lab3:基于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相关选项

出现如下界面
在这里插入图片描述
修改其中的配置:

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) 
qemu-system-x86_64 -kernel arch/x86/boot/bzImage

在这里插入图片描述
出现kernel panic

5.制作内存根文件系统

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

在这里插入图片描述
编译安装

make -j$(nproc) && make install

6.制作根文件系统镜像

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/

7.编写init脚本

将init脚本文件放在根文件系统跟目录下

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

对proc和sys进行挂载

chmod +x init

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

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

运行

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

在这里插入图片描述

8.配置vscode并调试linux内核

由于 Linux 内核高度定制化,所以没有办法直接通过配置 includePath 等让 Intellisense 正常提示,这里借助一个 Python 脚本来生成 compile_commands.json 文件帮助 Intellisense 正常提示(包括头文件和宏定义等)

python ./scripts/gen_compile_commands.py

在断点里增加函数断点:start_kernel,运行并启动调试
在这里插入图片描述
start_kernel函数会执行一系列初始化操作,其中包括初始化各种重要的数据结构、驱动程序、中断处理程序等。在此阶段,内核会创建一些必要的核心数据结构,例如物理内存管理器、虚拟内存管理器以及进程调度器等。

rest_init
在这里插入图片描述
在这里插入图片描述

start_kernel的结尾是arch_call_reset_init(),这个函数执行了reset_init()函数,进入reset_init函数内部,并且这个函数是由0号进程执行的。在rest_init函数中,内核将通过下面的代码产生第一个真正的进程。

kernel_thread函数是通过_do_fork函数来创建进程的
在这里插入图片描述
在新线程(进程)中运行kernel_init()函数, 在kernel_init()函数里面调用了run_init_process函数
在这里插入图片描述

kernel_init()最终会通过do_execve系统调用来执行根文件系统下的/sbin/init文件

然后是2号进程的创建,2号进程比所有内核进程最早创建,而kernel_thread创建了2号进程,同时进程执行的函数是kthreadd():
在这里插入图片描述2号进程在不停地查看是否有需要创建的内核进程,如果kthread_create_list不空即有需要创建的内核进程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值