rk3506的uboot源码分析(四)

上一章节中,我们讲到了

cpp 复制代码
void board_init_f(ulong boot_flags)
{
	gd->flags = boot_flags;
	gd->have_console = 0;

	if (initcall_run_list(init_sequence_f))
		hang();

#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
		!defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64)
	/* NOTREACHED - jump_to_copy() does not return */
	hang();
#endif
}

这里的initcall_run_list会调用init_sequence_f这个函数指针里的函数。那么我们接下来分析这个init_sequence_f里的函数。定义太长,我就不列举了。init_sequence_f定义就在u-boot/common/board_f.c。

init_sequence_f内部的函数作用分析

setup_mon_len

这个就在boot/common/board_f.c。

执行:

cpp 复制代码
gd->mon_len = (ulong)&__bss_end - (ulong)_start;

这里得到uboot image的大小。这个bss_end和start的值都在u-boot/u-boot.lds里定义了。在第一章中也分析了具体的值。

fdtdec_setup

这个定义在u-boot/lib/fdtdec.c

主要执行的就是

cpp 复制代码
int fdtdec_setup(void)
{
    gd->fdt_blob = (ulong *)&__bss_end;   // 就这一行
    return 0;
}

这里主要做的就是把 gd->fdt_blob 指向设备树二进制数据,告诉系统"设备树在这里"。

initf_malloc

定义在u-boot/common/dlmalloc.c

cpp 复制代码
int initf_malloc(void)
{
#if CONFIG_VAL(SYS_MALLOC_F_LEN)           // 如果开了 early malloc
    assert(gd->malloc_base);               // 确认 board_init_f_init_reserve 已经设好了
    gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);  // 池子大小 = 0x100000 (1MB)
    gd->malloc_ptr = 0;                    // 已用字节 = 0(池子还是空的)
#endif
    return 0;
}

这个就是之前board_init_f_alloc_reserve在这里我们空出了1MB的大小。

cpp 复制代码
ulong board_init_f_alloc_reserve(ulong top)   // top = 0x03f00000
{
    top -= CONFIG_VAL(SYS_MALLOC_F_LEN);       // top = 0x03e00000  ← 抠出 1MB
    top = rounddown(top - sizeof(gd), 16);
    return top;                                // 返回 ≈ 0x03dfff00
}

这里就是存储的他的大小和使用情况。

log_init

定义在u-boot/common/log.c

cpp 复制代码
int log_init(void)
{
    struct log_driver *drv = ll_entry_start(struct log_driver, log_driver);
    const int count = ll_entry_count(struct log_driver, log_driver);
    struct log_driver *end = drv + count;

    INIT_LIST_HEAD((struct list_head *)&gd->log_head);   // ① 初始化日志链表头

    while (drv < end) {                                   // ② 遍历所有日志驱动
        struct log_device *ldev;
        ldev = calloc(1, sizeof(*ldev));                  // ③ 分配一个设备节点
        ldev->drv = drv;                                  // ④ 绑定驱动
        list_add_tail(&ldev->sibling_node,                // ⑤ 挂到链表上
                      (struct list_head *)&gd->log_head);
        drv++;
    }

    gd->flags |= GD_FLG_LOG_READY;                        // ⑥ 标记:日志可用
    gd->default_log_level = LOGL_INFO;                    // ⑦ 默认日志级别 = INFO

    return 0;
}

U-Boot 的日志系统支持多个日志驱动(输出目标),比如

驱动 输出到
console 串口控制台
syslog 网络 syslog 服务器
... ...

每个驱动用宏注册后,链接器把它们全部排在一起 ,形成一张连续的表ll_entry_start / ll_entry_count 就是读取这张表的起止位置和条目数------不需要手动注册,编译时自动聚合。

initf_bootstage

这个就定义在u-boot/common/board_f.c这里

这里主要是清空数组,之后开始记录每一步的时间。可以说从这里开始,就有了一个秒表,记录每一步的时间。

initf_console_record

这里主要是记录,可能之前已经有了printf了,但是这时候串口还没有初始化,所以将消息先存储。后续再用。

后边太多了,省略点把~,直接调重要的了。

timer_init

初始化定时器,但是在rk3506里是空函数,真正的初始化在**initf_dm**里。

init_baud_rate

就在u-boot/common/board_f.c

cpp 复制代码
static int init_baud_rate(void)
{
    if (gd && gd->serial.baudrate)                          // 如果之前已经设过了
        gd->baudrate = gd->serial.baudrate;                 //   直接用那个值
    else                                                     // 否则
        gd->baudrate = env_get_ulong("baudrate", 10,        //   从环境变量读
                                     CONFIG_BAUDRATE);      //   读不到就用默认值

    return 0;
}

=========先更到这=======================

相关推荐
小此方7 分钟前
Linux网络(二十二):深入解析IP协议:从地址寻址、头部结构到内核机制与TTL环路控制
linux·网络·tcp/ip
Ruiery8 分钟前
Linux 6.6内核内存管理深度解析(四):大页(HugeTLB / THP)— 为什么一个页表项要管 2MB
linux·运维·服务器
Lsetea12 分钟前
OpenSSL报certificate rejected:error 28与CA辅助信任属性排查
linux·https·ssl证书·openssl·证书链
沫璃染墨14 分钟前
从零入门计算机网络系列(五):UDP套接字编程实战——从核心API到客户端与服务器通信
linux·网络·c++·vscode·网络协议·udp
Margrop1 Margrop16 分钟前
别再挨个试清华、中科大、阿里源了!国家队下场的“CERNET 镜像聚合站”,凭什么让你的下载直接起飞?
linux·开源镜像·cernet
一条破秋裤24 分钟前
05_设备树自定义属性_写入读取验证
linux·网络·数据库
此生决int36 分钟前
Linux系统(07)——进程概念(下)
linux·运维·服务器
迷途之人不知返1 小时前
【基础IO】-3-系统级别的文件操作
linux
下辈子不要当码农1 小时前
Linux驱动(2)
linux·运维·单片机
m0_587383001 小时前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能