庖丁解牛Linux系统分析读书笔记-搭建Linux内核调试环境

庖丁解牛Linux系统分析读书笔记-搭建Linux内核调试环境

获取源码

从 https://www.kernel.org 下载源码,得到你所选的内核版本对应的 tarball (tar.xz) 文件。
下载5.4版本

unxz linux-5.4.267.tar.xz
tar -xvf linux-5.4.267.tar

要求系统安装有qemu,以及gcc等(archlinux使用指令base-devel进行安装)
使用的gcc版本:gcc 版本 13.2.1 20230801 (GCC)

配置内核

常用的方式:
导出当前内核设置
将使用默认的 Arch 内核设置为自定义内核创建一个 .config 文件

$ zcat /proc/config.gz > .config

高级配置
• make menuconfig: 老的 ncurses 界面,被 nconfig 取代
• make nconfig: 新的命令行 ncurses 界面
• make xconfig: 用户友好的图形界面,需要安装 packagekit-qt5包。建议没有经验的用户使用此方法。
• make gconfig: 和 xconfig 类似的图形界面,使用 gtk.
推荐menuconfig或nconfig

调试内核所需配置
需要进行以下配置:

Kernel hacking  --->
     Compile-time checks and compiler options  ---> 
         [*] Compile the kernel with debug info
         [*]     Provide GDB scripts for kernel debugging


Processor type and features  --->
    [*] Randomize the address of the kernel image (KASLR) 

编译

make

make -jn # n表示用于编译的CPU核数

参考:https://wiki.archlinuxcn.org/wiki/%E5%86%85%E6%A0%B8/%E4%BC%A0%E7%BB%9F%E7%BC%96%E8%AF%91#%E7%BC%96%E8%AF%91

下面就算编译成功了。
在这里插入图片描述

问题:
编译过程有提示:没有bc指令,安装后即可正常编译
bc就是一款用于任意精度计算的语言。

man bc
NAME
       bc - An arbitrary precision calculator language

SYNTAX
       bc [ -hlwsqv ] [long-options] [  file ... ]

DESCRIPTION
       bc is a language that supports arbitrary precision numbers with interactive execution of statements.  There are some similarities
       in  the  syntax  to  the C programming language.  A standard math library is available by command line option.  If requested, the
       math library is defined before processing any files.  bc starts by processing code from all the files listed on the command  line
       in the order listed.  After all files have been processed, bc reads from the standard input.  All code is executed as it is read.
       (If a file contains a command to halt the processor, bc will never read from the standard input.)

       This  version of bc contains several extensions beyond traditional bc implementations and the POSIX draft standard.  Command line
       options can cause these extensions to print a warning or to be rejected.  This document describes the language accepted  by  this
       processor.  Extensions will be identified as such.

编译结果验证

使用qemu启动内核,总中会曝出Kernel panic,说明内核是可以正常加载。(根据提示可以看出是因为没有根文件系统导致的)

$ qemu-system-x86_64 -kernel arch/x86/boot/bzImage

在这里插入图片描述

制作根文件系统

qemu-system-x86_64模拟x86_64架构,该架构计算机在启动过程:

  1. 首先Bios加载bootloader(如grub)
  2. 由bootloader加载内核,并将内核挂载到内存的根文件系统(就是将内核加载到内存中),包含必要的驱动和工具
  3. 内核加载
  4. 内核执行完毕后,然后内核在内存根文件系统中执行一些初始化任务
    a. 常见的有systemd,busybox
    b. 比如busybox,就是根据inittable配置启动各种任务,下面使用busybox作为init系统
    c. busybox作为一个程序,本身保存就在一个文件系统中,运行的时候也是在一个文件系统中,也就是我们说的内存文件系统 ,这就是我们需要创建的
  5. 最后init根据配置挂载真正的磁盘根文件系统(这个就是我们用户使用的文件系统)
    在这里插入图片描述

为了简化实验过程,这里借助BusyBox构建内存根文件系统

BusyBox安装

busybox:在单个小型可执行文件中为嵌入式系统提供了许多常见的 UNIX 实用程序。软件包还包含 runit;
安装busybox
busybox提供了一个基本的工具包,可以作为linux内核的前端供用户使用,这里同时用它实现系统init处理
官网下载源码,编译安装:https://busybox.net/downloads/
使用静态编译的目的是为了方便迁移,而不依赖当前的系统其他的其他组件

