ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

u-boot程序框架

2019-08-30 14:41:21  阅读:237  来源: 互联网

标签:初始化 框架 boot 程序 bootm init gd CONFIG


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,             //gd->have_console = 1,用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的内存,设置                                                            gd->new_bootstage

            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                                                或GD_FLG_ENV_DEFAULT;插入或设置环境变量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是否支持解析镜像的结                                            果填充images.os的成员,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

标签:初始化,框架,boot,程序,bootm,init,gd,CONFIG
来源: https://blog.csdn.net/m0_37765662/article/details/100156086

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有