搭建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
相关推荐
蝎子莱莱爱打怪2 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes
崔小汤呀2 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应2 天前
vi编辑器使用
linux·后端·操作系统
何中应2 天前
Linux进程无法被kill
linux·后端·操作系统
何中应2 天前
rm-rf /命令操作介绍
linux·后端·操作系统
何中应2 天前
Linux常用命令
linux·操作系统
葛立国2 天前
从 / 和 /dev 说起:Linux 文件系统与挂载点一文理清
linux
DianSan_ERP3 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
哇哈哈20213 天前
信号量和信号
linux·c++
呉師傅3 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