$ tar -jxvf buysbox-1.36.1.tar.bz2

$ make menuconfig # 配置busybox  注意:编译称静态连接库,而不是动态链接库,如下配置项:
Settings ------>
    [*] Build static binary (no shard libs)

$ make && make install    # 默认安装在源码的 _install/ 目录下

制作根文件系统

busybox的安装结果,就是我们根文件系统的基础,将busybox安装结果的全部全部拷贝到rootfs下
rootfs就是我们根文件系统的根目录

$ mkdir rootfs    # 作为根文件系统的根目录

将安装的busybox复制到根文件系统
$ cp busybox-1.36.1/_install/* rootfs/ -rf

$ cd rootfs/
$ mkdir dev proc sys home
$ sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/

制作init脚本,直接放在根目录下(/rootfs/init),文件名为:init

#!/bin/sh
mount -t proc nono /proc
mount -t sysfs nono /sys

echo "welcome MengningOS!"
echo "-------------------"

cd home

/bin/sh

在这里插入图片描述

将rootfs打包成文件系统镜像
在rootfs目录下执行

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

挂载根文件系统启动

可以开到init脚本支持执行,内容被答应了出来

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

在这里插入图片描述

移植完busybox后开机启动,在终端中打印出一条:/bin/sh: can’t access tty; job control turned off信息

解决系统启动的问题

参考:https://blog.csdn.net/zhanzheng520/article/details/10355461
问题分析:
首先来了解下inittable文件,该文件保存在/etc/inittable
如果存在/etc/inittable文件,Busybox init 程序解析它,然后按照他的指示创建各种子进程,否则使用默认的配置创建子进程.
/etc/inittable文件中每个条目用来定义一个子进程,并确定它的启动方法,格式定义如下:
:::

例如:
ttySAC0::askfirst:-/bin/sh

对于Busybox init进程,上述各个字段作用如下:1:2:3:4

  1. 表示这个子进程要使用的控制台(既标准输入、标准输出、标准错误设备)。若果省略,则使用与init进程一样的控制台
  2. 对于busybox init程序,这个字段没有意思,可以省略。
  3. 表示init进程如何控制这个子进程。
  4. 要执行的程序,它即可执行程序,也可以是脚本
    如果字段前有“-”字符,这个程序被称为“交互的”
    所以:::sysinit:/bin/sh 使用的是和init进程一样的控制台,而我们的console使用的是ttySAC0,所以就报错了。

问题解决

  1. 增加文件:/etc/inittable
    下面不一定是tty0,只要是dev目录下有的tty设备都可以
::sysinit:/etc/init.d/rcS
tty0::sysinit:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
  1. 将init文件的内容,复制到/etc/init.d/rcS
    不知道原因,init文件不能没有(哪怕是空的都没问题),否则无法启动
#!/bin/sh
mount -t proc nono /proc
mount -t sysfs nono /sys

echo "welcome MengningOS!"
echo "-------------------"

cd home

/bin/sh 这个不用了,在inittable中定义他的启动模式

重新打包内存根文件系统镜像,启动内核,结果如下:
可以发现,init脚本的日志正常被打印出来,系统也可以正常进入了。
在这里插入图片描述

还是有一些瑕疵,提示/init执行异常,然后提示执行/sbin/init才最终成功的
下面是直接用/sbin/init替换之前新建的init脚本,可以看到直接运行成功,不会报错了
在这里插入图片描述

跟踪调试Linux内核

使用gdb跟踪调试linux内核,有两个参数:
-s :表示在端口1234创建一个gdb-server,可以使用-gdb tcp:xxxx 来指定其他端口
-S:表示启动后暂停虚拟机,等待gdb执行continue指令

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

可以看到qemu启动后立刻暂停了
在这里插入图片描述

另起一个终端,启动gdb与上面的qemu连接
在linux源码目录下:

  1. 执行:gdb vmlinux
    右边就是启动gdb,使用target remote:1234连接到远程的gdb服务器上
    并在内核的初始化方法上打上断点
    在这里插入图片描述

  2. 按下C后,系统继续执行。
    可以看到系统在断点处,停了下来,使用bt/list等gdb指令,可以查看此时的系统状态
    在这里插入图片描述
    在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值