尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Qemu模拟arm64启动Uboot + Linux

Qemu模拟arm64启动Uboot + Linux
📅 发布时间:2026/6/18 17:07:20

目的:

由 U-Boot 引导 Linux 是一套非常经典的“全栈”仿真玩法,虽然Qemu可以跳过U-Boot直接启动Linux,但是要还原真实硬件的启动流程,U-Boot是绕不开要调试和学习的,以此简单记录下。使用Qemu可以用于早期的方案验证,提前排除风险。无实物,纯模拟,不用担心硬件bug,省去了很多调试力气。

一、uboot

1.1 安装依赖库

编译uboot时,需要编译主机工具,而编译工具,又依赖于一些常用的开发库。

sudo apt install -y uuid-dev libssl-dev libgnutls28-dev libncurses-dev swig python3-dev u-boot-tools mtd-utils pkg-config cpio

1.2 编译uboot

下载,编译,启动,不再赘述。ubifs依赖于ubi,ubi依赖于mtd,mtd可以是nor,spi,nand。

#下载 wget https://ftp.denx.de/pub/u-boot/u-boot-2026.01.tar.bz2 tar -jxvf u-boot-2026.01.tar.bz2 cd u-boot-2026.01 #配置,已开启ubi配置 make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- qemu_arm64_defconfig make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- menuconfig (或以下方法) cat << EOF >> .config CONFIG_CMD_MTD=y CONFIG_MTD=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_CFI=y CONFIG_MTD_NOR_FLASH=y CONFIG_MTD_DEVICE=y CONFIG_CMD_UBI=y CONFIG_CMD_UBIFS=y EOF make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- olddefconfig #编译 make ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- -j4 cp u-boot.bin ../ 启动 qemu-system-aarch64 -machine virt -cpu cortex-a53 -smp 2 -m 512 -kernel u-boot -nographic

1.3 启动uboot

启动uboot,可以识别两个mtd设备,以及操作ubi卷。镜像文件可以裸放到支持norflash上,ubi卷上,或者ubifs文件系统中。需要uboot支持读接口获取镜像文件并启动,因为重心不在此,就不继续考究了。

Bloblist at 0 not found (err=-2) alloc space exhausted ptr 400 limit 0 Bloblist at 0 not found (err=-2) U-Boot 2026.01 (Jun 11 2026 - 11:35:10 +0800) DRAM: 512 MiB using memory 0x5e637000-0x5f677000 for malloc() Core: 51 devices, 14 uclasses, devicetree: board Flash: 64 MiB Loading Environment from Flash... *** Warning - bad CRC, using default environment In: serial,usbkbd Out: serial,vidconsole Err: serial,vidconsole No USB controllers found Net: eth0: virtio-net#32 Hit any key to stop autoboot: 0 => => mtd list List of MTD devices: * nor0 - device: flash@0 - parent: root_driver - driver: cfi_flash - path: /flash@0 - type: NOR flash - block size: 0x20000 bytes - min I/O: 0x1 bytes - 0x000000000000-0x000002000000 : "nor0" * nor1 - device: flash@0 - parent: root_driver - driver: cfi_flash - path: /flash@0 - type: NOR flash - block size: 0x20000 bytes - min I/O: 0x1 bytes - 0x000000000000-0x000002000000 : "nor1"

1.4 初探UBI

擦除nor,attach mtd设备,创建ubi卷。uboot下似乎只支持读,没有支持ubifs格式化、写入的操作,因此无法挂载ubifs文件系统。我想这是安全的行为,如果在uboot下创建文件系统,要做好和kernel的版本同步。这个很麻烦,也很容易把不一致性传递给kernel,导致长期使用后ubifs的累加错误。

=> protect off all Un-Protect Flash Bank # 1 Un-Protect Flash Bank # 2 => erase all Erase Flash Bank # 1 ................................................................................................................................................................................................................................................................ done Erase Flash Bank # 2 ................................................................................................................................................................................................................................................................ done => ubi part nor0 0 force ubi0: attaching mtd0 ubi0: scanning is finished ubi0: empty MTD device detected ubi0: attached mtd0 (name "nor0", size 32 MiB) ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 130944 bytes ubi0: min./max. I/O unit sizes: 1/1, sub-page size 1 ubi0: VID header offset: 64 (aligned 64), data offset: 128 ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0 ubi0: user volume: 0, internal volumes: 1, max. volumes count: 128 ubi0: max/mean erase counter: 0/0, WL threshold: 4096, image sequence number: 0 ubi0: available PEBs: 252, total reserved PEBs: 4, PEBs reserved for bad PEB handling: 0 => ubi create system 0xa00000 dynamic Creating dynamic volume system of size 10485760 => ubi info layout Volume information dump: vol_id 0 reserved_pebs 81 alignment 1 data_pad 0 vol_type 3 name_len 6 usable_leb_size 130944 used_ebs 81 used_bytes 10606464 last_eb_bytes 130944 corrupted 0 upd_marker 0 skip_check 0 name system Volume information dump: vol_id 2147479551 reserved_pebs 2 alignment 1 data_pad 0 vol_type 3 name_len 13 usable_leb_size 130944 used_ebs 2 used_bytes 261888 last_eb_bytes 2 corrupted 0 upd_marker 0 skip_check 0 name layout volume => ubi ubi ubifsload ubifsls ubifsmount ubifsumount => ubifsmount system UBIFS error (pid: 1): cannot open "system", error -22 Error reading superblock on volume 'system' errno=-22!

