uboot向linux內(nèi)核傳遞啟動參數(shù)_第1頁
uboot向linux內(nèi)核傳遞啟動參數(shù)_第2頁
uboot向linux內(nèi)核傳遞啟動參數(shù)_第3頁
uboot向linux內(nèi)核傳遞啟動參數(shù)_第4頁
uboot向linux內(nèi)核傳遞啟動參數(shù)_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、u-boot向linux內(nèi)核傳遞啟動參數(shù)(詳細)U-BOOT在啟動內(nèi)核時,會向內(nèi)核傳遞一些參數(shù).BootLoader可以通過兩種方法傳遞參數(shù)給內(nèi)核,一種是舊的參數(shù)結(jié)構(gòu)方式(parameter_struct),主要是2.6之前的內(nèi)核使用的方式。另外一種就是現(xiàn)在的2.6內(nèi)核在用的參數(shù)鏈表(taggedlist)方式。這些參數(shù)主要包括,系統(tǒng)的根設(shè)備標志,頁面大小,內(nèi)存的起始地址和大小,RAMDISK的起始地址和大小,壓縮的RAMDISK根文件系統(tǒng)的起始地址和大小,當(dāng)前內(nèi)核命令參數(shù)等而這些參數(shù)是通過structtag來傳遞的。U-boot把要傳遞給kernel的東西保存在structtag數(shù)據(jù)結(jié)構(gòu)中,

2、啟動kernel時,把這個結(jié)構(gòu)體的物理地址傳給kernel;Linuxkernel通過這個地址分析出u-boot傳遞的參數(shù)。大家都知道U-Boot啟動的時候會將啟動參數(shù)的地址放入R2中,然后再啟動內(nèi)核。首先看兩個重要的數(shù)據(jù)結(jié)構(gòu):第一個是global_data,定義在include/asm-arm/global_data.h文件中:typedefstructglobal_databd_t*bd;unsignedlongflags;unsignedlongbaudrate;unsignedlonghave_console;/*serial_init()wascalled*/unsignedlong

3、reloc_off;/*RelocationOffset*/unsignedlongenv_addr;/*AddressofEnvironmentstruct*/unsignedlongenv_valid;/*ChecksumofEnvironmentvalid?*/unsignedlongfb_base;/*baseaddressofframebuffer*/#ifdefCONFIG_VFDunsignedcharvfd_type;/*displaytype*/#endif#if0unsignedlongcpu_clk;/*CPUclockinHz!*/unsignedlongbus_clk

4、;unsignedlongram_size;/*RAMsize*/unsignedlongreset_status;/*resetstatusregisteratboot*/#endifvoid*jt;/*jumptable*/gd_t;在同一個文件中有如下定義:#defineDECLARE_GLOBAL_DATA_PTRregistervolatilegd_t*gdasm(r8)在需要使用gd指針的時候,只需要加入DECLARE_GLOBAL_DATA_PTR這句話就可以了??梢灾?,gd指針始終是放在r8中的。其中的第一個變量,bd_t結(jié)構(gòu)體,定義于include/asm-arm/u-bo

5、ot.h中:typedefstructbd_infointbi_baudrate;/*serialconsolebaudrate*/unsignedlongbi_ip_addr;/*IPAddress*/unsignedcharbi_enetaddr6;/*Ethernetadress*/structenvironment_s*bi_env;ulongbi_arch_number;/*uniqueidforthisboard*/ulongbi_boot_params;/*wherethisboardexpectsparams*/struct/*RAMconfiguration*/ulongst

6、art;ulongsize;bi_dramCONFIG_NR_DRAM_BANKS;#ifdefCONFIG_HAS_ETH1/*secondonboardethernetport*/unsignedcharbi_enet1addr6;#endifbd_t;bd_t中的變量bi_boot_params,表示傳遞給內(nèi)核的參數(shù)的位置。然后看看gd和bd的初始化,在lib_arm/board.c中:gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-sizeof(gd_t);memset(void*)gd,0,sizeof(gd_t);gd-bd=(bd_t*)(cha

