【问题标题】:Debugging Linux Kernel with Yocto SDK使用 Yocto SDK 调试 Linux 内核
【发布时间】:2022-08-24 19:33:25
【问题描述】:
我正在尝试使用 KGDB 从我的 arm Yocto 映像生成的 SDK 中调试 Linux 内核。为此,我首先确保将 KGDB 编译为内置模块:
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
此外,在我的 image.bb 中,我安装了内核源代码:
`TOOLCHAIN_TARGET_TASK += \"kernel-devsrc\"`
最后,我通过在内核启动命令中添加kgdboc=ttySTM0,115200 kgdbwait 在启动时启动 KGDB。这会停止引导过程,直到 KGDB 连接到主机端的 GDB。然后,通过从 Yocto-SDK 启动 arm-ostl-linux-gnueabi-gdb 并设置 set serial baud 115200 和 target remote /dev/ttyUSB1 我可以恢复和调试剩余的引导例程。
KGDB<->GDB 在启动时通过串行连接工作得很好。但是,我当前的问题是,并非所有内核源都安装在 SDK 中,这使得 GDB 抱怨 /usr/src/kernel/*/*/*.c: No such file or directory.,使得调试几乎毫无用处。
因此,我通过将 cp --parents $(find -type f -name \"*.c\") $kerneldir/build 添加到 openembedded-core/meta/recipes-kernel/linux/kernel-devsrc.bb 的 do_install() 函数来强制安装所有 .c 源,该函数使用上述 TOOLCHAIN_TARGET_TASK += \"kernel-devsrc\" 调用.
在将我的补丁添加到内核源代码之后,这有效地将所有生成的内核 .c 文件添加到 SDK,但它也添加了许多我的架构(arm)甚至不需要的 .c,使 SDK 变得不必要地大。
所以,我的问题是:
- 有没有更好的方法来使用 Yocto 做到这一点?
- 如果没有,我怎样才能只过滤需要添加到 SDK 中的 .c?
提前致谢!
标签:
linux
gdb
embedded-linux
yocto
remote-debugging
【解决方案1】:
过滤掉不需要的源的一种方法是通过使用以下脚本在元层中创建 kernel-devsrc.bbappend 来扩展开放嵌入式 kernel-devsrc.bb:
do_install_append(){
bbplain "--------------Including Kernel Sources------------------"
cd ${S}
# Find binary files (*.o) as a hint to find relevant sources
for f in `find ${B} -type f -name "*.o"`; do
# Extract file name
file="${f##*/}"
# Extract only path
path=${f%/*}
# Remove global part of the path
path="${path##@(${B})}"
# Remove object extension
file=${file%.o}
# Copy relevant sources to the SDK
cp --parents $(find .$path -maxdepth 1 -type f -name ${file}.c -o -name ${file}.S) $kerneldir/build 2>/dev/null || :
done
}
使用这种方法,我们首先在二进制文件夹中查找已编译的目标文件,因为这些文件为我们提供了当前 defconfig 正在使用哪些内核组件的信息。有了这些信息,我们可以找到相应的内核 .c 和 .S 源并将它们安装在 SDK 中。这样可以避免复制所有源,在我的情况下,这会将 src 文件夹从 ~610MB 减少到 18MB。
已知限制:
有一些目标文件(在我的例子中是 5)没有同名的相应源,即 .tmp_vmlinux.kallsyms2.o、dtc-parser.tab.o、dtc-lexer.lex.o、.tmp_vmlinux.kallsyms1。 o 和 vmlinux.o。我们可以使脚本更复杂以捕捉那些极端情况,或者使用2>/dev/null || : 忽略它们,如图所示。