WINCE的内存配置-config.bib文件的解析
WINCE的內(nèi)存(包括SDRAM及FLASH)的配置包含兩個(gè)方面:源代碼(包括C和匯編)中的定義,及系統(tǒng)配置文件CONFIG.BIB中的定義。源代碼中需要定義內(nèi)存的物理及虛擬地址,大小,并初始化名為OEMAddressTable的結(jié)構(gòu)數(shù)組,以告知系統(tǒng)物理地址與虛擬地址的對(duì)應(yīng)關(guān)系,系統(tǒng)根據(jù)其設(shè)置生成MMU頁(yè)表。而CONFIG.BIB中一般會(huì)將內(nèi)存定義成不同的段,各段用作不同的用途。
CONFIG.BIB文件
CONFIG.BIB文件分兩個(gè)部分,我們且稱之為段,MEMORY段和CONFIG段。MEMORY段定義內(nèi)存的分片方法,CONFIG段定義系統(tǒng)其它的一些屬性。以下是一個(gè)CONFIG.BIB文件MEMORY段的例子:
MEMORY
; 名稱 起始地址 大小 屬性
RESERVED 80000000 00008000 RESERVED
DRV_GLB 80008000 00001000 RESERVED
CS8900 80010000 00030000 RESERVED
EDBG 80040000 00080000 RESERVED
NK 800C0000 00740000 RAMIMAGE
RAM 81000000 00800000 RAM
名稱原則上可以取任意字符串,ROMIMAGE通過(guò)一個(gè)內(nèi)存片的屬性來(lái)判斷它的用途。RESERVE屬性表明該片內(nèi)存是BSP自己使用的,系統(tǒng)不必關(guān)心其用途;RAMIMAGE說(shuō)明它是一片存放OS IMAGE的內(nèi)存;而RAM則表示些片內(nèi)存為RAM,系統(tǒng)可以在其中分配空間,運(yùn)行程序。
但存放 ROM的這片內(nèi)存的名稱,即NK一般不要改動(dòng)。因?yàn)?/span>BIB文件中定義將一個(gè)文件加入到哪個(gè)ROM片(WINCE支持將ROM IMAGE存放在不連續(xù)的幾個(gè)內(nèi)存片中)中時(shí)會(huì)用到這個(gè)名稱,如下現(xiàn)這行BIB文件項(xiàng)就定義將touch.dll放在名稱為NK這片ROM中,
touch.dll $(_FLATRELEASEDIR)/touch.dll NK SH
因而,如果將NK改為其它名稱,則系統(tǒng)中所有的BIB文件中的這個(gè)NK串都需要改動(dòng)。
注意:保證各片內(nèi)存不要重疊;而且中間不要留空洞,以節(jié)約內(nèi)存;兩種設(shè)備如果不能同時(shí)被加載,就應(yīng)該只為其保留一片從而節(jié)約內(nèi)存,例如,本例中的 CS8950是為網(wǎng)卡驅(qū)動(dòng)程序保留的,EDBG是為網(wǎng)卡作調(diào)試(KITL)用時(shí)保留的,而系統(tǒng)設(shè)計(jì)成這兩個(gè)程序不會(huì)同時(shí)加載(CS8950在啟動(dòng)時(shí)判斷如果EDBG在運(yùn)行就會(huì)自動(dòng)退出),這樣為這兩個(gè)驅(qū)動(dòng)程序各保留一片內(nèi)存實(shí)在浪費(fèi)而且也沒(méi)有必要。
RAM片必須在物理上是連續(xù)的,如果系統(tǒng)的物理內(nèi)存被分成了幾片,則在RAM片只能聲明一片,其它的內(nèi)存在啟動(dòng)階段由OEMGetExtensionDRAM報(bào)告給系統(tǒng),如果有多于一個(gè)的內(nèi)存片,應(yīng)該用 OEMEnumExtensionDRAM報(bào)告。NK片則沒(méi)有此限制,只是NK跨越兩個(gè)以上物理內(nèi)存片時(shí),系統(tǒng)啟動(dòng)時(shí)會(huì)顯示這個(gè)OS包跨越了多個(gè)物理內(nèi)存片,認(rèn)為是個(gè)錯(cuò)誤,但并不影響系統(tǒng)的執(zhí)行與穩(wěn)定性,因?yàn)橄到y(tǒng)啟動(dòng)之時(shí)便會(huì)打開(kāi)MMU而使用虛擬地址,從而看到連續(xù)的內(nèi)存空間。當(dāng)然,如果內(nèi)核自己都被放在了兩個(gè)內(nèi)存片上,那系統(tǒng)應(yīng)該就無(wú)法啟動(dòng)了。而其它保留起來(lái)的內(nèi)存片是一般是給驅(qū)動(dòng)程序DMA用,應(yīng)該保證它們?cè)谖锢砩系倪B續(xù)性,因?yàn)?/span>DMA是直接用物理地址的。
CONFIG段中以下幾個(gè)需要格外注意:
ROMSTART,它定義ROM的起始位置,應(yīng)該和NK片的起始位置相同。
ROMSIZE,定義ROM的大小,應(yīng)該和NK片的大小相同。
如果不需要NK。BIN文件,則可以不設(shè)這兩個(gè)值。
ROMWIDTH,它只是定義ROMIMAG生成ROM包時(shí)如何組織文件,而非其字面含義:ROM的寬度,所以一般都應(yīng)該為32
COMPRESSION,一般定義為ON,以打開(kāi)壓縮功能,從而減小BIN文件的尺寸。
AUTOSIZE,一般應(yīng)該設(shè)為ON,以使系統(tǒng)將定義給ROM但沒(méi)有用掉的內(nèi)存當(dāng)做RAM使用,而提高RAM的使用率。注意,如果ROM是FLASH,則不能設(shè)為ON,因?yàn)?/span>FLASH不能當(dāng)作RAM使用。
ROMOFFSET,它定義OS起始位置(即ROMSTART)的物理地址和虛擬地址的差值,有些BSP中并沒(méi)有使用這個(gè)定義。
OEMAddressTable及其它
OEMAddressTable用來(lái)初始化系統(tǒng)中各種設(shè)備的虛擬地址與物理地址的對(duì)映關(guān)系。在我使用的BSP中,它是這樣定義并初始化的:
typedef struct
{
ULONG ulVirtualAddress;
ULONG ulPhysicalAddress;
ULONG ulSizeInMegs;
} AddressTableStruct;
#define MEG(A) (((A - 1)>>20) + 1)
const AddressTableStruct OEMAddressTable[] =
{
{ SDRAM_VIRTUAL_MEMORY, //虛擬地址
PHYSICAL_ADDR_SDRAM_MAIN, //物理地址
MEG(SDRAM_MAIN_BLOCK_SIZE) //這段空間的大小,以M計(jì)
},
………………………
{
0,
0,
0
}
};
如例子所示,OEMAddressTable為一個(gè)結(jié)構(gòu)數(shù)組,每項(xiàng)的第一個(gè)成員為虛擬地址,第二個(gè)成員為對(duì)應(yīng)的物理地址,最后一個(gè)成員為該段空間的大小。這個(gè)數(shù)組的最后一項(xiàng)必須全部為0,以示整個(gè)數(shù)組的結(jié)束。內(nèi)核啟動(dòng)時(shí)會(huì)讀取這個(gè)數(shù)組的內(nèi)容以初始化MMU頁(yè)表,啟用MMU,從爾使程序可以用虛擬地址來(lái)訪問(wèn)設(shè)備。當(dāng)然,OEMAddressTable中所用到的每個(gè)物理地址及虛擬地址都需要在頭文件中定義,每個(gè)BSP中定義這些值的文件不盡相同,所以,在此不能說(shuō)明具體在哪個(gè)文件,讀者朋友可以參考具體BSP的文檔及代碼。
不連續(xù)內(nèi)存的處理
如果內(nèi)存在物理上是連續(xù)的,則 OEMAddressTable中只需要一項(xiàng)就可以完成對(duì)內(nèi)存的地址映射。但如果BSP運(yùn)行在SDRAM物理上不連續(xù)的系統(tǒng)上時(shí), OEMAddressTable中需要更多的項(xiàng)來(lái)將SDRAM映射到連續(xù)的虛擬地址上,當(dāng)然也可以將它們映射到不連續(xù)的虛擬地址上,但似乎沒(méi)有理由那么做。而且,當(dāng)其物理地址不連續(xù)時(shí)系統(tǒng)需要做更多的工作。例如,我有這樣一個(gè)系統(tǒng):32M SDRAM,16M FLASH,SDRAM在物理上不連續(xù),被分成了4個(gè)8M的內(nèi)存塊,我的SDRAM的使用情況如下圖所示:
CONFIG。BIB文件的MEMORY段如下所示:
MEMORY
RESERVED 80000000 00008000 RESERVED
DRV_GLB 80008000 00001000 RESERVED
CS8900 80010000 00030000 RESERVED
EDBG 80040000 00080000 RESERVED
NK 800C0000 00940000 RAMIMAGE
RAM 81800000 00800000 RAM
在這32M的空間中,BSP保留了前0x80000字節(jié),接下來(lái)是NK,它占用了0x940000字節(jié),而且它跨越了兩個(gè)內(nèi)存片,這些和其它BSP的設(shè)置都沒(méi)有多大差別,接下來(lái)看RAM片,它只占用了最后的8M空間,前面說(shuō)過(guò),在這種物理內(nèi)存不連續(xù)的系統(tǒng)中,RAM片不能跨越兩個(gè)物理內(nèi)存塊,所以它被設(shè)計(jì)成只占用該系統(tǒng)中的最后一個(gè)物理內(nèi)存片,而其它兩片則由OEMEnumExtensionDRAM在運(yùn)行時(shí)刻報(bào)告給系統(tǒng),該函數(shù)的內(nèi)容如下:
pMemSections[0].dwFlags=0;
pMemSections[0].dwStart=(SDRAM_VIRTUAL_MEMORY + 0x1000000);
pMemSections[0].dwLen=0x800000;
pMemSections[1].dwFlags=0;
pMemSections[1].dwStart=(SDRAM_VIRTUAL_MEMORY + 0x0A00000);
pMemSections[1].dwLen=0x600000;
return 2;
這樣,系統(tǒng)所有的內(nèi)存都被激活,系統(tǒng)可用內(nèi)存就變成了8+8+6=24M,可以將RAM定義為這三片中的任意一片,而在 OEMEnumExtensionDRAM中報(bào)告其它兩片。但把RAM放在最后一片物理內(nèi)存上有一個(gè)很大的好處,即如果NK變大,例如編譯一個(gè)DEBUG 版的系統(tǒng)時(shí),這時(shí),只需要將OEMEnumExtensionDRAM中的內(nèi)容注釋掉,CONFIG.BIB文件不用做任何改動(dòng),系統(tǒng)就可運(yùn)行,只是在 MAKEIMG時(shí)會(huì)有一個(gè)警告說(shuō)系統(tǒng)包太大,可能無(wú)法運(yùn)行,但實(shí)際不會(huì)影響系統(tǒng)的執(zhí)行與穩(wěn)定性,因?yàn)?/span>NK之后的那段內(nèi)存并沒(méi)有被使用,正好被漲大的系統(tǒng)占用,這在調(diào)試時(shí)極其方便。
而如果系統(tǒng)物理內(nèi)存是連續(xù)的,那將變得簡(jiǎn)單的多,還以上面的設(shè)置為例,如果這32M的SDRAM是物理上連續(xù)的,內(nèi)存的使用情況就可以表示如下圖:
所有者系統(tǒng)可用內(nèi)存都可以定義在RAM片中。
對(duì)硬件知識(shí)了解不多的朋友請(qǐng)注意:SDRAM是否在物理上連續(xù),與我們的板上有幾片SDRAM沒(méi)有關(guān)系,應(yīng)該向硬件工程師了解SDRAM的地址分布情況。
?
?
?
?
Understanding Memory Sections in config.bib, boot.bib, and OEMAddressTable in Windows CE 5.0 and 6.0
Introduction
Windows CE uses .bib (binary image builder) files to track, among other things, the memory layout of bootloaders as well as OS images.? If you’re writing a new BSP, you’ll definitely need a config.bib file for your OS, and you’ll likely need a boot.bib file for your bootloader.
?Let’s take a few minutes to understand how .bib files relate to memory usage.? It’s going to be muddy at the beginning, but I promise if you stick with me through the end you’ll be glad that you did.? Well, maybe you won’t be glad but you’ll know more about .bib files.? Let’s get to it!
?OEMAddressTable
Before we look at the .bib files themselves, it’s important to understand the OEMAddressTable.? This table defines the mappings between physical and virtual addresses.? For MIPS and SH processors, this table is hard coded into the processor.? For x86 and ARM, the mapping is defined in a variable called OEMAddressTable.? Since .bib files operate largely on virtual addresses, we need to remember to reference the OEMAddressTable to address any confusion about what is happening at a particular physical address.
?The table’s layout is quite simple.? Each line creates a mapping of virtual addresses to physical addresses.? The syntax is: Base virtual address, base physical address, size.? Let’s take an example from the Mainstone BSP:
?DCD? ???0x80000000, 0xA0000000,? 64???? ; MAINSTONEII: SDRAM (64MB).
DCD???? 0x88000000, 0x5C000000,?? 1???? ; BULVERDE: Internal SRAM (64KB bank 0).
DCD???? 0x88100000, 0x58000000,?? 1???? ; BULVERDE: Internal memory PM registers.
DCD???? 0x88200000, 0x4C000000,?? 1???? ; BULVERDE: USB host controller.
?So in the first line, we are mapping the 64MB of RAM at physical address 0xA0000000 to the virtual address 0x80000000.? Since 64MB = 0x04000000 this means that the physical addresses 0xA000000-0xA4000000 are now mapped to virtual addresses 0x80000000-0x84000000.? Likewise, we’ve mapped the USB host controller which resides at physical addresses 0x4C000000-0x4C100000 to virtual addresses 0x88200000-0x88300000.
?Inside Windows CE, memory access is virtual by default.? So when we access memory at 0x81005000, we’ll be accessing some physical memory in the Mainstone’s 64MB SDRAM bank.? If we access memory at 0x88201000, we’ll be accessing the USB host controller, physically.? If we access memory at 0x86001000, we’ll get a page fault because this virtual address has no corresponding physical address.
?Now that we understand the OEMAddressTable, let’s talk about the .bib files.
?Config.bib – this contains a lot of configuration info for a CE OS image.? The MEMORY section is what we’ll focus on – it defines the memory blueprint for the CE image.? Here are the important terms:
?RAMIMAGE – This is the virtual address region that the kernel and any other components you select for your image will be placed in.? This can be RAM or linearly addressable flash.? Your config.bib file should have exactly one RAMIMAGE section.? It needs to be virtually contiguous, and it needs to be large enough to hold whatever components you’ve selected.
?RAM – This is the virtual address region of RAM that the kernel can allocate to applications and RAM-based file systems.? It needs to be virtually contiguous.? (If you need a non-contiguous section, you can allocate another, non-virtually-contiguous section at run-time by implementing the OEMGetExtensionDRAM function, but that’s outside our scope)
?RESERVED – These are virtual address regions that are set aside – the kernel won’t allocate memory in these addresses and components won’t be placed in these addresses.
?AUTOSIZE - In the CONFIG section, we have the AUTOSIZE=ON (or OFF) variable.? If this variable is on, it will treat the RAMIMAGE and RAM regions as a single region, allocating just enough space to hold all of the components to the RAMIMAGE section and making the rest of the space available as RAM.? This is a pretty convenient and easy way to make sure you’re getting maximal use out of your RAM.? One thing autosize won’t do is interfere with reserved or unallocated regions.
?Eboot.bib (sometimes known as boot.bib) – this works identically to config.bib, except we’re building a bootloader image as opposed to one with a full kernel.? All of the terminology is exactly the same.? The only difference is, in the case where we’re not using an MMU in the bootloader (CEPC is an example of these), the addresses will be physical as opposed to virtual.? Otherwise, the layout is identical.
?Bringing it together
In almost all cases, the bootloader and OS use the same OEMAddressTable.? Thus, they have the same virtual address space.
?This is especially useful when it comes to RESERVED regions.? Since nothing will be allocated or placed in these addresses, only components that refer directly to the address will have access.? That means we can use these regions for special buffers (say, DMA) or passing arguments passed in from the bootloader to the OS.? It also means that, if you want, you can leave the bootloader in RAM.
?Keep in mind that while RESERVED means that we won’t allocate/place components in those virtual addresses, by default if an area isn’t specified in a .bib file then we won’t allocate/place in it.? This means RESERVED is really more of a comment then anything.? However, it is useful in our .bib files because it helps us identify the location of special buffers and arguments so that we know not to overwrite them in other modules.
?An Example
Let’s take a look at a simplified example in the CEPC BSP:
Here’s our OEMAddressTable (platform/common/src/x86/common/startup/startup.asm):
_OEMAddressTable:
??????? dd? 80000000h,???? 0,????? 04000000h
This means that we’re mapping physical addresses 0x00000000-0x04000000 to virtual addresses 0x80000000-0x84000000.? That’s 64MB of RAM.
Here’s our boot.bib (platform/CEPC/src/bootloader/eboot/boot.bib):
MEMORY
;?? Name???? Start???? Size????? Type
;?? -------? --------? --------? ----
??? EBOOT?? 00130000? 00020000? RAMIMAGE
??? RAM??????? 00150000? 00070000? RAM
??? ETHDMA???? 00200000? 00020000? RESERVED
Remember the CEPC bootloader uses physical addresses.? So in virtual address terms, our bootloader code is living at 0x80130000-0x80150000, with RAM available from 0x80150000-0x801C0000.? We’re reserving a buffer for our Ethernet card from 0x80200000-0x80220000.
?And a condensed version of config.bib (platform/CEPC/files/config.bib):
?MEMORY
;?? Name???? Start???? Size????? Type
;?? -------? --------? --------? ----
; 64 MB of RAM (note: AUTOSIZE will adjust boundary)
??? NK?????? 80220000? 009E0000? RAMIMAGE
??? RAM????? 80C00000? 03400000? RAM
??? DMA????? 80100000? 00030000? RESERVED ??; Native DMA reserved.
??? BOOTARGS 801FFF00? 00000100? RESERVED?? ; Boot arguments
??? EDBG_DMA 80200000? 00020000? RESERVED?? ; EDBG DMA buffer
There are several interesting things going on here:
First, our OS image (NK) starts at 0x80220000, and RAM resides directly above it.? That means we’re not allowing any components or allocation to write below 0x80220000, and thus our bootloader code is protected.
?Second, note that we have also reserved some regions.? The EDBG_DMA corresponds to the same addresses that the bootloader reserved.? This way we can make a smooth transition from bootloader to kernel without worrying about the contents of this memory being tampered with.?
?Another region has been reserved from 0x80100000-0x80130000.? This is very close to the start of our bootloader.? If we reserved even a byte more, we would not expect our bootloader to continue to be executable after we boot the OS.? However, since the bootloader’s address space isn’t referenced by any region in config.bib, we know that it will remain untouched by the OS.? This way we can jump back to the bootloader code during a warm reset, if desired.
?We’re not required to keep our bootloader in memory, though.? We could easily place the bootloader (in boot.bib) at the end of the RAM space (in config.bib).? This way after the image was successfully downloaded we could allocate memory over the top of the bootloader and make full use of all of our system RAM.? What you don’t want to do is intersect the bootloader with the RAMIMAGE part of config.bib – this means you’ll overwrite the code you’re running to download, during download!
Finally, notice we have a special reserved region called “boot arguments”.? If we at the CEPC’s bootloader we will see that it writes explicitly to the (physical) 0x001FFF00-0x002000000.? You’ll also notice this isn’t used anywhere in the boot.bib layout.? That means we can be assured it will be untouched (unless, of course, something else in the bootloader writes explicitly to that address range).
This is how we pass arguments from the bootloader to the OS – the OS can read directly from 0x801FFF00 and be assured that the kernel won’t tamper with it because it is RESERVED.? Technically, we could have indicated that area as RESERVED in the bootloader as well.
?Hopefully this has given you some insight into .bib memory layouts.
update: In response to a comment generated by this entry I'd like to point out that the virtual addresses used in both OEMAddressTable and config.bib must fall between 0x80000000 and 0xA0000000 - the kernel virtual memory space reserved for cachable access.
總結(jié)
以上是生活随笔為你收集整理的WINCE的内存配置-config.bib文件的解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 蓝牙地址的规则
- 下一篇: WinCE中sources文件中targ