目录
一、开发环境配置
二、测试
三、Makefile
四、开发前需要了解的知识
在前面我们使用Verilog实现了一个简易的RISC-V处理器,并且能烧录到板子上跑一些简单C程序,传送门:
RISC-V处理器的设计与实现(一)—— 基本指令集_risc_v处理器_Patarw_Li的博客-CSDN博客
RISC-V处理器的设计与实现(二)—— CPU框架设计_Patarw_Li的博客-CSDN博客
RISC-V处理器的设计与实现(三)—— 上板验证_Patarw_Li的博客-CSDN博客
接下来我会开始编写一个riscv上的简易操作系统,然后放到我们做的riscv处理器上运行,参考的资料和视频链接如下:
[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春
riscv-operating-system-mooc: 开放课程《循序渐进,学习开发一个 RISC-V 上的操作系统》配套教材代码仓库。mirror to https://github.com/plctlab/riscv-operating-system-mooc
本人自己做的 riscv-cpu 项目仓库(如果觉得对你有帮助请一定一定点个 star!):
riscv-cpu: 一个基于RISC-V指令集的CPU实现(成功移植到野火征途PRO开发板)
一、开发环境配置
使用的开发环境如下:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.2 LTS
Release: 20.04
Codename: focal
$ uname -r
5.15.0-76-generic
安装Ubuntu 20.04官方提供的 GNU工具链和 QEMU 模拟器:
sudo apt update
sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc
其中 gcc-riscv64-unknown-elf 就是我们的交叉编译工具,可以把程序编译成riscv上的可执行文件; gdb为debug工具;qemu是一个模拟器,可以模拟出riscv系统。
二、测试
在配置好开发环境后,我们可以用一个程序来测试一下,下面是前面文章用到的led程序,我们会在Ubuntu上把这个C程序利用交叉编译工具链编译成二进制.bin文件,然后通过串口将.bin文件烧录到处理器的memory中:
int main(){
int n = 5;
int sum = 0;
for (int i = 1; i <= n; ++i) {
sum = sum + i;
}
int* gpio_data = (int*) 0x30000004; // gpio_data寄存器的地址
*gpio_data = sum; // 将gpio_data寄存器的内容改为sum值
return 0;
}
然后我们需要编译我们的led.c程序:
riscv64-unknown-elf-gcc -c -nostdlib -march=rv32i -mabi=ilp32 led.c -o main.o
- -c 选项是编译、汇编到目标代码,但不进行链接。
- -nostdlib 告诉编译器不要把标准库编译进去。
- -march=rv32i -mabi=ilp32 用于指定指令集架构和 ABI,因为我们只实现了部分整数指令,所以使用rv32i。
编译后,我们可以得到 main.o
,它是一个 ELF 文件。我们只需要 .text
部分的机器指令,所以用 objcopy
对它进行处理:
riscv64-unknown-elf-objcopy -O binary -j .text main.o main.bin
-
-O binary
选项用于输出纯二进制文件。 -
-j .text
是告诉它只保留.text
部分。
经过处理,生成的二进制文件只含有机器指令。但此时的程序并不能直接运行。我们用 objdump
进行反编译,看看生成的汇编是怎么样的:
riscv64-unknown-elf-objdump -D -b binary main.bin -mriscv
可以看到第一行直接将sp(堆栈指针寄存器,stack pointor)减去了32,此时sp寄存器为负值,肯定无法正常执行,所以我们还需要一个初始化文件init.s来帮助我们初始化sp寄存器,内容如下:
li sp, 0x10000000
addi sp, sp, 256
我们处理器的ram地址是从0x10000000开始, 利用li sp, 0x10000000指令将sp寄存器内容初始化为0x10000000,然后将栈的大小设置为256(因为这里栈是向下递减的)。
然后将init.s编译成init.o文件:
riscv64-unknown-elf-gcc -c -nostdlib -march=rv32i -mabi=ilp32 init.s -o init.o
然后我们再把init.o和main.o链接起来,生成final.o:
riscv64-unknown-elf-ld -melf32lriscv -o final.o init.o main.o
最后生成二进制文件final.bin:
riscv64-unknown-elf-objcopy -O binary -j .text final.o final.bin
用 objdump
进行反编译,看看生成的汇编是怎么样的:
riscv64-unknown-elf-objdump -D -b binary final.bin -mriscv
可以看到前面已经变成初始化文件init.s里面的内容了,这样也就不用担心sp为负的问题了。
然后编写串口上位机发送Python程序(串口发送程序已经更新至gitee仓库:cpu_prj: 一个基于RISC-V指令集的CPU实现):
import serial
try:
ser = serial.Serial("COM3", 19200, timeout=0.5)
if ser.is_open:
print("COM3" + " open success!")
with open('./final.bin', 'rb') as f:
a = f.read()
print("sending bin file")
count = ser.write(a)
print("send over, the number of byte: ", count)
except Exception as e:
print("---error---: ", e)
# 如果报错ModuleNotFoundError: No module named 'serial',则执行 pip install pyserial
将编译好的final.bin文件移动到和串口发送程序同目录下,记得修改串口设置为你自己的,我这里用的串口为COM3,波特率为19200。
将移植了riscv处理器的开发板与pc连接,按住key1不动后,然后运行python串口程序,程序发送完毕后松开key1,然后点击板子上的复位按键,即可看到四个led灯全亮:
知道如何烧录程序到处理器上的话,之后操作系统的开发和验证都会方便很多。
三、Makefile
既然生成二进制文件要这么多步骤,我们可以使用Makefile来帮助我们自动化构建,这样我们就不需要每次修改代码都要执行这么多指令,工程结构如下 :
main.c为用户编写的代码,init.s为上面的初始化文文件,Makefile脚本代码如下:
CROSS_COMPILE = riscv64-unknown-elf-
CFLAGS = -c -nostdlib -march=rv32i -mabi=ilp32
CC = ${CROSS_COMPILE}gcc
LD = ${CROSS_COMPILE}ld
OBJCOPY = ${CROSS_COMPILE}objcopy
OBJDUMP = ${CROSS_COMPILE}objdump
all: final.bin
final.bin:
${CC} ${CFLAGS} -o init.o init.s
${CC} ${CFLAGS} -o main.o main.c
${LD} -melf32lriscv -o final.o init.o main.o
${OBJCOPY} -O binary -j .text final.o final.bin
code: all
@${OBJDUMP} -D -b binary final.bin -mriscv | less
clean:
rm -fr *.o *.bin
1. 生成二进制.bin文件,执行make即可:
make
之后将final.bin文件烧录到板子上即可。
2. 查看二进制文件的final.bin的汇编代码:
make code
3. 清除所有生成的文件:
make clean
如果对Makefile不熟悉的可以看这篇文章:Makefile教程(绝对经典,所有问题看这一篇足够了)_GUYUEZHICHENG的博客-CSDN博客
四、开发前需要了解的知识
在进行操作系统的开发前,你应该要熟悉如下知识:文章来源:https://www.toymoban.com/news/detail-522178.html
- 交叉编译
- 调试器GDB
- 模拟器QEMU
- 项目构造工具Make
如果遇到问题也欢迎加群 892873718 交流~ 文章来源地址https://www.toymoban.com/news/detail-522178.html
到了这里,关于开发一个RISC-V上的操作系统(一)—— 环境搭建的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!