ARM體系架構下的linux啟動之一,從bootloader到linux內核
bootloader本身叫做嵌入式系統(tǒng)的引導程序。但是,它支持X86,MIPS,PowerPC,ARM等多種體系架構。
對于操作系統(tǒng)的啟動來講,當機器開始上電時,首先加載bootloader,它用來完成最基本的硬件的初始化,然后加載Linux內核。
用于ARM的bootloader一般為U-BOOT,用它來完成對linux內核的加載設置,一般bootloader燒寫在開發(fā)板的Flash里,包括Nor Flash或Nand Flash,其中由于NorFlash支持芯片內執(zhí)行XIP(eXcute In Place),代碼可以直接在FLASH上執(zhí)行,而NandFlash需要把代碼拷到RAM中再去執(zhí)行。但是RAM的處理速度比Flash的處理速度要快得多,一般仍然把代碼放在RAM中執(zhí)行。
一般的bootloader需要完成以下五種功能:
1)RAM的初始化:為調用linux內核做準備。
2)串口的初始化:由于一般的嵌入式系統(tǒng)開發(fā)板上沒有視頻終端,只能用串口進行開發(fā),串口的初始化非常重要。
3)檢測處理器類型:用來預處理加載內核的處理器類型的傳遞工作。
4)設置Linux的啟動參數(shù):包括加載地址,啟動方式(從本地分區(qū)或NFS進行根文件系統(tǒng)加載),以及Linux根文件系統(tǒng)
的加載方式。通常用一個標記列表來記錄linux內核啟動的各個參數(shù)。
5)調用linux內核鏡像:此時ARM的處理器中的幾個特殊的寄存器值:r0=0,r1=處理器類型,r2=標記列表在RAM中的位置。
2. linux kernel的啟動分析
首先從http://www.kernel.org 上下載一個linux內核的標準版,然后
$make menuconfig
這時你會發(fā)現(xiàn),里面配置的體系架構為X86的,找不到關于ARM配置的相關選項,這時由于當前的內核體系架構與你用于開發(fā)的電腦上的體系架構一模一樣。如果要做ARM架構下的配置:
$make menuconfig ARCH=arm
便可以對ARM體系下的linux內核進行配置操作。
如果需要編譯,還要指定交叉編譯器和體系架構類型。
關于linux的內核一般有兩種映像,一種是非壓縮的映像:Image,另一種是他的壓縮版zImage,在壓縮的鏡像前端還包括了解壓縮的代碼。由于嵌入式系統(tǒng)的存儲空間較小,一般會采用zImage的內核,犧牲速度,但是能得到較小的內核。
Linux內核中zImage的入口程序為arch/arm/boot/compressed/head.S
這個文件主要完成以下工作:
1)開啟MMU和Cache
2)調用decompress_kernel()解壓內核
3)調用call_kernel()進入非壓縮內核Image 的啟動
head.S文件分析:
在113行以上是關于debug的相關代碼和ARM的不同版本的差別。從114行開始,便是函數(shù)的入口:
從這段代碼中可以看出,總共操作的3個寄存器r0,r1,r2正是bootloader調用linux內核時需要操作的3個寄存器。r0寄存器中存放0。然后是r1的CPU類型和r2中的傳入?yún)?shù)列表的指針地址。
評論