使用VSCode对Linux内核调试环境搭建和start_kernel跟踪分析

一、环境搭建

  1. 安装 build-essential

    sudo apt install build-essential
    

    build-essential是一个Ubuntu的软件包,包含了GNU编译器集合,GNU调试器,和其他编译软件所必需的开发库和工具。这个软件包是C语言的开发包,包含了gcc、make、gdb和libc函数库等很多工具。

  2. 安装 qemu

    sudo apt install qemu 	
    

    qemu是一款通用且免费的虚拟机;在这里用于安装重构的linux内核;

  3. 安装一些linux下的开发库

    sudo apt install libncurses5-dev bison flex libssl-dev libelf-dev
    

    其中,libncurses5-dev是一个开发库,它提供了一些函数,用于在终端上显示文本界面。
    bison是一个解析器生成器,它可以将上下文无关文法转换为解析器。
    flex是一个快速的词法分析器生成器,它可以将正则表达式转换为词法分析器。
    libssl-dev是一个安全套接字层(SSL)开发库,它提供了一些函数,用于加密和解密数据。
    libelf-dev是一个ELF(可执行和链接格式)开发库,它提供了一些函数,用于读取和修改ELF文件。

  4. 下载内核的源码并解压

    sudo apt install axel
    axel -n 20 https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.4.34.tar.xz
    

    在这里插入图片描述

  5. 配置内核相关选项

```
make defconfig 
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/06bb7e01b1e84b189f173fd5efed98f3.png)
```
make menuconfig  # 打开debug相关选项
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/a31f45cf6b4d47268e2404c8ce792674.png)
配置好后进行编译
![在这里插入图片描述](https://img-blog.csdnimg.cn/9e0c03643aa04cf59cd13ee0ad9ad6f5.png)

二、 制作内存根文件系统

  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 -j$(nproc) && sudo make install
    
  3. 制作根文件系统镜像

    mkdir rootfs # 在/linux-5.4.34文件夹下新建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/
    
  4. 给init添加权限并打包内存根文件系统镜像

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

    在这里插入图片描述

三、VSCode断点分析

1. 安装vscode和相关插件

```
sudo apt install ./code_1.76.1-1678294265_amd64.deb
sudo apt install global
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/08175344417343c4861d5fcf00767b1a.png)
  1. 使用vscode打开linux目录并添加断点
    在这里插入图片描述
    在断点处成功停了下来
    在这里插入图片描述

2. 调试分析

设置另一个断点在 rest_init 函数处,并继续执行直到该断点被触发。可以看到,rest_init 是在 start_kernel 函数的结尾调用的。在 main.c 中找到 start_kernel 函数,它是内核启动的起点。浏览 start_kernel 函数,可以看到 init_task 变量被初始化,它类似于之前分析 mykernel 时的第一个进程的 PCB。此外,还有许多其他模块的初始化工作,因为每个启动点都涉及到复杂的模块,而且内核非常庞大,包括许多模块。在研究内核的某个模块时,需要了解 start_kernel 函数,因为内核的主要模块的初始化工作都在该函数中调用。

在 start_kernel 函数中,有许多设置的内容,其中包括 trap_init 函数的调用,涉及一些初始化中断向量。只需要查看 arck_x86 的代码,它在 set_intr_gate 设置了许多中断门和硬件中断。start_kernel 函数的最后一句是 rest_init,内核启动完成后,调用 call_cpu_idle,当系统没有需要执行的进程时,就调用 idle 进程。

1. trap_init()
在 start_kernel 函数中还调用了 trap_init 函数来初始化中断处理程序和中断向量表。这个函数在 arch/x86/kernel/traps.c 文件中定义,主要功能是通过 set_intr_gate 函数将中断向量表的项设置成对应的中断处理函数。在 trap_init 中,还会初始化系统调用(syscall)的中断处理函数,以及初始化各个异常的中断处理函数。

2. mm_init()
在 start_kernel 函数中还调用了 mm_init 函数来初始化内存管理系统。这个函数主要是用来初始化内核代码所占用的地址空间,并初始化虚拟内存系统。在 mm_init 中,还会初始化物理内存管理系统,包括将整个物理内存空间映射到内核地址空间中,并为每个进程创建一个页表,以便实现虚拟内存的管理。

3. sched_init()
在 start_kernel 函数中还调用了 sched_init 函数来初始化进程调度系统。这个函数主要是用来初始化进程控制块(PCB)和进程调度队列,以及初始化各个进程调度算法。在 sched_init 中,还会初始化内核线程的 PCB 和进程调度队列,以便它们也能够被进程调度系统管理。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值