7、r*)gd-sizeof(bd_t);memset(gd-bd,0,sizeof(bd_t);說明這兩個結(jié)構(gòu)體在內(nèi)存中的位置是在uboot的代碼在往下的地址處,所以進行操作的時候不要覆蓋了這個位置!在board/smdk2410/smdk2410.c中,有如下初始化:gd-bd-bi_boot_params=0 x30000100;說明參數(shù)位置在0 x30000100?,F(xiàn)在,具體看看uboot是如何(按什么格式)把參數(shù)放入內(nèi)存中。內(nèi)核參數(shù)鏈表的格式和說明可以從內(nèi)核源代碼目錄樹中的include/asm-arm/setup.h中找到,參數(shù)鏈表必須以ATAG_CORE開始,以ATAG_NONE結(jié)束

8、。這里的ATAG_CORE,ATAG_NONE是各個參數(shù)的標記,本身是一個32位值,例如:ATAG_CORE=Ox5441OOO1。其它的參數(shù)標記還包括:ATAG_MEM32,ATAG_INITRD,ATAG_RAMDISK,ATAG_COMDLINE等。每個參數(shù)標記就代表一個參數(shù)結(jié)構(gòu)體,由各個參數(shù)結(jié)構(gòu)體構(gòu)成了參數(shù)鏈表。參數(shù)結(jié)構(gòu)體的定義如下:structtagstructtag_headerhdr;unionstructtag_corecore;structtag_mem32mem;structtag_videotextvideotext;structtag_ramdiskramdisk;st

9、ructtag_initrdinitrd;structtag_serialnrserialnr;structtag_revisionrevision;structtag_videolfbvideolfb;structtag_cmdlinecmdline;structtag_acornacorn;structtag_memclkmemclk;u;參數(shù)結(jié)構(gòu)體包括兩個部分,一個是tag_header結(jié)構(gòu)體,一個是u聯(lián)合體。tag_header結(jié)構(gòu)體的定義如下:structtag_headeru32size;u32tag;其中size:表示整個tag結(jié)構(gòu)體的大小(用字的個數(shù)來表示,而不是字節(jié)的個數(shù)),

10、等于tag_header的大小加上u聯(lián)合體的大小,例如,參數(shù)結(jié)構(gòu)體ATAG_CORE的size=(sizeof(tag-tag_header)+sizeof(tag-u.core)2,般通過函數(shù)tag_size(struct*tag_xxx)來獲得每個參數(shù)結(jié)構(gòu)體的size。其中tag:表示整個tag結(jié)構(gòu)體的標記,如:ATAG_CORE等。聯(lián)合體u包括了所有可選擇的內(nèi)核參數(shù)類型,包括:tag_core,tag_mem32,tag_ramdisk等。參數(shù)結(jié)構(gòu)體之間的遍歷是通過函數(shù)tag_next(struct*tag)來實現(xiàn)的。本系統(tǒng)參數(shù)鏈表包括的結(jié)構(gòu)體有:ATAG_CORE,ATAG_MEM,A

11、TAG_RAMDISK,ATAG_INITRD32,ATAG_CMDLINE,ATAG_END。在整個參數(shù)鏈表中除了參數(shù)結(jié)構(gòu)體ATAG_CORE和ATAG_END的位置固定以外,其他參數(shù)結(jié)構(gòu)體的順序是任意的。本BootLoader所傳遞的參數(shù)鏈表如下:第一個內(nèi)核參數(shù)結(jié)構(gòu)體,標記為ATAG_CORE,參數(shù)類型為tag_core。每個參數(shù)類型的定義請參考源代碼文件。我們知道u-boot傳遞給內(nèi)核的參數(shù)有很多個,如系統(tǒng)的根設(shè)備標志,頁面大小,內(nèi)存的起始地址和大小,RAMDISK的起始地址和大小,壓縮的RAMDISK根文件系統(tǒng)的起始地址和大小等,而每個參數(shù)我們都是單獨的采用一個structtag來標識

12、的,之前提到的參數(shù)標記如ATAG_MEM32,ATAG_INTRD等就是用來標識該tag結(jié)構(gòu)是用來存放的哪種類型的參數(shù)。由于不同類型的參數(shù)傳遞的信息內(nèi)容也不盡相同,為了綜合不同參數(shù)的tag結(jié)構(gòu),所以在structtag結(jié)構(gòu)中定義了一個聯(lián)合體union,根據(jù)不同的參數(shù)標記符來選擇聯(lián)合體中不同的結(jié)構(gòu)體來存儲參數(shù)的內(nèi)容,如參數(shù)標記若為ATAG_MEM32,則聯(lián)合體中采用structtag_mem32來存儲內(nèi)存參數(shù)的內(nèi)容。然而內(nèi)核是如何從gd-bd-bi_boot_params指定的地址上知道參數(shù)從哪里開始以及到哪里結(jié)束呢?所以我們在構(gòu)建各種參數(shù)tag時,在開始時先要構(gòu)建一個參數(shù)標記為ATAG_COR

13、E的tag結(jié)構(gòu)標示從這個tag結(jié)構(gòu)開始接下來就是參數(shù)現(xiàn)來結(jié)合代碼分析在u-boot中是如何來構(gòu)建這多個參數(shù)的tag結(jié)構(gòu):/common/cmd_bootm.c文件中,bootm命令對應(yīng)的do_bootm函數(shù),當(dāng)分析ulmage中信息發(fā)現(xiàn)OS是Linux時,調(diào)用./lib_arm/bootm.c文件中的do_bootm_linux函數(shù)來啟動Linuxkernel。#ifdefined(CONFIG_SETUP_MEMORY_TAGS)|defined(CONFIG_CMDLINE_TAG)|defined(CONFIG_INITRD_TAG)|defined(CONFIG_SERIAL_TAG)

14、|defined(CONFIG_REVISION_TAG)|defined(CONFIG_LCD)|defined(CONFIG_VFD)setup_start_tag(bd);/通過bd結(jié)構(gòu)體中參數(shù)在內(nèi)存中的存放地址gd-bd-bi_boot_params來構(gòu)建初始化的tag結(jié)構(gòu),表明參數(shù)結(jié)構(gòu)的開始#ifdefCONFIG_SERIAL_TAGsetup_serial_tag(¶ms);/構(gòu)建串口參數(shù)的tag結(jié)構(gòu)#endif#ifdefCONFIG_REVISION_TAGsetup_revision_tag(¶ms);#endif#ifdefCONFIG_SETUP_MEM

15、ORY_TAGSsetup_memory_tags(bd);/構(gòu)建內(nèi)存參數(shù)的tag結(jié)構(gòu)#endif#ifdefCONFIG_CMDLINE_TAGsetup_commandline_tag(bd,commandline);/構(gòu)建命令行參數(shù)的tag結(jié)構(gòu)#endif#ifdefCONFIG_INITRD_TAGif(initrd_start&initrd_end)setup_initrd_tag(bd,initrd_start,initrd_end);/構(gòu)建ramdisk參數(shù)的tag結(jié)構(gòu)#endif#ifdefined(CONFIG_VFD)|defined(CONFIG_LCD)setup_vi

16、deolfb_tag(gd_t*)gd);#endifsetup_end_tag(bd);/最后是構(gòu)建參數(shù)tag結(jié)構(gòu)結(jié)束的tag結(jié)構(gòu),標示參數(shù)已經(jīng)結(jié)束,參數(shù)標記為ATAG_NONE#endif注意上面參數(shù)的tag結(jié)構(gòu)的構(gòu)建是有宏的約束的,再來看看具體是怎樣構(gòu)建每個tag結(jié)構(gòu)的:#ifdefined(CONFIG_SETUP_MEMORY_TAGS)|defined(CONFIG_CMDLINE_TAG)|defined(CONFIG_INITRD_TAG)|defined(CONFIG_SERIAL_TAG)|defined(CONFIG_REVISION_TAG)|defined(CONFI

17、G_LCD)|defined(CONFIG_VFD)staticvoidsetup_start_tag(bd_t*bd)params=(structtag*)bd-bi_boot_params;/將指定的內(nèi)存中存放參數(shù)列表的地址強制轉(zhuǎn)化為structtag的結(jié)構(gòu),這樣便于內(nèi)核存取各個參數(shù)params-hdr.tag=ATAG_CORE;/標示這個tag結(jié)構(gòu)是用來標示參數(shù)結(jié)構(gòu)的開始params-hdr.size二tag_size(tag_core);/存放整個tag結(jié)構(gòu)的大小params-u.core.flags=0;params-u.core.pagesize=0;params-u.core.

