基于VS Code的Linux内核调试环境搭建及start_kernel跟踪分析

1、安装开发工具

sudo apt install build-essential
 
sudo apt install qemu # install QEMU#作为一个虚拟机
 
sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
#编译内核所需的依赖---一些基础库

2、下载内核源码

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

3、配置内核选项

make defconfig   # Default configuration is based on 'x86_64_defconfig'
make menuconfig  # 打开debug相关选项

按Enter回车进入“--->” ,“y”和"n"改动“[*] [ ]”来分别进行下面设置:

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)

4、编译和运行内核

make -j$(nproc) # nproc gives the number of CPU cores/threads available

# 测试一下内核能不能正常加载运行,因为没有文件系统最终会kernel panic
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

测试了一下出现了Kernel panic: 

5、制作内存根文件系统

        电脑加电启动首先由bootloader加载内核,内核紧接着需要挂载内存根文件系统,其中包含必要的设备驱动和工具,bootloader加载根文件系统到内存中,内核会将其挂载到根目录/下,然后运行根文件系统中init脚本执行一些启动任务,最后才挂载真正的磁盘根文件系统。

        我们这里为了简化实验环境,仅制作内存根文件系统。这里借助BusyBox 构建极简内存根文件系统,提供基本的用户态可执行程序。

        首先从https://www.busybox.net下载 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

make menuconfig  #记得要编译成静态链接,不用动态链接库

  Settings  --->
            [*] Build static binary (no shared libs)静态编译

 然后编译安装,默认会安装到源码目录下的 _install 目录中。

make -j$(nproc) && make install

然后制作内存根文件系统镜像,过程如下:

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/

注:我在linux-5.4.34文件夹下创建的rootfs文件夹,linux-5.4.34文件夹与busybox-1.31.1文件夹同级,都在/home/mjn目录下。如下图所示。

        接下来准备init脚本文件放在根文件系统跟目录下(rootfs/init),添加如下内容到init文件:(使用touch init 创建init脚本文件,再“vim init”打开init文件,再按i进入插入模式,粘贴进去,再按ESC进入命令模式,:wq保存并退出即可。)

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "Wellcome MajingnanOS!"
echo "--------------------"
cd home
/bin/sh

其中mount命令是对proc和sys进行挂载。

接下来对脚本添加可执行权限:

chmod +x init

打包成内存根文件系统镜像

find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz 

测试挂载根文件系统,看内核启动完成后是否执行init脚本(注:我的rootfs.cpio.gz放在了linux-5.4.34文件里面)

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

成功执行了init脚本。

6、配置VSCode调试Linux内核

        首先在linux系统下载vscode安装包,打开ubuntu自带的火狐浏览器下载:官方下载地址,选择.deb下载选项,这里我下载的是:

然后执行安装命令 sudo apt install ./<filename>.deb,我的文件对应的安装命令是:

sudo apt install ./code_1.76.2-1678817801_amd64.deb

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

sudo apt install global

接下来在VScode里搜索安装这几个扩展:

 

 准备在vscode中打开前面准备好的linux-5.4.34文件夹,需要做两件事情:

(1)命令行输入

python ./scripts/gen_compile_commands.py

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

(2)需要在linux-5.4.34文件夹下在此之前直接先手动放好配置文件:新建一个.vscode文件夹,(需要点击ctrl+h显示隐藏文件)把配置文件里的文件全部放入.vscode文件夹内:

接下来就可以在vscode里打开linux-5.4.34文件夹:可以看到.vscode配置文件夹已经出现了。

同时改一下tasks.json:跟前面文件放置的问题一致。(我的文件放置是这样改)

这下vscode的调试环境就配置好了。

7、跟踪分析

        因为linux内核的起点是"start_kernel"函数,因此先在start_kernel处打断点:点击运行和调试图标,在断点里增加函数断点:start_kernel,点击运行--启动调试,就可以从start_kernel开始进行跟踪分析啦。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫客36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值