搭建ARM LINUX 内核 QEMU 仿真调试环境

  1. 准备编译linux内核

获取内核源码:wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v6.x/linux-6.1.80.tar.xz

bash 复制代码
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j32

  1. 确认编译产出

2.1 最常见的内核镜像文件(具体名称取决于架构和配置)

arch/arm64/boot/Image # 对于ARM64

arch/x86/boot/bzImage # 对于x86_64

arch/arm/boot/zImage # 对于ARM

/vmlinux # 未压缩带符号表的镜像,gdb调试用


  1. 准备根文件系统
    3.1 下载编译busybox
bash 复制代码
$ wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
$ tar -xf busybox-1.36.1.tar.bz2
$ cd busybox-1.36.1
$ make menuconfig
Settings --->
 [*] Build static binary (no shared libs)
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j32
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- CONFIG_PREFIX=../rootfs/arm64/ install # 会生成_install目录

3.2 制作根文件系统

静态链接的不需要复制so文件

3.2.1 /etc/profile

  • 用户登录shell时自动执行的脚本,用于设置环境变量
bash 复制代码
# 设置主机名HOSTNAME、用户名USER和家目录HOME
export HOSTNAME=virt-machine
export USER=root
export HOME=/home
# 设置命令提示符的格式,例如 [root@virt-machine ~]#
export PS1="[$USER@$HOSTNAME \W]\# "
# 设置shell查找命令的路径
PATH=/bin:/sbin:/usr/bin:/usr/sbin
# 设置动态链接器查找共享库的路径
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

3.2.2 /etc/fstab

  • 定义系统启动时需要自动挂载的文件系统
bash 复制代码
#device  mount-point    type     options   dump   fsck order
proc /proc proc defaults 0 0
# 内核提供的虚拟文件系统,用于访问内核信息和调试
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
# 将QEMU启动参数中定义的 9p网络文件系统(共享文件)挂载到虚拟机的 /mnt目录
kmod_mount /mnt 9p trans=virtio 0 0

3.2.3 /etc/inittab

  • init进程(系统第一个进程)的配置文件,定义了系统的运行级别和启动流程
bash 复制代码
#系统初始化时执行/etc/init.d/rcS脚本
::sysinit:/etc/init.d/rcS 
#这两行都用于启动shell
# respawn表示如果shell进程退出,会自动重新启动
::respawn:-/bin/sh
# askfirst则会先打印"Please press Enter to activate this console"并等待回车
::askfirst:-/bin/sh 
#在串口控制台(console=ttyAMA0)下,通常使用respawn;在图形界面或终端下,使用askfirst。这里可能配置了两个,系统会选择其中一个

3.2.4 /etc/init.d/rcS

bash 复制代码
# 创建虚拟文件系统挂载点 /sys /tmp /proc /mnt
mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
# 挂载所有在 /etc/fstab文件中定义的文件系统
/bin/mount -a
# pseudo-terminal slave​ 虚拟终端从设备文件系统的挂载点。它为每个打开的终端(如 SSH 连接、xterm 窗口)提供一个对应的设备文件(如 /dev/pts/0)
mkdir -p /dev/pts
# 将 devpts​ 文件系统挂载到 /dev/pts目录
mount -t devpts devpts /dev/pts
# 设置内核的热插拔事件处理程序为 /sbin/mdev
# 这是 BusyBox 的 mdev 机制的核心配置。当内核检测到设备事件(如USB设备插入、移除)时,会调用这个路径指定的程序来处理。mdev会根据这些事件,自动在 /dev目录下创建设备节点文件,实现设备的动态管理
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

  1. 制作虚拟硬盘
bash 复制代码
$ $mkdir virtdisk
$ $cd ./virtdisk/
$ $ls
$ $dd if=/dev/zero of=rootfs_ext4.img bs=1M count=1024
$ mkfs.ext4 rootfs_ext4.img
$ mkdir -p tmpfs
$ sudo mount  -t ext4 rootfs_ext4.img  tmpfs/ -o loop
$ sudo cp ../rootfs/arm64/  ./rootfs -a
$ sudo chown -R root:root rootfs
$ sudo cp -af rootfs/* tmpfs/
$ sudo umount  tmpfs
$ chmod 777 rootfs_ext4.img

  1. 启动qemu仿真
bash 复制代码
# 共享目录
mkdir share
SAHRE_DIR=./share
KERNEL_IMAGE=../linux-6.1.80/arch/arm64/boot/Image

# 启动qemu虚拟机
qemu-system-aarch64 \
  -machine virt -cpu cortex-a57 \
  -m 1024 \
  -smp 4 \
  -kernel $KERNEL_IMAGE\
  --append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8"  \
  -nographic \
  -drive if=none,file=../virtdisk/rootfs_ext4.img,id=hd0 \
  -device virtio-blk-device,drive=hd0 \
  --fsdev local,id=kmod_dev,path=$SAHRE_DIR,security_model=none \
  -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount
  # -s: 在1234端口启动GDB服务器; -S: 启动时暂停CPU

  1. 启动gbd调试
bash 复制代码
# 启动GDB并加载符号
gdb path/to/vmlinux  # vmlinux是带调试信息的未压缩内核
# # 连接到QEMU (默认端口1234)
# (gdb) target remote localhost:1234
相关推荐
2501_9419820512 小时前
别再手动发群消息了!企业微信外部群自动化推送的架构设计与实现
运维·自动化·企业微信
REDcker12 小时前
埋点系统设计:从成熟工具到自建方案
运维·服务器·网络·用户分析·埋点·埋点系统
予枫的编程笔记12 小时前
【Linux入门篇】Ubuntu和CentOS包管理不一样?apt与yum对比实操,看完再也不混淆
linux·人工智能·ubuntu·centos·linux包管理·linux新手教程·rpm离线安装
先做个垃圾出来………12 小时前
SSH密钥管理最佳实践
运维·ssh
RisunJan12 小时前
Linux命令-lpr(从命令行提交文件到打印机打印)
linux·运维·服务器
历程里程碑12 小时前
Linux 库
java·linux·运维·服务器·数据结构·c++·算法
Wpa.wk12 小时前
接口自动化 - 接口鉴权处理常用方法
java·运维·测试工具·自动化·接口自动化
Sheep Shaun12 小时前
如何让一个进程诞生、工作、终止并等待回收?——探索Linux进程控制与Shell的诞生
linux·服务器·数据结构·c++·算法·shell·进程控制
codingWhat12 小时前
Linux 入门指南
linux
Y1rong12 小时前
linux之信号量
linux