add shared segment mapping

This commit is contained in:
SKTT1Ryze 2021-04-09 17:45:53 +08:00
parent 12cc048eab
commit 82f24c4d78
9 changed files with 115 additions and 21 deletions

View File

@ -92,6 +92,8 @@ pub extern "C" fn rust_main(hart_id: usize) -> ! {
println!("_user_to_supervisor: {:#x}", _user_to_supervisor as usize);
println!("_supervisor_to_user: {:#x}", _supervisor_to_user as usize);
println!("_user_data: {:#x}", _user_data as usize);
println!("shared_add_task: {:#x}", task::shared_add_task as usize);
println!("shared_pop_task: {:#x}", task::shared_pop_task as usize);
// let executor = task::Executor::default();
@ -110,21 +112,21 @@ pub extern "C" fn rust_main(hart_id: usize) -> ! {
// todo: 这里要有个地方往tp里写东西目前会出错
let kernel_memory = memory::MemorySet::new_kernel().expect("create kernel memory set");
kernel_memory.activate();
let shared_scheduler = task::shared_scheduler();
println!("Shared scheduler: {:?}", shared_scheduler);
let process = task::Process::new(kernel_memory).expect("create process 1");
let stack_handle = process.alloc_stack().expect("alloc initial stack");
let task_1 = task::KernelTask::new(task_1(), process.clone());
println!("task_1: {:?}", task_1);
unsafe {
task::shared_add_task(shared_scheduler, task_1.shared_task_handle());
let _pop_task = task::shared_pop_task(shared_scheduler);
}
// 尝试进入用户态
user::try_enter_user(stack_handle.end.0 - 4)
// let task_1 = task::KernelTask::new(task_1(), process.clone());
// let task_2 = task::KernelTask::new(task_2(), process.clone());
// let task_3 = task::KernelTask::new(FibonacciFuture::new(5), process);
// println!("task_1: {:?}", task_1);
// println!("task_2: {:?}", task_2);
// println!("task_3: {:?}", task_3);
// let shared_scheduler = task::shared_scheduler();
// println!("Shared scheduler: {:?}", shared_scheduler);
// let user_1_memory = memory::MemorySet::new_user().expect("create user 1 memory set");
// let process_2 = task::Process::new(user_1_memory).expect("create process 2");
// let task_4 = task::user_task::UserTask::new(user_task_1(), process_2);

View File

@ -31,4 +31,11 @@ pub const SWAP_CONTEXT_VA: usize = SWAP_FRAME_VA - PAGE_SIZE;
/// 用户态栈的虚拟地址
/// 放在切换时保存的上下文下面
/// todo: 这个后面要移除
pub const USER_STACK_BOTTOM_VA: usize = SWAP_CONTEXT_VA - PAGE_SIZE;
/// 共享数据段在用户态中的虚拟地址
pub const USER_SHARED_DATA_VA: usize = 0xffff_ffff_ffff_0000;
/// 共享代码段在用户态中的虚拟地址
pub const USER_SHARED_TEXT_VA: usize = 0xffff_ffff_fffe_0000;

View File

@ -1,5 +1,28 @@
use crate::memory::{KERNEL_MAP_OFFSET, PhysicalPageNumber, SWAP_CONTEXT_VA, config::{FREE_MEMORY_START, MEMORY_END_ADDRESS, PAGE_SIZE, SWAP_FRAME_VA, USER_STACK_BOTTOM_VA}};
use crate::memory::{Mapping, MapType, Segment, Flags, VirtualAddress, VirtualPageNumber, PhysicalAddress, FrameTracker, AddressSpaceId};
use crate::memory::{
KERNEL_MAP_OFFSET,
PhysicalPageNumber,
SWAP_CONTEXT_VA,
config::{
FREE_MEMORY_START,
MEMORY_END_ADDRESS,
PAGE_SIZE,
SWAP_FRAME_VA,
USER_STACK_BOTTOM_VA,
USER_SHARED_DATA_VA,
USER_SHARED_TEXT_VA
}
};
use crate::memory::{
Mapping,
MapType,
Segment,
Flags,
VirtualAddress,
VirtualPageNumber,
PhysicalAddress,
FrameTracker,
AddressSpaceId
};
use alloc::vec::Vec;
use core::ops::Range;
@ -231,6 +254,10 @@ impl MemorySet {
pub fn new_bin() -> Option<MemorySet> {
extern "C" {
fn _swap_frame();
fn _sshared_data();
fn _eshared_data();
fn _sshared_text();
fn _eshared_text();
}
let mut mapping = Mapping::new_alloc()?;
let allocated_pairs = Vec::new();
@ -253,6 +280,21 @@ impl MemorySet {
range: swap_cx_va..swap_cx_va + PAGE_SIZE,
flags: Flags::READABLE | Flags::WRITABLE,
}, None)?;
// 映射共享数据段
let shared_data_len = _eshared_data as usize - _sshared_data as usize;
let va_range = VirtualAddress(USER_SHARED_DATA_VA)..VirtualAddress(USER_SHARED_DATA_VA + shared_data_len);
let pa_range =
VirtualAddress(_sshared_data as usize).physical_address_linear()..VirtualAddress(_eshared_data as usize).physical_address_linear();
mapping.map_defined(&va_range, &pa_range, Flags::READABLE | Flags::WRITABLE | Flags::USER);
// 映射共享代码段
let shared_text_len = _eshared_text as usize - _sshared_text as usize;
let va_range = VirtualAddress(USER_SHARED_TEXT_VA)..VirtualAddress(USER_SHARED_TEXT_VA + shared_text_len);
let pa_range =
VirtualAddress(_sshared_text as usize).physical_address_linear()..VirtualAddress(_eshared_text as usize).physical_address_linear();
mapping.map_defined(&va_range, &pa_range, Flags::READABLE | Flags::WRITABLE | Flags::EXECUTABLE | Flags::USER);
let address_space_id = crate::hart::KernelHartInfo::alloc_address_space_id()?; // todo: 释放asid
println!("New asid = {:?}", address_space_id);
Some(MemorySet { mapping, segments: Vec::new(), allocated_pairs, address_space_id })

View File

@ -90,6 +90,7 @@ pub static SHARED_RAW_TABLE: (unsafe fn(NonNull<()>, SharedTaskHandle) -> Option
///
/// 在内核态和用户态都可以调用访问的是shared_scheduler对应的同一块内存
#[link_section = ".shared_text"]
#[no_mangle]
pub unsafe fn shared_add_task(shared_scheduler: NonNull<()>, handle: SharedTaskHandle) -> Option<SharedTaskHandle> {
let s: NonNull<SharedScheduler> = shared_scheduler.cast();
// println!("Add task: scheduler = {:?}, handle = {:x?}", s, handle);
@ -101,6 +102,7 @@ pub unsafe fn shared_add_task(shared_scheduler: NonNull<()>, handle: SharedTaskH
///
/// 在内核态和用户态都可以调用访问的是shared_scheduler对应的同一块内存
#[link_section = ".shared_text"]
#[no_mangle]
pub unsafe fn shared_pop_task(shared_scheduler: NonNull<()>) -> TaskResult {
// 得到共享调度器的引用
let mut s: NonNull<SharedScheduler> = shared_scheduler.cast();

View File

@ -20,7 +20,7 @@ macro_rules! define_load_store {
mod handler;
mod timer;
pub use handler::TrapFrame;
pub use handler::{TrapFrame, trap_vector};
/// 初始化中断相关的子模块
///
@ -103,6 +103,10 @@ impl SwapContext {
self.x[1] = sp;
self
}
pub fn set_gp(&mut self, gp: usize) -> &mut Self {
self.x[2] = gp;
self
}
}
// 该函数的指针在从内核态返回到用户态之前被写到 stvec 寄存器里面去
@ -113,7 +117,7 @@ impl SwapContext {
#[export_name = "_user_to_supervisor"]
pub unsafe extern "C" fn user_to_supervisor() -> ! {
asm!(
".p2align 2",
// 交换 a0 和 sscratch原先保存着交换栈的栈顶指针
"csrrw a0, sscratch, a0",
@ -249,11 +253,12 @@ pub fn switch_to_user(context: &SwapContext, user_satp: usize) -> ! {
// 用户态发生中断时 pc 将会被设置成此值
let user_trap_va = SWAP_FRAME_VA as usize;
// 该函数最后应该跳转的虚拟地址
let jmp_va = supervisor_to_user as usize - _swap_frame as usize + SWAP_FRAME_VA;
let jmp_va = _supervisor_to_user as usize - _swap_frame as usize + SWAP_FRAME_VA;
// println!("jmp_va = {:#x}", jmp_va);
// 设置用户态陷入内核时需要跳转的地址
unsafe { stvec::write(user_trap_va, TrapMode::Direct); }
// 将 trap::handler 中的 trap_vector 以 Vectored 模式写入到 stvec 寄存器
// 设置 sstatus.SPP 的值为 User
unsafe { sstatus::set_spp(SPP::User); }

View File

@ -13,6 +13,10 @@ pub fn try_enter_user(kernel_stack_top: usize) -> ! {
fn _test_user_trap();
// 用户程序入口点
fn _test_user_entry();
fn _sshared_data();
fn _eshared_data();
fn _sshared_text();
fn _eshared_text();
}
// println!("_test_user_trap: {:#x}, _test_user_entry: {:#x}", _test_user_trap as usize, _test_user_entry as usize);
@ -55,7 +59,11 @@ pub fn try_enter_user(kernel_stack_top: usize) -> ! {
// 往 SwapContext 写东西
// _test_user_entry 由虚拟地址 0 映射到真实物理地址
*swap_cx = trap::SwapContext::new_to_user(
kernel_satp, 0, 0, kernel_stack_top, user_stack_top, _test_user_trap as usize);
kernel_satp, 0, 0, kernel_stack_top, user_stack_top, _test_user_trap as usize
);
// 在这里把 .shared_text 段在用户态的虚拟地址通过 gp 寄存器传过去
swap_cx.set_gp(memory::USER_SHARED_TEXT_VA);
// println!("swap_cx.epc: {:#x}", swap_cx.epc);
// println!("swap_cx.trap_handler: {:#x}", swap_cx.user_trap_handler);
trap::switch_to_user(swap_cx, user_satp)
@ -67,7 +75,7 @@ pub extern "C" fn test_user_trap() {
match scause::read().cause() {
Trap::Interrupt(Interrupt::SupervisorTimer) => {
println!("s mode timer!");
// 目前遇到时钟中断先让系统退出,等把内核进程队列完善好了再来处理
// 目前遇到时钟中断先让系统退出,等把内核完善好了再来处理
crate::sbi::shutdown();
},
Trap::Exception(scause::Exception::Breakpoint) => {
@ -75,7 +83,8 @@ pub extern "C" fn test_user_trap() {
crate::sbi::shutdown();
},
Trap::Exception(scause::Exception::UserEnvCall) => {
println!("user mode exit.");
println!("ecall from user.");
// 这里先返回到用户态
crate::sbi::shutdown();
}
_ => todo!("scause: {:?}, sepc: {:#x}, stval: {:#x}", scause::read().cause(), sepc::read(), stval::read())

View File

@ -1,3 +0,0 @@
fn main() {
println!("Hello world!");
}

View File

@ -1,6 +1,7 @@
#![no_std]
#![no_main]
#![feature(llvm_asm)]
#![feature(asm)]
#![feature(panic_info_message)]
#![feature(alloc_error_handler)]
extern crate alloc;
@ -38,6 +39,11 @@ pub fn handle_alloc_error(_layout: core::alloc::Layout) -> ! {
#[link_section = ".text.entry"]
#[export_name = "_start"]
fn main() -> ! {
unsafe {
asm!(
"lw t0, (gp)"
);
}
unsafe {
HEAP.lock().init(HEAP_SPACE.as_ptr() as usize, USER_HEAP_SIZE);
}

View File

@ -0,0 +1,24 @@
// 尝试在用户态给共享调度器添加任务
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct SharedTaskHandle {
/// 处理核编号
pub(crate) hart_id: usize,
/// 地址空间编号
pub(crate) address_space_id: AddressSpaceId,
/// task_ptr 是 Arc<Task> 的虚拟地址
pub(crate) task_ptr: usize,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct AddressSpaceId(u16);
impl AddressSpaceId {
pub(crate) unsafe fn from_raw(asid: usize) -> AddressSpaceId {
AddressSpaceId(asid as u16)
}
pub(crate) fn into_inner(self) -> usize {
self.0 as usize
}
}