完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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启动打印信息: |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
533 浏览 0 评论
803 浏览 1 评论
700 浏览 1 评论
1926 浏览 1 评论
3171 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:30 , Processed in 0.622877 second(s), Total 43, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号