資源描述:
《ucLinux內(nèi)核移植相關(guān)代碼分析》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、ucLinux內(nèi)核移植相關(guān)代碼分析?????本文通過(guò)整理之前研發(fā)的一個(gè)項(xiàng)目(ARM7TDMI+uCLinux),分析內(nèi)核啟動(dòng)過(guò)程及需要修改的文件,以供內(nèi)核移植者參考。整理過(guò)程中也同時(shí)參考了眾多網(wǎng)友的帖子,在此謝過(guò)。由于整理過(guò)程匆忙,難免錯(cuò)誤及講解的不夠清楚之處,請(qǐng)各位網(wǎng)友指正,這里提前謝過(guò)。本文分以下部分進(jìn)行介紹:1.?Bootloader及內(nèi)核解壓2.?內(nèi)核啟動(dòng)方式介紹3.?內(nèi)核啟動(dòng)地址的確定4.?arch/armnommu/kernel/head-armv.S分析5.?start_kernel()函數(shù)分析1.Bootloader及內(nèi)核解
2、壓?????Bootloader將內(nèi)核加載到內(nèi)存中,設(shè)定一些寄存器,然后將控制權(quán)交由內(nèi)核,該過(guò)程中,關(guān)閉MMU功能。通常,內(nèi)核都是以壓縮的方式存放,如zImage,這里有兩種解壓方法:使用內(nèi)核自解壓程序。arch/arm/boot/compressed/head.S或arch/arm/boot/compressed/head-xxxxx.Sarch/arm/boot/compressed/misc.c在Bootloader中增加解壓功能。使用該方法時(shí)內(nèi)核不需要帶有自解壓功能,而使用Bootloader中的解壓程序代替內(nèi)核自解壓程序。其工作過(guò)
3、程與內(nèi)核自解壓過(guò)程相似:Bootloader把壓縮方式的內(nèi)核解壓到內(nèi)存中,然后跳轉(zhuǎn)到內(nèi)核入口處開始執(zhí)行。2.幾種內(nèi)核啟動(dòng)方式介紹XIP(EXECUTEINPLACE)是指直接從存放代碼的位置上啟動(dòng)運(yùn)行。2.1非壓縮,非XIP非XIP方式是指在運(yùn)行之前需對(duì)代碼進(jìn)行重定位。該類型的內(nèi)核以非壓縮方式存放在Flash中,啟動(dòng)時(shí)由Bootloader加載到內(nèi)存后運(yùn)行。2.2非壓縮,XIP該類型的內(nèi)核以非壓縮格式存放在ROM/Flash中,不需要加載到內(nèi)存就能運(yùn)行,Bootloader直接跳轉(zhuǎn)到其存放地址執(zhí)行。Data段復(fù)制和BSS段清零的工作由內(nèi)核自
4、己完成。這種啟動(dòng)方式常用于內(nèi)存空間有限的系統(tǒng)中,另外,程序在ROM/Flash中運(yùn)行的速度相對(duì)較慢。2.3RAM自解壓壓縮格式的內(nèi)核由開頭一段自解壓代碼和壓縮內(nèi)核數(shù)據(jù)組成,由于以壓縮格式存放,內(nèi)核只能以非XIP方式運(yùn)行。RAM自解壓過(guò)程如下:壓縮內(nèi)核存放于ROM/Flash中,Bootloader啟動(dòng)后加載到內(nèi)存中的臨時(shí)空間,然后跳轉(zhuǎn)到壓縮內(nèi)核入口地址執(zhí)行自解壓代碼,內(nèi)核被解壓到最終的目的地址然后運(yùn)行。壓縮內(nèi)核所占據(jù)的臨時(shí)空間隨后被Linux回收利用。這種方式的內(nèi)核在嵌入式產(chǎn)品中較為常見。2.4ROM自解壓解壓縮代碼也能夠以XIP的方式在R
5、OM/Flash中運(yùn)行。ROM自解壓過(guò)程如下:壓縮內(nèi)核存放在ROM/Flash中,不需要加載到內(nèi)存就能運(yùn)行,Bootloader直接跳轉(zhuǎn)到其存放地址執(zhí)行其自解壓代碼,將壓縮內(nèi)核解壓到最終的目的地址并運(yùn)行。ROM自解壓方式存放的內(nèi)核解壓縮速度慢,而且也不能節(jié)省內(nèi)存空間。3.內(nèi)核啟動(dòng)地址的確定內(nèi)核自解壓方式Head.S/head-XXX.S獲得內(nèi)核解壓后首地址ZREALADDR,然后解壓內(nèi)核,并把解壓后的內(nèi)核放在ZREALADDR的位置上,最后跳轉(zhuǎn)到ZREALADDR地址上,開始真正的內(nèi)核啟動(dòng)。arch/armnommu/boot/Makefi
6、le,定義ZRELADDR和ZTEXTADDR。ZTEXTADDR是自解壓代碼的起始地址,如果從內(nèi)存啟動(dòng)內(nèi)核,設(shè)置為0即可,如果從Rom/Flash啟動(dòng),則設(shè)置ZTEXTADDR為相應(yīng)的值。ZRELADDR是內(nèi)核解壓縮后的執(zhí)行地址。arch/armnommu/boot/compressed/vmlinux.ld,引用LOAD_ADDR和TEXT_START。arch/armnommu/boot/compressed/Makefile,通過(guò)如下一行:SEDFLAGS=s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR
7、/$(ZRELADDR)/;使得TEXT_START=ZTEXTADDR,LOAD_ADDR=ZRELADDR。說(shuō)明:執(zhí)行完decompress_kernel函數(shù)后,代碼跳回head.S/head-XXX.S中,檢查解壓縮之后的kernel起始地址是否緊挨著kernelimage。如果是,beqcall_kernel,執(zhí)行解壓后的kernel。如果解壓縮之后的kernel起始地址不是緊挨著kernelimage,則執(zhí)行relocate,將其拷貝到緊接著kernelimage的地方,然后跳轉(zhuǎn),執(zhí)行解壓后的kernel。Bootloader解壓
8、方式Bootloader把解壓后的內(nèi)核放在內(nèi)存的TEXTADDR位置上,然后跳轉(zhuǎn)到TEXTADDR位置上,開始內(nèi)核啟動(dòng)。arch/armnommu/Makefile,一般設(shè)置TE