mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
feat(riscv): riscv下能够运行hello world用户程序 (#770)
* feat(riscv): riscv下能够运行hello world用户程序
This commit is contained in:
parent
40348dd8d5
commit
471d65cf15
@ -65,7 +65,7 @@ x86_64 = "=0.14.10"
|
||||
|
||||
# target为riscv64时,使用下面的依赖
|
||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "cc4d3ea82a", features = [ "s-mode" ] }
|
||||
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", rev = "4241a97", features = [ "s-mode" ] }
|
||||
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@ use system_error::SystemError;
|
||||
use crate::{
|
||||
driver::open_firmware::fdt::OpenFirmwareFdtDriver,
|
||||
init::boot_params,
|
||||
kdebug,
|
||||
libs::align::page_align_up,
|
||||
mm::{mmio_buddy::mmio_pool, MemoryManagementArch, PhysAddr},
|
||||
};
|
||||
@ -28,6 +29,7 @@ impl OpenFirmwareFdtDriver {
|
||||
|
||||
// drop the boot params guard in order to avoid deadlock
|
||||
drop(bp_guard);
|
||||
// kdebug!("map_fdt: map fdt to {:?}, size: {}", map_paddr, map_size);
|
||||
mmio_guard.map_phys(map_paddr, map_size)?;
|
||||
let mut bp_guard = boot_params().write();
|
||||
let vaddr = mmio_guard.vaddr() + offset;
|
||||
|
@ -112,7 +112,7 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
|
||||
arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
|
||||
arch_boot_params_guard.arch.fdt_size = fdt.total_size();
|
||||
arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
|
||||
|
||||
// kdebug!("fdt_paddr: {:?}, fdt_size: {}", fdt_paddr, fdt.total_size());
|
||||
drop(arch_boot_params_guard);
|
||||
|
||||
kinfo!(
|
||||
|
@ -160,7 +160,8 @@ unsafe extern "C" fn _save_context() -> ! {
|
||||
off_cause = const offset_of!(TrapFrame, cause),
|
||||
off_tp = const offset_of!(TrapFrame, tp),
|
||||
off_epc = const offset_of!(TrapFrame, epc),
|
||||
sr_sum_and_fsvs = const (SR_FS_VS | SR_SUM),
|
||||
sr_sum_and_fsvs = const (0), // 暂时在内核中不禁用FPU和Vector,以及不禁用用户内存访问
|
||||
// sr_sum_and_fsvs = const (SR_FS_VS | SR_SUM),
|
||||
csr_status = const CSR_SSTATUS,
|
||||
csr_epc = const CSR_SEPC,
|
||||
csr_tval = const CSR_STVAL,
|
||||
|
@ -48,10 +48,6 @@ fn riscv64_do_interrupt(trap_frame: &mut TrapFrame) {
|
||||
|
||||
/// 处理异常
|
||||
fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
|
||||
kdebug!(
|
||||
"riscv64_do_exception: from_user: {}",
|
||||
trap_frame.is_from_user()
|
||||
);
|
||||
let code = trap_frame.cause.code();
|
||||
|
||||
if code < EXCEPTION_HANDLERS.len() {
|
||||
@ -153,8 +149,16 @@ fn do_trap_user_env_call(trap_frame: &mut TrapFrame) -> Result<(), SystemError>
|
||||
// 9-11 reserved
|
||||
|
||||
/// 处理指令页错误异常 #12
|
||||
fn do_trap_insn_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||
kerror!("riscv64_do_irq: do_insn_page_fault");
|
||||
fn do_trap_insn_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||
let vaddr = trap_frame.badaddr;
|
||||
let cause = trap_frame.cause;
|
||||
let epc = trap_frame.epc;
|
||||
kerror!(
|
||||
"riscv64_do_irq: do_insn_page_fault vaddr: {:#x}, cause: {:?} epc: {:#x}",
|
||||
vaddr,
|
||||
cause,
|
||||
epc
|
||||
);
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
@ -179,8 +183,13 @@ fn do_trap_load_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError
|
||||
// 14 reserved
|
||||
|
||||
/// 处理页存储错误异常 #15
|
||||
fn do_trap_store_page_fault(_trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||
kerror!("riscv64_do_irq: do_trap_store_page_fault");
|
||||
fn do_trap_store_page_fault(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||
kerror!(
|
||||
"riscv64_do_irq: do_trap_store_page_fault: epc: {:#x}, vaddr={:#x}, cause={:?}",
|
||||
trap_frame.epc,
|
||||
trap_frame.badaddr,
|
||||
trap_frame.cause
|
||||
);
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ pub(super) unsafe fn riscv_mm_init() -> Result<(), SystemError> {
|
||||
mem_block_manager()
|
||||
.reserve_block(KERNEL_BEGIN_PA, KERNEL_END_PA - KERNEL_BEGIN_PA)
|
||||
.expect("Failed to reserve kernel memory");
|
||||
// 开启S-mode User Memory Access,允许内核访问用户空间
|
||||
riscv::register::sstatus::set_sum();
|
||||
|
||||
let mut bump_allocator = BumpAllocator::<RiscV64MMArch>::new(0);
|
||||
let _old_page_table = MMArch::table(PageTableKind::Kernel);
|
||||
@ -76,7 +78,7 @@ pub(super) unsafe fn riscv_mm_init() -> Result<(), SystemError> {
|
||||
|
||||
// 使用bump分配器,把所有的内存页都映射到页表
|
||||
{
|
||||
kdebug!("to create new page table");
|
||||
// kdebug!("to create new page table");
|
||||
// 用bump allocator创建新的页表
|
||||
let mut mapper: crate::mm::page::PageMapper<MMArch, &mut BumpAllocator<MMArch>> =
|
||||
crate::mm::page::PageMapper::<MMArch, _>::create(
|
||||
@ -85,7 +87,7 @@ pub(super) unsafe fn riscv_mm_init() -> Result<(), SystemError> {
|
||||
)
|
||||
.expect("Failed to create page mapper");
|
||||
new_page_table = mapper.table().phys();
|
||||
kdebug!("PageMapper created");
|
||||
// kdebug!("PageMapper created");
|
||||
|
||||
// 取消最开始时候,在head.S中指定的映射(暂时不刷新TLB)
|
||||
{
|
||||
|
@ -105,7 +105,9 @@ impl MemoryManagementArch for RiscV64MMArch {
|
||||
|
||||
const ENTRY_FLAG_PRESENT: usize = 1 << 0;
|
||||
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
const ENTRY_FLAG_READONLY: usize = (1 << 1);
|
||||
|
||||
const ENTRY_FLAG_WRITEABLE: usize = (1 << 2);
|
||||
|
||||
const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1);
|
||||
|
||||
|
@ -15,7 +15,7 @@ impl ProcessManager {
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
kdebug!("idle loop");
|
||||
// kdebug!("idle loop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ impl KernelThreadMechanism {
|
||||
// 使能中断
|
||||
frame.status.update_sie(true);
|
||||
frame.status.update_spp(SPP::Supervisor);
|
||||
frame.status.update_sum(true);
|
||||
|
||||
frame.ra = kernel_thread_bootstrap_stage1 as usize;
|
||||
|
||||
|
@ -28,6 +28,7 @@ use crate::{
|
||||
PROCESS_SWITCH_RESULT,
|
||||
},
|
||||
smp::cpu::ProcessorId,
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -53,7 +54,64 @@ static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
|
||||
};
|
||||
|
||||
pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! {
|
||||
unimplemented!("RiscV64 arch_switch_to_user")
|
||||
// 以下代码不能发生中断
|
||||
CurrentIrqArch::interrupt_disable();
|
||||
|
||||
let current_pcb = ProcessManager::current_pcb();
|
||||
let trap_frame_vaddr = VirtAddr::new(
|
||||
current_pcb.kernel_stack().stack_max_address().data() - core::mem::size_of::<TrapFrame>(),
|
||||
);
|
||||
let new_pc = VirtAddr::new(ret_from_exception as usize);
|
||||
|
||||
let mut arch_guard = current_pcb.arch_info_irqsave();
|
||||
arch_guard.ksp = trap_frame_vaddr.data();
|
||||
|
||||
arch_guard.ra = new_pc.data();
|
||||
drop(arch_guard);
|
||||
|
||||
// 删除kthread的标志
|
||||
current_pcb.flags().remove(ProcessFlags::KTHREAD);
|
||||
current_pcb.worker_private().take();
|
||||
|
||||
*current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
|
||||
|
||||
let mut trap_frame = TrapFrame::new();
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
Syscall::do_execve(path, argv, envp, &mut trap_frame).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"arch_switch_to_user(): pid: {pid:?}, Failed to execve: , error: {e:?}",
|
||||
pid = current_pcb.pid(),
|
||||
e = e
|
||||
);
|
||||
});
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
// 重要!在这里之后,一定要保证上面的引用计数变量、动态申请的变量、锁的守卫都被drop了,否则可能导致内存安全问题!
|
||||
|
||||
drop(current_pcb);
|
||||
|
||||
*(trap_frame_vaddr.data() as *mut TrapFrame) = trap_frame;
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
ready_to_switch_to_user(trap_frame_vaddr.data(), new_pc.data());
|
||||
}
|
||||
|
||||
#[naked]
|
||||
unsafe extern "C" fn ready_to_switch_to_user(trap_frame: usize, new_pc: usize) -> ! {
|
||||
asm!(
|
||||
concat!(
|
||||
"
|
||||
// 设置trap frame
|
||||
mv sp, a0
|
||||
// 设置返回地址
|
||||
|
||||
jr a1
|
||||
|
||||
"
|
||||
),
|
||||
options(noreturn)
|
||||
);
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
@ -98,6 +156,7 @@ impl ProcessManager {
|
||||
let current_arch_guard = current_pcb.arch_info_irqsave();
|
||||
// 拷贝浮点寄存器的状态
|
||||
new_arch_guard.fp_state = current_arch_guard.fp_state;
|
||||
new_arch_guard.sstatus = current_arch_guard.sstatus;
|
||||
|
||||
drop(current_arch_guard);
|
||||
|
||||
@ -128,11 +187,11 @@ impl ProcessManager {
|
||||
/// 参考: https://code.dragonos.org.cn/xref/linux-6.6.21/arch/riscv/include/asm/switch_to.h#76
|
||||
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
|
||||
assert!(!CurrentIrqArch::is_irq_enabled());
|
||||
kdebug!(
|
||||
"riscv switch process: prev: {:?}, next: {:?}",
|
||||
prev.pid(),
|
||||
next.pid()
|
||||
);
|
||||
// kdebug!(
|
||||
// "riscv switch process: prev: {:?}, next: {:?}",
|
||||
// prev.pid(),
|
||||
// next.pid()
|
||||
// );
|
||||
Self::switch_process_fpu(&prev, &next);
|
||||
Self::switch_local_context(&prev, &next);
|
||||
|
||||
@ -144,6 +203,8 @@ impl ProcessManager {
|
||||
drop(next_addr_space);
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
// kdebug!("current sum={}, prev sum={}, next_sum={}", riscv::register::sstatus::read().sum(), prev.arch_info_irqsave().sstatus.sum(), next.arch_info_irqsave().sstatus.sum());
|
||||
|
||||
// 获取arch info的锁,并强制泄露其守卫(切换上下文后,在switch_finish_hook中会释放锁)
|
||||
let next_arch = SpinLockGuard::leak(next.arch_info_irqsave()) as *mut ArchPCBInfo;
|
||||
let prev_arch = SpinLockGuard::leak(prev.arch_info_irqsave()) as *mut ArchPCBInfo;
|
||||
@ -153,7 +214,7 @@ impl ProcessManager {
|
||||
ProcessManager::current_pcb().preempt_enable();
|
||||
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!("riscv switch process: before to inner");
|
||||
// kdebug!("riscv switch process: before to inner");
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
// 正式切换上下文
|
||||
switch_to_inner(prev_arch, next_arch);
|
||||
@ -206,8 +267,8 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
|
||||
|
||||
addi sp , sp, -8
|
||||
sd a1, 0(sp)
|
||||
csrr a0, sstatus
|
||||
sd a0, {off_sstatus}(a1)
|
||||
csrr a1, sstatus
|
||||
sd a1, {off_sstatus}(a0)
|
||||
ld a1, 0(sp)
|
||||
addi sp, sp, 8
|
||||
|
||||
@ -271,13 +332,12 @@ unsafe extern "C" fn switch_to_inner(prev: *mut ArchPCBInfo, next: *mut ArchPCBI
|
||||
/// 在切换上下文完成后的钩子函数(必须在这里加一个跳转函数,否则会出现relocation truncated to fit: R_RISCV_JAL错误)
|
||||
unsafe extern "C" fn before_switch_finish_hook() {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
kdebug!(
|
||||
"before_switch_finish_hook, pid: {:?}, name: {:?}",
|
||||
pcb.pid(),
|
||||
pcb.basic().name()
|
||||
);
|
||||
// kdebug!(
|
||||
// "before_switch_finish_hook, pid: {:?}, name: {:?}",
|
||||
// pcb.pid(),
|
||||
// pcb.basic().name()
|
||||
// );
|
||||
switch_finish_hook();
|
||||
kdebug!("after switch_finish_hook");
|
||||
}
|
||||
|
||||
impl ProcessControlBlock {
|
||||
@ -344,6 +404,8 @@ impl ArchPCBInfo {
|
||||
///
|
||||
/// 返回一个新的ArchPCBInfo
|
||||
pub fn new(kstack: &KernelStack) -> Self {
|
||||
let mut sstatus = Sstatus::from(0);
|
||||
sstatus.update_sum(true);
|
||||
Self {
|
||||
ra: 0,
|
||||
ksp: kstack.stack_max_address().data(),
|
||||
@ -359,7 +421,7 @@ impl ArchPCBInfo {
|
||||
s9: 0,
|
||||
s10: 0,
|
||||
s11: 0,
|
||||
sstatus: Sstatus::from(0),
|
||||
sstatus,
|
||||
fp_state: FpDExtState::new(),
|
||||
local_context: LocalContext::new(ProcessorId::new(0)),
|
||||
}
|
||||
|
@ -1,7 +1,18 @@
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use riscv::register::sstatus::{Sstatus, FS, SPP};
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{arch::interrupt::TrapFrame, syscall::Syscall};
|
||||
use crate::{
|
||||
arch::{interrupt::TrapFrame, CurrentIrqArch},
|
||||
exception::InterruptArch,
|
||||
kdebug,
|
||||
mm::ucontext::AddressSpace,
|
||||
process::{
|
||||
exec::{load_binary_file, ExecParam, ExecParamFlags},
|
||||
ProcessManager,
|
||||
},
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
impl Syscall {
|
||||
pub fn do_execve(
|
||||
@ -10,7 +21,95 @@ impl Syscall {
|
||||
envp: Vec<String>,
|
||||
regs: &mut TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
unimplemented!("Syscall::do_execve")
|
||||
// 关中断,防止在设置地址空间的时候,发生中断,然后进调度器,出现错误。
|
||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
// crate::kdebug!(
|
||||
// "pid: {:?} do_execve: path: {:?}, argv: {:?}, envp: {:?}\n",
|
||||
// pcb.pid(),
|
||||
// path,
|
||||
// argv,
|
||||
// envp
|
||||
// );
|
||||
|
||||
let mut basic_info = pcb.basic_mut();
|
||||
// 暂存原本的用户地址空间的引用(因为如果在切换页表之前释放了它,可能会造成内存use after free)
|
||||
let old_address_space = basic_info.user_vm();
|
||||
|
||||
// 在pcb中原来的用户地址空间
|
||||
unsafe {
|
||||
basic_info.set_user_vm(None);
|
||||
}
|
||||
// 创建新的地址空间并设置为当前地址空间
|
||||
let address_space = AddressSpace::new(true).expect("Failed to create new address space");
|
||||
unsafe {
|
||||
basic_info.set_user_vm(Some(address_space.clone()));
|
||||
}
|
||||
|
||||
// to avoid deadlock
|
||||
drop(basic_info);
|
||||
|
||||
assert!(
|
||||
AddressSpace::is_current(&address_space),
|
||||
"Failed to set address space"
|
||||
);
|
||||
// kdebug!("Switch to new address space");
|
||||
|
||||
// 切换到新的用户地址空间
|
||||
unsafe { address_space.read().user_mapper.utable.make_current() };
|
||||
|
||||
drop(old_address_space);
|
||||
drop(irq_guard);
|
||||
// kdebug!("to load binary file");
|
||||
let mut param = ExecParam::new(path.as_str(), address_space.clone(), ExecParamFlags::EXEC)?;
|
||||
|
||||
// 加载可执行文件
|
||||
let load_result = load_binary_file(&mut param)
|
||||
.unwrap_or_else(|e| panic!("Failed to load binary file: {:?}, path: {:?}", e, path));
|
||||
// kdebug!("load binary file done");
|
||||
// kdebug!("argv: {:?}, envp: {:?}", argv, envp);
|
||||
param.init_info_mut().args = argv;
|
||||
param.init_info_mut().envs = envp;
|
||||
|
||||
// 把proc_init_info写到用户栈上
|
||||
let mut ustack_message = unsafe {
|
||||
address_space
|
||||
.write()
|
||||
.user_stack_mut()
|
||||
.expect("No user stack found")
|
||||
.clone_info_only()
|
||||
};
|
||||
let (user_sp, argv_ptr) = unsafe {
|
||||
param
|
||||
.init_info()
|
||||
.push_at(
|
||||
// address_space
|
||||
// .write()
|
||||
// .user_stack_mut()
|
||||
// .expect("No user stack found"),
|
||||
&mut ustack_message,
|
||||
)
|
||||
.expect("Failed to push proc_init_info to user stack")
|
||||
};
|
||||
address_space.write().user_stack = Some(ustack_message);
|
||||
|
||||
// kdebug!("write proc_init_info to user stack done");
|
||||
|
||||
regs.a0 = param.init_info().args.len();
|
||||
regs.a1 = argv_ptr.data();
|
||||
|
||||
// 设置系统调用返回时的寄存器状态
|
||||
regs.sp = user_sp.data();
|
||||
|
||||
regs.epc = load_result.entry_point().data();
|
||||
regs.status.update_spp(SPP::User);
|
||||
regs.status.update_fs(FS::Clean);
|
||||
regs.status.update_sie(true);
|
||||
regs.status.update_sum(true);
|
||||
|
||||
drop(param);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// ## 用于控制和查询与体系结构相关的进程特定选项
|
||||
|
@ -2,7 +2,7 @@
|
||||
pub mod nr;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{exception::InterruptArch, process::ProcessManager, syscall::Syscall};
|
||||
use crate::{exception::InterruptArch, kdebug, process::ProcessManager, syscall::Syscall};
|
||||
|
||||
use super::{interrupt::TrapFrame, CurrentIrqArch};
|
||||
|
||||
@ -29,6 +29,7 @@ macro_rules! syscall_return {
|
||||
}
|
||||
|
||||
pub(super) fn syscall_handler(syscall_num: usize, frame: &mut TrapFrame) -> () {
|
||||
// kdebug!("syscall_handler: syscall_num: {}", syscall_num);
|
||||
unsafe {
|
||||
CurrentIrqArch::interrupt_enable();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
driver::open_firmware::fdt::open_firmware_fdt_driver,
|
||||
kinfo,
|
||||
kdebug, kinfo,
|
||||
time::{clocksource::HZ, TimeArch},
|
||||
};
|
||||
pub struct RiscV64TimeArch;
|
||||
@ -14,10 +14,12 @@ static mut TIME_FREQ: usize = 0;
|
||||
///
|
||||
/// todo: 支持从acpi中获取
|
||||
fn init_time_freq() {
|
||||
kdebug!("init_time_freq: init");
|
||||
let fdt = open_firmware_fdt_driver().fdt_ref();
|
||||
if fdt.is_err() {
|
||||
panic!("init_time_freq: failed to get fdt");
|
||||
}
|
||||
kdebug!("init_time_freq: get fdt");
|
||||
let fdt = fdt.unwrap();
|
||||
let cpu_node = fdt.find_node("/cpus");
|
||||
if cpu_node.is_none() {
|
||||
|
@ -94,6 +94,7 @@ impl MemoryManagementArch for X86_64MMArch {
|
||||
|
||||
const ENTRY_FLAG_READONLY: usize = 0;
|
||||
|
||||
const ENTRY_FLAG_WRITEABLE: usize = 1 << 1;
|
||||
const ENTRY_FLAG_READWRITE: usize = 1 << 1;
|
||||
|
||||
const ENTRY_FLAG_USER: usize = 1 << 2;
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
CFLAGS += -I .
|
||||
|
||||
kernel_driver_subdirs:=acpi disk multiboot2 timers
|
||||
kernel_driver_subdirs:=acpi multiboot2
|
||||
|
||||
ECHO:
|
||||
@echo "$@"
|
||||
|
@ -34,11 +34,11 @@ impl RiscVSbiTimer {
|
||||
|
||||
fn handle_irq(trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
|
||||
// 更新下一次中断时间
|
||||
kdebug!(
|
||||
"riscv_sbi_timer: handle_irq: cpu_id: {}, time: {}",
|
||||
smp_get_processor_id().data(),
|
||||
CurrentTimeArch::get_cycles() as u64
|
||||
);
|
||||
// kdebug!(
|
||||
// "riscv_sbi_timer: handle_irq: cpu_id: {}, time: {}",
|
||||
// smp_get_processor_id().data(),
|
||||
// CurrentTimeArch::get_cycles() as u64
|
||||
// );
|
||||
sbi_rt::set_timer(CurrentTimeArch::get_cycles() as u64 + unsafe { INTERVAL_CNT } as u64);
|
||||
ProcessManager::update_process_times(trap_frame.is_from_user());
|
||||
Ok(())
|
||||
|
@ -1,10 +0,0 @@
|
||||
SRC = $(wildcard *.c)
|
||||
OBJ = $(SRC:.c=.o)
|
||||
CFLAGS += -I .
|
||||
|
||||
.PHONY: all
|
||||
|
||||
all: $(OBJ)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
13
kernel/src/driver/firmware/efi/esrt.rs
Normal file
13
kernel/src/driver/firmware/efi/esrt.rs
Normal file
@ -0,0 +1,13 @@
|
||||
//! 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/firmware/efi/esrt.c#1
|
||||
|
||||
use super::efi_manager;
|
||||
|
||||
#[inline(never)]
|
||||
pub(super) fn efi_esrt_init() {
|
||||
if !efi_manager().esrt_table_exists() {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: 参考linux 的 `efi_esrt_init`来实现
|
||||
todo!("efi_esrt_init")
|
||||
}
|
@ -29,6 +29,15 @@ pub static EFI_MEMRESERVE_TABLE_GUID: Guid = Guid::new(
|
||||
0xf0,
|
||||
[0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2],
|
||||
);
|
||||
|
||||
pub static EFI_SYSTEM_RESOURCE_TABLE_GUID: Guid = Guid::new(
|
||||
unsafe { mem::transmute_copy(&0xb122a263u32) },
|
||||
unsafe { mem::transmute_copy(&0x3661u32) },
|
||||
unsafe { mem::transmute_copy(&0x4f68u32) },
|
||||
0x99,
|
||||
0x29,
|
||||
[0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80],
|
||||
);
|
||||
/// 表示内核被加载到的地址的信息。
|
||||
///
|
||||
/// 对应 `DRAGONSTUB_EFI_PAYLOAD_EFI_GUID`
|
||||
|
@ -5,7 +5,10 @@ use uefi_raw::table::boot::{MemoryAttribute, MemoryType};
|
||||
|
||||
use crate::{
|
||||
arch::MMArch,
|
||||
driver::{firmware::efi::EFIInitFlags, open_firmware::fdt::open_firmware_fdt_driver},
|
||||
driver::{
|
||||
firmware::efi::{esrt::efi_esrt_init, EFIInitFlags},
|
||||
open_firmware::fdt::open_firmware_fdt_driver,
|
||||
},
|
||||
libs::align::{page_align_down, page_align_up},
|
||||
mm::{
|
||||
allocator::page_frame::PhysPageFrame, early_ioremap::EarlyIoRemap,
|
||||
@ -66,6 +69,11 @@ pub fn efi_init() {
|
||||
// todo: 模仿Linux的行为,做好接下来的几步工作:
|
||||
// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/firmware/efi/efi-init.c#217
|
||||
|
||||
// todo: early_init_dt_check_for_usable_mem_range
|
||||
|
||||
efi_find_mirror();
|
||||
efi_esrt_init();
|
||||
|
||||
// 保留mmap table的内存
|
||||
let base = page_align_down(data_from_fdt.mmap_base.unwrap() as usize);
|
||||
let offset = data_from_fdt.mmap_base.unwrap() as usize - base;
|
||||
@ -78,7 +86,7 @@ pub fn efi_init() {
|
||||
.expect("Failed to reserve memory for EFI mmap table");
|
||||
|
||||
// 保留内核的内存
|
||||
if let Some(info) = efi_manager().inner.read().dragonstub_load_info {
|
||||
if let Some(info) = efi_manager().inner_read().dragonstub_load_info {
|
||||
mem_block_manager()
|
||||
.reserve_block(
|
||||
PhysAddr::new(info.paddr as usize),
|
||||
@ -92,6 +100,31 @@ pub fn efi_init() {
|
||||
kinfo!("UEFI init done!");
|
||||
}
|
||||
|
||||
fn efi_find_mirror() {
|
||||
let efi_guard = efi_manager().inner_read();
|
||||
let mut total_size = 0;
|
||||
let mut mirror_size = 0;
|
||||
for md in efi_guard.mmap.iter() {
|
||||
let start = PhysAddr::new(md.phys_start as usize);
|
||||
let size = (md.page_count << (MMArch::PAGE_SHIFT as u64)) as usize;
|
||||
|
||||
if md.att.contains(MemoryAttribute::MORE_RELIABLE) {
|
||||
mem_block_manager().mark_mirror(start, size).unwrap();
|
||||
mirror_size += size;
|
||||
}
|
||||
|
||||
total_size += size;
|
||||
}
|
||||
|
||||
if mirror_size > 0 {
|
||||
kinfo!(
|
||||
"Memory: {}M/{}M mirrored memory",
|
||||
mirror_size >> 20,
|
||||
total_size >> 20
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn uefi_init(system_table: PhysAddr) -> Result<(), SystemError> {
|
||||
// 定义错误处理函数
|
||||
@ -142,7 +175,7 @@ fn uefi_init(system_table: PhysAddr) -> Result<(), SystemError> {
|
||||
let st_ref = unsafe { st_ptr.as_ref().unwrap() };
|
||||
|
||||
let runtime_service_paddr = efi_vaddr_2_paddr(st_ref.runtime_services as usize);
|
||||
let mut inner_write_guard = efi_manager().inner.write();
|
||||
let mut inner_write_guard = efi_manager().inner_write();
|
||||
inner_write_guard.runtime_paddr = Some(runtime_service_paddr);
|
||||
inner_write_guard.runtime_service_version = Some(st_ref.header.revision);
|
||||
|
||||
@ -189,7 +222,7 @@ fn uefi_init(system_table: PhysAddr) -> Result<(), SystemError> {
|
||||
///
|
||||
/// 在进入该函数前,请不要持有`efi_manager().inner`的写锁
|
||||
fn efi_vaddr_2_paddr(efi_vaddr: usize) -> PhysAddr {
|
||||
let guard = efi_manager().inner.read();
|
||||
let guard = efi_manager().inner_read();
|
||||
let mmap = &guard.mmap;
|
||||
|
||||
let efi_vaddr: u64 = efi_vaddr as u64;
|
||||
@ -236,6 +269,11 @@ fn reserve_memory_regions() {
|
||||
if md.is_memory() {
|
||||
open_firmware_fdt_driver().early_init_dt_add_memory(phys_start as u64, size as u64);
|
||||
if !md.is_usable_memory() {
|
||||
// kdebug!(
|
||||
// "Marking non-usable memory as nomap: {:#x}-{:#x}",
|
||||
// phys_start,
|
||||
// phys_start + size
|
||||
// );
|
||||
mem_block_manager()
|
||||
.mark_nomap(PhysAddr::new(phys_start), size)
|
||||
.unwrap();
|
||||
|
@ -1,9 +1,13 @@
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{libs::rwlock::RwLock, mm::PhysAddr};
|
||||
use crate::{
|
||||
libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
mm::PhysAddr,
|
||||
};
|
||||
|
||||
use self::{guid::DragonStubPayloadEFI, memmap::EFIMemoryMapInfo};
|
||||
|
||||
pub mod esrt;
|
||||
mod fdt;
|
||||
pub mod guid;
|
||||
pub mod init;
|
||||
@ -39,6 +43,8 @@ struct InnerEFIManager {
|
||||
pub memory_attribute_table_paddr: Option<PhysAddr>,
|
||||
/// uefi 内存保留表的物理地址
|
||||
pub memreserve_table_paddr: Option<PhysAddr>,
|
||||
/// uefi esrt表的物理地址
|
||||
pub esrt_table_paddr: Option<PhysAddr>,
|
||||
}
|
||||
|
||||
impl EFIManager {
|
||||
@ -52,6 +58,7 @@ impl EFIManager {
|
||||
dragonstub_load_info: None,
|
||||
memory_attribute_table_paddr: None,
|
||||
memreserve_table_paddr: None,
|
||||
esrt_table_paddr: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@ -97,6 +104,19 @@ impl EFIManager {
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn inner_read(&self) -> RwLockReadGuard<InnerEFIManager> {
|
||||
self.inner.read()
|
||||
}
|
||||
|
||||
fn inner_write(&self) -> RwLockWriteGuard<InnerEFIManager> {
|
||||
self.inner.write()
|
||||
}
|
||||
|
||||
/// 是否存在ESRT表
|
||||
fn esrt_table_exists(&self) -> bool {
|
||||
self.inner_read().esrt_table_paddr.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
// 在Rust中,我们使用枚举和bitflags来表示这些宏
|
||||
|
@ -20,7 +20,9 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
guid::{EFI_MEMORY_ATTRIBUTES_TABLE_GUID, EFI_MEMRESERVE_TABLE_GUID},
|
||||
guid::{
|
||||
EFI_MEMORY_ATTRIBUTES_TABLE_GUID, EFI_MEMRESERVE_TABLE_GUID, EFI_SYSTEM_RESOURCE_TABLE_GUID,
|
||||
},
|
||||
EFIManager,
|
||||
};
|
||||
|
||||
@ -29,6 +31,7 @@ static TABLE_PARSERS: &[&TableMatcher] = &[
|
||||
&TableMatcher::new(&MatchTableDragonStubPayloadEFI),
|
||||
&TableMatcher::new(&MatchTableMemoryAttributes),
|
||||
&TableMatcher::new(&MatchTableMemReserve),
|
||||
&TableMatcher::new(&MatchTableEsrt),
|
||||
];
|
||||
|
||||
impl EFIManager {
|
||||
@ -99,7 +102,7 @@ impl EFIManager {
|
||||
}
|
||||
|
||||
// 如果存在mem reserve table
|
||||
if let Some(mem_reserve) = efi_manager().inner.read().memreserve_table_paddr {
|
||||
if let Some(mem_reserve) = efi_manager().inner_read().memreserve_table_paddr {
|
||||
let mut prev_paddr = mem_reserve;
|
||||
while !prev_paddr.is_null() {
|
||||
let vaddr = EarlyIoRemap::map_not_aligned(prev_paddr, MMArch::PAGE_SIZE, true)
|
||||
@ -283,7 +286,7 @@ impl MatchTable for MatchTableDragonStubPayloadEFI {
|
||||
let vendor_table_vaddr = vendor_table_vaddr.unwrap();
|
||||
let data = unsafe { *(vendor_table_vaddr.data() as *const DragonStubPayloadEFI) };
|
||||
|
||||
efi_manager().inner.write().dragonstub_load_info = Some(data);
|
||||
efi_manager().inner_write().dragonstub_load_info = Some(data);
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
@ -349,6 +352,33 @@ impl MatchTable for MatchTableMemReserve {
|
||||
}
|
||||
}
|
||||
|
||||
struct MatchTableEsrt;
|
||||
|
||||
impl MatchTable for MatchTableEsrt {
|
||||
fn name(&self) -> &'static str {
|
||||
"ESRT"
|
||||
}
|
||||
|
||||
fn guid(&self) -> &'static uefi_raw::Guid {
|
||||
&EFI_SYSTEM_RESOURCE_TABLE_GUID
|
||||
}
|
||||
|
||||
fn map_size(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn post_process(
|
||||
&self,
|
||||
_vendor_table_vaddr: Option<VirtAddr>,
|
||||
table_raw: &ConfigurationTable,
|
||||
) -> Result<(), SystemError> {
|
||||
efi_manager().inner.write_irqsave().esrt_table_paddr =
|
||||
Some(PhysAddr::new(table_raw.vendor_table as usize));
|
||||
kdebug!("esrt_table_paddr: {:#x}", table_raw.vendor_table as usize);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
/// 用于匹配配置表的匹配器
|
||||
struct TableMatcher {
|
||||
table: &'static dyn MatchTable,
|
||||
|
@ -162,7 +162,7 @@ pub unsafe fn riscv_intc_init() -> Result<(), SystemError> {
|
||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/irqchip/irq-riscv-intc.c#23
|
||||
pub fn riscv_intc_irq(trap_frame: &mut TrapFrame) {
|
||||
let hwirq = HardwareIrqNumber::new(trap_frame.cause.code() as u32);
|
||||
kdebug!("riscv64_do_irq: interrupt {hwirq:?}");
|
||||
// kdebug!("riscv64_do_irq: interrupt {hwirq:?}");
|
||||
GenericIrqHandler::handle_domain_irq(riscv_intc_domain().clone().unwrap(), hwirq, trap_frame)
|
||||
.ok();
|
||||
if hwirq.data() == RiscVSbiTimer::TIMER_IRQ.data() {
|
||||
|
@ -1,6 +0,0 @@
|
||||
all:
|
||||
|
||||
CFLAGS += -I .
|
||||
|
||||
#HPET.o: HPET/HPET.c
|
||||
# $(CC) $(CFLAGS) -c HPET/HPET.c -o HPET/HPET.o
|
@ -61,8 +61,9 @@ fn kenrel_init_freeable() -> Result<(), SystemError> {
|
||||
|
||||
/// 切换到用户态
|
||||
fn switch_to_user() {
|
||||
let path = String::from("/bin/dragonreach");
|
||||
let argv = vec![String::from("/bin/dragonreach")];
|
||||
const INIT_PROGRAM: &str = "/bin/dragonreach";
|
||||
let path = String::from(INIT_PROGRAM);
|
||||
let argv = vec![path.clone()];
|
||||
let envp = vec![String::from("PATH=/")];
|
||||
|
||||
unsafe { arch_switch_to_user(path, argv, envp) };
|
||||
|
@ -145,5 +145,6 @@ pub fn panic(info: &PanicInfo) -> ! {
|
||||
}
|
||||
|
||||
println!("Current PCB:\n\t{:?}", (ProcessManager::current_pcb()));
|
||||
|
||||
ProcessManager::exit(usize::MAX);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ impl ElfLoader {
|
||||
) -> Result<(), ExecError> {
|
||||
let start = self.elf_page_start(start);
|
||||
let end = self.elf_page_align_up(end);
|
||||
|
||||
// kdebug!("set_elf_brk: start={:?}, end={:?}", start, end);
|
||||
if end > start {
|
||||
let r = user_vm_guard.map_anonymous(
|
||||
start,
|
||||
@ -133,6 +133,7 @@ impl ElfLoader {
|
||||
false,
|
||||
true,
|
||||
);
|
||||
// kdebug!("set_elf_brk: map_anonymous: r={:?}", r);
|
||||
if r.is_err() {
|
||||
kerror!("set_elf_brk: map_anonymous failed, err={:?}", r);
|
||||
return Err(ExecError::OutOfMemory);
|
||||
@ -254,18 +255,14 @@ impl ElfLoader {
|
||||
if total_size != 0 {
|
||||
let total_size = self.elf_page_align_up(VirtAddr::new(total_size)).data();
|
||||
|
||||
// kdebug!("total_size={}", total_size);
|
||||
|
||||
map_addr = user_vm_guard
|
||||
.map_anonymous(addr_to_map, total_size, tmp_prot, *map_flags, false, true)
|
||||
.map_err(map_err_handler)?
|
||||
.virt_address();
|
||||
// kdebug!("map ok: addr_to_map={:?}", addr_to_map);
|
||||
|
||||
let to_unmap = map_addr + map_size;
|
||||
let to_unmap_size = total_size - map_size;
|
||||
|
||||
// kdebug!("to_unmap={:?}, to_unmap_size={}", to_unmap, to_unmap_size);
|
||||
user_vm_guard.munmap(
|
||||
VirtPageFrame::new(to_unmap),
|
||||
PageFrameCount::from_bytes(to_unmap_size).unwrap(),
|
||||
@ -554,6 +551,7 @@ impl BinaryLoader for ElfLoader {
|
||||
if seg.p_type != PT_INTERP {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 接下来处理这个 .interpreter 段以及动态链接器
|
||||
// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/fs/binfmt_elf.c#881
|
||||
|
||||
@ -582,8 +580,6 @@ impl BinaryLoader for ElfLoader {
|
||||
}
|
||||
Self::parse_gnu_property()?;
|
||||
|
||||
// kdebug!("loadable_sections = {:?}", loadable_sections);
|
||||
|
||||
let mut elf_brk = VirtAddr::new(0);
|
||||
let mut elf_bss = VirtAddr::new(0);
|
||||
let mut start_code: Option<VirtAddr> = None;
|
||||
@ -606,6 +602,7 @@ impl BinaryLoader for ElfLoader {
|
||||
let loadable_sections = phdr_table
|
||||
.into_iter()
|
||||
.filter(|seg| seg.p_type == elf::abi::PT_LOAD);
|
||||
|
||||
for seg_to_load in loadable_sections {
|
||||
min_address = min(
|
||||
min_address,
|
||||
@ -695,7 +692,7 @@ impl BinaryLoader for ElfLoader {
|
||||
}
|
||||
|
||||
// 加载这个段到用户空间
|
||||
|
||||
// kdebug!("to load elf segment");
|
||||
let e = self
|
||||
.load_elf_segment(
|
||||
&mut user_vm,
|
||||
@ -706,10 +703,13 @@ impl BinaryLoader for ElfLoader {
|
||||
&elf_map_flags,
|
||||
total_size,
|
||||
)
|
||||
.map_err(|e| match e {
|
||||
SystemError::EFAULT => ExecError::BadAddress(None),
|
||||
SystemError::ENOMEM => ExecError::OutOfMemory,
|
||||
_ => ExecError::Other(format!("load_elf_segment failed: {:?}", e)),
|
||||
.map_err(|e| {
|
||||
kerror!("load_elf_segment failed: {:?}", e);
|
||||
match e {
|
||||
SystemError::EFAULT => ExecError::BadAddress(None),
|
||||
SystemError::ENOMEM => ExecError::OutOfMemory,
|
||||
_ => ExecError::Other(format!("load_elf_segment failed: {:?}", e)),
|
||||
}
|
||||
})?;
|
||||
|
||||
// 如果地址不对,那么就报错
|
||||
|
@ -21,7 +21,7 @@ pub struct PhysPageFrame {
|
||||
impl PhysPageFrame {
|
||||
pub fn new(paddr: PhysAddr) -> Self {
|
||||
return Self {
|
||||
number: paddr.data() / MMArch::PAGE_SIZE,
|
||||
number: paddr.data() >> MMArch::PAGE_SHIFT,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,6 @@ impl KernelMapper {
|
||||
|
||||
let count = PageFrameCount::new(page_align_up(size) / MMArch::PAGE_SIZE);
|
||||
// kdebug!("kernel mapper: map_phys: vaddr: {vaddr:?}, paddr: {paddr:?}, count: {count:?}, flags: {flags:?}");
|
||||
|
||||
for _ in 0..count.data() {
|
||||
let flusher = self.mapper.map_phys(vaddr, paddr, flags).unwrap();
|
||||
|
||||
|
@ -352,6 +352,11 @@ impl MemBlockManager {
|
||||
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::NOMAP);
|
||||
}
|
||||
|
||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/mm/memblock.c?fi=memblock_mark_mirror#940
|
||||
pub fn mark_mirror(&self, base: PhysAddr, size: usize) -> Result<(), SystemError> {
|
||||
return self.set_or_clear_flags(base, size, true, MemoryAreaAttr::MIRROR);
|
||||
}
|
||||
|
||||
fn set_or_clear_flags(
|
||||
&self,
|
||||
mut base: PhysAddr,
|
||||
|
@ -447,6 +447,8 @@ pub trait MemoryManagementArch: Clone + Copy + Debug {
|
||||
const ENTRY_FLAG_PRESENT: usize;
|
||||
/// 页表项为read only时的值
|
||||
const ENTRY_FLAG_READONLY: usize;
|
||||
/// 页表项的write bit
|
||||
const ENTRY_FLAG_WRITEABLE: usize;
|
||||
/// 页表项为可读写状态的值
|
||||
const ENTRY_FLAG_READWRITE: usize;
|
||||
/// 页面项标记页面为user page的值
|
||||
|
@ -530,9 +530,18 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
Self::from_data(Arch::ENTRY_FLAG_DEFAULT_TABLE)
|
||||
}
|
||||
};
|
||||
if user {
|
||||
r.set_user(true)
|
||||
} else {
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
if user {
|
||||
r.set_user(true)
|
||||
} else {
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
{
|
||||
r
|
||||
}
|
||||
};
|
||||
@ -607,7 +616,9 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
if value {
|
||||
return self.update_flags(Arch::ENTRY_FLAG_READWRITE, true);
|
||||
} else {
|
||||
return self.update_flags(Arch::ENTRY_FLAG_READONLY, true);
|
||||
return self
|
||||
.update_flags(Arch::ENTRY_FLAG_READONLY, true)
|
||||
.update_flags(Arch::ENTRY_FLAG_WRITEABLE, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -724,13 +735,25 @@ impl<Arch: MemoryManagementArch> PageFlags<Arch> {
|
||||
/// MMIO内存的页表项标志
|
||||
#[inline(always)]
|
||||
pub fn mmio_flags() -> Self {
|
||||
return Self::new()
|
||||
.set_user(false)
|
||||
.set_write(true)
|
||||
.set_execute(true)
|
||||
.set_page_cache_disable(true)
|
||||
.set_page_write_through(true)
|
||||
.set_page_global(true);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
Self::new()
|
||||
.set_user(false)
|
||||
.set_write(true)
|
||||
.set_execute(true)
|
||||
.set_page_cache_disable(true)
|
||||
.set_page_write_through(true)
|
||||
.set_page_global(true)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
{
|
||||
Self::new()
|
||||
.set_user(false)
|
||||
.set_write(true)
|
||||
.set_execute(true)
|
||||
.set_page_global(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -873,6 +896,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
let mut table = self.table();
|
||||
loop {
|
||||
let i = table.index_of(virt)?;
|
||||
|
||||
assert!(i < Arch::PAGE_ENTRY_NUM);
|
||||
if table.level() == 0 {
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
@ -891,13 +915,10 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> PageMapper<Arch, F> {
|
||||
|
||||
// 清空这个页帧
|
||||
MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
|
||||
|
||||
// 设置页表项的flags
|
||||
let flags: PageFlags<Arch> =
|
||||
PageFlags::new_page_table(virt.kind() == PageTableKind::User);
|
||||
|
||||
// kdebug!("Flags: {:?}", flags);
|
||||
|
||||
// 把新分配的页表映射到当前页表
|
||||
table.set_entry(i, PageEntry::new(frame, flags));
|
||||
|
||||
|
@ -188,7 +188,7 @@ pub fn load_binary_file(param: &mut ExecParam) -> Result<BinaryLoaderResult, Sys
|
||||
.load(param, &head_buf)
|
||||
.unwrap_or_else(|e| panic!("load_binary_file failed: error: {e:?}, param: {param:?}"));
|
||||
|
||||
// kdebug!("load_binary_file: load success");
|
||||
// kdebug!("load_binary_file: load success: {result:?}");
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user