riscv: 进程管理初始化 (#654)

This commit is contained in:
LoGin 2024-03-23 16:25:56 +08:00 committed by GitHub
parent 6046f77591
commit 401699735b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 85 additions and 35 deletions

View File

@ -71,7 +71,12 @@ fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
println!("{}/", node.name); println!("{}/", node.name);
node.properties().for_each(|p| { node.properties().for_each(|p| {
(0..n_spaces + 4).for_each(|_| print!(" ")); (0..n_spaces + 4).for_each(|_| print!(" "));
println!("{}: {:?}", p.name, p.value);
if p.name == "compatible" {
println!("{}: {:?}", p.name, p.as_str());
} else {
println!("{}: {:?}", p.name, p.value);
}
}); });
for child in node.children() { for child in node.children() {

View File

@ -1,7 +1,17 @@
use alloc::{string::String, sync::Arc, vec::Vec}; use core::{arch::asm, mem::ManuallyDrop};
use alloc::{
string::String,
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError; use system_error::SystemError;
use crate::process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager}; use crate::{
kerror,
mm::VirtAddr,
process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
};
use super::interrupt::TrapFrame; use super::interrupt::TrapFrame;
@ -28,7 +38,7 @@ pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<Str
impl ProcessManager { impl ProcessManager {
pub fn arch_init() { pub fn arch_init() {
unimplemented!("ProcessManager::arch_init") // do nothing
} }
/// fork的过程中复制线程 /// fork的过程中复制线程
@ -50,6 +60,7 @@ impl ProcessManager {
/// - `prev`上一个进程的pcb /// - `prev`上一个进程的pcb
/// - `next`下一个进程的pcb /// - `next`下一个进程的pcb
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) { pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
// todo: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/include/asm/switch_to.h#76
unimplemented!("ProcessManager::switch_process") unimplemented!("ProcessManager::switch_process")
} }
} }
@ -57,7 +68,27 @@ impl ProcessManager {
impl ProcessControlBlock { impl ProcessControlBlock {
/// 获取当前进程的pcb /// 获取当前进程的pcb
pub fn arch_current_pcb() -> Arc<Self> { pub fn arch_current_pcb() -> Arc<Self> {
unimplemented!("ProcessControlBlock::arch_current_pcb") // 获取栈指针
let mut sp: usize;
unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) };
let ptr = VirtAddr::new(sp);
let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1)));
// 从内核栈的最低地址处取出pcb的地址
let p = stack_base.data() as *const *const ProcessControlBlock;
if core::intrinsics::unlikely((unsafe { *p }).is_null()) {
kerror!("p={:p}", p);
panic!("current_pcb is null");
}
unsafe {
// 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下
let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> =
ManuallyDrop::new(Weak::from_raw(*p));
let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap();
return new_arc;
}
} }
} }
@ -80,7 +111,7 @@ impl ArchPCBInfo {
/// ///
/// 返回一个新的ArchPCBInfo /// 返回一个新的ArchPCBInfo
pub fn new(kstack: &KernelStack) -> Self { pub fn new(kstack: &KernelStack) -> Self {
unimplemented!("ArchPCBInfo::new") Self {}
} }
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变 // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
pub fn clone_from(&mut self, from: &Self) { pub fn clone_from(&mut self, from: &Self) {

View File

@ -1,8 +1,11 @@
use system_error::SystemError; use system_error::SystemError;
use crate::smp::{ use crate::{
cpu::{CpuHpCpuState, ProcessorId}, kwarn,
SMPArch, smp::{
cpu::{CpuHpCpuState, ProcessorId},
SMPArch,
},
}; };
pub struct RiscV64SMPArch; pub struct RiscV64SMPArch;
@ -10,10 +13,12 @@ pub struct RiscV64SMPArch;
impl SMPArch for RiscV64SMPArch { impl SMPArch for RiscV64SMPArch {
#[inline(never)] #[inline(never)]
fn prepare_cpus() -> Result<(), SystemError> { fn prepare_cpus() -> Result<(), SystemError> {
todo!() kwarn!("RiscV64SMPArch::prepare_cpus() is not implemented");
Ok(())
} }
fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError> { fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError> {
todo!() kwarn!("RiscV64SMPArch::start_cpu() is not implemented");
Ok(())
} }
} }

View File

@ -8,7 +8,7 @@ use super::{interrupt::TrapFrame, CurrentIrqArch};
/// 系统调用初始化 /// 系统调用初始化
pub fn arch_syscall_init() -> Result<(), SystemError> { pub fn arch_syscall_init() -> Result<(), SystemError> {
unimplemented!("arch_syscall_init") return Ok(());
} }
#[no_mangle] #[no_mangle]

View File

@ -20,14 +20,10 @@ use crate::{
exception::InterruptArch, exception::InterruptArch,
kerror, kwarn, kerror, kwarn,
libs::spinlock::SpinLockGuard, libs::spinlock::SpinLockGuard,
mm::{ mm::VirtAddr,
percpu::{PerCpu, PerCpuVar},
VirtAddr,
},
process::{ process::{
fork::{CloneFlags, KernelCloneArgs}, fork::{CloneFlags, KernelCloneArgs},
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, SwitchResult, KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
SWITCH_RESULT,
}, },
syscall::Syscall, syscall::Syscall,
}; };
@ -299,16 +295,7 @@ impl ProcessControlBlock {
impl ProcessManager { impl ProcessManager {
pub fn arch_init() { pub fn arch_init() {
{ // do nothing
// 初始化进程切换结果 per cpu变量
let mut switch_res_vec: Vec<SwitchResult> = Vec::new();
for _ in 0..PerCpu::MAX_CPU_NUM {
switch_res_vec.push(SwitchResult::new());
}
unsafe {
SWITCH_RESULT = Some(PerCpuVar::new(switch_res_vec).unwrap());
}
}
} }
/// fork的过程中复制线程 /// fork的过程中复制线程
/// ///
@ -421,8 +408,8 @@ impl ProcessManager {
x86::Ring::Ring0, x86::Ring::Ring0,
next.kernel_stack().stack_max_address().data() as u64, next.kernel_stack().stack_max_address().data() as u64,
); );
SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev); PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev);
SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next); PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next);
// kdebug!("switch tss ok"); // kdebug!("switch tss ok");
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
// 正式切换上下文 // 正式切换上下文

