在riscv输出hello world (#466)

增加了以下内容:
- SBI驱动
- 把内核的rust工具链升级到2023-08-15版本
- 输出riscv的helloworld
- 设置内核是PIC的
This commit is contained in:
LoGin 2023-12-07 02:13:22 +08:00 committed by GitHub
parent fca83acef4
commit 1a72a751b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 722 additions and 122 deletions

View File

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

View File

@ -17,7 +17,7 @@ impl CFilesArch for RiscV64CFilesArch {
} }
fn setup_files(&self, _c: &mut cc::Build, files: &mut Vec<std::path::PathBuf>) { 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( files.append(&mut FileUtils::list_all_files(
&arch_path("asm"), &arch_path("asm"),
Some("c"), Some("c"),

View File

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

4
env.mk
View File

@ -22,7 +22,9 @@ export OBJCOPY=$(DragonOS_GCC)/x86_64-elf-objcopy
else ifeq ($(ARCH), riscv64) else ifeq ($(ARCH), riscv64)
export CC=riscv64-unknown-elf-gcc 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 AS=riscv64-unknown-elf-as
export NM=riscv64-unknown-elf-nm export NM=riscv64-unknown-elf-nm
export AR=riscv64-unknown-elf-ar export AR=riscv64-unknown-elf-ar

View File

@ -6,7 +6,7 @@ export ARCH ?= x86_64
ifeq ($(ARCH), x86_64) ifeq ($(ARCH), x86_64)
export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json export TARGET_JSON=arch/x86_64/x86_64-unknown-none.json
else ifeq ($(ARCH), riscv64) else ifeq ($(ARCH), riscv64)
export TARGET_JSON=riscv64imac-unknown-none-elf export TARGET_JSON=arch/riscv64/riscv64imac-unknown-none-elf.json
endif endif
export CARGO_ZBUILD=-Z build-std=core,alloc,compiler_builtins -Z build-std-features=compiler-builtins-mem 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)" # @echo "Checking kernel... ARCH=$(ARCH)"
# @exit 1 # @exit 1
ifeq ($(ARCH), x86_64) 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) 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 endif

View File

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

View File

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

View File

@ -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

View File

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

View File

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

View File

@ -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)),
}
}

View File

@ -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指令
///
/// 仅针对指定的地址空间IDASID执行虚拟内存范围指定的
/// 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)
);
}
}

View File

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

View File

@ -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()
}

View File

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

View File

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

View File

@ -10,6 +10,19 @@ use super::interrupt::TrapFrame;
pub mod kthread; pub mod kthread;
pub mod syscall; 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>) -> ! { pub unsafe fn arch_switch_to_user(path: String, argv: Vec<String>, envp: Vec<String>) -> ! {
unimplemented!("RiscV64 arch_switch_to_user") unimplemented!("RiscV64 arch_switch_to_user")
} }

View File

@ -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"
}

View File

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

View File

