1. 程式人生 > >u-boot學習(五):u-boot啟動內核

u-boot學習(五):u-boot啟動內核

cor 定義 嵌入式 code efi cpu 頭文件 ng- part

u-boot的目的是啟動內核。內核位於Flash中,那麽u-boot就要將內核轉移到內存中。然後執行命令執行之。這些操作是由bootcmd命令完畢的。

bootcmd=nand read.jffs2 0x30007FC0 kernel;bootm 0x30007FC0

nand read.jffs2 0x30007FC0 kernel 從Flash讀出內核,kernel代表從kernel分區讀出內核到0x30007FC0。

1、為什麽會用0x30007FC0這麽怪的地址呢,由於真實的內核映像文件是uImage文件。它包括:頭部+真正的內核。而頭部大小正好是64字節。64字節+0x30007FC0正好是0x30008000,這個0x30008000就是真正內核的載入地址,這樣安排。就不用又一次移動內核了。

2、另一個概念就是kernel分區。事實上這是分區的概念,我們在include/configs/100ask24x0.h中將分區寫死,分區的名字並不重要。重要的是起始地址以及分區的大小。

#define MTDPARTS_DEFAULT "mtdparts=nandflash0:[email protected](bootloader),"                             "128k(params),"                             "2m(kernel),"                             "-(root)"
bootm 0x30007FC0命令在讀取完內核後啟動內核,調用do_bootm函數。它有零個作用:

1、依據頭部移動內核到合適的位置(上面分析了,此處不需移動)。

2、啟動do_bootm_linux。它也有兩個作用:告訴內核一些參數,即設置啟動參數;跳到入口地址啟動內核。


Bootloader與內核的交互是單向的。Bootloader將各類參數傳給內核。

因為它們不能同一時候執行。傳遞辦法僅僅有一個:Bootloader將參數放在某個約定的地方後。再啟動內核,內核啟動後從這個地方獲得參數。

除了約定好參數存放的地址外,還要規定參數的結構。內核期望以標記列表的形式來傳遞啟動參數。

標記,就是一種數據結構;標記列表,就是挨著存放的多個標記。標記列表以標記ATAG_CORE開始,以標記ATAG_NONE結束。標記的數據結構為tag,它由一個tag_header結構和一個聯合(union)組成。

tag_header結構表示標記的類型及長度,比方是表示內存還是表示命令行參數等。

對於不同類型的標記使用不同的聯合(union)。比方表示內存時使用tag_mem32。表示命令時使用tag_cmdline。數據結構tag和tag_header定義在inlcude/asm/setup.h頭文件裏。

struct tag_header {
	u32 size;
	u32 tag;
};

struct tag {
	struct tag_header hdr;
	union {
		struct tag_core		core;
		struct tag_mem32	mem;
		struct tag_videotext	videotext;
		struct tag_ramdisk	ramdisk;
		struct tag_initrd	initrd;
		struct tag_serialnr	serialnr;
		struct tag_revision	revision;
		struct tag_videolfb	videolfb;
		struct tag_cmdline	cmdline;

		/*
		 * Acorn specific
		 */
		struct tag_acorn	acorn;

		/*
		 * DC21285 specific
		 */
		struct tag_memclk	memclk;
	} u;
};
能夠利用這些結構設置標記ATAG_CORE、設置內存標記、設置命令行標記、設置標記ATAG_CORE。源代碼中的setup_memory_tags、setup_commadnline_tag函數完畢內存標記和命令標記的設置,一般設置這兩個標記就能夠了。

設置完標記後,最後通過theKernel(0, bd->bi_arch_number, bd->bi_boot_params)調用內核。當中,theKernel指向內核存放的地址(對於ARM架構的CPU。一般是上面提到的0x30008000),bd->bi_arch_number就是第二階段代碼中board_init函數設置的機器類型ID,而bd->bi_boot_params就是標記列表的開始地址。

參考:韋東山 《嵌入式Linux應用開發全然手冊》


u-boot學習(五):u-boot啟動內核