uboot两阶段代码分析
1、启动过程特征总结
(1)第一阶段为汇编阶段(start.s)、第二阶段为C阶段(board.c中的start_armboot 函数)
(2)第一阶段在SRAM中、第二阶段在DRAM中
(3)第一阶段注重SoC内部、第二阶段注重SoC外部Board内部
2、移植时的注意点
(1)x210_sd.h头文件中的宏定义
(2)特定硬件的初始化函数位置(譬如网卡)
start.s分析
主要功能分析
头文件包含 -28-
启动代码的16字节头部占位 -49-
(1)构建异常向量表 -58- (2)设置CPU为SVC模式 -149-
设置L2、L1cache和MMU -216-
启动方式读取 -224-
设置栈(SRAM中的栈) -280-(在sram中设置的栈)
跳到lowlevel_init.S中执行lowlevel_init -288- (3)关看门狗 lowlevel_init.S(-61-) (4)开发板供电置锁 lowlevel_init.S(100-104)
判断当前代码执行位置 lowlevel_init.S(110-115)
(5)时钟初始化 lowlevel_init.S(-118-) 配置值在x210_sd.h中
(6)DDR初始化 lowlevel_init.S(-121-)
(7)串口初始化并打印"OK" lowlevel_init.S(-125-)
(8)重定位 -349-
(9)建立映射表并开启MMU -360-
再次设置栈(ddr中) -386-
清bss -400-
(10)跳转到第二阶段 -441-
其中lowlevel_init.S中总共做了哪些事情:
检查复位状态、IO恢复、关看门狗、开发板供电锁存、时钟初始化、DDR初始化、串口初始化并打印'O'、tzpc初始化、打印'K'。
其中值得关注的:关看门狗、开发板供电锁存、时钟初始化、DDR初始化、打印"OK"
第二阶段主要是对开发板级别的硬件、软件数据结构进行初始化。
board.c中的start_armboot 函数
init_sequence cpu_init 空的 board_init 网卡、机器码、内存传参地址 dm9000_pre_init 网卡 gd->bd->bi_arch_number 机器码 gd->bd->bi_boot_params 内存传参地址 interrupt_init 定时器 env_init init_baudrate gd数据结构中波特率 serial_init 空的 console_init_f 空的 display_banner 打印启动信息 print_cpuinfo 打印CPU时钟设置信息 checkboard 检验开发板名字 dram_init gd数据结构中DDR信息 display_dram_config 打印DDR配置信息表 mem_malloc_init 初始化uboot自己维护的堆管理器的内存 mmc_initialize inand/SD卡的SoC控制器和卡的初始化 env_relocate 环境变量重定位 gd->bd->bi_ip_addr gd数据结构赋值 gd->bd->bi_enetaddr gd数据结构赋值 devices_init 空的 jumptable_init 不用关注的 console_init_r 真正的控制台初始化 enable_interrupts 空的 loadaddr、bootfile 环境变量读出初始化全局变量 board_late_init 空的 eth_initialize 空的 x210_preboot_init LCD初始化和显示logo check_menu_update_from_sd 检查自动更新 main_loop 主循环