@ -30,7 +30,7 @@ pub struct KSet {
} }
impl Hash for 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.self_ref.as_ptr().hash(state);
self.inner.read().name.hash(state); self.inner.read().name.hash(state);
} }
@ -123,7 +123,7 @@ impl KSet {
#[allow(dead_code)] #[allow(dead_code)]
pub fn cleanup_weak(&self) { pub fn cleanup_weak(&self) {
let mut kobjects = self.kobjects.write(); 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> { pub fn as_kobject(&self) -> Arc<dyn KObject> {

View File

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

View File

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

View File

@ -148,7 +148,7 @@ impl Softirq {
/// @param irq_num 中断向量号码 /// @param irq_num 中断向量号码
pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) { pub fn unregister_softirq(&self, softirq_num: SoftirqNumber) {
// kdebug!("unregister_softirq softirq_num = {:?}", softirq_num as u64); // 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; table_guard[softirq_num as usize] = None;
drop(table_guard); drop(table_guard);

View File

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

View File

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

View File

@ -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"); tty_early_init().expect("tty early init failed");
unsafe { VideoRefreshManager::video_init().ok() }; let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
scm_init(); scm_init(video_ok);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,12 +10,15 @@ use crate::{
driver::{ driver::{
tty::serial::serial8250::send_to_default_serial8250_port, video::video_refresh_manager, 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, mm::VirtAddr,
syscall::SystemError, 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框架列表 /// 全局的UI框架列表
pub static SCM_FRAMEWORK_LIST: SpinLock<LinkedList<Arc<dyn ScmUiFramework>>> = 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); // 禁用双缓冲 SCM_DOUBLE_BUFFER_ENABLED.store(false, Ordering::SeqCst); // 禁用双缓冲
if enable_put_to_window {
textui_init_no_alloc(); 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()); 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() { pub fn scm_enable_put_to_window() {
// mm之前要继续往窗口打印信息时因为没有动态内存分配(textui并没有往scm注册)且使用的是textui,要直接修改textui里面的值 // mm之前要继续往窗口打印信息时因为没有动态内存分配(textui并没有往scm注册)且使用的是textui,要直接修改textui里面的值
if CURRENT_FRAMEWORK.read().is_none() { if CURRENT_FRAMEWORK.read().is_none() {
super::textui::ENABLE_PUT_TO_WINDOW.store(true, Ordering::SeqCst); textui_enable_put_to_window();
} else { } else {
let r = CURRENT_FRAMEWORK let r = CURRENT_FRAMEWORK
.write() .write()
@ -387,8 +394,8 @@ pub fn scm_enable_put_to_window() {
pub fn scm_disable_put_to_window() { pub fn scm_disable_put_to_window() {
// mm之前要停止往窗口打印信息时因为没有动态内存分配(rwlock与otion依然能用但是textui并没有往scm注册)且使用的是textui,要直接修改textui里面的值 // mm之前要停止往窗口打印信息时因为没有动态内存分配(rwlock与otion依然能用但是textui并没有往scm注册)且使用的是textui,要直接修改textui里面的值
if CURRENT_FRAMEWORK.read().is_none() { if CURRENT_FRAMEWORK.read().is_none() {
super::textui::ENABLE_PUT_TO_WINDOW.store(false, Ordering::SeqCst); textui_disable_put_to_window();
assert!(super::textui::ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst) == false); assert!(textui_is_enable_put_to_window() == false);
} else { } else {
let r = CURRENT_FRAMEWORK let r = CURRENT_FRAMEWORK
.write() .write()

View File

@ -37,7 +37,25 @@ pub const TEXTUI_CHAR_HEIGHT: u32 = 16;
pub static mut TEXTUI_IS_INIT: bool = false; 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的可变实例 /// 获取TEXTUI_FRAMEWORK的可变实例
pub fn textui_framework() -> Arc<TextUiFramework> { pub fn textui_framework() -> Arc<TextUiFramework> {
@ -904,12 +922,12 @@ impl ScmUiFramework for TextUiFramework {
} }
// 启用ui框架的回调函数 // 启用ui框架的回调函数
fn enable(&self) -> Result<i32, SystemError> { fn enable(&self) -> Result<i32, SystemError> {
ENABLE_PUT_TO_WINDOW.store(true, Ordering::SeqCst); textui_enable_put_to_window();
return Ok(0); return Ok(0);
} }
// 禁用ui框架的回调函数 // 禁用ui框架的回调函数
fn disable(&self) -> Result<i32, SystemError> { fn disable(&self) -> Result<i32, SystemError> {
ENABLE_PUT_TO_WINDOW.store(false, Ordering::SeqCst); textui_disable_put_to_window();
return Ok(0); return Ok(0);
} }
@ -986,7 +1004,7 @@ pub fn textui_putchar(
character, character,
fr_color, fr_color,
bk_color, bk_color,
ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst), textui_is_enable_put_to_window(),
); );
} else { } else {
//未初始化暴力输出 //未初始化暴力输出
@ -994,7 +1012,7 @@ pub fn textui_putchar(
character, character,
fr_color, fr_color,
bk_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, character,
fr_color, fr_color,
bk_color, bk_color,
ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst), textui_is_enable_put_to_window(),
)?; )?;
} else { } else {
no_init_textui_putchar_window( no_init_textui_putchar_window(
character, character,
fr_color, fr_color,
bk_color, bk_color,
ENABLE_PUT_TO_WINDOW.load(Ordering::SeqCst), textui_is_enable_put_to_window(),
)?; )?;
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -59,6 +59,13 @@ unsafe extern "C" fn rs_current_pcb_thread_rbp() -> u64 {
return ProcessManager::current_pcb().arch_info_irqsave().rbp() as 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] #[no_mangle]
unsafe extern "C" fn rs_preempt_disable() { unsafe extern "C" fn rs_preempt_disable() {
return ProcessManager::preempt_disable(); return ProcessManager::preempt_disable();

View File

@ -915,7 +915,7 @@ impl Drop for ProcessControlBlock {
.unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}")); .unwrap_or_else(|e| panic!("procfs_unregister_pid failed: error: {e:?}"));
if let Some(ppcb) = self.parent_pcb.read().upgrade() { 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());
} }
} }
} }

View File

@ -83,7 +83,7 @@ impl Timer {
/// @brief 将定时器插入到定时器链表中 /// @brief 将定时器插入到定时器链表中
pub fn activate(&self) { pub fn activate(&self) {
let inner_guard = self.0.lock(); 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() { if timer_list.is_empty() {
@ -133,7 +133,8 @@ impl Timer {
pub fn cancel(&self) -> bool { pub fn cancel(&self) -> bool {
TIMER_LIST TIMER_LIST
.lock() .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 true
} }
} }

View File

@ -47,7 +47,7 @@ install_ubuntu_debian_pkg()
lsb-release \ lsb-release \
llvm-dev libclang-dev clang gcc-multilib \ llvm-dev libclang-dev clang gcc-multilib \
gcc build-essential fdisk dosfstools dnsmasq bridge-utils iptables libssl-dev pkg-config \ 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没有安装 # 如果python3没有安装
if [ -z "$(which python3)" ]; then if [ -z "$(which python3)" ]; then