u-boot程序框架

u-boot程序框架


_start:(u-boot\arch\arm\cpu\armv8\start.S)

    b   reset

            b   save_boot_params                //保存重要的寄存器数据

            .globl  save_boot_params_ret

                    bl  lowlevel_init           //底层初始化:关看门狗,设置SRAM。。。

                    bl  _main

                   

_main:(u-boot\arch\arm\lib\crt0.S)

    bl  board_init_f_alloc_reserve 

    bl  board_init_f_init_reserve               //建立C语言运行环境的内存分布

    bl  board_init_f   

    bl  spl_relocate_stack_gd                   //重新分配内存

    ldr lr, =board_init_r

   

board_init_f(common\board_f.c)

    init_sequence_f

            setup_mon_len        //设gd->mon_len为__bss_end-_start

            initf_malloc,       //设gd->malloc_limit为(1KB),gd->malloc_ptr = 0

            log_init,

            initf_bootstage,

            initf_console_record,

            arch_cpu_init,      //读PRO_ID寄存器内容解析出CPU id到全局变量s5p_cpu_id

            mach_cpu_init, 

            initf_dm,           //初始化dm资源,绑定dm驱动到gd中,扫描设备树中dm设备内容 

            arch_cpu_init_dm,

            timer_init,          //初始化定时器4和gd->arch中的定时器成员

            env_init,            //初始化environment

            init_baud_rate,      //初始化波特率设置

            serial_init,         //串口设置

            console_init_f,      //用CONFIG_SILENT_CONSOLE可让控制台“沉默”                        

            display_options,     //打印u-boot版本信息

            display_text_info,   //开debug时,打印u-boot code的内存地址

            announce_dram_init,

            dram_init,          //初始化gd->ram_size为通过写读SDRAM校验后得到的实际大小

            setup_dest_addr,     //gd->ram_top,gd->relocaddr设为SDRAM末尾

            reserve_round_4k,    //gd->relocaddr调整为4KB对齐

            reserve_video,     //依赖CONFIG_LCD(未定义),为显存预留内存,初始化gd->fb_base

            reserve_trace,    //依赖CONFIG_TRACE(未定义),初始化gd->trace_buff

            reserve_uboot,   //预留gd->mon_len个字节给u-boot code,地址存于gd->relocaddr

            reserve_malloc,   //预留malloc和env区

            reserve_board,    //预留struct bd_info的空间并清零,地址存于gd->bd

            setup_machine,   //依赖CONFIG_MACH_TYPE(未定义),设置gd->bd->bi_arch_number

            reserve_global_data,   //预留struct global_data的空间,地址存于gd->new_gd

            reserve_fdt,          //预留存放设备树的内存,设置gd->fdt_size和gd->new_fdt

            reserve_bootstage,     //依赖CONFIG_BOOTSTAGE(未定义),预留存放struct bootstage_data的内存
            reserve_arch,

            reserve_stacks,         //设置gd->irq_sp(需16B对齐),预留为4个word的地址记到gd->start_addr_sp

            dram_init_banksize,    //初始化gd->bd->bi_dram

            show_dram_config,      //打印DRAM的大小

            display_new_sp,        //打印gd->start_addr_sp的值

            reloc_fdt,             //将gd->fdt_blob地址的设备树重定位到gd->new_fdt地址上,更新gd->fdt_blob

            reloc_bootstage,     //依赖CONFIG_BOOTSTAGE(未定义),重定位gd->bootstage内容到gd->new_bootstage,更新gd->bootstage

            setup_reloc,        //初始化gd->reloc_off为重定位目标地址与链接地址之差,重定位gd_t内容到gd->new_gd

           

board_init_r:(common\board_r.c)

    init_sequence_r

            initr_trace,      //依赖CONFIG_TRACE(未定义),trace system函数未实现

            initr_reloc,      //gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;标志重定位完成

            initr_reloc_global_data,  //重定位全局变量:monitor_flash_len,
