RK3288 Uboot启动流程分析

Uboot的启动过程大同小异,rk3288的uboot启动也是分为两个过程:
uboot的启动由arch/arm/cpu/armv7/start.S 开始,调用了_main,而_main 的实现是在arch/arm/lib/crt0.S中完成,在_main中主要完成以下几个任务:
1、为调用board_init_f 设置初始环境,这个环境起始就是提供了一个堆栈和一个存储GD结构体的地方。
2、调用board_init_f。在这里会初始化串口、timer、计算重定位的位置等。
3、调用relocate_code将uboot从当前我位置重定位到上一步计算到的addr。
4、调用board_init_r。这里大多都是c代码实现了,在初始化堆栈后完成各种初始化,lcd点亮logo也是在这个函数中实现。并且最后会调用do_bootm_linux 来启动内核,
5、当没有立即启动内核时,会调用到run_main_loop,进入uboot的cmd处理阶段。
整体代码调用流程:

/*arch/arm/cpu/armv7/start.S*/
bl _main
    /*arch/arm/lib/crt0.S*/
    /* 以ENTRY(_main)为入口 主要调用流程如下:*/
    ENTRY(_main)
        /* 设置初始化环境:在RAM中提供一个临时的堆栈和一个GD */
        ldr	sp, =(CONFIG_SPL_STACK)
        ...
        /* 调用board_init_f */
        bl	board_init_f
            /*common/board_f.c*/
            /* 注意此时只有一个简单的初始化环境只能使用GD来传递数据*/
            void board_init_f(ulong boot_flags)
                /* 挨个调用list中的函数 */
                if (initcall_run_list(init_sequence_f)) 
                     arch_cpu_init,		/* basic arch cpu dependent setup */
                     timer_init,		/* initialize timer */ 
                     env_init,		/* initialize environment */
                     init_baud_rate,		/* initialze baudrate settings */
                     serial_init,		/* serial communications setup */
                     console_init_f,		/* stage 1 init of console */
                     display_options,	/* say that we are here */
                     display_text_info,	/* show debugging info if required */
                     print_cpuinfo,		/* display cpu info (and speed) */
                     dram_init_f,		/* configure available RAM banks */
                     calculate_relocation_address, /* 计算重定位的位置 */
                     announce_dram_init,
                     setup_dram_config,
                     show_dram_config,
        /* 调用重定位代码 ,重定位至board_init_f 计算出的addr */
        b	relocate_code
        /* 调用board_init_r */
        ldr	pc, =board_init_r
            /* commod/board_r.c */
            void board_init_r(gd_t *new_gd, ulong dest_addr)
                /* 一次调用list中的函数 */
                if (initcall_run_list(init_sequence_r))
                    initr_trace,
                    initr_malloc,
                    board_init,	/* Setup chipselects */
                    initr_serial, /* 串口初始化 */
                        serial_initialize();
                    interrupt_init  
                    /* /u-boot/board/rockchip/rk32xx/rk32xx.c */  
                    board_late_init,    
                        int board_late_init(void)
                            board_init_adjust_env();
                            /* /u-boot/board/rockchip/common/rkloader/parameter.c */
                            load_disk_partitions();
                                int load_disk_partitions(void)
                            /* 设备树解析 */  
                            /*  /u-boot/board/rockchip/common/rkloader/rkimage.c */
                            rkimage_prepare_fdt();    
                                /* 从boot或者resource image读取fdt地址,resource会覆盖boot.img的fdt. */
                                content = rkimage_load_fdt(get_disk_partition(RESOURCE_NAME));    
                            pmic_init(0);  
                            /* PWM 初始化 */      
                            pwm_regulator_init();
                            fg_init(0); /*fuel gauge init*/
                            /* /board/rockchip/common/rkboot/fastboot.c */
                            board_fbt_preboot();
                                void board_fbt_preboot(void)
                                    fbt_fastboot_init(); 
                                    /* Uboot lcd 显示logo */       
                                    #ifdef CONFIG_LCD
                                        g_logo_on_state = 0; /* 判断是否显示logo的标记位 */
                                        g_logo_on_state = fdtdec_get_int(gd->fdt_blob, node, "rockchip,uboot-logo-on", 0);
                                        /* 根据dts中的值来确定是否显示logo */
                                        if (g_logo_on_state != 0) {
                                            lcd_enable_logo(true);
                                            drv_lcd_init();
                                        }        
                                    /* 低电量、未充电关机 */
                                    board_fbt_low_power_off();
                                    lcd_standby(0);
                                    /* 先显示再点亮背光 */
                                    rk_pwm_bl_config(-1);
                                    
                                    rkloader_run_misc_cmd();
                                        /*/board/rockchip/common/rkloader/rkloader.c*/
                                        int rkloader_run_misc_cmd(void)                                   
                                                /* common/cmd_bootrk.c */
                                                char *const boot_cmd[] = {"bootrk", "recovery"}
                                                do_bootrk(NULL, 0, ARRAY_SIZE(boot_cmd), boot_cmd);
                                                    /* 启动内核 */
                                                    do_bootm_linux(0, 0, NULL, &images);
                                                        boot_prep_linux(images);
                                                        boot_jump_linux(images, flag);
                       run_main_loop,
                           /* 当没有立即启动kernel时,进入uboot 的最终循环,处理各种cmd,也可以通过cmd启动kernel */ 
                           for (;;)
                               /* common/main.c */
                               main_loop();      
                                   bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); 
                                   modem_init();
                                   cli_init();
                                   run_preboot_environment_command(); 

实际uboot启动打印信息:
在这里插入图片描述

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值