Uboot启动两个阶段

.

Uboot启动两级阶段

第一阶段

  • 流程:
Created with Raphaël 2.2.0Uboot入口ENTRY(_start)构建异常向量表禁止中断,进入ARM状态,SVC模式设置L2、L1cache和MMU识别并暂存启动介质选择第一次设置栈(SRAM)并调用lowlevel_init检查复位状态关看门狗供电锁存判断运行地址决定是否初始化时钟和DDRsystem_clock_init(时钟初始化)mem_ctrl_asm_init(DDR初始化)uart_asm_init(串口初始化并打印'O')pop {pc} (打印'K')第二次设置栈(DDR)判断Uboot是否进行Relocatemovi_bl2_copy使能域访问设置TTB(转换表基地址)使能MMU单元第三次设置栈(DDR)清理BSS段_start_armboot第二阶段

第二阶段

对开发板级别的硬件、软件数据结构进行初始化

  • 代码分析
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    start_armboot // 开始arm的启动
    // Uboot启动地址0x33e00000 Uboot大小2M 堆大小912KB 栈大小512KB 存放全局数据的结构体
    gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
    gd = (gd_t*)gd_base; // 将结构体指针gd实例化(分配空间)
    init_sequence();
    cpu_init(); // 空的,在汇编阶段已经初始化过
    board_init(); // 开发板
    dm9000_pre_init(); // 网卡初始化
    gd->bd->bi_arch_number = MACH_TYPE; // 机器码
    gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100); // 内存传参(启动参数)
    interrupt_init(); // 定时器4,用于计时
    env_init(); // 环境变量初始化
    init_baudrate(); // 软件层gd数据结构波特率初始化
    serial_init(); // 空的,在汇编阶段已经初始化过
    console_init_f(); // 控制台第一步初始化
    display_banner(); // 打印Uboot版本号
    print_cpuinfo(); // 打印SOC时钟频率信息
    checkboard(); // 检验开发板名字
    dram_init(); // 软件层gd数据结构DDR信息初始化
    display_dram_config(); // 打印板上DDR内存大小
    mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE); // 初始化Uboot所维护的堆内存
    mmc_initialize(gd->bd); // 初始化iNand/SD卡 或 SOC上的控制器
    env_relocate (); // 环境变量重定位
    gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); // 初始化软件层gd数据结构IP地址
    gd->bd->bi_enetaddr // 初始化软件层gd数据结构以太网地址
    devices_init (); // 参数传递,没有实现驱动初始化
    jumptable_init (); // 跳转表
    console_init_r (); // 控制台第二步初始化
    enable_interrupts (); // 空的
    loadaddr、bootfile // 内核启动环境变量读出初始化全局变量
    board_late_init (); // 空的
    eth_initialize(gd->bd); // 空的
    x210_preboot_init(); // LCD初始化和显示开机logo
    check_menu_update_from_sd() // 检查自动更新
    main_loop() // 主循环
区别第一阶段第二阶段
语言汇编阶段C阶段
代码所在区域SRAMDRAM
初始化SoC内部SoC外部Board内部

要是觉得不错,就鼓励一下吧!