1.1.运行环境:x86_64, Ubuntu-20.04.1, qemu
1.2.下载源码,安装必要的依赖;源码包linux, busybox都放在/home目录:
$ sudo apt update
$ sudo apt install build-essential
$ sudo apt install gcc-multilib
$ sudo apt install git
$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git //下载linux源码;
$ git clone git://git.busybox.net/busybox //下载busybox;
$ sudo apt install flex
$ sudo apt install bison
$ sudo apt install libncurses5-dev
$ sudo apt install pkg-config
$ sudo apt install libglade2-dev
$ sudo apt install libssl-dev
$ sudo apt install libelf-dev
1.3.编译内核;
$ cd /home/linux
$ make defconfig #配置内核(按默认选项配置)
$ make menuconfig #进入图形化的内核配置界面,自定义配置
进入图形化的内核配置界面后,接着按下面操作
1)按【↓】箭头键,找到最下面的 Kernel hacking,按【enter】键进入该配置项
2)按【↓】箭头键,找到 Compile-time checks and compiler options ,按【enter】键进入该配置项
不同的版本可能界面不一样:
在Debug information (Disable debug information)这里按enter;
选择Generate DWARF Version 5 debuginfo 会出现以下界面 //也可以尝试选择其他的;
1)按【↑】【↓】箭头键调整选项,找到子配置项,Provide GDB scripts for kernel debugging,也按【空格键】选中
2)连按两下【ESC】键,退出该配置项,再连按两下【ESC】键,退回配置主页。
3)找到并回车进入 Processor type and features 选项,再在接近底部的Build a relocatable kernel 项下,按【空格键】去掉配置项Randomize the address of the kernel image (KASLR)
4)多次连按【ESC】,退出配置,此时提示是否希望保存新的配置,回车选择Yes。回到终端,继续执行本文后面命令。
编译内核:
$ make //vmware,ubuntu上从git下载源码,初次编译内核,耗时28分钟;
1.4.配置 Busybox,生成配置文件;
$ make defconfig //先切换到busybox目录,配置 Busybox,生成配置文件(按默认选项配置)
$ make menuconfig //进入图形化的配置界面
进入图形化的配置界面后,接着按下面操作
1) 进入Setting --直接按【enter】进入配置组
2) 按【↓】箭头键,找到构建选项 build options
3) 按【↓】箭头键,找到构建选项下的 build static binary (no shared libs),按【空格键】,选中
4) 按下【esc】退出配置组
5) 再按下【esc】,提示保存修改,按【enter】键选择 yes 确认保存
6) 配置完成,回到终端.
编译busybox
$ make install -j2 //编译busybox
1.5.用 Busybox 制作根文件系统
$ sudo dd if=/dev/zero of=rootfs.img bs=1M count=100 //创建 100M 磁盘镜像 rootfs.img
$ sudo mkfs.ext4 rootfs.img //在磁盘镜像中创建 ext4 根文件系统
$ sudo mkdir rootfs
$ sudo mount -o loop rootfs.img rootfs //挂载根文件系统
$ cd rootfs/
$ sudo rm -rf lost+found/
$ sudo mkdir -pv {bin,sbin,etc/init.d,proc,sys,usr/{bin,sbin},tmp,dev} //{}内,不要有空格
$ sudo cp -drv /home/busybox/_install/* .
$ sudo chmod u+s bin/busybox //根文件系统上安装 busybox
创建系统配置文件 /etc/inittab
$ sudo vim inittab
inittab内容如下:
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::restart:/sbin/init
::shutdown:/bin/umount -a -r
创建系统设置脚本 /etc/init.d/rcS
$ sudo vim ./init.d/rcS
rcS内容如下:
#!/bin/sh
echo "INIT SCRIPT"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t debugfs debugfs /sys/kernel/debug
mount -t tmpfs tmpfs /tmp
mdev -s
mount -n -o remount,rw /
echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"
赋予rcS文件执行权限:
$ sudo chmod +x etc/init.d/rcS
卸载根文件系统
$ sudo umount rootfs
若卸载时提示target is busy,则执行fuser -v rootfs 查看占用rootfs的进程。
查看没什么特别大的问题,则执行fuser -k rootfs可以直接结束使用rootfs文件的进程。
再次卸载根文件系统sudo umount rootfs。
1.6.安装qemu
sudo apt-get install qemu-system-x86
1.在/home目录下创建文件:(注意这里所有的路径要灵活换成你所搭建环境的路径)
$ sudo vim ./.gdbinit
文件内容:
add-auto-load-safe-path /home/linux
2.qemu 运行虚拟机,其中:-s 参数:为虚拟机启动一个 gdbserver ,等待 gdb 客户端连接。默认 tcp 端口 1234 。-S 参数:挂起虚拟机,直到 gdb 客户端连接并 给出继续执行的指令。
sudo qemu-system-x86_64 -kernel /home/linux/arch/x86_64/boot/bzImage -hda /home/rootfs.img -append "console=ttyS0 root=/dev/sda" -nographic -s -S
3.另开一个shell,通过tcp端口1234执行gdb调试:
$ cd /home/linux
$ gdb vmlinux //自动进入gdb页面
(gdb) target remote :1234
(gdb) break start_kernel
(gdb) c
正常退出:1)先结束 qemu:Ctrl+A 松开后按 X 退出qemu; 显示如下
/ # QEMU: Terminated
2)再退出 gdb ,在 gdb 所在终端,输入quit
回车即可。
至此可以用 gdb进行调试了;以下部分为用图形化界面调试,习惯gdb命令行可不必理会。
1.install vscode
$ sudo dpkg -i code_1.67.1-1651841865_amd64.deb
修改配置文件:vscode任务栏,Run-->Add Configuration...
{
// 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",
}
]
}
3.以上,此时将断点设在init/main.c中的start_kernel函数中,然后Qemu 开启GDB调试,vscode start debug即可开始调试内核
参考:运行及调试Linux内核的方法_SuperSuperZ的博客-CSDN博客