uboot引导过程

u-boot源代码的目录结构
1、board中存放于开发板相关的配置文件,每一个开发板都以子文件夹的形式出现。
2、Commom文件夹实现u-boot行下支持的命令,每一个命令对应一个文件。
3、cpu中存放特定cpu架构相关的目录,每一款cpu架构都对应了一个子目录。
4、Doc是文档目录,有u-boot非常完善的文档。
5、Drivers中是u-boot支持的各种设备的驱动程序。
6、Fs是支持的文件系统,其中最常用的是JFFS2文件系统。
7、Include文件夹是u-boot使用的头文件,还有各种硬件平台支持的汇编文件,系统配置文件和文件系统支持的文件。

8、lib_xxx与体系结构相关的库文件。如ARM相关的库放在lib_arm目录下。
9、Net是与网络协议相关的代码,bootp协议、TFTP协议、NFS文件系统得实现。
10、Tooles是生成U-boot的工具。

start.S  ->  start_armboot ()   ->   main_loop ()
main_loop()会调用abortboot (bootdelay)判断在delay time内有没有键按下,并给出“Hit any key to stop autoboot”,若没有键按下则run_command (s, 0)(s为默认的bootcmd)。这里默认的bootcmd需要根据内核的位置设置,若bootcmd未赋值,Uboot就会一直等待。如果敲入bootm,也会启动kernel,并且传入参数。如果使用tftp从pc中下载kernel并启动也是可以的。

cpu/arm920t/start.S:(代码就不展开,简单介绍)

.globl _start
_start:    b    start_code                //set the cpu to SVC32 mode
    ldr    pc, _undefined_instruction
    ldr    pc, _software_interrupt
    ldr    pc, _prefetch_abort

...

start_code:            /*set the cpu to SVC32 mode   */

...

relocate:                /* relocate U-Boot to RAM       将uboot复制到ram */

...
stack_setup:         /* Set up the stack         设置程序栈 */

...

ldr    pc, _start_armboot    //执行_start_armboot,第一个C函数

_start_armboot:    .word start_armboot

...

lib_arm/broad.c:

start_armboot 是U-Boot 执行的第一个C 语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。

void start_armboot (void)
{

...

gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

...

/* 顺序执行init_sequence 数组中的初始化函数 */

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang ();
        }
    }

/* initialize environment */
    env_relocate ();

//各种初始化...

...

/* Initialize from environment      通过环境变量初始化 */
    if ((s = getenv ("loadaddr")) != NULL) {
        load_addr = simple_strtoul (s, NULL, 16);
    }

...

/* main_loop()循环不断执行  */

for (;;) {
        main_loop ();
    }

}

init_sequence[]数组保存着基本的初始化函数指针。

init_fnc_t *init_sequence[] = {
  cpu_init,     /* 基本的处理器相关配置 -- cpu/arm920t/cpu.c */
  board_init,     /* 基本的板级相关配置 --board/smdk2410/smdk2410.c */
  interrupt_init,     /* 初始化例外处理 --cpu/arm920t/s3c24x0/interrupt.c */
  env_init,     /* 初始化环境变量 -- common/env_flash.c */
  init_baudrate,  /* 初始化波特率设置 -- lib_arm/board.c */
  serial_init,    /* 串口通讯设置 -- cpu/arm920t/s3c24x0/serial.c*/
  console_init_f,  /* 控制台初始化阶段1 -- common/console.c */
  display_banner, /* 打印u-boot 信息 -- lib_arm/board.c */
  dram_init,         /* 配置可用的RAM --board/smdk2410/smdk2410.c */
  display_dram_config, /* 显示RAM的配置大小 -- lib_arm/board.c */
  NULL,
};
common/main.c:

void main_loop (void)
{

...

install_auto_complete();

s = getenv ("bootdelay");

s = getenv ("bootcmd");

if (bootdelay >= 0 && s && !abortboot (bootdelay)) {

  run_command (s, 0);      //如果延时大于等于零,并且没有在延时过程中接收到按键,则引导内核。

}

}

 

posted @ 2015-01-27 15:25  ht-beyond  阅读(1093)  评论(0编辑  收藏  举报