Skip to content

riscv: 进程管理初始化 #654

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion kernel/src/arch/riscv64/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
41 changes: 36 additions & 5 deletions kernel/src/arch/riscv64/process/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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的过程中复制线程
Expand All @@ -50,14 +60,35 @@ 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")
}
}

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;
}
}
}

Expand All @@ -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) {
Expand Down
15 changes: 10 additions & 5 deletions kernel/src/arch/riscv64/smp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
use system_error::SystemError;

use crate::smp::{
cpu::{CpuHpCpuState, ProcessorId},
SMPArch,
use crate::{
kwarn,
smp::{
cpu::{CpuHpCpuState, ProcessorId},
SMPArch,
},
};

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(())
}
}
2 changes: 1 addition & 1 deletion kernel/src/arch/riscv64/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use super::{interrupt::TrapFrame, CurrentIrqArch};

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

#[no_mangle]
Expand Down
23 changes: 5 additions & 18 deletions kernel/src/arch/x86_64/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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的过程中复制线程
///
Expand Down Expand Up @@ -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);
// 正式切换上下文
Expand Down
8 changes: 7 additions & 1 deletion kernel/src/process/idle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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进程数组的引用
Expand Down
24 changes: 20 additions & 4 deletions kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand All @@ -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 }
Expand Down Expand Up @@ -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()
Expand Down