Skip to content

Commit 4016997

Browse files
authored
riscv: 进程管理初始化 (#654)
1 parent 6046f77 commit 4016997

File tree

7 files changed

+85
-35
lines changed

7 files changed

+85
-35
lines changed

kernel/src/arch/riscv64/init/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
7171
println!("{}/", node.name);
7272
node.properties().for_each(|p| {
7373
(0..n_spaces + 4).for_each(|_| print!(" "));
74-
println!("{}: {:?}", p.name, p.value);
74+
75+
if p.name == "compatible" {
76+
println!("{}: {:?}", p.name, p.as_str());
77+
} else {
78+
println!("{}: {:?}", p.name, p.value);
79+
}
7580
});
7681

7782
for child in node.children() {

kernel/src/arch/riscv64/process/mod.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
use alloc::{string::String, sync::Arc, vec::Vec};
1+
use core::{arch::asm, mem::ManuallyDrop};
2+
3+
use alloc::{
4+
string::String,
5+
sync::{Arc, Weak},
6+
vec::Vec,
7+
};
28
use system_error::SystemError;
39

4-
use crate::process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager};
10+
use crate::{
11+
kerror,
12+
mm::VirtAddr,
13+
process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager},
14+
};
515

616
use super::interrupt::TrapFrame;
717

@@ -28,7 +38,7 @@ pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<Str
2838

2939
impl ProcessManager {
3040
pub fn arch_init() {
31-
unimplemented!("ProcessManager::arch_init")
41+
// do nothing
3242
}
3343

3444
/// fork的过程中复制线程
@@ -50,14 +60,35 @@ impl ProcessManager {
5060
/// - `prev`:上一个进程的pcb
5161
/// - `next`:下一个进程的pcb
5262
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
63+
// todo: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/include/asm/switch_to.h#76
5364
unimplemented!("ProcessManager::switch_process")
5465
}
5566
}
5667

5768
impl ProcessControlBlock {
5869
/// 获取当前进程的pcb
5970
pub fn arch_current_pcb() -> Arc<Self> {
60-
unimplemented!("ProcessControlBlock::arch_current_pcb")
71+
// 获取栈指针
72+
let mut sp: usize;
73+
unsafe { asm!("mv {}, sp", lateout(reg) sp, options(nostack)) };
74+
let ptr = VirtAddr::new(sp);
75+
76+
let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1)));
77+
78+
// 从内核栈的最低地址处取出pcb的地址
79+
let p = stack_base.data() as *const *const ProcessControlBlock;
80+
if core::intrinsics::unlikely((unsafe { *p }).is_null()) {
81+
kerror!("p={:p}", p);
82+
panic!("current_pcb is null");
83+
}
84+
unsafe {
85+
// 为了防止内核栈的pcb weak 指针被释放,这里需要将其包装一下
86+
let weak_wrapper: ManuallyDrop<Weak<ProcessControlBlock>> =
87+
ManuallyDrop::new(Weak::from_raw(*p));
88+
89+
let new_arc: Arc<ProcessControlBlock> = weak_wrapper.upgrade().unwrap();
90+
return new_arc;
91+
}
6192
}
6293
}
6394

