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);
node.properties().for_each(|p| {
(0..n_spaces + 4).for_each(|_| print!(" "));
if p.name == "compatible" {
println!("{}: {:?}", p.name, p.as_str());
} else {
println!("{}: {:?}", p.name, p.value);
}
});
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 crate::process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager};
use crate::{
kerror,
mm::VirtAddr,
process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
};
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 {
pub fn arch_init() {
unimplemented!("ProcessManager::arch_init")
// do nothing
}
/// fork的过程中复制线程
@ -50,6 +60,7 @@ impl ProcessManager {
/// - `prev`上一个进程的pcb
/// - `next`下一个进程的pcb
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")
}
}
@ -57,7 +68,27 @@ impl ProcessManager {
impl ProcessControlBlock {
/// 获取当前进程的pcb
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
pub fn new(kstack: &KernelStack) -> Self {
unimplemented!("ArchPCBInfo::new")
Self {}
}
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
pub fn clone_from(&mut self, from: &Self) {

View File

@ -1,8 +1,11 @@
use system_error::SystemError;
use crate::smp::{
use crate::{
kwarn,
smp::{
cpu::{CpuHpCpuState, ProcessorId},
SMPArch,
},
};
pub struct RiscV64SMPArch;
@ -10,10 +13,12 @@ pub struct RiscV64SMPArch;
impl SMPArch for RiscV64SMPArch {
#[inline(never)]
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> {
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> {
unimplemented!("arch_syscall_init")
return Ok(());
}
#[no_mangle]

View File

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

View File

@ -74,7 +74,13 @@ impl ProcessManager {
return VirtAddr::new(x86::current::registers::rsp() as usize);
#[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进程数组的引用

View File

@ -41,7 +41,12 @@ use crate::{
spinlock::{SpinLock, SpinLockGuard},
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,
sched::{
completion::Completion,
@ -73,7 +78,7 @@ pub mod utils;
/// 系统中所有进程的pcb
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次的全局变量标志进程管理器是否已经初始化完成
static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false;
@ -118,6 +123,7 @@ impl ProcessManager {
};
ALL_PROCESS.lock_irqsave().replace(HashMap::new());
Self::init_switch_result();
Self::arch_init();
kdebug!("process arch init done.");
Self::init_idle();
@ -127,6 +133,16 @@ impl ProcessManager {
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 {
unsafe { __PROCESS_MANAGEMENT_INIT_DONE }
@ -399,14 +415,14 @@ impl ProcessManager {
/// 上下文切换完成后的钩子函数
unsafe fn switch_finish_hook() {
// kdebug!("switch_finish_hook");
let prev_pcb = SWITCH_RESULT
let prev_pcb = PROCESS_SWITCH_RESULT
.as_mut()
.unwrap()
.get_mut()
.prev_pcb
.take()
.expect("prev_pcb is None");
let next_pcb = SWITCH_RESULT
let next_pcb = PROCESS_SWITCH_RESULT
.as_mut()
.unwrap()
.get_mut()