Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

为 rCore-Tutorial 提供 K210 支持 #80

Open
wyfcyx opened this issue Jul 14, 2020 · 8 comments
Open

为 rCore-Tutorial 提供 K210 支持 #80

wyfcyx opened this issue Jul 14, 2020 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@wyfcyx
Copy link
Collaborator

wyfcyx commented Jul 14, 2020

之前基于教程第二版进行移植,截止到 lab1 可以在 K210 上运行。参考这里
经过上周例会上的协商,应重点在第三版上进行移植工作。于是我将第三版 fork 了一份,在上面一边学习一边进行移植工作(我会将学习与移植的过程持续更新在这里)。思路仍是和之前一样基于 rjgg 魔改过的 OpenSBI 0.3。
目前,lab0 已经可以在 K210 上运行,代码可以在这里找到。值得一提的是,我对整个开发流程进行了封装,目前只需在 os 目录下 make run-k210 即可一键完成构建、烧写以及进入终端与串口进行通信。有兴趣的同学可以帮我一起测试一下。
令人惊喜的是,目前使用的命令行串口终端 cu 支持多颜色字体输出。但还不知道它对输入的支持怎么样:事实上我们在用户程序之前都不必考虑这一点。
v3-lab0-k210
另外,@luojia65 正在用 Rust 自己实现一个 SBI,目前在 Qemu 上已经可以成功启动并在终端输出字符串。之后会考虑是否将现在使用 OpenSBI 换掉。

@wyfcyx wyfcyx added the enhancement New feature or request label Jul 14, 2020
@wyfcyx wyfcyx self-assigned this Jul 14, 2020
@luojia65
Copy link

在搞SBI实现了。设备树有点难搞,其它的好说。

@wyfcyx
Copy link
Collaborator Author

wyfcyx commented Jul 21, 2020

经历了无数坑爹的事情,目前终于做到了:

  1. 能在 S 态处理基本上所有的异常;
  2. 能在 S 态处理时钟中断并输出 100 ticks
  3. 能在 S 态收到软件中断并进行处理;
  4. 能将 M 态外部中断限制到在 hart0 上收到,但是由于 K210 上 S 态外部中断不存在,因此任何软硬件代理都无效,代理到 S 态软件中断并进行处理应该可行,且效果与之前基本相同。预计明天可以完成。
    具体探索历程请看这里

@SKTT1Ryze
Copy link

在 Maixpy Go 上试验,学长写的 lab0 确实能在 k210 板子上跑了。能正确处理时钟中断并输出 100 ticks

@am009
Copy link

am009 commented Jul 23, 2020

我虽然是初学者, 没真正接触过嵌入式开发, 但也想学习如何移植rcore-tutorial到k210板子上. 搜集了一个下午的相关资料, 想分享一下, 希望能帮到水平相近的人.
希望不会有错误的地方误导了别人.

k210实现了 RV64IMAFDC (RV64GC)这些拓展, 达到G对应的general purpose的目标成为标准通用的指令集架构, 原本还有 S U表示支持supervisor模式和user模式, 但由于RISC-V的特权指令集的1.11版本在2019年8月份才正式作为发布定下来, k210实现的只是1.9.1版本这个草案, 造成了尴尬的局面. 因为有不少地方不兼容, 有些指令都不同. 许多地方直接把它当作不支持S和U并且没有分页能力的芯片来用, 如Linux方面在k210上的相关移植的实现就是运行在machine模式, nommu(不使用分页). 但是实际上K210还是支持Sv39分页模式和Supervisor模式的.

RISC-V中通过misa寄存器表示实现了哪些拓展. K210的misa寄存器=0x800000000014112d, 这里面S对应的比特位确实是为1的. 如何检测分页模式的支持? 查找特权指令集的手册发现是, 当向satp寄存器的高位mod字段写入值的时候, 如果是不支持的分页模式, 整次写入无效, satp寄存器不改变.

相关的资料都很少, K210的datasheet中主要在说其他部分, 对CPU部分只有非常非常简单的介绍, 更没有提这些privilege的事情. 其他地方更是没有资料(因为我搜了很久都没有什么有价值的信息), 反而是我们rcore这边对这个芯片的CPU部分探索得更加深入. 其他许多地方都打算把k210作为不支持特权级的板子用. 甚至把device tree里cpu内的mmu-type字段设置为none.

相关链接:

The K210 has an sv39 MMU following the priviledge specification v1.9.
Since this is a non-ratified draft specification, the kernel does not
support it and the K210 support enabled only for the !MMU case.
Be consistent with this by setting the CPUs MMU type to "none".