@@ -80,7 +111,7 @@ impl ArchPCBInfo {
80111
///
81112
/// 返回一个新的ArchPCBInfo
82113
pub fn new(kstack: &KernelStack) -> Self {
83-
unimplemented!("ArchPCBInfo::new")
114+
Self {}
84115
}
85116
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
86117
pub fn clone_from(&mut self, from: &Self) {

kernel/src/arch/riscv64/smp/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
use system_error::SystemError;
22

3-
use crate::smp::{
4-
cpu::{CpuHpCpuState, ProcessorId},
5-
SMPArch,
3+
use crate::{
4+
kwarn,
5+
smp::{
6+
cpu::{CpuHpCpuState, ProcessorId},
7+
SMPArch,
8+
},
69
};
710

811
pub struct RiscV64SMPArch;
912

1013
impl SMPArch for RiscV64SMPArch {
1114
#[inline(never)]
1215
fn prepare_cpus() -> Result<(), SystemError> {
13-
todo!()
16+
kwarn!("RiscV64SMPArch::prepare_cpus() is not implemented");
17+
Ok(())
1418
}
1519

1620
fn start_cpu(cpu_id: ProcessorId, hp_state: &CpuHpCpuState) -> Result<(), SystemError> {
17-
todo!()
21+
kwarn!("RiscV64SMPArch::start_cpu() is not implemented");
22+
Ok(())
1823
}
1924
}

kernel/src/arch/riscv64/syscall/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use super::{interrupt::TrapFrame, CurrentIrqArch};
88

99
/// 系统调用初始化
1010
pub fn arch_syscall_init() -> Result<(), SystemError> {
11-
unimplemented!("arch_syscall_init")
11+
return Ok(());
1212
}
1313

1414
#[no_mangle]

kernel/src/arch/x86_64/process/mod.rs

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,10 @@ use crate::{
2020
exception::InterruptArch,
2121
kerror, kwarn,
2222
libs::spinlock::SpinLockGuard,
23-
mm::{
24-
percpu::{PerCpu, PerCpuVar},
25-
VirtAddr,
26-
},
23+
mm::VirtAddr,
2724
process::{
2825
fork::{CloneFlags, KernelCloneArgs},
29-
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, SwitchResult,
30-
SWITCH_RESULT,
26+
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
3127
},
3228
syscall::Syscall,
3329
};
@@ -299,16 +295,7 @@ impl ProcessControlBlock {
299295

300296
impl ProcessManager {
301297
pub fn arch_init() {
302-
{
303-
// 初始化进程切换结果 per cpu变量
304-
let mut switch_res_vec: Vec<SwitchResult> = Vec::new();
305-
for _ in 0..PerCpu::MAX_CPU_NUM {
306-
switch_res_vec.push(SwitchResult::new());
307-
}
308-
unsafe {
309-
SWITCH_RESULT = Some(PerCpuVar::new(switch_res_vec).unwrap());
310-
}
311-
}
298+
// do nothing
312299
}
313300
/// fork的过程中复制线程
314301
///
@@ -421,8 +408,8 @@ impl ProcessManager {
421408
x86::Ring::Ring0,
422409
next.kernel_stack().stack_max_address().data() as u64,
423410
);
424-
SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev);
425-
SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next);
411+
PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().prev_pcb = Some(prev);
412+
PROCESS_SWITCH_RESULT.as_mut().unwrap().get_mut().next_pcb = Some(next);
426413
// kdebug!("switch tss ok");
427414
compiler_fence(Ordering::SeqCst);
428415
// 正式切换上下文

kernel/src/process/idle.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,13 @@ impl ProcessManager {
7474
return VirtAddr::new(x86::current::registers::rsp() as usize);
7575

7676
#[cfg(target_arch = "riscv64")]
77-
unimplemented!("stack_ptr() is not implemented on RISC-V")
77+
{
78+
let stack_ptr: usize;
79+
unsafe {
80+
core::arch::asm!("mv {}, sp", out(reg) stack_ptr);
81+
}
82+
return VirtAddr::new(stack_ptr);
83+
}
7884
}
7985

8086
/// 获取idle进程数组的引用

kernel/src/process/mod.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ use crate::{
4141
spinlock::{SpinLock, SpinLockGuard},
4242
wait_queue::WaitQueue,
4343
},
44-
mm::{percpu::PerCpuVar, set_IDLE_PROCESS_ADDRESS_SPACE, ucontext::AddressSpace, VirtAddr},
44+
mm::{
45+
percpu::{PerCpu, PerCpuVar},
46+
set_IDLE_PROCESS_ADDRESS_SPACE,
47+
ucontext::AddressSpace,
48+
VirtAddr,
49+
},
4550
net::socket::SocketInode,
4651
sched::{
4752
completion::Completion,
@@ -73,7 +78,7 @@ pub mod utils;
7378
/// 系统中所有进程的pcb
7479
static ALL_PROCESS: SpinLock<Option<HashMap<Pid, Arc<ProcessControlBlock>>>> = SpinLock::new(None);
7580

76-
pub static mut SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None;
81+
pub static mut PROCESS_SWITCH_RESULT: Option<PerCpuVar<SwitchResult>> = None;
7782

7883
/// 一个只改变1次的全局变量,标志进程管理器是否已经初始化完成
7984
static mut __PROCESS_MANAGEMENT_INIT_DONE: bool = false;
@@ -118,6 +123,7 @@ impl ProcessManager {
118123
};
119124

120125
ALL_PROCESS.lock_irqsave().replace(HashMap::new());
126+
Self::init_switch_result();
121127
Self::arch_init();
122128
kdebug!("process arch init done.");
123129
Self::init_idle();
@@ -127,6 +133,16 @@ impl ProcessManager {
127133
kinfo!("Process Manager initialized.");
128134
}
129135

136+
fn init_switch_result() {
137+
let mut switch_res_vec: Vec<SwitchResult> = Vec::new();
138+
for _ in 0..PerCpu::MAX_CPU_NUM {
139+
switch_res_vec.push(SwitchResult::new());
140+
}
141+
unsafe {
142+
PROCESS_SWITCH_RESULT = Some(PerCpuVar::new(switch_res_vec).unwrap());
143+
}
144+
}
145+
130146
/// 判断进程管理器是否已经初始化完成
131147
pub fn initialized() -> bool {
132148
unsafe { __PROCESS_MANAGEMENT_INIT_DONE }
@@ -399,14 +415,14 @@ impl ProcessManager {
399415
/// 上下文切换完成后的钩子函数
400416
unsafe fn switch_finish_hook() {
401417
// kdebug!("switch_finish_hook");
402-
let prev_pcb = SWITCH_RESULT
418+
let prev_pcb = PROCESS_SWITCH_RESULT
403419
.as_mut()
404420
.unwrap()
405421
.get_mut()
406422
.prev_pcb
407423
.take()
408424
.expect("prev_pcb is None");
409-
let next_pcb = SWITCH_RESULT
425+
let next_pcb = PROCESS_SWITCH_RESULT
410426
.as_mut()
411427
.unwrap()
412428
.get_mut()

0 commit comments

Comments
 (0)