uboot高级开发-2014版以后

概述

以RK3568平台为例,讲述uboot开发所必须的知识要点。

配置文件

做裁剪或增加某配置项,需要涉及如下文件:
1、configs/xxx_defconfig : 可以在make menuconfig中查看到的配置
2、include/configs/xxx.h :如何确定这个文件名?
该文件名通过: include/config.h(自动生成)确定

启动流程

从u-boot.lds可以查看到uboot.bin的入口函数:

  1 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
  2 OUTPUT_ARCH(aarch64)
  3 ENTRY(_start)
  4 SECTIONS
  5 {
  6  . = 0x00000000;
  7  . = ALIGN(8);
  8  .text :
  9  {
 10   *(.__image_copy_start)
 11   arch/arm/cpu/armv8/start.o (.text*)
 12   *(.text*)
 13  }

arch/arm/cpu/armv8/start.S

cpu是cortex-a55,使用的是armv8内核

代码流程

先进入board_init_f,再进入board_init_r

123     bl  board_init_f


188     b   board_init_r            /* PC relative jump */

common/board_f.c::board_init_f

board_init_f
    init_sequence_f : 顺序执行列表中的接口函数
    

common/board_r.c::board_init_r

board_init_r
    init_sequence_r : 顺序执行列表中的接口函数
        board_init
        board_late_init
        run_main_loop

arch/arm/mach-rockchip/board.c::board_init

平台初始化最核心部分

board_init
    board_debug_init:串口iomux、clk配置,监听串口输入(获取ctrl+m、ctrl+c等)
    init_kernel_dtb:切到kernel dtb
    clks_probe : 初始化系统频率
    regulators_enable_boot_on:初始化系统电源
    set_armclk_rate: __weak, ARM提频(平台有需求才实现)
    dvfs_init: 宽温芯片的调频调压
    rk_board_init : rk平台具体实现

arch/arm/mach-rockchip/board.c::board_late_init

board_lata_init
    rockchip_set_ethaddr : 设置mac地址
    rockchip_set_serialno : 设置serialno
    setup_boot_mode : 解析reboot xxx命令;识别按键和loader烧写模式、recovery
    charge_display : 充电显示
    rockchip_show_logo: 显示开机logo
    soc_clk_dump : 打印clk tree
    rk_board_late_init : __weak, 由各个具体平台进行实现

common/board_r.c::run_main_loop

run_main_loop
    common/main.c::main_loop

ENV框架

env/存储类型.c中定义struct env_driver
例:
U_BOOT_ENV_LOCATION(nowhere) = {
	.location	= ENVL_NOWHERE,
	.init		= env_nowhere_init,
	ENV_NAME("nowhere")
};

#define U_BOOT_ENV_LOCATION(__name)					\
	ll_entry_declare(struct env_driver, __name, env_driver)
	
#define ll_entry_declare(_type, _name, _list)				\
	_type _u_boot_list_2_##_list##_2_##_name __aligned(4)		\
			__attribute__((unused,				\
			section(".u_boot_list_2_"#_list"_2_"#_name)))

即:将nowhere(env in mem)env_driver加入位于段u_boot_list_2_xx的列表中
获取对应存储器的env_driver:

common/board_f.c
    init_sequence_f
        env_init
            env_driver_lookup_default
                env_driver_lookup // 获取ENVL_NOWHERE对应的env_driver
        drv->init // 得到env存放的地址,保存在gd->env_addr

使用env_driver,例如printenv流程

common/board_r.c
    init_sequence_r
        initr_env_nowhere   //这里是rk平台需要在uboot中使用kernel的设备树,需要访问env中的devtype等信息,故加此代码
            set_default_env(NULL);
                himport_r(&env_htab, (char *)default_environment,
			        sizeof(default_environment), '\0', flags, 0,0, NULL)

最终,将default_environment放入env_htab(struct hsearch_data)中,这里是env_in_nowhere的流程
其他流程例如nand为:

common/board_r.c
    init_sequence_r
        initr_env
            env_relocate
                env_load -> env_nand_load
                    env_import(buf, 1); //buf: 指定地址下的env数据
                        himport_r

himport_r同env_in_nowhere流程。
至此,env数据被放到入env_htab表中。那么如何使用呢?
以printenv为例:

cmd/nvedit.c
    env_print
        hexport_r

hexport_r将遍历上述的env_htab表获取对应数据。
整体流程框图如下:

    env_in_nowhere  |           |                       |
    env_in_nand     | => list <=|   env core  env_htab <=>   printenv       
    env_in_mmc      |     |     |                       |
                          V                     ▲
                    env_driver.init     --      |
                    env_driver.load     --      |

TODO。。。

抽空添加:dtb、DM、platform、gpio-uclass、pinctrl-uclass、clk-uclass、GICv2/v3

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值