xv6-k210/doc/report_2020_12_26.md

286 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
marp: true
---
# **xv6-k210 移植报告**
+ 报告人: 车春池
+ 华中科技大学本科三年级
+ 时间: 2020-12-26
+ 地点: 北京中科院计算所
```
(`-') (`-') <-.(`-')
(OO )_.-> _(OO ) __( OO)
(_| \_)--.,--.(_/,-.\ ,--. (`-') '-'. ,--. .----. .--. .----.
\ `.' / \ \ / (_/ / .' ( OO).-> | .' / \_,-. | /_ | / .. \
\ .') \ / / . / -. (,------. | /) .' .' | | | / \ .
.' \ _ \ /_)' .-. \ `------' | . ' .' /_ | | ' \ / '
/ .'. \ \-'\ / \ `-' / | |\ \ | | | | \ `' /
`--' '--' `-' `----' `--' '--' `------' `--' `---''
```
---
## **前言**
+ `xv6``xv6-riscv``MIT` 写的教学操作系统,在 [github](https://github.com/mit-pdos/xv6-riscv.git) 上开源
+ `xv6` 官方目前只支持 `qemu` 平台
+ `k210``kendryte` 产商于 2018 年发布的 `RISC-V` 双核 64 位处理器
+ `RustSBI`:华科网安同学 `洛佳` 提供的强大的 `Rust` 嵌入式项目,为移植工作提供很大帮助
---
## **当前成果**
![run](../img/xv6-k210_on_k210.gif)
---
## **运行流程**
+ 需要`RISC-V` 编译链,用它来编译二进制内核镜像,可以是 `riscv64-unknown-elf` 或者 `riscv64-linux-gnu`
+ 需要搭载 `k210` 芯片的开发板: `Maixpy` 系列,淘宝有售
+ SD 卡:可选,如果不跑文件系统的话
+ 在 `github` 上获得项目源码: `git clone https://github.com/SKTT1Ryze/xv6-k210`
+ 用读卡器把 SD 卡连接到电脑
+ 进入到 `xv6-k210` 目录下运行命令 `make sdcard`,然后 `Makefile` 会打包一个文件系统镜像写入到 SD 卡
+ 将 SD 卡插到 `k210` 板子上,并用 type-C 线连接 `k210` 板子到电脑上
+ 在 `xv6-k210` 目录下运行命令 `make run`
+ 查看 `USB` 端口: `ls /dev/ | grep USB`
---
## **K210**
+ 两个核心,双核对等,具备独立 FPU
+ 64 位处理核
+ 标称频率为 400MHZ
+ 双精度浮点处理单元
+ PLIC 支持高级中断管理
+ CLINT 支持 CPU 内置定时器中断与跨核心中断
+ 8M 的片上 SRAM
---
## **K210 SRAM**
|模块名称|映射类型|开始地址|结束地址|空间大小|
|---|---|---|---|---|
|通用 SRAM 存储器|经 CPU 缓存|0x80000000|0x805FFFFF|0x600000|
|AI SRAM 存储器|经 CPU 缓存|0x80600000|0x807FFFFF|0x200000|
|通用 SRAM 存储器|非 CPU 缓存|0x40000000|0x405FFFFF|0x6000000|
|AI SRAM 存储器|非 CPU 缓存|0x40600000|0x407FFFFF|0x200000|
---
## **K210 VS QEMU**
+ 指令集标准版本不同qemu 是 v1.11k210 是 v1.9.1
+ `MMIO` 内存布局不同
+ 虚拟文件系统 vs SD 卡上的文件系统
---
## **RustSBI**
+ 脱胎于 2020 年暑假鹏城实验室的“rCore代码之夏”活动
+ 操作系统二进制接口标准SBI 标准)的一种实现
+ Rust 语言编写
+ 模块化设计,方便支持新的平台
+ 进入国际 RISC-V SBI 实现列表,获得编号 4
| Implementation ID | Name |
|--- |--- |
| 0 | Berkeley Boot Loader (BBL)|
| 1 | OpenSBI |
| 2 | Xvisor |
| 3 | KVM |
| **4** | **RustSBI** |
| 5 | Diosix |
---
## **移植工作一览**
+ 多核启动
+ 内存分配
+ 虚拟内存管理
+ 中断处理
+ S 态外部中断
+ 用户多进程
+ SD 卡驱动
+ 文件系统
+ 软硬件协同调试
+ 中文文档
---
## **多核启动**
+ 链接脚本 k210.ld调整内核镜像布局和指定内核入口点
+ `RustSBI` 将处理器核从 `M` 态切换到 `S` 态,然后跳转到内核起始地址
+ entry_k210.S操作系统内核运行的第一段代码对应链接脚本中的内核入口点
+ `main.c`:进入 `supervisor` 模式S 态)
+ `RustSBI` 提供接口,使得可以在启动的第 0 个核中唤醒其他核
---
## **多核启动**
![boot](../img/boot.jpg)
---
## **内存分配**
+ `kalloc.c`
+ 可分配的内存空间范围:`kernel_end` ~ `PHYSTOP`
+ 内存分配初始化void kinit(),初始化锁,开拓内存空间
+ void* kalloc()4096 字节
+ 内核维护一个链表:空闲链表
---
## **虚拟内存管理**
+ `vm.c`
+ 维护一个内核页表 `kernel_pagetable`
+ 在 void kvminit() 里面进行`内核空间`虚拟地址到物理地址的映射
+ 进行 MMIO内核空间用户态空间 RustSBI 等内存空间的映射
+ 在 void kvminithart() 里面将内核页表的首地址放到 `satp` 寄存器,然后运行 `sfence.vma` 指令
---
## **虚拟内存管理**
**但是!! K210 采用的是 1.9 版本的 RISC-V 标准,不存在 sfence.vma 这条指令,只有旧版指令 sfence.vm**
怎么办?求助 `RustSBI`
---
## **虚拟内存管理**
**RustSBI 如何解决这个问题?**
+ `sfence.vma` 作为异常指令被 `RustSBI` 捕获
+ 读取 `satp`(读取 `ppn`
+ 根据第二步读取的值写 `sptbr` v1.9 指令集版本使用的寄存器,相当于 `satp`)设置页表
+ 设置 `mstatus` 中相应的位开启分页(内核无法做这个工作)
+ 运行旧版指令 `sfence.vm` 清空 `TLB`
+ 写 `mepc` 并返回到 `sfence.vma` 的下一条指令去运行(`mepc + 4`
---
## **虚拟内存管理**
<!-- <img src="../img/mem_map.jpg"> -->
![mem_map](../img/mem_map.jpg)
---
## **中断处理**
+ `trap.c`
+ void kerneltrap()S 态中断或异常陷入这个函数,在这里处理或者转发
+ void usertrap()U 态中断或异常陷入这里
+ int devintr():判断中断的来源(比如时钟中断返回 2
---
## **中断处理**
中断处理初始化工作:
+ void trapinithart()
+ 将 `kernelvec` 地址写入到 `stvec`
+ `kernelvec` 函数在 `kernelvec.S` 汇编文件里面,保存上下文,进入 `kerneltrap`,恢复上下文,返回
+ 设置 `sstatus.sie`
+ 设置 `sie` 开启外部中断,时钟中断和软件中断
---
## **时钟中断**
**通过 RustSBI 设置时钟中断**
+ `timer.c`
+ 参考 `rCore` 实现
+ void set_next_timeout():设置下一次时钟中断的时间
+ void timerinit():初始化时钟中断
+ void timer_tick():触发时钟中断的时候进入这里,这里也会设置下一次时钟中断
+ 神奇的 bugset_next_timeout 中的 printf("");
---
## **S 态外部中断**
以下参考吴一凡学长的文档,如有雷同,纯属照搬。
为什么需要移植 S 态外部中断?
+ **RustSBI 运行在 M 态OS 内核运行在 S 态**
+ **想要使用 S 态众多的数据结构来对外部中断进行处理**
移植 S 态外部中断遇到的问题:`k210` 上没有 S 态外部中断!
怎么办?
**求助 RustSBI**
---
## **S 态外部中断**
**RustSBI 使用黑科技解决 K210 上 S 态外部中断**
感谢吴一凡学长移植 `rCore``k210` 上的文档和洛佳同学的解惑。
不敢班门弄斧,只说一下步骤:
+ `RustSBI` 提供一个接口
```Rust
match cause {
Trap::Exception(Exception::SupervisorEnvCall) => {
if trap_frame.a7 == 0x0A000004 && trap_frame.a6 == 0x210 {
// We use implementation specific sbi_rustsbi_k210_sext function (extension
// id: 0x0A000004, function id: 0x210) to register S-level interrupt handler
// for K210 chip only. This chip uses 1.9.1 version of privileged spec,
// which did not declare any S-level external interrupts.
...
} else {
...
}}}
```
+ S 态外部中断处理函数 `supervisor_external_handler`
+ 将这个函数指针作为参数调用 `RustSBI` 提供的接口
+ 外部中断将会在 `supervisor_external_handler` 中处理
---
## **用户多进程**
+ `proc.c` & `trap.c` & `trampoline.S` & `swtch.S`
+ 内核维护一个进程队列
+ 每个进程拥有独立的页表和独立的用户态空间
+ 在 scheduler() 进行进程调度
+ 通过 swtch(struct context*, struct context*) 进行上下文切换
+ 每次时钟中断内核会调用 yield() 函数,这个函数里面调用 swtch 进行进程切换
+ 双核跑多进程
+ 目前的用户进程是写死在内核里面的,后面文件系统移植好了才能真正意义上跑用户进程
+ 移植文档: https://github.com/SKTT1Ryze/xv6-k210/wiki/Process-Management
---
## **用户多进程**
![proc](../img/proc.jpg)
---
## **SD 卡驱动**
+ `sdcard.c`
+ 官方 SDK demo 实现了读取 sd 卡的例程
+ 暴力出奇迹,移植官方 SDK 到内核中
+ 问题:官方 SDK 编译链不同,代码太多,依赖关系复杂
+ 通过 SPI 协议与 SD 卡通信
+ 和很多外设打交道,比如 GPIOFPIO 等等,还需要调整时钟信号
+ 最终将官方 SDK 部分模块移植到了内核中,成功通过 SD 卡读取测试
+ SD 卡读写还不稳定
+ C 开发环境缺乏包管理工具
---
## **文件系统**
+ 由于 SD 卡读写不稳定的问题还没解决,还没完成
+ xv6 文件系统 or Fat32 文件系统 or 全都要
---
## **软硬协同调试**
+ 硬件调试非常非常麻烦,希望有软件调试环境
+ `Makefile` + 条件编译
+ `make run [platform=xxx]`
+ 类似于封装硬件抽象层
+ `RustSBI` 基本上处理了大部分平台无关性
+ 软件调试,一键部署
---
## **依赖于 RustSBI 的模块**
- [x] 多核启动
- [ ] 内存分配
- [x] 虚拟内存管理(`sfence.vma` 指令)
- [x] 时钟中断
- [x] S 态外部中断(其实有 bug 还没修)
- [ ] 用户多进程
- [x] SD 卡驱动
- [x] 文件系统
- [x] 平台无关性
---
## **中文文档**
+ 移植文档
+ `xv6-riscv` 原理文档
---
## **致谢**
+ 感谢比赛方和陈渝老师提供这次演讲机会,并且感谢邵志远老师一直以来对我的支持
+ `xv6-k210` 项目得到了很多同学的支持,特别是华科 18 级计卓班的刘一鸣和陆思彤同学,进程管理这部分的调试工作大部分是他们在做
+ 感谢 `RustSBI` 项目
+ 感谢 `rCore-Tutorial` 项目和今年暑假在鹏城实验室的`代码之夏`活动,让我踏入了 `Rust` 语言和体系结构的大门
+ 感谢洛佳同学和吴一凡学长技术上的帮助
---
## **谢谢各位**
华中科技大学
计算机科学与技术学院
校交 1801 班
车春池