uclinux啟動(dòng)過程詳細(xì)分析
存儲(chǔ)了可用物理內(nèi)存起始地址的變量memory_start的初始化是通過一個(gè)ld腳本中定義的變量_end進(jìn)行的。ld腳本是用來控制GNU ld連接器在連接內(nèi)核各個(gè)目標(biāo)文件部分的時(shí)候的配置動(dòng)作,比如這樣一個(gè)腳本:
SECTION
{
。=0x10000;
.text:{*(.text)}
。=0x8000000;
.data:{*(.data)}
.bss :{*(.bss)}
}
用來配置ld連接目標(biāo)文件的時(shí)候?qū)⑺械哪繕?biāo)文件中的存儲(chǔ)程序正文的.text段(section)連接到一起,并且映射到輸出文件的地址0x10000處,將所有目標(biāo)文件中已初始化的數(shù)據(jù).data段連接到一起并放置到輸出可執(zhí)行文件的0x8000000地址處,而所有目標(biāo)文件中還未初始化的數(shù)據(jù)段.bss連接起來后影射到輸出文件中緊跟在.data段之后的位置。
這個(gè)ld配置腳本文件對(duì)每個(gè)平臺(tái)都是不同的。如為MICETEK上所使用的uClinux版本使用的ld配置文件為arch/armnomm/vmLinux.lds。可以通過修改某個(gè)平臺(tái)上的ld腳本配置文件中的_end變量來達(dá)到配置其可用物理內(nèi)存起始地址的目的。
setup_arch()在完成對(duì)memory_start變量的初始化之后,通過某些特定手段檢測(cè)不同類型的內(nèi)存分布情況。比如為檢測(cè)某段地址范圍是否為RAM的方法是通過將某個(gè)地址的數(shù)據(jù)讀出來,將它加1后寫回內(nèi)存地址中,然后再讀出來和原始數(shù)據(jù)比較看看其值是否成功增加了1,這樣反復(fù)操作兩次,最后將數(shù)據(jù)恢復(fù)。如果是可讀可寫的RAM,那么這個(gè)測(cè)試的結(jié)果就是每次比較都是成功的,否則就不能將這個(gè)地址當(dāng)作RAM。
在setup_arch()中還可能根據(jù)所用平臺(tái)進(jìn)行對(duì)flash memory和ROM的測(cè)試。在這些平臺(tái)相關(guān)的工作完成之后,setup_arch()將對(duì)系統(tǒng)運(yùn)行的第一個(gè)進(jìn)程init_task的mm_struct結(jié)構(gòu)中描述地址空間分布的變量start_code,end_code,end_data和brk進(jìn)行初始化,start_code為0,其他三個(gè)數(shù)值分別為來自于ld腳本配置文件中定義的相關(guān)變量_etext、_edata和_end。
此后setup_arch()將根據(jù)Linux中為系統(tǒng)中的第一塊rom/flash memory card所分配的固定的主/從設(shè)備號(hào)(可以從Document/devices.txt中得到)來創(chuàng)建根文件系統(tǒng)的設(shè)備號(hào),并存儲(chǔ)在后來將要用到的全局變量ROOT_DEV中。
setup_arch()最后完成對(duì)系統(tǒng)啟動(dòng)參數(shù)的保存。
在調(diào)用setup_arch()返回之后,start_kernel()中得到了系統(tǒng)可用物理內(nèi)存的起始和結(jié)束地址,以及命令啟動(dòng)時(shí)的命令行參數(shù)。
(2) paging_init()
在Linux中,paging_init()的一項(xiàng)主要功能是建立頁目錄和頁表,而且將Linux移植到不同平臺(tái)的過程中非常重要的一個(gè)步驟就是修改這個(gè)函數(shù)來適應(yīng)新的硬件平臺(tái)的虛擬內(nèi)存體系。但是由于在uClinux中不再使用虛擬內(nèi)存機(jī)制,也就不再需要維護(hù)頁目錄和頁表數(shù)據(jù)結(jié)構(gòu)了,所以paging_init()在這里只是為系統(tǒng)啟動(dòng)的時(shí)候保留一部分特殊用途的內(nèi)存區(qū)間。它返回后,從可以使用的內(nèi)存空間開始,依次是如下的數(shù)據(jù)結(jié)構(gòu):
empty_bad_page_table 占用1頁(4KB)
empty_bad_page 占用1頁(4KB)
empty_zero_page 占用1頁,并初始化為全0
mem_map
bitmap
paging_init()函數(shù)在返回前通過調(diào)用free_area_init(start_mem,end_mem)進(jìn)行建立buddy system的映射位圖關(guān)系,以及建立空閑物理頁面鏈表的操作。
(3)free_area_init()
這個(gè)函數(shù)用于建立管理物理頁幀的數(shù)據(jù)結(jié)構(gòu)mem_map,有多少物理頁幀就有多少mem_map_t類型的結(jié)構(gòu)體與之相對(duì)應(yīng)。每個(gè)頁面的mem_map_t結(jié)構(gòu)中的flags被標(biāo)明為PG_DMA和PG_reserved,并且頁幀號(hào)被賦給相應(yīng)的數(shù)值。同時(shí)建立了管理空閑頁面的bitmap映射表,并且所有的位都被清零。
(3) mem_init()
mem_init()函數(shù)遍歷整個(gè)可用物理內(nèi)存地址空間,將每個(gè)頁面相對(duì)應(yīng)的struct page結(jié)構(gòu)中flags的PG_reserved 標(biāo)志位清除,標(biāo)志用戶個(gè)數(shù)的count計(jì)數(shù)器置1,并同時(shí)統(tǒng)計(jì)可用物理頁面數(shù)量,然后打印系統(tǒng)的各個(gè)內(nèi)存參數(shù),如可用RAM和ROM的大小、內(nèi)核代碼段和數(shù)據(jù)段大小等。
======================================================
摘 要:本文采用三星公司的S3C44B0微處理器,對(duì)uClinux操作系統(tǒng)內(nèi)核的引導(dǎo)過程進(jìn)行了剖析。
關(guān)鍵字:S3C44B0X;uClinux;嵌入式系統(tǒng);內(nèi)核引導(dǎo)
1 前言
伴隨著微電子的發(fā)展,用于嵌入式設(shè)備的處理器速度越來越快,功能也越來越強(qiáng)大。三星公司生產(chǎn)的S3C44B0微處理器,采用的是ARM7TDMI內(nèi)核。該內(nèi)核因?yàn)橛兄男?、成本低等特點(diǎn),因此非常適合作為移動(dòng)手持終端的處理器核心。Linux操作系統(tǒng)因?yàn)樗拈_放性,使得它不斷的被應(yīng)用到各個(gè)領(lǐng)域。在嵌入式領(lǐng)域同樣也出現(xiàn)了各種各樣的Linux變體,最常用的是uClinux。也正是因?yàn)閡Clinux操作系統(tǒng)支持不帶MMU單元的ARM處理器,因此該系統(tǒng)可以對(duì)S3C44B0微處理器有很好的支持。
在嵌入式系統(tǒng)開發(fā)中,第一個(gè)部分便是系統(tǒng)的引導(dǎo)。而系統(tǒng)的引導(dǎo)過程是通過BootLoader來完成的。BootLoader程序是與硬件緊密相關(guān)的一段代碼,而且編寫的時(shí)候比較復(fù)雜,它主要的功能是初始化微處理器以及周邊的硬件資源,并且引導(dǎo)操作系統(tǒng)的啟動(dòng)。下面我將以S3C44B0微處理器來作為例子,對(duì)uClinux操作系統(tǒng)內(nèi)核的引導(dǎo)過程進(jìn)行一個(gè)剖析。
2 BootLoader程序概念
簡(jiǎn)單的說Boot Lodaer就是在操作系統(tǒng)內(nèi)核運(yùn)行之前運(yùn)行的一段小程序,通過這段小程序,可以初始化硬件設(shè)備、建立系統(tǒng)的內(nèi)存空間映射圖,從而將系統(tǒng)的軟硬件環(huán)境設(shè)置成一個(gè)適合的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。最終,BootLoader把操作系統(tǒng)內(nèi)核映象加載到RAM中,并將系統(tǒng)控制權(quán)傳遞給它。
2.1 典型的BootLoader程序框架
操作系統(tǒng)角度來說,Boot Loader的總目標(biāo)就是正確的調(diào)用內(nèi)核來執(zhí)行。
由于Boot Loader的實(shí)現(xiàn)依賴于CPU的體系結(jié)構(gòu),因此大多數(shù)Boot Loader都分為Stage1和Stage2兩大部分。依賴于CPU體系結(jié)構(gòu)的代碼,例如設(shè)備初始化代碼等,通常都放在Stage1中,而且通常都用匯編語言來實(shí)現(xiàn),以達(dá)到短小精悍的目的。而Stage2通常用C語言來實(shí)現(xiàn),這樣可以實(shí)現(xiàn)更加復(fù)雜的功能,而且代碼會(huì)具有更好的可讀性和可移植性。
Boot Loader的Stage1通常包括如下步驟:
1) 硬件設(shè)備初始化
評(píng)論