View File

@ -74,7 +74,13 @@ impl ProcessManager {
return VirtAddr::new(x86::current::registers::rsp() as usize); return VirtAddr::new(x86::current::registers::rsp() as usize);
#[cfg(target_arch = "riscv64")] #[cfg(target_arch = "riscv64")]
unimplemented!("stack_ptr() is not implemented on RISC-V") {
let stack_ptr: usize;
unsafe {
core::arch::asm!("mv {}, sp", out(reg) stack_ptr);
}
return VirtAddr::new(stack_ptr);
}
} }
/// 获取idle进程数组的引用 /// 获取idle进程数组的引用

View File

@ -41,7 +41,12 @@ use crate::{
spinlock::{SpinLock, SpinLockGuard}, spinlock::{SpinLock, SpinLockGuard},
wait_queue::WaitQueue, wait_queue::WaitQueue,
}, },
mm::{percpu::PerCpuVar, set_IDLE_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr}, mm::{
percpu::{PerCpu, PerCpuVar},
set_IDLE_PROCESS_ADDRESS_SPACE,
ucontext::AddressSpace,
VirtAddr,
},
net::socket::SocketInode, net::socket::SocketInode,
sched::{ sched::{
completion::Completion, completion::Completion,
@ -73,7 +78,7 @@ pub mod utils;
/// 系统中所有进程的pcb /// 系统中所有进程的pcb
static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None); static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None);
pub static mut SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None; pub static mut PROCESS_SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None;
/// 一个只改变1次的全局变量标志进程管理器是否已经初始化完成 /// 一个只改变1次的全局变量标志进程管理器是否已经初始化完成
static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false; static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false;
@ -118,6 +123,7 @@ impl ProcessManager {
}; };
ALL_PROCESS.lock_irqsave().replace(HashMap::new()); ALL_PROCESS.lock_irqsave().replace(HashMap::new());
Self::init_switch_result();
Self::arch_init(); Self::arch_init();
kdebug!("process arch init done."); kdebug!("process arch init done.");
Self::init_idle(); Self::init_idle();
@ -127,6 +133,16 @@ impl ProcessManager {
kinfo!("Process Manager initialized."); kinfo!("Process Manager initialized.");
} }
fn init_switch_result() {
let mut switch_res_vec: Vec<SwitchResult> = Vec::new();
for _ in 0..PerCpu::MAX_CPU_NUM {
switch_res_vec.push(SwitchResult::new());
}
unsafe {
PROCESS_SWITCH_RESULT = Some(PerCpuVar::new(switch_res_vec).unwrap());
}
}
/// 判断进程管理器是否已经初始化完成 /// 判断进程管理器是否已经初始化完成
pub fn initialized() -> bool { pub fn initialized() -> bool {
unsafe { __PROCESS_MANAGEMENT_INIT_DONE } unsafe { __PROCESS_MANAGEMENT_INIT_DONE }
@ -399,14 +415,14 @@ impl ProcessManager {
/// 上下文切换完成后的钩子函数 /// 上下文切换完成后的钩子函数
unsafe fn switch_finish_hook() { unsafe fn switch_finish_hook() {
// kdebug!("switch_finish_hook"); // kdebug!("switch_finish_hook");
let prev_pcb = SWITCH_RESULT let prev_pcb = PROCESS_SWITCH_RESULT
.as_mut() .as_mut()
.unwrap() .unwrap()
.get_mut() .get_mut()
.prev_pcb .prev_pcb
.take() .take()
.expect("prev_pcb is None"); .expect("prev_pcb is None");
let next_pcb = SWITCH_RESULT let next_pcb = PROCESS_SWITCH_RESULT
.as_mut() .as_mut()
.unwrap() .unwrap()
.get_mut() .get_mut()