Browse Source

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

LoGin 11 months ago
parent
commit
401699735b

+ 6 - 1
kernel/src/arch/riscv64/init/mod.rs

@@ -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!(" "));
-        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() {

+ 36 - 5
kernel/src/arch/riscv64/process/mod.rs

@@ -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) {

+ 10 - 5
kernel/src/arch/riscv64/smp/mod.rs

@@ -1,8 +1,11 @@
 use system_error::SystemError;
 
-use crate::smp::{
-    cpu::{CpuHpCpuState, ProcessorId},
-    SMPArch,
+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(())
     }
 }

+ 1 - 1
kernel/src/arch/riscv64/syscall/mod.rs

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

+ 5 - 18
kernel/src/arch/x86_64/process/mod.rs

@@ -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);
         // 正式切换上下文

+ 7 - 1
kernel/src/process/idle.rs

@@ -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进程数组的引用

+ 20 - 4
kernel/src/process/mod.rs

@@ -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()