0%

编译调试Linux内核

编译环境

本文基于 Ubuntu 18.04.2,对Linux 4.20内核进行了构建,然后在qemu下启动。 参考文档:

编译过程

编译内核

源码下载:https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.20.tar.gz

下载后解压,然后安装几个依赖即可:

1
2
3
4
tar -xvf linux-4.20.tar.gz

apt install libncurses5-dev bison flex
apt install libelf-dev libssl-dev
编译前先要进行config:
1
2
3
cd linux-4.20
ARCH=x86_64 make defconfig
make menuconfig
需要打开的地方比较多,而且按目前的config来编译的内核,调试时单步还是有些“跳”,可能还需要再摸索下。
1
2
3
4
5
6
7
Kernel hacking ---> Compile-time checks and compiler options ---> Compile the kernel with debug info ---> yes
Kernel hacking ---> Compile-time checks and compiler options ---> Provide GDB scripts for kernel debugging ---> yes
General setup ---> Configure standard kernel features ---> yes
General setup ---> Configure standard kernel features ---> Load all symbols for debugging/ksymoops ---> yes
General setup ---> Configure standard kernel features ---> Include all symbols in kallsyms ---> yes
General setup -> Compiler optimization level (Optimize for performance) ---> Optimize for size
Kernel hacking ---> Memory Debugging ---> KASan: runtime memory debugger ---> yes
最后就是编译了,最后的"2"代表CPU核数,可以用"nproc"命令查看。构建好的内核为 "linux-4.20/arch/x86_64/boot/bzImage" 。
1
ARCH=x86_64 make -j 2

创建initramfs

光有内核还不够,再用debootstrap来创建一个initramfs,命令中的"xenial"是Ubuntu 16.04的代号:

1
debootstrap --include linux-image-generic xenial debootstrap http://archive.ubuntu.com/ubuntu
debootstrap目录创建好后,chroot进行切换,然后执行一些添加用户之类的操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
# chroot
chroot debootstrap

# 修改root密码
passwd root

# 添加用户,可选
/usr/sbin/adduser user

# 将根文件系统设置为可读写
cat << EOF | tee "debootstrap/etc/fstab"
/dev/vda / ext4 errors=remount-ro,acl 0 1
EOF
最后,将debootstrap目录创建为qcow2镜像:
1
virt-make-fs --format qcow2 --size +1G --type ext4 debootstrap xenial-debootstrap.ext4.qcow2
使用qemu启动和调试 -----------

注:下面的qemu和gdb最好都在screen中新开会话执行,这样不阻塞你的ssh会话。

编译好的kernel配合initramfs可以直接在qemu下启动:

1
2
3
4
qemu-system-x86_64 -kernel linux-4.20/arch/x86_64/boot/bzImage \
-drive file=xenial-debootstrap.ext4.qcow2 \
-net nic -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::9999-:9999,hostfwd=tcp::8000-:8000 \
-nographic -append "root=/dev/sda console=ttyS0"
如果要配合gdb调试,则添加"-s -S"参数:
1
2
3
4
qemu-system-x86_64 -kernel linux-4.20/arch/x86_64/boot/bzImage \
-drive file=xenial-debootstrap.ext4.qcow2 \
-net nic -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::9999-:9999,hostfwd=tcp::8000-:8000 \
-nographic -append "root=/dev/sda console=ttyS0" -s -S
带上"-s -S"参数后qemu会停止等待调试器,在宿主机中进入到linux-4.20目录启动"gdb vmlinux",然后通过默认的1234端口远程连接到qemu即可。
1
2
gdb vmlinux
target remote localhost:1234
其它的gdb下断点,continue之类的,就跟gdb调试其它普通程序一样,就不再多做介绍了。在启动的qemu中执行"shutdown -h now"可以“关机”退出qemu。