Experimental preparation
在 Github 上下载对应的实验文件:linux-kernel-labs/linux: Linux kernel source tree (github.com)
在 tools/labs 目录中输入命令:
1 | make clean |
然后在 skels/kernel_modules 目录中就会有实验文件:
1 | ➜ labs git:(master) ✗ ls skels/kernel_modules/ |
Booting the virtual machine
虚拟机基础结构摘要:
~/src/linux:Linux 内核源代码,编译模块需要~/src/linux/tools/labs/qemu:用于生成和运行 QEMU VM 的脚本和辅助文件
为了启动虚拟机,我们需要在 ~/src/linux/tools/labs 目录中使用 make boot 命令:
1 | ➜ labs git:(master) ✗ make boot |
在默认情况下,您不会收到提示或任何图形界面,但您可以使用 minicom 或屏幕连接到虚拟机公开的控制台:
- 在
~/src/linux/tools/labs目录中使用minicom -D serial.pts:
1 | ➜ labs git:(master) ✗ minicom -D serial.pts |
1 | Welcome to minicom 2.7.1 |
- 要访问虚拟机,请在登录提示符下输入用户名 root,无需输入密码
- 虚拟机将使用 root 帐户的权限启动
1 | Poky (Yocto Project Reference Distro) 2.3 qemux86 /dev/hvc0 |
Adding and using a virtual disk
在目录中,您有一个新的虚拟机磁盘,位于文件 ~/src/linux/tools/labs/mydisk.img,我们要将磁盘添加到虚拟机中,并在虚拟机中使用它
- 如果没有
mydisk.img文件,则在如下网站中下载:mydisk.img
修改 ~/src/linux/tools/labs/qemu/Makefile,在对应位置添加如下代码:
1 | -drive file=$(YOCTO_IMAGE),if=virtio,format=raw \ |
启动虚拟机,创建目录并尝试挂载新磁盘
- 已经向 qemu 添加了两个磁盘(
disk1.img和disk2.img)
1 | root@qemux86:~# /dev/vd |
- vda 是根分区,vdb 是
disk1.img,vdc 是disk2.img,vdd 是mydisk.img - 无需在
/dev中手动创建新磁盘的条目,因为虚拟机使用 devtmpfs(在 Linux 内核启动早期建立一个初步的/dev,令一般启动程序不用等待 udev) - 使用
mount命令进行挂载:
1 | mkdir /test |
- 结果挂载失败了(
/test中并没有出现mydisk.img中的文件),我们无法挂载虚拟磁盘的原因是,我们在内核中没有支持格式化的文件系统 - 您需要识别 mydisk.img 的文件系统,并编译对该文件系统的内核支持
1 | ➜ labs git:(master) ✗ file mydisk.img |
- 您需要在内核中启用 btrfs 支持并重新编译内核映像(退出前记得 save)
1 | make menuconfig |
1 | root@qemux86:~ |
GDB spelunking
使用 gdb 显示创建内核线程 kernel_thread 的函数的源代码
- 使用 gdb 查找内存中 jiffies 变量的地址及其内容
- 该变量保存自系统启动以来的计时周期数
要跟踪 jiffies 变量的值,请在 gdb 中使用动态分析,方法是:
- 先启动虚拟机
- 然后运行
make gdb命令
PS:由于我这里的环境有点问题,所以我使用了 gdb vmlinux 外加 target remote :1234 的形式来进行调试(也可以参考一下)
1 | pwndbg> x/gx & jiffies |