来自: http://bxr.su/FreeBSD/sys/gnu/dts/riscv/kendryte/k210.dtsi

下面的链接是rcore-plus对k210支持相关的issue, 支持时稍微修改了opensbi.
oscourse-tsinghua/rcore_plus#34 (comment)

western digit的对linux machine mode nommu的ppt.
https://linuxplumbersconf.org/event/4/contributions/386/attachments/298/502/RISC-V-NOMMU-Linux-Plumbers-2019.pdf

这里似乎是的k210的memory map
https://github.com/laanwj/k210-sdk-stuff/blob/master/doc/memory_map.md

@wyfcyx
Copy link
Collaborator Author

wyfcyx commented Jul 23, 2020

关于这次移植的一点心得体会:

为何不直接用 M 态?

由于这会与基于 Qemu 的原本 rCore-Tutorial 在架构上出入太大,且需要扔掉在 OS 原理中非常重要的虚拟内存相关内容。当然,选择将内核放到 S 态运行就意味着网上能参考的资料非常少,甚至官方提供的手册都基本没有什么用,只能去啃官方 SDK 代码试图反推怎样才能更好跟硬件打交道。

移植现状?

情况还是比较乐观的,经过一通简单的魔改(修改 hart 上以及 PLIC 上的若干寄存器),验证 K210 对于 S 态的支持还算比较好,中断/异常都基本能很好的处理了。比较大的问题是猜测 S 态外部中断没有实现,因此只能通过 S 态软中断来处理它,需要注意区分是本来就是软中断来的,还是从外部中断转发过来的;还有就是高速串口一旦基于中断而不是轮询访问就会出现诡异的输出,这个也能通过换成通用串口来解决。页表和用户态的话,由于 rjgg 之前搞过(Rust 版本问题难以复现了),应该还是比较容易成功的。

移植有何意义?

整体上,移植的成功能让不仅仅满足于软件模拟的同学以一个比较低廉的价格在真实硬件上验证他的实现,并在这个过程中更加形象的认识体系结构,也会让整个教程更加令人信服。而对我个人而言,虽然踩坑的的过程无比痛苦,但是收获是巨大的:我看到了硬件、软件甚至编译器无论是谁都可能偷偷捣乱,让输出结果一塌糊涂;同时我也对 RISC-V 架构有了更深刻的理解。

下一步计划

在程序基本能跑通后,准备和 @luojia65 为 K210 单独定制一套基于 SBI 子集的 M 态软件,替换掉已经被涂抹的面目全非的原 OpenSBI。大家有兴趣也可以一同参与。

@wyfcyx
Copy link
Collaborator Author

wyfcyx commented Jul 31, 2020

之前通过实现发现将 M 态外部中断代理到 S 态软中断进行处理是可行的,然而高速串口基于中断的输入有问题,总是会莫名其妙向后偏移 7 次输入。注意到能够找到的所有串口中断输入的程序都使用通用串口,猜测可能高速串口对于中断的处理有问题,试图将串口的使用从 K210 上的高速串口换成通用串口。

最近几天有一半时间都不能干活,简单将 K210 官方 SDK 中的相关代码直接放到 OpenSBI 中完成了串口替换,轮询输入仍没有问题,但是中断的时候读到的寄存器的值还是有问题。后来发现不能在输入中断处理过程中向串口中输出,会影响到相关状态寄存器的值。删掉相关代码之后终于能通过中断正确输入一个字符,然而后续中断无法触发,原因不明。而且整个项目已经被我搞的非常混乱,给调试带来很大困难。按照之前的计划,只能先放弃处理串口中断基于轮询进行输入。这个就等 tutorial 跑起来之后再考虑。

一些相关资源

  • 基于 K210 官方 SDK 能够工作在 M 态的通用串口中断小程序
    // 注意在 entry_user.c 中进行了 UART3 的大部分初始化工作
    #include <stdio.h>
    #include "bsp.h"
    #include "clint.h"
    #include "uarths.h"
    #include "plic.h"
    #include "sysctl.h"
    #include "uart.h"
    #include "fpioa.h"
    
    #define UART_NUM UART_DEVICE_3
    
    
    void on_uart_recv(void* ctx) {
        char c;
        uart_receive_data(UART_NUM, &c, 1);
        uart_send_data(UART_NUM, &c, 1);
    }
    
    int main() {
      uart_irq_register(UART_NUM, UART_RECEIVE, on_uart_recv, NULL, 2);
      char *hel = {"hello world!\r\n"};
      uart_send_data(UART_NUM, hel, strlen(hel));
      while (1);
    }
  • 一个也许能工作的串口中断输入库:buffered-uart,然而我不知道怎么把它跑起来,因此尚不知道能否工作。

