配置VSCode跟踪调试Linux内核启动过程

配置VSCode

  1. 安装VSCode插件C/C++ Intellisense和C/C++ Themes。由于插件C/C++ Intellisense需要GNU Global,还需要使用如下命令安装GNUGlobal。

sudo apt install global
  1. 修改.vscode配置项,参考

https://github.com/mengning/linuxkernel/tree/master/src/kerneldebuging、
  1. 由于 Linux 内核高度定制化,所以没有办法直接通过配置 includePath 等让 Intellisense 正常提示,这里借助一个 Python 脚本来生成 compile_commands.json 文件帮助 Intellisense 正常提示(包括头文件和宏定义等)。在Linux源代码目录下直接运行如下命令就可以生成 compile_commands.json 了。

python ./scripts/gen_compile_commands.py

安装开发工具

sudo apt install build-essential
 
sudo apt install qemu # install QEMU#作为一个虚拟机
 
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev

下载内核源代码

此处建议直接去网站上下载,用axel会有一些问题

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

进入如下界面

配置VSCode跟踪调试Linux内核启动过程_第1张图片

按如下内容配置即可

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)

编译和运行内核

make -j$(nproc) # nproc gives the number of CPU cores/threads available
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

由于没有文件系统最终会kernel panic

配置VSCode跟踪调试Linux内核启动过程_第2张图片

注意:此处需要注释掉代码中的my_start_kernel(),否则系统会卡在这一步,不会往后执行

配置VSCode跟踪调试Linux内核启动过程_第3张图片

制作内存根文件系统

  1. 下载源代码

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
  1. 编译并安装

make menuconfig
make -j$(nproc) && make install

注意要编译成静态链接,不用动态链接库

Settings  --->
    [*] Build static binary (no shared libs)
  1. 制作内存根文件系统镜像

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/
  1. 准备init脚本文件放在根文件系统跟目录下(rootfs/init),添加如下内容到init文件(注意给脚本添加执行权限)

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome MengningOS!"
echo "--------------------"
cd home
/bin/sh
  1. 打包成内存根文件系统镜像

find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz 
  1. 测试挂载根文件系统,看内核启动完成后是否执行init脚本

qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz

如果执行成功,会显示如下

配置VSCode跟踪调试Linux内核启动过程_第4张图片

跟踪调试

(做到这一步才发现Ubuntu22调试有问题,后面换成了Ubuntu18)

  1. 在start_kernel处打上断点,启动调试

配置VSCode跟踪调试Linux内核启动过程_第5张图片
  1. 此处0号进程被创建

配置VSCode跟踪调试Linux内核启动过程_第6张图片
  1. 0号进程创建后就是内核初始化工作,继续跳过。start_kernel会执行一些初始化操作,包括初始化各种重要的数据结构、驱动程序、中断处理程序等,并建立好一些必要的核心数据结构,如物理内存管理器、虚拟内存管理器,以及进程调度器等,一直到最后剩余初始化函数

配置VSCode跟踪调试Linux内核启动过程_第7张图片
  1. 可以进入到函数里面看一下

配置VSCode跟踪调试Linux内核启动过程_第8张图片
  1. 里面还有一层,进入可以看到内核在此处产生第一个真正的进程(pid=1)

配置VSCode跟踪调试Linux内核启动过程_第9张图片
  1. rest_init执行结束后,start_kernel也就全部完成了

你可能感兴趣的:(linux)