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

Qemu模拟arm64启动Uboot + Linux

目的:

由 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
http://www.jsqmd.com/news/1037041/

相关文章:

  • 2026 成都市天府新区奢品回收业态迭代分析与新店综合实力推荐排行榜 - 奢侈品回收
  • 2026山东大学项目实训4月7日
  • MC68336/376微控制器架构解析:TPU、QADC与SIM模块的嵌入式实战
  • RAG+多智能体在金融分析中的实盘落地方法论
  • 2026西岛登岛攻略:三亚湾海岸线必吃舟记渔港海鲜 - 资讯速览
  • 2026哈尔滨长途搬家哪家靠谱?跨城搬迁公司测评,鑫福庆9.8分稳居行业首位 - 热点速览
  • 【计算机毕业设计案例】基于 Django 的用户行为协同过滤音乐播放平台的设计与实现 基于 Django 的智能化协同过滤音乐推荐客户端系统(程序+文档+讲解+定制)
  • Windows批处理文件遍历:如何高效获取纯文件名(不带路径)
  • 如何像Python一样编译C++代码
  • AI科技热点日报 | 2026年06月18日
  • 成都锦江区名包回收实测!片区门店筛选,二手名包高价变现 - 开心测评
  • 朝阳家装口碑怎么选?2026 正规家装企业综合测评指南 - 装修新知
  • 2026年 精密慢走丝加工厂推荐榜:附近厂家技术实力与微米级精度口碑之选 - 品牌发掘
  • 2026 合肥正规名表回收商家完整名单(上门 + 到店均可) - 企业推荐官【官方】
  • 逆向实战:从零破解网易云音乐评论接口加密参数
  • 雅琪诺“礼服工艺”的技术体系解析:从裁剪到定型的全流程精工标准
  • 【Qt】界面优化:绘图API
  • 2026年旋转接头厂家推荐榜单:高温/高压/高速旋转接头,蒸汽导热油及液压水用旋转接头优质品牌选型指南 - 品牌发掘
  • 2026 年 6 月最新|自动涂胶系统 / 涂胶供料系统 / 涂胶计量系统 / 涂胶分配系统厂家实测排名 权威榜单推荐 - 商业新知
  • 深度解析:如何利用Waifu2x-Extension-GUI实现多媒体内容超分辨率增强
  • 深度解析:Android超大图片加载的性能优化与内存管理实战指南
  • 2026常州光谱测金仪器科普指南,无损检测精准识别黄金纯度 - 奢侈品回收测评
  • 2026年6月头部电力管源头厂家口碑推荐,非开挖管道/九孔格栅管/通信波纹管/PVC塑料管,电力管厂家推荐分析 - 品牌推荐师
  • 2026高速冷冻离心机高品质制造厂商:全流程质检保障离心转速精度 - 品牌推荐大师
  • 网课记笔记写论文刷题,哪些学生平板推荐能覆盖全部学习场景? - 资讯速览
  • 高效eUICC管理架构解析:企业级智能卡管理实战指南
  • Java 异常 详解
  • 05 | 一不小心就死锁了,怎么办?
  • 基于Springboot2+vue2的高校办公室行政事务管理系统
  • cyancat-开源数据库管理工具