进一步计划

之后先想办法把 buffered-uart 跑通看看能不能正常工作,如果可以的话基于它重新实现一套 SBI,否则就基于官方 SDK 实现 SBI。

@wyfcyx
Copy link
Collaborator Author

wyfcyx commented Aug 4, 2020

搞完 lab2 之后重新整理了一下代码,发现高速串口中断在 M 态可以正常处理了!
然后继续尝试软件代理到 ssoft,在 M 态中断处理中使用了 sbi_putc(0) 黑科技才能收到 S 态软中断,现在做的比较粗糙,直接用 stval 保存收到的字符,这样有其他外部中断的话就不支持了,之后会尝试在 OpenSBI 里面搞一块缓冲区保存读到的字符,S 态就直接从里面读。但不管怎样,它终于正常工作了!
其实一定要弄到 S 态处理的理由是中断处理需要修改处于 S 态的内核的数据结构,如果在 M 态处理的话,由于 M 态只能看到物理地址,就得手动查页表。但即使如此,我也觉得把外部中断弄到 M 态处理相比现下的强行代理要好上许多:不仅更加自然,潜在的 bug 更少,将代码写在内核直接利用里面的模块也不会很复杂。至于时钟中断和异常处理,它们在 S 态的支持比较好,可以原封不动。
这样总归有些奇怪,但这是我目前想到的比较优雅的解决方案。
能正常跑的串口中断代码

@yxd0379
Copy link

yxd0379 commented Mar 3, 2022

我虽然是初学者, 没真正接触过嵌入式开发, 但也想学习如何移植rcore-tutorial到k210板子上. 搜集了一个下午的相关资料, 想分享一下, 希望能帮到水平相近的人. 希望不会有错误的地方误导了别人.

k210实现了 RV64IMAFDC (RV64GC)这些拓展, 达到G对应的general purpose的目标成为标准通用的指令集架构, 原本还有 S U表示支持supervisor模式和user模式, 但由于RISC-V的特权指令集的1.11版本在2019年8月份才正式作为发布定下来, k210实现的只是1.9.1版本这个草案, 造成了尴尬的局面. 因为有不少地方不兼容, 有些指令都不同. 许多地方直接把它当作不支持S和U并且没有分页能力的芯片来用, 如Linux方面在k210上的相关移植的实现就是运行在machine模式, nommu(不使用分页). 但是实际上K210还是支持Sv39分页模式和Supervisor模式的.

RISC-V中通过misa寄存器表示实现了哪些拓展. K210的misa寄存器=0x800000000014112d, 这里面S对应的比特位确实是为1的. 如何检测分页模式的支持? 查找特权指令集的手册发现是, 当向satp寄存器的高位mod字段写入值的时候, 如果是不支持的分页模式, 整次写入无效, satp寄存器不改变.

相关的资料都很少, K210的datasheet中主要在说其他部分, 对CPU部分只有非常非常简单的介绍, 更没有提这些privilege的事情. 其他地方更是没有资料(因为我搜了很久都没有什么有价值的信息), 反而是我们rcore这边对这个芯片的CPU部分探索得更加深入. 其他许多地方都打算把k210作为不支持特权级的板子用. 甚至把device tree里cpu内的mmu-type字段设置为none.

相关链接:

The K210 has an sv39 MMU following the priviledge specification v1.9.
Since this is a non-ratified draft specification, the kernel does not
support it and the K210 support enabled only for the !MMU case.
Be consistent with this by setting the CPUs MMU type to "none".

来自: http://bxr.su/FreeBSD/sys/gnu/dts/riscv/kendryte/k210.dtsi

下面的链接是rcore-plus对k210支持相关的issue, 支持时稍微修改了opensbi. oscourse-tsinghua/rcore_plus#34 (comment)

western digit的对linux machine mode nommu的ppt. https://linuxplumbersconf.org/event/4/contributions/386/attachments/298/502/RISC-V-NOMMU-Linux-Plumbers-2019.pdf

这里似乎是的k210的memory map https://github.com/laanwj/k210-sdk-stuff/blob/master/doc/memory_map.md

k210的core看起来是Rocket core

https://canaan-creative.com/716.html

https://www.hexiaoqing.net/wp-content/uploads/2016/05/AIoT%E6%8A%80%E6%9C%AF%E6%8C%91%E6%88%98%E4%B8%8ERISC-V-%E5%A4%84%E7%90%86%E5%99%A8%E6%9C%BA%E9%81%87-202007.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants