加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

GT2440--U-Boot分析(三)

发布时间:2020-12-15 18:34:52 所属栏目:百科 来源:网络整理
导读:第二阶段: 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_FLASHulong size;#endif/*

第二阶段: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.6boardGTStudioconfig.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,sizeof (gd_t));
	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
	memset (gd->bd,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,10) : CONFIG_BOOTDELAY;

	debug ("### main_loop entered: bootdelay=%dnn",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()进行分析。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读