<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          S3C2440之MMU操作(MDK4.22)

          作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
          關(guān)于MMU知識(shí):

          1.ARM CPU上的地址轉(zhuǎn)換過程涉及到了3個(gè)概念,虛擬地址VA,變換地址MVA,物理地址PA。當(dāng)沒有啟動(dòng)MMU的時(shí)候,CPU核,CACHE,MMU見到的都是PA。

          本文引用地址:http://www.ex-cimer.com/article/201611/318144.htm

          啟動(dòng)MMU之后,CPU核對(duì)外發(fā)出VA,VA被轉(zhuǎn)換為MVA,供給CACHE和MMU使用,MMU再將MVA轉(zhuǎn)換為PA,最終找到真實(shí)的地址。

          CPU看見的VA,CACHE和MMU看不見VA,看見的是MVA;設(shè)備只看到VA。

          轉(zhuǎn)換算法:如果VA<32M,那么使用進(jìn)程PID來轉(zhuǎn)換,PID通過CP15的C13讀取。

          if(VA<32M) then

          MVA = VA | (PID << 25);

          else

          MVA = VA; //VA >= 32M

          2.協(xié)處理器的cp15寄存器c2的31-14位存放一級(jí)頁表的地址,一級(jí)頁表有4096項(xiàng),每項(xiàng)4字節(jié),共16k,所以c2的0到13位不使用

          若為段映射,只需要一級(jí)頁表,每段1M,4096*1M=4G空間;若為頁映射就需要二級(jí)頁表,目標(biāo)的物理頁有大頁,小頁,極小頁。


          3.一級(jí)頁表的描述符和二級(jí)頁表描述符


          注意到一級(jí)描述符是用來指引二級(jí)描述符的,除了段的直接指引到物理內(nèi)存,若使用二級(jí)頁表的話,那么二級(jí)頁表類型有粗頁表,細(xì)頁表兩種。

          粗頁表256項(xiàng),每項(xiàng)指引真是內(nèi)存為4K大小,本身占256*4=1k字節(jié);細(xì)頁表1024項(xiàng),每項(xiàng)指引1k大小,本身二級(jí)頁表占1024*4=4k字節(jié)。

          所以注意到,若要對(duì)應(yīng)真實(shí)物理頁的大頁的話,怎么辦呢?利用粗頁的話,需要16個(gè)粗頁二級(jí)描述符;利用細(xì)頁的話,需要64個(gè)二級(jí)描述符。


          4段的轉(zhuǎn)換舉例


          5內(nèi)存訪問權(quán)限問題

          注意到一級(jí)頁表中的描述符中有domain字段,4位,共16種情況


          對(duì)應(yīng)的為cp15中的c3寄存器設(shè)置。

          00無訪問權(quán)限,任何訪問都會(huì)導(dǎo)致domain fault異常

          01客戶模式,使用段描述符,頁描述符進(jìn)行權(quán)限檢查

          10保留

          11管理模式,不進(jìn)行權(quán)限檢查,運(yùn)行任何訪問

          cp15中的c3 + domain + cp15寄存器c1中的R/S/A位 + 描述符AP共同決定訪問權(quán)限

          6TIB和Cache的作用

          TLB是為了減輕頁表訪問所帶來的訪問內(nèi)存負(fù)擔(dān),利用程序訪問的局部性原理,選擇高速且容量較小的存儲(chǔ)器存儲(chǔ)近期使用的頁表?xiàng)l目。

          一般做法:在啟動(dòng)MMU之前使無效整個(gè)TLB;更改頁表表項(xiàng)的時(shí)候,使無效所涉及到的虛擬地址所對(duì)應(yīng)到的TLB條目。

          Cache的作用,在主存和CPU通用寄存器之間設(shè)置一個(gè)高速,容量相對(duì)較小的存儲(chǔ)器。把正在執(zhí)行的指令的附近一部分?jǐn)?shù)據(jù)或者指令從主存調(diào)入這個(gè)

          存儲(chǔ)器,供CPU在一段時(shí)間內(nèi)使用。Cache的(1)clean操作是將cache或writerbuffer已經(jīng)臟的數(shù)據(jù)寫入主存(2)invalidate不將數(shù)據(jù)寫入主存,使之不能

          再使用而已。

          cp15的寄存器1的12位Icr位開啟Icaches;第2位寫1開啟Dcaches;Writterbuffer和Dcache緊密結(jié)合,沒有專門的控制為開啟,停止它。

          程序部分:

          本程序?qū)?-1M映射為本身,將0xa0000000~0xa000fffff映射為0x56000000~0x560ffffff,將0xb0000000~0xb3ffffff映射為0x30000000~0x3fffffff

          涉及到代碼文件有s3c2440.s文件,init.c文件,led.c文件,led.sct文件

          s3c2440.s主要是調(diào)用一些初始化程序,init.c是初始化代碼,led.c只是利用新的虛擬地址尋找gpio,點(diǎn)亮led。

          編譯器MDK4.22a

          led.sct文件如下所示:

          LR_ROM1 0x00000000 0x00200000 { ; load region size_region
          NANDFLASH 0x00000000 0x00200000 { ; load address = execution address
          *.o (initcode, +First)
          .ANY (+RO)
          }
          }


          LR_ROM2 2048 2048 {
          SDRAM 0xb0004000 {
          led.o (*)
          }
          }

          存在多個(gè)加載域,會(huì)產(chǎn)生多個(gè)bin,可以參見的另一篇文章講到如何連接多個(gè)bin文件S3C2440開發(fā)工具realview MDK4.22使用入門

          init.c文件:

          //creat page table
          void create_page_table(void)
          {
          #define MMU_FULL_ACCESS(3<<10)
          #define MMU_DOMAIN(0<<5)
          #define MMU_SPECIAL(1<<4)
          #define MMU_CACHEABLE(1<<3)
          #define MMU_BUFFERABLE(1<<2)
          #define MMU_SECTION(2<<0)
          #define MMU_SECDESC(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |
          MMU_SECTION)
          #define MMU_SECDESC_WB(MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL |
          MMU_SECTION | MMU_CACHEABLE | MMU_BUFFERABLE)
          #define MMU_SECTION_SIZE0x00100000

          ulong virtualaddr, physicaladdr;
          ulong *mmu_tlb_base = (ulong*)0x30000000;

          /*<1>0~1M map to 0~1M virtualaddr == physicaladdr*/
          virtualaddr = 0;
          physicaladdr = 0;


          //mmu page table store at 0x30000000
          //vritualaddr>>20 is index of mmu page table
          *(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;

          /*<2>0xa0000000~0xa000fffff map to 0x56000000~0x560fffff*/
          virtualaddr = 0xa0000000;
          physicaladdr = 0x56000000;
          *(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC;


          /*<3>0xb0000000~0xb3ffffff map to 0x30000000~0x33fffffff total=64m totaldescs=64*/
          virtualaddr = 0xb0000000;
          physicaladdr = 0x30000000;

          while(virtualaddr < (ulong)0xb4000000)
          {
          *(mmu_tlb_base + (virtualaddr>>20)) = (physicaladdr&0xfff00000) | MMU_SECDESC_WB;
          virtualaddr += MMU_SECTION_SIZE;
          physicaladdr += MMU_SECTION_SIZE;
          }
          }




          //init MMU
          void mmu_init(void)
          {
          ulong ttb = 0x30000000;

          __asm{
          mov r0,#0
          mcr p15,0,r0,c7,c7,0 //invalidate Icache Dcache

          mcrp15,0,r0,c7,c10,4//drain writer buffer
          mcr p15,0,r0,c8,c7,0 //invalidate TLB

          mov r4,ttb
          mcr p15,0,r4,c2,c0,0 //set page table base-addr

          mvn r0,#0 //invert all bits:0x0000000->0xffffffff
          mcr p15,0,r0,c3,c0,0 //set domain(all is 0b11)


          mrc p15,0,r0,c1,c0,0 //read control register

          bic r0,r0,#0x3000
          bic r0,r0,#0x0300
          bic r0,r0,#0x0087

          orr r0,r0,#0x0002
          orr r0,r0,#0x0004
          orr r0,r0,#0x1000
          orr r0,r0,#0x0001

          mcr p15,0,r0,c1,c0,0

          };
          }



          關(guān)鍵詞: S3C2440MMU操作MDK4.2

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();