0%

qemu 镜像启动相关实验

多分区镜像如何挂载

利用mount -o offset选项进行挂载。即偏移地址。

1
sudo mount -v -o offset=1048576 -t vfat sdimage.img ~/mount/boot/

Units: sectors of 1 * 512 = 512 bytes
一个扇区为512bytes。

1
2
3
4
5
sudo fdisk -l starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img
Device Start End Sectors Size Type
starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img1 2048 34815 32768 16M Linux filesystem
starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img2 34816 239615 204800 100M EFI System
starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img3 239616 3479518 3239903 1.6G Linux filesystem

如挂载第三个分区
offset = 239616 * 512

1
sudo mount -o offset=122683392 starfive-jh7110-VF2_515_v2.5.0-69-minimal-desktop.img test_mnt_dir 

qcow2 格式

制作

1
qemu-img create -f qcow2 image.qcow2 1G

挂载

1
sudo qemu-nbd --connect=/dev/nbd0 image.qcow2

connect 后, 如果该镜像中有分区的话, 需要等几秒中, 等分区节点出来

connect 时注意该镜像文件未被使用, 否则后续步骤会有问题

创建分区

1
2
sudo fdisk /dev/ndb0
n p 选start sector 回车 选end sector 回车 w 保存

创建文件系统

1
sudo mkfs.ext4 /dev/nbd0p1
1
2
3
4
5
6
7
8
9
10
sudo fdisk -l /dev/nbd0
Disk /dev/nbd0: 10 GiB, 10737418240 bytes, 20971520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 664E2EB5-C2C5-414B-AFBC-A422A6627DC8

Device Start End Sectors Size Type
/dev/nbd0p1 128 20971392 20971265 10G Linux filesystem
1
2
sudo fdisk -l /dev/nbd0
sudo mount /dev/nbd0p1 mnt_dir

系统只有一个loop设备时, 需要将其他的loop设备卸载后, 才能挂载该节点

卸载

修改里面的文件修改完后, 要及时卸载

1
2
sudo umount mnt_dir
sudo qemu-nbd --disconnect /dev/nbd0

u-boot extlinux

conf

1
2
3
4
5
6
label l0
menu label Debian GNU/Linux bookworm/sid 6.0.0-6-riscv64 # menu 显示项
linux /boot/vmlinux-6.0.0-6-riscv64 # 内核
initrd /boot/initrd.img-6.0.0-6-riscv64 # ramdisk
fdtdir /boot/dtbs/ # dtb
append root=LABEL=rootfs rw noquiet root=LABEL=rootfs # rootfs

注意下面几项:

initrd

1
2
file initrd.img-6.0.0-6-riscv64
initrd.img-6.0.0-6-riscv64: gzip compressed data, was "mkinitramfs-MAIN_aDjhxR", last modified: Sun Jan 8 06:50:27 2023, from Unix

Linux kernel提出了一个RAM disk的解决方案,把一些启动所必须的用户程序和驱动模块放在RAM disk中,这个RAM disk看上去和普通的disk一样,有文件系统,有cache,内核启动时,首先把RAM disk挂载起来,等到init程序和一些必要模块运行起来之后,再切到真正的文件系统之中。

查看initramfs的内容

1
2
mkdir initrdtmp && cd initrdtmp
zcat ../initrd.img-6.0.0-6-riscv64 ../initrd.img-6.0.0-6-riscv64.gz|cpio -i --make-directories

initrd 不一定非得用 mkinitramfs 来制作, 使用制作busybox 时的 cpio -H newc 也是可以的

1
find .| cpio -o -H newc | gzip > ../busybox_rootfs.cpio.gz

linux

支持 bzImage Image 格式编译出来的vmlinux elf

fdtdir

fdtdir 指定 dtb的目录, 一般名字会根据Machine 参数指定
需要注意dtb 一定是匹配的.
qemu 使用时, 可以使用下面的命令生成对应的 dtb 文件, 注意cpu 内存 machine的配置要和 qemu 启动虚拟机的命令指定的参数一致

1
sudo qemu-system-riscv64 -machine virt,dumpdtb=qemu-riscv.dtb -cpu rv64 -m 2G -smp 2

append

指定kernel cmdline
如 rootfs 启动, rootfs 在 /dev/mmcblk1p3 节点

1
append root=/dev/mmcblk1p3 rw console=tty0 console=ttyS0,115200 init=/init

如qemu 启动, 在指定hda 等参数后, 生成的节点一般是vda
则使用下面的配置即可

1
append root=/dev/vda rw init=/init #或rdinit=/linuxrc

本根分区启动, 适用于只有一个分区的情况:

1
append root=LABEL=rootfs rw noquiet

u-boot 编译

注意一定是 S-mode的, 别选错了

1
2
make qemu-riscv64_smode_defconfig O=virt_build
make O=virt_build -j12