通过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

相关推荐
换个号退隐江湖i17 小时前
LLM 调试日志刷屏怎么办?用 tee 边看边存
linux
@insist12318 小时前
系统集成项目管理工程师-信息和文档管理
网络·数据库·软考·系统集成项目管理工程师·软考中项·软件水平考试
极客互动API18 小时前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
DYWorker00118 小时前
搭建嵌入式Linux虚拟机开发环境
linux
QH1392923188018 小时前
Keysight N5183B N5183B 微波模拟信号发生器
网络·单片机·嵌入式硬件·集成测试·信息与通信
weipt18 小时前
从ollama到llama.cpp
linux·服务器·llama
LabVIEW开发18 小时前
基于原始套接字实现LabVIEW网络Ping检测的编程方法
网络·labview·labview知识·labview功能·labview程序
加油码18 小时前
动静态库的链接底层原理(进阶版)
linux·c++
东莞和裕包装18 小时前
如何管控广州定制纸箱生产中的啤切精度与印刷色差质量问题
大数据·运维·网络·人工智能
笨笨饿19 小时前
#110_SCH3000 平台图传系统配置指南:从 DVP 摄像头到 UVC/WiFi 双通道传输
c语言·stm32·单片机·嵌入式硬件·物联网·vim