设为首页 加入收藏

TOP

uboot中main_loop分析(二)
2014-11-24 13:57:54 来源: 作者: 【 】 浏览:2
Tags:uboot main_loop分析
cmd_tbl_t;

extern cmd_tbl_t __u_boot_cmd_start;
extern cmd_tbl_t __u_boot_cmd_end;

#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 U_BOOT_CMD_MKENT(name,maxargs,rep,cmd,usage,help) /
{#name, maxargs, rep, cmd, usage, help}

uboot中的命令使用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 分别对应命令结构体在内存中开始和结束的地址。

3。abortboot函数的分析
abortboot是uboot在引导期间的延时函数。期间可以按键进入uboot的命令行。
common/main.c
static __inline__ int abortboot(int bootdelay)
{
int abort = 0;
printf("Hit any key to stop autoboot: %2d ", bootdelay);

#if defined CONFIG_ZERO_BOOTDELAY_CHECK //如果定义了这个宏,即使定义延时为0,也会检查一次是否有按键按下。只要在这里执行之前按键,还是能进入uboot的命令行。
if (bootdelay >= 0) {
if (tstc()) { /* we got a key press */ 测试是否有按键按下
(void) getc(); /* consume input */接收按键值
puts ("/b/b/b 0");
abort = 1; /* don't auto boot */修改标记,停止自动引导
}
}
#endif

while ((bootdelay > 0) && (!abort)) { //如果延时大于零并且停止标记没有赋值则进入延时循环,直到延时完或者接收到了按
int i;

--bootdelay;
/* delay 100 * 10ms */ 每秒中测试按键100次,之后延时10ms。
for (i=0; !abort && i<100; ++i) {
if (tstc()) { /* we got a key press */
abort = 1; /* don't auto boot */*/修改标记,停止自动引导
bootdelay = 0; /* no more delay */延时归零
(void) getc(); /* consume input */获取按键
break;
}
udelay(10000);//延时10000us,也就是10ms
}

printf("/b/b/b%2d ", bootdelay);//打印当前剩余时间
}

putc('/n');
return abort;//返回结果:1-停止引导,进入命令行; 0-引导内核。
}

可以看到uboot延时的单位是秒,如果想提高延时的精度,比如想进 10ms级的延时,将udelay(10000)改为udelay(100)就可以了

4。引导命令
include/configs/smartarm.h

#define CONFIG_BOOTCOMMAND "run yboot "
#define CONFIG_EXTRA_ENV_SETTINGS /
"serverip=192.168.1.110/0" /
"gatewayip=192.168.1.254/0" /
"ipaddr=192.168.1.164/0" /
"bootfile=uImage/0"/
/
"upkernel=" "tftp 80008000 uImage;"/
"nand erase clean 0x00200000 $(filesize);"/
"nand write.jffs2 0x80008000 0x00200000 $(filesize);"/
"setenv kernelsize $(filesize); saveenv/0"/
/
"upsafefs=" "tftp 80008000 safefs.cramfs;"/
"nand erase clean 0x00600000 $(filesize);"/
"nand write.jffs2 0x80008000 0x00600000 $(filesize)/0"/
/
"yboot=" "nand read.jffs2 0x81000000 0x00200000 $(filesize);"/
"bootm 81000000/0"/

/
"safemode=" "setenv bootargs root=/dev/mtdblock3 console=ttyS0,115200, mem=64M rootfstype=cramfs; run yboot/0"/
/
"zhiyuan=" "run upsafefs; run upkernel/0"

可见,引导内核其实就是将内核读取到内存中然后再跳到那个地方引导。

5。run_command
common/main.c
int run_command (const char *cmd, int flag)
{
cmd_tbl_t *cmdtp;
char cmdbuf[CONFIG_SYS_CBSIZE]; /* working copy of cmd */
char *token; /* start of token in cmdbuf */
char *sep; /* end of token (separator) in cmdbuf */
char finaltoken[CONFIG_SYS_CBSIZE];
char *str = cmdbuf;
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
int argc, inquotes;
int repeatable = 1;
int rc = 0;

clear_ctrlc(); /* forget a
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇uboot分析之bootm_start 下一篇汇编告诉你为什么C++可以对函数重..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: