如何制作文件系统并用qemu运行linux内核

本文详细介绍如何从零开始构建一个简单的Linux系统,包括编译BusyBox、制作文件系统镜像及使用QEMU运行内核等步骤。

上一文我们介绍了如何编译内核和busybox:
如何编译Linux内核源码?

本文介绍如何制作一个简版的文件系统、制作fs镜像文件并最终通过qemu将linux内核运行起来!


制作一个简版文件系统

编译完成后的busybox就安装在源码根目录下的_install目录了,我们进入_install目录,补充一些必要的文件或目录,相关的shell命令如下:

$ mkdir -p etc dev mnt proc sys tmp mnt
$ mkdir -p etc/init.d/

$ mkdir etc dev mnt
$ mkdir -p proc sys tmp mnt
$ mkdir -p etc/init.d/
$ vim etc/fstab
proc        /proc           proc         defaults        0        0
tmpfs       /tmp            tmpfs      defaults        0        0
sysfs       /sys            sysfs        defaults        0        0
$ vim etc/init.d/rcS
echo -e "Welcome to tinyLinux"
/bin/mount -a
echo -e "Remounting the root filesystem"
mount  -o  remount,rw  /
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
$ chmod 755 etc/init.d/rcS
$ vim etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
$ chmod 755 etc/inittab
$ cd dev
$ sudo mknod console c 5 1
$ sudo mknod null c 1 3
$ sudo mknod tty1 c 4 1 

制作根文件系统镜像文件

思路:

  1. 先制作一个空的镜像文件;
  2. 然后把此镜像文件格式化为ext3格式
  3. 接着把此镜像文件挂载,并把根文件系统复制到挂载目录
  4. 卸载该镜像文件。
  5. 打成gzip包。
#!/bin/bash
rm -rf rootfs.ext3
rm -rf fs
dd if=/dev/zero of=./rootfs.ext3 bs=1M count=32
mkfs.ext3 rootfs.ext3
mkdir fs
mount -o loop rootfs.ext3 ./fs
cp -rf ./_install/* ./fs
umount ./fs
gzip --best -c rootfs.ext3 > rootfs.img.gz

最终生成的文件系统镜像名字为:rootfs.img.gz

准备好了内核和文件系统镜像,接下来就是见证奇迹的时刻!

qemu运行linux内核

$ qemu-system-x86_64 \
  -kernel ./linux-4.9.229/arch/x86_64/boot/bzImage  \
  -initrd ./busybox-1.30.0/rootfs.img.gz   \
  -append "root=/dev/ram init=/linuxrc"  \
-serial file:output.txt

img

这样一个完整的最小linux系统就起来啦.
在这里插入图片描述

<think> 首先,用户的问题是关于在MacBook Pro上安装Docker编译Linux内核并使用QEMU启动内核进行调试的方法。用户提供了几个引用,我必须参考这些引用,但它们不是直接相关的。引用[1]是关于在Docker中运行macOS的,引用[2]是关于休眠功能的,引用[3]是关于在M1 MacBook上使用Docker编译内核并用QEMU启动的。引用[3]似乎最相关,因为它涉及M1 MacBook、Docker、编译内核QEMU启动。 从引用[3]:"M1 macbook上安装docker 编译内核 并使用qemu启动内核。。然后通过下面命令生成rootfs ..." 这表明在M1 MacBook上使用Docker编译内核并用QEMU启动。 用户使用的是MacBook Pro,可能不是M1,但由于引用[3]是基于ARM的M1,我应该确保方法适用于标准的MacBook Pro,包括Intel和Apple Silicon。 用户的问题:"我想获取在MacBook Pro上安装Docker编译Linux内核,并使用QEMU启动内核进行调试的方法" 所以,我的回答需要结构化,清晰,逐步指导如何: 1. 安装Docker在MacBook Pro上。 2. 使用Docker编译Linux内核。 3. 使用QEMU启动编译好的内核。 4. 添加调试功能,如使用GDB。 参考用户提供的引用: - 引用[1]是关于Docker运行macOS的,不相关。 - 引用[2]是关于休眠的,不相关。 - 引用[3]直接相关:"M1 macbook上安装docker 编译内核 并使用qemu启动内核。。" 它提供了生成rootfs的命令。 从引用[3]的具体内容:"M1 macbook上安装docker 编译内核 并使用qemu启动内核。。然后通过下面命令生成rootfs # 首先为 init 赋予可执行权限 $ sudo chmod +x init # 进入 busybox 编译成果目录 cd ~/kvm/busybox-1.32.1/_install # 使用 cpio 制作成 rootfs ... find . -print0 | cpio --null -ov --format=newc | gzip -9 > ./initramfs-busybox-arm64.cpio.gz" 这表明步骤包括编译busybox生成initramfs用于QEMU启动内核。 用户还提到"进行调试",所以我需要包括调试部分,比如如何使用GDB与QEMU一起调试内核系统级指令要求: - 所有行内数学表达式使用$...$格式(但这个问题可能没有数学表达式)。 - 独立公式使用$$...$$(可能不需要)。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识,如[^1]。 在回答中,我应该自然地引用参考内容。引用来自用户提供的站内引用,所以我可以在回答中提及它们。 结构化回答: 1. **简介**:简要解释过程。 2. **步骤**: a. 安装Docker:如何在MacBook Pro上安装Docker。 b. 编译Linux内核:使用Docker容器编译内核。 c. 生成rootfs:创建initramfs或文件系统(如引用[3]中的busybox)。 d. 使用QEMU启动内核:配置QEMU运行内核。 e. 调试:如何使用GDB调试内核。 3. **注意事项**:针对MacBook Pro的特殊考虑,比如Apple Silicon vs Intel。 4. **相关问题**:生成几个相关问题。 参考来源: - 引用[3]是主要参考,因为它直接匹配用户的需求。 - 引用[1]和[2]不太相关,但用户说"上述引用仅供参考",所以我只需参考[3]。 在回答中,当提到具体步骤时,可以添加引用标识,如[^3]。 确保回答真实可靠:基于标准知识和参考。 详细步骤: 1. **安装Docker**: - 在Mac上,可以从Docker官网下载安装包。 - 确保安装了Homebrew,然后使用`brew cask install docker`或直接下载。 2. **编译Linux内核**: - 使用Docker容器来编译内核,以避免主机依赖。 - 拉取一个合适的镜像,比如Debian-based或Ubuntu,用于编译。 - 下载Linux内核源码,配置编译选项。 - 在容器中运行编译命令。 3. **生成rootfs**: - 如引用[3]所示,编译busybox生成initramfs。 - 创建init脚本。 4. **启动QEMU**: - 安装QEMU:在Mac上使用`brew install qemu`。 - 配置QEMU参数启动内核和initramfs。 5. **调试**: - QEMU支持GDB stub,可以使用`-s`参数启用调试服务器。 - 在主机上使用gdb连接进行调试。 针对MacBook Pro: - 如果是M1/M2芯片,架构是ARM64,需要编译ARM64内核。 - 如果是Intel,编译x86_64内核。 用户没有指定芯片,所以我应该覆盖两者或询问。 在回答中,假设通用方法。 生成相关问题: 基于用户的问题,生成3-4个相关问题。 例如: 1. 如何优化内核编译速度在Docker中? 2. QEMU配置选项有哪些用于调试? 3. 如何在调试时设置断点? 4. 常见问题解决。 回答使用中文。 </think> 以下是针对在MacBook Pro上安装Docker、编译Linux内核,并使用QEMU启动内核进行调试的详细步骤。这个方法基于标准实践和参考引用[^3](涉及在M1 MacBook上使用Docker编译内核并用QEMU启动),并结合了针对MacBook Pro(包括Intel和Apple Silicon芯片)的优化建议。整个过程分为几个清晰步骤,确保逻辑性和可靠性。我会尽量简化操作,并添加调试支持。 ### 1. **前提准备** 在开始前,确保你的MacBook Pro满足以下要求: - macOS版本:建议macOS Big Sur或更高版本。 - 磁盘空间:至少20GB可用空间(用于内核源码、编译输出和容器)。 - 工具安装: - 安装Homebrew(macOS包管理器):在终端运行 `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`。 - 安装Docker:从[Docker官网](https://www.docker.com/products/docker-desktop)下载Docker Desktop并安装,或通过Homebrew运行 `brew install --cask docker`。 - 安装后启动Docker Desktop,并在终端运行 `docker --version` 验证安装成功。 - 安装QEMU运行 `brew install qemu`。 - 选择内核版本:建议使用稳定版本(如Linux 6.1),避免最新开发版。这里以编译ARM64内核为例(针对Apple Silicon M1/M2芯片),如果是Intel芯片,替换为x86_64架构。 ### 2. **使用Docker编译Linux内核** 使用Docker容器编译内核可以隔离环境依赖,避免污染主机系统。参考引用[^3],我们基于Linux内核源码和容器化编译流程。 ```bash # 步骤1: 创建项目目录并下载内核源码 mkdir ~/kml-debug && cd ~/kml-debug git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git cd linux # 步骤2: 启动Docker编译容器 # 如果是Apple Silicon芯片(M1/M2),使用arm64v8/ubuntu镜像;Intel芯片则使用ubuntu:20.04 docker run -it --rm \ -v $(pwd):/usr/src/linux \ -w /usr/src/linux \ arm64v8/ubuntu:20.04 /bin/bash # 步骤3: 在容器内安装编译工具并编译内核 # 更新系统并安装依赖 apt update && apt install -y build-essential flex bison libssl-dev libelf-dev ncurses-dev # 配置内核编译选项(使用默认配置) make defconfig # 编译内核(启用调试符号,便于调试) make -j$(nproc) KCFLAGS="-g" # -g参数添加调试符号,-j用于并行编译加速 # 编译完成后,内核镜像位于 arch/arm64/boot/Image(ARM64)或 arch/x86/boot/bzImage(Intel) # 退出容器(编译产物会保留在主机目录) exit ``` - **说明**:编译过程可能需要1-2小时,取决于MacBook配置。编译输出(如 `arch/arm64/boot/Image`)会自动映射到主机 `/usr/src/linux` 目录下。 - **注意事项**:如果编译失败,检查依赖是否完整;Apple Silicon需要ARM64镜像,确保Docker偏好设置中启用Rosetta用于Intel兼容性[^3]。 ### 3. **生成rootfs(initramfs)** 启动内核需要一个文件系统,参考引用[^3],我们使用busybox创建轻量级initramfs(包含init脚本),便于QEMU启动和调试。 ```bash # 步骤1: 编译busybox并生成rootfs cd ~/kml-debug git clone https://github.com/mirror/busybox.git cd busybox # 配置并编译busybox make defconfig make menuconfig # 可选:启用静态链接以减少依赖(在 Settings > Build Options > Build static binary 选中) make -j$(nproc) make install # 输出在 _install 目录 # 步骤2: 创建init脚本(用于initramfs) mkdir -p _install/usr/bin echo '#!/bin/sh' > _install/init echo 'mount -t proc none /proc' >> _init/init echo 'mount -t sysfs none /sys' >> _init/init echo 'exec /bin/sh' >> _init/init chmod +x _install/init # 参考引用[^3],赋予init执行权限 # 步骤3: 生成initramfs镜像 cd _install find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs-busybox.cpio.gz ``` - **说明**:initramfs是一个gzip压缩的cpio归档文件,包含最小文件系统,允许内核启动到shell提示符。这基于引用[^3]的命令,确保了调试环境的简洁性。 ### 4. **使用QEMU启动内核并调试** 启动QEMU模拟器,加载编译好的内核和initramfs,并启用GDB调试支持。 ```bash # 步骤1: 启动QEMU(针对ARM64内核) cd ~/kml-debug qemu-system-aarch64 \ -machine virt \ -cpu cortex-a72 \ -smp 4 \ # 使用4个CPU核心 -m 2G \ # 分配2GB内存 -kernel linux/arch/arm64/boot/Image \ -initrd busybox/initramfs-busybox.cpio.gz \ -append "console=ttyAMA0" \ -nographic \ -serial mon:stdio \ -s -S # -s启用GDB服务器(端口1234),-S暂停CPU等待调试器附加 # 如果是Intel芯片,使用x86_64命令: # qemu-system-x86_64 -kernel linux/arch/x86/boot/bzImage -initrd busybox/initramfs-busybox.cpio.gz -append "console=ttyS0" -nographic -serial mon:stdio -s -S ``` - **调试步骤**: - 在另一个终端窗口,启动GDB连接QEMU调试服务器: ```bash cd ~/kml-debug/linux gdb vmlinux # vmlinux是编译生成的带符号内核文件 (gdb) target remote :1234 # 连接到QEMU (gdb) b start_kernel # 设置断点在内核启动函数 (gdb) c # 继续执行 ``` - 调试环境启动后,你可以设置断点(如 `b do_fork`)、检查变量( `print variable`),或分析内核崩溃。 - **常用调试命令**: - `info registers` 查看寄存器。 - `bt` 查看堆栈回溯。 - `monitor quit` 退出QEMU。 ### 5. **注意事项和优化** - **调试优化**:在编译内核时启用 `CONFIG_DEBUG_INFO=y`(修改 `.config` 文件),以获取完整调试符号。使用QEMU的 `-gdb tcp::1234` 参数替代 `-s` 可自定义端口。 - **性能问题**:在MacBook Pro上,QEMU可能较慢;Apple Silicon芯片建议使用 `accel=hvf` 参数启用硬件加速(例如 `-accel hvf`)。 - **常见问题**: - 内核启动失败:检查initramfs路径是否正确,引用[^3]强调在 `busybox/_install` 目录下执行命令。 - GDB连接失败:确保QEMU启动时 `-s` 参数生效,并验证端口无冲突。 - **安全警告**:调试内核时避免在生产环境使用。 ### 相关问题 基于本方法,以下是可能的相关问题: 1. 如何在QEMU中模拟网络接口用于内核网络调试? 2. 如何优化内核编译速度在使用Docker容器时? 3. 在调试过程中,如何处理内核崩溃(Kernel Panic)? 4. 有什么替代方案不使用Docker直接在macOS编译内核? 如果您有具体内核版本或调试场景,可以提供更多细节,我会进一步优化步骤!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量子象限

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值