当前位置: 首页 > news >正文

qemu(4) -- qemu-system-arm使用

1. 前言

参考网上的资料,使用qemu中的vexpress_a9板子,跑一下Linux环境。

2. 源码

2.1 u-boot

可以到U-Boot官网下载对应的源码,我下载的是u-boot-2025.04-rc5.tar.gz,大约24MB。

3.2 linux

可以到The Linux Kernel Archives官网下载对应的源码,我下载的是linux-5.15.180.tar.xz,大约121MB。最新的是linux-6.14.4.tar.xz,qemu开启lcd时,6.14提示Guest has not initialized the display (yet),不清楚为什么就切换为5.15的版本了。

4.3 busybox

可以到BUSYBOX官网下载对应的源码,我下载的是busybox-1.37.0.tar.bz2,大约2.4MB。1.37.0版本有些bug,busybox-1.37.0/libbb/hash_md5_sha.c文件需要进行以下修改,其中13161318行是新增的,否者编译的时候报错。

1316 # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
1317 || ctx->process_block == sha1_process_block64_shaNI
1318 #endif

4.4 rootfs

构建rootfs时需要手动添加一些文件。

$ tree rootfs
rootfs/
└── vexpress_a9├── dev│   ├── console│   ├── null│   ├── tty1│   ├── tty2│   ├── tty3│   └── tty4├── etc│   ├── fstab│   ├── init.d│   │   └── rcS│   ├── inittab│   ├── profile│   └── sysconfig│       └── HOSTNAME├── mnt├── proc├── root├── sys├── tmp└── var

3. 依赖

安装编译所需要的依赖包。

# gnutls-dev,编译u-boot时需要
# libmpc-dev,编译内核时需要
sudo apt install gnutls-dev libmpc-dev

3. 编译

设置交叉编译所需要的环境变量,也可以将这些变量写到make命令后面,这样就不需要定义为环境变量。

export ARCH=arm
export CROSS_COMPILE=arm-none-linux-gnueabihf-
# 获取主机的cpu核心数,后面命令行中会需要
JOBS=$(nproc)

3.1 u-boot

# 进入u-boot源码目录
cd u-boot-2025.04-rc5
# “O=”指定编译输出目录,使用vexpress_ca9x4板子的配置
make O=../build/uboot_vexpress_a9 vexpress_ca9x4_defconfig
# about 1min
make O=../build/uboot_vexpress_a9 -j${JOBS}
# 将编译出的mkimage程序拷贝到PATH目录中,后面linux制作uImage时会用到它
cp ../build/uboot_vexpress_a9/tools/mkimage ~/bins
# 将u-boot的镜像拷贝到images目录,之后qemu启动时使用
cp ../build/uboot_vexpress_a9/u-boot ../build/images
# 退出u-boot源码目录
cd ..

3.2 busybox

# 进入busybox源码目录
cd busybox-1.37.0
# 使用默认的配置
make O=../build/busybox_vexpress_a9 defconfig
# 执行menconfig修改一些配置项,修改的内容都在“Settings --->”下面
# [*] Build static binary (no shared libs),表示使用静态链接,不使用动态库
# (./_install)Destination path for 'make install' => ../rootfs_vexpress_a9,表示修改安装目录,此处的目录是相对于编译目录而言的
# [*] vi-style line editing commands (New),启用vi命令
make O=../build/busybox_vexpress_a9 menuconfig
# about 1min,此处install会先编译后安装
make O=../build/busybox_vexpress_a9 install -j${JOBS}
# 可以看到busybox已经创建 好了目录结构
ls ../build/rootfs_vexpress_a9/
# 退出busybox源码目录
cd ..

3.3 linux

# 进入linux源码目录
cd linux-5.15.180
# 使用vexpress的配置
make O=../build/linux_vexpress_a9 vexpress_defconfig
# about 6min,编译kernel镜像,zImage表示压缩镜像
make O=../build/linux_vexpress_a9 zImage -j${JOBS}
# 编译设备树
make O=../build/linux_vexpress_a9 dtbs
# 编译模块文件
make O=../build/linux_vexpress_a9 modules
# 使用u-boot-2025.04-rc5编译出的mkimage程序制作uImage,LOADADDR指定uImage中的头信息
make O=../build/linux_vexpress_a9 uImage LOADADDR=0x60003000
# 将内核镜像zImage拷贝到images目录
cp ../build/linux_vexpress_a9/arch/arm/boot/zImage ../build/images
# 将内核镜像uImage拷贝到boot目录,之后通过u-boot加载内核时,从boot目录读取该文件
cp ../build/linux_vexpress_a9/arch/arm/boot/uImage ../build/rootfs_vexpress_a9/boot
# 将设备树拷贝到images和boot目录,前者用于直接启动,后者用于u-boot启动
cp ../build/linux_vexpress_a9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb ../build/images
cp ../build/linux_vexpress_a9/arch/arm/boot/dts/vexpress-v2p-ca9.dtb ../build/rootfs_vexpress_a9/boot
# 退出linux源码目录
cd ..

3.4 rootfs

  1. busybox已经构建了一部分rootfs的内容,还需要手动补充一些文件。
# 进入创建的根目录
$ cd build/rootfs_vexpress_a9
# 查看当前的目录结构
$ ls
bin  linuxrc  sbin  usr
# 执行脚本完善文件系统的内容
$ ../../rootfs/vexpress_a9.sh
# 查看当前的目录结构
$ ls
bin  boot  dev  etc  linuxrc  mnt  proc  root  sbin  tmp  usr  var
# 退出根目录
cd ../..
  1. 创一个文件,将其格式化为ext4,然后挂载到主机中,将根目中的内容复制进去。
# 进入images目录
cd build/images
# 创建一个32MB的文件rootfs.ext4,使用0填充
dd if=/dev/zero of=rootfs.ext4 bs=1M count=32
# 将rootfs.ext4文件格式化成ext4文件系统
mkfs.ext4 rootfs.ext4
# 创建一个临时目录作为挂载点
mkdir temp/
# 将文件rootfs.ext4挂载到temp/目录上,mount会自动识别文件系统格式,需要管理员权限,-o loop表示挂载的是一个文件虚拟的块设备
sudo mount rootfs.ext4 temp/ -o loop
# 将根目中的文件拷贝到temp/目录中
sudo cp ../rootfs_vexpress_a9/* temp/ -r
# 取消挂载,此时rootfs.ext4就是一个根文件系统镜像了,其文件系统格式为ext4,且拥有../rootfs_vexpress_a9/目录下的所有文件
sudo umount temp
# 退出images目录
cd ../..

4. 启动

4.1 linux

qemu可以直接启动linux。

# 进入images目录
$ cd build/images
# 无窗口启动,启动日志会直接输出到控制台,先按下CTRL+a再按下x可以退出qemu
$ qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -dtb vexpress-v2p-ca9.dtb -sd rootfs.ext4 -append "root=/dev/mmcblk0 rw console=ttyAMA0" -nographic
....(此处省略许多日志,日志中ALSA等信息是可声卡有关的错误,暂时可以先不理会)
-----------------------------------
*****welcome to vexpress board*****
-----------------------------------Please press Enter to activate this console.(此处按下回车即可登录到控制台)
# 进入linux控制台
[root@vexpress ~]$ ls
bin         etc         mnt         sbin        var
boot        linuxrc     proc        tmp
dev         lost+found  root        usr
# 有窗口启动,可以看到qemu弹出了gui窗口,等待一段时间会在窗口上出现小企鹅,启动日志会输出到gui窗口
$ qemu-system-arm -M vexpress-a9 -m 512M -kernel zImage -dtb vexpress-v2p-ca9.dtb -sd rootfs.ext4 -append "root=/dev/mmcblk0 rw console=tty0"
# 退出images目录
cd ../..

有窗口启动时,鼠标单击窗口即可进行输入交互,我在两个电脑上运行过,有个电脑gui窗口交互有些问题,输入的命令总是收的不全,另一台电脑正常。鼠标点进窗口后就不能点击qemu窗口的菜单栏了,根据窗口标题提示,需要先按下Ctrl+Alt+g,表示将鼠标的焦点退出控制台,然后才能点击窗口的菜单栏,通过菜单栏的【Machine】》【Quit】可以退出qemu。
有窗口的启动

4.2 u-boot

qemu可以直接运行u-boot,然后通过u-boot加载内核。

# 进入images目录
$ cd build/images
# 无窗口启动,启动日志会直接输出到控制台,rootfs.ext4会被映射为u-boot的mmc 0,先按下CTRL+a再按下x可以退出qemu
$ qemu-system-arm -M vexpress-a9 -m 512M -kernel u-boot -sd rootfs.ext4 -nographic
# 进入u-boot命令行,加载uImage文件到内存0x60003000位置
=> ext4load mmc 0 0x60003000 boot/uImage
# 加载设备树文件到内存0x60500000位置,确保不覆盖uImage即可
=> ext4load mmc 0 0x60500000 boot/vexpress-v2p-ca9.dtb
# 设置启动参数
=> setenv bootargs "root=/dev/mmcblk0 rw console=ttyAMA0"
# 启动linux,两个地址分别指向内核和设备树的位置
=> bootm 0x60003000 - 0x60500000
...(此处省略许多日志,日志中ALSA等信息是可声卡有关的错误,暂时可以先不理会)
-----------------------------------
*****welcome to vexpress board*****
-----------------------------------Please press Enter to activate this console.(此处按下回车即可登录到控制台)
[root@vexpress ~]$ ls
bin         etc         mnt         sbin        var
boot        linuxrc     proc        tmp
dev         lost+found  root        usr
# 退出images目录
cd ../..

上一篇:qemu(3) – qemu-arm使用
下一篇:qemu(4) – qemu-system-arm使用
目录:全部文章合集

参考

QEMU教程
U-Boot 文档

相关文章:

  • 从股指到期指,哪些因素影响基差?
  • Selenium3自动化测试,Python3测试开发教程视频测试用例设计
  • 学习与规划的融合Dyna-Q:python从零实现
  • 【Github仓库】Learn-Vim随笔
  • Redis ⑧-RESP | 渐进式遍历 | 数据库管理
  • 机器人--主机--控制系统
  • YOLOv8模型训练过程
  • MCP:智能家居的“大脑”,如何引领未来居住革命
  • LangChain4j +DeepSeek大模型应用开发——7 项目实战 创建硅谷小鹿
  • Python Cookbook-6.14 实现状态设计模式
  • DeepSeek 赋能自然语言处理:从理论到实践的全方位解析
  • Qt指南针
  • 支持selenium的chrome driver更新到136.0.7103.49
  • 打包 Python 项目为 Windows 可执行文件:高效部署指南
  • 33、VS中提示“以下文件中的行尾不一致。是否将行尾标准化?“是什么意思?
  • 【C语言练习】014. 使用数组作为函数参数
  • Java关键字解析
  • Canvas特效实例:黑客帝国-字母矩阵(字母雨)
  • OpenAI最新发布的GPT-4.1系列模型,性能体验如何?
  • 设计模式简述(十四)组合模式
  • 以色列消防部门:已控制住耶路撒冷山火
  • 空间站第八批科学实验样品返抵地球并交付科学家
  • 国家卫健委对近日肖某引发舆情问题开展调查
  • 全国台联原会长杨国庆逝世,享年89岁
  • 滨江集团:一季度营收225.07亿元,净利润9.75亿元
  • 中国银行副行长刘进任该行党委副书记