u-boot分析3

10 篇文章 0 订阅

转载自:http://blog.csdn.net/delphi308/article/details/6459596

/*这里定义了一个新的数据类型init_fnc_t

 *这个数据类型是参数为空,返回值为int的函数。
 */

typedef int (init_fnc_t) (void);
/*init_sequence是一个指针数组,指向的是init_fnc_t类型的函数*/
init_fnc_t *init_sequence[] = {
    cpu_init, /* basic cpu dependent setup */
    board_init, /* basic board dependent setup */
    interrupt_init, /* set up exceptions */
    env_init, /* initialize environment */
    init_baudrate, /* initialze baudrate settings */
    serial_init, /* serial communications setup */
    console_init_f, /* stage 1 init of console */
    display_banner, /* say that we are here */
    dram_init, /* configure available RAM banks */
    display_dram_config,
#if defined(CONFIG_VCMA9) || defined (CONFIG_CMC_PU2)
    checkboard,
#endif
    NULL,
};

/*init_fnc_ptr为指向函数指针的指针*/
init_fnc_t **init_fnc_ptr;
/*init_fnc_ptr初始化指向init_sequence指针数组,下面的循环遇到NULL结束*/
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
    if ((*init_fnc_ptr)() != 0) {/*(*init_fnc_ptr)()为C中调用指针指向的函数*/
        hang ();
    }

}

转载自:http://blog.csdn.net/toraloo/article/details/7820994

第二阶段的第一部分。smdk2410去掉多余代码后

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. */
	<span style="color:#ff0000;">/*初始化各类外设,如IIC、LCD、键盘、USB等,当然只有在定义了这些外设的前提下,才对这些外设进行初始化。*/</span>
	jumptable_init ();	/* table init*/
        <span style="color:#ff0000;"> /*初始化跳转表gd->jt,该跳转表是一个函数指针数组,它定义了U-Boot中基本的常用函数库*/ </span>
	console_init_r ();	/* fully init console as a device */
	<span style="color:#ff0000;">/* 初始化控制台,即标准输入、标准输出和标准错误,在这里都是串口。 */</span>
	/* 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() 进行分析。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值