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 //根据环境变量启动内核 用图形化具体描述为: 我们看到最后启动内核的时候用到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之间的段里面。 当我们使用命令的时候,就根据命令的名字找到其对应的函数进行操作! |
|
来自: zzjiwang > 《uboot第二阶段》