二、kernel

2.1 编译kernel

编译,启动,不再赘述。

#配置,去掉nor,后续模拟nand make ARCH=arm64 defconfig ./scripts/config --enable DEBUG_INFO \ --enable DEBUG_KERNEL \ --enable GDB_SCRIPTS \ --enable KALLSYMS_ALL \ --enable FRAME_POINTER ./scripts/config --disable MTD_CFI \ --disable MTD_GENPROBE \ --disable MTD_CFI_AMDSTD \ --disable MTD_CFI_UTIL \ --disable MTD_PHYSMAP \ --disable MTD_PHYSMAP_OF cat << EOF >> .config # MTD 核心与分区支持 CONFIG_MTD=y CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CHAR=y # 核心 1:启用 block2mtd 驱动 CONFIG_MTD_BLOCK=y CONFIG_MTD_BLOCK2MTD=y # 核心 2:启用 nandsim 驱动及其依赖的 NAND 框架 CONFIG_MTD_RAW_NAND=y CONFIG_MTD_NAND_NANDSIM=m # UBI 与 UBIFS 配置 CONFIG_MTD_UBI=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_MTD_UBI_BEB_LIMIT=20 CONFIG_UBIFS_FS=y CONFIG_UBIFS_FS_ADVANCED_COMPR=y CONFIG_UBIFS_FS_LZO=y CONFIG_UBIFS_FS_ZLIB=y EOF make ARCH=arm64 olddefconfig #编译 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8 cp arch/arm64/boot/Image ../ #启动 qemu-system-aarch64 \ -machine virt,virtualization=on \ -cpu cortex-a53 \ -kernel arch/arm64/boot/Image \ -append "console=ttyAMA0 nokaslr" \ -nographic

2.2 制作rootfs

解决Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)问题,需要busybox做个rootfs。

#下载 wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2 tar -jxvf busybox-1.36.1.tar.bz2 cd busybox-1.36.1/ #配置,启用静态链接 ,配置为静态编译。简单,无需拷贝动态链接库 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig sed -i 's/^# CONFIG_STATIC.*/CONFIG_STATIC=y/' .config #关闭tc,解决编译问题 sed -i 's/CONFIG_TC=y/CONFIG_TC=n/' .config #编译 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j4 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install #打包rootfs mkdir -p rootfs cp -av busybox-1.36.1/_install/* rootfs/ cd rootfs mkdir -p {dev,etc,lib,proc,sys,mnt,root,etc/init.d,tmp} #创建基础设备节点 sudo mknod -m 666 dev/tty1 c 4 1 sudo mknod -m 666 dev/tty2 c 4 2 sudo mknod -m 666 dev/tty3 c 4 3 sudo mknod -m 666 dev/tty4 c 4 4 sudo mknod -m 666 dev/console c 5 1 sudo mknod -m 666 dev/null c 1 3 #创建初始启动脚本 cat > etc/init.d/rcS << EOF #!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys mount -t devtmpfs devtmpfs /dev mount -t tmpfs tmpfs /tmp EOF chmod +x etc/init.d/rcS #制作initramfs镜像 find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initrd.img cd .. #容量信息 @@@:~/linux$ ls -alh ./ -rw-r--r-- 1 l16952 l16952 33M Jun 16 10:24 Image -rw-r--r-- 1 l16952 l16952 1.2M Jun 16 10:45 initrd.img -rw-r--r-- 1 l16952 l16952 1.6M Jun 16 09:37 u-boot.bin

三、uboot启动kernel

3.1 制作镜像

创建虚拟磁盘,存放Image,initrd.img。让uboot通过virtio读取并加载启动

#创建128MB的空磁盘文件 dd if=/dev/zero of=disk.img bs=1M count=128 #烧录内核 Image 到磁盘的 0 偏移处 dd if=Image of=disk.img bs=1M conv=notrunc #烧录根文件系统 initrd.img 到磁盘偏移 50MB 处 dd if=initrd.img of=disk.img bs=1M seek=50 conv=notrunc

3.2 启动镜像

