|
u-boot 第一阶段启动流程:http://www.amobbs.com/thread-5595629-1-1.html
详细请看:http://m18271260665.blog.163.com/
首先还是来一张图片大致看一下第二阶段完成的任务:
在第一阶段start.S的最后有这样一句代码:
ldr pc, _start_armboot @ jump to C code
当第一阶段的全部任务完成之后,就会调到_start_armboot 处开始执行第二阶段的代码,这里的_start_armboot 是一个标签,是函数void start_armboot (void)的首地址。这个函数在/lib_arm/board.c中。接下来就是按照上图中的步骤开始一步一步进行。
同样,board.c中,也用到了很多的条件编译,这里把没用编译的都去掉了,方便阅读,精简后的代码如下:
- typedef struct environment_s {
- uint32_t crc; /* CRC32 over data bytes */
- unsigned char flags; /* active/obsolete flags */
- unsigned char data[ENV_SIZE]; /* Environment data */
-
- } env_t;
-
- typedef struct bd_info {
- //串口通讯波特率
- int bi_baudrate; /* serial console baudrate */
- //IP 地址
- unsigned long bi_ip_addr; /* IP Address */
- //环境变量起始地址
- struct environment_s *bi_env;
- //开发板的机器码
- ulong bi_arch_number; /* unique id for this board */
- //uboot传递给内核参数的起始地址
- ulong bi_boot_params; /* where this board expects params */
- //内存信息
- struct /* RAM configuration */
- {
- ulong start;//内存的起始地址
- ulong size;//内存大小
- }bi_dram[1];
- } bd_t;
-
- typedef struct global_data {
- bd_t *bd;
- unsigned long flags; //uboot是否重定向的标志
- //串口波特率
- unsigned long baudrate;
- //是否有一个控制台标志
- unsigned long have_console; /* serial_init() was called */
- //环境变量所在的地址
- unsigned long env_addr; /* Address of Environment struct */
- //环境变量是否有效
- unsigned long env_valid; /* Checksum of Environment valid? */
- unsigned long fb_base; /* base address of frame buffer */
- void **jt; /* jump table */
- } gd_t;
-
-
- typedef int (init_fnc_t) (void);
- register volatile gd_t *gd asm ("r8");
- ulong monitor_flash_len;
-
- init_fnc_t *init_sequence[] = {
- //初始化CPU相关设置:系统时钟操作函数
- arch_cpu_init, /* basic arch cpu dependent setup */
- //初始化开发板相关设置:开发板的机器码
- board_init, /* basic board dependent setup */
- //初始化定时器
- timer_init, /* initialize timer */
- //初始化环境变量
- env_init, /* initialize environment */
- //初始化波特率
- init_baudrate, /* initialze baudrate settings */
- //串口初始化
- serial_init, /* serial communications setup */
- //控制台设备一级初始化
- console_init_f, /* stage 1 init of console */
- //打印u-boot版本、编译时间
- display_banner, /* say that we are here */
-
- //打印CPU类型和当前运行频率
- print_cpuinfo, /* display cpu info (and speed) */
-
- //打印开发板名称
- checkboard, /* display board info */
-
- //配置可用的内存
- dram_init, /* configure available RAM banks */
- //显示当前内存大小
- display_dram_config,
- NULL,
- };
-
- void start_armboot (void)
- {
- init_fnc_t **init_fnc_ptr;
- char *s;
-
-
- /* Pointer is writable since we allocated a register for it
- * _armboot_start :0x20f00044
- * CONFIG_SYS_MALLOC_LEN:0x120000
- * sizeof(gd_t) :0x40 [64byte]
- *
- * gd : 0x20de0004
- */
- gd = (gd_t*)(_armboot_start - CONFIG_SYS_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 :0x20de0004 - 0x38 = 0x20ddffcc
- gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
- memset (gd->bd, 0, sizeof (bd_t));
-
- gd->flags |= GD_FLG_RELOC;
-
- //uboot去掉bss段的大小
- monitor_flash_len = _bss_start - _armboot_start;
-
- //外围硬件初始化
- for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
- if ((*init_fnc_ptr)() != 0) {
- hang ();
- }
- }
-
- //将堆区初始化为0
- /* armboot_start is defined in the board-specific linker script */
- mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
- CONFIG_SYS_MALLOC_LEN);
-
-
- puts ("NAND: ");
-
- //NAND FALSH 初始化
- nand_init(); /* go init the NAND */
-
- /*读取Nand Flash的环境变量,然后做CRC校验,如果错误则使用默认的环境变量*/
- env_relocate ();
-
- /*获得IP 地址*/
- gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
-
- //初始化输入、输出设备列表
- stdio_init (); /* get the devices list going. */
-
-
- jumptable_init ();
-
- //初始化标准输入、输出、出错
- console_init_r (); /* fully init console as a device */
-
- /* 使能IRQ异常 */
- enable_interrupts ();
-
- /* Initialize from environment */
- if ((s = getenv ("loadaddr")) != NULL) {
- load_addr = simple_strtoul (s, NULL, 16);
- }
-
- //初始化网卡设备
- eth_initialize(gd->bd);
-
- /* 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 */
- }
-
-
- void hang (void)
- {
- puts ("### ERROR ### Please RESET the board ###\n");
- for (;;);
- }
复制代码
相关的初始化完成之后,会进入到main_loop ();
- void main_loop (void)
- {
- char *s;
- int bootdelay;
-
- u_boot_hush_start ();
-
- 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>");
-
- if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
-
- parse_string_outer(s, FLAG_PARSE_SEMICOLON |
- FLAG_EXIT_FROM_LOOP);
-
- /*
- * Main Loop for Monitor Command Processing
- */
- parse_file_outer();
- /* This point is never reached */
- for (;;);
- }
-
- static __inline__ int abortboot(int bootdelay)
- {
- int abort = 0;
-
- printf("Hit any key to stop autoboot: %2d ", bootdelay);
-
- /*
- * Check if key already pressed
- * Don't check if bootdelay < 0
- */
- 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 */
- }
- }
-
- while ((bootdelay > 0) && (!abort)) {
- int i;
-
- --bootdelay;
- /* delay 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);
- }
-
- printf("\b\b\b%2d ", bootdelay);
- }
-
- putc('\n');
-
- return abort;
- }
复制代码
最后bootcmd这条命令设置为引导内核气动就OK了。。。
u-boot 第一阶段启动流程:http://www.amobbs.com/thread-5595629-1-1.html
详细请看:http://m18271260665.blog.163.com/
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
|