怎么搭建学习Linux内核的运行、调试环境?

hegangben
2026-01-07 / 0 评论 / 2 阅读 / 正在检测是否收录...

作者:Tools boy
链接:https://www.zhihu.com/question/66594120/answer/355840304
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一步一步教你搭建linux内核调试环境,因为毕设跟os有关,最近在学习ulk3(深入理解linux内核第三版),感觉光看书不动手实践是很容易遗忘知识,于是开始动手调试书上对应版本的linux2.6内核环境: ubuntu-14.04.1 32位桌面版 内核版本:3.13.0-32-generic 调试的内核为:linux-2.6.26版本调试工具:qemu,gdb,busybox

1.编译x86下的linux2.6内核首先下载linux-2.6.26版本内核Index of /pub/linux/kernel/v2.6/. ubuntu安装qemusudo apt-get install qemu
tar -zvxf linux-2.6.26.tar.gz
sudo apt-get install libncurses5-dev (执行linux+busybox菜单式的配置,需要的库)
进入linux2.6-26根目录,执行以下命令
make menuconfig,选择 kernel hacking—>
[*] compile the kernel with debug info 让其携带调试信息
make defconfig 生成配置文件
make 编译kernel接着make时,会出现 undefined reference to __mutex_lockslowpath
mk3mgc8h.png

解决方法:需要去kernel/目录找到mutex.c修改,在static跟void之间加上__used,同样__mutex_unlockslowpath也要加上__usedstatic __used void fastcall noinline __sched __mutex_lock_slowpath继续make,会出现以下错误gcc: error: elf_i386: No such file or directory
make[1]: * [arch/x86/vdso/vdso32-int80.so.dbg] Error 1
make: * [arch/x86/vdso] Error 2
原因在于我的宿主机是gcc 4.8.2,编译器版本过高,不再支持 linker-style 架构.需要修改arch/x86/vdso/Makefile,大约在28,29行 找到 VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 把"-m elf_x86_64" 替换为 "-m64"2然后再继续找,大约在72行左右,找到VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1中的 "-m elf_i386" 替换为 "-m32"接着继续执行make,就可以继续编译内核,出现以下字样就表示内核编译ok了Root device is (8, 1)
Setup is 12160 bytes (padded to 12288 bytes).
System is 2653 kB
CRC ae462731
Kernel: arch/x86/boot/bzImage is ready (#4)
Building modules, stage 2.
MODPOST 1 modules2.接着使用busybox制作文件镜像建立目标根目录映像dd if=/dev/zero of=myinitrd4M.img bs=4096 count=1024
mke2fs myinitrd4M.img
mkdir rootfs
sudo mount -o loop myinitrd4M.img rootfs
准备dev目录
sudo mkdir rootfs/dev
linux启动过程中会启用 console设备
sudo mknod rootfs/dev/console c 5 1
另外需要提供一个linux根设备,我们使用 ram
sudo mknod rootfs/dev/ram b 1 0接着下载busyboxhttps://www.busybox.net/downloads/busybox-1.20.1.tar.bz2 执行以下命令make defconfig
make menuconfig修改如下配置:
busybox settings –> build options –> build busybox
as a static binary( no share libs)
执行make
在busybox目录下
sudo make CONFIG_PREFIX=(path to rootfs)/ install
sudo umount rootfs
完成根文件系统的制作接着执行qemu-system-i386 -kernel ../linux-2.6.26/arch/x86/boot/bzImage -initrd myinitrd4M.img -append "root=/dev/ram init=/bin/ash"看是否可以顺利的进入到busybox提供的shell环境
mk3medic.png

作者:Tools boy
链接:https://www.zhihu.com/question/66594120/answer/355840304
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.qemu+gdb调试内核首先执行以下指令(就上条指令后面+ -s -S)qemu-system-i386 -kernel ../linux-2.6.26/arch/x86/boot/bzImage -initrd myinitrd4M.img -append "root=/dev/ram init=/bin/ash" -s -S可以看到在新打开的qemu虚拟机上,整个是一个黑屏,此时qemu在等待gdb的链接接着开启另外一个终端,执行gdb接着在gdb界面中 targe remote之前加载符号表file ../linux-2.6.26/vmlinux target remote: 1234 则可以建立gdb和gdbserver之间的连接.很多教程说接下来直接b startkernel,然后就可以调试内核了,然而我一直没有成功,这个bug卡了我两天,一直无法断点,后来查了英文资料得知(gdbserver inside qemu does not stop on breakpoints),一开始必须使用硬件断点hk startkernel才可以断点接着在start_kernel下硬件断点 hk startkernel(,普通的break断点无法使得gdb在断点处运行,这是一个gdb的bug(),接下来就可以愉快的调试内核了
mk3melq3.png

0

评论 (0)

取消