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,             //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

上一篇:php – imagescale无法正常工作


下一篇:使用PHP / GD,如何修剪图像?