u-boot 裝置樹形式擷取bootargs
1. 程式調用過程
do_bootm bootm_start(cmdtp, flag, argc, argv) bootm_load_os(images.os, &load_end, 1) boot_fn = boot_os[images.os.os]; boot_fn(0, argc, argv, &images); do_bootm_linux boot_prep_linux create_fdt(bootm_headers_t *images) ftd_chosen bootargs
2. 詳細分析
do_bootm bootm_start(cmdtp, flag, argc, argv) bootm_load_os(images.os, &load_end, 1) boot_fn = boot_os[images.os.os]; boot_fn(0, argc, argv, &images); do_bootm_linux boot_prep_linux //以上內容。參見上節 #ifdef CONFIG_OF_LIBFDT if (images->ft_len) { debug("using: FDT\n"); if (create_fdt(images)) { printf("FDT creation failed! hanging..."); hang(); } } else #endif //如果使用裝置樹進行傳遞參數,則需要在相應的標頭檔中宏定義 #define CONFIG_OF_LIBFDT ( origen.h (\include\configs) boot_jump_linux
3. create_fdt 分析
static int create_fdt(bootm_headers_t *images) ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; struct lmb *lmb = &images->lmb; ulong rd_len; int ret; boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); //為fdt 保留一塊空間 ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,initrd_start, initrd_end); //ramdisk 設定,暫且不管 ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); //對裝置樹進行重新導向。得到裝置樹的地址 ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); fdt_chosen(*of_flat_tree, 1); // 尋找 chosen node ,如果沒有這個節點則建立 str = getenv("bootargs"); //擷取 啟動參數 err = fdt_setprop(fdt, nodeoffset,"bootargs", str, strlen(str)+1); //將bootargs 設定為裝置樹的屬性 fixup_memory_node(*of_flat_tree); for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { start[bank] = bd->bi_dram[bank].start; size[bank] = bd->bi_dram[bank].size; } //記憶體的首地址和長度 fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS); //修正或者添加 memory node fdt_fixup_ethernet(*of_flat_tree); //和網卡相關的fdt fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); //ramdisk 相關的fdt4.
boot_jump_linux #ifdef CONFIG_OF_LIBFDT if (images->ft_len) r2 = (unsigned long)images->ft_addr; else #endif kernel_entry(0, machid, r2); //傳遞給核心的參數存放的地址,裝置樹的地址。 //在為使用裝置樹之前,使用的 gd->bd->bi_boot_params;即0x30001000 這個地址
參考文獻:
http://blog.csdn.net/xy010902100449/article/details/46918145
Uboot mainline 從 v1.1.3開始支援Device Tree,其對ARM的支援則是和ARM核心支援Device Tree同期完成。
為了使能Device Tree,需要編譯Uboot的時候在config檔案中加入#define CONFIG_OF_LIBFDT
在Uboot中,可以從NAND、SD或者TFTP等任意介質將.dtb讀入記憶體,假設.dtb放入的記憶體位址為0x71000000,之後可在Uboot運行命令fdt addr命令設定.dtb的地址,如:
U-Boot> fdt addr 0x71000000
fdt的其他命令就變地可以使用,如fdt resize、fdt print等。
對於ARM來講,可以透過bootz kernel_addr initrd_address dtb_address的命令來啟動核心,即dtb_address作為bootz或者bootm的最後一次參數,第一個參數為核心映像的地址,第二個參數為initrd的地址,若不存在initrd,可以用 -代替。