TinyEMU之RISCV-PK编译
本文属于《 TinyEMU模拟器基础系列教程》之一,欢迎查看其它文章。
1 riscv-pk简介
RISCV-PK(RISC-V Proxy Kernel),是一个轻量级的应用程序执行环境,可以承载静态链接的RISC-V ELF二进制文件。它旨在支持有限I/O能力的捆绑RISC-V实现,从而通过将I/O相关的系统调用代理到主机来处理它们。
riscv-pk是一个代理内核,包含 bootloader,可以帮助模拟一个系统环境来运行Linux系统。
这里,我们可以简单理解为,就是把riscv-pk当作bootloader,bootloader的实际工作比较复杂,但是它最主要的工作就是启动 Linux内核。bootloader和 Linux 内核的关系,就跟 PC 上的BIOS和Windows的关系类似,bootloader就相当于BIOS。
riscv-pk的github:https://github.com/riscv-software-src/riscv-pk/tree/master
因此,本文的目的就是,编译出bootloader。
2 准备工作
环境为Ubuntu 20.04。
2.1 下载riscv-pk源码
下载riscv-pk源码
git clone https://github.com/riscv-software-src/riscv-pk.git
进入源码目录(必须进入.git文件所在目录)
cd riscv-pk
获取该仓库中,特定commit版本的源码
git checkout ac2c910b18c3e36cfd85080472e78ad2fe484325
- 在diskimage-linux-riscv-2018-09-23\patches\readme.txt中,指定了必须使用riscv-pk的git version为
ac2c910b18c3e36cfd85080472e78ad2fe484325
。- 不知道diskimage-linux-riscv-2018-09-23是什么的,可查看前文《TinyEMU之源码编译与使用》。
显示当前HEAD,已经切换到ac2c910;并且还会打印出这个commit的修改信息“Fix git-submodule fatal error for berkeley-softfloat-3”。
2.2 给riscv-pk源码打补丁
补丁文件为:diskimage-linux-riscv-2018-09-23\patches\riscv-pk.diff。
将riscv-pk.diff,拷贝至riscv-pk源码目录下。
执行如下命令,给源码打补丁:
patch -p1 < ./riscv-pk.diff
我们可以看到,成功对Makefile.in,.c,.s,.lds等文件,打了补丁。
- 在riscv-pk.diff中,记录了各文件,应该如何修改。在执行patch命令时,就会将riscv-pk.diff中的内容,写入各文件,也就是打补丁。如果没有打补丁,有可能编译失败(Makefile.in);我们还发现,补丁会修改c代码文件,没打补丁的话,也会影响程序代码执行。
- 注意:riscv-pk.diff文件,仅能对本commit版(ac2c910b18c3e36cfd85080472e78ad2fe484325)代码,打补丁;对其他的版本,打补丁会失败。
- 个人猜测,可能是TinyEMU作者,对riscv-pk源码进行了修改,以适配TinyEMU来运行,因此出了这个特定commit的补丁文件。
到这里,源码目录下的代码,就是完全正确的了。
接下来,开始编译。
3 编译riscv-pk
创建build目录
mkdir build
进入build目录
cd build
配置编译环境
../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu
- 指定交叉编译器为riscv64-unknown-linux-gnu,默认编译,会生成64位RISC-V的pk和bbl。
- riscv64-unknown-linux-gnu交叉编译器,我们已经在前文中装好了,不清楚的请看此文《TinyEMU之Linux Kernel编译》。
- 执行命令
../configure -h
,会打印帮助信息,此处不再赘述。
执行编译
make
很快编译完毕。
生成了64位RISC-V架构的可执行程序,bbl和pk。
- pk是代理内核,主要是将I/O相关的系统调用,代理到主机来处理(在TinyEMU中,我们不关心,这个pk)。
- bbl就是Bootloader,我们在TinyEMU中,用它来加载并启动linux系统。
4 bbl格式转换
在diskimage-linux-riscv-2018-09-23/readme.txt中,有明确描述:TinyEMU只支持原始(RAW)boot loader和kernel image。
因此,必须使用以下命令,将ELF格式bbl,转换为RAW格式bbl:
riscv64-unknown-linux-gnu-objcopy -O binary bbl bbl.bin
这个bbl.bin,才能在TinyEMU中,被正确加载执行。