任务目标
任务一:通过 QEMU 仿真 RISC-V 环境并启动 openEuler RISC-V 系统,设法输出 neofetch 结果并截图提交
任务二:在 openEuler RISC-V 系统上通过 obs 命令行工具 osc,从源代码构建 RISC-V 版本的 rpm 包,比如 pcre2。(提示首先需要在 openEuler的 OBS什么是 OBS? 上注册账号 https://build.openeuler.openatom.cn/project/show/openEuler:Mainline:RISC-V)
任务三:尝试使用 qemu user & nspawn 或者 docker 加速完成任务二
本人将采用 openEuler 23.09 进行作业 (铁头娃)
过程
启动 openEuler RISC-V 镜像
采用与笔试时相同的镜像,唯一不同的是把托管交给libvirt了,配置方式与常规镜像相同,不过需要小小的 customize 一下
<loader type="rom">/path/to/fw_payload_oe_uboot_2304.bin</loader>
使用 neofetch 获取信息
通过 libvirt 启动后,我们使用 dnf install 安装 neofetch
No match for argument: neofetch
Error: Unable to find a match: neofetch
哦,23.09 没有 neofetch呀,我们从 github下载 latest 然后安装吧
wget https://github.com/dylanaraps/neofetch/archive/refs/tags/7.1.0.zip
unzip 7.1.0.zip
cd neofetch-7.1.0
make install
现在我们就能看到neofetch的结果了
安装 osc
通过资料查询发现 openEuler 23.09 并没有osc 和 build 包,只能手动补上了,在 openSUSE 的源中找到了依赖环境类似的 fedora 38 的包,通过 wget 拉取并安装
其中 osc 选择的包为 osc-1.6.1-403.9.noarch.rpm, 直接使用 dnf 进行安装
obs-build 则直接拉取 github 进行安装
git clone https://github.com/openSUSE/obs-build.git
cd osb-build
make install
以及在后面拉去依赖的时候,还会发生缺少 tar_scm 的情况,所以在这里我先提前补好这个依赖
git clone https://github.com/openSUSE/obs-service-tar_scm
cd obs-service-tar_scm
make install
初始化 osc 项目
首先配置一下 osc 账户和服务器,账户需要先到官网注册
# ~/.config/osc/oscrc
[general]
apiurl = https://build.openeuler.openatom.cn
no_verify = 1
[https://build.openeuler.openatom.cn]
user=<hidden>
pass=<hidden>
然后接下来就是创建远程分支并将项目拉取到本地,并对文件进行重命名
osc branch openEuler:Mainline:RISC-V coreutils
osc co home:root:openEuler:Maniline:RISC-V coreutils
osc up -S
rm -f _service;for file in `ls | grep -v .osc`;do new_file=${file##*:};mv $file $new_file;done
编译
输入指令开始编译
osc build standard_riscv64 riscv64
第一次编译会要求是否信任一些依赖源,我这里都选择只信任首次,编译结果如下
可以看到成功编译出来了
使用容器进行加速
这里就比较牵扯到本人日用环境相关部分了,本人当前的工作机是一台台式机兼服务器,平时运行一些东西时使用 rootless podman 较多,包括本博客在内的所有对外服务基本上都是在这台机器上使用 podman-compose 作为 hook 进行持久化部署的,所以第一次自然想着是在用户级别的容器上进行 osc build
编写了一个简单的脚本和 带有 build 和 osc 的Containerfile 进行操作
osc.sh
#!/usr/bin/bash
RUNTIME=podman
IMAGE_NAME=osc-build
WORKDIR=./build
OSCRC=./oscrc
main() {
if [[ "$1" == "build" ]]; then
$RUNTIME build -t $IMAGE_NAME .
return
elif [[ "$1" == "run" ]]; then
$RUNTIME run -it --rm --network=host -v $WORKDIR:/root/build:Z -v $OSCRC:/root/.config/osc/oscrc:z --privileged $IMAGE_NAME
fi
}
main $1
Containerfile
FROM docker.io/library/fedora:39
RUN dnf install osc obs-build -y
WORKDIR /root
使用 ./osc.sh build 先进行镜像构筑,再运行 ./osc.sh run 进入容器空间
操作的过程与vm相似这里就不再赘述了,最大的问题可能还是在于当运行 build 以后出现了 mknod permission denied 的相关错误,然后在这个 issue 里找到了答案,issue 提到的 rootless.md 中有详细说明
Making device nodes within a container fails, even when running --privileged.
The kernel does not allow non root user processes (processes without CAP_MKNOD) to create device nodes. If a container needs to create device nodes, it must be run as root.
所以很无奈,我只能使用有根容器进行编译了,这里虽然还是用的有根容器,但是后面的编译可能会更倾向于在本地 OS 进行编译,因为 Fedora 39 在 FS 资源隔离上我个人还是相对比较满意,不太会影响我目前的工作流,下面就给出有根容器和OS的编译结果
首先是有根容器
然后是OS下编译
OS相比容器少花了100s,而且多套一层也没有为我的工作流带来什么便利,这也是我以后更多会在本地直接编译的原因。
总结
相对来说还是很简单,整个过程也还有前辈们留下了一些资料可以参考,也对当前 osc 的工作流有了一点熟悉