u-boot调试串口输出对应的系统函数
接上Debug串口,启动机器,u-boot哗啦啦地打印一行行的字符。刚接触u-boot的时候,对机器后台做了什么,几乎一无所知。
如果要很有信心地定制出一个简单并且可靠的系统,或者快速完成一项新的任务,那么,机器后台运行的内容知道的越多越好。
比如,曾经遇到过这样的问题:在全局区定义一个变量int a,在board_early_init_f函数中对这个变量进行赋值,编译没有问题,系统却挂掉了。
为什么?
全局区定义的未初始化的变量,在bss段。在board_early_init_f函数函数执行阶段,完整的c环境没有建立起来。board_early_init_f在board_init_f函数中被调用,直到board_init_f函数的末尾,准备运行board_init_r之前,u-boot对代码作了一次relocate, 这个时候才分配了bss段。bss段的地址指向DDR内存。
在SPL阶段的board_init_f中,board_early_init_f运行在DDR内存控制器初始化之前。所以,当u-boot在DDR内存还不能工作的时候,去访问DDR内存,这就难怪系统会挂掉了。
修改变量的定义为int a=0;系统就不会挂掉了。已初始化的变量在刚开始的时候被载入到静态内存当中,访问当然没有问题。
从这个例子可以看到,了解机器代码的运行情况很重要。
u-boot在汇编代码中简单地初始化CPU、MMU、Cache、中断、状态寄存器之后,转到C代码运行,执行board_init_f。board_init_f执行一个初始化函数集。然后转到board_init_r执行。board_init_r也执行一个初始化函数集,然后转到main_loop函数。main_loop函数或者在bootdelay结束后进行系统引导,或者在用户按下任意按键之后进入一个循环,在循环中读取控制台输入,执行命令,这就是我们看到的u-boot命令行界面。
board_init_f -> display_options:
U-Boot ...
board_init_f -> print_cpuinfo:
CPU: ...
Reset cause: ...
board_init_f -> init_func_i2c:
I2C: ready
board_init_f -> announce_dram_init ... show_dram_config:
DRAM: ...
board_init_r -> initr_mmc:
MMC: ...
board_init_r -> initr_env -> env_relocate -> env_relocate_spec -> env_import -> set_default_env:
*** Warning - bad CRC, using default environment
board_init_r -> console_init_r -> stdio_print_current_devices:
In: serial
Out: serial
Err: serial
在autoboot中run_command(bootcmd)。bootcmd是一个环境变量字符串,从此时起u-boot以运行脚本的方式引导系统启动Linux.
bootz:
Starting kernel ...
如果能在板级代码中按执行顺序放置板级代码的各个函数,并且表明函数的调用路径,那么,看起来乱糟糟的板级代码,就有条理很多,修改和调试也方便很多。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