u-boot2013.01 使用设备树,设备树获得bootargs过程分析

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 相关的fdt
4.
 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,可以用 -代替。                                       

你可能感兴趣的:(u-boot,分析)