mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 14:16:47 +00:00
riscv: 进程管理初始化 (#654)
This commit is contained in:
parent
6046f77591
commit
401699735b
@ -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() {
|
||||
|
@ -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) {
|
||||
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use super::{interrupt::TrapFrame, CurrentIrqArch};
|
||||
|
||||
/// 系统调用初始化
|
||||
pub fn arch_syscall_init() -> Result<(), SystemError> {
|
||||
unimplemented!("arch_syscall_init")
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -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);
|
||||
// 正式切换上下文
|
||||
|
@ -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进程数组的引用
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user