浏览代码

在riscv输出hello world (#466)

增加了以下内容:
- SBI驱动
- 把内核的rust工具链升级到2023-08-15版本
- 输出riscv的helloworld
- 设置内核是PIC的
LoGin 1 年之前
父节点
当前提交
1a72a751b1
共有 41 个文件被更改,包括 722 次插入122 次删除
  1. 4 0
      Makefile
  2. 1 1
      build-scripts/kernel_build/src/cfiles/arch/riscv64.rs
  3. 1 1
      build-scripts/kernel_build/src/cfiles/mod.rs
  4. 3 1
      env.mk
  5. 3 3
      kernel/Makefile
  6. 1 1
      kernel/rust-toolchain.toml
  7. 2 5
      kernel/src/Makefile
  8. 34 0
      kernel/src/arch/riscv64/asm/head.S
  9. 0 9
      kernel/src/arch/riscv64/boot/head.S
  10. 1 0
      kernel/src/arch/riscv64/driver/mod.rs
  11. 220 0
      kernel/src/arch/riscv64/driver/sbi/ecall.rs
  12. 194 0
      kernel/src/arch/riscv64/driver/sbi/legacy.rs
  13. 93 0
      kernel/src/arch/riscv64/driver/sbi/mod.rs
  14. 14 0
      kernel/src/arch/riscv64/init/mod.rs
  15. 4 3
      kernel/src/arch/riscv64/link.ld
  16. 2 0
      kernel/src/arch/riscv64/mod.rs
  17. 13 0
      kernel/src/arch/riscv64/process/mod.rs
  18. 18 0
      kernel/src/arch/riscv64/riscv64imac-unknown-none-elf.json
  19. 3 6
      kernel/src/arch/x86_64/driver/hpet.rs
  20. 2 2
      kernel/src/driver/base/kset.rs
  21. 21 2
      kernel/src/driver/tty/serial/serial8250/mod.rs
  22. 8 5
      kernel/src/driver/video/mod.rs
  23. 1 1
      kernel/src/exception/softirq.rs
  24. 0 1
      kernel/src/filesystem/fat/entry.rs
  25. 5 10
      kernel/src/filesystem/procfs/mod.rs
  26. 3 3
      kernel/src/init/mod.rs
  27. 3 12
      kernel/src/ipc/signal_types.rs
  28. 1 1
      kernel/src/ipc/syscall.rs
  29. 1 4
      kernel/src/lib.rs
  30. 0 4
      kernel/src/libs/elf.rs
  31. 5 6
      kernel/src/libs/futex/futex.rs
  32. 15 8
      kernel/src/libs/lib_ui/screen_manager.rs
  33. 25 7
      kernel/src/libs/lib_ui/textui.rs
  34. 7 5
      kernel/src/libs/lib_ui/textui_no_alloc.rs
  35. 1 3
      kernel/src/libs/notifier.rs
  36. 1 1
      kernel/src/mm/mmio_buddy.rs
  37. 0 13
      kernel/src/net/socket.rs
  38. 7 0
      kernel/src/process/c_adapter.rs
  39. 1 1
      kernel/src/process/mod.rs
  40. 3 2
      kernel/src/time/timer.rs
  41. 1 1
      tools/bootstrap.sh

+ 4 - 0
Makefile

@@ -76,7 +76,11 @@ clean-docs:
 	bash -c "cd docs && make clean && cd .."
 
 gdb:
+ifeq ($(ARCH), x86_64)
 	rust-gdb -n -x tools/.gdbinit
+else
+	gdb-multiarch -n -x tools/.gdbinit
+endif
 
 # 写入磁盘镜像
 write_diskimage:

+ 1 - 1
build-scripts/kernel_build/src/cfiles/arch/riscv64.rs

@@ -17,7 +17,7 @@ impl CFilesArch for RiscV64CFilesArch {
     }
 
     fn setup_files(&self, _c: &mut cc::Build, files: &mut Vec<std::path::PathBuf>) {
-        files.push(PathBuf::from("src/arch/riscv64/boot/head.S"));
+        files.push(PathBuf::from("src/arch/riscv64/asm/head.S"));
         files.append(&mut FileUtils::list_all_files(
             &arch_path("asm"),
             Some("c"),

+ 1 - 1
build-scripts/kernel_build/src/cfiles/mod.rs

@@ -26,7 +26,7 @@ impl CFilesBuilder {
         c.flag("-fno-builtin")
             .flag("-nostdlib")
             .flag("-fno-stack-protector")
-            .flag("-fno-pie")
+            .flag("-static-pie")
             .flag("-Wno-expansion-to-defined")
             .flag("-Wno-unused-parameter")
             .flag("-O1");

+ 3 - 1
env.mk

@@ -22,7 +22,9 @@ export OBJCOPY=$(DragonOS_GCC)/x86_64-elf-objcopy
 else ifeq ($(ARCH), riscv64)
 
 export CC=riscv64-unknown-elf-gcc
-export LD=riscv64-unknown-elf-ld
+# binutils版本需要>=2.38
+# 而ubuntu的unknown-elf的版本比较旧,所以使用了riscv64-linux-gnu-ld
+export LD=riscv64-linux-gnu-ld
 export AS=riscv64-unknown-elf-as
 export NM=riscv64-unknown-elf-nm
 export AR=riscv64-unknown-elf-ar

+ 3 - 3
kernel/Makefile

@@ -6,7 +6,7 @@ export ARCH ?= x86_64
 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
+	export TARGET_JSON=arch/riscv64/riscv64imac-unknown-none-elf.json
 endif
 
 export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem
@@ -33,8 +33,8 @@ 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)
+	@cargo +nightly-2023-08-15 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)
+	@cargo +nightly-2023-08-15 check --workspace $(CARGO_ZBUILD) --message-format=json --target ./src/$(TARGET_JSON)
 endif
 

+ 1 - 1
kernel/rust-toolchain.toml

@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-01-21"
+channel = "nightly-2023-08-15"
 components = ["rust-src"]

+ 2 - 5
kernel/src/Makefile

@@ -40,11 +40,8 @@ kernel_subdirs := common driver debug exception smp syscall ktest libs time
 
 
 kernel_rust:
-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
+	RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2023-08-15 $(CARGO_ZBUILD) build --release --target $(TARGET_JSON)
+
 
 all: kernel
 

+ 34 - 0
kernel/src/arch/riscv64/asm/head.S

@@ -0,0 +1,34 @@
+#include "common/asm.h"
+
+.section .bootstrap
+
+#define CSR_SIE			0x104
+#define CSR_SIP			0x144
+
+#define CSR_IE CSR_SIE
+#define CSR_IP CSR_SIP
+
+// 内核入口(从DragonStub跳转到这里)
+// 参数:
+//   a0: hartid (核心ID)
+//   a1: fdt (平坦设备树)
+.global _start
+.type _start, @function
+ENTRY(_start)
+	/* Mask all interrupts */
+	csrw CSR_IE, zero
+	csrw CSR_IP, zero
+	/* Load the global pointer */
+.option push
+.option norelax
+	la sp, BSP_IDLE_STACK_SPACE
+	li t0, 32768
+	add sp, sp, t0
+.option pop
+	/* Call the kernel */
+	call kernel_main
+	nop
+_loop:
+	j _loop
+
+

+ 0 - 9
kernel/src/arch/riscv64/boot/head.S

@@ -1,9 +0,0 @@
-#include "common/asm.h"
-
-.section .bootstrap
-
-.global _start
-.type _start, @function
-ENTRY(_start)
-loop:
-    j loop

+ 1 - 0
kernel/src/arch/riscv64/driver/mod.rs

@@ -0,0 +1 @@
+pub mod sbi;

+ 220 - 0
kernel/src/arch/riscv64/driver/sbi/ecall.rs

@@ -0,0 +1,220 @@
+#![allow(dead_code)]
+use super::SbiError;
+
+/// 使用给定的扩展和函数 ID 进行零参数的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 不接受任何参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+pub unsafe fn ecall0(extension_id: usize, function_id: usize) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        in("a6") function_id,
+        in("a7") extension_id,
+        lateout("a0") error,
+        lateout("a1") value,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 使用给定的扩展和函数 ID 进行单参数的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 接受一个参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+pub unsafe fn ecall1(
+    arg: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg => error,
+        in("a6") function_id,
+        in("a7") extension_id,
+        lateout("a1") value,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 一个带有给定扩展和函数ID的两参数`ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数ID接受两个参数时,才安全调用此函数。否则,行为将是未定义的,
+/// 因为将额外的中断寄存器传递给SBI实现时,其内容将是未定义的。
+#[inline]
+pub unsafe fn ecall2(
+    arg0: usize,
+    arg1: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg0 => error,
+        inlateout("a1") arg1 => value,
+        in("a6") function_id,
+        in("a7") extension_id,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 使用给定的扩展和函数 ID 进行 3参数 的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 接受一个参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+pub unsafe fn ecall3(
+    arg0: usize,
+    arg1: usize,
+    arg2: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg0 => error,
+        inlateout("a1") arg1 => value,
+        in("a2") arg2,
+        in("a6") function_id,
+        in("a7") extension_id,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 使用给定的扩展和函数 ID 进行 4参数 的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 接受一个参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+pub unsafe fn ecall4(
+    arg0: usize,
+    arg1: usize,
+    arg2: usize,
+    arg3: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg0 => error,
+        inlateout("a1") arg1 => value,
+        in("a2") arg2,
+        in("a3") arg3,
+        in("a6") function_id,
+        in("a7") extension_id,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 使用给定的扩展和函数 ID 进行 5参数 的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 接受一个参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+pub unsafe fn ecall5(
+    arg0: usize,
+    arg1: usize,
+    arg2: usize,
+    arg3: usize,
+    arg4: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg0 => error,
+        inlateout("a1") arg1 => value,
+        in("a2") arg2,
+        in("a3") arg3,
+        in("a4") arg4,
+        in("a6") function_id,
+        in("a7") extension_id,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}
+
+/// 使用给定的扩展和函数 ID 进行 6参数 的 `ecall`。
+///
+/// # 安全性
+/// 只有在给定的函数 ID 接受一个参数时,调用此函数才是安全的,否则行为是未定义的,
+/// 因为当传递给 SBI 实现时,额外的参数寄存器将具有未定义的内容。
+#[inline]
+#[allow(clippy::too_many_arguments)]
+pub unsafe fn ecall6(
+    arg0: usize,
+    arg1: usize,
+    arg2: usize,
+    arg3: usize,
+    arg4: usize,
+    arg5: usize,
+    extension_id: usize,
+    function_id: usize,
+) -> Result<usize, SbiError> {
+    let error: isize;
+    let value: usize;
+
+    core::arch::asm!(
+        "ecall",
+        inlateout("a0") arg0 => error,
+        inlateout("a1") arg1 => value,
+        in("a2") arg2,
+        in("a3") arg3,
+        in("a4") arg4,
+        in("a5") arg5,
+        in("a6") function_id,
+        in("a7") extension_id,
+    );
+
+    match error {
+        0 => Result::Ok(value),
+        e => Result::Err(SbiError::new(e)),
+    }
+}

+ 194 - 0
kernel/src/arch/riscv64/driver/sbi/legacy.rs

@@ -0,0 +1,194 @@
+use crate::{
+    arch::driver::sbi::ecall::{ecall0, ecall1},
+    mm::VirtAddr,
+};
+use core::arch::asm;
+
+/// `sbi_set_timer` extension ID
+pub const SET_TIMER_EID: usize = 0x00;
+/// `sbi_console_putchar` extension ID
+pub const CONSOLE_PUTCHAR_EID: usize = 0x01;
+/// `sbi_console_getchar` extension ID
+pub const CONSOLE_GETCHAR_EID: usize = 0x02;
+/// `sbi_clear_ipi` extension ID
+pub const CLEAR_IPI_EID: usize = 0x03;
+/// `sbi_send_ipi` extension ID
+pub const SEND_IPI_EID: usize = 0x04;
+/// `sbi_remote_fence_i` extension ID
+pub const REMOTE_FENCE_I_EID: usize = 0x05;
+/// `sbi_remote_sfence_vma` extension ID
+pub const REMOTE_SFENCE_VMA_EID: usize = 0x06;
+/// `sbi_remote_sfence_vma_asid` extension ID
+pub const REMOTE_SFENCE_VMA_ASID_EID: usize = 0x07;
+/// `sbi_shutdown` extension ID
+pub const SHUTDOWN_EID: usize = 0x08;
+
+/// 计划在未来的某个时间触发中断。
+///
+/// ## 参数
+///
+/// - `stime`:要触发中断的绝对时间,以滴答为单位。如果`stime`小于当前时间,则不会触发中断。
+///
+/// ## 详情
+///
+/// 要清除计时器中断而不预约另一个计时器事件,可以将时间设置为无限远(`u64::MAX`)或
+/// mask `sie` CSR的`STIE` 位。此函数将清除待处理计时器中断位。
+///
+/// 注意:`time` 是一个绝对时间,不是从调用时刻开始的偏移量。这意味着如果您想要设置一个未来`n`和tick之后
+/// 触发的时钟,您需要首先读取 `time` CSR,然后将滴答数添加到该值。关于如何确定每个滴答的时间,
+/// 这是平台依赖的,而时钟频率应在 CPU 节点的 `timebase-frequency` 属性中表达,如果可用的话。
+#[inline]
+pub unsafe fn set_timer(stime: u64) {
+    #[cfg(target_arch = "riscv64")]
+    unsafe {
+        ecall1(stime as usize, SET_TIMER_EID, 0).ok();
+    }
+
+    #[cfg(target_arch = "riscv32")]
+    unsafe {
+        asm!(
+            "ecall",
+            inout ("a0") stime as usize => _,
+            inout ("a1") (stime >> 32) as usize => _,
+            in("a7") SET_TIMER_EID,
+        );
+    }
+}
+
+/// 将字符写入调试控制台。如果仍有待处理的控制台输出,此调用将阻塞。如果不存在控制台,则不会执行任何操作。
+#[inline]
+pub unsafe fn console_putchar(c: u8) {
+    unsafe {
+        ecall1(c.into(), CONSOLE_PUTCHAR_EID, 0).ok();
+    }
+}
+
+/// 尝试从调试控制台获取一个字符。
+/// 如果没有任何字符等待阅读,或者没有调试控制台设备,则此函数将返回[`None`]。
+#[inline]
+pub unsafe fn console_getchar() -> Option<u8> {
+    let mut ret: i8;
+
+    unsafe {
+        asm!(
+            "ecall",
+            lateout("a0") ret,
+            in("a7") CONSOLE_GETCHAR_EID,
+        );
+    }
+
+    match ret {
+        -1 => None,
+        _ => Some(ret as u8),
+    }
+}
+
+/// 清除current核心的待处理中断(IPIs)。
+#[inline]
+#[deprecated = "S模式可以直接清除`sip.SSIP` CSR位,因此无需调用此函数。"]
+pub unsafe fn clear_ipi() {
+    unsafe {
+        asm!(
+            "ecall",
+            in("a7") CLEAR_IPI_EID,
+            lateout("a0") _,
+        );
+    }
+}
+
+/// 向所有由`hart_mask`位掩码指定的核心发送中断(IPI)。接收到的中断表示为监视器软件中断。
+///
+/// ## 参数
+/// - `hart_mask`: 一个长度为`n_harts / size_of::<usize>()`的二进制位向量,向上取整到下一个`usize`。
+#[inline]
+pub unsafe fn send_ipi(hart_mask: &[usize]) {
+    unsafe {
+        asm!(
+            "ecall",
+            inlateout("a0") hart_mask.as_ptr() => _,
+            in("a7") SEND_IPI_EID,
+        );
+    }
+}
+
+/// 对指定的心脏(hart)执行 `FENCE.I` 指令
+///
+/// ## 参数
+/// - `hart_mask`: 一个长度为 `n_harts / size_of::<usize>()` 的位矢量,
+/// 向上取整到下一个 `usize」。
+#[inline]
+pub unsafe fn remote_fence_i(hart_mask: &[usize]) {
+    unsafe {
+        asm!(
+            "ecall",
+            inlateout("a0") hart_mask.as_ptr() => _,
+            in("a7") REMOTE_FENCE_I_EID,
+        );
+    }
+}
+
+/// 在指定的hart上执行`SFENCE.VMA`指令
+/// 为指定的虚拟内存范围(由`start`和`size`指定)执行。
+///
+/// ## 参数
+/// - `hart_mask`: 一个长度为`n_harts / size_of::<usize>()`的二进制向量,
+/// 向上取整到下一个`usize`。
+/// - `start`: 要执行`SFENCE.VMA`的起始虚拟地址。
+/// - `size`: 要对`start`执行的`SFENCE.VMA`的字节大小。例如,要失效一个
+/// 包含2个4-KiB页面的区域,您会为`size`传递`8192`。
+///
+/// 如果`start`和`size`都为`0`,或者如果`size`为[`usize::MAX`],则将执行完整的
+/// `SFENCE.VMA`,而不仅仅是一个或多个页面大小的`SFENCE.VMA`。
+#[inline]
+pub unsafe fn remote_sfence_vma(hart_mask: &[usize], start: VirtAddr, size: usize) {
+    unsafe {
+        asm!(
+            "ecall",
+            inlateout("a0") hart_mask.as_ptr() => _,
+            in("a1") start.data(),
+            in("a2") size,
+            in("a7") REMOTE_SFENCE_VMA_EID,
+        );
+    }
+}
+
+/// 在指定的hart上执行SFENCE.VMA指令
+///
+/// 仅针对指定的地址空间ID(ASID)执行虚拟内存范围指定的
+/// start和size的hart_mask位掩码。
+///
+/// ## 参数
+/// - `hart_mask`: 一个长度为`n_harts / size_of::<usize>()`的二进制向量,
+/// 向上取整到下一个`usize`。
+/// - `start`: 要执行`SFENCE.VMA`的起始虚拟地址。
+/// - `size`: 要对`start`执行的`SFENCE.VMA`的字节大小。例如,要失效一个
+/// 包含2个4-KiB页面的区域,您会为`size`传递`8192`。
+/// - `asid`: 要执行`SFENCE.VMA`的地址空间ID。
+///
+/// 如果start和size都为0,或者如果size为[usize::MAX],则将执行全
+/// 部SFENCE.VMA,而不是多个页面大小的SFENCE.VMA`。
+#[inline]
+pub unsafe fn remote_sfence_vma_asid(hart_mask: &[usize], start: usize, size: usize, asid: usize) {
+    unsafe {
+        asm!(
+            "ecall",
+            inlateout("a0") hart_mask.as_ptr() => _,
+            in("a1") start,
+            in("a2") size,
+            in("a3") asid,
+            in("a7") REMOTE_SFENCE_VMA_ASID_EID,
+        );
+    }
+}
+
+/// 将所有核心置于关闭状态,此时处理器的执行模式比当前监督模式具有更高的特权。此调用不会返回。
+#[inline]
+pub unsafe fn shutdown() -> ! {
+    unsafe {
+        asm!(
+            "ecall",
+            in("a7") SHUTDOWN_EID,
+            options(noreturn)
+        );
+    }
+}

+ 93 - 0
kernel/src/arch/riscv64/driver/sbi/mod.rs

@@ -0,0 +1,93 @@
+use self::legacy::console_putchar;
+
+/// The SBI S-mode driver.
+///
+/// Some code takes from `https://github.com/repnop/sbi.git`
+mod ecall;
+pub mod legacy;
+
+/// Error codes returned by SBI calls
+///
+/// note: `SBI_SUCCESS` is not represented here since this is to be used as the
+/// error type in a `Result`
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum SbiError {
+    /// The SBI call failed
+    Failed,
+    /// The SBI call is not implemented or the functionality is not available
+    NotSupported,
+    /// An invalid parameter was passed
+    InvalidParameter,
+    /// The SBI implementation has denied execution of the call functionality
+    Denied,
+    /// An invalid address was passed
+    InvalidAddress,
+    /// The resource is already available
+    AlreadyAvailable,
+    /// The resource was previously started
+    AlreadyStarted,
+    /// The resource was previously stopped
+    AlreadyStopped,
+}
+
+impl SbiError {
+    #[inline]
+    fn new(n: isize) -> Self {
+        match n {
+            -1 => SbiError::Failed,
+            -2 => SbiError::NotSupported,
+            -3 => SbiError::InvalidParameter,
+            -4 => SbiError::Denied,
+            -5 => SbiError::InvalidAddress,
+            -6 => SbiError::AlreadyAvailable,
+            -7 => SbiError::AlreadyStarted,
+            -8 => SbiError::AlreadyStopped,
+            n => unreachable!("bad SBI error return value: {}", n),
+        }
+    }
+}
+
+impl core::fmt::Display for SbiError {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        write!(
+            f,
+            "{}",
+            match self {
+                SbiError::AlreadyAvailable => "resource is already available",
+                SbiError::Denied => "SBI implementation denied execution",
+                SbiError::Failed => "call to SBI failed",
+                SbiError::InvalidAddress => "invalid address passed",
+                SbiError::InvalidParameter => "invalid parameter passed",
+                SbiError::NotSupported => "SBI call not implemented or functionality not available",
+                SbiError::AlreadyStarted => "resource was already started",
+                SbiError::AlreadyStopped => "resource was already stopped",
+            }
+        )
+    }
+}
+
+/// 向控制台打印字符串。
+///
+/// 该函数接受一个字节切片 `s` 作为输入,并迭代切片中的每个字节 `c`。
+/// 然后调用 `console_putchar` 函数,将 `c` 的值作为参数传递给它。
+///
+/// # 安全性
+/// 该函数被标记为 `unsafe`,因为它调用了 `console_putchar` 函数,
+/// 而假设该函数执行可能有副作用或违反内存安全的底层操作。
+/// 调用者有责任确保 `s` 切片是有效的并且正确终止的。
+///
+/// # 参数
+///
+/// * `s` - 表示要打印的字符串的字节切片。
+///
+/// # 示例
+///
+/// ```
+/// let message = b"Hello, World!";
+/// console_putstr(message);
+/// ```
+pub unsafe fn console_putstr(s: &[u8]) {
+    for c in s {
+        unsafe { console_putchar(*c) };
+    }
+}

+ 14 - 0
kernel/src/arch/riscv64/init/mod.rs

@@ -0,0 +1,14 @@
+use core::intrinsics::unreachable;
+
+use crate::{
+    driver::tty::serial::serial8250::send_to_default_serial8250_port, init::init_before_mem_init,
+    kdebug,
+};
+
+#[no_mangle]
+unsafe extern "C" fn kernel_main(hartid: usize, fdt_addr: usize) -> ! {
+    init_before_mem_init();
+    send_to_default_serial8250_port(&b"Hello, world! RISC-V!\n"[..]);
+    loop {}
+    unreachable()
+}

+ 4 - 3
kernel/src/arch/riscv64/link.ld

@@ -10,8 +10,8 @@ ENTRY(_start)
 
 SECTIONS
 {
-	KERNEL_VMA = 0xffffffc000000000;
-	//KERNEL_VMA = 0;
+	//KERNEL_VMA = 0xffffffc000000000;
+	KERNEL_VMA = 0;
 	. = 0x1000000;
 	
 	.boot.text :
@@ -44,7 +44,8 @@ SECTIONS
 		_data = .;
 		*(.data)
 		*(.data.*)
-		
+		*(.got.plt)
+   		*(.got)
 		_edata = .;
 	}
 

+ 2 - 0
kernel/src/arch/riscv64/mod.rs

@@ -1,5 +1,7 @@
 pub mod asm;
 pub mod cpu;
+pub mod driver;
+mod init;
 pub mod interrupt;
 pub mod ipc;
 mod kvm;

+ 13 - 0
kernel/src/arch/riscv64/process/mod.rs

@@ -10,6 +10,19 @@ use super::interrupt::TrapFrame;
 pub mod kthread;
 pub mod syscall;
 
+#[allow(dead_code)]
+#[repr(align(32768))]
+union InitProcUnion {
+    /// 用于存放idle进程的内核栈
+    idle_stack: [u8; 32768],
+}
+
+#[link_section = ".data.init_proc_union"]
+#[no_mangle]
+static BSP_IDLE_STACK_SPACE: InitProcUnion = InitProcUnion {
+    idle_stack: [0; 32768],
+};
+
 pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! {
     unimplemented!("RiscV64 arch_switch_to_user")
 }

+ 18 - 0
kernel/src/arch/riscv64/riscv64imac-unknown-none-elf.json

@@ -0,0 +1,18 @@
+{
+  "arch": "riscv64",
+  "code-model": "medium",
+  "cpu": "generic-rv64",
+  "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
+  "eh-frame-header": false,
+  "emit-debug-gdb-scripts": false,
+  "features": "+m,+a,+c",
+  "is-builtin": false,
+  "linker": "rust-lld",
+  "linker-flavor": "ld.lld",
+  "llvm-target": "riscv64",
+  "max-atomic-width": 64,
+  "panic-strategy": "abort",
+  "relocation-model": "pic",
+  "position-independent-executables": true,
+  "target-pointer-width": "64"
+}

+ 3 - 6
kernel/src/arch/x86_64/driver/hpet.rs

@@ -67,7 +67,7 @@ impl Hpet {
         let tm_num = hpet.timers_num();
         kinfo!("HPET has {} timers", tm_num);
         hpet_info.hpet_number = tm_num as u8;
-        drop(hpet);
+
         drop(mmio);
         if tm_num == 0 {
             return Err(SystemError::ENODEV);
@@ -118,7 +118,6 @@ impl Hpet {
 
         unsafe { regs.write_main_counter_value(0) };
 
-        drop(regs);
         drop(inner_guard);
 
         let (inner_guard, timer_reg) = unsafe { self.timer_mut(0).ok_or(SystemError::ENODEV) }?;
@@ -130,7 +129,6 @@ impl Hpet {
             volwrite!(timer_reg, config, 0x004c);
             volwrite!(timer_reg, comparator_value, ticks);
         }
-        drop(timer_reg);
         drop(inner_guard);
 
         // todo!("register irq in C");
@@ -142,7 +140,6 @@ impl Hpet {
         // 置位旧设备中断路由兼容标志位、定时器组使能标志位
         unsafe { regs.write_general_config(3) };
 
-        drop(regs);
         drop(inner_guard);
 
         kinfo!("HPET enabled");
@@ -208,7 +205,7 @@ impl Hpet {
     pub fn main_counter_value(&self) -> u64 {
         let (inner_guard, regs) = unsafe { self.hpet_regs() };
         let value = regs.main_counter_value();
-        drop(regs);
+
         drop(inner_guard);
         return value;
     }
@@ -217,7 +214,7 @@ impl Hpet {
         let (inner_guard, regs) = unsafe { self.hpet_regs() };
         let period = regs.counter_clock_period();
         kdebug!("HPET period: {}", period);
-        drop(regs);
+
         drop(inner_guard);
         return period;
     }

+ 2 - 2
kernel/src/driver/base/kset.rs

@@ -30,7 +30,7 @@ pub struct KSet {
 }
 
 impl Hash for KSet {
-    fn hash<H: ~const core::hash::Hasher>(&self, state: &mut H) {
+    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
         self.self_ref.as_ptr().hash(state);
         self.inner.read().name.hash(state);
     }
@@ -123,7 +123,7 @@ impl KSet {
     #[allow(dead_code)]
     pub fn cleanup_weak(&self) {
         let mut kobjects = self.kobjects.write();
-        kobjects.drain_filter(|x| x.upgrade().is_none());
+        kobjects.retain(|x| x.upgrade().is_some());
     }
 
     pub fn as_kobject(&self) -> Arc<dyn KObject> {

+ 21 - 2
kernel/src/driver/tty/serial/serial8250/mod.rs

@@ -59,12 +59,17 @@ pub(super) fn serial8250_manager() -> &'static Serial8250Manager {
     &Serial8250Manager
 }
 
+/// 标记serial8250是否已经初始化
+static mut INITIALIZED: bool = false;
+
 #[derive(Debug)]
 pub(super) struct Serial8250Manager;
 
 impl Serial8250Manager {
     /// 初始化串口设备(在内存管理初始化之前)
     pub fn early_init(&self) -> Result<(), SystemError> {
+        // todo: riscv64: 串口设备初始化
+        #[cfg(not(target_arch = "riscv64"))]
         serial8250_pio_port_early_init()?;
         return Ok(());
     }
@@ -101,10 +106,14 @@ impl Serial8250Manager {
                 return e;
             })?;
 
-        // todo: 把驱动注册到platform总线
+        // 把驱动注册到platform总线
         platform_driver_manager()
             .register(serial8250_isa_driver.clone() as Arc<dyn PlatformDriver>)?;
 
+        unsafe {
+            INITIALIZED = true;
+        }
+
         return Ok(());
     }
 
@@ -469,7 +478,7 @@ impl Driver for Serial8250ISADriver {
     fn delete_device(&self, device: &Arc<dyn Device>) {
         let mut inner = self.inner.write();
 
-        inner.devices.drain_filter(|d| Arc::ptr_eq(d, device));
+        inner.devices.retain(|d| !Arc::ptr_eq(d, device));
     }
 
     fn bus(&self) -> Option<Arc<dyn Bus>> {
@@ -539,5 +548,15 @@ impl KObject for Serial8250ISADriver {
 
 /// 临时函数,用于向默认的串口发送数据
 pub fn send_to_default_serial8250_port(s: &[u8]) {
+    #[cfg(target_arch = "x86_64")]
     send_to_serial8250_pio_com1(s);
+
+    #[cfg(target_arch = "riscv64")]
+    {
+        if unsafe { INITIALIZED } {
+            todo!("riscv64: send_to_default_serial8250_port")
+        } else {
+            unsafe { crate::arch::driver::sbi::console_putstr(s) };
+        }
+    }
 }

+ 8 - 5
kernel/src/driver/video/mod.rs

@@ -170,11 +170,14 @@ impl VideoRefreshManager {
         return self.device_buffer.read();
     }
 
-    /**
-     * @brief 初始化显示驱动
-     *
-     * @return int
-     */
+    /// 在riscv64平台下暂时不支持
+    #[cfg(target_arch = "riscv64")]
+    pub unsafe fn video_init() -> Result<(), SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
+    /// 此函数用于初始化显示驱动,为后续的图形输出做好准备。
+    #[cfg(not(target_arch = "riscv64"))]
     pub unsafe fn video_init() -> Result<(), SystemError> {
         static INIT: AtomicBool = AtomicBool::new(false);
 

+ 1 - 1
kernel/src/exception/softirq.rs

@@ -148,7 +148,7 @@ impl Softirq {
     /// @param irq_num 中断向量号码   
     pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
         // kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64);
-        let table_guard = &mut self.table.write();
+        let mut table_guard = self.table.write();
         // 将软中断向量清空
         table_guard[softirq_num as usize] = None;
         drop(table_guard);

+ 0 - 1
kernel/src/filesystem/fat/entry.rs

@@ -625,7 +625,6 @@ impl FATDir {
                 // todo: 设置创建、访问时间
                 dot_entry.flush(&fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
 
-                drop(dot_entry);
                 // 偏移量加上一个目录项的长度
                 offset += FATRawDirEntry::DIR_ENTRY_LEN;
 

+ 5 - 10
kernel/src/filesystem/procfs/mod.rs

@@ -115,7 +115,8 @@ impl ProcFSInode {
     /// @brief 去除Vec中所有的\0,并在结尾添加\0
     #[inline]
     fn trim_string(&self, data: &mut Vec<u8>) {
-        data.drain_filter(|x: &mut u8| *x == 0);
+        data.retain(|x| *x != 0);
+
         data.push(0);
     }
     // todo:其他数据获取函数实现
@@ -420,15 +421,9 @@ impl IndexNode for LockedProcFSInode {
         if let FileType::Dir = guard.metadata.file_type {
             return Ok(());
         }
-        // 获取数据信息
-        let private_data = match data {
-            FilePrivateData::Procfs(p) => p,
-            _ => {
-                panic!("ProcFS: FilePrivateData mismatch!");
-            }
-        };
-        // 释放资源
-        drop(private_data);
+        // 释放data
+        *data = FilePrivateData::Procfs(ProcfsFilePrivateData::new());
+
         return Ok(());
     }
 

+ 3 - 3
kernel/src/init/mod.rs

@@ -10,8 +10,8 @@ fn init_intertrait() {
 }
 
 /// 在内存管理初始化之前,执行的初始化
-fn init_before_mem_init() {
+pub fn init_before_mem_init() {
     tty_early_init().expect("tty early init failed");
-    unsafe { VideoRefreshManager::video_init().ok() };
-    scm_init();
+    let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
+    scm_init(video_ok);
 }

+ 3 - 12
kernel/src/ipc/signal_types.rs

@@ -423,17 +423,8 @@ impl SigPending {
     /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。
     pub fn flush_by_mask(&mut self, mask: &SigSet) {
         // 定义过滤器,从sigqueue中删除mask中被置位的信号
-        let filter = |x: &mut SigInfo| {
-            if mask.contains(SigSet::from_bits_truncate(x.sig_no as u64)) {
-                return true;
-            }
-            return false;
-        };
-        let filter_result: Vec<SigInfo> = self.queue.q.drain_filter(filter).collect();
-        // 回收这些siginfo
-        for x in filter_result {
-            drop(x)
-        }
+        let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64));
+        self.queue.q.retain(filter);
     }
 }
 
@@ -496,7 +487,7 @@ impl SigQueue {
             return false;
         };
         // 从sigqueue中过滤出结果
-        let mut filter_result: Vec<SigInfo> = self.q.drain_filter(filter).collect();
+        let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect();
         // 筛选出的结果不能大于1个
         assert!(filter_result.len() <= 1);
 

+ 1 - 1
kernel/src/ipc/syscall.rs

@@ -105,7 +105,7 @@ impl Syscall {
     ) -> Result<usize, SystemError> {
         // 请注意:用户态传进来的user_sigaction结构体类型,请注意,这个结构体与内核实际的不一样
         let act: *mut UserSigaction = new_act as *mut UserSigaction;
-        let mut old_act = old_act as *mut UserSigaction;
+        let old_act = old_act as *mut UserSigaction;
         let mut new_ka: Sigaction = Default::default();
         let mut old_sigaction: Sigaction = Default::default();
         // 如果传入的,新的sigaction不为空

+ 1 - 4
kernel/src/lib.rs

@@ -7,11 +7,9 @@
 #![feature(const_trait_impl)]
 #![feature(const_refs_to_cell)]
 #![feature(core_intrinsics)]
-#![feature(cstr_from_bytes_until_nul)]
 #![feature(c_void_variant)]
-#![feature(drain_filter)]
+#![feature(extract_if)]
 #![feature(inline_const)]
-#![feature(is_some_and)]
 #![feature(naked_functions)]
 #![feature(panic_info_message)]
 #![feature(ptr_internals)]
@@ -22,7 +20,6 @@
 #![feature(ptr_to_from_bits)]
 #![feature(concat_idents)]
 #![cfg_attr(target_os = "none", no_std)]
-#![feature(atomic_mut_ptr)]
 
 #[cfg(test)]
 #[macro_use]

+ 0 - 4
kernel/src/libs/elf.rs

@@ -659,8 +659,6 @@ impl BinaryLoader for ElfLoader {
                 return Err(ExecError::InvalidParemeter);
             }
 
-            drop(p_vaddr);
-
             // end vaddr of this segment(code+data+bss)
             let seg_end_vaddr_f = self.elf_page_align_up(VirtAddr::new(
                 (seg_to_load.p_vaddr + seg_to_load.p_filesz) as usize,
@@ -683,8 +681,6 @@ impl BinaryLoader for ElfLoader {
                 end_data = Some(seg_end_vaddr_f);
             }
 
-            drop(seg_end_vaddr_f);
-
             let seg_end_vaddr = VirtAddr::new((seg_to_load.p_vaddr + seg_to_load.p_memsz) as usize);
 
             if seg_end_vaddr > elf_brk {

+ 5 - 6
kernel/src/libs/futex/futex.rs

@@ -124,7 +124,9 @@ impl FutexHashBucket {
 
     /// 将FutexObj从bucket中删除
     pub fn remove(&mut self, futex: Arc<FutexObj>) {
-        self.chain.drain_filter(|x| Arc::ptr_eq(x, &futex));
+        self.chain
+            .extract_if(|x| Arc::ptr_eq(x, &futex))
+            .for_each(drop);
     }
 }
 
@@ -174,7 +176,7 @@ pub struct PrivateKey {
 }
 
 impl Hash for PrivateKey {
-    fn hash<H: ~const Hasher>(&self, state: &mut H) {
+    fn hash<H: Hasher>(&self, state: &mut H) {
         self.address.hash(state);
     }
 }
@@ -284,7 +286,6 @@ impl Futex {
             kwarn!("error:{e:?}");
             e
         })?;
-        drop(bucket_mut);
         drop(futex_map_guard);
         drop(irq_guard);
         sched();
@@ -368,7 +369,6 @@ impl Futex {
         // 从队列中唤醒
         let count = bucket_mut.wake_up(key.clone(), Some(bitset), nr_wake)?;
 
-        drop(bucket_mut);
         drop(binding);
 
         FutexData::try_remove(&key);
@@ -427,7 +427,6 @@ impl Futex {
             // 唤醒nr_wake个进程
             let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?;
             let ret = bucket_1_mut.wake_up(key1.clone(), None, nr_wake as u32)?;
-            drop(bucket_1_mut);
             // 将bucket1中最多nr_requeue个任务转移到bucket2
             for _ in 0..nr_requeue {
                 let bucket_1_mut = futex_data_guard.get_mut(&key1).ok_or(SystemError::EINVAL)?;
@@ -615,7 +614,7 @@ impl Futex {
 
         let atomic_addr = AtomicU64::new(uaddr.data() as u64);
         // 这个指针是指向指针的指针
-        let ptr = atomic_addr.as_mut_ptr();
+        let ptr = atomic_addr.as_ptr();
         match op {
             FutexOP::FUTEX_OP_SET => unsafe {
                 *((*ptr) as *mut u32) = oparg;

+ 15 - 8
kernel/src/libs/lib_ui/screen_manager.rs

@@ -10,12 +10,15 @@ use crate::{
     driver::{
         tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager,
     },
-    libs::{rwlock::RwLock, spinlock::SpinLock},
+    libs::{lib_ui::textui::textui_is_enable_put_to_window, rwlock::RwLock, spinlock::SpinLock},
     mm::VirtAddr,
     syscall::SystemError,
 };
 
-use super::textui_no_alloc::textui_init_no_alloc;
+use super::{
+    textui::{textui_disable_put_to_window, textui_enable_put_to_window},
+    textui_no_alloc::textui_init_no_alloc,
+};
 
 /// 全局的UI框架列表
 pub static SCM_FRAMEWORK_LIST: SpinLock<LinkedList<Arc<dyn ScmUiFramework>>> =
@@ -274,10 +277,14 @@ pub trait ScmUiFramework: Sync + Send + Debug {
 /// ## 调用时机
 ///
 /// 该函数在内核启动的早期进行调用。调用时,内存管理模块尚未初始化。
-pub fn scm_init() {
+pub fn scm_init(enable_put_to_window: bool) {
     SCM_DOUBLE_BUFFER_ENABLED.store(false, Ordering::SeqCst); // 禁用双缓冲
-
-    textui_init_no_alloc();
+    if enable_put_to_window {
+        textui_enable_put_to_window();
+    } else {
+        textui_disable_put_to_window();
+    }
+    textui_init_no_alloc(enable_put_to_window);
 
     send_to_default_serial8250_port("\nfinish_scm_init\n\0".as_bytes());
 }
@@ -370,7 +377,7 @@ pub fn scm_enable_double_buffer() -> Result<i32, SystemError> {
 pub fn scm_enable_put_to_window() {
     // mm之前要继续往窗口打印信息时,因为没有动态内存分配(textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值
     if CURRENT_FRAMEWORK.read().is_none() {
-        super::textui::ENABLE_PUT_TO_WINDOW.store(true, Ordering::SeqCst);
+        textui_enable_put_to_window();
     } else {
         let r = CURRENT_FRAMEWORK
             .write()
@@ -387,8 +394,8 @@ pub fn scm_enable_put_to_window() {
 pub fn scm_disable_put_to_window() {
     // mm之前要停止往窗口打印信息时,因为没有动态内存分配(rwlock与otion依然能用,但是textui并没有往scm注册),且使用的是textui,要直接修改textui里面的值
     if CURRENT_FRAMEWORK.read().is_none() {
-        super::textui::ENABLE_PUT_TO_WINDOW.store(false, Ordering::SeqCst);
-        assert!(super::textui::ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst) == false);
+        textui_disable_put_to_window();
+        assert!(textui_is_enable_put_to_window() == false);
     } else {
         let r = CURRENT_FRAMEWORK
             .write()

+ 25 - 7
kernel/src/libs/lib_ui/textui.rs

@@ -37,7 +37,25 @@ pub const TEXTUI_CHAR_HEIGHT: u32 = 16;
 
 pub static mut TEXTUI_IS_INIT: bool = false;
 
-pub static ENABLE_PUT_TO_WINDOW: AtomicBool = AtomicBool::new(true);
+static ENABLE_PUT_TO_WINDOW: AtomicBool = AtomicBool::new(false);
+
+/// 启用将文本输出到窗口的功能。
+pub fn textui_enable_put_to_window() {
+    ENABLE_PUT_TO_WINDOW.store(true, Ordering::SeqCst);
+}
+
+/// 禁用将文本输出到窗口的功能。
+pub fn textui_disable_put_to_window() {
+    ENABLE_PUT_TO_WINDOW.store(false, Ordering::SeqCst);
+}
+
+/// 检查是否启用了将文本输出到窗口的功能。
+///
+/// # 返回
+/// 如果启用了将文本输出到窗口的功能,则返回 `true`,否则返回 `false`。
+pub fn textui_is_enable_put_to_window() -> bool {
+    ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst)
+}
 
 /// 获取TEXTUI_FRAMEWORK的可变实例
 pub fn textui_framework() -> Arc<TextUiFramework> {
@@ -904,12 +922,12 @@ impl ScmUiFramework for TextUiFramework {
     }
     // 启用ui框架的回调函数
     fn enable(&self) -> Result<i32, SystemError> {
-        ENABLE_PUT_TO_WINDOW.store(true, Ordering::SeqCst);
+        textui_enable_put_to_window();
         return Ok(0);
     }
     // 禁用ui框架的回调函数
     fn disable(&self) -> Result<i32, SystemError> {
-        ENABLE_PUT_TO_WINDOW.store(false, Ordering::SeqCst);
+        textui_disable_put_to_window();
 
         return Ok(0);
     }
@@ -986,7 +1004,7 @@ pub fn textui_putchar(
                 character,
                 fr_color,
                 bk_color,
-                ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst),
+                textui_is_enable_put_to_window(),
             );
     } else {
         //未初始化暴力输出
@@ -994,7 +1012,7 @@ pub fn textui_putchar(
             character,
             fr_color,
             bk_color,
-            ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst),
+            textui_is_enable_put_to_window(),
         );
     }
 }
@@ -1021,14 +1039,14 @@ pub fn textui_putstr(
                 character,
                 fr_color,
                 bk_color,
-                ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst),
+                textui_is_enable_put_to_window(),
             )?;
         } else {
             no_init_textui_putchar_window(
                 character,
                 fr_color,
                 bk_color,
-                ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst),
+                textui_is_enable_put_to_window(),
             )?;
         }
     }

+ 7 - 5
kernel/src/libs/lib_ui/textui_no_alloc.rs

@@ -21,12 +21,14 @@ pub static NO_ALLOC_OPERATIONS_LINE: AtomicI32 = AtomicI32::new(0);
 pub static NO_ALLOC_OPERATIONS_INDEX: AtomicI32 = AtomicI32::new(0);
 
 /// 当系统刚启动的时候,由于内存管理未初始化,而texiui需要动态内存分配。因此只能暂时暴力往屏幕(video_frame_buffer_info)输出信息
-pub fn textui_init_no_alloc() {
-    let height = video_refresh_manager().device_buffer().height();
-    let width = video_refresh_manager().device_buffer().width();
-    TRUE_LINE_NUM.store((height / TEXTUI_CHAR_HEIGHT) as i32, Ordering::SeqCst);
+pub fn textui_init_no_alloc(video_enabled: bool) {
+    if video_enabled {
+        let height = video_refresh_manager().device_buffer().height();
+        let width = video_refresh_manager().device_buffer().width();
+        TRUE_LINE_NUM.store((height / TEXTUI_CHAR_HEIGHT) as i32, Ordering::SeqCst);
 
-    CHAR_PER_LINE.store((width / TEXTUI_CHAR_WIDTH) as i32, Ordering::SeqCst);
+        CHAR_PER_LINE.store((width / TEXTUI_CHAR_WIDTH) as i32, Ordering::SeqCst);
+    }
 }
 
 pub fn no_init_textui_putchar_window(

+ 1 - 3
kernel/src/libs/notifier.rs

@@ -65,9 +65,7 @@ impl<V: Clone + Copy, T> NotifierChain<V, T> {
 
     /// @brief 在通知链中取消注册节点
     pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
-        let remove = self
-            .0
-            .drain_filter(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
+        let remove = self.0.extract_if(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
         match remove.count() {
             0 => return Err(SystemError::ENOENT),
             _ => return Ok(()),

+ 1 - 1
kernel/src/mm/mmio_buddy.rs

@@ -354,7 +354,7 @@ impl MmioBuddyMemPool {
             // element 只会有一个元素
             let mut element: Vec<MmioBuddyAddrRegion> = list_guard
                 .list
-                .drain_filter(|x| x.vaddr == buddy_vaddr)
+                .extract_if(|x| x.vaddr == buddy_vaddr)
                 .collect();
             if element.len() == 1 {
                 list_guard.num_free -= 1;

+ 0 - 13
kernel/src/net/socket.rs

@@ -305,7 +305,6 @@ impl Socket for RawSocket {
                     }
                 }
             }
-            drop(socket);
             drop(socket_set_guard);
             SOCKET_WAITQUEUE.sleep();
         }
@@ -371,8 +370,6 @@ impl Socket for RawSocket {
                     // 发送数据包
                     socket.send_slice(&buffer).unwrap();
 
-                    drop(socket);
-
                     iface.poll(&mut socket_set_guard).ok();
 
                     drop(socket_set_guard);
@@ -489,7 +486,6 @@ impl Socket for UdpSocket {
 
             if socket.can_recv() {
                 if let Ok((size, remote_endpoint)) = socket.recv_slice(buf) {
-                    drop(socket);
                     drop(socket_set_guard);
                     poll_ifaces();
                     return (Ok(size), Endpoint::Ip(Some(remote_endpoint)));
@@ -498,7 +494,6 @@ impl Socket for UdpSocket {
                 // 如果socket没有连接,则忙等
                 // return (Err(SystemError::ENOTCONN), Endpoint::Ip(None));
             }
-            drop(socket);
             drop(socket_set_guard);
             SOCKET_WAITQUEUE.sleep();
         }
@@ -545,7 +540,6 @@ impl Socket for UdpSocket {
             match socket.send_slice(&buf, *remote_endpoint) {
                 Ok(()) => {
                     // kdebug!("udp write: send ok");
-                    drop(socket);
                     drop(socket_set_guard);
                     poll_ifaces();
                     return Ok(buf.len());
@@ -731,7 +725,6 @@ impl Socket for TcpSocket {
                             return (Err(SystemError::ENOTCONN), Endpoint::Ip(None));
                         };
 
-                        drop(socket);
                         drop(socket_set_guard);
                         poll_ifaces();
                         return (Ok(size), Endpoint::Ip(Some(endpoint)));
@@ -751,7 +744,6 @@ impl Socket for TcpSocket {
             } else {
                 return (Err(SystemError::ENOTCONN), Endpoint::Ip(None));
             }
-            drop(socket);
             drop(socket_set_guard);
             SOCKET_WAITQUEUE.sleep();
         }
@@ -765,7 +757,6 @@ impl Socket for TcpSocket {
             if socket.can_send() {
                 match socket.send_slice(buf) {
                     Ok(size) => {
-                        drop(socket);
                         drop(socket_set_guard);
                         poll_ifaces();
                         return Ok(size);
@@ -825,7 +816,6 @@ impl Socket for TcpSocket {
                     // avoid deadlock
                     drop(inner_iface);
                     drop(iface);
-                    drop(socket);
                     drop(sockets);
                     loop {
                         poll_ifaces();
@@ -837,7 +827,6 @@ impl Socket for TcpSocket {
                                 return Ok(());
                             }
                             tcp::State::SynSent => {
-                                drop(socket);
                                 drop(sockets);
                                 SOCKET_WAITQUEUE.sleep();
                             }
@@ -916,7 +905,6 @@ impl Socket for TcpSocket {
             if socket.is_active() {
                 // kdebug!("tcp accept: socket.is_active()");
                 let remote_ep = socket.remote_endpoint().ok_or(SystemError::ENOTCONN)?;
-                drop(socket);
 
                 let new_socket = {
                     // Initialize the TCP socket's buffers.
@@ -965,7 +953,6 @@ impl Socket for TcpSocket {
 
                 return Ok((new_socket, Endpoint::Ip(Some(remote_ep))));
             }
-            drop(socket);
             drop(sockets);
             SOCKET_WAITQUEUE.sleep();
         }

+ 7 - 0
kernel/src/process/c_adapter.rs

@@ -59,6 +59,13 @@ unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 {
     return ProcessManager::current_pcb().arch_info_irqsave().rbp() as u64;
 }
 
+#[no_mangle]
+#[cfg(target_arch = "riscv64")]
+unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 {
+    // 不应该实现这个函数
+    unimplemented!("rs_current_pcb_thread_rbp")
+}
+
 #[no_mangle]
 unsafe extern "C" fn rs_preempt_disable() {
     return ProcessManager::preempt_disable();

+ 1 - 1
kernel/src/process/mod.rs

@@ -915,7 +915,7 @@ impl Drop for ProcessControlBlock {
             .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
 
         if let Some(ppcb) = self.parent_pcb.read().upgrade() {
-            ppcb.children.write().drain_filter(|pid| *pid == self.pid());
+            ppcb.children.write().retain(|pid| *pid != self.pid());
         }
     }
 }

+ 3 - 2
kernel/src/time/timer.rs

@@ -83,7 +83,7 @@ impl Timer {
     /// @brief 将定时器插入到定时器链表中
     pub fn activate(&self) {
         let inner_guard = self.0.lock();
-        let timer_list = &mut TIMER_LIST.lock();
+        let mut timer_list = TIMER_LIST.lock();
 
         // 链表为空,则直接插入
         if timer_list.is_empty() {
@@ -133,7 +133,8 @@ impl Timer {
     pub fn cancel(&self) -> bool {
         TIMER_LIST
             .lock()
-            .drain_filter(|x| Arc::<Timer>::as_ptr(&x) == self as *const Timer);
+            .extract_if(|x| Arc::<Timer>::as_ptr(&x) == self as *const Timer)
+            .for_each(|p| drop(p));
         true
     }
 }

+ 1 - 1
tools/bootstrap.sh

@@ -47,7 +47,7 @@ install_ubuntu_debian_pkg()
         lsb-release \
         llvm-dev libclang-dev clang gcc-multilib \
         gcc build-essential fdisk dosfstools dnsmasq bridge-utils iptables libssl-dev pkg-config \
-		sphinx gcc-riscv64-unknown-elf
+		sphinx gcc-riscv64-unknown-elf gcc-riscv64-linux-gnu gdb-multiarch
 	
 	# 如果python3没有安装
 	if [ -z "$(which python3)" ]; then