转载 : https://blog.csdn.net/eidolon_foot/article/details/104905084
此调试在VisualBox虚拟机和PC都可进行。
操作系统:ubuntu 19.10(unbuntu镜像下载)
Linux内核:linux-5.5.9 (https://www.kernel.org/)
QEMU:qemu-4.2.0(https://download.qemu.org/)
GDB:gdb-9.1(https://download.qemu.org/)
busybox:busybox-1.31.1(https://busybox.net/)
参考:
https://blog.csdn.net/jasonLee_lijiaqi/article/details/80967912
https://blog.csdn.net/WANG__RONGWEI/article/details/79207536
1. 下载并解压
下载以上版本的文件到个人主文件夹,例如:/home/yong 。
运行命令 cd 进入个人主文件夹。
运行命令tar -xzvf 或者tar -xjvf或者tar xvf或者...解开归档文件。
2. 编译Linux内核
安装依赖:
-
sudo apt-get install aptitude
-
sudo apt install libncurses5-dev
-
sudo apt-get install libssl-dev
-
sudo apt install flex
-
sudo apt install bison
-
sudo apt install libelf-dev
进入解压后的linux-5.5.9内核目录,运行make menuconfig配置内核:
Kernel hacking里面,配置[*] Compile the kernel with debug info,选中选项。
Processor type and features里面,配置[ ] Randomize the address of the kernel image,取消选项。
编译:
-
make
-
make bzImage
如果不裁剪配置,会编译时间比较长。裁剪过的配置文件https://download.csdn.net/download/eidolon_foot/12268020,能编译快一些。
3.安装QEMU
通过apt-get安装:
sudo apt install qemu-system
或者下载源码编译安装。过程如下:
安装依赖:
-
sudo apt-get install libsdl2-2.0
-
sudo apt-get install libsdl2-dev
-
sudo apt-get install libpixman-1-dev
-
sudo apt-get install texinfo
-
sudo apt-get install libglib2.0-dev
编译安装:
-
./configure --enable-debug --target-list=x86_64-softmmu
-
sudo make
-
sudo make install
4.GDB
通过apt-get安装GDB:
sudo apt install gdb
或者下载源码编译安装(这种情况,后面调试时候可能会出现Remote 'g' packet reply is too long错误,需要修改源码remote.c文件,网上有许多如何修改的文章)。gdb-9.1源码编译过程:
建立目录:
mkdir ~/gdb
进入目录:
-
cd
-
cd gdb
配置:
-
~/gdb-9.1/configure --prefix=/home/yong/gdb
-
make
-
make install
执行:
~/gdb/bin/gdb
5
. busybox建立最小文件系统
配置busybox:
-
cd ~/busybox-1.31.1/
-
make defconfig
-
make menuconfig
“Setting”里面,配置 [*] Build static binary (no shared libs),选中此条。
编译安装:
-
make
-
make install
成功后,可以在busybox-1.31.1中看到生成的_install目录。通过下面的命令可以验证busybox是否安装正确:
./busybox ls
生成根文件系统:
将上一步生成的_install文件夹复制到其他位置
-
mkdir ~/ramdisk
-
cd
-
cd ramdisk
-
cp -r ~/busybox-1.31.1/_install/* .
设置初始化进程init
ln -s bin/busybox init
设置开机启动程序
创建一些程序运行所需要的文件夹
mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin},dev}
init程序会先访问etc/inittab文件,因此,需要编写inittab,指定开机需要启动的所有程序
-
cd etc
-
vim inittab
inittab文件的内容如下
-
::sysinit:/etc/init.d/rcS
-
::askfirst:-/bin/sh
-
::restart:/sbin/init
-
::ctrlaltdel:/sbin/reboot
-
::shutdown:/bin/umount -a -r
-
::shutdown:/sbin/swapoff -a
赋予可执行权限
chmod +x inittab
编写系统初始化命令
从inittab文件中可以看出,先执行的是/etc/init.d/rcS脚本,因此,生成rcS脚本
-
mkdir init.d
-
cd init.d
-
vim rcS
rcS文件的内容如下
-
#!/bin/sh
-
mount proc
-
mount -o remount,rw /
-
mount -a
-
clear
-
echo "Start......"
赋予可执行权限
chmod +x rcS
在rcS脚本中,mount -a 是自动挂载 /etc/fstab ,可以理解为挂载文件系统,因此还需要编写 fstab文件来设置文件系统。
-
cd ~/ramdisk/etc/
-
vim fstab
fstab文件内容如下
-
# /etc/fstab
-
proc /proc proc defaults 0 0
-
sysfs /sys sysfs defaults 0 0
-
devtmpfs /dev devtmpfs defaults 0 0
RAM Disk中相关文件的配置完成。
压缩生成文件镜像如下
-
cd ~/ramdisk
-
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img
生成的initramfs.img就是根文件系统。
测试根文件系统:
-
cd
-
qemu-system-x86_64 -kernel ~/linux-5.5.9/arch/x86/boot/bzImage -initrd ~/initramfs.img
我用VM虚拟机下运行,有时会出现kernel panic错误,多运行几次就正常了,可能是我的机器有点慢的原因。
6
. 调试内核
运行linux-5.5.9内核:
qemu-system-x86_64 -kernel ~/linux-5.5.9/arch/x86/boot/bzImage -initrd ~/initramfs.img -S -s -m 1024 -nographic
或者
qemu-system-x86_64 -kernel ~/linux-5.5.9/arch/x86/boot/bzImage -initrd ~/initramfs.img -S -s
打开另一个终端,运行GDB:
-
gdb ~/linux-5.5.9/vmlinux
-
target remote:1234
-
b start_kernel
-
c
可以看到gdb运行到start_kernel
断点处停下来了,可以使用gdb进行调试。
GCC和busybox 版本需要相应。例如,在busybox-1.31.1中date.c文件的stime在新的GCC中已经改为clock_settime,如果用老版本的gcc编译会因为找不到stime而链接失败。
VS code配置 (https://zhuanlan.zhihu.com/p/105069730)
// c/c++ , gdb debug , global
官网下载安装vscode:https://code.visualstudio.com
1. vscode打开kernel源码文件夹
2. 安装gdb debug插件
3. Debug->Open Configurations,做以下配置
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "kernel-debug",
"type": "cppdbg",
"request": "launch",
"miDebuggerServerAddress": "127.0.0.1:1234",
"program": "${workspaceFolder}/vmlinux",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"logging": {
"engineLogging": false
},
"MIMode": "gdb",
}
]
}
此时将断点设在init/main.c中的start_kernel函数中,然后Qemu 开启GDB调试,vscode start debug即可开始调试内核。