通过qemu仿真树莓派系统调试IoT固件和程序

通过qemu仿真树莓派系统调试IoT固件和程序

本文将介绍如何使用 QEMU 模拟器在 x86 架构的主机上运行 Raspberry Pi OS(树莓派操作系统)。我们将从下载镜像、提取内核和设备树文件,到启动模拟环境,并进行一些常见的操作,如更改密码和交叉编译,以及如何通过 GDB 进行远程调试。


1. 下载 Raspberry Pi OS 镜像

首先,我们需要下载适用于树莓派的轻量版 Raspberry Pi OS 镜像。本文使用的是 2024-10-22-raspios-bullseye-armhf-lite.img,这是一个基于 Debian Bullseye 的 ARM 架构镜像。

你可以从 Raspberry Pi 官方网站 或其他可信来源下载该镜像。


2. 提取内核和设备树文件

为了在 QEMU 中运行 Raspberry Pi OS,我们需要从镜像中提取内核 (kernel*.img) 和设备树文件 (.dtb)。以下是具体步骤:

2.1 创建挂载点并挂载镜像

sh 复制代码
# 1. 创建挂载点
sudo mkdir /mnt/rpi

# 2. 挂载镜像文件
sudo losetup -f --show -P 2024-10-22-raspios-bullseye-armhf-lite.img
# 假设输出为 /dev/loop0

# 3. 挂载第一个分区
sudo mount /dev/loop0p1 /mnt/rpi

2.2 复制内核和设备树文件

sh 复制代码
# 4. 复制内核和设备树文件
cp /mnt/rpi/kernel* .
cp /mnt/rpi/*.dtb .

# 5. 卸载分区
sudo umount /mnt/rpi

# 6. 删除 loop 设备
sudo losetup -d /dev/loop0

至此,我们已经成功提取了内核和设备树文件,这些文件将在后续步骤中用于 QEMU 启动。


3. 使用 QEMU 启动 Raspberry Pi OS

3.1 启动树莓派 3B 模拟环境

以下命令将使用 QEMU 模拟树莓派 3B 环境,并加载我们提取的内核和设备树文件:

sh 复制代码
sudo qemu-system-aarch64 -M raspi3b \
-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootdelay=1" \
-dtb ./bcm2710-rpi-3-b-plus.dtb \
-drive format=raw,file=2024-10-22-raspios-bullseye-armhf-lite.img \
-kernel kernel8.img \
-m 1G \
-smp 4 -serial stdio \
-net nic -net user,hostfwd=tcp::5022-:22  \
-usb -device usb-kbd  -device usb-mouse \
-k en-us \
-display sdl 
参数说明:
  • -M raspi3b:指定模拟的硬件平台为树莓派 3B。
  • -append:传递给内核的启动参数,包括根文件系统位置、日志级别等。
  • -dtb:指定设备树文件。
  • -drive:指定镜像文件及其格式。
  • -kernel:指定内核文件。
  • -m:分配内存大小(1GB)。
  • -smp:指定 CPU 核心数(4 核)。
  • -net:配置网络,允许通过 SSH 访问(主机端口 5022 映射到虚拟机端口 22)。
  • -usb:启用 USB 支持,添加键盘和鼠标设备。
  • -display sdl:使用 SDL 图形显示。

运行上述命令后,QEMU 将启动树莓派模拟环境,并进入 Raspberry Pi OS 的登录界面。


4. 使用预编译的 versatilepb 内核进行仿真

https://github.com/dhruvvyas90/qemu-rpi-kernel

如果你希望使用更通用的 ARM 平台(如 VersatilePB),可以使用以下命令:

sh 复制代码
qemu-system-arm -M versatilepb -cpu arm1176 -m 256 \
-drive format=raw,file=2024-10-22-raspios-bullseye-armhf-lite.img \
-dtb versatile-pb-bullseye-5.10.63.dtb \
-kernel kernel-qemu-5.10.63-bullseye \
-net nic -net user,hostfwd=tcp::5022-:22  \
-net user,hostfwd=tcp::2333-:2333 \
-nographic \
-append "root=/dev/sda2 panic=1 rootfstype=ext4 rw"
参数说明:
  • -M versatilepb:指定模拟的硬件平台为 VersatilePB。
  • -cpu arm1176:指定 CPU 类型。
  • -nographic:禁用图形界面,仅使用命令行模式。

4. 更改默认密码

Raspberry Pi OS 新版本需要通过在镜像文件中写入文件进行配置账号密码,否则无法实现登录。

这里我们直接挂载镜像来修改密码

以下是具体步骤:

sh 复制代码
# 1. 创建挂载点
sudo mkdir /mnt/rpi

# 2. 挂载镜像文件
sudo losetup -f --show -P 2024-10-22-raspios-bullseye-armhf-lite.img

# 3. 挂载第二个分区
sudo mount /dev/loop0p2 /mnt/rpi

# 4. 更改密码
sudo chroot /mnt/rpi passwd pi

# 5. 卸载分区
sudo umount /mnt/rpi

# 6. 删除 loop 设备
sudo losetup -d /dev/loop0

运行上述命令后,输入新密码即可完成更改。


5. 交叉编译与远程调试

5.1 交叉编译工具链配置

为了在 x86 主机上为 ARM 架构编译程序,我们需要设置交叉编译工具链。以下是配置示例:

sh 复制代码
./configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf CC=/home/kali/rpi-tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc --prefix=/opt/arm-linux-gnueabihf-gdb-8.2

make CXX=/home/kali/rpi-tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ CC=/home/kali/rpi-tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

5.2 使用 GDB 进行远程调试

在目标系统中启动 gdbserver

sh 复制代码
$ ./gdbserver :2333 /bin/sh

在主机端使用 GDB 连接到目标系统:

sh 复制代码
gef➤ gef-remote 127.0.0.1 2333

6. 使用qemu直接进行调试

qemu-aarch64 配合gdb可以实现调试arm架构的程序

sh 复制代码
# 1. 安装 QEMU User 模式工具
sudo apt install qemu-user gdb-multiarch

# 2. 用 QEMU 运行 ARM 可执行程序
qemu-aarch64 <你的ARM程序>

# 3. 运行 gdbserver 进行远程调试(在主机上执行)
qemu-aarch64 -g 2333 <你的ARM程序>

# 4. 在另一个终端启动 gdb-multiarch 并连接 gdbserver
gdb-multiarch
gef> set architecture aarch64
gef> gef-remote 127.0.0.1:2333

参考链接

https://zhuanlan.zhihu.com/p/613032457

https://www.gandalf.site/2018/12/iotqemuiot.html

相关推荐
学术小白人8 小时前
【EI会议征稿通知】2026年智能感知与自主控制国际学术会议(IPAC 2026)
人工智能·物联网·数据分析·区块链·能源
岁岁种桃花儿13 小时前
Nginx 站点垂直扩容(单机性能升级)全攻略
网络·nginx·dns
Xの哲學13 小时前
Linux SMP 实现机制深度剖析
linux·服务器·网络·算法·边缘计算
知识分享小能手13 小时前
Ubuntu入门学习教程,从入门到精通,Ubuntu 22.04的Linux网络配置(14)
linux·学习·ubuntu
皇族崛起13 小时前
【视觉多模态】- scannet 数据的 Ubuntu 百度网盘全速下载
linux·ubuntu·3d建模·dubbo
CAU界编程小白13 小时前
Linux系统编程系列之进程控制(下)
linux·进程控制
一颗青果14 小时前
公网构建全流程与参与主体深度解析
网络
RisunJan14 小时前
Linux命令-ifconfig命令(配置和显示网络接口的信息)
linux·运维·服务器
LaoWaiHang14 小时前
Linux基础知识04:pwd命令与cd命令
linux
lbb 小魔仙14 小时前
【Linux】100 天 Linux 入门:从命令行到 Shell 脚本,告别“光标恐惧”
linux·运维·服务器