在QEMU上运行OpenSBI+Linux+Rootfs

news2024/10/6 0:35:24

在QEMU上运行OpenSBI+Linux+Rootfs

  • 1 编译QEMU
  • 2 安装交叉编译工具
  • 3 编译OpenSBI
  • 4 编译Linux
  • 5 创建根文件系统
    • 5.1 编译busybox
    • 5.2 创建目录结构
    • 5.3 制作文件系统镜像
      • 5.3.1 创建 ext2 文件
      • 5.3.2 将目录结构拷贝进 ext2 文件
      • 5.3.3 取消挂载
  • 6 运行OpenSBI+Linux+Rootfs

本文所使用的版本,如下:

  • qemu-7.1.0
  • 交叉编译工具:riscv64-glibc-ubuntu-20.04-nightly-2023.01.31-nightly
  • opensbi v1.2
  • linux 5.15.158
  • busybox 1.36.1

1 编译QEMU

下载qemu-7.1.0源码

wget https://download.qemu.org/qemu-7.1.0.tar.xz

解压

tar xvJf qemu-7.1.0.tar.xz

进入目录

cd qemu-7.1.0

配置qemu

./configure --target-list=riscv64-softmmu,riscv64-linux-user --prefix=/opt/qemu

riscv64-softmmu 指定生成riscv64 system emulator
riscv64-linux-user 指定生成riscv64 user mode emulator

执行编译

make -j`nproc`

在qemu-7.1.0/build/目录下,生成了可执行程序qemu-system-riscv64

查看qemu版本

./qemu-system-riscv64 --version

可以看到版本号为:QEMU emulator version 7.1.0

安装(可选)

sudo make install

安装时,会将可执行程序qemu-system-riscv64,以及头文件等其他文件,拷贝至/opt/qemu目录下。

到这里,模拟器已经准备好了,我们还需要准备OpenSBI(Bootloader)、Linux Kernel以及文件系统(busybox)。
接下来,我们继续。

2 安装交叉编译工具

我们先安装交叉编译工具,以便后续编译OpenSBI、Linux Kernel以及busybox。

下载编译好的RISC-V交叉编译器:
riscv64-glibc-ubuntu-20.04-nightly-2023.01.31-nightly.tar.gz

解压

tar -xvzf riscv64-glibc-ubuntu-20.04-nightly-2023.01.31-nightly.tar.gz

编辑.bashrc

vim ~/.bashrc

将编译器bin路径(/home/tools/riscv/bin替换为自己的路径),加入.bashrc文件末尾。

export PATH=/home/tools/riscv/bin:$PATH

使路径生效

source ~/.bashrc

最后,查看编译器版本,以验证安装

riscv64-unknown-linux-gnu-gcc -v

编译器环境搭建好了。

3 编译OpenSBI

下载源码

git clone https://github.com/riscv-software-src/opensbi.git

进入目录

cd opensbi/

获取V1.2版本源码

git checkout v1.2

实验时,使用最新版本,会报错,因此这里使用V1.2版本。
具体报错信息,如下:
qemu-system-riscv64: Some ROM regions are overlapping
These ROM regions might have been loaded by direct user request or by default.
They could be BIOS/firmware images, a guest kernel, initrd or some other file loaded into guest memory.
Check whether you intended to load all this guest code, and whether it has been built to load to the correct addresses.
The following two regions overlap (in the memory address space):
fw_jump.elf ELF program header segment 1 (addresses 0x0000000000000000 - 0x0000000000023940)
mrom.reset (addresses 0x0000000000001000 - 0x0000000000001028)

设置环境变量

export CROSS_COMPILE=riscv64-unknown-linux-gnu-

执行编译

make PLATFORM=generic

编译完后,在opensbi/build/platform/generic/firmware/目录下
生成的固件,如下所示:
在这里插入图片描述

生成的固件有三种类型:dynamic、jump和payload

  • dynamic:带有动态信息的固件
  • jump:指定下一级的boot地址跳转
  • payload:包含下一级boot的二进制内容,通常是uboot/linux

这里我们使用jump类型固件(fw_jump.elf),OpenSBI运行后,可以直接跳转到kernel运行。

因为opensbi本身就是一个bootloader,因此可以不使用uboot引导kernel,通过opensbi的jump固件,可以直接跳转到kernel启动。

4 编译Linux

Linux内核官网:https://www.kernel.org,进去找到linux-5.15.158版。

这里,可直接下载linux-5.15.158源码:
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.158.tar.xz

解压

tar -xf linux-5.15.158.tar.xz

进入目录

cd linux-5.15.158

配置环境变量

export ARCH=riscv
export CROSS_COMPILE=riscv64-unknown-linux-gnu-

使用linux默认配置

make defconfig

执行编译

make -j`nproc`

编译完成后,在linux-5.15.158/arch/riscv/boot下生成可执行文件Image

5 创建根文件系统

5.1 编译busybox

下载busybox源码

git clone https://git.busybox.net/busybox
cd busybox

打开busybox配置界面

make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- menuconfig

配置为生成静态二进制可执行程序,选择“Build static binary (no shared libs)”

在这里插入图片描述

如果是动态编译,那么在kernel中运行时,需要携带运行库。
没有运行库,就会报错: Starting init: /sbin/init exists but couldn’t execute it (error -8)

执行编译与安装

make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j`nproc`
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- install -j`nproc`
cd ..

源码目录下,生成了二进制文件: busybox

5.2 创建目录结构

创建主要目录

mkdir root && cd root
mkdir -p bin etc etc/init.d dev lib proc opt sbin sys tmp usr usr/bin usr/lib usr/sbin

将busybox文件,复制到bin目录中

cp /path/to/busybox/busybox bin/busybox

生成指向init文件的符号链接

ln -s ../bin/busybox sbin/init
ln -s sbin/init init
ln -s ../bin/busybox bin/sh

接下来,解释这些命令。

  • ln -s ../bin/busybox sbin/init:表示在sbin目录下创建一个名为 init 的符号链接,该链接指向父目录中的 bin 子目录下的 busybox 文件。
    在标准的 Linux 发行版中,/sbin/init 是初始化系统的入口点,即这个init文件,就是init进程,它是内核启动的第一个用户级进程。
    因此,需要使用 BusyBox 替代标准的 init 进程。
    需要将 BusyBox 的路径链接到 /sbin/init 或 /init,以便在系统启动时能够找到并执行它。
  • ln -s sbin/init init:表示在当前目录下创建一个名为init的符号链接,该链接指向sbin/init文件。
  • ln -s ../bin/busybox bin/sh:表示在bin目录下创建一个名为sh的符号链接,该链接指向父目录中的 bin 子目录下的 busybox 文件。
    许多脚本和程序都依赖于 /bin/sh 的存在。
    通过创建这个链接,可以确保这些脚本能够在使用BusyBox的系统中正常运行。
    比如,当 init 进程先执行,然后会调用 /etc/init.d/rcS 启动脚本,此时如果没有/bin/sh的话,就会报错:can’t run ‘/etc/init.d/rcS’: No such file or directory


    若没有找到init文件时,会报以下错误:
    [ 0.584936] Run /sbin/init as init process
    [ 0.593521] Run /etc/init as init process
    [ 0.594686] Run /bin/init as init process
    [ 0.595995] Run /bin/sh as init process
    [ 0.596717] Kernel panic - not syncing: No working init found.

创建必要设备节点

sudo mknod dev/sda b 8 0 
sudo mknod dev/console c 5 1

创建初始化脚本

vim etc/init.d/rcS

在rcS中填入如下内容

#!/bin/sh
/bin/busybox mount -o remount rw /
/bin/busybox --install -s

mount -t proc proc /proc
mount -t sysfs sys /sys

接下来,解释这些命令。

  • /bin/busybox mount -o remount rw /:使用 BusyBox 中的 mount 命令,来重新挂载(remount)根文件系统(/)为读写模式(rw)。
    从Kernel日志:VFS: Mounted root (ext2 filesystem) readonly on device 254:0,发现默认按照只读挂载,因此本命令就是,以可读写重新挂载。
  • /bin/busybox --install -s :将 BusyBox 安装到当前系统中,包括在/bin目录下,创建大量常用命令的符号链接(可作为单独命令使用),会进行写入操作,因此需要文件系统可写。

赋予rcS文件可执行权限

chmod +x etc/init.d/rcS

此时root目录结构,如下所示:

在这里插入图片描述

到这里,root目录下,已经具备了一个linux文件系统的基本目录了。

5.3 制作文件系统镜像

我们,将上述root目录结构,打包成ext2镜像文件。

5.3.1 创建 ext2 文件

生成4M大小的,空白镜像文件rootfs.ext2

dd if=/dev/zero of=rootfs.ext2 bs=1M count=4

将镜像文件rootfs.ext2,格式化为ext2文件系统

mkfs.ext2 rootfs.ext2

5.3.2 将目录结构拷贝进 ext2 文件

创建目录

mkdir /mnt/ext2/

将rootfs.ext2,挂载到/mnt/ext2/目录

mount -t ext2 rootfs.ext2 /mnt/ext2/

挂载到/mnt/ext2/目录后,当你在 /mnt/ext2/ 下写入文件或修改文件时,这些更改会反映到 rootfs.ext2 文件中。

拷贝root目录内容,至/mnt/ext2/

cp -pr root/* /mnt/ext2/

也就是,将目录结构拷贝进 rootfs.ext2 文件中了。

5.3.3 取消挂载

umount /mnt/ext2/
sync		# 强制内容立刻写入文件

到这里,我们已经对rootfs.ext2文件写入完毕,写入的内容,主要包括busybox、目录结构、rcS文件等。

rootfs.ext2,即为可供 Linux kernel 挂载所用的根文件系统。

6 运行OpenSBI+Linux+Rootfs

将fw_jump.elf、Image、rootfs.ext2,拷贝到qemu-7.1.0/build/目录下。

新建start-qemu.sh脚本,输入以下内容:

#!/bin/sh

./qemu-system-riscv64 -M virt \
-bios fw_jump.elf \
-kernel Image \
-append "rootwait root=/dev/vda ro" \
-drive file=rootfs.ext2,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=net0 -device virtio-net-device,netdev=net0 -nographic
  • bios,指定OpenSBI可执行文件fw_jump.elf
  • kernel,指定Linux镜像Image
  • drive,指定根文件系统rootfs.ext2

修改权限

chmod 777 start-qemu.sh

在QEMU中,运行OpenSBI+Linux+Rootfs

./start-qemu.sh

运行效果,如下所示:

在这里插入图片描述

成功进入Linux!

在这里插入图片描述

基本命令可用,使用poweroff命令可关机。

如果Kernel,发生panic异常时,通过Ctrl+C无法退出。
可以通过以下命令,来退出qemu:
kill $(ps aux | grep qemu | grep -v grep | awk '{print $2}')


参考链接:

  • 《手把手教你在QEMU上运行RISC-V Linux》
  • 《在 QEMU 上运行 RISC-V 64 位版本的 Linux》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1649516.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二证券|集合竞价915到920能成交吗?

不能,买卖日9点15分到9点20分是集合竞价申报时刻,还没有发生集合竞价。 在这个时刻段内,投资者能够申报,也能够撤单,但这些挂单并不会立即成交。9:25时,系统会对一切收到的挂单进行一次性促成处理&#xf…

外网禅道配置

exportfs -avrf 修改代码,避免启动太慢:vi /opt/zbox/bin/zbox.php 启动和停止 /opt/zbox/zbox start /opt/zbox/zbox stop

windows 双网卡同时接入内外网

在公司使用wifi接入使用桌面云,但是公司wifi不能上外网,查资料不方便,通过手机同时接入外网。 同一台电脑设置同时连接内外网(wifi或共享的网络)_win7电脑同时使用手机和usb网卡使用wifi-CSDN博客 route print查看当前…

SolidWorks进行热力学有限元分析二、模型装配

1.先打开软件,新建装配体 2.选中你要装配的零件,直接导入就行 3.鼠标点击左键直接先放进去 4.开始装配,点配合 5.选择你要接触的两个面,鼠标右键确定,然后把剩下的面对齐一下就行了 6.搞定

【C 数据结构-动态内存管理】4. 无用单元收集(垃圾回收机制)

文章目录 【 1. 问题描述与解决方法 】【 2. 中断回收机制 】 【 1. 问题描述与解决方法 】 问题描述 动态存储管理的运行机制可以概括为:当用户发出申请空间的请求后,系统向用户分配内存;用户运行结束释放存储空间后,系统回收内…

5月5日智渍洁对江苏某公司冷却塔清洗-智渍洁

简报:5月5日智渍洁对江苏某公司冷却塔清洗 5月5日智渍洁对江苏某公司冷却塔清洗 - 重庆智渍洁环保科技有限公司简报:5月5日智渍洁对江苏某公司冷却塔清洗https://www.zhizijie.com/hl/zixun/gongsi/236.html

Python Dash库:一个Web应用只需几行代码

大家好,在数据科学领域,数据可视化是将数据以图形化形式展示出来,帮助我们更直观地理解数据。Python中有一个非常流行的数据可视化库叫做Dash,Dash以其简洁、高效和强大的功能而闻名,它允许开发者快速构建交互式Web应用…

Vulnhub项目:NAPPING: 1.0.1

1、靶机介绍 靶机地址:Napping: 1.0.1 ~ VulnHub 2、渗透过程 老规矩,先探测,靶机ip:192.168.56.152 本机ip:192.168.56.146 来看一看靶机开放哪些端口,nmap一下 nmap -sS -sV -A -T5 192.168.56.152 开…

Zookeeper服务

一、什么是Zookeeper Zookeeper 是一个分布式应用程序的协调服务,它提供了一个高性能的分布式配置管理、分布式锁服务和分布式协调服务。它是 Apache 软件基金会的一个项目,被设计用来处理大规模的分布式系统中的一些关键问题。 Zookeeper的组成员关系&…

java10基础(this super关键字 重写 final关键字 多态 抽象类)

目录 一. this和super关键字 1. this关键字 2. super关键字 二. 重写 三. final关键字 四. 多态 五. 抽象类 1. 抽象方法 2. 抽象类 3. 面向抽象设计 一. this和super关键字 1. this关键字 this 当前对象的引用 this.属性 this.方法名() this() -- 调用构造函数 …

2024 AI中转计费平台系统源码

简介: 2024 AI中转计费平台系统源码 文件下载https://www.skpan.cn/CNZjzyC4txX 图片:

荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)

本题链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 3 4 2 .... ***. ..a. 输出 yes 思路: 根据题意,这里 1 s 可以移动多次,我们将每次可以移动避开雪的的位置存储起来,判断当…

运维开发工程师教程之MongoDB单机版设置

MongoDB单机版设置 一、创建虚拟机 在VMware Workstation软件中新建一个虚拟机,具体操作步骤如下: ①运行VMware Workstation软件,进入到主界面,单击“创建新的虚拟机”来创建新的虚拟机,如图3-1所示。 图3-1 VMware…

3D相机及应用

无论是2D相机和3D相机,在工业应用中都有着不可或缺的作用。3D相机与2D相机的最大区别在于,3D相机可以获取真实世界尺度下的3D信息,而2D相机只能获取像素尺度下的2D平面图像信息。通过3D相机得到的数据,我们可以还原出被测量物体的…

shell脚本脚本变量

shell脚本的概念: 1.讲要执行的命令按顺序保存到一个文本文件 2.给文件可执行权限 3.可以结合各种shell控制语句以完成更复杂的操作 linux中包含shell的文件有 [rootlocalhost ~]# cat /etc/shells /bin/sh #UNIX最初使用的 shell,已经被…

流量暴涨!抖音+快手+小红书获客攻略!

在数字营销的海洋中,抖音、快手和小红书无疑是三座巨大的灯塔,照亮了品牌和个人获取流量的道路。这些平台不仅拥有庞大的用户基础,而且其独特的算法和社交特性让获客变得更加高效而精准。接下来,让我们深入探讨如何通过这三个平台…

鸿蒙OpenHarmony【基于Hi3516DV300开发板(时钟应用开发)】

概述 本文将介绍如何快速搭建基于OpenHarmony标准系统(Hi3516DV300开发板)的应用开发环境,并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过本链接获取。 时钟App是一款显示实时时间的应用,…

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关,纯C语言的UI库(目前只能应用于128*64的单色OLED屏幕上,后期会改进,支持更多尺寸)。因此,我们可以在PC上实现它,本文就以在PC上使用 VScode…

124.反转链表(力扣)

题目描述 代码解决(思路1:双指针) class Solution { public:ListNode* reverseList(ListNode* head) {ListNode*temp;//保存cur下一个节点ListNode*curhead;ListNode*preNULL;while(cur){tempcur->next;// 保存一下 cur的下一个节点&#…

新的循环体和define

目录 do while讲解 练习: 结果: 分析: 定义:宏(define) 练习: 结果: 分析: define的优缺点 优点: 缺点: 作业: 大家假期…