1. 前置安装
1.1 编译好的内核
参考:
https://blog.csdn.net/qq_51950769/article/details/148596916
1.2 编译busybox
BusyBox 是一个非常轻量级的多合一工具箱,常被称为“Linux 的瑞士军刀”。
简单来说:
它把很多常用的 Linux 命令(比如 ls、cp、mv、sh、mount 等)集成到一个单一的可执行文件里。适合用于资源有限的环境,比如嵌入式系统、initramfs、恢复系统等。
为什么用 BusyBox?
- 体积小:比安装完整的 GNU 工具链省空间很多;
- 方便:一个文件搞定常用命令;
- 灵活:可以自定义编译,裁剪只需要的命令。
# 下载源码
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xjf busybox-1.36.1.tar.bz2
cd busybox-1.36.1# 配置(选择你想要的功能)
make menuconfig# 编译
make -j$nproc# 安装到指定目录(方便打包initramfs)
make CONFIG_PREFIX=../busybox-root install# 或者默认安装, 后续制作根文件系统采用这种方式
make install
成功安装后:
查看安装目录的文件,tree
:
1.3 根文件系统的制作
根文件系统提供操作系统运行所需的基本工具和环境。它包含启动程序(如 init),负责启动用户空间进程。
没有根文件系统,内核是“裸”的,无法完成完整的系统启动和运行;根文件系统为系统提供了完整的用户空间环境。
- 准备根文件系统目录
进入到busybox的目录
cd busybox-1.36.1/
root@ubantu64:~/busybox-1.36.1# ls
applets busybox_ldscript.README.txt configs editors INSTALL mailutils miscutils procps shell util-linux
applets_sh busybox.links console-tools examples klibc-utils Makefile modutils qemu_multiarch_testing size_single_applets.sh
arch busybox_unstripped coreutils findutils libbb Makefile.custom networking README sysklogd
archival busybox_unstripped.map debianutils include libpwdgrp Makefile.flags NOFORK_NOEXEC.lst runit testsuite
AUTHORS busybox_unstripped.out docs init LICENSE Makefile.help NOFORK_NOEXEC.sh scripts TODO
busybox Config.in e2fsprogs _install loginutils make_single_applets.sh printutils selinux TODO_unicode
root@ubantu64:~/busybox-1.36.1# cd _install/
root@ubantu64:~/busybox-1.36.1/_install##创建目录
mkdir -p etc/init.d mnt tmp sys dev proc
结果:
- 创建文件系统表(fstab)
vim etc/fstab
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
如图:
- 创建启动脚本rcS
vim etc/init.d/rcSecho -e "Welcome to tinyLinux"
/bin/mount -a
mount -o remount,rw /
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
如图:
给rcS可执行权限chmod 755 rcS。
- 创建初始化程序配置文件inittab
vim etc/inittab::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
如图:
- 创建设备文件节点
cd dev
mknod console c 5 1
mknod null c 1 3
mknod tty1 c 4 1
- 镜像制作
(1) 创建一个空的镜像,并把这个镜像文件格式化为ext4
(2) 挂载到一个空的目录,并把_install/*等启动文件复制到这个镜像中
(3) 卸载镜像文件
(4) 使用gzip进行压缩
# 先创建一个空的镜像并格式化为ext4
mkdir ~/image
cd ~/image
dd if=/dev/zero of=./rootfs.ext4 bs=1M count=32
mkfs.ext4 rootfs.ext4
# 创建一个空目录fs
mkdir fs
# 挂载到fs,并复制启动文件
mount -o loop rootfs.ext4 ./fs
cp -rf busybox-1.36.1/_install/* ./fs
#卸载镜像文件
umount ./fs
# 使用gzip压缩
gzip --best -c rootfs.ext4 > rootfs.img.gz
最终结果:
1.4 安装qemu-system-x86_64
qemu-system-x86_64
是什么?
qemu-system-x86
是 QEMU 提供的一个用于模拟 x86 架构(如 x86_64 或 i386)计算机系统的可执行程序。简单来说:它可以在你的电脑上虚拟出一个完整的 x86 电脑,用来运行操作系统、测试内核、开发系统级软件等。
apt install qemu-system-x86
2. 内核调试
进行内核调试,我们需要使用两个命令:
2.1 qemu-system-x86_64
qemu-system-x86_64
主要用来启动一个内核。
qemu-system-x86_64 \-kernel ~/linux-5.10.126/arch/x86/boot/bzImage \-initrd ~/kernal/rootfs.img.gz \-append "root=/dev/ram init=/linuxrc" \-serial file:output.txt
参数解释:
-kernel
指定要加载的 Linux 内核镜像(通常是 bzImage 格式)。-initrd
:指定 initrd(初始化内存盘)文件,系统启动时会加载到内存中,通常用于提供根文件系统。-append
:传递给内核的启动参数,这里是指定root=/dev/ram:告诉内核从 RAM 磁盘(initrd)挂载根文件系统。
init=/linuxrc:指定初始化进程为 /linuxrc。-S
:启动时暂停 CPU-s
:在 TCP 端口 1234 上开启 GDB 服务器
扩展参数:
-nographic
:禁用图形输出,所有输出(包括串口输出)将重定向到终端(即你运行命令的终端窗口),用于无头(headless)运行。-smp
是 QEMU 中用于指定虚拟机的 CPU 配置的参数,全称是 “Symmetric Multi-Processing”(对称多处理)。-m
是 QEMU 中用于指定 虚拟机内存大小 的参数。-cpu
是 QEMU 中用于指定虚拟 CPU 类型和特性的参数。-enable-kvm
,用于启用 KVM(Kernel-based Virtual Machine)硬件加速。-serial
: 串口(Serial Port):在 QEMU 虚拟机中,串口是一个虚拟的通信接口,通常用于内核调试、系统日志输出或与外部工具交互。file:output.txt:将虚拟机的串口输出写入到当前目录下的 output.txt 文件中(如果文件不存在会自动创建,已存在则会覆盖)。
不使用图像化启动命令:
qemu-system-x86_64 \-kernel ~/linux-5.10.126/arch/x86/boot/bzImage \-initrd ~/kernal/rootfs.img.gz \-append "root=/dev/ram init=/linuxrc console=ttyS0" \-nographic \-serial mon:stdio \-monitor none
2.2 gdb
执行:
gdb vmlinux
在执行:
target remote :1234
此时qemu中跑的linux内核:
最后在提醒:想调试的话,最好把Makefile中的编译选项全部从O2
改为O1
:
3 参考文章
https://zhuanlan.zhihu.com/p/17345710829
https://blog.csdn.net/weixin_37867857/article/details/88205130