u-boot-spl运行时CONFIG_VAL(SYS_MALLOC_F_LEN)代码块被跳过原因排查
排查方向
1. 验证预编译宏的实际展开结果
直接查看board_init.c的预处理输出,确认CONFIG_VAL(SYS_MALLOC_F_LEN)是否正确展开为CONFIG_SPL_SYS_MALLOC_F_LEN:
- 执行命令:
arm-linux-gnueabihf-gcc -E common/init/board_init.c -I include -I arch/arm/include -D CONFIG_SPL_BUILD=1 | grep -A5 -B5 CONFIG_VAL - 检查输出中
#if CONFIG_VAL(SYS_MALLOC_F_LEN)是否被替换为#if CONFIG_SPL_SYS_MALLOC_F_LEN,以及该宏的数值是否为0x2000000。若展开错误,说明Kconfig的宏替换逻辑在编译时未正确生效。
2. 确认编译时是否传入正确的CONFIG_SPL_BUILD宏
虽然spl/u-boot.cfg显示CONFIG_SPL_BUILD=1,但需确认编译过程中是否真的将该宏传递给编译器:
- 执行
make V=1 spl查看编译日志,搜索board_init.c的编译命令,检查是否包含-DCONFIG_SPL_BUILD=1参数。若缺少该参数,CONFIG_VAL会回退到非SPL版本的宏定义。
3. 检查CONFIG_SPL_SYS_MALLOC_F_LEN的作用域
确认.config中的CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000000是否被正确同步到SPL编译配置:
- 查看
spl/.config文件(若存在),确认该宏是否存在且值正确。有时主.config的宏不会自动同步到spl子目录,需重新执行make spl_defconfig或make savedefconfig后重新编译。
4. 排查编译优化导致的代码折叠
GCC的优化选项(如-O2)可能会将编译器认为“无意义”的代码折叠,导致执行路径被跳过:
- 临时修改Makefile,给
board_init.c添加-O0编译选项,重新编译SPL后用GDB调试,观察代码是否还会被跳过。若恢复正常,说明是优化导致的代码路径被移除。 - 同时查看
board_init.o的反汇编文件,确认被跳过的代码段是否存在,以及条件分支的判断逻辑是否符合预期。
5. 验证CONFIG_VAL宏的定义逻辑
核对include/linux/kconfig.h中CONFIG_VAL的实现,确认CONFIG_SPL_BUILD为1时,是否正确拼接CONFIG_SPL_前缀:
#define CONFIG_VAL(name) _CONFIG_VAL(name) #define _CONFIG_VAL(name) CONFIG_##__CONFIG_PREPEND##name
若__CONFIG_PREPEND在SPL编译时未被设置为SPL_,宏替换会失败。可在board_init.c开头添加调试代码:
#ifdef CONFIG_SPL_BUILD #warning "SPL_BUILD is defined" #warning "CONFIG_SPL_SYS_MALLOC_F_LEN is " __stringify(CONFIG_SPL_SYS_MALLOC_F_LEN) #endif
重新编译,查看编译警告是否符合预期。
6. 检查SPL链接脚本的内存布局
若SPL的内存分配逻辑存在问题,可能导致代码执行路径异常:
- 查看对应平台的链接脚本(如
arch/arm/mach-qemu/virt-u-boot-spl.lds),确认.text段地址范围正确,且SPL运行内存足够容纳0x2000000大小的malloc区域。内存不足可能导致代码执行异常被跳过。
内容的提问来源于stack exchange,提问作者Chan Kim
相关产品推荐
相关产品推荐