gd->fdt_blob(CONFIG_OF_EMBED)

            initr_barrier,

            initr_malloc,              //初始化malloc功能和清零malloc区

            log_init,                  //依赖CONFIG_LOG(未定义),初始化log驱动

            initr_bootstage,            //设进度为BOOTSTAGE_ID_START_UBOOT_R,并记到bootstage(依赖CONFIG_BOOTSTAGE-未定义),show_boot_progress()(未实现)提示进度,枚举bootstage_id罗列了进度id                                             

            initr_console_record,       //依赖CONFIG_CONSOLE_RECORD(未定义),给console record功能分配内存

            bootstage_relocate,         //依赖CONFIG_BOOTSTAGE(未定义),重定位gd->bootstage的内容

            stdio_init_tables,              //初始化标准输入输出设备链表

            initr_serial,                   //调用drivers/serial/serial-uclass.c(依赖CONFIG_DM_SERIAL),在设备树alias节点获得属性"stdout-path"或"console",从而得到作为标准输入输出的设备节点,生成UCLASS_SERIAL类的udevice来匹配兼容的驱动及probe;该串行设备记录到                                                                 gd->cur_serial_dev;标志GD_FLG_SERIAL_READY

            initr_announce,             //打印u-boot重定位后起始地址(需开DEBUG)

            power_init_board,

            initr_env,                      //通用env层(env/env.c)调用env硬件驱动层(若定义CONFIG_ENV_IS_IN_NAND则在env/nand.c),加载nand中CONFIG_ENV_OFFSET开始的env数据到栈中,检查crc成功则将其(失败则使用default_environment复制到堆中,内存地址记录进env_htab,标志置位GD_FLG_ENV_READY插入或设置环境变量fdtcontroladdr为gd->fdt_blob

            initr_secondary_cpu,

            stdio_add_devices,              //调用drv_xxx_init()(需开CONFIG_XXX),如drv_lcd_init()(需定义CONFIG_LCD),drv_system_init()则关于串口;驱动通用层填充stdio_dev并注册添加到标准输入输出链表上,硬件初始化

            initr_jumptable,       //为函数跳转表(struct jt_funcs定义)分配内存并记录内存地址到gd->jt

            console_init_r,       //定义CONFIG_SILENT_CONSOLE和环境变量"silent"可标志GD_FLG_SILENT,在标准输入输出设备(stdio_add_devices()生成,common/console.c)将首个标志为DEV_FLAGS_INPUT或DEV_FLAGS_OUTPUT作为控制台io设备,设置环境变量”stdxxx”为设备名,标志GD_FLG_DEVINIT

            run_main_loop,                  //初始化hush解析器(CONFIG_HUSH_PARSER),用环境变量"bootdelay"或设备树节点config的属bootdelay作为启动延迟时间,通过hush解析控制台输入的内容打断倒计时并进入命令行;倒计时期间控制台无输入则执行环境变量或设备树/config节点的bootcmd,最后执行命令bootm 0x30007FC0

                main_loop();


main_loop() (common\main.c)

    run_preboot_environment_command();

            run_command_list(p, -1, 0);

    autoboot_command(s);

            run_command_list(s, -1, 0);

                board_run_command(buff);

                    do_bootm(NULL, 0, 2, bootm_argv);

                   

do_bootm(NULL, 0, 2, bootm_argv)(common\bootm.c)

     do_bootm_states(...)

            bootm_start()      //环境变量verify决定后续是否对kernel镜像进行校验和检查,lmb(logical memory blocks)相关内容的初始化

            bootm_find_os()

                    boot_get_kernel()       //获取kernel镜像格式为IMAGE_FORMAT_LEGACY,验证镜像hcrc,打印镜像的名字、类型、数据大小、加载地址和入口地址,验证dcrc(依赖env的verify),判断arch是否支持解析镜像的结员,kernel入口地址记到images.ep,镜像头部地址记到mages.os.start

            bootm_find_other()

                    boot_get_ramdisk()      //解析ramdisk镜像,bootm第三个参数为其地址(如bootm xxx yyy,yyy为对应地址)

                    boot_get_fdt()          //获取和解析设备树镜像内容,设备树镜像的起始地址需在bootm命令第四个参数指明,如bootm xxx                                                 yyy zzz,zzz为对应地址

            bootm_load_os()             //解压os数据或移动到images->os.load地址,所以kernel应有Load Address=Entry Point

            boot_ramdisk_high()         //重新定位并初始化ramdisk,需定义CONFIG_SYS_BOOT_RAMDISK_HIGH

            bootm_os_get_boot_func()        //根据os类型获得启动函数boot_fn = do_bootm_linux

            boot_selected_os()              //通过函数指针boot_fn调用do_bootm_linux(BOOTM_STATE_OS_GO, ...),进而调用                                                                    boot_jump_linux(images, BOOTM_STATE_OS_GO)

                do_bootm_linux()

                    boot_jump_linux()

                        announce_and_cleanup(fake)      //打印提示开始启动内核,注销驱动模型下设备驱动;调用cleanup_before_linux():关L1/2 D-cache和MMU,冲刷掉dcache内数据;关I-cache,失效I-cache内条目,失效整个分支预测器阵列;执行数据和指令内存屏障,确保前面的操作完成

                        kernel_entry(0, machid, r2);        //参数r2传递启动参数(tag或设备树)的内存地址,正式跳转到kernel

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值