#定义一块virtio块设备,运行程序访问该设备获取disk.img中的镜像 qemu-system-aarch64 \ -machine virt,virtualization=on \ -cpu cortex-a53 \ -m 1024M \ -bios u-boot.bin \ -drive file=disk.img,format=raw,if=none,id=mydisk \ -device virtio-blk-device,drive=mydisk \ -nographic #进uboot命令行,执行以下操作 #读取内核Image virtio read 0x40080000 0x0 0x11170 #读取initrd.img virtio read 0x44000000 0x19000 0xBB8 #设置启动参数 setenv bootargs "rdinit=/sbin/init console=ttyAMA0 loglevel=8" #指定 initrd 内存段的起始地址和具体十六进制大小 booti 0x40080000 0x44000000:0x125cb4 $fdtcontroladdr

3.3 自动启动

使用环境变量,或者脚本,但是因为没有固化到介质中,所以重启qemu仍会丢失

#设置环境变量 setenv bootcmd 'virtio read 0x40080000 0x0 0x11170; virtio read 0x44000000 0x19000 0xBB8; setenv bootargs "rdinit=/sbin/init console=ttyAMA0 loglevel=8"; booti 0x40080000 0x44000000:0x125cb4 $fdtcontroladdr' #保存环境变量 saveenv #kernel下reboot Please press Enter to activate this console. ~ #reboot umount: devtmpfs busy - remounted read-only umount: can't unmount /: Invalid argument swapoff: can't open '/etc/fstab': No such file or directory The system is going down NOW! Sent SIGTERM to all processes Sent SIGKILL to all processes Requesting system reboot #boot下reset Hit any key to stop autoboot: 0 => reset resetting ...

3.4 固化启动配置

让uboot拥有两块flash,使用文件来模拟,存储boot镜像和环境变量。

#生成第一块 64MB 的 Flash,并把 u-boot.bin 重新烧进去 dd if=/dev/zero of=pflash.img bs=1M count=64 dd if=u-boot.bin of=pflash.img conv=notrunc #生成第二块 64MB 的 Flash,专门给 U-Boot 存环境变量 dd if=/dev/zero of=pflash_env.img bs=1M count=64 #用双flash命令启动QEMU qemu-system-aarch64 \ -machine virt,virtualization=on \ -cpu cortex-a53 \ -m 1024M \ -drive file=pflash.img,format=raw,if=pflash \ -drive file=pflash_env.img,format=raw,if=pflash \ -drive file=disk.img,format=raw,if=none,id=mydisk \ -device virtio-blk-device,drive=mydisk \ -nographic #保存环境变量,这次是真实写入pflash_env.img中 setenv bootcmd 'virtio read 0x40080000 0x0 0x11170; virtio read 0x44000000 0x19000 0xBB8; setenv bootargs "rdinit=/sbin/init console=ttyAMA0 loglevel=8"; booti 0x40080000 0x44000000:0x125cb4 $fdtcontroladdr' saveenv #后续直接用QEMU命令即可启动uboot+kernel qemu-system-aarch64 \ -machine virt,virtualization=on \ -cpu cortex-a53 \ -m 1024M \ -drive file=pflash.img,format=raw,if=pflash \ -drive file=pflash_env.img,format=raw,if=pflash \ -drive file=disk.img,format=raw,if=none,id=mydisk \ -device virtio-blk-device,drive=mydisk \ -nographic

相关新闻

  • 朝阳家装口碑怎么选?2026 正规家装企业综合测评指南 - 装修新知
  • 【计算机毕业设计案例】基于 Django 的用户行为协同过滤音乐播放平台的设计与实现 基于 Django 的智能化协同过滤音乐推荐客户端系统(程序+文档+讲解+定制)
  • AI科技热点日报 | 2026年06月18日

最新新闻

  • 西安专业定制私家团旅行社排行 合规服务商盘点 - 起跑123
  • 2026 北京黄金回收实力梯队公示,全城优质连锁门店实力深度盘点 - 奢侈品回收测评
  • 嵌入式调试实战:观察点与寄存器操作在CodeWarrior中的高效应用
  • 2026成都黄金回收价格对比:收的顶同城高价回收实测 - 奢侈品回收评测
  • 2026年6月最新雅典中国官方售后电话地址及客户服务网点查询 - 亨得利官方服务中心
  • 上海非法吸收公众存款罪律师推荐|非吸、企业融资、团队涉案辩护 - 法律资讯

日新闻

  • 2026年不锈钢卷板厂家推荐排行榜:冷轧热轧/304/201不锈钢卷板,高颜值耐腐蚀源头厂家实力精选 - 企业推荐官【官方】
  • FLUX.1-dev FP8模型实战指南:24GB以下显卡高效部署方案
  • 2026佛山长途搬家价目表:跨省跨市搬家费用完整计算指南 - 从来都是英雄出少年

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号