GT2440--U-Boot分析(三)
2012-08-02 06:07
218 查看
第二阶段:board.c
入口:start_armboot(void)
上述代码为将start_armboot()去除多余不执行的代码的,当start_armboot ()完成一系列的初始化工作之后将进入死循环main_loop中(亦为主循环)。
Main_loop()分析:
对main_loop()进行阅读后,你将会发现其中获取命令之后是通过run_command()这一函数来执行这些指令功能的,因此在对run_command()进行分析。
入口: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()进行分析。
相关文章推荐
- GT2440--U-Boot分析(二)
- GT2440--U-Boot分析(四)
- 基于TQ2440开发板的U-boot-1.1.6的start.S代码分析
- [转贴] u-boot 分析 - <节选> [嵌入式Linux系统开发技术详解-基于ARM]
- jz2440 uboot 移植(顶层Makefile分析)
- 移植u-boot12.04到jz2440 -->支持nandflash启动
- u-boot-2010.06 源码分析<3>--第二阶段
- TQ2440之uboot---6.start.S中relocate部分分析,adr与ldr区别
- <Linux>u-boot 命令分析并编写一个命令
- u-boot2012.04移植到jz2440 -- ->正常显示u-boot启动信息
- <Linux>u-boot启动Linux内核分析
- TQ2440的学习——UBOOT移植(NAND FLASH的支持)——初步分析
- TQ2440 学习笔记—— 31、移植U-Boot【U-Boot 的启动过程第二阶段源码分析】
- 移植u-boot-1.3.4到GT2440(第二版2.0)
- <2012 11 2> U-boot(2)U-boot架构分析与移植重点
- 2440超详细uboot移植笔记(一)------分析源码
- U-Boot启动过程完全分析<转>
- u-boot-2010.06 源码分析<3>--第二阶段
- fl2440——u-boot启动过程的简要分析
- MTD中的nand驱动初步分析---面向u-boot