Tcore是我在暑假参与清华陈渝教授带领的summer school时和同来参与研修的东南大学李可然同学决定一起做的在一个基于Rcore衍生项目,终极目标是一起做出一个基于Riscv的Cpu并且开发一个可以移植到该Cpu上完整的操作系统,将操作系统继续钻研下去
13
stars
3
forks
source link
你好,我在以RocketChip为原型的K210芯片基础上重实现了Linux0.11,目前内核可以正常运行,想要和你们进行一些探讨和交流 #9
Open
lizhirui opened 4 years ago
我采用K210芯片中的其中一个Timer用于任务调度,其周期为10ms,每个任务都有独立的用户态堆栈和内核态堆栈,由于switch_to函数使用汇编语言编写并依赖于x86处理器的TSS机制,而RISC-V架构并不支持该机制,因此将该函数重构,手工备份了现场环境,并处理好了返回路径不一致问题(上下文切换可能来自Exception(即exception_environment_call_from_u_mode),也可能来自Interrupt(External Interrupt,由plic管理的Timer中断),对于Exception来说只需要按照正常路径返回即可,而Interrupt则需要去设置timer和plic相关的eoi标志,标记本次中断处理已完成,防止中断再次触发。放置了一个全局变量用来标识上下文切换来源,并且该标识不受上下文切换的影响而改变,因此通过它可以决定正确的返回中断路径(由一个叫做interupt_recover的函数在上下文切换后进行了处理))。
该芯片由于在启动后会自行将Flash中的程序加载到RAM的0x80000000处并从该地址处开始执行,因此不需要编写引导程序,镜像由内核镜像和文件系统拼接完成,后者拼接在前者的500KB边界处,大小为360KB,文件系统为Minix1.0版文件系统(最大文件长度14)。
我利用exception_instruction_access_fault、exception_load_access_fault以及exception_store_or_amo_address_fault通过调用memory.c中的do_no_page和do_wp_page函数实现了需求页加载和写时复制功能。
我规定了如下系统调用规范:通过a0、a1、a2分别传递第一、第二、第三参数,通过a7传递系统调用号,通过a0传递系统调用的返回值,通过ecall指令发起系统调用。
由于目前没有可以为RISC-V处理器编译出a.out可执行文件的编译器/链接器(Linux0.11仅支持该类型的可执行文件,且必须是ZMAGIC,不分段,同时不支持地址重定向),因此通过objcopy将elf转换为bin,并通过objdump对elf进行反汇编从而得到符号_start,并写了一个程序,读取_start的地址,构造a.out头部并将bin数据加入处理好数据对齐问题从而构成a.out格式的可执行文件。目前写了一个简易版的shell(由于当年的全套工具貌似已经丢失,网络上无法获得源代码),内部实现了一个简易版的ls命令(截图在下面)以及exit命令,同时将合成的bin文件放置在了 附件中,可以烧入K210芯片进行测试(串口波特率115200,建议使用putty作为终端工具,并选中”Terminal -> Keyboard”中的“The Control-?(127)”,这样退格功能可以正常运行,做了个延时启动(为了调试方便),所以上电复位几秒后串口才会有显示)。
在trap入口处负责堆栈的切换,若先前的特权级为User,则切换到Kernel Stack,否则不进行切换。