6200uboot启动过程
注:PC此时跳到0x42800000处开始执行。
在这启动过程中主要包括系统信息采集(CPU信息、MAC、外设信息),配置一些系统模块正常工作,DDR2地址重映射(由0X40000000映射到0X00000000),今天阅读的Uboot_6200代码没有做PC重置,原来在Uboot_1.3.3版的代码会涉及到中断向量表搬移(从Norflash搬至ESRAM,以及PC重置)。
主要记录下今天阅读的uboot自启动下遇到的一个问题)。在void start_unicoreboot(void)最后会执行main_loop(),进入函数后,获取默认启动过程,同时延迟一段时间,调试人员按键以执行部分调试功能,该boot设置时间为3秒左右。当没有按键触发时,将继续执行。今天阅读的主要问题出在获取默认启动参数:
s 为char型指针,通过char *getenv(char *name)传入”bootcmd”字符串来获取参数并赋予s。内部调用env_get_char(nxt)来检测参数是否已存在,以及参数个数是否在范围内。确定一般要求后,检测参数开头是否匹配,匹配后返回参数地址。而后在调用其他参数进行参数解析,
由解析出的第一个参数(即命令名)来获取所在结构体地址,而该结构体cmd_tbl_t则预设了对于该命令即其他解析出来的参数做出适当的处理(该boot中参数为”bootcmd=bootm 0X40000000,注意该一定是不对的,因为PC起始为0x42800000……我没有获得完整的版本,但是通过对0x40000000修改及连接脚本和./board/prochip/SEP611/config.mk中的TEXT_BASE的修改是可以改正的)。问题在于那个参数所在的数组使我从开始做了错误的分析,
uchar default_environment[] =
{
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\0"
#endif
};
对于uboot_cmd_cfg的嵌入还有一点不理解,
#define Struct_Section __attribute__ ((unused,section,”u_boot_cmd”)).
其次
#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}
以及cmd_tbl_t的构成。
做下整理
阅读下链接脚本u-boot.lds:
section定义了:
__u_boot_cmd_start=.;
.u_boot_cmd:{*(.u_boot_cmd)}
__u_boot_cmd_end=.;
这说明编译的u_boot_cmd段被存放于该处(由__u_boot_cmd_start及__u_boot_cmd_end界定)
声明类型:
struct cmd_tbl_s
{
char *name; /* Command Name */
int maxargs; /* maximum number of arguments */
int repeatable; /* autorepeat allowed? */
/* Implementation function */
int (*cmd)(struct cmd_tbl_s *, int, int, char *[]);
char *usage; /* Usage message (short) */
#ifdef CFG_LONGHELP
char *help; /* Help message (long) */
#endif
#ifdef CONFIG_AUTO_COMPLETE
/* do auto completion on the arguments */
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cm
dv[]);
#endif
};
typedef struct cmd_tbl_s cmd_tbl_t;
重要的是下面的宏定义
#define Struct_Section __attribute__ ((unused,section,”u_boot_cmd”)).
第一次遇到这种定义,应该和编译器相关,对于这部分知识了解不多,应该是说明:
该段存放于u_boot_cmd段处,且其他部分不得占用该空间。
#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}
这是一个宏定义,涉及到##和#运算符。
看如下一个变量的定义就很清楚了:
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"
);
函数定义:
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
120 {
121 ulong iflag;
122 const char *type_name;
123 uint unc_len = CFG_BOOTM_LEN;
124 uint8_t comp, type, os;
………………………………………………………………
}
下面就开始涉及到搬运即解压内核了(bootm 0x40000000)