WinCE6.0学习之EBoot源码分析----startup.s(三)
生活随笔
收集整理的這篇文章主要介紹了
WinCE6.0学习之EBoot源码分析----startup.s(三)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
下面將詳細敘述MMU的設置,也是本人花費時間最多的一部分內容,無論是2410、6410甚至是Cortex-A8核的ARM,MMU的設置基本都一樣,所以移植時這部分可以直接搬過來,只需要更改全局內存映射表的映射關系即可。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 先說說為什么在EBoot要設置MMU?其實有大牛們討論過這個話題,在系統啟動時會對頁表進行重新映射,包括二級頁表的設置,而在EBoot中只進行了一級頁表的設置,最后也沒有給出明確的答案,有的說是WinCE規定的,這里先不追究了,等以后研究了系統啟動后的代碼,再來討論這個問題。OAL作為WinCE的開始需要啟用虛擬內存,需要為MMU設置正確的頁表進行地址映射,另外WinCE編譯系統產生的二進制文件.bib使用的內存地址都是虛擬地址,這些虛擬地址是編譯系統對二進制代碼進行地址重定位的重要依據,所以在Eboot中對MMU進行設置,定義內存映射表的依據是全局內存映射表,在PLATFORM\SMDK6410\SRC\INC\oemaddrtab_cfg.inc文件中定義,內容如下: g_oalAddressTable
????????; mDDR 128 MB
????????????????;DCD???????? 0x80000000, 0x50000000,????64???????? ; 64 MB DRAM
????????????????[ SMDK6410_X5D
????????????????DCD???????? 0x80000000, 0x60000000,???? 64???????? ; 64 MB DRAM
????????????????|
????????????????DCD???????? 0x80000000, 0x50000000,????128???????? ; 128 MB DRAM
????????????????]
????????????????DCD???????? 0x90000000, 0x70000000,????4????????????; SROM SFR
????????????????DCD???????? 0x00000000, 0x00000000,????0????????????; end of table ??? 它是以g_oalAddressTable宏開始的,DCD用來分配一片連續的字存儲單元,第一個參數是虛擬地址值,第二個參數是對應的物理地址值,第三個參數指明分配的大小,在映射表的最后,將三個參數的值均設為0,表示是映射表的結束。下面看startup.s文件中的源碼。 ;------------------------------------
;???????? Initialize MMU Table
;------------------------------------
????????;----------------------------
????????; Compute physical address of the OEMAddressTable.
20
????????????????add????????????????????r11, pc, #g_oalAddressTable -(. + 8)
????????????????ldr????????????????????r10, =PT_1ST_BASE????????????????????????????????????????; (r10) = 1st level page table ?? 上面的代碼將R11賦值為內存映射表的地址,R10賦值為頁表存儲的地址,PT_1ST_BASE在最開始處已經進行了定義,是頁表基地址0x50010000,解釋一下R11的賦值語句。ARM處理器是流水線結構,允許指令預取,所以PC一般等于當前執行指令下面的第2條指令的地址,即PC=當前指令地址值+8字節,而“.”代表的是當前指令的地址值,PC=(. + 8),這樣R11獲得的是g_oalAddressTable的地址。那為什么不直接mov? r11? #g_oalAddressTable進行賦值呢?確實不能這樣,這樣可以編譯通過,但是執行不通過,只能采用和PC的相對值來換算。 add????????????????????r10, r10, #0x2000????????????????????; (r10) = ptr to 1st PTE for "unmapped space" ??? 這一條代碼,將R10的值增加了0x2000,因為第1級MMU的入口是地址值的高14為(過濾掉低18位),g_oalAddressTable中看出,DRAM的起始虛擬地址為0x80000000,而0x80000000>>18=0x2000,正好是0x80000000地址對應的第1級MMU入口的偏移值,也就是說R10現在存儲的是0x80000000虛擬地址對應的頁表的存儲地址。那么為什么要右移18位?第1級頁表將4GB的地址空間劃分為多個1MB的段,對應的就有4096個頁表項,而ARM地址映射時,虛擬地址被分為兩部分:高位+低位,高位用來表示虛擬地址對應的頁表針對頁表首地址的偏移值,而低位表示在頁表1MB地址空間中的偏移量,頁表中的一個頁表項可以描述4字節的虛擬頁(因為ARM是32位的,每次都是讀取4字節的數據),那么1MB的空間就需要256KB個這樣的頁表項才可以描述(256K*4=1M),而要表示256KB的大小,需要虛擬地址的低18位,剩下的高14位就可以用來計算虛擬地址對應頁表相對于頁表首地址的偏移量了。 mov????????????????????r0, #0x0E???????????????????????????? ; (r0) = PTE for 0: 1MB cachable bufferable
????????????????orr????????????????????r0, r0, #0x400????????????????????; set kernel r/w permission ??? 上面的兩條代碼用來設置頁表項的高速緩沖、寫緩沖以及讀寫屬性,具體的設置請參看CP15協處理器C1寄存器的功能,以后有時間會整理一篇關于CP15協處理器的說明。其實讀者如果仔細看會發現,設置后R0=0x40E,和文件開始聲明的PT_1ST_ENTRY_CNB變量的值是一樣的,所以也可以用mov? r0? PT_1ST_ENTRY_CNB來代替兩條語句,但是本人覺得用兩條語句更能表明設置了什么,語義更明確。 25
????????????????mov????????????????????r1, r11????????????????????????????????????????; (r1) = ptr to MemoryMap array
30
????????????????ldr????????????????????r2, [r1], #4???????????????????????????? ; (r2) = virtual address to map Bank at
????????????????ldr????????????????????r3, [r1], #4???????????????????????????? ; (r3) = physical address to map from
????????????????ldr????????????????????r4, [r1], #4???????????????????????????? ; (r4) = num MB to map ??? 首先將R11也就是g_oalAddressTable指向的全局內存映射表的地址賦給R1(這就是高手的代碼書寫習慣,不會直接操作R11),然后依次將R1指向的地址處的數據賦值給R2、R3和R4寄存器,“#4”是表示每次操作完后,R1的地址值增加4字節,指向下一個數據,其實對照oemaddrtab_cfg.inc的映射表,很容易發現,R2獲得的是虛擬地址的值,R3獲得的是對應物理地址的值,R4則是這段存儲空間的大小。 cmp????????????????????r4, #0????????????????????????????????????????; End of table?
????????????????beq????????????????????%F40 ??? 上面兩條代碼用來判斷是否到了oemaddrtab_cfg.in中映射表的結尾,上面已經介紹過,映射表的最后一條的三個參數全部都為0,標識映射表的結束。beq是一條跳轉語句,表示如果相等,則跳轉,%F40表明向后尋找名稱為40的標號(F=After)。
????????; mDDR 128 MB
????????????????;DCD???????? 0x80000000, 0x50000000,????64???????? ; 64 MB DRAM
????????????????[ SMDK6410_X5D
????????????????DCD???????? 0x80000000, 0x60000000,???? 64???????? ; 64 MB DRAM
????????????????|
????????????????DCD???????? 0x80000000, 0x50000000,????128???????? ; 128 MB DRAM
????????????????]
????????????????DCD???????? 0x90000000, 0x70000000,????4????????????; SROM SFR
????????????????DCD???????? 0x00000000, 0x00000000,????0????????????; end of table ??? 它是以g_oalAddressTable宏開始的,DCD用來分配一片連續的字存儲單元,第一個參數是虛擬地址值,第二個參數是對應的物理地址值,第三個參數指明分配的大小,在映射表的最后,將三個參數的值均設為0,表示是映射表的結束。下面看startup.s文件中的源碼。 ;------------------------------------
;???????? Initialize MMU Table
;------------------------------------
????????;----------------------------
????????; Compute physical address of the OEMAddressTable.
20
????????????????add????????????????????r11, pc, #g_oalAddressTable -(. + 8)
????????????????ldr????????????????????r10, =PT_1ST_BASE????????????????????????????????????????; (r10) = 1st level page table ?? 上面的代碼將R11賦值為內存映射表的地址,R10賦值為頁表存儲的地址,PT_1ST_BASE在最開始處已經進行了定義,是頁表基地址0x50010000,解釋一下R11的賦值語句。ARM處理器是流水線結構,允許指令預取,所以PC一般等于當前執行指令下面的第2條指令的地址,即PC=當前指令地址值+8字節,而“.”代表的是當前指令的地址值,PC=(. + 8),這樣R11獲得的是g_oalAddressTable的地址。那為什么不直接mov? r11? #g_oalAddressTable進行賦值呢?確實不能這樣,這樣可以編譯通過,但是執行不通過,只能采用和PC的相對值來換算。 add????????????????????r10, r10, #0x2000????????????????????; (r10) = ptr to 1st PTE for "unmapped space" ??? 這一條代碼,將R10的值增加了0x2000,因為第1級MMU的入口是地址值的高14為(過濾掉低18位),g_oalAddressTable中看出,DRAM的起始虛擬地址為0x80000000,而0x80000000>>18=0x2000,正好是0x80000000地址對應的第1級MMU入口的偏移值,也就是說R10現在存儲的是0x80000000虛擬地址對應的頁表的存儲地址。那么為什么要右移18位?第1級頁表將4GB的地址空間劃分為多個1MB的段,對應的就有4096個頁表項,而ARM地址映射時,虛擬地址被分為兩部分:高位+低位,高位用來表示虛擬地址對應的頁表針對頁表首地址的偏移值,而低位表示在頁表1MB地址空間中的偏移量,頁表中的一個頁表項可以描述4字節的虛擬頁(因為ARM是32位的,每次都是讀取4字節的數據),那么1MB的空間就需要256KB個這樣的頁表項才可以描述(256K*4=1M),而要表示256KB的大小,需要虛擬地址的低18位,剩下的高14位就可以用來計算虛擬地址對應頁表相對于頁表首地址的偏移量了。 mov????????????????????r0, #0x0E???????????????????????????? ; (r0) = PTE for 0: 1MB cachable bufferable
????????????????orr????????????????????r0, r0, #0x400????????????????????; set kernel r/w permission ??? 上面的兩條代碼用來設置頁表項的高速緩沖、寫緩沖以及讀寫屬性,具體的設置請參看CP15協處理器C1寄存器的功能,以后有時間會整理一篇關于CP15協處理器的說明。其實讀者如果仔細看會發現,設置后R0=0x40E,和文件開始聲明的PT_1ST_ENTRY_CNB變量的值是一樣的,所以也可以用mov? r0? PT_1ST_ENTRY_CNB來代替兩條語句,但是本人覺得用兩條語句更能表明設置了什么,語義更明確。 25
????????????????mov????????????????????r1, r11????????????????????????????????????????; (r1) = ptr to MemoryMap array
30
????????????????ldr????????????????????r2, [r1], #4???????????????????????????? ; (r2) = virtual address to map Bank at
????????????????ldr????????????????????r3, [r1], #4???????????????????????????? ; (r3) = physical address to map from
????????????????ldr????????????????????r4, [r1], #4???????????????????????????? ; (r4) = num MB to map ??? 首先將R11也就是g_oalAddressTable指向的全局內存映射表的地址賦給R1(這就是高手的代碼書寫習慣,不會直接操作R11),然后依次將R1指向的地址處的數據賦值給R2、R3和R4寄存器,“#4”是表示每次操作完后,R1的地址值增加4字節,指向下一個數據,其實對照oemaddrtab_cfg.inc的映射表,很容易發現,R2獲得的是虛擬地址的值,R3獲得的是對應物理地址的值,R4則是這段存儲空間的大小。 cmp????????????????????r4, #0????????????????????????????????????????; End of table?
????????????????beq????????????????????%F40 ??? 上面兩條代碼用來判斷是否到了oemaddrtab_cfg.in中映射表的結尾,上面已經介紹過,映射表的最后一條的三個參數全部都為0,標識映射表的結束。beq是一條跳轉語句,表示如果相等,則跳轉,%F40表明向后尋找名稱為40的標號(F=After)。
轉載于:https://blog.51cto.com/jazka/572644
總結
以上是生活随笔為你收集整理的WinCE6.0学习之EBoot源码分析----startup.s(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【iOS】Quartz2D图片剪切
- 下一篇: 深信服虚拟桌面部署及性能优化关键点配置(