分享

uboot第二阶段代码分析

 zzjiwang 2014-11-01
start_armboot
        cpu_init //初始化IRQ/FIQ模式的栈
        board_init
                /* 设置时钟 */
                clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
                设置IO管脚
                gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;//机器ID
                gd->bd->bi_boot_params = 0x30000100;//传参的存放地址
                icache_enable()
                dcache_enable();
        interrupt_init //初始化定时器
        env_init        //检查flash上的环境参数是否有效
        init_baudrate //以下三个函数用于初始化串口
        serial_init
        console_init_f
        dram_init  //检测系统内存映射
                gd->bd->bi_dram[0].start = PHYS_SDRAM_1;            //内存起始地址
                gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;  //内存大小
        flash_init //识别norflash并初始化
        nand_init //识别nandflash
        env_relocate //将环境变量读入内存有效位置
        main_loop //根据环境变量启动内核

用图形化具体描述为:

uboot第二阶段代码分析 - 小白 - 小白的博客


我们看到最后启动内核的时候用到u-boot的命令,我们下面来说一下这些命令的格式:
uboot中每个命令都通过U_BOOT_CMD宏来定义,格式如下:
#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
各参数的意义如下:
name:命令的名字,注意,它不是一个字符串(不要用双引号括起来)
maxargs:最大的参数个数
rep:命令是否可重复,可重复是指运行一个命令后,下次敲回车即可再次运行
cmd:对应的函数指针,类型为:*(cmd)(struct cmd_tbl_s *,int, int, char *[])
usage:简短的使用说明,这是个字符串
help:较详细的命令说明

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

比如对于bootm其定义为:
U_BOOT_CMD(
  bootm, CFG_MAXARGS, 1, do_bootm,
  "bootm   - boot application image from memory\n",
  "[addr [arg ...]]\n    - boot application image stored in memory\n"
  "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"
  "\t'arg' can be the address of an initrd image\n"
#ifdef CONFIG_OF_FLAT_TREE
"\tWhen booting a Linux kernel which requires a flat device-tree\n"
"\ta third argument is required which is the address of the of the\n"
"\tdevice-tree blob. To boot that kernel without an initrd image,\n"
"\tuse a '-' for the second argument. If you do not pass a third\n"
"\ta bd_info struct will be passed instead\n"
#endif
);

宏展开就是:
cmd_tbl_t __u_boot_cmd_bootm __attribute__ ((unused,section (".u_boot_cmd")))
{ bootm  CFG_MAXARGS , 1,  do_bootm , string1, string2}
对于每一个用U_BOOT_CMD定义的命令,其实都是在".u_boot_cmd"段中定义一个cmd_tbl_t 结构体,连接脚本里面有如下代码:
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
程序中就是根据命令的名字在__u_boot_cmd_start ~__u_boot_cmd_end 中找到其对应的cmd_tbl_t 结构体,然后调用其函数!

最后我们来总结一下,命令的实现与应用:
我们用U_BOOT_CMD宏定义一个命令,包括命令名、对应的函数,以及说明!定义的这个命令被存放在__u_boot_cmd_start ~__u_boot_cmd_end之间的段里面。
当我们使用命令的时候,就根据命令的名字找到其对应的函数进行操作!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多