From 4fda81ce81939d83b74c8042d6fb4223deff3685 Mon Sep 17 00:00:00 2001 From: LoGin Date: Sat, 25 Nov 2023 12:07:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E5=BE=97DragonOS=20kernel=20=E8=83=BD?= =?UTF-8?q?=E4=B8=BAriscv64=E7=BC=96=E8=AF=91=E9=80=9A=E8=BF=87(=E5=B0=9A?= =?UTF-8?q?=E6=9C=AA=E8=83=BD=E5=90=AF=E5=8A=A8)=20(#457)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 使得DragonOS kernel 能为riscv64编译通过(尚未能启动) * 修正了系统调用号声明不正确的问题,同时添加了编译配置文档 --- .vscode/settings.json | 9 +- Makefile | 37 +- .../kernel_build/src/bindgen/arch/mod.rs | 2 + .../kernel_build/src/bindgen/arch/riscv64.rs | 10 + .../kernel_build/src/cfiles/arch/mod.rs | 2 + .../kernel_build/src/cfiles/arch/riscv64.rs | 41 ++ .../kernel_build/src/cfiles/arch/x86_64.rs | 1 + build-scripts/kernel_build/src/cfiles/mod.rs | 4 +- .../kernel_build/src/constant/mod.rs | 1 + docs/index.rst | 2 +- docs/kernel/configuration/arch.md | 31 ++ docs/kernel/configuration/index.rst | 1 + env.mk | 48 +++ kernel/.cargo/config.toml | 9 +- kernel/Cargo.toml | 9 +- kernel/Makefile | 31 +- kernel/src/Makefile | 68 +++- kernel/src/arch/arch.h | 8 + kernel/src/arch/mod.rs | 14 +- kernel/src/arch/riscv64/asm/bitops.rs | 9 + kernel/src/arch/riscv64/asm/irqflags.h | 20 + kernel/src/arch/riscv64/asm/mod.rs | 1 + kernel/src/arch/riscv64/asm/spinlock.c | 35 ++ kernel/src/arch/riscv64/boot/bootscript.cmd | 2 + kernel/src/arch/riscv64/boot/head.S | 9 + kernel/src/arch/riscv64/cpu.rs | 10 + kernel/src/arch/riscv64/include/asm/asm.h | 68 ++++ .../src/arch/riscv64/include/asm/irqflags.h | 14 + kernel/src/arch/riscv64/interrupt/ipi.rs | 6 + kernel/src/arch/riscv64/interrupt/mod.rs | 41 ++ kernel/src/arch/riscv64/ipc/mod.rs | 1 + kernel/src/arch/riscv64/ipc/signal.rs | 342 +++++++++++++++++ kernel/src/arch/riscv64/kvm/mod.rs | 22 ++ kernel/src/arch/riscv64/link.ld | 97 +++++ kernel/src/arch/riscv64/mm/bump.rs | 8 + kernel/src/arch/riscv64/mm/mod.rs | 109 ++++++ kernel/src/arch/riscv64/mod.rs | 21 ++ kernel/src/arch/riscv64/msi.rs | 16 + kernel/src/arch/riscv64/pci/mod.rs | 23 ++ kernel/src/arch/riscv64/pio.rs | 35 ++ kernel/src/arch/riscv64/process/kthread.rs | 39 ++ kernel/src/arch/riscv64/process/mod.rs | 77 ++++ kernel/src/arch/riscv64/process/syscall.rs | 22 ++ kernel/src/arch/riscv64/rand.rs | 3 + kernel/src/arch/riscv64/sched.rs | 5 + kernel/src/arch/riscv64/syscall/mod.rs | 18 + kernel/src/arch/riscv64/syscall/nr.rs | 306 +++++++++++++++ kernel/src/arch/riscv64/time.rs | 8 + kernel/src/arch/x86_64/cpu.rs | 2 +- kernel/src/arch/x86_64/driver/apic/apic.h | 44 ++- kernel/src/arch/x86_64/include/asm/asm.h | 65 ++-- kernel/src/{ => arch/x86_64}/link.lds | 0 kernel/src/arch/x86_64/mm/c_adapter.rs | 7 + kernel/src/arch/x86_64/mm/mod.rs | 62 ++- kernel/src/arch/x86_64/msi.rs | 8 +- kernel/src/arch/x86_64/process/c_adapter.rs | 7 + kernel/src/arch/x86_64/process/mod.rs | 5 +- kernel/src/arch/x86_64/rand.rs | 33 -- .../x86_64/{syscall.rs => syscall/mod.rs} | 41 +- kernel/src/arch/x86_64/syscall/nr.rs | 357 ++++++++++++++++++ kernel/src/common/asm.h | 5 - kernel/src/common/atomic.h | 3 + kernel/src/common/idr.h | 8 +- kernel/src/common/math.h | 3 + kernel/src/common/stddef.h | 10 +- kernel/src/common/string.h | 27 +- kernel/src/driver/disk/ahci/ahcidisk.rs | 16 +- kernel/src/driver/pci/pci_irq.c | 2 +- kernel/src/driver/pci/pci_irq.rs | 10 +- kernel/src/driver/timers/rtc/rtc.rs | 9 +- kernel/src/exception/gate.h | 48 ++- kernel/src/exception/irq.c | 24 +- kernel/src/exception/trap.c | 8 +- kernel/src/filesystem/procfs/mod.rs | 3 +- kernel/src/filesystem/vfs/file.rs | 22 +- kernel/src/filesystem/vfs/syscall.rs | 22 +- kernel/src/include/DragonOS/refcount.h | 7 +- kernel/src/include/bindings/wrapper.h | 1 + kernel/src/ktest/test-idr.c | 8 +- kernel/src/lib.rs | 6 +- kernel/src/libs/atomic.rs | 26 -- kernel/src/libs/cpu.c | 7 + kernel/src/libs/elf.rs | 43 ++- kernel/src/libs/idr.c | 6 +- kernel/src/libs/lock_free_flags.rs | 8 +- kernel/src/libs/lockref.c | 6 + kernel/src/libs/lz4.c | 7 +- kernel/src/libs/mod.rs | 1 - kernel/src/libs/rwlock.rs | 4 +- kernel/src/libs/string.c | 54 +-- kernel/src/mm/c_adapter.rs | 7 - kernel/src/mm/mm.h | 3 + kernel/src/mm/mmio_buddy.rs | 2 +- kernel/src/mm/ucontext.rs | 1 + kernel/src/net/syscall.rs | 35 +- kernel/src/process/c_adapter.rs | 23 +- kernel/src/process/fork.rs | 6 +- kernel/src/process/idle.rs | 7 +- kernel/src/process/kthread.rs | 6 +- kernel/src/process/mod.rs | 33 +- kernel/src/process/syscall.rs | 8 +- kernel/src/sched/syscall.rs | 2 +- kernel/src/smp/ipi.h | 31 +- kernel/src/smp/smp.c | 9 +- kernel/src/syscall/misc.rs | 34 +- kernel/src/syscall/mod.rs | 195 +++------- kernel/src/syscall/syscall.c | 14 + kernel/src/time/sleep.rs | 14 +- kernel/src/virt/kvm/vm.rs | 7 +- tools/.gdbinit | 2 +- tools/bootstrap.sh | 22 +- tools/run-qemu.sh | 11 +- 112 files changed, 2587 insertions(+), 615 deletions(-) create mode 100644 build-scripts/kernel_build/src/bindgen/arch/riscv64.rs create mode 100644 build-scripts/kernel_build/src/cfiles/arch/riscv64.rs create mode 100644 docs/kernel/configuration/arch.md create mode 100644 env.mk create mode 100644 kernel/src/arch/riscv64/asm/bitops.rs create mode 100644 kernel/src/arch/riscv64/asm/irqflags.h create mode 100644 kernel/src/arch/riscv64/asm/mod.rs create mode 100644 kernel/src/arch/riscv64/asm/spinlock.c create mode 100644 kernel/src/arch/riscv64/boot/bootscript.cmd create mode 100644 kernel/src/arch/riscv64/boot/head.S create mode 100644 kernel/src/arch/riscv64/cpu.rs create mode 100644 kernel/src/arch/riscv64/include/asm/asm.h create mode 100644 kernel/src/arch/riscv64/include/asm/irqflags.h create mode 100644 kernel/src/arch/riscv64/interrupt/ipi.rs create mode 100644 kernel/src/arch/riscv64/interrupt/mod.rs create mode 100644 kernel/src/arch/riscv64/ipc/mod.rs create mode 100644 kernel/src/arch/riscv64/ipc/signal.rs create mode 100644 kernel/src/arch/riscv64/kvm/mod.rs create mode 100644 kernel/src/arch/riscv64/link.ld create mode 100644 kernel/src/arch/riscv64/mm/bump.rs create mode 100644 kernel/src/arch/riscv64/mm/mod.rs create mode 100644 kernel/src/arch/riscv64/mod.rs create mode 100644 kernel/src/arch/riscv64/msi.rs create mode 100644 kernel/src/arch/riscv64/pci/mod.rs create mode 100644 kernel/src/arch/riscv64/pio.rs create mode 100644 kernel/src/arch/riscv64/process/kthread.rs create mode 100644 kernel/src/arch/riscv64/process/mod.rs create mode 100644 kernel/src/arch/riscv64/process/syscall.rs create mode 100644 kernel/src/arch/riscv64/rand.rs create mode 100644 kernel/src/arch/riscv64/sched.rs create mode 100644 kernel/src/arch/riscv64/syscall/mod.rs create mode 100644 kernel/src/arch/riscv64/syscall/nr.rs create mode 100644 kernel/src/arch/riscv64/time.rs rename kernel/src/{ => arch/x86_64}/link.lds (100%) create mode 100644 kernel/src/arch/x86_64/mm/c_adapter.rs rename kernel/src/arch/x86_64/{syscall.rs => syscall/mod.rs} (85%) create mode 100644 kernel/src/arch/x86_64/syscall/nr.rs delete mode 100644 kernel/src/libs/atomic.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 8ddd4749..c00fa165 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -171,7 +171,8 @@ "mman.h": "c", "clocksource.h": "c", "ata.h": "c", - "barrier": "c" + "barrier": "c", + "charconv": "c" }, "C_Cpp.errorSquiggles": "enabled", "esbonio.sphinx.confDir": "", @@ -180,8 +181,12 @@ "./kernel/Cargo.toml", "./tools/Cargo.toml", ], + // "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf", + "rust-analyzer.cargo.target": "x86_64-unknown-none", "rust-analyzer.check.overrideCommand": [ "make", - "check" + "check", + ], + } \ No newline at end of file diff --git a/Makefile b/Makefile index c6890c5e..71e36454 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,13 @@ +# 导入环境变量 +include env.mk + + +export ROOT_PATH=$(shell pwd) + SUBDIRS = kernel user tools build-scripts -# ifndef $(EMULATOR) -ifeq ($(EMULATOR), ) -export EMULATOR=__NO_EMULATION__ -endif + + # todo: 增加参数,判断是否在QEMU中仿真,若是,则启用该环境变量 # export EMULATOR=__QEMU_EMULATION__ @@ -18,28 +22,7 @@ ifeq ($(OS),Darwin) # Assume Mac OS X NPROCS:=$(shell system_profiler | awk '/Number Of CPUs/{print $4}{next;}') endif -# if arch not defined, set it to x86_64 -export ARCH?=x86_64 -CFLAGS_DEFINE_ARCH="__$(ARCH)__" - - -export ROOT_PATH=$(shell pwd) - -export DEBUG=DEBUG -export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(CFLAGS_DEFINE_ARCH) -D $(EMULATOR) -O1 - -ifeq ($(DEBUG), DEBUG) -GLOBAL_CFLAGS += -g -endif - - -export CC=$(DragonOS_GCC)/x86_64-elf-gcc -export LD=ld -export AS=$(DragonOS_GCC)/x86_64-elf-as -export NM=$(DragonOS_GCC)/x86_64-elf-nm -export AR=$(DragonOS_GCC)/x86_64-elf-ar -export OBJCOPY=$(DragonOS_GCC)/x86_64-elf-objcopy # 检查是否需要进行fmt --check # 解析命令行参数 @@ -60,13 +43,13 @@ all: kernel user kernel: mkdir -p bin/kernel/ @if [ -z $$DragonOS_GCC ]; then echo "\033[31m [错误]尚未安装DragonOS交叉编译器, 请使用tools文件夹下的build_gcc_toolchain.sh脚本安装 \033[0m"; exit 1; fi - $(MAKE) -C ./kernel all || (sh -c "echo 内核编译失败" && exit 1) + $(MAKE) -C ./kernel all ARCH=$(ARCH) || (sh -c "echo 内核编译失败" && exit 1) .PHONY: user user: @if [ -z $$DragonOS_GCC ]; then echo "\033[31m [错误]尚未安装DragonOS交叉编译器, 请使用tools文件夹下的build_gcc_toolchain.sh脚本安装 \033[0m"; exit 1; fi - $(MAKE) -C ./user all || (sh -c "echo 用户程序编译失败" && exit 1) + $(MAKE) -C ./user all ARCH=$(ARCH) || (sh -c "echo 用户程序编译失败" && exit 1) .PHONY: clean clean: diff --git a/build-scripts/kernel_build/src/bindgen/arch/mod.rs b/build-scripts/kernel_build/src/bindgen/arch/mod.rs index 0b84a1f6..59ea10a2 100644 --- a/build-scripts/kernel_build/src/bindgen/arch/mod.rs +++ b/build-scripts/kernel_build/src/bindgen/arch/mod.rs @@ -2,6 +2,7 @@ use crate::utils::cargo_handler::{CargoHandler, TargetArch}; use self::x86_64::X86_64BindgenArch; +pub mod riscv64; pub mod x86_64; pub(super) trait BindgenArch { @@ -13,6 +14,7 @@ pub(super) fn current_bindgenarch() -> &'static dyn BindgenArch { let arch = CargoHandler::target_arch(); match arch { TargetArch::X86_64 => &X86_64BindgenArch, + TargetArch::Riscv64 => &riscv64::RiscV64BindgenArch, _ => panic!("Unsupported arch: {:?}", arch), } } diff --git a/build-scripts/kernel_build/src/bindgen/arch/riscv64.rs b/build-scripts/kernel_build/src/bindgen/arch/riscv64.rs new file mode 100644 index 00000000..c8eb32e6 --- /dev/null +++ b/build-scripts/kernel_build/src/bindgen/arch/riscv64.rs @@ -0,0 +1,10 @@ +use super::BindgenArch; + +pub struct RiscV64BindgenArch; +impl BindgenArch for RiscV64BindgenArch { + fn generate_bindings(&self, builder: bindgen::Builder) -> bindgen::Builder { + builder + .clang_arg("-I./src/arch/riscv64/include") + .clang_arg("--target=riscv64-none-none-elf") + } +} diff --git a/build-scripts/kernel_build/src/cfiles/arch/mod.rs b/build-scripts/kernel_build/src/cfiles/arch/mod.rs index 16c24651..a856f846 100644 --- a/build-scripts/kernel_build/src/cfiles/arch/mod.rs +++ b/build-scripts/kernel_build/src/cfiles/arch/mod.rs @@ -6,6 +6,7 @@ use crate::utils::cargo_handler::{CargoHandler, TargetArch}; use self::x86_64::X86_64CFilesArch; +pub mod riscv64; pub mod x86_64; pub(super) trait CFilesArch { @@ -25,6 +26,7 @@ pub(super) fn current_cfiles_arch() -> &'static dyn CFilesArch { let arch = CargoHandler::target_arch(); match arch { TargetArch::X86_64 => &X86_64CFilesArch, + TargetArch::Riscv64 => &riscv64::RiscV64CFilesArch, _ => panic!("Unsupported arch: {:?}", arch), } } diff --git a/build-scripts/kernel_build/src/cfiles/arch/riscv64.rs b/build-scripts/kernel_build/src/cfiles/arch/riscv64.rs new file mode 100644 index 00000000..f72b6691 --- /dev/null +++ b/build-scripts/kernel_build/src/cfiles/arch/riscv64.rs @@ -0,0 +1,41 @@ +use std::path::PathBuf; + +use crate::{constant::ARCH_DIR_RISCV64, utils::FileUtils}; + +use super::CFilesArch; + +pub(super) struct RiscV64CFilesArch; + +impl CFilesArch for RiscV64CFilesArch { + fn setup_defines(&self, c: &mut cc::Build) { + c.define("__riscv64__", None); + c.define("__riscv", None); + } + + fn setup_global_include_dir(&self, c: &mut cc::Build) { + c.include("src/arch/riscv64/include"); + } + + fn setup_files(&self, _c: &mut cc::Build, files: &mut Vec) { + files.push(PathBuf::from("src/arch/riscv64/boot/head.S")); + files.append(&mut FileUtils::list_all_files( + &arch_path("asm"), + Some("c"), + true, + )); + } + + fn setup_global_flags(&self, c: &mut cc::Build) { + // 在这里设置编译器,不然的话vscode的rust-analyzer会报错 + c.compiler("riscv64-unknown-elf-gcc"); + // // c.flag("-march=rv64imafdc"); + // c.no_default_flags(true); + c.flag("-mcmodel=medany"); + c.flag("-mabi=lp64"); + c.flag("-march=rv64imac"); + } +} + +fn arch_path(relative_path: &str) -> PathBuf { + PathBuf::from(format!("{}/{}", ARCH_DIR_RISCV64, relative_path)) +} diff --git a/build-scripts/kernel_build/src/cfiles/arch/x86_64.rs b/build-scripts/kernel_build/src/cfiles/arch/x86_64.rs index a0a12013..e10a5a89 100644 --- a/build-scripts/kernel_build/src/cfiles/arch/x86_64.rs +++ b/build-scripts/kernel_build/src/cfiles/arch/x86_64.rs @@ -50,6 +50,7 @@ impl CFilesArch for X86_64CFilesArch { fn setup_global_flags(&self, c: &mut Build) { c.asm_flag("-m64"); + c.flag("-mcmodel=large").flag("-m64"); } } diff --git a/build-scripts/kernel_build/src/cfiles/mod.rs b/build-scripts/kernel_build/src/cfiles/mod.rs index f06c507d..94d91416 100644 --- a/build-scripts/kernel_build/src/cfiles/mod.rs +++ b/build-scripts/kernel_build/src/cfiles/mod.rs @@ -23,14 +23,12 @@ impl CFilesBuilder { } fn setup_global_flags(c: &mut Build) { - c.flag("-mcmodel=large") - .flag("-fno-builtin") + c.flag("-fno-builtin") .flag("-nostdlib") .flag("-fno-stack-protector") .flag("-fno-pie") .flag("-Wno-expansion-to-defined") .flag("-Wno-unused-parameter") - .flag("-m64") .flag("-O1"); // set Arch-specific flags diff --git a/build-scripts/kernel_build/src/constant/mod.rs b/build-scripts/kernel_build/src/constant/mod.rs index 7bd10304..065e67b7 100644 --- a/build-scripts/kernel_build/src/constant/mod.rs +++ b/build-scripts/kernel_build/src/constant/mod.rs @@ -1 +1,2 @@ pub const ARCH_DIR_X86_64: &str = "src/arch/x86_64"; +pub const ARCH_DIR_RISCV64: &str = "src/arch/riscv64"; diff --git a/docs/index.rst b/docs/index.rst index 583ac9e5..6901002e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,6 +18,7 @@ :maxdepth: 1 :caption: 内核层 + kernel/configuration/index kernel/boot/index kernel/core_api/index kernel/locking/index @@ -30,7 +31,6 @@ kernel/ktest/index kernel/cpu_arch/index kernel/libs/index - kernel/configuration/index .. toctree:: diff --git a/docs/kernel/configuration/arch.md b/docs/kernel/configuration/arch.md new file mode 100644 index 00000000..ce01d35f --- /dev/null +++ b/docs/kernel/configuration/arch.md @@ -0,0 +1,31 @@ +# 目标架构配置 + +## 支持的架构 + +- x86_64 +- riscv64 + +## 架构相关配置 + +为了能支持vscode的调试功能,我们需要修改`.vscode/settings.json`文件的以下行: +``` + "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf", + // "rust-analyzer.cargo.target": "x86_64-unknown-none", +``` + +如果想要为x86_64架构编译,请启用x86_64那一行,注释掉其它的。 +如果想要为riscv64架构编译,请启用riscv64那一行,注释掉其它的。 + + +同时,我们还需要修改makefile的环境变量配置: + +请修改`env.mk`文件的以下行: +```Makefile +ifeq ($(ARCH), ) +# !!!!在这里设置ARCH,可选x86_64和riscv64 +# !!!!!!!如果不同时调整这里以及vscode的settings.json,那么自动补全和检查将会失效 +export ARCH=riscv64 +endif +``` + +请注意,更换架构需要重新编译,因此请运行`make clean`清理编译结果。然后再运行`make run`即可。 diff --git a/docs/kernel/configuration/index.rst b/docs/kernel/configuration/index.rst index 17a1243a..6dbf54ed 100644 --- a/docs/kernel/configuration/index.rst +++ b/docs/kernel/configuration/index.rst @@ -7,3 +7,4 @@ :caption: 目录 config + arch diff --git a/env.mk b/env.mk new file mode 100644 index 00000000..788314c7 --- /dev/null +++ b/env.mk @@ -0,0 +1,48 @@ + +ifeq ($(ARCH), ) +# !!!!在这里设置ARCH,可选x86_64和riscv64 +# !!!!!!!如果不同时调整这里以及vscode的settings.json,那么自动补全和检查将会失效 +export ARCH=x86_64 +endif + +ifeq ($(EMULATOR), ) +export EMULATOR=__NO_EMULATION__ +endif + +# 设置编译器 +ifeq ($(ARCH), x86_64) + +export CC=$(DragonOS_GCC)/x86_64-elf-gcc +export LD=ld +export AS=$(DragonOS_GCC)/x86_64-elf-as +export NM=$(DragonOS_GCC)/x86_64-elf-nm +export AR=$(DragonOS_GCC)/x86_64-elf-ar +export OBJCOPY=$(DragonOS_GCC)/x86_64-elf-objcopy + +else ifeq ($(ARCH), riscv64) + +export CC=riscv64-unknown-elf-gcc +export LD=riscv64-unknown-elf-ld +export AS=riscv64-unknown-elf-as +export NM=riscv64-unknown-elf-nm +export AR=riscv64-unknown-elf-ar +export OBJCOPY=riscv64-unknown-elf-objcopy + +endif + + +export DEBUG=DEBUG + +export CFLAGS_DEFINE_ARCH="__$(ARCH)__" + +export GLOBAL_CFLAGS := -fno-builtin -fno-stack-protector -D $(CFLAGS_DEFINE_ARCH) -D $(EMULATOR) -O1 + +ifeq ($(ARCH), x86_64) +GLOBAL_CFLAGS += -mcmodel=large -m64 +else ifeq ($(ARCH), riscv64) +GLOBAL_CFLAGS += -mcmodel=medany -march=rv64imac -mabi=lp64 +endif + +ifeq ($(DEBUG), DEBUG) +GLOBAL_CFLAGS += -g +endif \ No newline at end of file diff --git a/kernel/.cargo/config.toml b/kernel/.cargo/config.toml index 3cacb135..146246b4 100644 --- a/kernel/.cargo/config.toml +++ b/kernel/.cargo/config.toml @@ -1,9 +1,6 @@ -[build] -target = "src/arch/x86_64/x86_64-unknown-none.json" - -[unstable] -build-std = ["core", "compiler_builtins", "alloc"] -build-std-features = ["compiler-builtins-mem"] +# [unstable] +# build-std = ["core", "compiler_builtins", "alloc"] +# build-std-features = ["compiler-builtins-mem"] [target.'cfg(target_os = "none")'] runner = "bootimage runner" diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 8e88bb6e..0420973f 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -23,8 +23,6 @@ backtrace = [] # 运行时依赖项 [dependencies] -x86 = "0.52.0" -x86_64 = "0.14.10" bit_field = "0.10" bitflags = "1.3.2" bitfield-struct = "0.5.3" @@ -43,10 +41,15 @@ acpi = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/acpi-rs.git" intertrait = { path = "src/libs/intertrait" } linkme = "0.2" ida = { path = "src/libs/ida" } -mini-backtrace = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/mini-backtrace.git", rev = "ba98506685" } klog_types = { path = "crates/klog_types" } kdepends = { path = "crates/kdepends" } +# target为x86_64时,使用下面的依赖 +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86 = "0.52.0" +x86_64 = "0.14.10" +mini-backtrace = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/mini-backtrace.git", rev = "ba98506685" } + # 构建时依赖项 [build-dependencies] diff --git a/kernel/Makefile b/kernel/Makefile index acf5e215..a8b93c4f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,17 +1,40 @@ +# 导入环境变量 +include ../env.mk + +export ARCH ?= x86_64 +# 如果是x86_64, 则使用x86_64-unknown-none.json作为target +ifeq ($(ARCH), x86_64) + export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json +else ifeq ($(ARCH), riscv64) + export TARGET_JSON=riscv64imac-unknown-none-elf +endif + +export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem + +.PHONY: ECHO +ECHO: + @echo "$@" all: @if [ -z $$DragonOS_GCC ]; then echo "\033[31m [错误]尚未安装DragonOS交叉编译器, 请使用tools文件夹下的build_gcc_toolchain.sh脚本安装 \033[0m"; exit 1; fi - $(MAKE) -C src all + $(MAKE) -C src all ARCH=$(ARCH) || (sh -c "echo 内核编译失败" && exit 1) clean: rm -f Cargo.lock - $(MAKE) -C src clean + $(MAKE) -C src clean ARCH=$(ARCH) .PHONY: fmt fmt: cargo fmt --all $(FMT_CHECK) +.PHONY: check +check: ECHO +# @echo "Checking kernel... ARCH=$(ARCH)" +# @exit 1 +ifeq ($(ARCH), x86_64) + @cargo +nightly-2023-01-21 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON) +else ifeq ($(ARCH), riscv64) + @cargo +nightly-2023-01-21 check --workspace $(CARGO_ZBUILD) --message-format=json --target $(TARGET_JSON) +endif -check: - cargo +nightly-2023-01-21 check --workspace --message-format=json --target ./src/arch/x86_64/x86_64-unknown-none.json diff --git a/kernel/src/Makefile b/kernel/src/Makefile index 0da4a15e..0f85e6c7 100644 --- a/kernel/src/Makefile +++ b/kernel/src/Makefile @@ -15,11 +15,21 @@ LDFLAGS_UNWIND = RUSTFLAGS_UNWIND = ifeq ($(UNWIND_ENABLE), yes) CFLAGS_UNWIND = -funwind-tables +ifeq ($(ARCH), x86_64) LDFLAGS_UNWIND = --eh-frame-hdr +endif RUSTFLAGS_UNWIND = -Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld endif -CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -I $(shell pwd) -I $(shell pwd)/include -I $(shell pwd)/arch/x86_64/include +RUSTFLAGS = $(RUSTFLAGS_UNWIND) + +CFLAGS = $(GLOBAL_CFLAGS) -fno-pie $(CFLAGS_UNWIND) -I $(shell pwd) -I $(shell pwd)/include + +ifeq ($(ARCH), x86_64) + CFLAGS += -I $(shell pwd)/arch/x86_64/include +else ifeq ($(ARCH), riscv64) + CFLAGS += -I $(shell pwd)/arch/riscv64/include +endif export ASFLAGS := --64 @@ -30,12 +40,47 @@ kernel_subdirs := common driver debug exception smp syscall ktest libs time kernel_rust: - RUSTFLAGS="$(RUSTFLAGS_UNWIND)" cargo +nightly-2023-01-21 build --release --target ./arch/x86_64/x86_64-unknown-none.json +ifeq ($(ARCH), riscv64) + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2023-01-21 $(CARGO_ZBUILD) build --release --target riscv64imac-unknown-none-elf +else + RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2023-01-21 $(CARGO_ZBUILD) build --release --target $(TARGET_JSON) +endif all: kernel +# if x86_64 +ifeq ($(ARCH), x86_64) + $(MAKE) __link_x86_64_kernel +else ifeq ($(ARCH), riscv64) + $(MAKE) __link_riscv64_kernel +endif + + @echo "Kernel Build Done." + +ECHO: + @echo "$@" + +$(kernel_subdirs): ECHO + + $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)" + +kernel: $(kernel_subdirs) kernel_rust + +__link_riscv64_kernel: @echo "Linking kernel..." - $(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T link.lds --no-relax + $(LD) -b elf64-littleriscv -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/riscv64imac-unknown-none-elf/release/libdragonos_kernel.a -T arch/riscv64/link.ld --no-relax + $(OBJCOPY) -I elf64-littleriscv -O elf64-littleriscv -R ".eh_frame" kernel ../../bin/kernel/kernel.elf + rm kernel + +# 构建uboot的scr文件 + @echo "Generating kernel scr file..." + @mkdir -p $(ROOT_PATH)/bin/sysroot/boot/ + @mkimage -A riscv -T script -d arch/riscv64/boot/bootscript.cmd $(ROOT_PATH)/bin/sysroot/boot/boot.scr + + +__link_x86_64_kernel: + @echo "Linking kernel..." + $(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a -T arch/x86_64/link.lds --no-relax # 生成kallsyms current_dir=$(pwd) @@ -49,7 +94,7 @@ all: kernel # 重新链接 @echo "Re-Linking kernel..." @echo $(shell find . -name "*.o") - $(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T link.lds --no-relax + $(LD) -b elf64-x86-64 -z muldefs $(LDFLAGS_UNWIND) -o kernel $(shell find . -name "*.o") ../target/x86_64-unknown-none/release/libdragonos_kernel.a ./debug/kallsyms.o -T arch/x86_64/link.lds --no-relax @echo "Generating kernel ELF file..." # 生成内核文件 ifeq ($(UNWIND_ENABLE), yes) @@ -57,21 +102,10 @@ ifeq ($(UNWIND_ENABLE), yes) else $(OBJCOPY) -I elf64-x86-64 -O elf64-x86-64 -R ".eh_frame" kernel ../../bin/kernel/kernel.elf endif - @echo "Kernel Build Done." - -ECHO: - @echo "$@" - -$(kernel_subdirs): ECHO - - $(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" kernel_root_path="$(shell pwd)" - -kernel: $(kernel_subdirs) kernel_rust - - + rm kernel clean: - cargo clean + @cargo clean rm -rf $(GARBAGE) @list='$(kernel_subdirs)'; for subdir in $$list; do \ echo "Clean in dir: $$subdir";\ diff --git a/kernel/src/arch/arch.h b/kernel/src/arch/arch.h index 320ef366..e5257f29 100644 --- a/kernel/src/arch/arch.h +++ b/kernel/src/arch/arch.h @@ -9,4 +9,12 @@ #ifdef __x86_64__ # define AK_ARCH_X86_64 1 +#endif + +#ifdef __riscv +# define AK_ARCH_riscv 1 +#endif + +#ifdef __riscv64 +# define AK_ARCH_riscv64 1 #endif \ No newline at end of file diff --git a/kernel/src/arch/mod.rs b/kernel/src/arch/mod.rs index 3fe4d8f5..cc6469ec 100644 --- a/kernel/src/arch/mod.rs +++ b/kernel/src/arch/mod.rs @@ -1,12 +1,18 @@ -pub mod x86_64; -#[cfg(target_arch = "x86_64")] -pub use self::x86_64::*; //公开x86_64架构下的函数,使外界接口统一 - use crate::{ driver::pci::pci::{BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber}, mm::PhysAddr, }; +#[cfg(target_arch = "x86_64")] +pub mod x86_64; +#[cfg(target_arch = "x86_64")] +pub use self::x86_64::*; // 公开x86_64架构下的函数,使外界接口统一 + +#[cfg(target_arch = "riscv64")] +pub mod riscv64; +#[cfg(target_arch = "riscv64")] +pub use self::riscv64::*; // 公开riscv64架构下的函数,使外界接口统一 + pub mod io; /// TraitPciArch Pci架构相关函数,任何架构都应独立实现trait里的函数 diff --git a/kernel/src/arch/riscv64/asm/bitops.rs b/kernel/src/arch/riscv64/asm/bitops.rs new file mode 100644 index 00000000..26594a73 --- /dev/null +++ b/kernel/src/arch/riscv64/asm/bitops.rs @@ -0,0 +1,9 @@ +/// @brief ffz - 寻找u64中的第一个0所在的位(从第0位开始寻找) +/// 请注意,如果x中没有0,那么结果将是未定义的。请确保传入的x至少存在1个0 +/// +/// @param x 目标u64 +/// @return i32 bit-number(0..63) of the first (least significant) zero bit. +#[inline] +pub fn ffz(x: u64) -> i32 { + (!x).trailing_zeros() as i32 +} diff --git a/kernel/src/arch/riscv64/asm/irqflags.h b/kernel/src/arch/riscv64/asm/irqflags.h new file mode 100644 index 00000000..13a73926 --- /dev/null +++ b/kernel/src/arch/riscv64/asm/irqflags.h @@ -0,0 +1,20 @@ +#pragma once +#include +// 保存当前rflags的值到变量x内并关闭中断 +#define local_irq_save(x) \ + do \ + { \ + } while (1) +// 恢复先前保存的rflags的值x +#define local_irq_restore(x) \ + do \ + { \ + } while (1) +#define local_irq_disable() \ + do \ + { \ + } while (1) +#define local_irq_enable() \ + do \ + { \ + } while (1) diff --git a/kernel/src/arch/riscv64/asm/mod.rs b/kernel/src/arch/riscv64/asm/mod.rs new file mode 100644 index 00000000..7d9ea44b --- /dev/null +++ b/kernel/src/arch/riscv64/asm/mod.rs @@ -0,0 +1 @@ +pub mod bitops; diff --git a/kernel/src/arch/riscv64/asm/spinlock.c b/kernel/src/arch/riscv64/asm/spinlock.c new file mode 100644 index 00000000..a5cb9c6e --- /dev/null +++ b/kernel/src/arch/riscv64/asm/spinlock.c @@ -0,0 +1,35 @@ +#include +#include + +void __arch_spin_lock(spinlock_t *lock) +{ + while(1); + rs_preempt_disable(); +} + +void __arch_spin_unlock(spinlock_t *lock) +{ + while(1); + rs_preempt_enable(); +} + +void __arch_spin_lock_no_preempt(spinlock_t *lock) +{ + while(1); +} + +void __arch_spin_unlock_no_preempt(spinlock_t *lock) +{ + while(1); +} + +long __arch_spin_trylock(spinlock_t *lock) +{ + uint64_t tmp_val = 0; + rs_preempt_disable(); + // 交换tmp_val和lock的值,若tmp_val==1则证明加锁成功 + while(1); + if (!tmp_val) + rs_preempt_enable(); + return tmp_val; +} diff --git a/kernel/src/arch/riscv64/boot/bootscript.cmd b/kernel/src/arch/riscv64/boot/bootscript.cmd new file mode 100644 index 00000000..316e4c7c --- /dev/null +++ b/kernel/src/arch/riscv64/boot/bootscript.cmd @@ -0,0 +1,2 @@ +load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /boot/kernel.elf +if fdt addr -q ${fdt_addr_r}; then bootelf ${kernel_addr_r} ${fdt_addr_r};else bootelf ${kernel_addr_r} ${fdtcontroladdr};fi diff --git a/kernel/src/arch/riscv64/boot/head.S b/kernel/src/arch/riscv64/boot/head.S new file mode 100644 index 00000000..430a2285 --- /dev/null +++ b/kernel/src/arch/riscv64/boot/head.S @@ -0,0 +1,9 @@ +#include "common/asm.h" + +.section .bootstrap + +.global _start +.type _start, @function +ENTRY(_start) +loop: + j loop diff --git a/kernel/src/arch/riscv64/cpu.rs b/kernel/src/arch/riscv64/cpu.rs new file mode 100644 index 00000000..a3dee48f --- /dev/null +++ b/kernel/src/arch/riscv64/cpu.rs @@ -0,0 +1,10 @@ +/// 获取当前cpu的id +#[inline] +pub fn current_cpu_id() -> u32 { + unimplemented!("RiscV64 current_cpu_id") +} + +/// 重置cpu +pub unsafe fn cpu_reset() -> ! { + unimplemented!("RiscV64 cpu_reset") +} diff --git a/kernel/src/arch/riscv64/include/asm/asm.h b/kernel/src/arch/riscv64/include/asm/asm.h new file mode 100644 index 00000000..64631adc --- /dev/null +++ b/kernel/src/arch/riscv64/include/asm/asm.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include + +// RISC-V 没有直接的开启/关闭中断的指令,你需要通过修改CSR寄存器来实现 +// 你可能需要在你的中断处理程序中处理这些操作 + +#define nop() __asm__ __volatile__("nop\n\t") + +// RISC-V 没有 hlt 指令,你可能需要使用 wfi 指令来等待中断 +#define hlt() __asm__ __volatile__("wfi\n\t") + +// RISC-V 没有 pause 指令,你可能需要使用其他方法来实现处理器等待 + +// RISC-V 使用 fence 指令来实现内存屏障 +#define io_mfence() __asm__ __volatile__("fence rw,rw\n\t" :: \ + : "memory") +#define io_sfence() __asm__ __volatile__("fence w,w\n\t" :: \ + : "memory") +#define io_lfence() __asm__ __volatile__("fence r,r\n\t" :: \ + : "memory") + +// 开启中断 +#define sti() __asm__ __volatile__("csrsi mstatus, 8\n\t" :: \ + : "memory") + +// 关闭中断 +#define cli() __asm__ __volatile__("csrci mstatus, 8\n\t" :: \ + : "memory") + + +// 从io口读入8个bit +unsigned char io_in8(unsigned short port) +{ + while(1); +} + +// 从io口读入32个bit +unsigned int io_in32(unsigned short port) +{ + while(1); +} + +// 输出8个bit到输出端口 +void io_out8(unsigned short port, unsigned char value) +{ + while(1); +} + +// 输出32个bit到输出端口 +void io_out32(unsigned short port, unsigned int value) +{ + while(1); +} + +/** + * @brief 验证地址空间是否为用户地址空间 + * + * @param addr_start 地址起始值 + * @param length 地址长度 + * @return true + * @return false + */ +bool verify_area(uint64_t addr_start, uint64_t length){ + while(1); +} \ No newline at end of file diff --git a/kernel/src/arch/riscv64/include/asm/irqflags.h b/kernel/src/arch/riscv64/include/asm/irqflags.h new file mode 100644 index 00000000..8b042bea --- /dev/null +++ b/kernel/src/arch/riscv64/include/asm/irqflags.h @@ -0,0 +1,14 @@ +#pragma once + +// 保存当前rflags的值到变量x内并关闭中断 +#define local_irq_save(x) \ + do \ + { \ + } while (1) +// 恢复先前保存的rflags的值x +#define local_irq_restore(x) \ + do \ + { \ + } while (1) +#define local_irq_disable() cli(); +#define local_irq_enable() sti(); diff --git a/kernel/src/arch/riscv64/interrupt/ipi.rs b/kernel/src/arch/riscv64/interrupt/ipi.rs new file mode 100644 index 00000000..962e093c --- /dev/null +++ b/kernel/src/arch/riscv64/interrupt/ipi.rs @@ -0,0 +1,6 @@ +use crate::exception::ipi::{IpiKind, IpiTarget}; + +#[inline(always)] +pub fn send_ipi(kind: IpiKind, target: IpiTarget) { + unimplemented!("RiscV64 send_ipi") +} diff --git a/kernel/src/arch/riscv64/interrupt/mod.rs b/kernel/src/arch/riscv64/interrupt/mod.rs new file mode 100644 index 00000000..5c18a310 --- /dev/null +++ b/kernel/src/arch/riscv64/interrupt/mod.rs @@ -0,0 +1,41 @@ +use crate::exception::{InterruptArch, IrqFlags, IrqFlagsGuard}; + +pub mod ipi; + +pub struct RiscV64InterruptArch; + +impl InterruptArch for RiscV64InterruptArch { + unsafe fn interrupt_enable() { + unimplemented!("RiscV64InterruptArch::interrupt_enable") + } + + unsafe fn interrupt_disable() { + unimplemented!("RiscV64InterruptArch::interrupt_disable") + } + + fn is_irq_enabled() -> bool { + unimplemented!("RiscV64InterruptArch::is_irq_enabled") + } + + unsafe fn save_and_disable_irq() -> IrqFlagsGuard { + unimplemented!("RiscV64InterruptArch::save_and_disable_irq") + } + + unsafe fn restore_irq(flags: IrqFlags) { + unimplemented!("RiscV64InterruptArch::restore_irq") + } +} + +/// 中断栈帧结构体 +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct TrapFrame { + // todo +} + +impl TrapFrame { + /// 判断当前中断是否来自用户模式 + pub fn from_user(&self) -> bool { + unimplemented!("TrapFrame::from_user") + } +} diff --git a/kernel/src/arch/riscv64/ipc/mod.rs b/kernel/src/arch/riscv64/ipc/mod.rs new file mode 100644 index 00000000..a3c1b22f --- /dev/null +++ b/kernel/src/arch/riscv64/ipc/mod.rs @@ -0,0 +1 @@ +pub mod signal; diff --git a/kernel/src/arch/riscv64/ipc/signal.rs b/kernel/src/arch/riscv64/ipc/signal.rs new file mode 100644 index 00000000..053ff7ea --- /dev/null +++ b/kernel/src/arch/riscv64/ipc/signal.rs @@ -0,0 +1,342 @@ +use crate::{ + arch::{sched::sched, CurrentIrqArch}, + exception::InterruptArch, + kerror, + process::ProcessManager, +}; + +/// 信号处理的栈的栈指针的最小对齐数量 +pub const STACK_ALIGN: u64 = 16; +/// 信号最大值 +pub const MAX_SIG_NUM: usize = 64; +#[allow(dead_code)] +#[derive(Eq)] +#[repr(usize)] +#[allow(non_camel_case_types)] +#[atomic_enum] +pub enum Signal { + INVALID = 0, + SIGHUP = 1, + SIGINT, + SIGQUIT, + SIGILL, + SIGTRAP, + /// SIGABRT和SIGIOT共用这个号码 + SIGABRT_OR_IOT, + SIGBUS, + SIGFPE, + SIGKILL, + SIGUSR1, + + SIGSEGV = 11, + SIGUSR2, + SIGPIPE, + SIGALRM, + SIGTERM, + SIGSTKFLT, + SIGCHLD, + SIGCONT, + SIGSTOP, + SIGTSTP, + + SIGTTIN = 21, + SIGTTOU, + SIGURG, + SIGXCPU, + SIGXFSZ, + SIGVTALRM, + SIGPROF, + SIGWINCH, + /// SIGIO和SIGPOLL共用这个号码 + SIGIO_OR_POLL, + SIGPWR, + + SIGSYS = 31, + + SIGRTMIN = 32, + SIGRTMAX = 64, +} + +/// 为Signal实现判断相等的trait +impl PartialEq for Signal { + fn eq(&self, other: &Signal) -> bool { + *self as usize == *other as usize + } +} + +impl From for Signal { + fn from(value: usize) -> Self { + if value <= MAX_SIG_NUM { + let ret: Signal = unsafe { core::mem::transmute(value) }; + return ret; + } else { + kerror!("Try to convert an invalid number to Signal"); + return Signal::INVALID; + } + } +} + +impl Into for Signal { + fn into(self) -> usize { + self as usize + } +} + +impl From for Signal { + fn from(value: i32) -> Self { + if value < 0 { + kerror!("Try to convert an invalid number to Signal"); + return Signal::INVALID; + } else { + return Self::from(value as usize); + } + } +} + +impl Into for Signal { + fn into(self) -> SigSet { + SigSet { + bits: (1 << (self as usize - 1) as u64), + } + } +} +impl Signal { + /// 判断一个数字是否为可用的信号 + #[inline] + pub fn is_valid(&self) -> bool { + return (*self) as usize <= MAX_SIG_NUM; + } + + /// const convertor between `Signal` and `SigSet` + pub const fn into_sigset(self) -> SigSet { + SigSet { + bits: (1 << (self as usize - 1) as u64), + } + } + + /// 判断一个信号是不是实时信号 + /// + /// ## 返回值 + /// + /// - `true` 这个信号是实时信号 + /// - `false` 这个信号不是实时信号 + #[inline] + pub fn is_rt_signal(&self) -> bool { + return (*self) as usize >= Signal::SIGRTMIN.into(); + } + + /// 调用信号的默认处理函数 + pub fn handle_default(&self) { + match self { + Signal::INVALID => { + kerror!("attempting to handler an Invalid"); + } + Signal::SIGHUP => sig_terminate(self.clone()), + Signal::SIGINT => sig_terminate(self.clone()), + Signal::SIGQUIT => sig_terminate_dump(self.clone()), + Signal::SIGILL => sig_terminate_dump(self.clone()), + Signal::SIGTRAP => sig_terminate_dump(self.clone()), + Signal::SIGABRT_OR_IOT => sig_terminate_dump(self.clone()), + Signal::SIGBUS => sig_terminate_dump(self.clone()), + Signal::SIGFPE => sig_terminate_dump(self.clone()), + Signal::SIGKILL => sig_terminate(self.clone()), + Signal::SIGUSR1 => sig_terminate(self.clone()), + Signal::SIGSEGV => sig_terminate_dump(self.clone()), + Signal::SIGUSR2 => sig_terminate(self.clone()), + Signal::SIGPIPE => sig_terminate(self.clone()), + Signal::SIGALRM => sig_terminate(self.clone()), + Signal::SIGTERM => sig_terminate(self.clone()), + Signal::SIGSTKFLT => sig_terminate(self.clone()), + Signal::SIGCHLD => sig_ignore(self.clone()), + Signal::SIGCONT => sig_continue(self.clone()), + Signal::SIGSTOP => sig_stop(self.clone()), + Signal::SIGTSTP => sig_stop(self.clone()), + Signal::SIGTTIN => sig_stop(self.clone()), + Signal::SIGTTOU => sig_stop(self.clone()), + Signal::SIGURG => sig_ignore(self.clone()), + Signal::SIGXCPU => sig_terminate_dump(self.clone()), + Signal::SIGXFSZ => sig_terminate_dump(self.clone()), + Signal::SIGVTALRM => sig_terminate(self.clone()), + Signal::SIGPROF => sig_terminate(self.clone()), + Signal::SIGWINCH => sig_ignore(self.clone()), + Signal::SIGIO_OR_POLL => sig_terminate(self.clone()), + Signal::SIGPWR => sig_terminate(self.clone()), + Signal::SIGSYS => sig_terminate(self.clone()), + Signal::SIGRTMIN => sig_terminate(self.clone()), + Signal::SIGRTMAX => sig_terminate(self.clone()), + } + } +} + +/// siginfo中的si_code的可选值 +/// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态 +#[derive(Copy, Debug, Clone)] +#[repr(i32)] +pub enum SigCode { + /// sent by kill, sigsend, raise + User = 0, + /// sent by kernel from somewhere + Kernel = 0x80, + /// 通过sigqueue发送 + Queue = -1, + /// 定时器过期时发送 + Timer = -2, + /// 当实时消息队列的状态发生改变时发送 + Mesgq = -3, + /// 当异步IO完成时发送 + AsyncIO = -4, + /// sent by queued SIGIO + SigIO = -5, +} + +impl SigCode { + /// 为SigCode这个枚举类型实现从i32转换到枚举类型的转换函数 + #[allow(dead_code)] + pub fn from_i32(x: i32) -> SigCode { + match x { + 0 => Self::User, + 0x80 => Self::Kernel, + -1 => Self::Queue, + -2 => Self::Timer, + -3 => Self::Mesgq, + -4 => Self::AsyncIO, + -5 => Self::SigIO, + _ => panic!("signal code not valid"), + } + } +} + +bitflags! { + #[repr(C,align(8))] + #[derive(Default)] + pub struct SigFlags:u32{ + const SA_NOCLDSTOP = 1; + const SA_NOCLDWAIT = 2; + const SA_SIGINFO = 4; + const SA_ONSTACK = 0x08000000; + const SA_RESTART = 0x10000000; + const SA_NODEFER = 0x40000000; + const SA_RESETHAND = 0x80000000; + const SA_RESTORER =0x04000000; + const SA_ALL = Self::SA_NOCLDSTOP.bits()|Self::SA_NOCLDWAIT.bits()|Self::SA_NODEFER.bits()|Self::SA_ONSTACK.bits()|Self::SA_RESETHAND.bits()|Self::SA_RESTART.bits()|Self::SA_SIGINFO.bits()|Self::SA_RESTORER.bits(); + } + + /// 请注意,sigset 这个bitmap, 第0位表示sig=1的信号。也就是说,Signal-1才是sigset_t中对应的位 + #[derive(Default)] + pub struct SigSet:u64{ + const SIGHUP = 1<<0; + const SIGINT = 1<<1; + const SIGQUIT = 1<<2; + const SIGILL = 1<<3; + const SIGTRAP = 1<<4; + /// SIGABRT和SIGIOT共用这个号码 + const SIGABRT_OR_IOT = 1<<5; + const SIGBUS = 1<<6; + const SIGFPE = 1<<7; + const SIGKILL = 1<<8; + const SIGUSR = 1<<9; + const SIGSEGV = 1<<10; + const SIGUSR2 = 1<<11; + const SIGPIPE = 1<<12; + const SIGALRM = 1<<13; + const SIGTERM = 1<<14; + const SIGSTKFLT= 1<<15; + const SIGCHLD = 1<<16; + const SIGCONT = 1<<17; + const SIGSTOP = 1<<18; + const SIGTSTP = 1<<19; + const SIGTTIN = 1<<20; + const SIGTTOU = 1<<21; + const SIGURG = 1<<22; + const SIGXCPU = 1<<23; + const SIGXFSZ = 1<<24; + const SIGVTALRM= 1<<25; + const SIGPROF = 1<<26; + const SIGWINCH = 1<<27; + /// SIGIO和SIGPOLL共用这个号码 + const SIGIO_OR_POLL = 1<<28; + const SIGPWR = 1<<29; + const SIGSYS = 1<<30; + const SIGRTMIN = 1<<31; + // TODO 写上实时信号 + const SIGRTMAX = 1< for SigChildCode { + fn into(self) -> i32 { + self as i32 + } +} + +/// 信号默认处理函数——终止进程 +fn sig_terminate(sig: Signal) { + ProcessManager::exit(sig as usize); +} + +/// 信号默认处理函数——终止进程并生成 core dump +fn sig_terminate_dump(sig: Signal) { + ProcessManager::exit(sig as usize); + // TODO 生成 coredump 文件 +} + +/// 信号默认处理函数——暂停进程 +fn sig_stop(sig: Signal) { + let guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; + ProcessManager::mark_stop().unwrap_or_else(|e| { + kerror!( + "sleep error :{:?},failed to sleep process :{:?}, with signal :{:?}", + e, + ProcessManager::current_pcb(), + sig + ); + }); + drop(guard); + sched(); + // TODO 暂停进程 +} + +/// 信号默认处理函数——继续进程 +fn sig_continue(sig: Signal) { + ProcessManager::wakeup_stop(&ProcessManager::current_pcb()).unwrap_or_else(|_| { + kerror!( + "Failed to wake up process pid = {:?} with signal :{:?}", + ProcessManager::current_pcb().pid(), + sig + ); + }); +} +/// 信号默认处理函数——忽略 +fn sig_ignore(_sig: Signal) { + return; +} diff --git a/kernel/src/arch/riscv64/kvm/mod.rs b/kernel/src/arch/riscv64/kvm/mod.rs new file mode 100644 index 00000000..ec466767 --- /dev/null +++ b/kernel/src/arch/riscv64/kvm/mod.rs @@ -0,0 +1,22 @@ +use alloc::sync::Arc; + +use crate::{libs::mutex::Mutex, syscall::SystemError}; + +#[derive(Debug, Clone, Default)] +pub struct RiscV64KVMArch {} + +impl RiscV64KVMArch { + /// @brief 查看CPU是否支持虚拟化 + pub fn kvm_arch_cpu_supports_vm() -> Result<(), SystemError> { + unimplemented!("RiscV64KVMArch::kvm_arch_cpu_supports_vm") + } + + /// @brief 初始化KVM + pub fn kvm_arch_init() -> Result<(), SystemError> { + Ok(()) + } + + pub fn kvm_arch_dev_ioctl(cmd: u32, _arg: usize) -> Result { + unimplemented!("RiscV64KVMArch::kvm_arch_dev_ioctl") + } +} diff --git a/kernel/src/arch/riscv64/link.ld b/kernel/src/arch/riscv64/link.ld new file mode 100644 index 00000000..e3e10bcf --- /dev/null +++ b/kernel/src/arch/riscv64/link.ld @@ -0,0 +1,97 @@ +OUTPUT_FORMAT( + "elf64-littleriscv", + "elf64-littleriscv", + "elf64-littleriscv" +) + +OUTPUT_ARCH(riscv) +ENTRY(_start) + + +SECTIONS +{ + //KERNEL_VMA = 0xffffffc000000000; + KERNEL_VMA = 0; + . = 0; + + .boot.text : + { + KEEP(*(.multiboot_header)) + *(.bootstrap) + *(.bootstrap.code64) + *(.bootstrap.data) + . = ALIGN(4096); + } + + . += KERNEL_VMA; + . = ALIGN(32768); + text_start_pa = .; + .text (text_start_pa): AT(text_start_pa - KERNEL_VMA) + { + _text = .; + + /* any files' .text */ + *(.text) + + /* any files' .text.*, for example: rust .text._ZN* */ + *(.text.*) + + _etext = .; + } + . = ALIGN(32768); + data_start_pa = .; + .data (data_start_pa): AT(data_start_pa - KERNEL_VMA) + { + _data = .; + *(.data) + *(.data.*) + + _edata = .; + } + + . = ALIGN(32768); + + rodata_start_pa = .; + .rodata (rodata_start_pa): AT(rodata_start_pa - KERNEL_VMA) + { + _rodata = .; + *(.rodata) + *(.rodata.*) + _erodata = .; + } + + . = ALIGN(32768); + + init_proc_union_start_pa = .; + .data.init_proc_union (init_proc_union_start_pa): AT(init_proc_union_start_pa - KERNEL_VMA) + { *(.data.init_proc_union) } + + . = ALIGN(32768); + bss_start_pa = .; + .bss (bss_start_pa): AT(bss_start_pa - KERNEL_VMA) + { + _bss = .; + *(.bss) + *(.bss.*) + _ebss = .; + } + + eh_frame = .; + .eh_frame (eh_frame): AT(eh_frame - KERNEL_VMA) + { + __eh_frame_hdr_start = .; + *(.eh_frame_hdr) + __eh_frame_hdr_end = .; + __eh_frame_start = .; + *(.eh_frame) + *(.rela.eh_frame) + __eh_frame_end = .; + } + + _end = .; + + /DISCARD/ : { + /* *(.eh_frame) */ + + } +} diff --git a/kernel/src/arch/riscv64/mm/bump.rs b/kernel/src/arch/riscv64/mm/bump.rs new file mode 100644 index 00000000..08198e30 --- /dev/null +++ b/kernel/src/arch/riscv64/mm/bump.rs @@ -0,0 +1,8 @@ +use crate::mm::{allocator::bump::BumpAllocator, MemoryManagementArch, PhysMemoryArea}; + +impl BumpAllocator { + pub unsafe fn arch_remain_areas(_ret_areas: &mut [PhysMemoryArea], res_count: usize) -> usize { + // todo: riscv64 + return res_count; + } +} diff --git a/kernel/src/arch/riscv64/mm/mod.rs b/kernel/src/arch/riscv64/mm/mod.rs new file mode 100644 index 00000000..7a251f33 --- /dev/null +++ b/kernel/src/arch/riscv64/mm/mod.rs @@ -0,0 +1,109 @@ +use crate::mm::{ + allocator::page_frame::{FrameAllocator, PageFrameCount, PageFrameUsage}, + page::PageFlags, + MemoryManagementArch, PhysAddr, VirtAddr, +}; + +pub mod bump; + +pub type PageMapper = crate::mm::page::PageMapper; + +/// RiscV64的内存管理架构结构体 +#[derive(Debug, Clone, Copy, Hash)] +pub struct RiscV64MMArch; + +impl MemoryManagementArch for RiscV64MMArch { + const PAGE_SHIFT: usize = 12; + + const PAGE_ENTRY_SHIFT: usize = 9; + + /// sv39分页只有三级 + const PAGE_LEVELS: usize = 3; + + const ENTRY_ADDRESS_SHIFT: usize = 39; + + const ENTRY_FLAG_DEFAULT_PAGE: usize = Self::ENTRY_FLAG_PRESENT; + + const ENTRY_FLAG_DEFAULT_TABLE: usize = Self::ENTRY_FLAG_PRESENT; + + const ENTRY_FLAG_PRESENT: usize = 1 << 0; + + const ENTRY_FLAG_READONLY: usize = 1 << 1; + + const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); + + const ENTRY_FLAG_USER: usize = (1 << 4); + + const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); + + const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); + + const ENTRY_FLAG_NO_EXEC: usize = 0; + + const ENTRY_FLAG_EXEC: usize = (1 << 3); + + const PHYS_OFFSET: usize = 0xffff_ffc0_0000_0000; + + const USER_END_VADDR: crate::mm::VirtAddr = VirtAddr::new(0x0000_003f_ffff_ffff); + + const USER_BRK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffff_ffff); + + const USER_STACK_START: crate::mm::VirtAddr = VirtAddr::new(0x0000_001f_ffa0_0000); + + unsafe fn init() -> &'static [crate::mm::PhysMemoryArea] { + todo!() + } + + unsafe fn invalidate_page(address: crate::mm::VirtAddr) { + todo!() + } + + unsafe fn invalidate_all() { + todo!() + } + + unsafe fn table(table_kind: crate::mm::PageTableKind) -> crate::mm::PhysAddr { + todo!() + } + + unsafe fn set_table(table_kind: crate::mm::PageTableKind, table: crate::mm::PhysAddr) { + todo!() + } + + fn virt_is_valid(virt: crate::mm::VirtAddr) -> bool { + todo!() + } + + fn initial_page_table() -> crate::mm::PhysAddr { + todo!() + } + + fn setup_new_usermapper() -> Result + { + todo!() + } +} + +/// 获取内核地址默认的页面标志 +pub unsafe fn kernel_page_flags(virt: VirtAddr) -> PageFlags { + unimplemented!("riscv64::kernel_page_flags") +} + +/// 全局的页帧分配器 +#[derive(Debug, Clone, Copy, Hash)] +pub struct LockedFrameAllocator; + +impl FrameAllocator for LockedFrameAllocator { + unsafe fn allocate(&mut self, count: PageFrameCount) -> Option<(PhysAddr, PageFrameCount)> { + unimplemented!("RiscV64 LockedFrameAllocator::allocate") + } + + unsafe fn free(&mut self, address: crate::mm::PhysAddr, count: PageFrameCount) { + assert!(count.data().is_power_of_two()); + unimplemented!("RiscV64 LockedFrameAllocator::free") + } + + unsafe fn usage(&self) -> PageFrameUsage { + unimplemented!("RiscV64 LockedFrameAllocator::usage") + } +} diff --git a/kernel/src/arch/riscv64/mod.rs b/kernel/src/arch/riscv64/mod.rs new file mode 100644 index 00000000..b7917194 --- /dev/null +++ b/kernel/src/arch/riscv64/mod.rs @@ -0,0 +1,21 @@ +pub mod asm; +pub mod cpu; +pub mod interrupt; +pub mod ipc; +mod kvm; +pub mod mm; +pub mod msi; +pub mod pci; +pub mod pio; +pub mod process; +pub mod rand; +pub mod sched; +pub mod syscall; +pub mod time; + +pub use self::interrupt::RiscV64InterruptArch as CurrentIrqArch; +pub use self::kvm::RiscV64KVMArch as KVMArch; +pub use self::mm::RiscV64MMArch as MMArch; +pub use self::pci::RiscV64PciArch as PciArch; +pub use self::pio::RiscV64PortIOArch as CurrentPortIOArch; +pub use self::time::RiscV64TimeArch as CurrentTimeArch; diff --git a/kernel/src/arch/riscv64/msi.rs b/kernel/src/arch/riscv64/msi.rs new file mode 100644 index 00000000..9b7aa2fa --- /dev/null +++ b/kernel/src/arch/riscv64/msi.rs @@ -0,0 +1,16 @@ +use crate::driver::pci::pci_irq::TriggerMode; + +/// @brief 获得MSI Message Address +/// @param processor 目标CPU ID号 +/// @return MSI Message Address +pub fn arch_msi_message_address(processor: u16) -> u32 { + unimplemented!("riscv64::arch_msi_message_address()") +} +/// @brief 获得MSI Message Data +/// @param vector 分配的中断向量号 +/// @param processor 目标CPU ID号 +/// @param trigger 申请中断的触发模式,MSI默认为边沿触发 +/// @return MSI Message Address +pub fn arch_msi_message_data(vector: u16, _processor: u16, trigger: TriggerMode) -> u32 { + unimplemented!("riscv64::arch_msi_message_data()") +} diff --git a/kernel/src/arch/riscv64/pci/mod.rs b/kernel/src/arch/riscv64/pci/mod.rs new file mode 100644 index 00000000..68082d54 --- /dev/null +++ b/kernel/src/arch/riscv64/pci/mod.rs @@ -0,0 +1,23 @@ +use crate::{ + arch::TraitPciArch, + driver::pci::pci::{BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber}, +}; + +pub struct RiscV64PciArch; +impl TraitPciArch for RiscV64PciArch { + fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 { + unimplemented!("RiscV64PciArch::read_config") + } + + fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) { + unimplemented!("RiscV64PciArch::write_config") + } + + fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr { + unimplemented!("RiscV64PciArch::address_pci_to_physical") + } + + fn ecam_root(segement: SegmentGroupNumber) -> Result { + unimplemented!("RiscV64PciArch::ecam_root") + } +} diff --git a/kernel/src/arch/riscv64/pio.rs b/kernel/src/arch/riscv64/pio.rs new file mode 100644 index 00000000..140525f3 --- /dev/null +++ b/kernel/src/arch/riscv64/pio.rs @@ -0,0 +1,35 @@ +use crate::arch::io::PortIOArch; + +pub struct RiscV64PortIOArch; + +impl PortIOArch for RiscV64PortIOArch { + #[inline(always)] + unsafe fn in8(port: u16) -> u8 { + unimplemented!("RiscV64PortIOArch::in8") + } + + #[inline(always)] + unsafe fn in16(port: u16) -> u16 { + unimplemented!("RiscV64PortIOArch::in16") + } + + #[inline(always)] + unsafe fn in32(port: u16) -> u32 { + unimplemented!("RiscV64PortIOArch::in32") + } + + #[inline(always)] + unsafe fn out8(port: u16, data: u8) { + unimplemented!("RiscV64PortIOArch::out8") + } + + #[inline(always)] + unsafe fn out16(port: u16, data: u16) { + unimplemented!("RiscV64PortIOArch::out16") + } + + #[inline(always)] + unsafe fn out32(port: u16, data: u32) { + unimplemented!("RiscV64PortIOArch::out32") + } +} diff --git a/kernel/src/arch/riscv64/process/kthread.rs b/kernel/src/arch/riscv64/process/kthread.rs new file mode 100644 index 00000000..0f3ee8c8 --- /dev/null +++ b/kernel/src/arch/riscv64/process/kthread.rs @@ -0,0 +1,39 @@ +use alloc::sync::Arc; + +use crate::{ + process::{ + fork::CloneFlags, + kthread::{KernelThreadCreateInfo, KernelThreadMechanism}, + Pid, + }, + syscall::SystemError, +}; + +impl KernelThreadMechanism { + /// 伪造trapframe,创建内核线程 + /// + /// ## 返回值 + /// + /// 返回创建的内核线程的pid + pub fn __inner_create( + info: &Arc, + clone_flags: CloneFlags, + ) -> Result { + unimplemented!("KernelThreadMechanism::__inner_create") + } +} + +/// 内核线程引导函数的第一阶段 +/// +/// 当内核线程开始执行时,会先执行这个函数,这个函数会将伪造的trapframe中的数据弹出,然后跳转到第二阶段 +/// +/// 跳转之后,指向Box的指针将传入到stage2的函数 +// #[naked] +// pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() { +// todo!() +// } +pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() { + // 这个函数要是naked的,只是因为现在还没有实现,而naked func不能打`unimplemented!()` + // 所以先写成了普通函数 + unimplemented!("kernel_thread_bootstrap_stage1") +} diff --git a/kernel/src/arch/riscv64/process/mod.rs b/kernel/src/arch/riscv64/process/mod.rs new file mode 100644 index 00000000..c5fa8032 --- /dev/null +++ b/kernel/src/arch/riscv64/process/mod.rs @@ -0,0 +1,77 @@ +use alloc::{string::String, sync::Arc, vec::Vec}; + +use crate::{ + process::{fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager}, + syscall::SystemError, +}; + +use super::interrupt::TrapFrame; + +pub mod kthread; +pub mod syscall; + +pub unsafe fn arch_switch_to_user(path: String, argv: Vec, envp: Vec) -> ! { + unimplemented!("RiscV64 arch_switch_to_user") +} + +impl ProcessManager { + pub fn arch_init() { + unimplemented!("ProcessManager::arch_init") + } + + /// fork的过程中复制线程 + /// + /// 由于这个过程与具体的架构相关,所以放在这里 + pub fn copy_thread( + current_pcb: &Arc, + new_pcb: &Arc, + clone_args: KernelCloneArgs, + current_trapframe: &TrapFrame, + ) -> Result<(), SystemError> { + unimplemented!("ProcessManager::copy_thread") + } + + /// 切换进程 + /// + /// ## 参数 + /// + /// - `prev`:上一个进程的pcb + /// - `next`:下一个进程的pcb + pub unsafe fn switch_process(prev: Arc, next: Arc) { + unimplemented!("ProcessManager::switch_process") + } +} + +impl ProcessControlBlock { + /// 获取当前进程的pcb + pub fn arch_current_pcb() -> Arc { + unimplemented!("ProcessControlBlock::arch_current_pcb") + } +} + +/// PCB中与架构相关的信息 +#[derive(Debug)] +#[allow(dead_code)] +pub struct ArchPCBInfo { + // todo: add arch related fields +} + +#[allow(dead_code)] +impl ArchPCBInfo { + /// 创建一个新的ArchPCBInfo + /// + /// ## 参数 + /// + /// - `kstack`:内核栈的引用 + /// + /// ## 返回值 + /// + /// 返回一个新的ArchPCBInfo + pub fn new(kstack: &KernelStack) -> Self { + unimplemented!("ArchPCBInfo::new") + } + // ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变 + pub fn clone_from(&mut self, from: &Self) { + unimplemented!("ArchPCBInfo::clone_from") + } +} diff --git a/kernel/src/arch/riscv64/process/syscall.rs b/kernel/src/arch/riscv64/process/syscall.rs new file mode 100644 index 00000000..e718bc98 --- /dev/null +++ b/kernel/src/arch/riscv64/process/syscall.rs @@ -0,0 +1,22 @@ +use alloc::{string::String, vec::Vec}; + +use crate::{ + arch::interrupt::TrapFrame, + syscall::{Syscall, SystemError}, +}; + +impl Syscall { + pub fn do_execve( + path: String, + argv: Vec, + envp: Vec, + regs: &mut TrapFrame, + ) -> Result<(), SystemError> { + unimplemented!("Syscall::do_execve") + } + + /// ## 用于控制和查询与体系结构相关的进程特定选项 + pub fn arch_prctl(option: usize, arg2: usize) -> Result { + unimplemented!("Syscall::arch_prctl") + } +} diff --git a/kernel/src/arch/riscv64/rand.rs b/kernel/src/arch/riscv64/rand.rs new file mode 100644 index 00000000..373f84fa --- /dev/null +++ b/kernel/src/arch/riscv64/rand.rs @@ -0,0 +1,3 @@ +pub fn rand() -> usize { + unimplemented!("RiscV64 rand"); +} diff --git a/kernel/src/arch/riscv64/sched.rs b/kernel/src/arch/riscv64/sched.rs new file mode 100644 index 00000000..8a9cf82d --- /dev/null +++ b/kernel/src/arch/riscv64/sched.rs @@ -0,0 +1,5 @@ +/// 发起调度 +#[no_mangle] +pub extern "C" fn sched() { + unimplemented!("RiscV64::sched") +} diff --git a/kernel/src/arch/riscv64/syscall/mod.rs b/kernel/src/arch/riscv64/syscall/mod.rs new file mode 100644 index 00000000..81d72440 --- /dev/null +++ b/kernel/src/arch/riscv64/syscall/mod.rs @@ -0,0 +1,18 @@ +/// 系统调用号 +pub mod nr; +use crate::{exception::InterruptArch, syscall::SystemError}; + +use super::{interrupt::TrapFrame, CurrentIrqArch}; + +/// 系统调用初始化 +pub fn arch_syscall_init() -> Result<(), SystemError> { + unimplemented!("arch_syscall_init") +} + +#[no_mangle] +pub extern "C" fn syscall_handler(frame: &mut TrapFrame) -> () { + unsafe { + CurrentIrqArch::interrupt_enable(); + } + unimplemented!("syscall_handler") +} diff --git a/kernel/src/arch/riscv64/syscall/nr.rs b/kernel/src/arch/riscv64/syscall/nr.rs new file mode 100644 index 00000000..e7f45b2d --- /dev/null +++ b/kernel/src/arch/riscv64/syscall/nr.rs @@ -0,0 +1,306 @@ +#![allow(dead_code)] +#![allow(non_upper_case_globals)] +pub const SYS_ACCEPT: usize = 202; +pub const SYS_ACCEPT4: usize = 242; +pub const SYS_ACCT: usize = 89; +pub const SYS_ADD_KEY: usize = 217; +pub const SYS_ADJTIMEX: usize = 171; +pub const SYS_ARCH_SPECIFIC_SYSCALL: usize = 244; +pub const SYS_BIND: usize = 200; +pub const SYS_BPF: usize = 280; +pub const SYS_BRK: usize = 214; +pub const SYS_CAPGET: usize = 90; +pub const SYS_CAPSET: usize = 91; +pub const SYS_CHDIR: usize = 49; +pub const SYS_CHROOT: usize = 51; +pub const SYS_CLOCK_ADJTIME: usize = 266; +pub const SYS_CLOCK_GETRES: usize = 114; +pub const SYS_CLOCK_GETTIME: usize = 113; +pub const SYS_CLOCK_NANOSLEEP: usize = 115; +pub const SYS_CLOCK_SETTIME: usize = 112; +pub const SYS_CLONE: usize = 220; +pub const SYS_CLONE3: usize = 435; +pub const SYS_CLOSE: usize = 57; +pub const SYS_CLOSE_RANGE: usize = 436; +pub const SYS_CONNECT: usize = 203; +pub const SYS_COPY_FILE_RANGE: usize = 285; +pub const SYS_DELETE_MODULE: usize = 106; +pub const SYS_DUP: usize = 23; +pub const SYS_DUP3: usize = 24; +pub const SYS_EPOLL_CREATE1: usize = 20; +pub const SYS_EPOLL_CTL: usize = 21; +pub const SYS_EPOLL_PWAIT: usize = 22; +pub const SYS_EPOLL_PWAIT2: usize = 441; +pub const SYS_EVENTFD2: usize = 19; +pub const SYS_EXECVE: usize = 221; +pub const SYS_EXECVEAT: usize = 281; +pub const SYS_EXIT: usize = 93; +pub const SYS_EXIT_GROUP: usize = 94; +pub const SYS_FACCESSAT: usize = 48; +pub const SYS_FACCESSAT2: usize = 439; +pub const SYS_FADVISE64: usize = 223; +pub const SYS_FALLOCATE: usize = 47; +pub const SYS_FANOTIFY_INIT: usize = 262; +pub const SYS_FANOTIFY_MARK: usize = 263; +pub const SYS_FCHDIR: usize = 50; +pub const SYS_FCHMOD: usize = 52; +pub const SYS_FCHMODAT: usize = 53; +pub const SYS_FCHOWN: usize = 55; +pub const SYS_FCHOWNAT: usize = 54; +pub const SYS_FCNTL: usize = 25; +pub const SYS_FDATASYNC: usize = 83; +pub const SYS_FGETXATTR: usize = 10; +pub const SYS_FINIT_MODULE: usize = 273; +pub const SYS_FLISTXATTR: usize = 13; +pub const SYS_FLOCK: usize = 32; +pub const SYS_FREMOVEXATTR: usize = 16; +pub const SYS_FSCONFIG: usize = 431; +pub const SYS_FSETXATTR: usize = 7; +pub const SYS_FSMOUNT: usize = 432; +pub const SYS_FSOPEN: usize = 430; +pub const SYS_FSPICK: usize = 433; +pub const SYS_FSTAT: usize = 80; +pub const SYS_FSTATFS: usize = 44; +pub const SYS_FSYNC: usize = 82; +pub const SYS_FTRUNCATE: usize = 46; +pub const SYS_FUTEX: usize = 98; +pub const SYS_GET_MEMPOLICY: usize = 236; +pub const SYS_GET_ROBUST_LIST: usize = 100; +pub const SYS_GETCPU: usize = 168; +pub const SYS_GETCWD: usize = 17; +pub const SYS_GETDENTS64: usize = 61; +pub const SYS_GETEGID: usize = 177; +pub const SYS_GETEUID: usize = 175; +pub const SYS_GETGID: usize = 176; +pub const SYS_GETGROUPS: usize = 158; +pub const SYS_GETITIMER: usize = 102; +pub const SYS_GETPEERNAME: usize = 205; +pub const SYS_GETPGID: usize = 155; +pub const SYS_GETPID: usize = 172; +pub const SYS_GETPPID: usize = 173; +pub const SYS_GETPRIORITY: usize = 141; +pub const SYS_GETRANDOM: usize = 278; +pub const SYS_GETRESGID: usize = 150; +pub const SYS_GETRESUID: usize = 148; +pub const SYS_GETRLIMIT: usize = 163; +pub const SYS_GETRUSAGE: usize = 165; +pub const SYS_GETSID: usize = 156; +pub const SYS_GETSOCKNAME: usize = 204; +pub const SYS_GETSOCKOPT: usize = 209; +pub const SYS_GETTID: usize = 178; +pub const SYS_GETTIMEOFDAY: usize = 169; +pub const SYS_GETUID: usize = 174; +pub const SYS_GETXATTR: usize = 8; +pub const SYS_INIT_MODULE: usize = 105; +pub const SYS_INOTIFY_ADD_WATCH: usize = 27; +pub const SYS_INOTIFY_INIT1: usize = 26; +pub const SYS_INOTIFY_RM_WATCH: usize = 28; +pub const SYS_IO_CANCEL: usize = 3; +pub const SYS_IO_DESTROY: usize = 1; +pub const SYS_IO_GETEVENTS: usize = 4; +pub const SYS_IO_PGETEVENTS: usize = 292; +pub const SYS_IO_SETUP: usize = 0; +pub const SYS_IO_SUBMIT: usize = 2; +pub const SYS_IO_URING_ENTER: usize = 426; +pub const SYS_IO_URING_REGISTER: usize = 427; +pub const SYS_IO_URING_SETUP: usize = 425; +pub const SYS_IOCTL: usize = 29; +pub const SYS_IOPRIO_GET: usize = 31; +pub const SYS_IOPRIO_SET: usize = 30; +pub const SYS_KCMP: usize = 272; +pub const SYS_KEXEC_FILE_LOAD: usize = 294; +pub const SYS_KEXEC_LOAD: usize = 104; +pub const SYS_KEYCTL: usize = 219; +pub const SYS_KILL: usize = 129; +pub const SYS_LGETXATTR: usize = 9; +pub const SYS_LINKAT: usize = 37; +pub const SYS_LISTEN: usize = 201; +pub const SYS_LISTXATTR: usize = 11; +pub const SYS_LLISTXATTR: usize = 12; +pub const SYS_LOOKUP_DCOOKIE: usize = 18; +pub const SYS_LREMOVEXATTR: usize = 15; +pub const SYS_LSEEK: usize = 62; +pub const SYS_LSETXATTR: usize = 6; +pub const SYS_MADVISE: usize = 233; +pub const SYS_MBIND: usize = 235; +pub const SYS_MEMBARRIER: usize = 283; +pub const SYS_MEMFD_CREATE: usize = 279; +pub const SYS_MIGRATE_PAGES: usize = 238; +pub const SYS_MINCORE: usize = 232; +pub const SYS_MKDIRAT: usize = 34; +pub const SYS_MKNODAT: usize = 33; +pub const SYS_MLOCK: usize = 228; +pub const SYS_MLOCK2: usize = 284; +pub const SYS_MLOCKALL: usize = 230; +pub const SYS_MMAP: usize = 222; +pub const SYS_MOUNT: usize = 40; +pub const SYS_MOUNT_SETATTR: usize = 442; +pub const SYS_MOVE_MOUNT: usize = 429; +pub const SYS_MOVE_PAGES: usize = 239; +pub const SYS_MPROTECT: usize = 226; +pub const SYS_MQ_GETSETATTR: usize = 185; +pub const SYS_MQ_NOTIFY: usize = 184; +pub const SYS_MQ_OPEN: usize = 180; +pub const SYS_MQ_TIMEDRECEIVE: usize = 183; +pub const SYS_MQ_TIMEDSEND: usize = 182; +pub const SYS_MQ_UNLINK: usize = 181; +pub const SYS_MREMAP: usize = 216; +pub const SYS_MSGCTL: usize = 187; +pub const SYS_MSGGET: usize = 186; +pub const SYS_MSGRCV: usize = 188; +pub const SYS_MSGSND: usize = 189; +pub const SYS_MSYNC: usize = 227; +pub const SYS_MUNLOCK: usize = 229; +pub const SYS_MUNLOCKALL: usize = 231; +pub const SYS_MUNMAP: usize = 215; +pub const SYS_NAME_TO_HANDLE_AT: usize = 264; +pub const SYS_NANOSLEEP: usize = 101; +pub const SYS_NEWFSTATAT: usize = 79; +pub const SYS_NFSSERVCTL: usize = 42; +pub const SYS_OPEN_BY_HANDLE_AT: usize = 265; +pub const SYS_OPEN_TREE: usize = 428; +pub const SYS_OPENAT: usize = 56; +pub const SYS_OPENAT2: usize = 437; +pub const SYS_PERF_EVENT_OPEN: usize = 241; +pub const SYS_PERSONALITY: usize = 92; +pub const SYS_PIDFD_GETFD: usize = 438; +pub const SYS_PIDFD_OPEN: usize = 434; +pub const SYS_PIDFD_SEND_SIGNAL: usize = 424; +pub const SYS_PIPE2: usize = 59; +pub const SYS_PIVOT_ROOT: usize = 41; +pub const SYS_PKEY_ALLOC: usize = 289; +pub const SYS_PKEY_FREE: usize = 290; +pub const SYS_PKEY_MPROTECT: usize = 288; +pub const SYS_PPOLL: usize = 73; +pub const SYS_PRCTL: usize = 167; +pub const SYS_PREAD64: usize = 67; +pub const SYS_PREADV: usize = 69; +pub const SYS_PREADV2: usize = 286; +pub const SYS_PRLIMIT64: usize = 261; +pub const SYS_PROCESS_MADVISE: usize = 440; +pub const SYS_PROCESS_VM_READV: usize = 270; +pub const SYS_PROCESS_VM_WRITEV: usize = 271; +pub const SYS_PSELECT6: usize = 72; +pub const SYS_PTRACE: usize = 117; +pub const SYS_PWRITE64: usize = 68; +pub const SYS_PWRITEV: usize = 70; +pub const SYS_PWRITEV2: usize = 287; +pub const SYS_QUOTACTL: usize = 60; +pub const SYS_READ: usize = 63; +pub const SYS_READAHEAD: usize = 213; +pub const SYS_READLINKAT: usize = 78; +pub const SYS_READV: usize = 65; +pub const SYS_REBOOT: usize = 142; +pub const SYS_RECVFROM: usize = 207; +pub const SYS_RECVMMSG: usize = 243; +pub const SYS_RECVMSG: usize = 212; +pub const SYS_REMAP_FILE_PAGES: usize = 234; +pub const SYS_REMOVEXATTR: usize = 14; +pub const SYS_RENAMEAT2: usize = 276; +pub const SYS_REQUEST_KEY: usize = 218; +pub const SYS_RESTART_SYSCALL: usize = 128; +pub const SYS_RISCV_FLUSH_ICACHE: usize = 259; +pub const SYS_RSEQ: usize = 293; +pub const SYS_RT_SIGACTION: usize = 134; +pub const SYS_RT_SIGPENDING: usize = 136; +pub const SYS_RT_SIGPROCMASK: usize = 135; +pub const SYS_RT_SIGQUEUEINFO: usize = 138; +pub const SYS_RT_SIGRETURN: usize = 139; +pub const SYS_RT_SIGSUSPEND: usize = 133; +pub const SYS_RT_SIGTIMEDWAIT: usize = 137; +pub const SYS_RT_TGSIGQUEUEINFO: usize = 240; +pub const SYS_SCHED_GET_PRIORITY_MAX: usize = 125; +pub const SYS_SCHED_GET_PRIORITY_MIN: usize = 126; +pub const SYS_SCHED_GETAFFINITY: usize = 123; +pub const SYS_SCHED_GETATTR: usize = 275; +pub const SYS_SCHED_GETPARAM: usize = 121; +pub const SYS_SCHED_GETSCHEDULER: usize = 120; +pub const SYS_SCHED_RR_GET_INTERVAL: usize = 127; +pub const SYS_SCHED_SETAFFINITY: usize = 122; +pub const SYS_SCHED_SETATTR: usize = 274; +pub const SYS_SCHED_SETPARAM: usize = 118; +pub const SYS_SCHED_SETSCHEDULER: usize = 119; +pub const SYS_SCHED_YIELD: usize = 124; +pub const SYS_SECCOMP: usize = 277; +pub const SYS_SEMCTL: usize = 191; +pub const SYS_SEMGET: usize = 190; +pub const SYS_SEMOP: usize = 193; +pub const SYS_SEMTIMEDOP: usize = 192; +pub const SYS_SENDFILE: usize = 71; +pub const SYS_SENDMMSG: usize = 269; +pub const SYS_SENDMSG: usize = 211; +pub const SYS_SENDTO: usize = 206; +pub const SYS_SET_MEMPOLICY: usize = 237; +pub const SYS_SET_ROBUST_LIST: usize = 99; +pub const SYS_SET_TID_ADDRESS: usize = 96; +pub const SYS_SETDOMAINNAME: usize = 162; +pub const SYS_SETFSGID: usize = 152; +pub const SYS_SETFSUID: usize = 151; +pub const SYS_SETGID: usize = 144; +pub const SYS_SETGROUPS: usize = 159; +pub const SYS_SETHOSTNAME: usize = 161; +pub const SYS_SETITIMER: usize = 103; +pub const SYS_SETNS: usize = 268; +pub const SYS_SETPGID: usize = 154; +pub const SYS_SETPRIORITY: usize = 140; +pub const SYS_SETREGID: usize = 143; +pub const SYS_SETRESGID: usize = 149; +pub const SYS_SETRESUID: usize = 147; +pub const SYS_SETREUID: usize = 145; +pub const SYS_SETRLIMIT: usize = 164; +pub const SYS_SETSID: usize = 157; +pub const SYS_SETSOCKOPT: usize = 208; +pub const SYS_SETTIMEOFDAY: usize = 170; +pub const SYS_SETUID: usize = 146; +pub const SYS_SETXATTR: usize = 5; +pub const SYS_SHMAT: usize = 196; +pub const SYS_SHMCTL: usize = 195; +pub const SYS_SHMDT: usize = 197; +pub const SYS_SHMGET: usize = 194; +pub const SYS_SHUTDOWN: usize = 210; +pub const SYS_SIGALTSTACK: usize = 132; +pub const SYS_SIGNALFD4: usize = 74; +pub const SYS_SOCKET: usize = 198; +pub const SYS_SOCKETPAIR: usize = 199; +pub const SYS_SPLICE: usize = 76; +pub const SYS_STATFS: usize = 43; +pub const SYS_STATX: usize = 291; +pub const SYS_SWAPOFF: usize = 225; +pub const SYS_SWAPON: usize = 224; +pub const SYS_SYMLINKAT: usize = 36; +pub const SYS_SYNC: usize = 81; +pub const SYS_SYNC_FILE_RANGE: usize = 84; +pub const SYS_SYNCFS: usize = 267; +pub const SYS_SYSCALLS: usize = 443; +pub const SYS_SYSINFO: usize = 179; +pub const SYS_SYSLOG: usize = 116; +pub const SYS_TEE: usize = 77; +pub const SYS_TGKILL: usize = 131; +pub const SYS_TIMER_CREATE: usize = 107; +pub const SYS_TIMER_DELETE: usize = 111; +pub const SYS_TIMER_GETOVERRUN: usize = 109; +pub const SYS_TIMER_GETTIME: usize = 108; +pub const SYS_TIMER_SETTIME: usize = 110; +pub const SYS_TIMERFD_CREATE: usize = 85; +pub const SYS_TIMERFD_GETTIME: usize = 87; +pub const SYS_TIMERFD_SETTIME: usize = 86; +pub const SYS_TIMES: usize = 153; +pub const SYS_TKILL: usize = 130; +pub const SYS_TRUNCATE: usize = 45; +pub const SYS_UMASK: usize = 166; +pub const SYS_UMOUNT2: usize = 39; +pub const SYS_UNAME: usize = 160; +pub const SYS_UNLINKAT: usize = 35; +pub const SYS_UNSHARE: usize = 97; +pub const SYS_USERFAULTFD: usize = 282; +pub const SYS_UTIMENSAT: usize = 88; +pub const SYS_VHANGUP: usize = 58; +pub const SYS_VMSPLICE: usize = 75; +pub const SYS_WAIT4: usize = 260; +pub const SYS_WAITID: usize = 95; +pub const SYS_WRITE: usize = 64; +pub const SYS_WRITEV: usize = 66; + +// ===以下是为了代码一致性,才定义的调用号=== + +pub const SYS_GETDENTS: usize = SYS_GETDENTS64; diff --git a/kernel/src/arch/riscv64/time.rs b/kernel/src/arch/riscv64/time.rs new file mode 100644 index 00000000..75fa0b6d --- /dev/null +++ b/kernel/src/arch/riscv64/time.rs @@ -0,0 +1,8 @@ +use crate::time::TimeArch; +pub struct RiscV64TimeArch; + +impl TimeArch for RiscV64TimeArch { + fn get_cycles() -> usize { + unimplemented!("Riscv64TimeArch::get_cycles") + } +} diff --git a/kernel/src/arch/x86_64/cpu.rs b/kernel/src/arch/x86_64/cpu.rs index 96ad425d..300088cf 100644 --- a/kernel/src/arch/x86_64/cpu.rs +++ b/kernel/src/arch/x86_64/cpu.rs @@ -9,7 +9,7 @@ pub fn current_cpu_id() -> u32 { } /// 重置cpu -pub fn cpu_reset() -> ! { +pub unsafe fn cpu_reset() -> ! { // 重启计算机 unsafe { x86::io::outb(0x64, 0xfe) }; loop {} diff --git a/kernel/src/arch/x86_64/driver/apic/apic.h b/kernel/src/arch/x86_64/driver/apic/apic.h index 4eea5c96..1d95dc69 100644 --- a/kernel/src/arch/x86_64/driver/apic/apic.h +++ b/kernel/src/arch/x86_64/driver/apic/apic.h @@ -4,6 +4,7 @@ #include #include #include +#include #pragma GCC push_options #pragma GCC optimize("O0") @@ -222,15 +223,52 @@ void rs_apic_init_ap(); */ int apic_init(); -// =========== 中断控制操作接口 ============ -void apic_ioapic_enable(ul irq_num); +#if ARCH(I386) || ARCH(X86_64) + + // =========== 中断控制操作接口 ============ + void apic_ioapic_enable(ul irq_num); void apic_ioapic_disable(ul irq_num); ul apic_ioapic_install(ul irq_num, void *arg); void apic_ioapic_uninstall(ul irq_num); -void apic_ioapic_edge_ack(ul irq_num); // ioapic边沿触发 应答 +void apic_ioapic_edge_ack(ul irq_num); // ioapic边沿触发 应答 // void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答 void apic_local_apic_edge_ack(ul irq_num); // local apic边沿触发 应答 +#else +void apic_ioapic_enable(ul irq_num) +{ + while (1) + ; +} +void apic_ioapic_disable(ul irq_num) +{ + while (1) + ; +} +ul apic_ioapic_install(ul irq_num, void *arg) +{ + while (1) + ; +} +void apic_ioapic_uninstall(ul irq_num) +{ + while (1) + ; +} +void apic_ioapic_edge_ack(ul irq_num) +{ + while (1) + ; +} // ioapic边沿触发 应答 + +// void apic_local_apic_level_ack(ul irq_num);// local apic电平触发 应答 +void apic_local_apic_edge_ack(ul irq_num) +{ + while (1) + ; +} // local apic边沿触发 应答 + +#endif /** * @brief 构造RTE Entry结构体 diff --git a/kernel/src/arch/x86_64/include/asm/asm.h b/kernel/src/arch/x86_64/include/asm/asm.h index d65abb68..cb92daef 100644 --- a/kernel/src/arch/x86_64/include/asm/asm.h +++ b/kernel/src/arch/x86_64/include/asm/asm.h @@ -4,13 +4,7 @@ #include #include -// 定义类型的缩写 -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ul; -typedef unsigned long long int ull; -typedef long long int ll; + #define sti() __asm__ __volatile__("sti\n\t" :: \ : "memory") // 开启外部中断 @@ -135,35 +129,6 @@ unsigned long *get_rbx() return tmp; } -// ========= MSR寄存器组操作 ============= -/** - * @brief 向msr寄存器组的address处的寄存器写入值value - * - * @param address 地址 - * @param value 要写入的值 - */ -void wrmsr(uint64_t address, uint64_t value) -{ - __asm__ __volatile__("wrmsr \n\t" ::"d"(value >> 32), "a"(value & 0xffffffff), "c"(address) - : "memory"); -} - -/** - * @brief 从msr寄存器组的address地址处读取值 - * rdmsr返回高32bits在edx,低32bits在eax - * @param address 地址 - * @return uint64_t address处的寄存器的值 - */ -uint64_t rdmsr(uint64_t address) -{ - unsigned int tmp0, tmp1; - __asm__ __volatile__("rdmsr \n\t" - : "=d"(tmp0), "=a"(tmp1) - : "c"(address) - : "memory"); - return ((uint64_t)tmp0 << 32) | tmp1; -} - uint64_t get_rflags() { unsigned long tmp = 0; @@ -416,4 +381,30 @@ static __always_inline uint32_t __read4b(uint64_t vaddr) : "a"(vaddr) : "memory"); return retval; -} \ No newline at end of file +} + + +/** + * @brief 逐字节比较指定内存区域的值,并返回s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。 + * 若两块内存区域的内容相同,则返回0 + * + * @param s1 内存区域1 + * @param s2 内存区域2 + * @param len 要比较的内存区域长度 + * @return int s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。若两块内存区域的内容相同,则返回0 + */ +static inline int memcmp(const void *s1, const void *s2, size_t len) +{ + int diff; + + asm("cld \n\t" // 复位DF,确保s1、s2指针是自增的 + "repz; cmpsb\n\t" CC_SET(nz) + : CC_OUT(nz)(diff), "+D"(s1), "+S"(s2) + : "c"(len) + : "memory"); + + if (diff) + diff = *(const unsigned char *)(s1 - 1) - *(const unsigned char *)(s2 - 1); + + return diff; +} diff --git a/kernel/src/link.lds b/kernel/src/arch/x86_64/link.lds similarity index 100% rename from kernel/src/link.lds rename to kernel/src/arch/x86_64/link.lds diff --git a/kernel/src/arch/x86_64/mm/c_adapter.rs b/kernel/src/arch/x86_64/mm/c_adapter.rs new file mode 100644 index 00000000..90926ea9 --- /dev/null +++ b/kernel/src/arch/x86_64/mm/c_adapter.rs @@ -0,0 +1,7 @@ +use super::LowAddressRemapping; + +#[no_mangle] +unsafe extern "C" fn rs_unmap_at_low_addr() -> usize { + LowAddressRemapping::unmap_at_low_address(true); + return 0; +} diff --git a/kernel/src/arch/x86_64/mm/mod.rs b/kernel/src/arch/x86_64/mm/mod.rs index 105b714b..5226b069 100644 --- a/kernel/src/arch/x86_64/mm/mod.rs +++ b/kernel/src/arch/x86_64/mm/mod.rs @@ -1,5 +1,6 @@ pub mod barrier; pub mod bump; +mod c_adapter; use alloc::vec::Vec; use hashbrown::HashSet; @@ -233,6 +234,60 @@ impl MemoryManagementArch for X86_64MMArch { return Ok(crate::mm::ucontext::UserMapper::new(new_umapper)); } + + const PAGE_SIZE: usize = 1 << Self::PAGE_SHIFT; + + const PAGE_OFFSET_MASK: usize = Self::PAGE_SIZE - 1; + + const PAGE_MASK: usize = !(Self::PAGE_OFFSET_MASK); + + const PAGE_ADDRESS_SHIFT: usize = Self::PAGE_LEVELS * Self::PAGE_ENTRY_SHIFT + Self::PAGE_SHIFT; + + const PAGE_ADDRESS_SIZE: usize = 1 << Self::PAGE_ADDRESS_SHIFT; + + const PAGE_ADDRESS_MASK: usize = Self::PAGE_ADDRESS_SIZE - Self::PAGE_SIZE; + + const PAGE_ENTRY_SIZE: usize = 1 << (Self::PAGE_SHIFT - Self::PAGE_ENTRY_SHIFT); + + const PAGE_ENTRY_NUM: usize = 1 << Self::PAGE_ENTRY_SHIFT; + + const PAGE_ENTRY_MASK: usize = Self::PAGE_ENTRY_NUM - 1; + + const PAGE_NEGATIVE_MASK: usize = !((Self::PAGE_ADDRESS_SIZE) - 1); + + const ENTRY_ADDRESS_SIZE: usize = 1 << Self::ENTRY_ADDRESS_SHIFT; + + const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - Self::PAGE_SIZE; + + const ENTRY_FLAGS_MASK: usize = !Self::ENTRY_ADDRESS_MASK; + + unsafe fn read(address: VirtAddr) -> T { + return core::ptr::read(address.data() as *const T); + } + + unsafe fn write(address: VirtAddr, value: T) { + core::ptr::write(address.data() as *mut T, value); + } + + unsafe fn write_bytes(address: VirtAddr, value: u8, count: usize) { + core::ptr::write_bytes(address.data() as *mut u8, value, count); + } + + unsafe fn phys_2_virt(phys: PhysAddr) -> Option { + if let Some(vaddr) = phys.data().checked_add(Self::PHYS_OFFSET) { + return Some(VirtAddr::new(vaddr)); + } else { + return None; + } + } + + unsafe fn virt_2_phys(virt: VirtAddr) -> Option { + if let Some(paddr) = virt.data().checked_sub(Self::PHYS_OFFSET) { + return Some(PhysAddr::new(paddr)); + } else { + return None; + } + } } impl X86_64MMArch { @@ -542,6 +597,7 @@ pub fn test_buddy() { kdebug!("release done!, allocated: {allocated}, free_count: {free_count}"); } } + /// 全局的页帧分配器 #[derive(Debug, Clone, Copy, Hash)] pub struct LockedFrameAllocator; @@ -571,12 +627,6 @@ impl FrameAllocator for LockedFrameAllocator { } } -impl LockedFrameAllocator { - pub fn get_usage(&self) -> PageFrameUsage { - unsafe { self.usage() } - } -} - /// 获取内核地址默认的页面标志 pub unsafe fn kernel_page_flags(virt: VirtAddr) -> PageFlags { let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.clone().unwrap(); diff --git a/kernel/src/arch/x86_64/msi.rs b/kernel/src/arch/x86_64/msi.rs index 5f24e063..650e7f01 100644 --- a/kernel/src/arch/x86_64/msi.rs +++ b/kernel/src/arch/x86_64/msi.rs @@ -2,7 +2,7 @@ use crate::driver::pci::pci_irq::TriggerMode; /// @brief 获得MSI Message Address /// @param processor 目标CPU ID号 /// @return MSI Message Address -pub fn ia64_pci_get_arch_msi_message_address(processor: u16) -> u32 { +pub fn arch_msi_message_address(processor: u16) -> u32 { 0xfee00000 | ((processor as u32) << 12) } /// @brief 获得MSI Message Data @@ -10,11 +10,7 @@ pub fn ia64_pci_get_arch_msi_message_address(processor: u16) -> u32 { /// @param processor 目标CPU ID号 /// @param trigger 申请中断的触发模式,MSI默认为边沿触发 /// @return MSI Message Address -pub fn ia64_pci_get_arch_msi_message_data( - vector: u16, - _processor: u16, - trigger: TriggerMode, -) -> u32 { +pub fn arch_msi_message_data(vector: u16, _processor: u16, trigger: TriggerMode) -> u32 { match trigger { TriggerMode::EdgeTrigger => vector as u32, TriggerMode::AssertHigh => vector as u32 | 1 << 15 | 1 << 14, diff --git a/kernel/src/arch/x86_64/process/c_adapter.rs b/kernel/src/arch/x86_64/process/c_adapter.rs index c315d991..8c5d46fd 100644 --- a/kernel/src/arch/x86_64/process/c_adapter.rs +++ b/kernel/src/arch/x86_64/process/c_adapter.rs @@ -1,8 +1,15 @@ +use crate::kdebug; + use super::table::TSSManager; #[no_mangle] unsafe extern "C" fn set_current_core_tss(stack_start: usize, ist0: usize) { let current_tss = TSSManager::current_tss(); + kdebug!( + "set_current_core_tss: stack_start={:#x}, ist0={:#x}\n", + stack_start, + ist0 + ); current_tss.set_rsp(x86::Ring::Ring0, stack_start as u64); current_tss.set_ist(0, ist0 as u64); } diff --git a/kernel/src/arch/x86_64/process/mod.rs b/kernel/src/arch/x86_64/process/mod.rs index 358d8be2..102aa2f3 100644 --- a/kernel/src/arch/x86_64/process/mod.rs +++ b/kernel/src/arch/x86_64/process/mod.rs @@ -17,7 +17,7 @@ use x86::{controlregs::Cr4, segmentation::SegmentSelector}; use crate::{ arch::process::table::TSSManager, exception::InterruptArch, - kwarn, + kerror, kwarn, libs::spinlock::SpinLockGuard, mm::{ percpu::{PerCpu, PerCpuVar}, @@ -275,10 +275,13 @@ impl ProcessControlBlock { pub fn arch_current_pcb() -> Arc { // 获取栈指针 let ptr = VirtAddr::new(x86::current::registers::rsp() as usize); + let stack_base = VirtAddr::new(ptr.data() & (!(KernelStack::ALIGN - 1))); + // 从内核栈的最低地址处取出pcb的地址 let p = stack_base.data() as *const *const ProcessControlBlock; if unlikely((unsafe { *p }).is_null()) { + kerror!("p={:p}", p); panic!("current_pcb is null"); } unsafe { diff --git a/kernel/src/arch/x86_64/rand.rs b/kernel/src/arch/x86_64/rand.rs index 7d507669..6916c64d 100644 --- a/kernel/src/arch/x86_64/rand.rs +++ b/kernel/src/arch/x86_64/rand.rs @@ -1,38 +1,5 @@ use core::arch::x86_64::_rdtsc; -use alloc::vec::Vec; - -use crate::{ - libs::rand::GRandFlags, - syscall::{user_access::UserBufferWriter, Syscall, SystemError}, -}; - pub fn rand() -> usize { return unsafe { (_rdtsc() * _rdtsc() + 998244353_u64 * _rdtsc()) as usize }; } - -impl Syscall { - /// ## 将随机字节填入buf - /// - /// ### 该系统调用与linux不一致,因为目前没有其他随机源 - pub fn get_random(buf: *mut u8, len: usize, flags: GRandFlags) -> Result { - if flags.bits() == (GRandFlags::GRND_INSECURE.bits() | GRandFlags::GRND_RANDOM.bits()) { - return Err(SystemError::EINVAL); - } - - let mut writer = UserBufferWriter::new(buf, len, true)?; - - let mut ret = Vec::new(); - let mut count = 0; - while count < len { - let rand = rand(); - for offset in 0..4 { - ret.push((rand >> offset * 2) as u8); - count += 1; - } - } - - writer.copy_to_user(&ret, 0)?; - Ok(len) - } -} diff --git a/kernel/src/arch/x86_64/syscall.rs b/kernel/src/arch/x86_64/syscall/mod.rs similarity index 85% rename from kernel/src/arch/x86_64/syscall.rs rename to kernel/src/arch/x86_64/syscall/mod.rs index 6ef96d90..a967ab71 100644 --- a/kernel/src/arch/x86_64/syscall.rs +++ b/kernel/src/arch/x86_64/syscall/mod.rs @@ -1,33 +1,24 @@ use core::ffi::c_void; use crate::{ - arch::{ipc::signal::X86_64SignalArch, CurrentIrqArch}, + arch::{ + ipc::signal::X86_64SignalArch, + syscall::nr::{SYS_ARCH_PRCTL, SYS_RT_SIGRETURN}, + CurrentIrqArch, + }, exception::InterruptArch, include::bindings::bindings::set_system_trap_gate, ipc::signal_types::SignalArch, libs::align::SafeForZero, mm::VirtAddr, process::ProcessManager, - syscall::{Syscall, SystemError, SYS_RT_SIGRETURN}, + syscall::{Syscall, SystemError, SYS_SCHED}, }; use alloc::string::String; use super::{interrupt::TrapFrame, mm::barrier::mfence}; -pub const SYS_LSTAT: usize = 6; -pub const SYS_READV: usize = 19; -pub const SYS_ACCESS: usize = 21; -pub const SYS_UNLINK: usize = 87; -pub const SYS_CHMOD: usize = 90; -pub const SYS_FCHMOD: usize = 91; -pub const SYS_UMASK: usize = 95; -pub const SYS_SYSINFO: usize = 99; -pub const SYS_CLOCK_GETTIME: usize = 228; -pub const SYS_OPENAT: usize = 257; -pub const SYS_FCHMODAT: usize = 268; -pub const SYS_FACCESSAT: usize = 269; -pub const SYS_PRLIMIT64: usize = 302; -pub const SYS_FACCESSAT2: usize = 439; +pub mod nr; /// ### 存储PCB系统调用栈以及在syscall过程中暂存用户态rsp的结构体 /// @@ -73,10 +64,14 @@ macro_rules! syscall_return { #[no_mangle] pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () { - unsafe { - CurrentIrqArch::interrupt_enable(); - } let syscall_num = frame.rax as usize; + // 防止sys_sched由于超时无法退出导致的死锁 + if syscall_num != SYS_SCHED { + unsafe { + CurrentIrqArch::interrupt_enable(); + } + } + let args = [ frame.rdi as usize, frame.rsi as usize, @@ -107,6 +102,14 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () { show ); } + SYS_ARCH_PRCTL => { + syscall_return!( + Syscall::arch_prctl(args[0], args[1]) + .unwrap_or_else(|e| e.to_posix_errno() as usize), + frame, + show + ); + } _ => {} } syscall_return!( diff --git a/kernel/src/arch/x86_64/syscall/nr.rs b/kernel/src/arch/x86_64/syscall/nr.rs new file mode 100644 index 00000000..c37dc36c --- /dev/null +++ b/kernel/src/arch/x86_64/syscall/nr.rs @@ -0,0 +1,357 @@ +#![allow(dead_code)] +#![allow(non_upper_case_globals)] +#![allow(non_snake_case)] +pub const SYS__SYSCTL: usize = 156; +pub const SYS_ACCEPT: usize = 43; +pub const SYS_ACCEPT4: usize = 288; +pub const SYS_ACCESS: usize = 21; +pub const SYS_ACCT: usize = 163; +pub const SYS_ADD_KEY: usize = 248; +pub const SYS_ADJTIMEX: usize = 159; +pub const SYS_AFS_SYSCALL: usize = 183; +pub const SYS_ALARM: usize = 37; +pub const SYS_ARCH_PRCTL: usize = 158; +pub const SYS_BIND: usize = 49; +pub const SYS_BPF: usize = 321; +pub const SYS_BRK: usize = 12; +pub const SYS_CAPGET: usize = 125; +pub const SYS_CAPSET: usize = 126; +pub const SYS_CHDIR: usize = 80; +pub const SYS_CHMOD: usize = 90; +pub const SYS_CHOWN: usize = 92; +pub const SYS_CHROOT: usize = 161; +pub const SYS_CLOCK_ADJTIME: usize = 305; +pub const SYS_CLOCK_GETRES: usize = 229; +pub const SYS_CLOCK_GETTIME: usize = 228; +pub const SYS_CLOCK_NANOSLEEP: usize = 230; +pub const SYS_CLOCK_SETTIME: usize = 227; +pub const SYS_CLONE: usize = 56; +pub const SYS_CLONE3: usize = 435; +pub const SYS_CLOSE: usize = 3; +pub const SYS_CLOSE_RANGE: usize = 436; +pub const SYS_CONNECT: usize = 42; +pub const SYS_COPY_FILE_RANGE: usize = 326; +pub const SYS_CREAT: usize = 85; +pub const SYS_CREATE_MODULE: usize = 174; +pub const SYS_DELETE_MODULE: usize = 176; +pub const SYS_DUP: usize = 32; +pub const SYS_DUP2: usize = 33; +pub const SYS_DUP3: usize = 292; +pub const SYS_EPOLL_CREATE: usize = 213; +pub const SYS_EPOLL_CREATE1: usize = 291; +pub const SYS_EPOLL_CTL: usize = 233; +pub const SYS_EPOLL_CTL_OLD: usize = 214; +pub const SYS_EPOLL_PWAIT: usize = 281; +pub const SYS_EPOLL_PWAIT2: usize = 441; +pub const SYS_EPOLL_WAIT: usize = 232; +pub const SYS_EPOLL_WAIT_OLD: usize = 215; +pub const SYS_EVENTFD: usize = 284; +pub const SYS_EVENTFD2: usize = 290; +pub const SYS_EXECVE: usize = 59; +pub const SYS_EXECVEAT: usize = 322; +pub const SYS_EXIT: usize = 60; +pub const SYS_EXIT_GROUP: usize = 231; +pub const SYS_FACCESSAT: usize = 269; +pub const SYS_FACCESSAT2: usize = 439; +pub const SYS_FADVISE64: usize = 221; +pub const SYS_FALLOCATE: usize = 285; +pub const SYS_FANOTIFY_INIT: usize = 300; +pub const SYS_FANOTIFY_MARK: usize = 301; +pub const SYS_FCHDIR: usize = 81; +pub const SYS_FCHMOD: usize = 91; +pub const SYS_FCHMODAT: usize = 268; +pub const SYS_FCHOWN: usize = 93; +pub const SYS_FCHOWNAT: usize = 260; +pub const SYS_FCNTL: usize = 72; +pub const SYS_FDATASYNC: usize = 75; +pub const SYS_FGETXATTR: usize = 193; +pub const SYS_FINIT_MODULE: usize = 313; +pub const SYS_FLISTXATTR: usize = 196; +pub const SYS_FLOCK: usize = 73; +pub const SYS_FORK: usize = 57; +pub const SYS_FREMOVEXATTR: usize = 199; +pub const SYS_FSCONFIG: usize = 431; +pub const SYS_FSETXATTR: usize = 190; +pub const SYS_FSMOUNT: usize = 432; +pub const SYS_FSOPEN: usize = 430; +pub const SYS_FSPICK: usize = 433; +pub const SYS_FSTAT: usize = 5; +pub const SYS_FSTATFS: usize = 138; +pub const SYS_FSYNC: usize = 74; +pub const SYS_FTRUNCATE: usize = 77; +pub const SYS_FUTEX: usize = 202; +pub const SYS_FUTIMESAT: usize = 261; +pub const SYS_GET_KERNEL_SYMS: usize = 177; +pub const SYS_GET_MEMPOLICY: usize = 239; +pub const SYS_GET_ROBUST_LIST: usize = 274; +pub const SYS_GET_THREAD_AREA: usize = 211; +pub const SYS_GETCPU: usize = 309; +pub const SYS_GETCWD: usize = 79; +pub const SYS_GETDENTS: usize = 78; +pub const SYS_GETDENTS64: usize = 217; +pub const SYS_GETEGID: usize = 108; +pub const SYS_GETEUID: usize = 107; +pub const SYS_GETGID: usize = 104; +pub const SYS_GETGROUPS: usize = 115; +pub const SYS_GETITIMER: usize = 36; +pub const SYS_GETPEERNAME: usize = 52; +pub const SYS_GETPGID: usize = 121; +pub const SYS_GETPGRP: usize = 111; +pub const SYS_GETPID: usize = 39; +pub const SYS_GETPMSG: usize = 181; +pub const SYS_GETPPID: usize = 110; +pub const SYS_GETPRIORITY: usize = 140; +pub const SYS_GETRANDOM: usize = 318; +pub const SYS_GETRESGID: usize = 120; +pub const SYS_GETRESUID: usize = 118; +pub const SYS_GETRLIMIT: usize = 97; +pub const SYS_GETRUSAGE: usize = 98; +pub const SYS_GETSID: usize = 124; +pub const SYS_GETSOCKNAME: usize = 51; +pub const SYS_GETSOCKOPT: usize = 55; +pub const SYS_GETTID: usize = 186; +pub const SYS_GETTIMEOFDAY: usize = 96; +pub const SYS_GETUID: usize = 102; +pub const SYS_GETXATTR: usize = 191; +pub const SYS_INIT_MODULE: usize = 175; +pub const SYS_INOTIFY_ADD_WATCH: usize = 254; +pub const SYS_INOTIFY_INIT: usize = 253; +pub const SYS_INOTIFY_INIT1: usize = 294; +pub const SYS_INOTIFY_RM_WATCH: usize = 255; +pub const SYS_IO_CANCEL: usize = 210; +pub const SYS_IO_DESTROY: usize = 207; +pub const SYS_IO_GETEVENTS: usize = 208; +pub const SYS_IO_PGETEVENTS: usize = 333; +pub const SYS_IO_SETUP: usize = 206; +pub const SYS_IO_SUBMIT: usize = 209; +pub const SYS_IO_URING_ENTER: usize = 426; +pub const SYS_IO_URING_REGISTER: usize = 427; +pub const SYS_IO_URING_SETUP: usize = 425; +pub const SYS_IOCTL: usize = 16; +pub const SYS_IOPERM: usize = 173; +pub const SYS_IOPL: usize = 172; +pub const SYS_IOPRIO_GET: usize = 252; +pub const SYS_IOPRIO_SET: usize = 251; +pub const SYS_KCMP: usize = 312; +pub const SYS_KEXEC_FILE_LOAD: usize = 320; +pub const SYS_KEXEC_LOAD: usize = 246; +pub const SYS_KEYCTL: usize = 250; +pub const SYS_KILL: usize = 62; +pub const SYS_LCHOWN: usize = 94; +pub const SYS_LGETXATTR: usize = 192; +pub const SYS_LINK: usize = 86; +pub const SYS_LINKAT: usize = 265; +pub const SYS_LISTEN: usize = 50; +pub const SYS_LISTXATTR: usize = 194; +pub const SYS_LLISTXATTR: usize = 195; +pub const SYS_LOOKUP_DCOOKIE: usize = 212; +pub const SYS_LREMOVEXATTR: usize = 198; +pub const SYS_LSEEK: usize = 8; +pub const SYS_LSETXATTR: usize = 189; +pub const SYS_LSTAT: usize = 6; +pub const SYS_MADVISE: usize = 28; +pub const SYS_MBIND: usize = 237; +pub const SYS_MEMBARRIER: usize = 324; +pub const SYS_MEMFD_CREATE: usize = 319; +pub const SYS_MIGRATE_PAGES: usize = 256; +pub const SYS_MINCORE: usize = 27; +pub const SYS_MKDIR: usize = 83; +pub const SYS_MKDIRAT: usize = 258; +pub const SYS_MKNOD: usize = 133; +pub const SYS_MKNODAT: usize = 259; +pub const SYS_MLOCK: usize = 149; +pub const SYS_MLOCK2: usize = 325; +pub const SYS_MLOCKALL: usize = 151; +pub const SYS_MMAP: usize = 9; +pub const SYS_MODIFY_LDT: usize = 154; +pub const SYS_MOUNT: usize = 165; +pub const SYS_MOUNT_SETATTR: usize = 442; +pub const SYS_MOVE_MOUNT: usize = 429; +pub const SYS_MOVE_PAGES: usize = 279; +pub const SYS_MPROTECT: usize = 10; +pub const SYS_MQ_GETSETATTR: usize = 245; +pub const SYS_MQ_NOTIFY: usize = 244; +pub const SYS_MQ_OPEN: usize = 240; +pub const SYS_MQ_TIMEDRECEIVE: usize = 243; +pub const SYS_MQ_TIMEDSEND: usize = 242; +pub const SYS_MQ_UNLINK: usize = 241; +pub const SYS_MREMAP: usize = 25; +pub const SYS_MSGCTL: usize = 71; +pub const SYS_MSGGET: usize = 68; +pub const SYS_MSGRCV: usize = 70; +pub const SYS_MSGSND: usize = 69; +pub const SYS_MSYNC: usize = 26; +pub const SYS_MUNLOCK: usize = 150; +pub const SYS_MUNLOCKALL: usize = 152; +pub const SYS_MUNMAP: usize = 11; +pub const SYS_NAME_TO_HANDLE_AT: usize = 303; +pub const SYS_NANOSLEEP: usize = 35; +pub const SYS_NEWFSTATAT: usize = 262; +pub const SYS_NFSSERVCTL: usize = 180; +pub const SYS_OPEN: usize = 2; +pub const SYS_OPEN_BY_HANDLE_AT: usize = 304; +pub const SYS_OPEN_TREE: usize = 428; +pub const SYS_OPENAT: usize = 257; +pub const SYS_OPENAT2: usize = 437; +pub const SYS_PAUSE: usize = 34; +pub const SYS_PERF_EVENT_OPEN: usize = 298; +pub const SYS_PERSONALITY: usize = 135; +pub const SYS_PIDFD_GETFD: usize = 438; +pub const SYS_PIDFD_OPEN: usize = 434; +pub const SYS_PIDFD_SEND_SIGNAL: usize = 424; +pub const SYS_PIPE: usize = 22; +pub const SYS_PIPE2: usize = 293; +pub const SYS_PIVOT_ROOT: usize = 155; +pub const SYS_PKEY_ALLOC: usize = 330; +pub const SYS_PKEY_FREE: usize = 331; +pub const SYS_PKEY_MPROTECT: usize = 329; +pub const SYS_POLL: usize = 7; +pub const SYS_PPOLL: usize = 271; +pub const SYS_PRCTL: usize = 157; +pub const SYS_PREAD64: usize = 17; +pub const SYS_PREADV: usize = 295; +pub const SYS_PREADV2: usize = 327; +pub const SYS_PRLIMIT64: usize = 302; +pub const SYS_PROCESS_MADVISE: usize = 440; +pub const SYS_PROCESS_VM_READV: usize = 310; +pub const SYS_PROCESS_VM_WRITEV: usize = 311; +pub const SYS_PSELECT6: usize = 270; +pub const SYS_PTRACE: usize = 101; +pub const SYS_PUTPMSG: usize = 182; +pub const SYS_PWRITE64: usize = 18; +pub const SYS_PWRITEV: usize = 296; +pub const SYS_PWRITEV2: usize = 328; +pub const SYS_QUERY_MODULE: usize = 178; +pub const SYS_QUOTACTL: usize = 179; +pub const SYS_READ: usize = 0; +pub const SYS_READAHEAD: usize = 187; +pub const SYS_READLINK: usize = 89; +pub const SYS_READLINKAT: usize = 267; +pub const SYS_READV: usize = 19; +pub const SYS_REBOOT: usize = 169; +pub const SYS_RECVFROM: usize = 45; +pub const SYS_RECVMMSG: usize = 299; +pub const SYS_RECVMSG: usize = 47; +pub const SYS_REMAP_FILE_PAGES: usize = 216; +pub const SYS_REMOVEXATTR: usize = 197; +pub const SYS_RENAME: usize = 82; +pub const SYS_RENAMEAT: usize = 264; +pub const SYS_RENAMEAT2: usize = 316; +pub const SYS_REQUEST_KEY: usize = 249; +pub const SYS_RESTART_SYSCALL: usize = 219; +pub const SYS_RMDIR: usize = 84; +pub const SYS_RSEQ: usize = 334; +pub const SYS_RT_SIGACTION: usize = 13; +pub const SYS_RT_SIGPENDING: usize = 127; +pub const SYS_RT_SIGPROCMASK: usize = 14; +pub const SYS_RT_SIGQUEUEINFO: usize = 129; +pub const SYS_RT_SIGRETURN: usize = 15; +pub const SYS_RT_SIGSUSPEND: usize = 130; +pub const SYS_RT_SIGTIMEDWAIT: usize = 128; +pub const SYS_RT_TGSIGQUEUEINFO: usize = 297; +pub const SYS_SCHED_GET_PRIORITY_MAX: usize = 146; +pub const SYS_SCHED_GET_PRIORITY_MIN: usize = 147; +pub const SYS_SCHED_GETAFFINITY: usize = 204; +pub const SYS_SCHED_GETATTR: usize = 315; +pub const SYS_SCHED_GETPARAM: usize = 143; +pub const SYS_SCHED_GETSCHEDULER: usize = 145; +pub const SYS_SCHED_RR_GET_INTERVAL: usize = 148; +pub const SYS_SCHED_SETAFFINITY: usize = 203; +pub const SYS_SCHED_SETATTR: usize = 314; +pub const SYS_SCHED_SETPARAM: usize = 142; +pub const SYS_SCHED_SETSCHEDULER: usize = 144; +pub const SYS_SCHED_YIELD: usize = 24; +pub const SYS_SECCOMP: usize = 317; +pub const SYS_SECURITY: usize = 185; +pub const SYS_SELECT: usize = 23; +pub const SYS_SEMCTL: usize = 66; +pub const SYS_SEMGET: usize = 64; +pub const SYS_SEMOP: usize = 65; +pub const SYS_SEMTIMEDOP: usize = 220; +pub const SYS_SENDFILE: usize = 40; +pub const SYS_SENDMMSG: usize = 307; +pub const SYS_SENDMSG: usize = 46; +pub const SYS_SENDTO: usize = 44; +pub const SYS_SET_MEMPOLICY: usize = 238; +pub const SYS_SET_ROBUST_LIST: usize = 273; +pub const SYS_SET_THREAD_AREA: usize = 205; +pub const SYS_SET_TID_ADDRESS: usize = 218; +pub const SYS_SETDOMAINNAME: usize = 171; +pub const SYS_SETFSGID: usize = 123; +pub const SYS_SETFSUID: usize = 122; +pub const SYS_SETGID: usize = 106; +pub const SYS_SETGROUPS: usize = 116; +pub const SYS_SETHOSTNAME: usize = 170; +pub const SYS_SETITIMER: usize = 38; +pub const SYS_SETNS: usize = 308; +pub const SYS_SETPGID: usize = 109; +pub const SYS_SETPRIORITY: usize = 141; +pub const SYS_SETREGID: usize = 114; +pub const SYS_SETRESGID: usize = 119; +pub const SYS_SETRESUID: usize = 117; +pub const SYS_SETREUID: usize = 113; +pub const SYS_SETRLIMIT: usize = 160; +pub const SYS_SETSID: usize = 112; +pub const SYS_SETSOCKOPT: usize = 54; +pub const SYS_SETTIMEOFDAY: usize = 164; +pub const SYS_SETUID: usize = 105; +pub const SYS_SETXATTR: usize = 188; +pub const SYS_SHMAT: usize = 30; +pub const SYS_SHMCTL: usize = 31; +pub const SYS_SHMDT: usize = 67; +pub const SYS_SHMGET: usize = 29; +pub const SYS_SHUTDOWN: usize = 48; +pub const SYS_SIGALTSTACK: usize = 131; +pub const SYS_SIGNALFD: usize = 282; +pub const SYS_SIGNALFD4: usize = 289; +pub const SYS_SOCKET: usize = 41; +pub const SYS_SOCKETPAIR: usize = 53; +pub const SYS_SPLICE: usize = 275; +pub const SYS_STAT: usize = 4; +pub const SYS_STATFS: usize = 137; +pub const SYS_STATX: usize = 332; +pub const SYS_SWAPOFF: usize = 168; +pub const SYS_SWAPON: usize = 167; +pub const SYS_SYMLINK: usize = 88; +pub const SYS_SYMLINKAT: usize = 266; +pub const SYS_SYNC: usize = 162; +pub const SYS_SYNC_FILE_RANGE: usize = 277; +pub const SYS_SYNCFS: usize = 306; +pub const SYS_SYSFS: usize = 139; +pub const SYS_SYSINFO: usize = 99; +pub const SYS_SYSLOG: usize = 103; +pub const SYS_TEE: usize = 276; +pub const SYS_TGKILL: usize = 234; +pub const SYS_TIME: usize = 201; +pub const SYS_TIMER_CREATE: usize = 222; +pub const SYS_TIMER_DELETE: usize = 226; +pub const SYS_TIMER_GETOVERRUN: usize = 225; +pub const SYS_TIMER_GETTIME: usize = 224; +pub const SYS_TIMER_SETTIME: usize = 223; +pub const SYS_TIMERFD_CREATE: usize = 283; +pub const SYS_TIMERFD_GETTIME: usize = 287; +pub const SYS_TIMERFD_SETTIME: usize = 286; +pub const SYS_TIMES: usize = 100; +pub const SYS_TKILL: usize = 200; +pub const SYS_TRUNCATE: usize = 76; +pub const SYS_TUXCALL: usize = 184; +pub const SYS_UMASK: usize = 95; +pub const SYS_UMOUNT2: usize = 166; +pub const SYS_UNAME: usize = 63; +pub const SYS_UNLINK: usize = 87; +pub const SYS_UNLINKAT: usize = 263; +pub const SYS_UNSHARE: usize = 272; +pub const SYS_USELIB: usize = 134; +pub const SYS_USERFAULTFD: usize = 323; +pub const SYS_USTAT: usize = 136; +pub const SYS_UTIME: usize = 132; +pub const SYS_UTIMENSAT: usize = 280; +pub const SYS_UTIMES: usize = 235; +pub const SYS_VFORK: usize = 58; +pub const SYS_VHANGUP: usize = 153; +pub const SYS_VMSPLICE: usize = 278; +pub const SYS_VSERVER: usize = 236; +pub const SYS_WAIT4: usize = 61; +pub const SYS_WAITID: usize = 247; +pub const SYS_WRITE: usize = 1; +pub const SYS_WRITEV: usize = 20; diff --git a/kernel/src/common/asm.h b/kernel/src/common/asm.h index 9d7973ee..7220c6f9 100644 --- a/kernel/src/common/asm.h +++ b/kernel/src/common/asm.h @@ -3,11 +3,6 @@ #ifndef __ASM__ #define __ASM__ - - - - - // 符号名 #define SYMBOL_NAME(X) X // 符号名字符串 diff --git a/kernel/src/common/atomic.h b/kernel/src/common/atomic.h index 88981818..1488a7ea 100644 --- a/kernel/src/common/atomic.h +++ b/kernel/src/common/atomic.h @@ -9,6 +9,8 @@ * */ #pragma once +#if ARCH(I386) || ARCH(X86_64) + #include #define atomic_read(atomic) ((atomic)->value) // 读取原子变量 @@ -105,3 +107,4 @@ inline long atomic_cmpxchg(atomic_t *ato, long oldval, long newval) bool success = arch_try_cmpxchg(&ato->value, &oldval, newval); return success ? oldval : newval; } +#endif \ No newline at end of file diff --git a/kernel/src/common/idr.h b/kernel/src/common/idr.h index 273749fe..86ba22c8 100644 --- a/kernel/src/common/idr.h +++ b/kernel/src/common/idr.h @@ -1,6 +1,10 @@ +#pragma once + +#if ARCH(I386) || ARCH(X86_64) #pragma GCC push_options #pragma GCC optimize("O1") + #include #include @@ -170,4 +174,6 @@ bool ida_count(struct ida *ida_p, int id); void ida_remove(struct ida *ida_p, int id); void ida_destroy(struct ida *ida_p); -#pragma GCC pop_options \ No newline at end of file +#pragma GCC pop_options + +#endif \ No newline at end of file diff --git a/kernel/src/common/math.h b/kernel/src/common/math.h index 6e38a669..d77958ea 100644 --- a/kernel/src/common/math.h +++ b/kernel/src/common/math.h @@ -1,10 +1,13 @@ #pragma once #include "stddef.h" #include +#if ARCH(I386) || ARCH(X86_64) + #if ARCH(I386) || ARCH(X86_64) #include #else #error Arch not supported. #endif +#endif int64_t pow(int64_t x, int y); diff --git a/kernel/src/common/stddef.h b/kernel/src/common/stddef.h index 6bccef75..3f3fea3c 100644 --- a/kernel/src/common/stddef.h +++ b/kernel/src/common/stddef.h @@ -8,4 +8,12 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t; // Signed integer type of the result of subt #ifndef __always_inline #define __always_inline __inline__ -#endif \ No newline at end of file +#endif + +// 定义类型的缩写 +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ul; +typedef unsigned long long int ull; +typedef long long int ll; \ No newline at end of file diff --git a/kernel/src/common/string.h b/kernel/src/common/string.h index 899367b2..a918aea5 100644 --- a/kernel/src/common/string.h +++ b/kernel/src/common/string.h @@ -40,7 +40,7 @@ long strnlen(const char *src, unsigned long maxlen); int strcmp(const char *FirstPart, const char *SecondPart); -char *strncpy(char *dst, const char *src, long count); +char *strncpy(char *restrict d, const char *restrict s, size_t n); long strncpy_from_user(char *dst, const char *src, unsigned long size); @@ -52,31 +52,6 @@ long strncpy_from_user(char *dst, const char *src, unsigned long size); */ long strnlen_user(const char *src, unsigned long maxlen); -/** - * @brief 逐字节比较指定内存区域的值,并返回s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。 - * 若两块内存区域的内容相同,则返回0 - * - * @param s1 内存区域1 - * @param s2 内存区域2 - * @param len 要比较的内存区域长度 - * @return int s1、s2的第一个不相等的字节i处的差值(s1[i]-s2[i])。若两块内存区域的内容相同,则返回0 - */ -static inline int memcmp(const void *s1, const void *s2, size_t len) -{ - int diff; - - asm("cld \n\t" // 复位DF,确保s1、s2指针是自增的 - "repz; cmpsb\n\t" CC_SET(nz) - : CC_OUT(nz)(diff), "+D"(s1), "+S"(s2) - : "c"(len) - : "memory"); - - if (diff) - diff = *(const unsigned char *)(s1 - 1) - *(const unsigned char *)(s2 - 1); - - return diff; -} - /** * @brief 拼接两个字符串(将src接到dest末尾) * diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index 7f097749..48f9aacc 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -12,12 +12,11 @@ use crate::driver::disk::ahci::HBA_PxIS_TFES; use crate::filesystem::kernfs::KernFSInode; use crate::filesystem::mbr::MbrDiskPartionTable; -use crate::include::bindings::bindings::verify_area; use crate::kdebug; use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; use crate::libs::{spinlock::SpinLock, vec_cursor::VecCursor}; -use crate::mm::phys_2_virt; +use crate::mm::{phys_2_virt, verify_area, VirtAddr}; use crate::syscall::SystemError; use crate::{ driver::disk::ahci::hba::{ @@ -108,11 +107,8 @@ impl AhciDisk { // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间 // TODO:在内存管理重构后,可以直接使用用户空间的内存地址 - let user_buf = if unsafe { verify_area(buf_ptr as u64, buf.len() as u64) } { - true - } else { - false - }; + + let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok(); let mut kbuf = if user_buf { let mut x: Vec = Vec::new(); x.resize(buf.len(), 0); @@ -267,11 +263,7 @@ impl AhciDisk { // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间 // TODO:在内存管理重构后,可以直接使用用户空间的内存地址 - let user_buf = if unsafe { verify_area(buf_ptr as u64, buf.len() as u64) } { - true - } else { - false - }; + let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok(); let mut kbuf = if user_buf { let mut x: Vec = Vec::with_capacity(buf.len()); x.resize(buf.len(), 0); diff --git a/kernel/src/driver/pci/pci_irq.c b/kernel/src/driver/pci/pci_irq.c index 5778ba96..5c5cbe53 100644 --- a/kernel/src/driver/pci/pci_irq.c +++ b/kernel/src/driver/pci/pci_irq.c @@ -12,7 +12,7 @@ void pci_irq_enable(ul irq_num) void pci_irq_disable(ul irq_num) { } -ul pci_irq_install(ul, void*) +ul pci_irq_install(ul num , void* data) { } void pci_irq_uninstall(ul irq_num) diff --git a/kernel/src/driver/pci/pci_irq.rs b/kernel/src/driver/pci/pci_irq.rs index 2f7d72b8..240e91ad 100644 --- a/kernel/src/driver/pci/pci_irq.rs +++ b/kernel/src/driver/pci/pci_irq.rs @@ -7,7 +7,7 @@ use alloc::ffi::CString; use alloc::vec::Vec; use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError}; -use crate::arch::msi::{ia64_pci_get_arch_msi_message_address, ia64_pci_get_arch_msi_message_data}; +use crate::arch::msi::{arch_msi_message_address, arch_msi_message_data}; use crate::arch::{PciArch, TraitPciArch}; use crate::include::bindings::bindings::{ c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL, @@ -370,14 +370,14 @@ pub trait PciInterrupt: PciDeviceStructure { } //MSI中断只需配置一次PCI寄存器 if common_msg.irq_index == 0 { - let msg_address = ia64_pci_get_arch_msi_message_address(0); + let msg_address = arch_msi_message_address(0); let trigger = match msg.irq_specific_message { IrqSpecificMsg::Legacy => { return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); } IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode, }; - let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger); + let msg_data = arch_msi_message_data(irq_num, 0, trigger); //写入Message Data和Message Address if address_64 { PciArch::write_config( @@ -518,14 +518,14 @@ pub trait PciInterrupt: PciDeviceStructure { _ => {} } - let msg_address = ia64_pci_get_arch_msi_message_address(0); + let msg_address = arch_msi_message_address(0); let trigger = match msg.irq_specific_message { IrqSpecificMsg::Legacy => { return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); } IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode, }; - let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger); + let msg_data = arch_msi_message_data(irq_num, 0, trigger); //写入Message Data和Message Address let pcistandardbar = self .bar() diff --git a/kernel/src/driver/timers/rtc/rtc.rs b/kernel/src/driver/timers/rtc/rtc.rs index e7e154e4..f30e5502 100644 --- a/kernel/src/driver/timers/rtc/rtc.rs +++ b/kernel/src/driver/timers/rtc/rtc.rs @@ -1,7 +1,6 @@ use crate::{ - arch::CurrentIrqArch, + arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch}, exception::InterruptArch, - include::bindings::bindings::{io_in8, io_out8}, syscall::SystemError, }; @@ -63,7 +62,7 @@ impl RtcTime { } unsafe { - io_out8(0x70, 0x00); + CurrentPortIOArch::out8(0x70, 0x00); } if !is_binary @@ -92,8 +91,8 @@ impl RtcTime { #[inline] fn read_cmos(addr: u8) -> u8 { unsafe { - io_out8(0x70, 0x80 | addr); - return io_in8(0x71); + CurrentPortIOArch::out8(0x70, 0x80 | addr); + return CurrentPortIOArch::in8(0x71); } } diff --git a/kernel/src/exception/gate.h b/kernel/src/exception/gate.h index 32deb002..ae0666f4 100644 --- a/kernel/src/exception/gate.h +++ b/kernel/src/exception/gate.h @@ -8,19 +8,20 @@ #ifndef __GATE_H__ #define __GATE_H__ +#pragma GCC push_options +#pragma GCC optimize("O0") +#if ARCH(I386) || ARCH(X86_64) #include #include -#pragma GCC push_options -#pragma GCC optimize("O0") -//描述符表的结构体 +// 描述符表的结构体 struct desc_struct { unsigned char x[8]; }; -//门的结构体 +// 门的结构体 struct gate_struct { unsigned char x[16]; @@ -28,19 +29,19 @@ struct gate_struct extern struct desc_struct GDT_Table[]; // GDT_Table是head.S中的GDT_Table extern struct gate_struct IDT_Table[]; // IDT_Table是head.S中的IDT_Table -//extern unsigned int TSS64_Table[26]; +// extern unsigned int TSS64_Table[26]; struct gdtr { uint16_t size; uint64_t gdt_vaddr; -}__attribute__((packed)); +} __attribute__((packed)); struct idtr { uint16_t size; uint64_t idt_vaddr; -}__attribute__((packed)); +} __attribute__((packed)); /** * @brief 初始化中段描述符表内的门描述符(每个16B) @@ -54,20 +55,20 @@ void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr) { ul __d0 = 0, __d1 = 0; ul tmp_code_addr = *code_addr; - __d0 = attr << 40; //设置P、DPL、Type + __d0 = attr << 40; // 设置P、DPL、Type __d0 |= ((ul)(ist) << 32); // 设置ist - __d0 |= 8 << 16; //设置段选择子为0x1000 + __d0 |= 8 << 16; // 设置段选择子为0x1000 - __d0 |= (0xffff & tmp_code_addr); //设置段内偏移的[15:00] + __d0 |= (0xffff & tmp_code_addr); // 设置段内偏移的[15:00] tmp_code_addr >>= 16; __d0 |= (0xffff & tmp_code_addr) << 48; // 设置段内偏移[31:16] tmp_code_addr >>= 16; - __d1 = (0xffffffff & tmp_code_addr); //设置段内偏移[63:32] + __d1 = (0xffffffff & tmp_code_addr); // 设置段内偏移[63:32] *gate_selector_addr = __d0; *(gate_selector_addr + 1) = __d1; @@ -101,7 +102,7 @@ void set_tss_descriptor(unsigned int n, void *addr) { unsigned long limit = 103; - + *(unsigned long *)(phys_2_virt(GDT_Table + n)) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute *(unsigned long *)(phys_2_virt(GDT_Table + n + 1)) = (((unsigned long)addr >> 32) & 0xffffffff) | 0; } @@ -127,8 +128,8 @@ void set_tss_descriptor(unsigned int n, void *addr) void set_intr_gate(unsigned int n, unsigned char ist, void *addr) { _set_gate(phys_2_virt(IDT_Table + n), 0x8E, ist, addr); // p=1,DPL=0, type=E - - //set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1,DPL=0, type=E + + // set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1,DPL=0, type=E } /** @@ -142,7 +143,7 @@ void set_trap_gate(unsigned int n, unsigned char ist, void *addr) { // kdebug("addr=%#018lx", (ul)(addr)); - //set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1,DPL=0, type=F + // set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1,DPL=0, type=F _set_gate(phys_2_virt(IDT_Table + n), 0x8F, ist, addr); // p=1,DPL=0, type=F } @@ -157,14 +158,13 @@ void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr) { // kdebug("addr=%#018lx", (ul)(addr)); - //set_gate((ul *)phys_2_virt(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1,DPL=3, type=F + // set_gate((ul *)phys_2_virt(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1,DPL=3, type=F _set_gate(phys_2_virt(IDT_Table + n), 0xEF, ist, addr); // p=1,DPL=3, type=F } - -static inline void set_system_intr_gate(unsigned int n,unsigned char ist,void * addr) //int3 +static inline void set_system_intr_gate(unsigned int n, unsigned char ist, void *addr) // int3 { - _set_gate(phys_2_virt(IDT_Table + n) , 0xEE , ist , addr); //P,DPL=3,TYPE=E + _set_gate(phys_2_virt(IDT_Table + n), 0xEE, ist, addr); // P,DPL=3,TYPE=E } /** * @brief 初始化TSS表的内容 @@ -186,6 +186,14 @@ void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsi *(unsigned long *)(Table + 19) = ist6; *(unsigned long *)(Table + 21) = ist7; } + +#else +void set_intr_gate(unsigned int n, unsigned char ist, void *addr) +{ + while (1) + ; +} #endif -#pragma GCC pop_options \ No newline at end of file +#pragma GCC pop_options +#endif \ No newline at end of file diff --git a/kernel/src/exception/irq.c b/kernel/src/exception/irq.c index 78f1cf33..a7c08221 100644 --- a/kernel/src/exception/irq.c +++ b/kernel/src/exception/irq.c @@ -13,10 +13,18 @@ #include #include #include +#include extern void ignore_int(); #pragma GCC push_options #pragma GCC optimize("O0") + +// 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt +#define IRQ_NAME2(name1) name1##interrupt(void) +#define IRQ_NAME(number) IRQ_NAME2(IRQ##number) + +#if ARCH(I386) || ARCH(X86_64) + // 保存函数调用现场的寄存器 #define SAVE_ALL_REGS \ "cld; \n\t" \ @@ -45,9 +53,7 @@ extern void ignore_int(); "movq %rdx, %ds; \n\t" \ "movq %rdx, %es; \n\t" -// 定义IRQ处理函数的名字格式:IRQ+中断号+interrupt -#define IRQ_NAME2(name1) name1##interrupt(void) -#define IRQ_NAME(number) IRQ_NAME2(IRQ##number) + // 构造中断entry // 为了复用返回函数的代码,需要压入一个错误码0 @@ -60,7 +66,15 @@ extern void ignore_int(); "pushq %rax \n\t" \ "movq $" #number ", %rsi \n\t" \ "jmp do_IRQ \n\t"); - +#elif ARCH(riscv) +#define Build_IRQ(number) \ + void IRQ_NAME(number); \ + __asm__(SYMBOL_NAME_STR(IRQ) #number "interrupt: \n\t" \ + "loopirq_"#number":\n\t"\ + "j loopirq_"#number"\n\t"); +#else +#define Build_IRQ(number) () +#endif // 构造中断入口 Build_IRQ(0x20); Build_IRQ(0x21); @@ -256,8 +270,10 @@ void irq_init() init_8259A(); #else +#if ARCH(I386) || ARCH(X86_64) memset((void *)interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM); apic_init(); +#endif #endif } diff --git a/kernel/src/exception/trap.c b/kernel/src/exception/trap.c index 57dc035d..be559be7 100644 --- a/kernel/src/exception/trap.c +++ b/kernel/src/exception/trap.c @@ -5,6 +5,7 @@ #include #include #include +#include extern void ignore_int(); @@ -204,9 +205,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) { cli(); unsigned long cr2 = 0; - +#if ARCH(I386) || ARCH(X86_64) __asm__ __volatile__("movq %%cr2, %0" : "=r"(cr2)::"memory"); - +#endif kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, regs->rsp, regs->rbp, regs->rip, rs_current_pcb_cpuid(), rs_current_pcb_pid()); kerror("regs->rax = %#018lx\n", regs->rax); @@ -308,6 +309,8 @@ void ignore_int_handler(struct pt_regs *regs, unsigned long error_code) void sys_vector_init() { + +#if ARCH(I386) || ARCH(X86_64) // 将idt重置为新的ignore_int入点(此前在head.S中有设置, // 但是那个不完整,某些版本的编译器的输出,在真机运行时会破坏进程执行环境,从而导致#GP for (int i = 0; i < 256; ++i) @@ -337,4 +340,5 @@ void sys_vector_init() // 中断号21-31由Intel保留,不能使用 // 32-255为用户自定义中断内部 +#endif } \ No newline at end of file diff --git a/kernel/src/filesystem/procfs/mod.rs b/kernel/src/filesystem/procfs/mod.rs index 1e5e74c3..5b106717 100644 --- a/kernel/src/filesystem/procfs/mod.rs +++ b/kernel/src/filesystem/procfs/mod.rs @@ -20,6 +20,7 @@ use crate::{ once::Once, spinlock::{SpinLock, SpinLockGuard}, }, + mm::allocator::page_frame::FrameAllocator, process::{Pid, ProcessManager}, syscall::SystemError, time::TimeSpec, @@ -212,7 +213,7 @@ impl ProcFSInode { /// 打开 meminfo 文件 fn open_meminfo(&self, pdata: &mut ProcfsFilePrivateData) -> Result { // 获取内存信息 - let usage = LockedFrameAllocator.get_usage(); + let usage = unsafe { LockedFrameAllocator.usage() }; // 传入数据 let data: &mut Vec = &mut pdata.data; diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 01f7a361..13857ba2 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -1,5 +1,3 @@ -use core::mem::MaybeUninit; - use alloc::{string::String, sync::Arc, vec::Vec}; use crate::{ @@ -419,28 +417,16 @@ impl Drop for File { #[derive(Debug)] pub struct FileDescriptorVec { /// 当前进程打开的文件描述符 - fds: [Option>>; FileDescriptorVec::PROCESS_MAX_FD], + fds: Vec>>>, } impl FileDescriptorVec { pub const PROCESS_MAX_FD: usize = 1024; + #[inline(never)] pub fn new() -> FileDescriptorVec { - // 先声明一个未初始化的数组 - let mut data: [MaybeUninit>>>; - FileDescriptorVec::PROCESS_MAX_FD] = unsafe { MaybeUninit::uninit().assume_init() }; - - // 逐个把每个元素初始化为None - for i in 0..FileDescriptorVec::PROCESS_MAX_FD { - data[i] = MaybeUninit::new(None); - } - // 由于一切都初始化完毕,因此将未初始化的类型强制转换为已经初始化的类型 - let data: [Option>>; FileDescriptorVec::PROCESS_MAX_FD] = unsafe { - core::mem::transmute::< - _, - [Option>>; FileDescriptorVec::PROCESS_MAX_FD], - >(data) - }; + let mut data = Vec::with_capacity(FileDescriptorVec::PROCESS_MAX_FD); + data.resize(FileDescriptorVec::PROCESS_MAX_FD, None); // 初始化文件描述符数组结构体 return FileDescriptorVec { fds: data }; diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 964d7044..6c8939c3 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -9,10 +9,9 @@ use alloc::{ use crate::{ driver::base::{block::SeekFrom, device::DeviceNumber}, filesystem::vfs::file::FileDescriptorVec, - include::bindings::bindings::verify_area, kerror, libs::rwlock::RwLockWriteGuard, - mm::VirtAddr, + mm::{verify_area, VirtAddr}, process::ProcessManager, syscall::{ user_access::{check_and_clone_cstr, UserBufferReader, UserBufferWriter}, @@ -994,12 +993,11 @@ impl IoVecs { _readv: bool, ) -> Result { // 检查iov指针所在空间是否合法 - if !verify_area( - iov as usize as u64, - (iovcnt * core::mem::size_of::()) as u64, - ) { - return Err(SystemError::EFAULT); - } + verify_area( + VirtAddr::new(iov as usize), + iovcnt * core::mem::size_of::(), + ) + .map_err(|_| SystemError::EFAULT)?; // 将用户空间的IoVec转换为引用(注意:这里的引用是静态的,因为用户空间的IoVec不会被释放) let iovs: &[IoVec] = core::slice::from_raw_parts(iov, iovcnt); @@ -1012,9 +1010,11 @@ impl IoVecs { continue; } - if !verify_area(iov.iov_base as usize as u64, iov.iov_len as u64) { - return Err(SystemError::EFAULT); - } + verify_area( + VirtAddr::new(iov.iov_base as usize), + iovcnt * core::mem::size_of::(), + ) + .map_err(|_| SystemError::EFAULT)?; slices.push(core::slice::from_raw_parts_mut(iov.iov_base, iov.iov_len)); } diff --git a/kernel/src/include/DragonOS/refcount.h b/kernel/src/include/DragonOS/refcount.h index 6ebb44e5..64dcbafa 100644 --- a/kernel/src/include/DragonOS/refcount.h +++ b/kernel/src/include/DragonOS/refcount.h @@ -1,7 +1,12 @@ #pragma once + +#if ARCH(I386) || ARCH(X86_64) + #include // 该结构体需要与libs/refcount.rs的保持一致,且以rust版本为准 typedef struct refcount_struct { atomic_t refs; -} refcount_t; \ No newline at end of file +} refcount_t; + +#endif \ No newline at end of file diff --git a/kernel/src/include/bindings/wrapper.h b/kernel/src/include/bindings/wrapper.h index d4b6b65f..60f0858d 100644 --- a/kernel/src/include/bindings/wrapper.h +++ b/kernel/src/include/bindings/wrapper.h @@ -10,6 +10,7 @@ */ #pragma once + #include #include #include diff --git a/kernel/src/ktest/test-idr.c b/kernel/src/ktest/test-idr.c index 567c455e..38c5fcaa 100644 --- a/kernel/src/ktest/test-idr.c +++ b/kernel/src/ktest/test-idr.c @@ -1,4 +1,8 @@ +#include + +#if ARCH(I386) || ARCH(X86_64) + #pragma GCC push_options #pragma GCC optimize("O1") #include "ktest.h" @@ -590,4 +594,6 @@ int ktest_test_idr(void *arg) return 0; } -#pragma GCC pop_options \ No newline at end of file +#pragma GCC pop_options + +#endif \ No newline at end of file diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index e8ed7d1b..fec0fdb8 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -53,6 +53,8 @@ mod sched; mod smp; mod syscall; mod time; + +#[cfg(target_arch = "x86_64")] mod virt; #[macro_use] @@ -79,7 +81,7 @@ use crate::mm::allocator::kernel_allocator::KernelAllocator; use crate::process::ProcessManager; -#[cfg(feature = "backtrace")] +#[cfg(all(feature = "backtrace", target_arch = "x86_64"))] extern crate mini_backtrace; extern "C" { @@ -120,7 +122,7 @@ pub fn panic(info: &PanicInfo) -> ! { } } - #[cfg(feature = "backtrace")] + #[cfg(all(feature = "backtrace", target_arch = "x86_64"))] { unsafe { let bt = mini_backtrace::Backtrace::<16>::capture(); diff --git a/kernel/src/libs/atomic.rs b/kernel/src/libs/atomic.rs deleted file mode 100644 index 6e942167..00000000 --- a/kernel/src/libs/atomic.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![allow(dead_code)] -use core::ptr::{read_volatile, write_volatile}; - -use crate::include::bindings::bindings::atomic_t; - -/// @brief 原子的读取指定的原子变量的值 -#[inline] -pub fn atomic_read(ato: *const atomic_t) -> i64 { - unsafe { - return read_volatile(&(*ato).value); - } -} - -/// @brief 原子的设置原子变量的值 -#[inline] -pub fn atomic_set(ato: *mut atomic_t, value: i64) { - unsafe { - write_volatile(&mut (*ato).value, value); - } -} - -impl Default for atomic_t { - fn default() -> Self { - Self { value: 0 } - } -} diff --git a/kernel/src/libs/cpu.c b/kernel/src/libs/cpu.c index 36a30aff..bfb179b7 100644 --- a/kernel/src/libs/cpu.c +++ b/kernel/src/libs/cpu.c @@ -30,6 +30,9 @@ uint Cpu_max_linear_addrline_size; uint64_t Cpu_tsc_freq = 0; struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM]; + +#if ARCH(I386) || ARCH(X86_64) + void cpu_init(void) { // 获取处理器制造商信息 @@ -100,3 +103,7 @@ void cpu_cpuid(uint32_t mop, uint32_t sop, uint32_t *eax, uint32_t *ebx, uint32_ : "0"(mop), "2"(sop) : "memory"); } + +#else +void cpu_init(void){} +#endif \ No newline at end of file diff --git a/kernel/src/libs/elf.rs b/kernel/src/libs/elf.rs index 24f1d5bb..77eb5507 100644 --- a/kernel/src/libs/elf.rs +++ b/kernel/src/libs/elf.rs @@ -37,7 +37,7 @@ pub struct ElfLoader; pub const ELF_LOADER: ElfLoader = ElfLoader::new(); impl ElfLoader { - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] pub const ELF_PAGE_SIZE: usize = MMArch::PAGE_SIZE; /// 读取文件的缓冲区大小 @@ -47,8 +47,7 @@ impl ElfLoader { Self } - #[cfg(target_arch = "x86_64")] - pub fn probe_x86_64( + fn inner_probe_common( &self, param: &ExecParam, ehdr: &FileHeader, @@ -58,11 +57,6 @@ impl ElfLoader { return Err(ExecError::WrongArchitecture); } - // 判断架构是否匹配 - if ElfMachine::from(ehdr.e_machine) != ElfMachine::X86_64 { - return Err(ExecError::WrongArchitecture); - } - // 判断是否以可执行文件的形式加载 if param.load_mode() == ExecLoadMode::Exec { // 检查文件类型是否为可执行文件 @@ -76,6 +70,32 @@ impl ElfLoader { return Ok(()); } + #[cfg(target_arch = "x86_64")] + pub fn probe_x86_64( + &self, + param: &ExecParam, + ehdr: &FileHeader, + ) -> Result<(), ExecError> { + // 判断架构是否匹配 + if ElfMachine::from(ehdr.e_machine) != ElfMachine::X86_64 { + return Err(ExecError::WrongArchitecture); + } + return self.inner_probe_common(param, ehdr); + } + + #[cfg(target_arch = "riscv64")] + pub fn probe_riscv( + &self, + param: &ExecParam, + ehdr: &FileHeader, + ) -> Result<(), ExecError> { + // 判断架构是否匹配 + if ElfMachine::from(ehdr.e_machine) != ElfMachine::RiscV { + return Err(ExecError::WrongArchitecture); + } + return self.inner_probe_common(param, ehdr); + } + /// 设置用户堆空间,映射[start, end)区间的虚拟地址,并把brk指针指向end /// /// ## 参数 @@ -471,8 +491,11 @@ impl BinaryLoader for ElfLoader { #[cfg(target_arch = "x86_64")] return self.probe_x86_64(param, &ehdr); - #[cfg(not(target_arch = "x86_64"))] - unimplemented!("Unsupported architecture"); + #[cfg(target_arch = "riscv64")] + return self.probe_riscv(param, &ehdr); + + #[cfg(not(any(target_arch = "x86_64", target_arch = "riscv64")))] + compile_error!("BinaryLoader: Unsupported architecture"); } fn load( diff --git a/kernel/src/libs/idr.c b/kernel/src/libs/idr.c index 54a585b9..46a417a2 100644 --- a/kernel/src/libs/idr.c +++ b/kernel/src/libs/idr.c @@ -1,6 +1,8 @@ +#include +#if ARCH(I386) || ARCH(X86_64) + #include #include - /** * @brief 更换两个idr_layer指针 * @@ -1052,3 +1054,5 @@ bool ida_empty(struct ida *ida_p) return false; } + +#endif \ No newline at end of file diff --git a/kernel/src/libs/lock_free_flags.rs b/kernel/src/libs/lock_free_flags.rs index 41f8767c..84c9dfb5 100644 --- a/kernel/src/libs/lock_free_flags.rs +++ b/kernel/src/libs/lock_free_flags.rs @@ -20,11 +20,15 @@ impl LockFreeFlags { } pub fn get_mut(&self) -> &mut T { - unsafe { &mut *self.inner.get() } + unsafe { + (self.inner.get().as_ref().unwrap() as *const T as *mut T) + .as_mut() + .unwrap() + } } pub fn get(&self) -> &T { - unsafe { &*self.inner.get() } + unsafe { self.inner.get().as_ref().unwrap() } } } diff --git a/kernel/src/libs/lockref.c b/kernel/src/libs/lockref.c index cdbe52a8..2e4f49ff 100644 --- a/kernel/src/libs/lockref.c +++ b/kernel/src/libs/lockref.c @@ -1,3 +1,7 @@ +#include + +#if ARCH(I386) || ARCH(X86_64) + #include #include @@ -241,3 +245,5 @@ bool lockref_inc_not_dead(struct lockref *lock_ref) spin_unlock(&lock_ref->lock); return retval; } + +#endif \ No newline at end of file diff --git a/kernel/src/libs/lz4.c b/kernel/src/libs/lz4.c index aacff2af..4afadd98 100644 --- a/kernel/src/libs/lz4.c +++ b/kernel/src/libs/lz4.c @@ -41,6 +41,7 @@ * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ #include +#if ARCH(I386) || ARCH(X86_64) #if ARCH(I386) || ARCH(X86_64) #include @@ -3152,4 +3153,8 @@ char *LZ4_slideInputBuffer(void *state) return (char *)(uptrval)((LZ4_stream_t *)state)->internal_donotuse.dictionary; } -#endif /* LZ4_COMMONDEFS_ONLY */ \ No newline at end of file +#endif /* LZ4_COMMONDEFS_ONLY */ + +#else + +#endif \ No newline at end of file diff --git a/kernel/src/libs/mod.rs b/kernel/src/libs/mod.rs index f511deea..8c5c86e0 100644 --- a/kernel/src/libs/mod.rs +++ b/kernel/src/libs/mod.rs @@ -1,5 +1,4 @@ pub mod align; -pub mod atomic; pub mod casting; pub mod elf; pub mod ffi_convert; diff --git a/kernel/src/libs/rwlock.rs b/kernel/src/libs/rwlock.rs index 23dd651d..5cf0f5b6 100644 --- a/kernel/src/libs/rwlock.rs +++ b/kernel/src/libs/rwlock.rs @@ -191,7 +191,7 @@ impl RwLock { return (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER; } - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] #[allow(dead_code)] #[inline] /// @brief 尝试获得WRITER守卫 @@ -205,7 +205,7 @@ impl RwLock { return r; } //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] #[allow(dead_code)] fn inner_try_write(&self) -> Option> { let res: bool = self diff --git a/kernel/src/libs/string.c b/kernel/src/libs/string.c index f25b84e3..e5971503 100644 --- a/kernel/src/libs/string.c +++ b/kernel/src/libs/string.c @@ -38,47 +38,27 @@ long strnlen(const char *src, unsigned long maxlen) FirstPart > SecondPart => 1 FirstPart < SecondPart => -1 */ - -int strcmp(const char *FirstPart, const char *SecondPart) +int strcmp(const char *l, const char *r) { - register int __res; - __asm__ __volatile__("cld \n\t" - "1: \n\t" - "lodsb \n\t" - "scasb \n\t" - "jne 2f \n\t" - "testb %%al, %%al \n\t" - "jne 1b \n\t" - "xorl %%eax, %%eax \n\t" - "jmp 3f \n\t" - "2: \n\t" - "movl $1, %%eax \n\t" - "jl 3f \n\t" - "negl %%eax \n\t" - "3: \n\t" - : "=a"(__res) - : "D"(FirstPart), "S"(SecondPart) - :); - return __res; + for (; *l == *r && *l; l++, r++) + ; + return *(unsigned char *)l - *(unsigned char *)r; } -char *strncpy(char *dst, const char *src, long count) +char *__stpncpy(char *restrict d, const char *restrict s, size_t n) { - __asm__ __volatile__("cld \n\t" - "1: \n\t" - "decq %2 \n\t" - "js 2f \n\t" - "lodsb \n\t" - "stosb \n\t" - "testb %%al, %%al \n\t" - "jne 1b \n\t" - "rep \n\t" - "stosb \n\t" - "2: \n\t" - : - : "S"(src), "D"(dst), "c"(count) - : "ax", "memory"); - return dst; + + for (; n && (*d = *s); n--, s++, d++) + ; +tail: + memset(d, 0, n); + return d; +} + +char *strncpy(char *restrict d, const char *restrict s, size_t n) +{ + __stpncpy(d, s, n); + return d; } long strncpy_from_user(char *dst, const char *src, unsigned long size) diff --git a/kernel/src/mm/c_adapter.rs b/kernel/src/mm/c_adapter.rs index 4af621e9..72c4a673 100644 --- a/kernel/src/mm/c_adapter.rs +++ b/kernel/src/mm/c_adapter.rs @@ -6,7 +6,6 @@ use alloc::vec::Vec; use hashbrown::HashMap; use crate::{ - arch::mm::LowAddressRemapping, include::bindings::bindings::{gfp_t, PAGE_U_S}, kerror, libs::{align::page_align_up, spinlock::SpinLock}, @@ -120,12 +119,6 @@ pub unsafe extern "C" fn kfree(vaddr: usize) -> usize { return 0; } -#[no_mangle] -pub unsafe extern "C" fn rs_unmap_at_low_addr() -> usize { - LowAddressRemapping::unmap_at_low_address(true); - return 0; -} - /// @brief 创建一块mmio区域,并将vma绑定到initial_mm /// /// @param size mmio区域的大小(字节) diff --git a/kernel/src/mm/mm.h b/kernel/src/mm/mm.h index c14cb419..a882804c 100644 --- a/kernel/src/mm/mm.h +++ b/kernel/src/mm/mm.h @@ -150,6 +150,7 @@ extern char _bss; extern char _ebss; extern char _end; +#if ARCH(I386) || ARCH(X86_64) /** * @brief 读取CR3寄存器的值(存储了页目录的基地址) * @@ -163,6 +164,8 @@ unsigned long *get_CR3() return tmp; } +#endif + /* * vm_area_struct中的vm_flags的可选值 * 对应的结构体请见mm-types.h diff --git a/kernel/src/mm/mmio_buddy.rs b/kernel/src/mm/mmio_buddy.rs index 29f4cb48..12cea565 100644 --- a/kernel/src/mm/mmio_buddy.rs +++ b/kernel/src/mm/mmio_buddy.rs @@ -480,7 +480,7 @@ impl MmioBuddyMemPool { return Err(SystemError::EPERM); } // 计算前导0 - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))] let mut size_exp: u32 = 63 - size.leading_zeros(); // kdebug!("create_mmio: size_exp: {}", size_exp); // 记录最终申请的空间大小 diff --git a/kernel/src/mm/ucontext.rs b/kernel/src/mm/ucontext.rs index 9d819a55..751c70c7 100644 --- a/kernel/src/mm/ucontext.rs +++ b/kernel/src/mm/ucontext.rs @@ -149,6 +149,7 @@ impl InnerAddressSpace { /// # Returns /// /// 返回克隆后的,新的地址空间的Arc指针 + #[inline(never)] pub fn try_clone(&mut self) -> Result, SystemError> { let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; let new_addr_space = AddressSpace::new(false)?; diff --git a/kernel/src/net/syscall.rs b/kernel/src/net/syscall.rs index 9a0980aa..9daf7a39 100644 --- a/kernel/src/net/syscall.rs +++ b/kernel/src/net/syscall.rs @@ -9,8 +9,8 @@ use crate::{ file::{File, FileMode}, syscall::{IoVec, IoVecs}, }, - include::bindings::bindings::verify_area, libs::spinlock::SpinLockGuard, + mm::{verify_area, VirtAddr}, net::socket::{AddressFamily, SOL_SOCKET}, process::ProcessManager, syscall::{Syscall, SystemError}, @@ -539,15 +539,11 @@ pub union SockAddr { impl SockAddr { /// @brief 把用户传入的SockAddr转换为Endpoint结构体 pub fn to_endpoint(addr: *const SockAddr, len: usize) -> Result { - if unsafe { - verify_area( - addr as usize as u64, - core::mem::size_of::() as u64, - ) - } == false - { - return Err(SystemError::EFAULT); - } + verify_area( + VirtAddr::new(addr as usize), + core::mem::size_of::(), + ) + .map_err(|_| SystemError::EFAULT)?; let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?; if len < addr.len()? { @@ -611,14 +607,19 @@ impl SockAddr { if addr.is_null() || addr_len.is_null() { return Ok(0); } + // 检查用户传入的地址是否合法 - if !verify_area( - addr as usize as u64, - core::mem::size_of::() as u64, - ) || !verify_area(addr_len as usize as u64, core::mem::size_of::() as u64) - { - return Err(SystemError::EFAULT); - } + verify_area( + VirtAddr::new(addr as usize), + core::mem::size_of::(), + ) + .map_err(|_| SystemError::EFAULT)?; + + verify_area( + VirtAddr::new(addr_len as usize), + core::mem::size_of::(), + ) + .map_err(|_| SystemError::EFAULT)?; let to_write = min(self.len()?, *addr_len as usize); if to_write > 0 { diff --git a/kernel/src/process/c_adapter.rs b/kernel/src/process/c_adapter.rs index 3cc782ae..3a0caab7 100644 --- a/kernel/src/process/c_adapter.rs +++ b/kernel/src/process/c_adapter.rs @@ -3,18 +3,18 @@ use crate::smp::core::smp_get_processor_id; use super::{kthread::kthread_init, process_init, ProcessManager, __PROCESS_MANAGEMENT_INIT_DONE}; #[no_mangle] -pub extern "C" fn rs_process_init() { +unsafe extern "C" fn rs_process_init() { process_init(); } #[no_mangle] -pub extern "C" fn rs_kthread_init() { +unsafe extern "C" fn rs_kthread_init() { kthread_init(); } /// 临时用于获取空闲进程的栈顶的函数,这个函数是为了旧的smp模块的初始化而写在这的 #[no_mangle] -pub extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize { +unsafe extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize { return ProcessManager::idle_pcb()[cpu_id as usize] .kernel_stack() .stack_max_address() @@ -22,12 +22,12 @@ pub extern "C" fn rs_get_idle_stack_top(cpu_id: u32) -> usize { } #[no_mangle] -pub extern "C" fn rs_current_pcb_cpuid() -> u32 { +unsafe extern "C" fn rs_current_pcb_cpuid() -> u32 { return smp_get_processor_id(); } #[no_mangle] -pub extern "C" fn rs_current_pcb_pid() -> u32 { +unsafe extern "C" fn rs_current_pcb_pid() -> u32 { if unsafe { __PROCESS_MANAGEMENT_INIT_DONE } { return ProcessManager::current_pcb().pid().0 as u32; } @@ -35,7 +35,7 @@ pub extern "C" fn rs_current_pcb_pid() -> u32 { } #[no_mangle] -pub extern "C" fn rs_current_pcb_preempt_count() -> u32 { +unsafe extern "C" fn rs_current_pcb_preempt_count() -> u32 { if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } { return 0; } @@ -43,7 +43,7 @@ pub extern "C" fn rs_current_pcb_preempt_count() -> u32 { } #[no_mangle] -pub extern "C" fn rs_current_pcb_flags() -> u32 { +unsafe extern "C" fn rs_current_pcb_flags() -> u32 { if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } { return 0; } @@ -51,7 +51,8 @@ pub extern "C" fn rs_current_pcb_flags() -> u32 { } #[no_mangle] -pub extern "C" fn rs_current_pcb_thread_rbp() -> u64 { +#[cfg(target_arch = "x86_64")] +unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 { if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } { return 0; } @@ -59,17 +60,17 @@ pub extern "C" fn rs_current_pcb_thread_rbp() -> u64 { } #[no_mangle] -pub extern "C" fn rs_preempt_disable() { +unsafe extern "C" fn rs_preempt_disable() { return ProcessManager::preempt_disable(); } #[no_mangle] -pub extern "C" fn rs_preempt_enable() { +unsafe extern "C" fn rs_preempt_enable() { return ProcessManager::preempt_enable(); } #[no_mangle] -pub extern "C" fn rs_process_do_exit(exit_code: usize) -> usize { +unsafe extern "C" fn rs_process_do_exit(exit_code: usize) -> usize { if unsafe { !__PROCESS_MANAGEMENT_INIT_DONE } { return 0; } diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 6860640c..18bf3093 100644 --- a/kernel/src/process/fork.rs +++ b/kernel/src/process/fork.rs @@ -154,7 +154,9 @@ impl ProcessManager { clone_flags: CloneFlags, ) -> Result { let current_pcb = ProcessManager::current_pcb(); - let new_kstack = KernelStack::new()?; + + let new_kstack: KernelStack = KernelStack::new()?; + let name = current_pcb.basic().name().to_string(); let pcb = ProcessControlBlock::new(name, new_kstack); @@ -212,6 +214,7 @@ impl ProcessManager { /// ## Panic /// /// - 如果当前进程没有用户地址空间,则panic + #[inline(never)] fn copy_mm( clone_flags: &CloneFlags, current_pcb: &Arc, @@ -289,6 +292,7 @@ impl ProcessManager { /// /// ## return /// - 发生错误时返回Err(SystemError) + #[inline(never)] pub fn copy_process( current_pcb: &Arc, pcb: &Arc, diff --git a/kernel/src/process/idle.rs b/kernel/src/process/idle.rs index 70aec18a..50fc4b8d 100644 --- a/kernel/src/process/idle.rs +++ b/kernel/src/process/idle.rs @@ -42,12 +42,12 @@ impl ProcessManager { unsafe { ks.clear_pcb(true) }; ks } else { - KernelStack::new().unwrap_or_else(|e| { + KernelStack::new().unwrap_or_else(|e: crate::syscall::SystemError| { panic!("Failed to create kernel stack struct for AP {}: {:?}", i, e) }) }; - let idle_pcb = ProcessControlBlock::new_idle(smp_get_processor_id(), kstack); + let idle_pcb = ProcessControlBlock::new_idle(i as u32, kstack); assert!(idle_pcb.basic().user_vm().is_none()); unsafe { @@ -72,6 +72,9 @@ impl ProcessManager { fn stack_ptr() -> VirtAddr { #[cfg(target_arch = "x86_64")] return VirtAddr::new(x86::current::registers::rsp() as usize); + + #[cfg(target_arch = "riscv64")] + unimplemented!("stack_ptr() is not implemented on RISC-V") } /// 获取idle进程数组的引用 diff --git a/kernel/src/process/kthread.rs b/kernel/src/process/kthread.rs index 12a660a8..bba47aa9 100644 --- a/kernel/src/process/kthread.rs +++ b/kernel/src/process/kthread.rs @@ -249,7 +249,9 @@ impl KernelThreadMechanism { KernelThreadClosure::EmptyClosure((Box::new(initial_kernel_thread), ())), "init".to_string(), ); - let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; + + let irq_guard: crate::exception::IrqFlagsGuard = + unsafe { CurrentIrqArch::save_and_disable_irq() }; // 由于当前是pid=0的idle进程,而__inner_create要求当前是kthread,所以先临时设置为kthread ProcessManager::current_pcb() .flags @@ -258,6 +260,7 @@ impl KernelThreadMechanism { create_info .set_to_mark_sleep(false) .expect("Failed to set to_mark_sleep"); + KernelThreadMechanism::__inner_create( &create_info, CloneFlags::CLONE_VM | CloneFlags::CLONE_SIGNAL, @@ -268,6 +271,7 @@ impl KernelThreadMechanism { .flags .get_mut() .remove(ProcessFlags::KTHREAD); + drop(irq_guard); kinfo!("Initializing kernel thread mechanism stage1 complete"); } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 84c2a2e2..a60d1ea8 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -117,9 +117,7 @@ impl ProcessManager { Self::init_idle(); kdebug!("process idle init done."); - unsafe { - __PROCESS_MANAGEMENT_INIT_DONE = true; - } + unsafe { __PROCESS_MANAGEMENT_INIT_DONE = true }; kinfo!("Process Manager initialized."); } @@ -424,9 +422,14 @@ impl ProcessManager { } /// 上下文切换的钩子函数,当这个函数return的时候,将会发生上下文切换 +#[cfg(target_arch = "x86_64")] pub unsafe extern "sysv64" fn switch_finish_hook() { ProcessManager::switch_finish_hook(); } +#[cfg(target_arch = "riscv64")] +pub unsafe extern "C" fn switch_finish_hook() { + ProcessManager::switch_finish_hook(); +} int_like!(Pid, AtomicPid, usize, AtomicUsize); @@ -592,11 +595,9 @@ impl ProcessControlBlock { let (pid, ppid, cwd) = if is_idle { (Pid(0), Pid(0), "/".to_string()) } else { - ( - Self::generate_pid(), - ProcessManager::current_pcb().pid(), - ProcessManager::current_pcb().basic().cwd(), - ) + let ppid = ProcessManager::current_pcb().pid(); + let cwd = ProcessManager::current_pcb().basic().cwd(); + (Self::generate_pid(), ppid, cwd) }; let basic_info = ProcessBasicInfo::new(Pid(0), ppid, name, cwd, None); @@ -632,6 +633,7 @@ impl ProcessControlBlock { }; // 初始化系统调用栈 + #[cfg(target_arch = "x86_64")] pcb.arch_info .lock() .init_syscall_stack(&pcb.syscall_stack.read()); @@ -1227,14 +1229,14 @@ impl KernelStack { #[allow(dead_code)] pub unsafe fn pcb(&self) -> Option> { // 从内核栈的最低地址处取出pcb的地址 - let p = self.stack.as_ref().unwrap().as_ptr() as *const ProcessControlBlock; - if unlikely(p.is_null()) { + let p = self.stack.as_ref().unwrap().as_ptr() as *const *const ProcessControlBlock; + if unlikely(unsafe { (*p).is_null() }) { return None; } // 为了防止内核栈的pcb指针被释放,这里需要将其包装一下,使得Arc的drop不会被调用 let weak_wrapper: ManuallyDrop> = - ManuallyDrop::new(Weak::from_raw(p)); + ManuallyDrop::new(Weak::from_raw(*p)); let new_arc: Arc = weak_wrapper.upgrade()?; return Some(new_arc); @@ -1244,10 +1246,11 @@ impl KernelStack { impl Drop for KernelStack { fn drop(&mut self) { if !self.stack.is_none() { - let pcb_ptr: Weak = unsafe { - Weak::from_raw(self.stack.as_ref().unwrap().as_ptr() as *const ProcessControlBlock) - }; - drop(pcb_ptr); + let ptr = self.stack.as_ref().unwrap().as_ptr() as *const *const ProcessControlBlock; + if unsafe { !(*ptr).is_null() } { + let pcb_ptr: Weak = unsafe { Weak::from_raw(*ptr) }; + drop(pcb_ptr); + } } // 如果该内核栈不可以被释放,那么,这里就forget,不调用AlignedBox的drop函数 if !self.can_be_freed { diff --git a/kernel/src/process/syscall.rs b/kernel/src/process/syscall.rs index e5bd99be..ba993b4f 100644 --- a/kernel/src/process/syscall.rs +++ b/kernel/src/process/syscall.rs @@ -19,8 +19,7 @@ use crate::{ procfs::procfs_register_pid, vfs::{file::FileDescriptorVec, MAX_PATHLEN}, }, - include::bindings::bindings::verify_area, - mm::{ucontext::UserStack, MemoryManagementArch, VirtAddr}, + mm::{ucontext::UserStack, verify_area, MemoryManagementArch, VirtAddr}, process::ProcessControlBlock, sched::completion::Completion, syscall::{ @@ -231,9 +230,8 @@ impl Syscall { /// 设置线程地址 pub fn set_tid_address(ptr: usize) -> Result { - if !unsafe { verify_area(ptr as u64, core::mem::size_of::() as u64) } { - return Err(SystemError::EFAULT); - } + verify_area(VirtAddr::new(ptr), core::mem::size_of::()) + .map_err(|_| SystemError::EFAULT)?; let pcb = ProcessManager::current_pcb(); pcb.thread.write().clear_child_tid = Some(VirtAddr::new(ptr)); diff --git a/kernel/src/sched/syscall.rs b/kernel/src/sched/syscall.rs index dd5c1c89..64e5c0b9 100644 --- a/kernel/src/sched/syscall.rs +++ b/kernel/src/sched/syscall.rs @@ -25,7 +25,7 @@ impl Syscall { if pcb.is_some() { let next_pcb = pcb.unwrap(); let current_pcb = ProcessManager::current_pcb(); - + // kdebug!("sched: current_pcb: {:?}, next_pcb: {:?}\n", current_pcb, next_pcb); if current_pcb.pid() != next_pcb.pid() { CPU_EXECUTING.set(smp_get_processor_id(), next_pcb.pid()); unsafe { ProcessManager::switch_process(current_pcb, next_pcb) }; diff --git a/kernel/src/smp/ipi.h b/kernel/src/smp/ipi.h index 84bc6fad..485d4571 100644 --- a/kernel/src/smp/ipi.h +++ b/kernel/src/smp/ipi.h @@ -3,25 +3,6 @@ #include #if ARCH(I386) || ARCH(X86_64) #include -#else -#error "error type of arch!" -#endif - -/** - * @brief 发送ipi消息 - * - * @param dest_mode 目标模式 - * @param deliver_status 投递模式 - * @param level 信号驱动电平 - * @param trigger 触发模式 - * @param vector 中断向量 - * @param deliver_mode 投递模式 - * @param dest_shorthand 投递目标速记值 - * @param apic_type apic的类型 (0:xapic 1: x2apic) - * @param destination 投递目标 - */ -extern void ipi_send_IPI(uint32_t dest_mode, uint32_t deliver_status, uint32_t level, uint32_t trigger, - uint32_t vector, uint32_t deliver_mode, uint32_t dest_shorthand, uint32_t destination); /** * @brief ipi中断处理注册函数 @@ -36,4 +17,14 @@ extern void ipi_send_IPI(uint32_t dest_mode, uint32_t deliver_status, uint32_t l */ extern int ipi_regiserIPI(uint64_t irq_num, void *arg, void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs), - uint64_t param, hardware_intr_controller *controller, char *irq_name); \ No newline at end of file + uint64_t param, hardware_intr_controller *controller, char *irq_name); + +#else +int ipi_regiserIPI(uint64_t irq_num, void *arg, + void (*handler)(uint64_t irq_num, uint64_t param, struct pt_regs *regs), + uint64_t param, hardware_intr_controller *controller, char *irq_name) +{ + return -1; +} + +#endif \ No newline at end of file diff --git a/kernel/src/smp/smp.c b/kernel/src/smp/smp.c index f674e66e..eb52e364 100644 --- a/kernel/src/smp/smp.c +++ b/kernel/src/smp/smp.c @@ -11,7 +11,9 @@ #include #include #include "exception/trap.h" +#include "exception/irq.h" #include "ipi.h" +#include /* x86-64 specific MSRs */ #define MSR_EFER 0xc0000080 /* extended feature register */ @@ -56,6 +58,7 @@ static struct X86CpuInfo __cpu_info[MAX_SUPPORTED_PROCESSOR_NUM] = {0}; void smp_init() { spin_init(&multi_core_starting_lock); // 初始化多核启动锁 +#if ARCH(I386) || ARCH(X86_64) // 设置多核启动时,要加载的页表 __APU_START_CR3 = (uint64_t)get_CR3(); @@ -135,6 +138,7 @@ void smp_init() // 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射 rs_unmap_at_low_addr(); kinfo("Successfully cleaned page table remapping!\n"); +#endif io_mfence(); } @@ -149,7 +153,7 @@ void smp_ap_start_stage2() io_mfence(); ++num_cpu_started; io_mfence(); - +#if ARCH(I386) || ARCH(X86_64) rs_apic_init_ap(); // ============ 为ap处理器初始化IDLE进程 ============= @@ -160,8 +164,9 @@ void smp_ap_start_stage2() spin_unlock_no_preempt(&multi_core_starting_lock); rs_init_syscall_64(); - + apic_timer_ap_core_init(); +#endif sti(); sched(); diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index c4e4929b..6de9e764 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -1,4 +1,10 @@ -use crate::arch::mm::LockedFrameAllocator; +use alloc::vec::Vec; + +use crate::{ + arch::{mm::LockedFrameAllocator, rand::rand}, + libs::rand::GRandFlags, + mm::allocator::page_frame::FrameAllocator, +}; use super::{user_access::UserBufferWriter, Syscall, SystemError}; @@ -30,7 +36,7 @@ impl Syscall { let mut writer = UserBufferWriter::new(info, core::mem::size_of::(), true)?; let mut sysinfo = SysInfo::default(); - let mem = LockedFrameAllocator.get_usage(); + let mem = unsafe { LockedFrameAllocator.usage() }; sysinfo.uptime = 0; sysinfo.loads = [0; 3]; sysinfo.totalram = mem.total().bytes() as u64; @@ -54,4 +60,28 @@ impl Syscall { kwarn!("SYS_UMASK has not yet been implemented\n"); return Ok(0o777); } + + /// ## 将随机字节填入buf + /// + /// ### 该系统调用与linux不一致,因为目前没有其他随机源 + pub fn get_random(buf: *mut u8, len: usize, flags: GRandFlags) -> Result { + if flags.bits() == (GRandFlags::GRND_INSECURE.bits() | GRandFlags::GRND_RANDOM.bits()) { + return Err(SystemError::EINVAL); + } + + let mut writer = UserBufferWriter::new(buf, len, true)?; + + let mut ret = Vec::new(); + let mut count = 0; + while count < len { + let rand = rand(); + for offset in 0..4 { + ret.push((rand >> offset * 2) as u8); + count += 1; + } + } + + writer.copy_to_user(&ret, 0)?; + Ok(len) + } } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 1f7a777b..00ea010d 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -4,11 +4,7 @@ use core::{ }; use crate::{ - arch::syscall::{ - SYS_ACCESS, SYS_CHMOD, SYS_CLOCK_GETTIME, SYS_FACCESSAT, SYS_FACCESSAT2, SYS_FCHMOD, - SYS_FCHMODAT, SYS_LSTAT, SYS_OPENAT, SYS_PRLIMIT64, SYS_READV, SYS_SYSINFO, SYS_UMASK, - SYS_UNLINK, - }, + arch::syscall::nr::*, libs::{futex::constant::FutexFlag, rand::GRandFlags}, process::{ fork::KernelCloneArgs, @@ -20,7 +16,7 @@ use num_traits::{FromPrimitive, ToPrimitive}; use crate::{ arch::{cpu::cpu_reset, interrupt::TrapFrame, MMArch}, - driver::base::{block::SeekFrom, device::DeviceNumber}, + driver::base::block::SeekFrom, filesystem::vfs::{ fcntl::FcntlCommand, file::FileMode, @@ -346,123 +342,6 @@ impl SystemError { } } -// 定义系统调用号 -pub const SYS_READ: usize = 0; -pub const SYS_WRITE: usize = 1; -pub const SYS_OPEN: usize = 2; -pub const SYS_CLOSE: usize = 3; -pub const SYS_STAT: usize = 4; -pub const SYS_FSTAT: usize = 5; - -pub const SYS_POLL: usize = 7; -pub const SYS_LSEEK: usize = 8; -pub const SYS_MMAP: usize = 9; -pub const SYS_MPROTECT: usize = 10; - -pub const SYS_MUNMAP: usize = 11; -pub const SYS_BRK: usize = 12; -pub const SYS_SIGACTION: usize = 13; -pub const SYS_RT_SIGPROCMASK: usize = 14; -pub const SYS_RT_SIGRETURN: usize = 15; - -pub const SYS_IOCTL: usize = 16; - -pub const SYS_WRITEV: usize = 20; -pub const SYS_PIPE: usize = 22; - -pub const SYS_MADVISE: usize = 28; - -pub const SYS_DUP: usize = 32; -pub const SYS_DUP2: usize = 33; - -pub const SYS_NANOSLEEP: usize = 35; - -pub const SYS_GETPID: usize = 39; - -pub const SYS_SOCKET: usize = 41; -pub const SYS_CONNECT: usize = 42; -pub const SYS_ACCEPT: usize = 43; -pub const SYS_SENDTO: usize = 44; -pub const SYS_RECVFROM: usize = 45; - -pub const SYS_RECVMSG: usize = 47; -pub const SYS_SHUTDOWN: usize = 48; -pub const SYS_BIND: usize = 49; -pub const SYS_LISTEN: usize = 50; -pub const SYS_GETSOCKNAME: usize = 51; -pub const SYS_GETPEERNAME: usize = 52; -pub const SYS_SOCKET_PAIR: usize = 53; -pub const SYS_SETSOCKOPT: usize = 54; -pub const SYS_GETSOCKOPT: usize = 55; - -pub const SYS_CLONE: usize = 56; -pub const SYS_FORK: usize = 57; -pub const SYS_VFORK: usize = 58; -pub const SYS_EXECVE: usize = 59; -pub const SYS_EXIT: usize = 60; -pub const SYS_WAIT4: usize = 61; -pub const SYS_KILL: usize = 62; - -pub const SYS_FCNTL: usize = 72; - -pub const SYS_FTRUNCATE: usize = 77; -pub const SYS_GET_DENTS: usize = 78; - -pub const SYS_GETCWD: usize = 79; - -pub const SYS_CHDIR: usize = 80; - -pub const SYS_MKDIR: usize = 83; - -pub const SYS_READLINK: usize = 89; - -pub const SYS_GETTIMEOFDAY: usize = 96; -pub const SYS_GETRUSAGE: usize = 98; - -pub const SYS_GETUID: usize = 102; -pub const SYS_SYSLOG: usize = 103; -pub const SYS_GETGID: usize = 104; -pub const SYS_SETUID: usize = 105; - -pub const SYS_SETGID: usize = 106; -pub const SYS_GETEUID: usize = 107; -pub const SYS_GETEGID: usize = 108; - -pub const SYS_GETPPID: usize = 110; -pub const SYS_GETPGID: usize = 121; - -pub const SYS_SIGALTSTACK: usize = 131; -pub const SYS_MKNOD: usize = 133; - -pub const SYS_ARCH_PRCTL: usize = 158; - -pub const SYS_REBOOT: usize = 169; - -pub const SYS_GETTID: usize = 186; - -#[allow(dead_code)] -pub const SYS_TKILL: usize = 200; - -#[allow(dead_code)] -pub const SYS_FUTEX: usize = 202; - -pub const SYS_GET_DENTS_64: usize = 217; -#[allow(dead_code)] -pub const SYS_SET_TID_ADDR: usize = 218; - -pub const SYS_EXIT_GROUP: usize = 231; - -pub const SYS_UNLINK_AT: usize = 263; - -pub const SYS_READLINK_AT: usize = 267; - -pub const SYS_ACCEPT4: usize = 288; - -pub const SYS_PIPE2: usize = 293; - -#[allow(dead_code)] -pub const SYS_GET_RANDOM: usize = 318; - // 与linux不一致的调用,在linux基础上累加 pub const SYS_PUT_STRING: usize = 100000; pub const SYS_SBRK: usize = 100001; @@ -499,6 +378,7 @@ impl Syscall { /// /// 这个函数内,需要根据系统调用号,调用对应的系统调用处理函数。 /// 并且,对于用户态传入的指针参数,需要在本函数内进行越界检查,防止访问到内核空间。 + #[inline(never)] pub fn handle( syscall_num: usize, args: &[usize], @@ -508,6 +388,7 @@ impl Syscall { SYS_PUT_STRING => { Self::put_string(args[0] as *const u8, args[1] as u32, args[2] as u32) } + #[cfg(target_arch = "x86_64")] SYS_OPEN => { let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) }; let path: Result<&str, core::str::Utf8Error> = path.to_str(); @@ -599,7 +480,9 @@ impl Syscall { Self::ioctl(fd, cmd as u32, data) } + #[cfg(target_arch = "x86_64")] SYS_FORK => Self::fork(frame), + #[cfg(target_arch = "x86_64")] SYS_VFORK => Self::vfork(frame), SYS_BRK => { @@ -644,7 +527,8 @@ impl Syscall { Self::chdir(r) } - SYS_GET_DENTS | SYS_GET_DENTS_64 => { + #[allow(unreachable_patterns)] + SYS_GETDENTS64 | SYS_GETDENTS => { let fd = args[0] as i32; let buf_vaddr = args[1]; @@ -704,6 +588,7 @@ impl Syscall { let exit_code = args[0]; Self::exit(exit_code) } + #[cfg(target_arch = "x86_64")] SYS_MKDIR => { let path_ptr = args[0] as *const c_char; let mode = args[1]; @@ -749,6 +634,7 @@ impl Syscall { } SYS_CLOCK => Self::clock(), + #[cfg(target_arch = "x86_64")] SYS_PIPE => { let pipefd: *mut i32 = args[0] as *mut c_int; if pipefd.is_null() { @@ -768,7 +654,7 @@ impl Syscall { } } - SYS_UNLINK_AT => { + SYS_UNLINKAT => { let dirfd = args[0] as i32; let pathname = args[1] as *const c_char; let flags = args[2] as u32; @@ -797,6 +683,7 @@ impl Syscall { } } + #[cfg(target_arch = "x86_64")] SYS_UNLINK => { let pathname = args[0] as *const u8; Self::unlink(pathname) @@ -808,7 +695,7 @@ impl Syscall { Self::kill(pid, sig) } - SYS_SIGACTION => { + SYS_RT_SIGACTION => { let sig = args[0] as c_int; let act = args[1]; let old_act = args[2]; @@ -828,6 +715,8 @@ impl Syscall { let oldfd: i32 = args[0] as c_int; Self::dup(oldfd) } + + #[cfg(target_arch = "x86_64")] SYS_DUP2 => { let oldfd: i32 = args[0] as c_int; let newfd: i32 = args[1] as c_int; @@ -1090,12 +979,17 @@ impl Syscall { res } + #[cfg(target_arch = "x86_64")] SYS_MKNOD => { let path = args[0]; let flags = args[1]; let dev_t = args[2]; let flags: ModeType = ModeType::from_bits_truncate(flags as u32); - Self::mknod(path as *const i8, flags, DeviceNumber::from(dev_t)) + Self::mknod( + path as *const i8, + flags, + crate::driver::base::device::DeviceNumber::from(dev_t), + ) } SYS_CLONE => { @@ -1143,11 +1037,10 @@ impl Syscall { SYS_READV => Self::readv(args[0] as i32, args[1], args[2]), SYS_WRITEV => Self::writev(args[0] as i32, args[1], args[2]), - SYS_ARCH_PRCTL => Self::arch_prctl(args[0], args[1]), + SYS_SET_TID_ADDRESS => Self::set_tid_address(args[0]), - SYS_SET_TID_ADDR => Self::set_tid_address(args[0]), - - SYS_STAT | SYS_LSTAT => { + #[cfg(target_arch = "x86_64")] + SYS_LSTAT => { let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) }; let path: Result<&str, core::str::Utf8Error> = path.to_str(); let res = if path.is_err() { @@ -1157,13 +1050,26 @@ impl Syscall { let kstat = args[1] as *mut PosixKstat; let vaddr = VirtAddr::new(kstat as usize); match verify_area(vaddr, core::mem::size_of::()) { - Ok(_) => { - if syscall_num == SYS_STAT { - Self::stat(path, kstat) - } else { - Self::lstat(path, kstat) - } - } + Ok(_) => Self::lstat(path, kstat), + Err(e) => Err(e), + } + }; + + res + } + + #[cfg(target_arch = "x86_64")] + SYS_STAT => { + let path: &CStr = unsafe { CStr::from_ptr(args[0] as *const c_char) }; + let path: Result<&str, core::str::Utf8Error> = path.to_str(); + let res = if path.is_err() { + Err(SystemError::EINVAL) + } else { + let path: &str = path.unwrap(); + let kstat = args[1] as *mut PosixKstat; + let vaddr = VirtAddr::new(kstat as usize); + match verify_area(vaddr, core::mem::size_of::()) { + Ok(_) => Self::stat(path, kstat), Err(e) => Err(e), } }; @@ -1172,15 +1078,16 @@ impl Syscall { } // 目前为了适配musl-libc,以下系统调用先这样写着 - SYS_GET_RANDOM => { + SYS_GETRANDOM => { let flags = GRandFlags::from_bits(args[2] as u8).ok_or(SystemError::EINVAL)?; Self::get_random(args[0] as *mut u8, args[1], flags) } - SYS_SOCKET_PAIR => { + SYS_SOCKETPAIR => { unimplemented!() } + #[cfg(target_arch = "x86_64")] SYS_POLL => { kwarn!("SYS_POLL has not yet been implemented"); Ok(0) @@ -1233,6 +1140,7 @@ impl Syscall { Self::get_rusage(who, rusage) } + #[cfg(target_arch = "x86_64")] SYS_READLINK => { let path = args[0] as *const u8; let buf = args[1] as *mut u8; @@ -1240,7 +1148,7 @@ impl Syscall { Self::readlink(path, buf, bufsiz) } - SYS_READLINK_AT => { + SYS_READLINKAT => { let dirfd = args[0] as i32; let pathname = args[1] as *const u8; let buf = args[2] as *mut u8; @@ -1258,6 +1166,7 @@ impl Syscall { Self::prlimit64(pid, resource, new_limit, old_limit) } + #[cfg(target_arch = "x86_64")] SYS_ACCESS => { let pathname = args[0] as *const u8; let mode = args[1] as u32; @@ -1295,6 +1204,7 @@ impl Syscall { Self::umask(mask) } + #[cfg(target_arch = "x86_64")] SYS_CHMOD => { let pathname = args[0] as *const u8; let mode = args[1] as u32; @@ -1314,6 +1224,7 @@ impl Syscall { _ => panic!("Unsupported syscall ID: {}", syscall_num), }; + return r; } @@ -1326,6 +1237,6 @@ impl Syscall { } pub fn reboot() -> Result { - cpu_reset(); + unsafe { cpu_reset() }; } } diff --git a/kernel/src/syscall/syscall.c b/kernel/src/syscall/syscall.c index 4281a43b..3b6bb661 100644 --- a/kernel/src/syscall/syscall.c +++ b/kernel/src/syscall/syscall.c @@ -8,6 +8,9 @@ #include #include #include