基于VS Code的Linux内核调试环境搭建及start_kernel跟踪分析
Ubuntt使用18.04.6版本
安装开发工具
sudo apt install build-essential
sudo apt install qemu # install QEMU
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
下载内核源码
sudo apt install axel
axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
xz -d linux-5.4.34.tar.xz
tar -xvf linux-5.4.34.tar
cd linux-5.4.34
配置内核选项
make defconfig # Default configuration is based on 'x86_64_defconfig'
make menuconfig
# 打开debug相关选项
Kernel hacking --->
Compile-time checks and compiler options --->
[*] Compile the kernel with debug info
[*] Provide GDB scripts for kernel debugging
[*] Kernel debugging
# 关闭KASLR,否则会导致打断点失败
Processor type and features ---->
[] Randomize the address of the kernel image (KASLR)
保存所选择的配置到myconfig.config并加载
编译和运行内核
make -j$(nproc) # nproc gives the number of CPU cores/threads available
# 测试一下内核能不能正常加载运行,因为没有文件系统最终会kernel panic
qemu-system-x86_64 -kernel arch/x86/boot/bzImage
制作根文件系统
电脑加电启动首先由bootloader加载内核,内核紧接着需要挂载内存根文件系统,其中包含必要的设备驱动和工具,bootloader加载根文件系统到内存中,内核会将其挂载到根目录/下,然后运行根文件系统中init脚本执行一些启动任务,最后才挂载真正的磁盘根文件系统。
我们这里为了简化实验环境,仅制作内存根文件系统。这里借助BusyBox 构建极简内存根文件系统,提供基本的用户态可执行程序。
1)安装busybox
axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2
tar -jxvf busybox-1.31.1.tar.bz2
cd busybox-1.31.1
2)设置静态链接
make menuconfig
# 记得要编译成静态链接,不用动态链接库。
Settings --->
[*] Build static binary (no shared libs)
3)编译安装
# 安装到源码目录下的 _install 目录中。
make -j$(nproc) && make install
4)制作内存根文件系统镜像
注意切换文件夹返回到Linux文件夹下
mkdir rootfs
cd rootfs
cp ../busybox-1.31.1/_install/* ./ -rf
mkdir dev proc sys home
sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
5)准备init脚本
#编写init脚本
vim init
#以下为init内容
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome 376OS!"
echo "--------------------"
cd home
/bin/sh
给init脚本添加可执行权限并打包测试
#给inti脚本添加可执行权限
chmod +x init
#打包成内存根文件系统镜像
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
#返回上一级
cd ../
#测试挂载根文件系统
qemu-system-x86_64 -kernel ./arch/x86/boot/bzImage -initrd rootfs.cpio.gz
可以看到,init脚本被执行。
wellcome376OS!
配置vscode调试linux内核
在linux-5.4.34下执行
python ./scripts/gen_compile_commands.py
使用vscode打开当前文件夹
同时,在linux-5.4.34文件夹下建立.vscode文件夹,并配置文件
跟踪分析
在start_kernel()处打断点,进行调试。
系统在创建0号进程后,执行了一系列初始化操作。
最终到达
在该函数中,分别执行了
创建了1号进程(用户进程的祖先)和2号进程(内核进程的祖先)
其中在2号进程中,在完成初始化后,会一直查询是否需要建立新的内核线程,最终执行,保持在轮询状态,在系统不需要调度的时候保持在idle态。
学号后三位:376