ubuntu-base(arm64与riscv64) 根文件系统, 并用qemu启动

ubuntu-base(arm64与riscv64) 根文件系统

有个小需求,是在 arm64riscv64 上都跑起来 speccpu 2017

首先在 Qemu 上跑起来,需要考虑需要的【Linux 内核、根文件系统、Bootloader 】,其中 Bootloader 在 Qemu 中可以很简化,对于内核可以使用kernel参数加载,对于根文件系统则要费一些功夫

提前结论:我使用过程中在 qemuapt 从网上下载包是有问题的(上网对目前的我还是有点困难,还得学习,后续学会网络再写一份博客),但是本地挂载文件系统,然后 chrootapt 是可以正常下载的,所以暂时折衷了以下,需要的包通过本地 chroot 来进行安装依赖的包,然后进入 qemu 中使用

以下两篇博客是我记录的在 x86 物理机上执行 speccpu 2017 以及 qemu 运行 (aarch64 & riscv64)Linux 的过程,有兴趣可以参考:

Qemu 启动 Linux(aarch64 与 riscv64):https://blog.csdn.net/jingyu_1/article/details/135746098

SPEC CPU 2017 quick start:https://blog.csdn.net/jingyu_1/article/details/135695701

零、需求分析

不需要很复杂的文件系统,不需要像 Ubuntu 发行版那样包含各种各样的功能,也不需要桌面,只需要精简的文件系统并且支持 apt 等包管理,因为可能需要安装一些

  • ubuntu-server(x 支持 apt,但是有点太大,包含了很多其他的内容)

  • ubuntu-base(y 支持 apt,可以安装 gcc fortran 等)

  • busybox(x )

  • buildroot (x 不支持)

  • yocto(x 配置太复杂)

一、qemu安装、交叉编译工具链、内核编译

这些内容可以参考我的其他博客:

其中对于内核的编译,有一点要说明

配置、编译都要指定架构 ARCH 和交叉编译工具链 CROSS_COMPILE,一般情况下选择 defconfig 够用,但是可能有时候要添加一些模块,这时候 menuconfig 可能更方便,例如在我的需求中,需要挂载 speccpu2017.iso,需要添加 iso9600 的模块,但是 linux 内核默认是没有添加这个模块的,对于我的需要要补充,按如下操作:(这一步你不一定需要)

  • menuconfig 界面中,使用箭头键导航到 File systems 部分

  • 进入 CD-ROM/DVD Filesystems 子菜单

  • 找到 ISO 9660 CDROM file system support 选项(通常标记为 CONFIG_ISO9660_FS

  • 使用空格键选择该选项以编译为模块(通常会显示为 M),这个更加常用

  • 如果希望直接编译进内核,而不是作为模块,选择它为内核(通常显示为 *

模块大多数情况下表示为驱动,并且大多数情况下不会直接编入内核,而是配置为模块,在后续过程中启用模块

二、构建根文件系统

主要参考:https://www.cnblogs.com/phoebus-ma/p/17436089.html,并根据需求作了一定修改

Ubuntu-base 镜像: https://cdimage.ubuntu.com/ubuntu-base/releases/jammy/release/,你也可以选择你需要的版本进行安装

(包含了 arm64 以及 riscv 的版本,这点还是很友好的)

1、安装依赖:
shell 复制代码
sudo apt install binfmt-support qemu-user-static 
# 如果没安装 qemu 以及交叉编译工具链,也可以使用 apt 安装 qemu-system-aarch64 gcc-aarch64-linux-gnu

我使用的是 ubuntu-base 22.04.3(arm64):ubuntu-base-22.04.3-base-arm64.tar.gz

关于 riscv 的版本可以从上面的官方 ubuntu-base 镜像中下载

2、编译内核:

如果未编译内核,则参考上面文档中的方式,执行

shell 复制代码
# 对于 arm64
make defconfig ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-
# make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-
make -j8 ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-

# 对于 riscv
make defconfig ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu-
# make menuconfig ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu-
make -j8 ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu-

当需要调整时,使用 menuconfig 配置,比如遇到我上面所说的情况,或者后续内核缺少某个模块的时候再来修改配置,重新编译,(以及后续提到的安装内核模块)

3、创建空磁盘:

我们这里依赖的是 ubuntu-base 的根文件系统,所以只需要创建一个空的虚拟磁盘镜像即可

一种是使用 qemu-img 命令

另一种是使用 dd 命令

下面举例创建名为 arm64.imageext4 格式的虚拟磁盘

也可以是其他名字,我这里只是为了区分 arm 和 riscv 使用的磁盘,它们的文件系统不能共享

这里推荐 qemu-img 更加便捷(比如扩容十分方便)

shell 复制代码
# 使用 qemu-img 创建20G的虚拟磁盘
qemu-img create -f raw arm64.image 20G
# 将虚拟磁盘格式化成 ext4 格式
sudo mkfs.ext4 arm64.image

使用 dd 也可以

shell 复制代码
# arm64.ext4 为 1G 大小, 下面的内容根据需要进行配置
dd if=/dev/zero of=arm64.ext4 bs=1M count=1024
# 将其格式化成为 ext4 格式
mkfs.ext4 arm64.ext4
4、构建文件系统
shell 复制代码
# 将其挂载在本地的 /mnt 目录, (这里不一定必须 /mnt 目录)
sudo mount -t ext4 arm64.ext4 /mnt/
# 将 ubuntu-base 解压到 文件系统中
sudo tar -xf ubuntu-base-22.04.3-base-arm64.tar.gz -C /mnt/
# sudo tar -xf ubuntu-base-22.04.3-base-riscv64.tar.gz -C /mnt/

# apt 下载安装 qemu-user-static, 包含了 qemu-aarch64-static
sudo cp /usr/bin/qemu-aarch64-static /mnt/usr/bin/
# sudo cp /usr/bin/qemu-riscv64-static /mnt/usr/bin/
# 拷贝主机中的网络信息到镜像中,方便后续用 apt 安装软件(参考的博客里说的,暂未进一步验证)
sudo cp /etc/resolv.conf /mnt/etc/

# 安装内核模块
# 进入 linux 的配置编译路径
# INSTALL_MOD_PATH 指定内核模块安装的目标路径
# 模块将被安装到挂载点 `/mnt` 下, 这通常用于当您正在为一个不同于当前运行的系统(如嵌入式系统或不同的根文件系统)构建模块
cd ~/linux-6.7
sudo make modules_install ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- INSTALL_MOD_PATH=/mnt
# sudo make modules_install ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- INSTALL_MOD_PATH=/mnt

注意:qemu-user-static 建议使用 apt 安装的

当我使用从 github 上下载的 qemu-aarch64-static,会存在问题,当时用 sudo apt install qemu-user-static 下载的 qemu-aarch64-static 就没有问题(暂时不清楚原因)

5、chroot

chroot(change root)命令在 Unix 和类 Unix 系统中用于改变当前运行进程及其子进程的根目录。

为了使 chroot 环境正常工作,您可能需要复制或挂载一些必要的文件和目录(如 /dev, /proc, /sys 等)到新的根目录下。

如果您的主系统和 chroot 环境的架构不同(例如,主系统是 x86_64,而 chroot 环境是针对 ARM 构建的),则会出现执行格式错误。二进制文件需要与宿主系统的处理器架构相匹配。

上面的 qemu-aarch64-static 就是为了在 x86 上模拟 arm,如果不添加这个执行文件,chroot 则会失败

shell 复制代码
# 执行 chroot 需要挂载一些必要的目录(也是参考的博客里说明的)
# 其中 proc、sys 可以让 lscpu 命令查看到当前 cpu 的信息
sudo mount -t proc /proc /mnt/proc
sudo mount -t sysfs /sys /mnt/sys
sudo mount -o bind /dev /mnt/dev
sudo mount -o bind /dev/pts /mnt/dev/pts

# 执行 chroot, 进入 ubuntu-base(arm64) 的根文件系统
sudo chroot /mnt

这里进入的终端,可以使用你使用的物理机的网络,使用 apt 安装一些包

shell 复制代码
apt update
# 可能碰到证书等问题, 这就需要:
apt install ca-certificates
apt install systemd vim
# 根据需要安装一些包
# apt install gcc g++ gfortran flex bison

由于我的需求不需要设置用户密码这些,所以并未配置

需要的话 -> 可以参考我前面提到的文档

除此之外,参考文档中的 serial-getty\@.service 不存在,怀疑是本地 ubuntu 系统里的那一个文件

我并未配置,不影响使用

shell 复制代码
# 当要退出时, 回到原本的终端中, 执行 exit
exit
# 然后卸载磁盘
sudo umount /mnt/proc
sudo umount /mnt/sys
sudo umount /mnt/dev/pts
sudo umount /mnt/dev
sudo umount /mnt
5、Qemu 运行 Ubuntu base

执行时注意路径即可(aarch64)

shell 复制代码
sudo qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a72 \
    -nographic \
    -smp 8 \
    -m 16G \
    -kernel ../linux-6.7/arch/arm64/boot/Image \
    -append "root=/dev/vda rw console=ttyAMA0" \
    -netdev tap,id=eth0 \
    -device virtio-net-device,netdev=eth0 \
    -drive file=arm64.image,if=none,format=raw,id=hd0 \
    -device virtio-blk-device,drive=hd0
    
# 切换到 bash 使用体验更好
bash
# 挂载这两个文件系统, 可以让 ubuntu 探测到处理器的信息, lscpu 可以查到相关信息
mount -t proc proc /proc
mount -t sysfs sysfs /sys

# 下面是我的需求, 在前面添加了 iso 的模块之后, 可以挂载, 并且安装
mount -t iso9660 -o ro,exec,loop cpu2017-1_0_2.iso /mnt

启动 riscv 版本

shell 复制代码
sudo qemu-system-riscv64 \
    -M virt \
    -nographic \
    -smp 8 \
    -m 16G \
    -kernel ../linux-6.7/arch/riscv/boot/Image \
    -append "root=/dev/vda rw console=ttyS0" \
    -netdev tap,id=eth0 \
    -device virtio-net-device,netdev=eth0 \
    -drive file=riscv64.image,if=none,format=raw,id=hd0 \
    -device virtio-blk-device,drive=hd0
    
# 切换到 bash 使用体验更好
bash
# 挂载这两个文件系统, 可以让 ubuntu 探测到处理器的信息, lscpu 可以查到相关信息
mount -t proc proc /proc
mount -t sysfs sysfs /sys

# 下面是我的需求, 在前面添加了 iso 的模块之后, 可以挂载, 并且安装我使用过程中在 `qemu` 中 `apt` 从网上下载包是有问题的(上网还是有点困难),但是本地挂载文件系统,然后 `chroot` 再 `apt` 是可以正常下载的,所以折衷了以下,**需要的包通过本地 chroot 来进行安装依赖的包,然后进入 qemu 中使用**
mount -t iso9660 -o ro,exec,loop cpu2017-1_0_2.iso /mnt

注:我使用过程中在 qemuapt 从网上下载包是有问题的(上网还是有点困难),但是本地挂载文件系统,然后 chrootapt 是可以正常下载的,所以折衷了以下,需要的包通过本地 chroot 来进行安装依赖的包,然后进入 qemu 中使用

Spec cpu2017 可以正常跑起来了

基本可以满足我的需求,但是还是有点取巧了

关于 qemu ubuntu-base 配置联网,还在学习中,有熟悉的大佬可以评论

附录:Qemu 运行 (ARM64、RISC-V)Ubuntu

关于这部分,正好有 Ubuntu 官方的示例:

https://wiki.ubuntu.com/ARM64/QEMU

https://wiki.ubuntu.com/RISC-V/QEMU

参考官方的示例,可以在 qemu 中执行 arm64 以及 riscv 版本的 ubuntu server

有一点比较隔应,arm64 的版本的 user 以及 password 不知道,也没在官网上找到,这个不敢保证

riscv 版本可以在上述文档中找到关于 user 以及 password 的描述

总体来说,这种方式很快并且便捷,但是体量比 ubuntu-base 大很多,所以也会慢很多,在 qemu 或嵌入式中还是推荐 ubuntu-base 制作根文件系统

其中 -m 指定内存、-smp 指定核心数量,可以给大一点,如下:

shell 复制代码
# 其中的mac地址根据官方的脚本随机生成
sudo qemu-system-aarch64 \
	-m 8G -smp 8 -cpu cortex-a57 -M virt -nographic \
	-pflash /usr/share/AAVMF/AAVMF_CODE.fd \
	-pflash flash1.img \
	-drive if=none,file=jammy-server-cloudimg-arm64.img,id=hd0 -device virtio-blk-device,drive=hd0 \
	-netdev type=tap,id=net0 -device virtio-net-device,netdev=net0,mac=00:16:3e:3d:74:0f
shell 复制代码
qemu-system-riscv64 \
	-machine virt -nographic -m 2048 -smp 4 \
	-bios /usr/lib/riscv64-linux-gnu/opensbi/generic/fw_jump.bin \
	-kernel /usr/lib/u-boot/qemu-riscv64_smode/uboot.elf \
	-device virtio-net-device,netdev=eth0 -netdev user,id=eth0 \
	-device virtio-rng-pci \
	-drive file=ubuntu-22.04.3-preinstalled-server-riscv64+unmatched.img,format=raw,if=virtio
相关推荐
徐某人..11 分钟前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm
AOwhisky32 分钟前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes
小龙在慢慢变强..1 小时前
目录结构(FHS 标准)
linux·运维·服务器
2035去旅行1 小时前
嵌入式开发,如何选择C标准库
linux·arm开发
刘延林.1 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
CodeOfCC3 小时前
Linux 嵌入式arm64安装openclaw
linux·运维·服务器
宵时待雨3 小时前
linux笔记归纳3:linux开发工具
linux·运维·笔记
magrich4 小时前
安装NoMachine并解决无外接显示器桌面黑屏
linux·运维·服务器
fish_xk4 小时前
Linus基础指令
linux·服务器
用户34268877621964 小时前
Agent + Ollama 部署踩坑记录
ubuntu