18、rootdev=0;params=tag_next(params);其中用到了一個重要的指針:params,這是一個指向structtag的指針,在文件的開始處聲明,可以被這個文件中的所有函數(shù)訪問:staticstructtag*params;tag和tag_header和內(nèi)核中的結(jié)構(gòu)一模一樣。tag_header中的tag字段表示的是這個tag的類型,在內(nèi)核和Bootloader中通過一些固定的整形常量來表示:#defineATAG_CORE0 x54410001#defineATAG_NONE0 x00000000#defineATAG_CORE0 x54410001#defineATAG

19、_MEM0 x54410002#defineATAG_VIDEOTEXT0 x54410003#defineATAG_RAMDISK0 x54410004#defineATAG_INITRD0 x54410005#defineATAG_INITRD20 x54420005#defineATAG_SERIAL0 x54410006#defineATAG_REVISION0 x54410007#defineATAG_VIDEOLFB0 x54410008#defineATAG_CMDLINE0 x54410009#defineATAG_ACORN0 x41000101#defineATAG_MEM

20、CLK0 x41000402上面是初始化tag鏈表(在SDRAM里),最后一句是作為鏈表的最關(guān)鍵部分,它的定義是:#definetag_next(t)(structtag*)(u32*)(t)+(t)-hdr.size)作用是指向下一個tag結(jié)構(gòu)體。一般在每個參數(shù)的tag結(jié)構(gòu)體的最后都要調(diào)用這個宏,內(nèi)核在遇到這個宏就可以直接跳轉(zhuǎn)到下一個參數(shù)tag結(jié)構(gòu)體的地址上來存取。再來看看其他參數(shù)種類的tag結(jié)構(gòu)的構(gòu)建#ifdefCONFIG_SETUP_MEMORY_TAGSstaticvoidsetup_memory_tags(bd_t*bd)inti;for(i=0;ihdr.tag=ATAG_MEM

21、;params-hdr.size=tag_size(tag_mem32);params-u.mem.start=bd-bi_drami.start;params-u.mem.size=bd-bi_drami.size;params=tag_next(params);其中defined(CONFIG_SETUP_MEMORY_TAGS)和defined(CONFIG_CMDLINE_TAG)是必不可少的。前者是標記內(nèi)存的信息,而后者是設(shè)置命令行標記(比如root=/dev/mtdblock2init=/linuxrcconsole=ttySACO”)到最后可以看到調(diào)用:theKernel(0,machid,bd-bi_boot_params);當(dāng)然,有很多的宏來選擇是否傳遞相應(yīng)的tag到linuxkenel.實際是這些所以針對于bd-bi_boot_params這個變量.這個變量是個整形變量,代表存放所有tag的buffer的地址.例如,在smdk2410.c中的board_init()函數(shù)中,對于這個變量進行了如下賦值:gd-bd-bi_boot_params=0 x30000100;0 x30000100這個值可以隨意指定,但是要保證和內(nèi)核中相應(yīng)的mach_type致.以smdk2410為例:在內(nèi)核中始終這

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論