您的位置:首页 > 其它

GT2440--U-Boot分析(三)

2012-08-02 06:07 218 查看
第二阶段:board.c

入口:start_armboot(void)

typedef int (init_fnc_t) (void);

void start_armboot (void)
{
init_fnc_t **init_fnc_ptr;	/* 用于调用初始化队列下的初始化函数 */
char *s;					/* 指向获取的环境变量 */
#ifndef CFG_NO_FLASH
ulong size;
#endif
/* _armboot_start = _start = TEXT_BASE = 0x33F00000 */
/* TEXT_BASE = 0x33F00000 定义在\u-boot-1.1.6\board\GTStudio\config.mk中 */
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");

memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
/* 计算u-boot monitor的大小 */
monitor_flash_len = _bss_start - _armboot_start;
/* 完成特定平台下的初始化工作 */
/* 注重board_init与dram_init */
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}

#ifndef CFG_NO_FLASH
/* configure available FLASH banks */
/* 调用的flash_init ()是返回值类型为ulong的版本 */
size = flash_init ();
display_flash_config (size);
#endif /* CFG_NO_FLASH */
/* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);

#if (CONFIG_COMMANDS & CFG_CMD_NAND)
//	puts ("NAND:  ");
nand_init();		/* go init the NAND */
#endif

/* initialize environment */
env_relocate ();

/* IP Address */
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

/* MAC Address */
{
int i;
ulong reg;
char *s, *e;
char tmp[64];

i = getenv_r ("ethaddr", tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL;

for (reg = 0; reg < 6; ++reg) {
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
}

devices_init ();	/* get the devices list going. */

jumptable_init ();	/* table init*/

console_init_r ();	/* fully init console as a device */

/* enable exceptions */
enable_interrupts ();
/* usb init	*/
usb_init();

/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_CS8900
cs8900_get_enetaddr (gd->bd->bi_enetaddr);
#endif

/* Initialize from environment */
if ((s = getenv ("loadaddr")) != NULL) {
load_addr = simple_strtoul (s, NULL, 16);
}
#if (CONFIG_COMMANDS & CFG_CMD_NET)
if ((s = getenv ("bootfile")) != NULL) {
copy_filename (BootFile, s, sizeof (BootFile));
}
#endif	/* CFG_CMD_NET */

#if (CONFIG_COMMANDS & CFG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
puts ("Net:   ");
#endif
eth_initialize(gd->bd);
#endif

/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;)
{
main_loop ();
}

/* NOTREACHED - no way out of command loop except booting */
}


上述代码为将start_armboot()去除多余不执行的代码的,当start_armboot ()完成一系列的初始化工作之后将进入死循环main_loop中(亦为主循环)。

Main_loop()分析:

void main_loop (void)
{
#ifndef CFG_HUSH_PARSER
static char lastcommand[CFG_CBSIZE] = { 0, };
int len;
int rc = 1;
int flag;
#endif

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
char *s;
int bootdelay;			//启动系统内核前的倒计时
#endif

#ifdef CONFIG_GTSTUDIO_LOGO
lcd_Init();				//LCD初始化输出
#endif

#ifdef CONFIG_JFFS2_CMDLINE
extern int mtdparts_init(void);
if (!getenv("mtdparts"))
{
run_command("mtdparts default", 0);
}
else
{
mtdparts_init();
}
#endif

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);

s = getenv ("bootcmd");

debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
/* 判断在bootdelay时间段下是否有按键下 */
if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
/* 无按键按下 */
# ifndef CFG_HUSH_PARSER
/* 判断是在nor flash下启动还是在nand flash下启动*/
if (bBootFrmNORFlash())
{
/* nor flash下启动 */
run_command("menu", 0);
}
/*
* Main Loop for Monitor Command Processing
*/
/* nand flash下启动 */
else
{
#ifdef CONFIG_SURPORT_WINCE
/* wince匹配 */
if (!TOC_Read())
{
/* Launch wince */
char cmd_buf[16];
printf("Booting wince ...\n");
strcpy(cmd_buf, "wince");
run_command(cmd_buf, 0);
}
else
#endif
{
printf("Booting Linux ...\n");
/* 调用加载内核函数 */
/*
* boot_zImage(ulong from, size_t size)最终调用
* call_linux(long a0, long a1, long a2)启动内核
*内核启动成功则脱离u-boot
*/
boot_zImage(0x240000,0x300000);
/*也可使用如下方法引导内核加载运行 */
/*
* s = getenv("bootcmd");
* run_command( s, 0);
*/
}
}

}
#endif	/* CONFIG_BOOTDELAY */
/* 在bootdelay时间段下有按键按下 */
run_command("menu", 0);

/*
* Main Loop for Monitor Command Processing
*/

for (;;) {
/* 获取串口下命令的长度 */
len = readline (CFG_PROMPT);

flag = 0;	/* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
else if (len == 0)
flag |= CMD_FLAG_REPEAT;
return;		/* retry autoboot */
}
#endif

if (len == -1)
puts ("<INTERRUPT>\n");
else
rc = run_command (lastcommand, flag);

if (rc <= 0) {
/* invalid command or not repeatable, forget it */
/* 取决于采用的操作系统 */
lastcommand[0] = 0;
}
}
#endif /*CFG_HUSH_PARSER*/
}


对main_loop()进行阅读后,你将会发现其中获取命令之后是通过run_command()这一函数来执行这些指令功能的,因此在对run_command()进行分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: