标签:
2016/7/16void board_init_r(gd_t *id, ulong dest_addr)1. board_init_r 函数分析
gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable(); /* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
icache_enable();
dcache_enable(); #ifdef CONFIG_GENERIC_MMC //如果单板支持mmc。只需要在单板文件中定义 CONFIG_GENERIC_MMC 即可
puts("MMC: ");
mmc_initialize(gd->bd);
#endif
/* initialize environment */
if (should_load_env())
env_relocate(); stdio_init(); /* get the devices list going. */ //得到设备清单
/* Initialize the list */
INIT_LIST_HEAD(&(devs.list));
drv_system_init ();
serial_stdio_init (); //主要是串口信息的初始化 jumptable_init(); //跳转表的出初始化,暂时不明白干嘛用的
console_init_r(); /* fully init console as a device */
/* set up exceptions */
interrupt_init();
/* enable exceptions */
enable_interrupts(); //设置中断和使能中断 /* Initialize from environment */
load_addr = getenv_ulong("loadaddr", 16, load_addr); (原值 0x30800000)
eth_initialize(gd->bd) /* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop();
} char *s;
int bootdelay; s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
int strict_strtol s = getenv ("bootcmd"); //获得boot命令
if (bootdelay != -1 && s && !abortboot(bootdelay)) {
run_command_list(s, -1, 0);
}for(;;)
len = readline (CONFIG_SYS_PROMPT);
strcpy (lastcommand, console_buffer);
rc = run_command(lastcommand, flag); char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */ //存储每一个cmd CONFIG_SYS_CBSIZE 256 命令的长度限制在256字节
char *token; /* start of token in cmdbuf */
char *sep; /* end of token (separator) in cmdbuf */
char finaltoken[CONFIG_SYS_CBSIZE];
char *str = cmdbuf; //为后续的while 解析做准备
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
int argc, inquotes;
int repeatable = 1; //命令的可重复性。在中断输入回车是否执行上一条命令
int rc = 0;
clear_ctrlc(); /* forget any previous Control C */ //清楚CTRL+C 中止的命令
if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
puts ("## Command too long!\n");
return -1;
} while (*str) {
/*
* Find separator, or string end
* Allow simple escape of ';' by writing "\;"
*/
for (inquotes = 0, sep = str; *sep; sep++) {
if ((*sep=='\'') &&
(*(sep-1) != '\\'))
inquotes=!inquotes;
if (!inquotes &&
(*sep == ';') && /* separator */
( sep != str) && /* past string start */
(*(sep-1) != '\\')) /* and NOT escaped */
break;
}
token = str;
/* find macros in this token and replace them */
process_macros (token, finaltoken); /* Extract arguments */
if ((argc = parse_line (finaltoken, argv)) == 0) {
rc = -1; /* no command at all */
continue;
}if (cmd_process(flag, argc, argv, &repeatable))
enum command_ret_t rc = CMD_RET_SUCCESS; //一个枚举变量。执行运行状态
enum command_ret_t {
CMD_RET_SUCCESS, /* 0 = Success */
CMD_RET_FAILURE, /* 1 = Failure */
CMD_RET_USAGE = -1, /* Failure, please report 'usage' error */
}; cmd_tbl_t *cmdtp;
struct cmd_tbl_s {
char *name; /* Command Name */ // 命令的查找 find_name 中有(strncmp (cmd, cmdtp->name, len) == 0)
int maxargs; /* maximum number of arguments */
int repeatable; /* autorepeat allowed? */ //命令的可重复性
/* Implementation function */
int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); //函数指针。命令的具体执行 cmd_call 中 result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
char *usage; /* Usage message (short) */ //命令的短 帮助信息 例如:输入help 在命令后边提示的
char *help; /* Help message (long) */ //命令的长帮助信息 例如 bootcmd -help
} . = ALIGN(4);
.u_boot_list : {
_u_boot_list__start = .;
_u_boot_list_cmd__start = .;
*(SORT(.u_boot_list.cmd.*));
_u_boot_list_cmd__end = .;
_u_boot_list_env_clbk__start = .;
*(SORT(.u_boot_list.env_clbk.*));
_u_boot_list_env_clbk__end = .;
*(SORT(.u_boot_list.*));
_u_boot_list__end = .;
} #define ll_entry_declare(_type, _name, _section_u, _section_d) _type _u_boot_list_##_section_u##_##_name __attribute__(( unused, aligned(4), section(".u_boot_list."#_section_d"."#_name))) //find_cmd 函数的具体分析。后续在分析 if (cmdtp == NULL) {
printf("Unknown command '%s' - try 'help'\n", argv[0]);
return 1;
} //如果没有相应的命令则打印提示 Unknown command ‘%s‘ - try ‘help‘\n
/* If OK so far, then do the command */
if (!rc) {
rc = cmd_call(cmdtp, flag, argc, argv);
*repeatable &= cmdtp->repeatable;
} //如果rc 等于 CMD_RET_SUCCESS 。则执行cmd对应的函数result = (cmdtp->cmd)(cmdtp, flag, argc, argv);//执行回调函数
int (*cmd)(struct cmd_tbl_s *, int, int, char * const []);//cmd 函数的原型
#include <common.h>
#include <command.h>
int do_xxx (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
....
return 0;
}
U_BOOT_CMD(
xxx, 1, 0, do_xxx,
"short usage message",
" long usage message"
); # define _CMD_HELP(x) x, //首先这里的宏定义 # 后边有个空格,这样的语法,还需要了解
# define _CMD_COMPLETE(x)
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) { #_name, _maxargs, _rep, _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
==>
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) { #_name, _maxargs, _rep, _cmd, _usage, _help,}
#define ll_entry_declare(_type, _name, _section_u, _section_d) _type _u_boot_list_##_section_u##_##_name __attribute__(( unused, aligned(4), section(".u_boot_list."#_section_d"."#_name)))
==>整理一下形式
#define ll_entry_declare(_type, _name, _section_u, _section_d) _type _u_boot_list_##_section_u##_##_name __attribute__(( unused, aligned(4),section(".u_boot_list."#_section_d"."#_name)))
#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) ll_entry_declare(cmd_tbl_t, _name, cmd, cmd) = U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp);
==》
#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) cmd_tbl_t _u_boot_list_##cmd##_##cmd_tbl_t __attribute__(( unused, aligned(4),section(".u_boot_list."#cmd"."#_name))) { #_name, _maxargs, _rep, _cmd, _usage, _help,}
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
==》
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) cmd_tbl_t _u_boot_list_##cmd##_##cmd_tbl_t __attribute__(( unused, aligned(4),section(".u_boot_list."cmd"."_name))) { #_name, _maxargs, _rep, _cmd, _usage, _help,}
U_BOOT_CMD(
bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,
"boot application image from memory", bootm_help_text
);
==>_name:bootm
_maxargs: CONFIG_SYS_MAXARGS(16)
_rep: 1
_cmd:do_bootm
_usage: "boot application image from memory" //字符串
_help : bootm_help_text //字符串 ==>字符数组的首地址
bootm_help_text:
static char bootm_help_text[] =
"[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"
"\nSub-commands to do part of the bootm sequence. The sub-commands "
"must be\n"
"issued in the order below (it's ok to not issue all sub-commands):\n"
"\tstart [addr [arg ...]]\n"
"\tloados - load OS image\n"
"\tcmdline - OS specific command line processing/setup\n"
"\tbdt - OS specific bd_t processing\n"
"\tprep - OS specific prep before relocation or go\n"
"\tgo - start OS";
}
cmd_tbl_t _u_boot_list_do_bootm_cmd_tbl_t __attribute__(( unused, aligned(4),section(".u_boot_list."do_bootm"."bootm))) { bootm, 16, 1, do_bootm, "boot application image from memory",
"[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"
"\nSub-commands to do part of the bootm sequence. The sub-commands "
"must be\n"
"issued in the order below (it's ok to not issue all sub-commands):\n"
"\tstart [addr [arg ...]]\n"
"\tloados - load OS image\n"
"\tcmdline - OS specific command line processing/setup\n"
"\tbdt - OS specific bd_t processing\n"
"\tprep - OS specific prep before relocation or go\n"
"\tgo - start OS";,} ; //观察这个存储在u_boot_list段中的这个 _u_boot_list_do_bootm_cmd_tbl_t可以知道。这是在定义一个 cmd_tbl_t类型的变量,同时对它进行初始化操作u-boot2013.01 smdk2410 启动第二阶段分析
标签:
原文地址:http://blog.csdn.net/u013377887/article/details/51923560