最近在debug linux。方法是在vmware的ubuntu虚拟机上编译linux最新的代码,并通过qeum启动然后通过 gdb attach 到linux内核去。
1:先获取linux 源码

cd /home/zhaosongqiang/Documents/linux_code/latest
git clonee git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

2:cpoy 一份现在启动的ubuntu的config 文件 作为我们编译linux的conf文件

cd /home/zhaosongqiang/Documents/linux_code/latest/linux-stable
cp /boot/config-`uname -r` .config

3:
make olddefconfig or make menuconfig
确保下列配置:前3个开启kernel的debug,最后一个配置linux kernel网络的时候有用(在make menuconfig 时开启CONFIG_E1000=y 参考下图1)

CONFIG_DEBUG_INFO=y 
CONFIG_GDB_SCRIPTS=y
CONFIG_DEBUG_KERNEL=y 
CONFIG_E1000=y

make menuconfig 开启e1000
4:sudo make -j4 (我的虚拟机配置了4核)
5:sudo make modules_install
6: sudo make install
执行4后会生成一个这样的文件
/home/zhaosongqiang/Documents/linux_code/latest/linux-stable/arch/x86/boot/bzImage
执行6后会根据linux当前版本生成一个类似的文件
/boot/initrd.img-5.16.0-rc2+

7:安装qemu

sudo apt-get install qemu
或者在有些高版本的ubuntu 上执行
sudo apt update #更新下下载源
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils

8:制作一个img的磁盘

dd if=/dev/zero of=/home/zhaosongqiang/rootfs.img bs=1G count=3
mkfs.ext4 rootfs.img

9:将8中制作的rootfs.img拷贝到vmware虚拟机的宿主机上,并为vmware虚拟机(ubuntu系统)添加一个CD 选择刚才拷贝的rootfs.img文件
10:启动qemu虚拟机(启动命令中root的值/dev/sr0可以通过lsblk确定,选择我们挂载的CD见下图2)

cd /home/zhaosongqiang/Documents/linux_code/latest
sudo qemu-system-x86_64 -kernel ./linux-stable/arch/x86/boot/bzImage -initrd /boot/initrd.img-5.16.0-rc2+ -m 4000 -append "root=/dev/sr0 nokaslr console=ttyS0" -nographic

在这里插入图片描述
11:设置网络
在这里插入图片描述
12:主机上选择一个共享文件夹挂载到QEMU虚拟机作为块设备

在ubuntu上创建一个文件夹 /my_directory
在qemu启动命令上加一个  -hdb fat:rw:/my_directory
在qemu虚拟机中执行:
1:mkdir -p /mnt/share
2: mount /dev/sda1 /mnt/share

13:安装并启动gdb 并attach 到运行的linux 上

apt-get install gdb
echo "add-auto-load-safe-path <kernel-dir>/vmlinux-gdb.py" >> ~/.gdbinit
cd /home/zhaosongqiang/Documents/linux_code/latest
sudo qemu-system-x86_64 -kernel ./linux-stable/arch/x86/boot/bzImage -initrd /boot/initrd.img-5.16.0-rc2+ -m 4000 -s -S -append "root=/dev/sr0 nokaslr console=ttyS0" -nographic
sudo gdb ./linux-stable/vmlinux
target remote :1234

下面这张图是通过gdb调试linux 查看一个进程的active_mm->mmap
在这里插入图片描述

下面贴上一些常用的命令:

**********************************环境搭建相关:**********************************
https://pnx9.github.io/thehive/Debugging-Linux-Kernel.html
mkinitramfs -o ramdisk.img
https://www.kernel.org/doc/html/latest/dev-tools/gdb-kernel-debugging.html
echo "add-auto-load-safe-path <kernel-dir>/vmlinux-gdb.py" >> ~/.gdbinit
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

**********************************启动相关:**********************************
cd /home/zhaosongqiang/Documents/linux_code/latest
qemu-system-x86_64 -kernel ./linux-stable/arch/x86/boot/bzImage -initrd ./ramdisk.img -m 1024 -s -S -append "nokaslr console=ttyS0" -nographic

sudo qemu-system-x86_64 -kernel ./linux-stable/arch/x86/boot/bzImage -initrd /boot/initrd.img-5.16.0-rc2+ -m 4000 -append "root=/dev/sr0 nokaslr console=ttyS0" -nographic


配置网络设置:
ip addr add 10.0.2.15/24 dev ens3
ip link set ens3 up
ip route add default via 10.0.2.2 dev ens3


sudo gdb ./linux-stable/vmlinux
target remote :1234

**********************************调试相关:**********************************
linux kernel 运行命令时gdb 命令窗口无法响应,需要在gdb  命令窗口输入: Ctrl+c
gdb 命令窗口运行时linux kernel暂停,需要在gdb 命令窗口输入: continue 

apropos lx_
获取指定task相关属性:p *$lx_task_by_pid(200)->active_mm->mmap
--------------------------------------------------------------
Ctrl+x+a :进入gdbtui 模式
	ctrl+p #previous command
	ctrl+n #next command
	ctrl+b #back the cursor
	ctrl+f #forward tthe cursor
--------------------------------------------------------------
设置gdb输出到指定文件
(gdb) set logging file <file name>
(gdb) set logging on
(gdb) p *$lx_task_by_pid(200)->active_mm->mmap
(gdb) set logging off
--------------------------------------------------------------
#在load_elf_binary  打断点
break load_elf_binary #load elf binary file and init mm_struct

参考:
https://wiki.qemu.org/Documentation/Networking#Network_Basics
https://www.kernel.org/doc/html/latest/dev-tools/gdb-kernel-debugging.html
https://pnx9.github.io/thehive/Debugging-Linux-Kernel.html
https://www.kernel.org/doc/html/latest/dev-tools/kunit/usage.html

如果要用eclipse编辑linux源码,将linux源码导入到eclipse后可能会出现源码中很多函数和macros无法index(因为默认的header文件路径是在/usr/include/linux 下这下面的header文件是给用户程序提供编译支持的,编译内核需要/usr/src/include/linux或者设置成linux源码中include目录)。参考:
HowTo use the CDT to navigate Linux kernel source
在这里插入图片描述

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