使用Yocto SDK调试ARM Linux Kernel的源码缺失与优化问题
使用Yocto SDK结合KGDB调试ARM Linux内核的源码缺失问题解决
问题背景
通过Yocto生成ARM架构镜像的SDK,配合KGDB调试Linux内核时,已完成以下配置:
- 内核编译时开启
CONFIG_KGDB=y和CONFIG_KGDB_SERIAL_CONSOLE=y - 镜像配方(image.bb)中添加
TOOLCHAIN_TARGET_TASK += "kernel-devsrc"以安装内核源码 - 内核启动参数添加
kgdboc=ttySTM0,115200 kgdbwait,等待KGDB连接 - 使用SDK中的
arm-ostl-linux-gnueabi-gdb,设置串口波特率后通过target remote /dev/ttyUSB1连接,串口通信正常
但SDK中的内核源码不全,GDB报错/usr/src/kernel/*/*/*.c: No such file or directory,调试无法正常进行。直接全量复制所有.c文件到SDK会导致体积冗余,因此需要更优的解决方案。
1. Yocto中的更优实现方式
利用内核编译生成的依赖文件(.o.d)筛选实际参与编译的源码文件,是最精准且高效的方式:
内核编译时,每个目标文件(.o)都会生成对应的.d文件,其中记录了编译该目标文件所需的源文件(.c)和头文件路径。通过解析这些.d文件,可以只复制实际被编译的.c文件,避免冗余。
修改openembedded-core/meta/recipes-kernel/linux/kernel-devsrc.bb的do_install()函数,替换全量复制的命令,添加以下逻辑:
# 从内核编译目录的.o.d文件中提取实际编译的.c文件路径 for dfile in $(find ${B} -name "*.o.d"); do # 筛选出.c文件路径并去重 grep -E '\.c$' "${dfile}" | cut -d ':' -f 1 | sort -u | while read srcfile; do # 确保源文件存在于内核源码目录 if [ -f "${S}/${srcfile}" ]; then # 按原目录结构安装到SDK的内核源码目录 install -D "${S}/${srcfile}" "${kerneldir}/build/${srcfile}" fi done done
这种方式只会打包真正参与当前内核编译的.c文件,既满足GDB调试的源码需求,又不会引入冗余文件。
2. 若需手动过滤添加所需.c文件
如果上述依赖解析方式不适用,可通过路径过滤的方式,仅复制ARM架构相关及核心功能的源码文件:
在kernel-devsrc.bb的do_install()中使用带路径筛选的find命令,示例如下:
# 仅复制ARM架构目录、核心内核目录及目标驱动目录下的.c文件 cp --parents $(find "${S}" -type f -name "*.c" \ -path "*/arch/arm/*" \ -o -path "*/kernel/*" \ -o -path "*/mm/*" \ -o -path "*/fs/*" \ -o -path "*/drivers/stm/*") \ "${kerneldir}/build/"
注意:需根据实际内核配置和硬件平台调整路径(比如将drivers/stm/*替换为对应硬件的驱动目录),这种方式虽然不如依赖解析精准,但能大幅减少冗余文件。
内容的提问来源于stack exchange,提问作者Jose Araya
相关产品推荐
相关产品推荐

