fix:Fix related issues with kexec (pr # 1303) code (#1339)
- Fix some legacy issues of PR 1303 - Supplement the error handling of PR 1303 Signed-off-by: JensenWei007 <jensenwei007@gmail.com>
This commit is contained in:
parent
dee2e02034
commit
be4ee4f0ac
|
|
@ -26,4 +26,9 @@ compile_commands.json
|
|||
/.direnv/
|
||||
/flake.nix
|
||||
flake.lock
|
||||
/default.nix
|
||||
/default.nix
|
||||
|
||||
# initram
|
||||
*.cpio
|
||||
*.cpio.xz
|
||||
*.cpio*
|
||||
|
|
|
|||
1
env.mk
1
env.mk
|
|
@ -10,5 +10,6 @@ ifeq ($(EMULATOR), )
|
|||
export EMULATOR=__NO_EMULATION__
|
||||
endif
|
||||
|
||||
export INITRAM_PATH?=$(ROOT_PATH)/x86.cpio.xz
|
||||
|
||||
export DADK?=$(shell which dadk)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,3 @@ src/include/bindings/bindings.h
|
|||
|
||||
# Build counter
|
||||
.build_count
|
||||
|
||||
# initram
|
||||
initram/*.cpio
|
||||
initram/*.cpio.xz
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@ use std::env;
|
|||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let path = format!("{}/initram/x86.cpio.xz", manifest_dir);
|
||||
if Path::new(&path).exists() {
|
||||
println!("cargo:rustc-cfg=has_initram_x86");
|
||||
if let Ok(initram_path) = env::var("INITRAM_PATH") {
|
||||
if Path::new(&initram_path).exists() {
|
||||
println!("cargo:rustc-cfg=has_initram");
|
||||
// 将路径传递给编译时常量
|
||||
println!("cargo:rustc-env=INITRAM_PATH={}", initram_path);
|
||||
println!("cargo:rerun-if-env-changed=INITRAM_PATH");
|
||||
}
|
||||
}
|
||||
|
||||
kernel_build::run();
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "此脚本暂时废置, 请使用 DragonBoot 仓库进行构建"
|
||||
|
|
@ -42,7 +42,7 @@ kernel_subdirs := debug
|
|||
TOOLCHAIN := +nightly-2025-08-10
|
||||
|
||||
kernel_rust:
|
||||
DRAGONOS_ACTUAL_BUILD=1 RUSTFLAGS="$(RUSTFLAGS)" cargo $(TOOLCHAIN) $(CARGO_ZBUILD) build --release --target $(TARGET_JSON)
|
||||
DRAGONOS_ACTUAL_BUILD=1 RUSTFLAGS="$(RUSTFLAGS)" INITRAM_PATH="$(INITRAM_PATH)" cargo $(TOOLCHAIN) $(CARGO_ZBUILD) build --release --target $(TARGET_JSON)
|
||||
|
||||
|
||||
all: kernel
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ impl ArchBootParams {
|
|||
|
||||
pub fn set_scratch(&mut self, _scratch: u32) {}
|
||||
|
||||
pub fn add_e820_entry(&mut self, _addr: u64, _size: u64, _mtype: u32) {}
|
||||
|
||||
pub fn init_setupheader(&mut self) {}
|
||||
|
||||
pub fn convert_to_buf(&self) -> &[u8] {
|
||||
|
|
|
|||
|
|
@ -24,3 +24,28 @@ impl SignalArch for LoongArch64SignalArch {
|
|||
todo!("la64:sys_rt_sigreturn")
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 信号处理备用栈的信息
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct LoongArch64SigStack {
|
||||
pub sp: usize,
|
||||
pub flags: u32,
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
impl LoongArch64SigStack {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sp: 0,
|
||||
flags: 0,
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for LoongArch64SigStack {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
use crate::init::kexec::Kimage;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use alloc::rc::Rc;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> bool {
|
||||
false
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {}
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn machine_kexec(kimage: Rc<SpinLock<Kimage>>) {}
|
||||
pub fn machine_kexec(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ pub mod time;
|
|||
|
||||
pub use self::elf::LoongArch64ElfArch as CurrentElfArch;
|
||||
pub use self::interrupt::LoongArch64InterruptArch as CurrentIrqArch;
|
||||
pub use self::ipc::signal::LoongArch64SigStack as SigStackArch;
|
||||
pub use self::ipc::signal::LoongArch64SignalArch as CurrentSignalArch;
|
||||
pub use self::mm::LoongArch64MMArch as MMArch;
|
||||
pub use self::pci::LoongArch64PciArch as PciArch;
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ impl BootCallbacks for DragonStubCallBack {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
log::error!("riscv64, early_init_memmap_sysfs is not impled");
|
||||
fn init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
log::error!("riscv64, init_memmap_sysfs is not impled");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ impl ArchBootParams {
|
|||
|
||||
pub fn set_scratch(&mut self, _scratch: u32) {}
|
||||
|
||||
pub fn add_e820_entry(&mut self, _addr: u64, _size: u64, _mtype: u32) {}
|
||||
|
||||
pub fn init_setupheader(&mut self) {}
|
||||
|
||||
pub fn convert_to_buf(&self) -> &[u8] {
|
||||
|
|
|
|||
|
|
@ -40,3 +40,28 @@ bitflags! {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/// @brief 信号处理备用栈的信息
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RiscV64SigStack {
|
||||
pub sp: usize,
|
||||
pub flags: u32,
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
impl RiscV64SigStack {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sp: 0,
|
||||
flags: 0,
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RiscV64SigStack {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
use crate::init::kexec::Kimage;
|
||||
use crate::libs::spinlock::SpinLock;
|
||||
use alloc::rc::Rc;
|
||||
use system_error::SystemError;
|
||||
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> bool {
|
||||
false
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {}
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn machine_kexec(kimage: Rc<SpinLock<Kimage>>) {}
|
||||
pub fn machine_kexec(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ pub use self::time::RiscV64TimeArch as CurrentTimeArch;
|
|||
|
||||
pub use self::elf::RiscV64ElfArch as CurrentElfArch;
|
||||
|
||||
pub use self::ipc::signal::RiscV64SigStack as SigStackArch;
|
||||
pub use self::ipc::signal::RiscV64SignalArch as CurrentSignalArch;
|
||||
|
||||
pub use crate::arch::smp::RiscV64SMPArch as CurrentSMPArch;
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ impl BootCallbacks for Mb2Callback {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
fn init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
// 没测试过, 可能有问题
|
||||
crate::mm::sysfs::early_memmap_init();
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ impl BootCallbacks for PvhBootCallback {
|
|||
}
|
||||
|
||||
fn init_initramfs(&self) -> Result<(), SystemError> {
|
||||
log::error!("x86 pvh, init_initramfs is not impled");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +124,7 @@ impl BootCallbacks for PvhBootCallback {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn early_init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
fn init_memmap_sysfs(&self) -> Result<(), SystemError> {
|
||||
crate::mm::sysfs::early_memmap_init();
|
||||
|
||||
let start_info = START_INFO.get();
|
||||
|
|
|
|||
|
|
@ -131,16 +131,34 @@ impl SigContext {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 信号处理备用栈的信息
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct X86SigStack {
|
||||
pub sp: *mut c_void,
|
||||
pub sp: usize,
|
||||
pub flags: u32,
|
||||
pub size: u32,
|
||||
pub fpstate: FpState,
|
||||
}
|
||||
|
||||
impl X86SigStack {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sp: 0,
|
||||
flags: 0,
|
||||
size: 0,
|
||||
fpstate: FpState::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for X86SigStack {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn do_signal(frame: &mut TrapFrame, got_signal: &mut bool) {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ use crate::mm::MemoryManagementArch;
|
|||
use crate::mm::{page::EntryFlags, PhysAddr};
|
||||
use alloc::rc::Rc;
|
||||
use core::mem::transmute;
|
||||
use system_error::SystemError;
|
||||
|
||||
type RelocateKernelFn =
|
||||
unsafe extern "C" fn(indirection_page: usize, start_address: usize, stack_page_address: usize);
|
||||
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> bool {
|
||||
pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
unsafe {
|
||||
unsafe extern "C" {
|
||||
unsafe fn __relocate_kernel_start();
|
||||
|
|
@ -69,10 +70,10 @@ pub fn machine_kexec_prepare(kimage: Rc<SpinLock<Kimage>>) -> bool {
|
|||
mess_buf.resize(2048, 0);
|
||||
slice.copy_from_slice(&mess_buf);
|
||||
}
|
||||
true
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {
|
||||
pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) -> Result<(), SystemError> {
|
||||
let pgd = ident_pt_alloc();
|
||||
kimage.lock().pgd = pgd;
|
||||
|
||||
|
|
@ -92,7 +93,7 @@ pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {
|
|||
let size = kimage.lock().segment[i].memsz;
|
||||
// TODO:处理可能不是页面整数的情况, 但是目前, 传入的参数都是在用户层页面对其和取整了
|
||||
let pages_nums = size / MMArch::PAGE_SIZE;
|
||||
ident_map_pages(pgd, addr, addr, pages_nums);
|
||||
ident_map_pages(pgd, addr, addr, pages_nums)?;
|
||||
}
|
||||
|
||||
// pages
|
||||
|
|
@ -106,7 +107,7 @@ pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {
|
|||
for i in 0..len {
|
||||
let page = kimage.lock().pages[i].clone();
|
||||
let addr = page.phys_address().data();
|
||||
ident_map_page(pgd, addr, addr);
|
||||
ident_map_page(pgd, addr, addr)?;
|
||||
}
|
||||
|
||||
// efi
|
||||
|
|
@ -126,11 +127,11 @@ pub fn init_pgtable(kimage: Rc<SpinLock<Kimage>>) {
|
|||
pgd,
|
||||
unsafe { MMArch::phys_2_virt(control_page_pa).unwrap().data() },
|
||||
control_page_pa.data(),
|
||||
);
|
||||
)?;
|
||||
|
||||
// cmdline
|
||||
let cmdline_ptr = boot_params().read().arch.hdr.cmd_line_ptr as usize;
|
||||
ident_map_page(pgd, cmdline_ptr, cmdline_ptr);
|
||||
ident_map_page(pgd, cmdline_ptr, cmdline_ptr)
|
||||
}
|
||||
|
||||
pub fn machine_kexec(kimage: Rc<SpinLock<Kimage>>) {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ pub use crate::arch::asm::pio::X86_64PortIOArch as CurrentPortIOArch;
|
|||
pub use crate::arch::ipc::signal::X86_64SignalArch as CurrentSignalArch;
|
||||
pub use crate::arch::time::X86_64TimeArch as CurrentTimeArch;
|
||||
|
||||
pub use crate::arch::ipc::signal::X86SigStack as SigStackArch;
|
||||
|
||||
pub use crate::arch::elf::X86_64ElfArch as CurrentElfArch;
|
||||
|
||||
pub use crate::arch::smp::X86_64SMPArch as CurrentSMPArch;
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ pub struct RamFSInode {
|
|||
self_ref: Weak<LockedRamFSInode>,
|
||||
/// 子Inode的B树
|
||||
children: BTreeMap<DName, Arc<LockedRamFSInode>>,
|
||||
/// 子Syms的B树, 记录符号到符号的链接
|
||||
syms: BTreeMap<DName, DName>,
|
||||
/// 当前inode的数据部分
|
||||
data: Vec<u8>,
|
||||
/// 当前inode的元数据
|
||||
|
|
@ -79,7 +77,6 @@ impl RamFSInode {
|
|||
parent: Weak::default(),
|
||||
self_ref: Weak::default(),
|
||||
children: BTreeMap::new(),
|
||||
syms: BTreeMap::new(),
|
||||
data: Vec::new(),
|
||||
metadata: Metadata {
|
||||
dev_id: 0,
|
||||
|
|
@ -331,7 +328,6 @@ impl IndexNode for LockedRamFSInode {
|
|||
parent: inode.self_ref.clone(),
|
||||
self_ref: Weak::default(),
|
||||
children: BTreeMap::new(),
|
||||
syms: BTreeMap::new(),
|
||||
data: Vec::new(),
|
||||
metadata: Metadata {
|
||||
dev_id: 0,
|
||||
|
|
@ -420,63 +416,6 @@ impl IndexNode for LockedRamFSInode {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
fn symlink(
|
||||
&self,
|
||||
name1: &str,
|
||||
name2: &str,
|
||||
other: &Arc<dyn IndexNode>,
|
||||
) -> Result<(), SystemError> {
|
||||
// TODO: 判断是否指向的other为一个符号链接
|
||||
// 也就是需要判断 test1 -> echo -> busybox 的情况下, other的name是busybox,但是name2是echo
|
||||
let other: &LockedRamFSInode = other
|
||||
.downcast_ref::<LockedRamFSInode>()
|
||||
.ok_or(SystemError::EPERM)?;
|
||||
let name = DName::from(name1);
|
||||
let other_name = DName::from(name2);
|
||||
let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
|
||||
let other_locked: SpinLockGuard<RamFSInode> = other.0.lock();
|
||||
|
||||
// 如果当前inode不是文件夹,那么报错
|
||||
if inode.metadata.file_type != FileType::Dir {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
|
||||
// 如果另一个inode是文件夹,那么也报错
|
||||
if other_locked.metadata.file_type == FileType::Dir {
|
||||
return Err(SystemError::EISDIR);
|
||||
}
|
||||
|
||||
// 如果当前文件夹下已经有同名文件,也报错。
|
||||
if inode.children.contains_key(&name) {
|
||||
return Err(SystemError::EEXIST);
|
||||
}
|
||||
|
||||
// 将子name插入父syms的B树中
|
||||
inode.syms.insert(name.clone(), other_name.clone());
|
||||
|
||||
inode
|
||||
.children
|
||||
.insert(name, other_locked.self_ref.upgrade().unwrap());
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn symunlink(&self, _name: &str) -> Result<(), SystemError> {
|
||||
// 若文件系统没有实现此方法,则返回“不支持”
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
fn get_nextsym(&self, name: &str) -> Result<String, SystemError> {
|
||||
let name = DName::from(name);
|
||||
let inode: SpinLockGuard<RamFSInode> = self.0.lock();
|
||||
|
||||
if let Some(r) = inode.syms.get(&name) {
|
||||
return Ok(r.0.to_string());
|
||||
}
|
||||
|
||||
return Ok(name.to_string());
|
||||
}
|
||||
|
||||
fn rmdir(&self, name: &str) -> Result<(), SystemError> {
|
||||
let name = DName::from(name);
|
||||
let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
|
||||
|
|
@ -661,7 +600,6 @@ impl IndexNode for LockedRamFSInode {
|
|||
parent: inode.self_ref.clone(),
|
||||
self_ref: Weak::default(),
|
||||
children: BTreeMap::new(),
|
||||
syms: BTreeMap::new(),
|
||||
data: Vec::new(),
|
||||
metadata: Metadata {
|
||||
dev_id: 0,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ pub mod syscall;
|
|||
pub mod utils;
|
||||
pub mod vcore;
|
||||
|
||||
use self::utils::rsplit_path;
|
||||
use ::core::{any::Any, fmt::Debug, sync::atomic::AtomicUsize};
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use derive_builder::Builder;
|
||||
|
|
@ -386,46 +385,6 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
|
|||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
/// @brief 在当前目录下,创建一个名为Name的符号链接(软链接),指向另一个IndexNode,支持链接向一个符号链接
|
||||
///
|
||||
/// @param name1 符号链接的名称, 将会在此目录下创建名为name的inode
|
||||
/// @param name1 要被指向的 name 名称, 会根据此name与other的name区分是否指向一个符号链接
|
||||
/// @param other 要被指向的IndexNode的Arc指针
|
||||
///
|
||||
/// @return 成功:Ok(新的inode的Arc指针)
|
||||
/// 失败:Err(错误码)
|
||||
fn symlink(
|
||||
&self,
|
||||
_name1: &str,
|
||||
_name2: &str,
|
||||
_other: &Arc<dyn IndexNode>,
|
||||
) -> Result<(), SystemError> {
|
||||
// 若文件系统没有实现此方法,则返回“不支持”
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
/// @brief 在当前目录下,删除一个名为Name的符号链接(软链接)
|
||||
///
|
||||
/// @param name 符号链接的名称
|
||||
///
|
||||
/// @return 成功:Ok()
|
||||
/// 失败:Err(错误码)
|
||||
fn symunlink(&self, _name: &str) -> Result<(), SystemError> {
|
||||
// 若文件系统没有实现此方法,则返回“不支持”
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
/// @brief 在当前目录下,获取名为Name的符号链接(软链接)的执行的文件名称
|
||||
///
|
||||
/// @param name 符号链接的名称
|
||||
///
|
||||
/// @return 成功:Ok()
|
||||
/// 失败:Err(错误码)
|
||||
fn get_nextsym(&self, _name: &str) -> Result<String, SystemError> {
|
||||
// 若文件系统没有实现此方法,则返回“不支持”
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
/// @brief 删除文件夹
|
||||
///
|
||||
/// @param name 文件夹名称
|
||||
|
|
@ -1334,20 +1293,3 @@ impl<'a> FilldirContext<'a> {
|
|||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
/// 查找链接文件的最底层链接, 目的是解决循环嵌套链接
|
||||
/// 如 test -> echo, echo -> busybox, 需要解析 test 的链接情况
|
||||
/// 返回 name 指向的文件的名称(可能为绝对路径, 具体值为symlink传入的参数值)
|
||||
/// 如果返回其本身(最底层文件名, 经过路径处理后的), 说明此文件不是链接文件
|
||||
#[allow(dead_code)]
|
||||
pub fn get_link_true_file(name: String) -> Result<String, SystemError> {
|
||||
let (filename, parent_path) = rsplit_path(&name);
|
||||
let parent_inode = match parent_path {
|
||||
None => ProcessManager::current_mntns().root_inode(),
|
||||
Some(path) => ProcessManager::current_mntns()
|
||||
.root_inode()
|
||||
.lookup(path)
|
||||
.unwrap(),
|
||||
};
|
||||
parent_inode.get_nextsym(filename)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -709,24 +709,6 @@ impl IndexNode for MountFSInode {
|
|||
return self.inner_inode.unlink(name);
|
||||
}
|
||||
|
||||
fn symlink(
|
||||
&self,
|
||||
name1: &str,
|
||||
name2: &str,
|
||||
other: &Arc<dyn IndexNode>,
|
||||
) -> Result<(), SystemError> {
|
||||
return self.inner_inode.symlink(name1, name2, other);
|
||||
}
|
||||
|
||||
fn symunlink(&self, _name: &str) -> Result<(), SystemError> {
|
||||
// 若文件系统没有实现此方法,则返回“不支持”
|
||||
return Err(SystemError::ENOSYS);
|
||||
}
|
||||
|
||||
fn get_nextsym(&self, name: &str) -> Result<String, SystemError> {
|
||||
return self.inner_inode.get_nextsym(name);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rmdir(&self, name: &str) -> Result<(), SystemError> {
|
||||
let inode_id = self.inner_inode.find(name)?.metadata()?.inode_id;
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ pub trait BootCallbacks: Send + Sync {
|
|||
/// 初始化内存块
|
||||
fn early_init_memory_blocks(&self) -> Result<(), SystemError>;
|
||||
/// 初始化内存 memmap 信息到 sysfs
|
||||
fn early_init_memmap_sysfs(&self) -> Result<(), SystemError>;
|
||||
fn init_memmap_sysfs(&self) -> Result<(), SystemError>;
|
||||
/// 初始化内存 memmap 信息到 boot_params
|
||||
fn init_memmap_bp(&self) -> Result<(), SystemError>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::filesystem::vfs::vcore::change_root_fs;
|
|||
use crate::{
|
||||
arch::{interrupt::TrapFrame, process::arch_switch_to_user},
|
||||
driver::net::e1000e::e1000e::e1000e_init,
|
||||
filesystem::vfs::vcore::mount_root_fs,
|
||||
filesystem::vfs::{vcore::mount_root_fs, VFS_MAX_FOLLOW_SYMLINK_TIMES},
|
||||
net::net_core::net_init,
|
||||
process::{
|
||||
exec::ProcInitInfo, execve::do_execve, kthread::KernelThreadMechanism, stdio::stdio_init,
|
||||
|
|
@ -75,7 +75,7 @@ fn kernel_init() -> Result<(), SystemError> {
|
|||
.inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
|
||||
.ok();
|
||||
|
||||
if super::enable_initramfs() {
|
||||
if super::initramfs_enabled() {
|
||||
// 使用 initramfs, 迁移文件系统
|
||||
#[cfg(feature = "initram")]
|
||||
change_root_fs().expect("Failed to mount root fs");
|
||||
|
|
@ -127,7 +127,7 @@ fn switch_to_user() -> ! {
|
|||
|
||||
let mut trap_frame = TrapFrame::new();
|
||||
|
||||
if super::enable_initramfs() {
|
||||
if super::initramfs_enabled() {
|
||||
// 使用 initramfs, 启动 /init
|
||||
log::info!("Initramfs, Boot with specified init process: /init");
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ fn run_init_process(
|
|||
let path = proc_init_info.proc_name.to_str().unwrap();
|
||||
|
||||
let pwd = ProcessManager::current_pcb().pwd_inode();
|
||||
let inode = pwd.lookup(path)?;
|
||||
let inode = pwd.lookup_follow_symlink(path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||
do_execve(
|
||||
inode,
|
||||
proc_init_info.args.clone(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use alloc::vec::Vec;
|
|||
|
||||
use crate::filesystem::ramfs::RamFS;
|
||||
use crate::filesystem::vfs::mount::MountFlags;
|
||||
use crate::filesystem::vfs::FilePrivateData;
|
||||
use crate::filesystem::vfs::FileSystem;
|
||||
use crate::filesystem::vfs::MountFS;
|
||||
use crate::init::boot::boot_callbacks;
|
||||
|
|
@ -31,49 +32,14 @@ pub fn INIT_ROOT_INODE() -> Arc<dyn IndexNode> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[allow(non_upper_case_globals, unexpected_cfgs)]
|
||||
#[used]
|
||||
pub static INITRAM_DATA: &[u8] = {
|
||||
#[cfg(has_initram_x86)]
|
||||
#[cfg(has_initram)]
|
||||
{
|
||||
include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/initram/x86.cpio.xz"))
|
||||
include_bytes!(env!("INITRAM_PATH"))
|
||||
}
|
||||
#[cfg(not(has_initram_x86))]
|
||||
{
|
||||
&[]
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "riscv64")]
|
||||
#[allow(non_upper_case_globals, unexpected_cfgs)]
|
||||
#[used]
|
||||
pub static INITRAM_DATA: &[u8] = {
|
||||
#[cfg(has_initram_riscv64)]
|
||||
{
|
||||
include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/initram/riscv64.cpio.xz"
|
||||
))
|
||||
}
|
||||
#[cfg(not(has_initram_riscv64))]
|
||||
{
|
||||
&[]
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(target_arch = "loongarch64")]
|
||||
#[allow(non_upper_case_globals, unexpected_cfgs)]
|
||||
#[used]
|
||||
pub static INITRAM_DATA: &[u8] = {
|
||||
#[cfg(has_initram_loongarch64)]
|
||||
{
|
||||
include_bytes!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/initram/loongarch64.cpio.xz"
|
||||
))
|
||||
}
|
||||
#[cfg(not(has_initram_loongarch64))]
|
||||
#[cfg(not(has_initram))]
|
||||
{
|
||||
&[]
|
||||
}
|
||||
|
|
@ -154,7 +120,7 @@ pub fn initramfs_init() -> Result<(), SystemError> {
|
|||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
let cpio_data = xz_decompress(get_initram()).unwrap();
|
||||
let cpio_data = xz_decompress(get_initram())?;
|
||||
|
||||
let collected_entries_vec = cpio_reader::iter_files(&cpio_data)
|
||||
.map(|entry| CpioEntryInfo {
|
||||
|
|
@ -180,7 +146,10 @@ pub fn initramfs_init() -> Result<(), SystemError> {
|
|||
for (index, entry) in collected_entries_vec.iter().enumerate() {
|
||||
// x86 的有 4 种文件:Dir, File, CharDevice, SymLink
|
||||
let name = entry.name.clone();
|
||||
let mode = ModeType::from_bits(entry.mode.bits()).unwrap();
|
||||
let mode = ModeType::from_bits(entry.mode.bits()).ok_or_else(|| {
|
||||
log::error!("initramfs: failed to get mode!");
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
let file_type = FileType::from(mode);
|
||||
log::info!(
|
||||
"Find cpio entry, Name:{}, ModeType:{:?}, FileType:{:?}",
|
||||
|
|
@ -191,24 +160,22 @@ pub fn initramfs_init() -> Result<(), SystemError> {
|
|||
let (filename, parent_path) = rsplit_path(&name);
|
||||
let parent_inode = match parent_path {
|
||||
None => INIT_ROOT_INODE(),
|
||||
Some(path) => INIT_ROOT_INODE().lookup(path).unwrap(),
|
||||
Some(path) => INIT_ROOT_INODE().lookup(path)?,
|
||||
};
|
||||
match file_type {
|
||||
FileType::Dir => {
|
||||
// 直接插入, 无需处理数据
|
||||
parent_inode.create(filename, file_type, mode).unwrap();
|
||||
parent_inode.create(filename, file_type, mode)?;
|
||||
}
|
||||
FileType::File => {
|
||||
// 插入, 随后写入文件数据
|
||||
let inode = parent_inode.create(filename, file_type, mode).unwrap();
|
||||
inode
|
||||
.write_at(
|
||||
0,
|
||||
entry.file.len(),
|
||||
&entry.file,
|
||||
SpinLock::new(crate::filesystem::vfs::FilePrivateData::Unused).lock(),
|
||||
)
|
||||
.unwrap();
|
||||
let inode = parent_inode.create(filename, file_type, mode)?;
|
||||
inode.write_at(
|
||||
0,
|
||||
entry.file.len(),
|
||||
&entry.file,
|
||||
SpinLock::new(crate::filesystem::vfs::FilePrivateData::Unused).lock(),
|
||||
)?;
|
||||
}
|
||||
FileType::CharDevice => {
|
||||
// 不处理, 如果使用 initramfs 那么直接从已经初始化好的根文件系统迁移到此文件系统
|
||||
|
|
@ -223,20 +190,28 @@ pub fn initramfs_init() -> Result<(), SystemError> {
|
|||
};
|
||||
}
|
||||
|
||||
// 处理链接文件
|
||||
// TODO: 正常来说必须使用软链接(符号链接), 但是现在内核没有实现软链接
|
||||
// 这里使用硬链接在一层符号嵌套访问上不会出问题, 但是执行多层符号嵌套会出问题, 这个使用了一个小暂时的方法
|
||||
// 处理链接文件, 使用符号链接
|
||||
for i in 0..links.len() {
|
||||
let entry = &collected_entries_vec[links[i]];
|
||||
let name = entry.name.clone();
|
||||
let (filename, parent_path) = rsplit_path(&name);
|
||||
let parent_inode = match parent_path {
|
||||
None => INIT_ROOT_INODE(),
|
||||
Some(path) => INIT_ROOT_INODE().lookup(path).unwrap(),
|
||||
Some(path) => INIT_ROOT_INODE().lookup(path)?,
|
||||
};
|
||||
let other_name = String::from_utf8(entry.file.clone()).unwrap();
|
||||
let other = parent_inode.lookup(&other_name).unwrap();
|
||||
parent_inode.symlink(filename, &other_name, &other).unwrap();
|
||||
let other_name = String::from_utf8(entry.file.clone()).map_err(|err| {
|
||||
log::error!("initramfs: failed to get utf8_name, err is {}", err);
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
let new_inode = parent_inode.create_with_data(
|
||||
filename,
|
||||
FileType::SymLink,
|
||||
ModeType::from_bits_truncate(0o777),
|
||||
0,
|
||||
)?;
|
||||
let buf = other_name.as_bytes();
|
||||
let len = buf.len();
|
||||
new_inode.write_at(0, len, buf, SpinLock::new(FilePrivateData::Unused).lock())?;
|
||||
}
|
||||
|
||||
// 下面的方式是查看外置 initramfs, 例如使用 qemu 的 -initrd 参数加载的
|
||||
|
|
|
|||
|
|
@ -32,20 +32,18 @@ pub fn do_kexec_load(
|
|||
return Ok(0);
|
||||
}
|
||||
|
||||
let image = kimage_alloc_init(entry, nr_segments, ksegments, flags).unwrap();
|
||||
let image = kimage_alloc_init(entry, nr_segments, ksegments, flags)?;
|
||||
|
||||
// load segment 的解析: https://zhuanlan.zhihu.com/p/105284305
|
||||
for i in 0..nr_segments {
|
||||
kimage_load_normal_segment(image.clone(), i);
|
||||
kimage_load_normal_segment(image.clone(), i)?;
|
||||
}
|
||||
|
||||
kimage_terminate(image.clone());
|
||||
|
||||
KexecArch::init_pgtable(image.clone());
|
||||
KexecArch::init_pgtable(image.clone())?;
|
||||
|
||||
if !KexecArch::machine_kexec_prepare(image.clone()) {
|
||||
return Err(SystemError::EADV);
|
||||
}
|
||||
KexecArch::machine_kexec_prepare(image.clone())?;
|
||||
|
||||
unsafe {
|
||||
KEXEC_IMAGE = Some(image.clone());
|
||||
|
|
@ -91,10 +89,10 @@ pub fn kimage_alloc_init(
|
|||
|
||||
image.lock().segment[..ksegments.len()].copy_from_slice(ksegments);
|
||||
|
||||
let temp_c = kimage_alloc_pages(image.clone(), 0, false);
|
||||
let temp_c = kimage_alloc_pages(image.clone(), 0, false)?;
|
||||
image.lock().control_code_page = temp_c.clone();
|
||||
|
||||
let temp_st = kimage_alloc_pages(image.clone(), 0, true);
|
||||
let temp_st = kimage_alloc_pages(image.clone(), 0, true)?;
|
||||
image.lock().stack_page = temp_st.clone();
|
||||
|
||||
Ok(image)
|
||||
|
|
@ -104,7 +102,7 @@ pub fn kimage_alloc_pages(
|
|||
kimage: Rc<SpinLock<Kimage>>,
|
||||
order: usize,
|
||||
store: bool,
|
||||
) -> Option<Arc<Page>> {
|
||||
) -> Result<Option<Arc<Page>>, SystemError> {
|
||||
let mut _page = None;
|
||||
let mut extra_pages: Vec<Arc<Page>> = Vec::new();
|
||||
let mut alloc = page_manager_lock_irqsave();
|
||||
|
|
@ -113,13 +111,11 @@ pub fn kimage_alloc_pages(
|
|||
|
||||
// 目前只分配一个页面, 后面改成多个, 使用 order 控制
|
||||
loop {
|
||||
let p = alloc
|
||||
.create_one_page(
|
||||
PageType::Normal,
|
||||
PageFlags::PG_RESERVED | PageFlags::PG_PRIVATE,
|
||||
&mut LockedFrameAllocator,
|
||||
)
|
||||
.unwrap();
|
||||
let p = alloc.create_one_page(
|
||||
PageType::Normal,
|
||||
PageFlags::PG_RESERVED | PageFlags::PG_PRIVATE,
|
||||
&mut LockedFrameAllocator,
|
||||
)?;
|
||||
|
||||
if check_isdst(kimage.clone(), p.clone()) {
|
||||
extra_pages.push(p);
|
||||
|
|
@ -136,7 +132,7 @@ pub fn kimage_alloc_pages(
|
|||
alloc.remove_page(&p.phys_address());
|
||||
}
|
||||
|
||||
_page
|
||||
Ok(_page)
|
||||
}
|
||||
|
||||
pub fn check_isdst(kimage: Rc<SpinLock<Kimage>>, page: Arc<Page>) -> bool {
|
||||
|
|
@ -170,7 +166,10 @@ pub fn kernel_kexec() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn kimage_add_entry(kimage: Rc<SpinLock<Kimage>>, entry: KimageEntry) {
|
||||
pub fn kimage_add_entry(
|
||||
kimage: Rc<SpinLock<Kimage>>,
|
||||
entry: KimageEntry,
|
||||
) -> Result<(), SystemError> {
|
||||
unsafe {
|
||||
if *kimage.lock().entry != 0 {
|
||||
let t = kimage.lock().entry.add(1);
|
||||
|
|
@ -180,7 +179,7 @@ pub fn kimage_add_entry(kimage: Rc<SpinLock<Kimage>>, entry: KimageEntry) {
|
|||
let k_entry = kimage.lock().entry;
|
||||
let k_last_entry = kimage.lock().last_entry;
|
||||
if k_entry == k_last_entry {
|
||||
let page = kimage_alloc_pages(kimage.clone(), 0, true).unwrap();
|
||||
let page = kimage_alloc_pages(kimage.clone(), 0, true)?.unwrap();
|
||||
|
||||
let ind_page =
|
||||
MMArch::phys_2_virt(page.phys_address()).unwrap().data() as *mut KimageEntry;
|
||||
|
|
@ -198,19 +197,26 @@ pub fn kimage_add_entry(kimage: Rc<SpinLock<Kimage>>, entry: KimageEntry) {
|
|||
kimage.lock().entry = t;
|
||||
*kimage.lock().entry = 0;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn kimage_set_destination(kimage: Rc<SpinLock<Kimage>>, destination: usize) {
|
||||
pub fn kimage_set_destination(
|
||||
kimage: Rc<SpinLock<Kimage>>,
|
||||
destination: usize,
|
||||
) -> Result<(), SystemError> {
|
||||
let d = destination & MMArch::PAGE_MASK;
|
||||
kimage_add_entry(kimage.clone(), d | IND_DESTINATION);
|
||||
kimage_add_entry(kimage.clone(), d | IND_DESTINATION)
|
||||
}
|
||||
|
||||
pub fn kimage_add_page(kimage: Rc<SpinLock<Kimage>>, page: usize) {
|
||||
pub fn kimage_add_page(kimage: Rc<SpinLock<Kimage>>, page: usize) -> Result<(), SystemError> {
|
||||
let p = page & MMArch::PAGE_MASK;
|
||||
kimage_add_entry(kimage.clone(), p | IND_SOURCE);
|
||||
kimage_add_entry(kimage.clone(), p | IND_SOURCE)
|
||||
}
|
||||
|
||||
pub fn kimage_load_normal_segment(kimage: Rc<SpinLock<Kimage>>, index: usize) {
|
||||
pub fn kimage_load_normal_segment(
|
||||
kimage: Rc<SpinLock<Kimage>>,
|
||||
index: usize,
|
||||
) -> Result<(), SystemError> {
|
||||
let segment = kimage.lock().segment[index];
|
||||
|
||||
let mut maddr = segment.mem;
|
||||
|
|
@ -218,11 +224,11 @@ pub fn kimage_load_normal_segment(kimage: Rc<SpinLock<Kimage>>, index: usize) {
|
|||
let mut buf = unsafe { segment.buffer.buf } as *mut u8;
|
||||
let mut ubytes = segment.bufsz;
|
||||
|
||||
kimage_set_destination(kimage.clone(), maddr);
|
||||
kimage_set_destination(kimage.clone(), maddr)?;
|
||||
|
||||
loop {
|
||||
let page = kimage_alloc_pages(kimage.clone(), 0, true).unwrap();
|
||||
kimage_add_page(kimage.clone(), page.phys_address().data());
|
||||
let page = (kimage_alloc_pages(kimage.clone(), 0, true)?).unwrap();
|
||||
kimage_add_page(kimage.clone(), page.phys_address().data())?;
|
||||
|
||||
let mut virt_data = unsafe { MMArch::phys_2_virt(page.phys_address()).unwrap().data() };
|
||||
virt_data += maddr & !(MMArch::PAGE_MASK);
|
||||
|
|
@ -233,8 +239,8 @@ pub fn kimage_load_normal_segment(kimage: Rc<SpinLock<Kimage>>, index: usize) {
|
|||
let uchunk = min(ubytes, mchunk);
|
||||
|
||||
if uchunk != 0 {
|
||||
let usegments_buf = UserBufferReader::new::<u8>(buf, uchunk, true).unwrap();
|
||||
let ksegment: &[u8] = usegments_buf.read_from_user(0).unwrap();
|
||||
let usegments_buf = UserBufferReader::new::<u8>(buf, uchunk, true)?;
|
||||
let ksegment: &[u8] = usegments_buf.read_from_user(0)?;
|
||||
unsafe { core::ptr::copy(ksegment.as_ptr(), virt_data as *mut u8, uchunk) };
|
||||
|
||||
ubytes -= uchunk;
|
||||
|
|
@ -245,7 +251,7 @@ pub fn kimage_load_normal_segment(kimage: Rc<SpinLock<Kimage>>, index: usize) {
|
|||
mbytes -= mchunk as isize;
|
||||
|
||||
if mbytes <= 0 {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ fn init_intertrait() {
|
|||
intertrait::init_caster_map();
|
||||
}
|
||||
|
||||
pub fn enable_initramfs() -> bool {
|
||||
pub fn initramfs_enabled() -> bool {
|
||||
#[cfg(feature = "initram")]
|
||||
unsafe {
|
||||
self::initram::__INIT_ROOT_ENABLED
|
||||
|
|
|
|||
|
|
@ -587,31 +587,6 @@ impl SigPending {
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief 信号处理备用栈的信息
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SigStack {
|
||||
pub sp: usize,
|
||||
pub flags: u32,
|
||||
pub size: u32,
|
||||
}
|
||||
|
||||
impl SigStack {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
sp: 0,
|
||||
flags: 0,
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SigStack {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 进程接收到的信号的队列
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SigQueue {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl Syscall for SysPidfdSendSignalHandle {
|
|||
.fd_table()
|
||||
.read()
|
||||
.get_file_by_fd(pidfd)
|
||||
.unwrap();
|
||||
.ok_or(SystemError::EBADF)?;
|
||||
if file.private_data.lock().is_pid() {
|
||||
pid = file.private_data.lock().get_pid();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,10 @@ pub fn xz_decompress(compressed_data: &[u8]) -> Result<Vec<u8>, SystemError> {
|
|||
decompressed_data.extend_from_slice(&temp_buffer[..output_produced]);
|
||||
break;
|
||||
}
|
||||
Err(err) => panic!("Decompression failed {}", err),
|
||||
Err(err) => {
|
||||
log::error!("Decompression failed {}", err);
|
||||
return Err(SystemError::E2BIG);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::mm::{
|
|||
use core::marker::PhantomData;
|
||||
use core::sync::atomic::compiler_fence;
|
||||
use core::sync::atomic::Ordering;
|
||||
use system_error::SystemError;
|
||||
|
||||
/// 恒等页表映射器( paddr == vaddr )
|
||||
#[derive(Hash)]
|
||||
|
|
@ -55,7 +56,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> IdentPageMapper<Arch, F> {
|
|||
virt: VirtAddr,
|
||||
phys: PhysAddr,
|
||||
mut allocator: F,
|
||||
) -> Option<PageFlush<Arch>> {
|
||||
) -> Result<Option<PageFlush<Arch>>, SystemError> {
|
||||
// 验证虚拟地址和物理地址是否对齐
|
||||
if !(virt.check_aligned(Arch::PAGE_SIZE) && phys.check_aligned(Arch::PAGE_SIZE)) {
|
||||
log::error!(
|
||||
|
|
@ -63,7 +64,7 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> IdentPageMapper<Arch, F> {
|
|||
virt,
|
||||
phys
|
||||
);
|
||||
return None;
|
||||
return Err(SystemError::EFAULT);
|
||||
}
|
||||
|
||||
let virt = VirtAddr::new(virt.data() & (!Arch::PAGE_NEGATIVE_MASK));
|
||||
|
|
@ -80,7 +81,10 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> IdentPageMapper<Arch, F> {
|
|||
let entry = PageEntry::new(phys, flags);
|
||||
let mut table = PageTable::new(VirtAddr::new(0), table_paddr, Arch::PAGE_LEVELS - 1);
|
||||
loop {
|
||||
let i = table.index_of(virt).unwrap();
|
||||
let i = table.index_of(virt).ok_or_else(|| {
|
||||
log::error!("ident_mapper, map_phys: failed to get index of addr!");
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
|
||||
assert!(i < Arch::PAGE_ENTRY_NUM);
|
||||
if table.level() == 0 {
|
||||
|
|
@ -88,14 +92,17 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> IdentPageMapper<Arch, F> {
|
|||
|
||||
table.set_entry(i, entry);
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
return Some(PageFlush::new(virt));
|
||||
return Ok(Some(PageFlush::new(virt)));
|
||||
} else {
|
||||
let next_table = table.next_level_table(i);
|
||||
if let Some(next_table) = next_table {
|
||||
table = next_table;
|
||||
} else {
|
||||
// 分配下一级页表
|
||||
let frame = allocator.allocate_one().unwrap();
|
||||
let frame = allocator.allocate_one().ok_or_else(|| {
|
||||
log::error!("ident_mapper, map_phys: allocate table failed");
|
||||
SystemError::ENOMEM
|
||||
})?;
|
||||
|
||||
// 清空这个页帧
|
||||
MMArch::write_bytes(MMArch::phys_2_virt(frame).unwrap(), 0, MMArch::PAGE_SIZE);
|
||||
|
|
@ -106,7 +113,10 @@ impl<Arch: MemoryManagementArch, F: FrameAllocator> IdentPageMapper<Arch, F> {
|
|||
table.set_entry(i, PageEntry::new(frame, flags));
|
||||
|
||||
// 获取新分配的页表
|
||||
table = table.next_level_table(i).unwrap();
|
||||
table = table.next_level_table(i).ok_or_else(|| {
|
||||
log::error!("ident_mapper, map_phys: get next_level_table failed");
|
||||
SystemError::EPERM
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -119,21 +129,27 @@ pub fn ident_pt_alloc() -> usize {
|
|||
new_imapper.paddr().data()
|
||||
}
|
||||
|
||||
pub fn ident_map_page(table_paddr: usize, virt: usize, phys: usize) {
|
||||
pub fn ident_map_page(table_paddr: usize, virt: usize, phys: usize) -> Result<(), SystemError> {
|
||||
unsafe {
|
||||
IdentPageMapper::<MMArch, LockedFrameAllocator>::map_phys(
|
||||
PhysAddr::new(table_paddr),
|
||||
VirtAddr::new(virt),
|
||||
PhysAddr::new(phys),
|
||||
LockedFrameAllocator,
|
||||
)
|
||||
)?
|
||||
.unwrap()
|
||||
.flush();
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 需要对齐
|
||||
pub fn ident_map_pages(table_paddr: usize, virt: usize, phys: usize, nums: usize) {
|
||||
pub fn ident_map_pages(
|
||||
table_paddr: usize,
|
||||
virt: usize,
|
||||
phys: usize,
|
||||
nums: usize,
|
||||
) -> Result<(), SystemError> {
|
||||
for i in 0..nums {
|
||||
let virt = virt + i * MMArch::PAGE_SIZE;
|
||||
let phys = phys + i * MMArch::PAGE_SIZE;
|
||||
|
|
@ -143,9 +159,10 @@ pub fn ident_map_pages(table_paddr: usize, virt: usize, phys: usize, nums: usize
|
|||
VirtAddr::new(virt),
|
||||
PhysAddr::new(phys),
|
||||
LockedFrameAllocator,
|
||||
)
|
||||
)?
|
||||
.unwrap()
|
||||
.flush()
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ fn memmap_sysfs_init() -> Result<(), SystemError> {
|
|||
.init_memmap_bp()
|
||||
.expect("init bp memmap failed");
|
||||
boot_callbacks()
|
||||
.early_init_memmap_sysfs()
|
||||
.init_memmap_sysfs()
|
||||
.expect("init sysfs memmap failed");
|
||||
|
||||
let memmap_kobj = CommonKobj::new("memmap".to_string());
|
||||
|
|
|
|||
|
|
@ -444,10 +444,9 @@ impl ProcessManager {
|
|||
ProcessManager::current_pcb().raw_pid().data(),
|
||||
pid
|
||||
);
|
||||
let new_inode = root_inode
|
||||
.create(&name, FileType::File, ModeType::from_bits_truncate(0o777))
|
||||
.unwrap();
|
||||
let file = File::new(new_inode, FileMode::O_RDWR | FileMode::O_CLOEXEC).unwrap();
|
||||
let new_inode =
|
||||
root_inode.create(&name, FileType::File, ModeType::from_bits_truncate(0o777))?;
|
||||
let file = File::new(new_inode, FileMode::O_RDWR | FileMode::O_CLOEXEC)?;
|
||||
{
|
||||
let mut guard = file.private_data.lock();
|
||||
*guard = FilePrivateData::Pid(PidPrivateData::new(pid));
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use crate::{
|
|||
cpu::current_cpu_id,
|
||||
ipc::signal::{AtomicSignal, SigSet, Signal},
|
||||
process::ArchPCBInfo,
|
||||
CurrentIrqArch,
|
||||
CurrentIrqArch, SigStackArch,
|
||||
},
|
||||
driver::tty::tty_core::TtyCore,
|
||||
exception::InterruptArch,
|
||||
|
|
@ -36,7 +36,7 @@ use crate::{
|
|||
ipc::{
|
||||
sighand::SigHand,
|
||||
signal::RestartBlock,
|
||||
signal_types::{SigInfo, SigPending, SigStack},
|
||||
signal_types::{SigInfo, SigPending},
|
||||
},
|
||||
libs::{
|
||||
align::AlignedBox,
|
||||
|
|
@ -757,7 +757,7 @@ pub struct ProcessControlBlock {
|
|||
sig_info: RwLock<ProcessSignalInfo>,
|
||||
sighand: RwLock<Arc<SigHand>>,
|
||||
/// 备用信号栈
|
||||
sig_altstack: RwLock<SigStack>,
|
||||
sig_altstack: RwLock<SigStackArch>,
|
||||
|
||||
/// 退出信号S
|
||||
exit_signal: AtomicSignal,
|
||||
|
|
@ -900,7 +900,7 @@ impl ProcessControlBlock {
|
|||
arch_info,
|
||||
sig_info: RwLock::new(ProcessSignalInfo::default()),
|
||||
sighand: RwLock::new(SigHand::new()),
|
||||
sig_altstack: RwLock::new(SigStack::new()),
|
||||
sig_altstack: RwLock::new(SigStackArch::new()),
|
||||
exit_signal: AtomicSignal::new(Signal::SIGCHLD),
|
||||
parent_pcb: RwLock::new(ppcb.clone()),
|
||||
real_parent_pcb: RwLock::new(ppcb),
|
||||
|
|
@ -1161,11 +1161,11 @@ impl ProcessControlBlock {
|
|||
return &self.sched_info;
|
||||
}
|
||||
|
||||
pub fn sig_altstack(&self) -> RwLockReadGuard<'_, SigStack> {
|
||||
pub fn sig_altstack(&self) -> RwLockReadGuard<'_, SigStackArch> {
|
||||
self.sig_altstack.read_irqsave()
|
||||
}
|
||||
|
||||
pub fn sig_altstack_mut(&self) -> RwLockWriteGuard<'_, SigStack> {
|
||||
pub fn sig_altstack_mut(&self) -> RwLockWriteGuard<'_, SigStackArch> {
|
||||
self.sig_altstack.write_irqsave()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use alloc::sync::Arc;
|
|||
|
||||
use crate::arch::interrupt::TrapFrame;
|
||||
use crate::arch::syscall::nr::SYS_EXECVE;
|
||||
use crate::filesystem::vfs::{IndexNode, MAX_PATHLEN};
|
||||
use crate::filesystem::vfs::{IndexNode, MAX_PATHLEN, VFS_MAX_FOLLOW_SYMLINK_TIMES};
|
||||
use crate::mm::page::PAGE_4K_SIZE;
|
||||
use crate::mm::{verify_area, VirtAddr};
|
||||
use crate::process::execve::do_execve;
|
||||
|
|
@ -61,20 +61,19 @@ impl SysExecve {
|
|||
envp: *const *const u8,
|
||||
) -> Result<(CString, Vec<CString>, Vec<CString>), SystemError> {
|
||||
let path: CString = check_and_clone_cstr(path, Some(MAX_PATHLEN))?;
|
||||
#[cfg(not(feature = "initram"))]
|
||||
let argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
|
||||
#[cfg(feature = "initram")]
|
||||
let mut argv: Vec<CString> = check_and_clone_cstr_array(argv)?;
|
||||
let envp: Vec<CString> = check_and_clone_cstr_array(envp)?;
|
||||
|
||||
// 这里需要处理符号链接, 目前内核没有完整实现, 这里是个简易的替代
|
||||
// 例如执行/bin/echo, 必须拿到echo这个名字, 目前内核只有硬链接, 会执行/bin/busybox, 导致无法识别命令
|
||||
#[cfg(feature = "initram")]
|
||||
{
|
||||
let real =
|
||||
crate::filesystem::vfs::get_link_true_file(argv[0].to_string_lossy().to_string())
|
||||
.unwrap();
|
||||
argv[0] = CString::new(real).unwrap();
|
||||
// 这里需要处理符号链接, 应用程序一般不支持嵌套符号链接
|
||||
// 如 test -> echo -> busybox, 需要内核代为解析到 echo, 传入 test 则不会让程序执行 echo 命令
|
||||
let root = ProcessManager::current_mntns().root_inode();
|
||||
if let Ok(real_inode) = root.lookup_follow_symlink2(
|
||||
argv[0].to_string_lossy().as_ref(),
|
||||
VFS_MAX_FOLLOW_SYMLINK_TIMES,
|
||||
false,
|
||||
) {
|
||||
let real_path = real_inode.absolute_path()?;
|
||||
argv[0] = CString::new(real_path).unwrap();
|
||||
}
|
||||
|
||||
Ok((path, argv, envp))
|
||||
|
|
@ -127,7 +126,7 @@ impl Syscall for SysExecve {
|
|||
let path = path.into_string().map_err(|_| SystemError::EINVAL)?;
|
||||
|
||||
let pwd = ProcessManager::current_pcb().pwd_inode();
|
||||
let inode = pwd.lookup(&path)?;
|
||||
let inode = pwd.lookup_follow_symlink(&path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
|
||||
|
||||
Self::execve(inode, path, argv, envp, frame)?;
|
||||
return Ok(0);
|
||||
|
|
|
|||
|
|
@ -37,9 +37,15 @@ impl Syscall for SysPidFdOpen {
|
|||
let pid = Self::pid(args);
|
||||
let flags = Self::flags(args);
|
||||
|
||||
let mode = ModeType::from_bits(flags).unwrap();
|
||||
let mode = ModeType::from_bits(flags).ok_or_else(|| {
|
||||
log::error!("SysPidFdOpen: failed to get mode!");
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
let file_type = FileType::from(mode);
|
||||
let file_mode = FileMode::from_bits(flags).unwrap();
|
||||
let file_mode = FileMode::from_bits(flags).ok_or_else(|| {
|
||||
log::error!("SysPidFdOpen: failed to get file_mode!");
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
|
||||
let root_inode = ProcessManager::current_mntns().root_inode();
|
||||
let name = format!(
|
||||
|
|
@ -47,20 +53,19 @@ impl Syscall for SysPidFdOpen {
|
|||
ProcessManager::current_pcb().raw_pid().data(),
|
||||
pid
|
||||
);
|
||||
let new_inode = root_inode.create(&name, file_type, mode).unwrap();
|
||||
let file = File::new(new_inode, file_mode).unwrap();
|
||||
let new_inode = root_inode.create(&name, file_type, mode)?;
|
||||
let file = File::new(new_inode, file_mode)?;
|
||||
{
|
||||
let mut guard = file.private_data.lock();
|
||||
*guard = FilePrivateData::Pid(PidPrivateData::new(pid));
|
||||
}
|
||||
|
||||
// 存入pcb
|
||||
let r = ProcessManager::current_pcb()
|
||||
ProcessManager::current_pcb()
|
||||
.fd_table()
|
||||
.write()
|
||||
.alloc_fd(file, None)
|
||||
.map(|fd| fd as usize);
|
||||
r
|
||||
.map(|fd| fd as usize)
|
||||
}
|
||||
|
||||
fn entry_format(&self, args: &[usize]) -> Vec<FormattedSyscallParam> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue