日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

u-boot向linux内核传递启动参数

發(fā)布時(shí)間:2023/12/10 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 u-boot向linux内核传递启动参数 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
U-BOOT 在啟動(dòng)內(nèi)核時(shí),會(huì)向內(nèi)核傳遞一些參數(shù).而這些參數(shù)是通過(guò) structtag來(lái)傳遞的。 U-boot 把要傳遞給 kernel 的東西保存在 struct tag數(shù)據(jù)結(jié)構(gòu)中,啟動(dòng) kernel 時(shí),把這個(gè)結(jié)構(gòu)體的物理地址傳給 kernelLinux kernel通過(guò)這個(gè)地址分析出u-boot傳遞的參數(shù)。
? ?? 例如u-boot-1.3.4在arm平臺(tái)下,該函數(shù)的實(shí)現(xiàn)位于:lib_arm\Bootm.c文件中.
???在文件中有如下代碼:(可以參照《完全手冊(cè)》的244頁(yè))
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
??? defined(CONFIG_CMDLINE_TAG) || \
??? defined(CONFIG_INITRD_TAG) || \
??? defined(CONFIG_SERIAL_TAG) || \
??? defined(CONFIG_REVISION_TAG) || \
??? defined(CONFIG_LCD) || \
??? defined(CONFIG_VFD)
static void setup_start_tag (bd_t *bd)
{
??? params =(struct tag *) bd->bi_boot_params;

???params->hdr.tag = ATAG_CORE;
???params->hdr.size = tag_size (tag_core);

???params->u.core.flags = 0;
???params->u.core.pagesize = 0;
???params->u.core.rootdev = 0;

??? params =tag_next (params);
}
???上面是初始化tag鏈表(在SDRAM里),最后一句是作為鏈表的最關(guān)鍵部分,它的定義是:
#definetag_next(t)???((struct tag *)((u32 *)(t) +(t)->hdr.size))?作用是指向下一個(gè)tag結(jié)構(gòu)體。
其中 defined (CONFIG_SETUP_MEMORY_TAGS) 和defined (CONFIG_CMDLINE_TAG)是必不可少的。前者是標(biāo)記內(nèi)存的信息,而后者是設(shè)置命令行標(biāo)記(比如“root=/dev/mtdblock2init=/linuxrc console=ttySAC0”)
????/common/cmd_bootm.c文件中, bootm 命令對(duì)應(yīng)的do_bootm函數(shù),當(dāng)分析 uImage 中信息發(fā)現(xiàn) OS Linux 時(shí) 調(diào)用./lib_arm/bootm.c文件中的 do_bootm_linux函數(shù)來(lái)啟動(dòng) Linuxkernel

?????? do_bootm_linux函數(shù)中:

voiddo_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char*argv[],

?????????????????ulong addr, ulong *len_ptr, int verify)

{

......

#if defined(CONFIG_SETUP_MEMORY_TAGS) || \

???defined (CONFIG_CMDLINE_TAG) || \

???defined (CONFIG_INITRD_TAG) || \

???defined (CONFIG_SERIAL_TAG) || \

???defined (CONFIG_REVISION_TAG) || \

???defined (CONFIG_LCD) || \

???defined (CONFIG_VFD)

??????setup_start_tag(bd);?????// 初始化tag 結(jié)構(gòu)體開(kāi)始

#ifdefCONFIG_SERIAL_TAG

??????setup_serial_tag(&params);

#endif

#ifdefCONFIG_REVISION_TAG

??????setup_revision_tag(&params);

#endif

#ifdefCONFIG_SETUP_MEMORY_TAGS

??????setup_memory_tags(bd);?????// 設(shè)置 RAM 參數(shù)

#endif

#ifdefCONFIG_CMDLINE_TAG

??????setup_commandline_tag (bd, commandline);

#endif

#ifdefCONFIG_INITRD_TAG

??????if (initrd_start &&initrd_end)

?????????????setup_initrd_tag (bd, initrd_start,initrd_end);

#endif

#if defined(CONFIG_VFD) || defined (CONFIG_LCD)

??????setup_videolfb_tag ((gd_t *) gd);

#endif

??????setup_end_tag(bd);?????????????// 初始化tag 結(jié)構(gòu)體結(jié)束

#endif

......

......

??????theKernel (0, machid,bd->bi_boot_params);

// 傳給 Kernel 的參數(shù)=(struct tag*) 型的 bd->bi_boot_params

當(dāng)然,有很多的宏來(lái)選擇是否傳遞相應(yīng)的tag到linuxkenel.實(shí)際是這些所以針對(duì)于 bd->bi_boot_params這個(gè)變量.這個(gè)變量是個(gè)整形變量,代表存放所有tag的buffer的地址.
例如,在 smdk2410.c 中的 board_init() 函數(shù)中,對(duì)于這個(gè)變量進(jìn)行了如下賦值:
???
???gd->bd->bi_boot_params = 0x30000100;
0x30000100這個(gè)值可以隨意指定, 但是要保證和內(nèi)核中相應(yīng)的mach_type 一致.以smdk2410為例:
在內(nèi)核中始終這個(gè)值的地方是: arch\arm\mach-s3c2410\mach-smdk2410.c的最后
MACHINE_START(SMDK2410, "SMDK2410")
???
???.phys_ram??? =S3C2410_SDRAM_PA,
???.phys_io??? =S3C2410_PA_UART,
???.io_pg_offst???= (((u32)S3C24XX_VA_UART) >> 18)& 0xfffc,
??? .boot_params???= S3C2410_SDRAM_PA + 0x100,
???.map_io?????? =smdk2410_map_io,
???.init_irq??? =smdk2410_init_irq,
???.timer?????? =&s3c24xx_timer,
MACHINE_END
紅色部分的值, 必須等于0x30000100, 否者將會(huì)出現(xiàn)無(wú)法啟動(dòng)的問(wèn)題.
內(nèi)核啟動(dòng)后,會(huì)讀取0x300000100位置的值, 當(dāng)然,內(nèi)核會(huì)把這個(gè)地址轉(zhuǎn)換成邏輯地址在操作. 因?yàn)閮?nèi)核跑起來(lái)后,MMU已經(jīng)工作,必須要把
0x300000100這個(gè)物理地址轉(zhuǎn)成邏輯地址然后在操作.
對(duì)于u- boot傳給內(nèi)核的參數(shù)中(tag), 內(nèi)核比較關(guān)系memory的信息,比如memory地址的起始,大小等.
如果沒(méi)有得到,那么內(nèi)核無(wú)法啟 動(dòng),內(nèi)核會(huì)進(jìn)入BUG()函數(shù),然后死在那里.
memory的信息是由
CONFIG_SETUP_MEMORY_TAGS宏決定的. 因此當(dāng)這個(gè)宏沒(méi)有被定義時(shí),內(nèi)核跑不起來(lái). 初始化meminfo時(shí)會(huì)失敗.現(xiàn)象就是:?
Starting Kernel ...
死掉.
一般需要定義:
#defineCONFIG_SETUP_MEMORY_TAGS
#defineCONFIG_CMDLINE_TAG

總結(jié)

以上是生活随笔為你收集整理的u-boot向linux内核传递启动参数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。