Add some comment for paging and add proposal doc

master
lcy1996 6 years ago
parent cef2d792be
commit 96cdf37b15

@ -0,0 +1,39 @@
# Rust OS 教学lab实验的制作 方案设计文档
## 1 实验目标
* 补全部分Rust OS尚未实现的基础功能
* 从现有Rust OS中裁剪出一个子集用于教学lab
* 参考现有ucore OS实验设计Rust OS教学lab基于riscv32并完成相关测试代码的编写
* 完成教学实验说明文档并补充每一个lab所需的代码注释
* 尝试配置基于浏览器的虚拟机实验环境
## 2 背景
现有的操作系统大实验是基于ucore OS完成的总共由8个小实验完成包含了操作系统从启动到进入shell的全过程内容包括硬件启动异常处理内存管理进程管理同步互斥文件系统等操作系统基础知识点。[ucore OS lab](https://github.com/chyyuu/ucore_os_lab)已经具有十分完善的[教学文档](https://objectkuan.gitbooks.io/ucore-docs/content/index.html)。
ucoreOS lab基于x86结构主要由C语言完成编写。x86架构由于其向后兼容性等种种原因整体结构比较复杂作为教学操作系统门槛比较高。相比较而言riscv32架构简洁高效易于实现是教学用cpu结构的不二选择。此外C语言的安全性一直以来饱受诟病。相较C语言Rust语言更加简洁、安全模块性好可复用性强可以通过采用现有库文件更优雅的解决文件。**最重要的是王润基等同学已经参照ucore OS实现了一个比较完整的基于x86_64和riscv32的Rust OS**因此我们决定再次基础上进行完善并裁剪出一个基于riscv32的教学用RustOS lab。
## 3 实验设计与分工
### 3.1 完善现有Rust OS基础功能
现有Rust OS在riscv32环境下还存在一些bugs或unimplemented features要想完成一个类似于ucore OS lab的教学实验框架首先要把这些漏洞完善。现简单将每个lab目前待完善的地方和负责填坑的人列举如下
**lab1:**主要涉及实验框架的编译、调试OS bootloader启动过程。现有实验框架已经完成不需要完善。
**lab2:**主要涉及物理内存管理由于riscv32结构的物理内存管理仅通过一个二级页表来实现不像x86架构下还需要兼容段表(虽然最终只是一个自映射)因此这部分比原本的ucore OS lab会更简洁、易理解一些。另外RustOS 的现有物理内存分配算法是通过线段树实现的,且相较原本的内存分配算法复用性更好。本分内容已经完成。
**lab3:**该部分实验主要涉及虚存管理部分,**目前RUST OS仅针对x86_64结构实现了page fault的处理**后续需要完成riscv32的page fault处理和虚存管理部分。
**lab4:**主要涉及内核线程创建和调度,现有框架中本部分内容已经完成,是否存在问题有待后续测试。
**lab5:**主要涉及用户线程管理,此部分内容似乎同样已经完成,是否存在问题有待后续测试。**事实上之前测试中似乎又提到没有wait过的进程退出内存不会被回收有待完善。**
**lab6:**此部分主要涉及进程调度器的相关内容,现有框架中本部分内容已经完成,是否存在问题有待后续测试。
**lab7:**@陈秋昊
**lab8:**@朱书聪
其中前6个lab现有框架已经实现完成主要涉及虚存管理和进程管理的部分内容有待完善此部分计划由刘辰屹来完成。lab7在riscv32下的完善计划由陈秋昊来完成lab8的完善计划由朱书聪来完成。上述为暂时的分工实际分工视各部分难度大小再进行调整。
此部分计划在第5周结束前完成。
### 3.2 教学lab的裁剪和测试程序的编写
此部分内容计划在第6周结束前完成
### 3.3 教学lab文档编写
此部分内容计划在第7周结束前完成可能向后顺延至第8周
### 3.4 在浏览器中运行Rust OS lab
目前没有能够探索到实现此计划的可行性,待定。
## 4 参考文献
ucore OS lab实验指导书https://objectkuan.gitbooks.io/ucore-docs/content/index.html
王润基同学的Rust OS开发文档https://rucore.gitbook.io/rust-os-docs/

@ -67,6 +67,7 @@ pub unsafe fn restore(flags: usize) {
pub extern fn rust_trap(tf: &mut TrapFrame) { pub extern fn rust_trap(tf: &mut TrapFrame) {
use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E}; use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E};
trace!("Interrupt: {:?}", tf.scause.cause()); trace!("Interrupt: {:?}", tf.scause.cause());
// page should be processed here but not now
match tf.scause.cause() { match tf.scause.cause() {
Trap::Interrupt(I::SupervisorTimer) => timer(), Trap::Interrupt(I::SupervisorTimer) => timer(),
Trap::Exception(E::IllegalInstruction) => illegal_inst(tf), Trap::Exception(E::IllegalInstruction) => illegal_inst(tf),

@ -63,33 +63,71 @@ impl PageTable for ActivePageTable {
self.get_entry(addr) self.get_entry(addr)
} }
/*
* @param:
* addr: virtual address of which the mapped physical frame should be unmapped
* @bridf:
^ unmap the virtual addresses' mapped physical frame
*/
fn unmap(&mut self, addr: usize) { fn unmap(&mut self, addr: usize) {
let page = Page::of_addr(VirtAddr::new(addr)); let page = Page::of_addr(VirtAddr::new(addr));
let (frame, flush) = self.0.unmap(page).unwrap(); let (frame, flush) = self.0.unmap(page).unwrap();
flush.flush(); flush.flush();
} }
/*
* @param:
* addr:input virtual address
* @brief:
* get the pageEntry of 'addr'
* @retval:
* a mutable PageEntry reference of 'addr'
*/
fn get_entry(&mut self, addr: usize) -> &mut PageEntry { fn get_entry(&mut self, addr: usize) -> &mut PageEntry {
let page = Page::of_addr(VirtAddr::new(addr)); let page = Page::of_addr(VirtAddr::new(addr));
// ???
let _ = self.0.translate_page(page); let _ = self.0.translate_page(page);
let entry_addr = ((addr >> 10) & 0x003ffffc) | (RECURSIVE_PAGE_PML4 << 22); let entry_addr = ((addr >> 10) & 0x003ffffc) | (RECURSIVE_PAGE_PML4 << 22);
unsafe { &mut *(entry_addr as *mut PageEntry) } unsafe { &mut *(entry_addr as *mut PageEntry) }
} }
/*
* @param:
* addr:the input (virutal) address
* @brief:
* get the addr's memory page slice
* @retval:
* a mutable reference slice of 'addr' 's page
*/
fn get_page_slice_mut<'a, 'b>(&'a mut self, addr: usize) -> &'b mut [u8] { fn get_page_slice_mut<'a, 'b>(&'a mut self, addr: usize) -> &'b mut [u8] {
use core::slice; use core::slice;
unsafe { slice::from_raw_parts_mut((addr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) } unsafe { slice::from_raw_parts_mut((addr & !(PAGE_SIZE - 1)) as *mut u8, PAGE_SIZE) }
} }
/*
* @param:
* addr: virtual address
* @brief:
* get the address's content
* @retval:
* the content(u8) of 'addr'
*/
fn read(&mut self, addr: usize) -> u8 { fn read(&mut self, addr: usize) -> u8 {
unsafe { *(addr as *const u8) } unsafe { *(addr as *const u8) }
} }
/*
* @param:
* addr: virtual address
* @brief:
* write the address's content
*/
fn write(&mut self, addr: usize, data: u8) { fn write(&mut self, addr: usize, data: u8) {
unsafe { *(addr as *mut u8) = data; } unsafe { *(addr as *mut u8) = data; }
} }
} }
// define the ROOT_PAGE_TABLE, and the virtual address of it?
const ROOT_PAGE_TABLE: *mut RvPageTable = const ROOT_PAGE_TABLE: *mut RvPageTable =
(((RECURSIVE_PAGE_PML4 << 10) | (RECURSIVE_PAGE_PML4 + 1)) << 12) as *mut RvPageTable; (((RECURSIVE_PAGE_PML4 << 10) | (RECURSIVE_PAGE_PML4 + 1)) << 12) as *mut RvPageTable;

@ -15,8 +15,11 @@ mod riscv {
// [0x80000000, 0x80800000] // [0x80000000, 0x80800000]
const P2_SIZE: usize = 1 << 22; const P2_SIZE: usize = 1 << 22;
const P2_MASK: usize = 0x3ff << 22; const P2_MASK: usize = 0x3ff << 22;
// RECURSIVE_PAGE_PML4 indicate the index of the self-maping entry in root pagetable
pub const RECURSIVE_PAGE_PML4: usize = 0x3fe; pub const RECURSIVE_PAGE_PML4: usize = 0x3fe;
// KERNEL_OFFSET indicate (virtual kernel address - physical kernel address) ???
pub const KERNEL_OFFSET: usize = 0; pub const KERNEL_OFFSET: usize = 0;
// KERNEL_PML4 indicate the index of the kernel entry in root pagetable
pub const KERNEL_PML4: usize = 0x8000_0000 >> 22; pub const KERNEL_PML4: usize = 0x8000_0000 >> 22;
pub const KERNEL_HEAP_OFFSET: usize = 0x8020_0000; pub const KERNEL_HEAP_OFFSET: usize = 0x8020_0000;
pub const KERNEL_HEAP_SIZE: usize = 0x0020_0000; pub const KERNEL_HEAP_SIZE: usize = 0x0020_0000;

Loading…
Cancel
Save