From a3b6a4fe292cef5343cf726d4cdf40f2d079d489 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 05:18:40 +0000 Subject: [PATCH 1/6] =?UTF-8?q?docs:=20=E7=BC=96=E5=86=99=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E5=88=87=E6=8D=A2=E7=9B=B8=E5=85=B3=E7=9A=84?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- document/Context.md | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 document/Context.md diff --git a/document/Context.md b/document/Context.md new file mode 100644 index 00000000..5b9f0771 --- /dev/null +++ b/document/Context.md @@ -0,0 +1,55 @@ +# 执行上下文与切换机制 + +本文档定义了程序执行上下文(Execution Context)的构成及其在执行流切换(Context Switch)时的操作流程。该机制广泛应用于多任务操作系统中,用于任务调度和资源管理。 + +## 1. 执行上下文(Execution Context)的构成 + +执行上下文是 CPU 恢复一个任务(进程或线程)执行所需的所有状态信息的集合。它主要由以下几个部分组成: + +| 要素 | 核心内容 | 存储位置/管理机制 | 切换需求 | +|----------------|---------------------------------------------|---------------------------------|----------------| +| **CPU 状态** | 包括通用寄存器、程序计数器、标志寄存器等 | 当前任务的内存区域中 | 每次切换时必需 | +| **地址空间** | 虚拟地址与物理地址的映射关系 | 特定的地址映射表 | 进程切换时必需 | +| **系统资源** | 文件描述符、网络连接等资源的引用 | 任务控制块(task control block) | 自动传递 | + +### 解释 +- **CPU 状态**:包括 CPU 寄存器的内容(如程序计数器、栈指针等),这些内容描述了任务在 CPU 执行期间的当前状态。 +- **地址空间**:指任务的内存布局,包括虚拟地址到物理地址的映射。每个任务的地址空间独立,任务切换时需要切换到新任务的地址空间。 +- **系统资源**:包括任务持有的资源,如文件、网络连接等。通常由任务控制块管理,切换时资源状态会自动继承。 + +## 2. 核心数据结构 + +在任务管理过程中,以下数据结构用于存储任务的状态和相关信息: + +| 结构体/寄存器 | 作用 | 存储内容 | 所属模块 | +|------------------|--------------------------------|----------------------------------|-----------------| +| **任务控制块 (task control block)** | 管理任务状态、资源、调度信息 | 存储任务的所有信息,包括系统资源、CPU 状态等 | 任务管理 | +| **内存栈** | 任务的独立执行栈 | 存储上下文信息、局部变量等 | 内存管理 | +| **当前任务指针** | 标识当前执行的任务 | 指向当前任务的任务控制块 | 调度管理 | +| **地址映射信息** | 管理任务的内存映射信息 | 存储任务地址空间的映射信息 | 内存管理 | + +### 解释 +- **任务控制块 (task control block)**:每个任务都有一个独立的控制块,存储任务的所有状态信息和资源管理信息。 +- **内存栈**:任务的执行栈,保存该任务的局部变量和中间计算结果。 +- **当前任务指针**:全局指针,始终指向当前正在执行的任务,确保操作系统知道当前哪个任务在 CPU 上执行。 + +## 3. 执行流切换(Context Switch)的关键操作 + +当操作系统决定切换当前任务(任务 A)到另一个任务(任务 B)时,执行流切换涉及以下几个关键操作: + +| 步骤 | 操作内容 | 触发条件 | 模块职责 | +|------------------|----------------------------------------------------------------------------|--------------------|--------------------| +| **步骤 1**: 保存与恢复状态 | 1. 将任务 A 的 CPU 寄存器和状态保存到任务 A 的内存区域中。
2. 从任务 B 的内存区域恢复 CPU 寄存器和状态。 | 每次任务切换时 | 调度管理/CPU核心 | +| **步骤 2**: 切换地址空间 | 更新任务的内存映射信息,确保任务 B 能访问到其专有的内存空间。 | 进程切换时 | 内存管理 | +| **步骤 3**: 更新当前任务 | 更新当前任务指针,指向任务 B 的控制块,确保调度器知道当前正在执行的是任务 B。 | 每次任务切换时 | 调度管理 | + +### 解释 +- **步骤 1:保存与恢复状态**:保存当前任务的状态(如寄存器的值),然后恢复新任务的状态。这确保了每个任务在执行流切换后能从它离开时的状态继续运行。 +- **步骤 2:切换地址空间**:任务的地址空间必须被切换,以便确保每个任务访问的是它自己的内存区域。通常通过更新地址映射信息来完成这一操作。 +- **步骤 3:更新当前任务**:调度器需要更新当前任务指针,指向新任务的控制块,确保下一次调度时可以恢复正确的任务。 + +--- + +### 总结 + +执行上下文切换是多任务操作系统中的关键机制,它确保操作系统能够在多个任务之间切换,保持各任务的独立性和执行状态。通过管理任务的 CPU 状态、地址空间和系统资源,操作系统能够高效地实现任务调度、资源分配与切换。本流程涉及的关键操作包括保存当前任务的状态、切换内存空间和更新任务指针,确保每个任务的状态能够正确恢复。 From bd313bfef75da96b198673ad0cf7dd602b6321f8 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 05:48:34 +0000 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20=E5=AE=9A=E4=B9=89=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E5=A0=86=E7=9A=84=E5=85=AC=E5=85=B1=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/mm/heap.rs | 81 +++++++++++++++++++++++++++++++++++++++++++++++ os/src/mm/mod.rs | 1 + 2 files changed, 82 insertions(+) create mode 100644 os/src/mm/heap.rs diff --git a/os/src/mm/heap.rs b/os/src/mm/heap.rs new file mode 100644 index 00000000..ccd74c6a --- /dev/null +++ b/os/src/mm/heap.rs @@ -0,0 +1,81 @@ +// 内核堆(Kernel Heap)的公共接口,提供了 C 风格的 kmalloc 家族函数。 + +// 引入在 kalloc.rs 中实现的全局分配器 +// #[global_allocator] +// static ALLOCATOR: ...; +// +// 假设全局分配器 ALLOCATOR 已经被正确设置和初始化。 + +// ------------------------------------------------------------------- +// C 风格的 kmalloc 家族接口 (Wrapper Functions) +// ------------------------------------------------------------------- + +/// kmalloc: 内核动态内存分配函数。 +/// +/// 功能: 分配至少 `size` 字节的内存块。返回的内存是**未初始化**的。 +/// +/// # Arguments +/// * `size`: 需要分配的字节数。 +/// +/// # Safety +/// 这是一个不安全函数,因为分配失败可能返回空指针,且使用者必须负责调用 kfree 释放。 +/// +/// # Returns +/// 分配内存块的指针 (*mut u8);失败则返回 ptr::null_mut()。 +#[inline] +pub unsafe fn kmalloc(_size: usize) -> *mut u8 { + todo!() +} + +/// kcalloc: 内核动态内存分配并清零函数。 +/// +/// 功能: 分配 `count * size` 字节的内存块,并将分配的内存**清零**。 +/// +/// # Arguments +/// * `count`: 元素数量。 +/// * `size`: 每个元素的字节数。 +/// +/// # Safety +/// 必须负责释放。如果乘法溢出或分配失败,返回空指针。 +/// +/// # Returns +/// 分配内存块的指针 (*mut u8);失败则返回 ptr::null_mut()。 +#[inline] +pub unsafe fn kcalloc(_count: usize, _size: usize) -> *mut u8 { + todo!() +} + +/// kfree: 释放之前由 kmalloc/kcalloc/krealloc 分配的内存块。 +/// +/// # Arguments +/// * `ptr`: 待释放的内存块指针。 +/// * `size`: 释放的内存块大小。 +/// +/// # Safety +/// * `ptr` 必须是由本分配器分配的。 +/// * `ptr` 必须是非空且尚未被释放。 +/// * `size` 必须与分配时的 `size` 相同。 +#[inline] +pub unsafe fn kfree(_ptr: *mut u8, _size: usize) { + todo!() +} + +/// krealloc: 重新调整内存块的大小。 +/// +/// 功能: 调整 `old_ptr` 指向的内存块大小为 `new_size`。 +/// +/// # Arguments +/// * `old_ptr`: 原始内存块的指针。 +/// * `old_size`: 原始内存块的大小。 +/// * `new_size`: 新需要的大小。 +/// +/// # Safety +/// * `old_ptr` 必须是本分配器分配的,且未释放。 +/// * `old_size` 必须与分配时的大小相同。 +/// +/// # Returns +/// 新的内存块指针 (*mut u8);失败则返回 ptr::null_mut()。 +#[inline] +pub unsafe fn krealloc(_old_ptr: *mut u8, _old_size: usize, _new_size: usize) -> *mut u8 { + todo!() +} diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index d8aba2b2..b3f80f0f 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -12,6 +12,7 @@ pub mod address; pub mod frame_allocator; +pub mod heap; pub mod global_allocator; pub mod page_table; From 495368cd0072bd31f76ce91d8316692fb473b85f Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 06:14:09 +0000 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20=E4=B8=BA=20Task=20=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=93=E5=A2=9E=E5=8A=A0=20kstack=5Ftracker=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E4=BB=A5=E6=94=AF=E6=8C=81=20RAII=20?= =?UTF-8?q?=E5=86=85=E5=AD=98=E9=87=8A=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/kernel/task.rs | 15 +++++++++------ os/src/mm/frame_allocator/frame_allocator.rs | 1 + os/src/mm/frame_allocator/mod.rs | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/os/src/kernel/task.rs b/os/src/kernel/task.rs index fe943daa..021481f2 100644 --- a/os/src/kernel/task.rs +++ b/os/src/kernel/task.rs @@ -2,7 +2,7 @@ use core::sync::atomic::AtomicPtr; -use crate::arch::{kernel::context::Context, trap::kerneltrap::TrapFrame}; +use crate::{arch::{kernel::context::Context, trap::kerneltrap::TrapFrame}, mm::frame_allocator::FrameTracker}; /// 任务 /// 存放任务的核心信息 @@ -26,14 +26,17 @@ pub struct Task { /// 任务的所属进程id /// NOTE: 由于采用了统一的任务模型,一个任务组内任务的 pid 是相同的,等于父任务的 pid 而父任务的 pid 等于自己的 tid pub pid: usize, + /// 父任务的id + pub ptid: usize, /// 内核栈基址 - kstack_base: usize, + pub kstack_base: usize, + /// 内核栈跟踪器 + pub kstack_tracker: FrameTracker, /// 中断上下文。指向当前任务内核栈上的 TrapFrame,仅在任务被中断时有效。 - trap_frame_ptr: AtomicPtr, - /// 父任务的id - parient_tid: usize, + /// XXX: AtomicPtr or *mut? + pub trap_frame_ptr: AtomicPtr, /// 退出码 - exit_code: isize, + pub exit_code: isize, // TODO: 由于部分相关子系统尚未实现,暂时留空 } diff --git a/os/src/mm/frame_allocator/frame_allocator.rs b/os/src/mm/frame_allocator/frame_allocator.rs index 947d6352..4d875a39 100644 --- a/os/src/mm/frame_allocator/frame_allocator.rs +++ b/os/src/mm/frame_allocator/frame_allocator.rs @@ -5,6 +5,7 @@ use crate::config::PAGE_SIZE; use crate::mm::address::{ConvertablePaddr, Paddr, PageNum, Ppn, PpnRange, UsizeConvert}; use alloc::vec::Vec; +#[derive(Debug)] pub struct FrameTracker(Ppn); impl FrameTracker { diff --git a/os/src/mm/frame_allocator/mod.rs b/os/src/mm/frame_allocator/mod.rs index 8c3737ac..65192070 100644 --- a/os/src/mm/frame_allocator/mod.rs +++ b/os/src/mm/frame_allocator/mod.rs @@ -25,3 +25,5 @@ mod frame_allocator; pub fn init_frame_allocator(start_addr: usize, end_addr: usize) { frame_allocator::init_frame_allocator(start_addr, end_addr); } + +pub use frame_allocator::FrameTracker; \ No newline at end of file From c9d3776e4a4eead28e8273dd60baa5bb98eed98a Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 06:20:05 +0000 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E5=AE=9A=E4=B9=89MemorySpace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/arch/riscv/mm/page_table.rs | 11 ++++++----- os/src/arch/riscv/mm/page_table_entry.rs | 15 +++++++++------ os/src/kernel/task.rs | 5 ++++- os/src/mm/frame_allocator/mod.rs | 2 +- os/src/mm/memory_space/mod.rs | 5 +++++ os/src/mm/mod.rs | 3 ++- os/src/mm/page_table/mod.rs | 1 - 7 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 os/src/mm/memory_space/mod.rs diff --git a/os/src/arch/riscv/mm/page_table.rs b/os/src/arch/riscv/mm/page_table.rs index 447d3a48..f77cbf60 100644 --- a/os/src/arch/riscv/mm/page_table.rs +++ b/os/src/arch/riscv/mm/page_table.rs @@ -1,8 +1,11 @@ use super::PageTableEntry; -use crate::mm::address::{AlignOps, PageNum, Ppn, PpnRange, UsizeConvert, Vaddr, Vpn, VpnRange, Paddr, ConvertablePaddr}; +use crate::mm::address::{ + AlignOps, ConvertablePaddr, Paddr, PageNum, Ppn, PpnRange, UsizeConvert, Vaddr, Vpn, VpnRange, +}; use crate::mm::frame_allocator::FrameTracker; use crate::mm::page_table::{ - PageSize, PageTableInner as PageTableInnerTrait, PagingError, PagingResult, UniversalPTEFlag, PageTableEntry as PageTableEntryTrait + PageSize, PageTableEntry as PageTableEntryTrait, PageTableInner as PageTableInnerTrait, + PagingError, PagingResult, UniversalPTEFlag, }; use alloc::vec::Vec; @@ -158,9 +161,7 @@ impl PageTableInnerTrait for PageTableInner { ) -> PagingResult<()> { // Validate flags: leaf pages must have at least one of R/W/X set if !flags.intersects( - UniversalPTEFlag::Readable - | UniversalPTEFlag::Writeable - | UniversalPTEFlag::Executable, + UniversalPTEFlag::Readable | UniversalPTEFlag::Writeable | UniversalPTEFlag::Executable, ) { return Err(PagingError::InvalidFlags); } diff --git a/os/src/arch/riscv/mm/page_table_entry.rs b/os/src/arch/riscv/mm/page_table_entry.rs index 892e2699..e8876ad0 100644 --- a/os/src/arch/riscv/mm/page_table_entry.rs +++ b/os/src/arch/riscv/mm/page_table_entry.rs @@ -16,8 +16,6 @@ bitflags::bitflags! { } } - - /* * SV39 Page Table Entry (PTE) format: * ------------------------------------------------ @@ -35,7 +33,7 @@ bitflags::bitflags! { */ const SV39_PTE_FLAG_MASK: usize = 0xff; // Lower 8 bits for SV39 PTE flags -const SV39_PTE_PPN_OFFSET: usize = 10; // PPN starts from bit 10 +const SV39_PTE_PPN_OFFSET: usize = 10; // PPN starts from bit 10 const SV39_PTE_PPN_MASK: u64 = 0x000f_ffff_ffff_c00; // Bits 10-53 for PPN impl UniversalConvertableFlag for SV39PTEFlags { @@ -84,8 +82,12 @@ impl PageTableEntryTrait for PageTableEntry { fn is_huge(&self) -> bool { // In SV39, we can't directly determine huge pages from the PTE alone. - let sv39_flags = SV39PTEFlags::from_bits((self.0 & SV39_PTE_FLAG_MASK as u64) as usize).unwrap(); - sv39_flags.intersects(SV39PTEFlags::union(SV39PTEFlags::READ, SV39PTEFlags::EXECUTE).union(SV39PTEFlags::WRITE)) + let sv39_flags = + SV39PTEFlags::from_bits((self.0 & SV39_PTE_FLAG_MASK as u64) as usize).unwrap(); + sv39_flags.intersects( + SV39PTEFlags::union(SV39PTEFlags::READ, SV39PTEFlags::EXECUTE) + .union(SV39PTEFlags::WRITE), + ) } fn is_empty(&self) -> bool { @@ -98,7 +100,8 @@ impl PageTableEntryTrait for PageTableEntry { } fn flags(&self) -> UniversalPTEFlag { - let sv39_flags = SV39PTEFlags::from_bits((self.0 & SV39_PTE_FLAG_MASK as u64) as usize).unwrap(); + let sv39_flags = + SV39PTEFlags::from_bits((self.0 & SV39_PTE_FLAG_MASK as u64) as usize).unwrap(); sv39_flags.to_universal() } diff --git a/os/src/kernel/task.rs b/os/src/kernel/task.rs index 021481f2..a4450bb6 100644 --- a/os/src/kernel/task.rs +++ b/os/src/kernel/task.rs @@ -2,7 +2,10 @@ use core::sync::atomic::AtomicPtr; -use crate::{arch::{kernel::context::Context, trap::kerneltrap::TrapFrame}, mm::frame_allocator::FrameTracker}; +use crate::{ + arch::{kernel::context::Context, trap::kerneltrap::TrapFrame}, + mm::frame_allocator::FrameTracker, +}; /// 任务 /// 存放任务的核心信息 diff --git a/os/src/mm/frame_allocator/mod.rs b/os/src/mm/frame_allocator/mod.rs index 65192070..bc609158 100644 --- a/os/src/mm/frame_allocator/mod.rs +++ b/os/src/mm/frame_allocator/mod.rs @@ -26,4 +26,4 @@ pub fn init_frame_allocator(start_addr: usize, end_addr: usize) { frame_allocator::init_frame_allocator(start_addr, end_addr); } -pub use frame_allocator::FrameTracker; \ No newline at end of file +pub use frame_allocator::FrameTracker; diff --git a/os/src/mm/memory_space/mod.rs b/os/src/mm/memory_space/mod.rs new file mode 100644 index 00000000..a6eaef90 --- /dev/null +++ b/os/src/mm/memory_space/mod.rs @@ -0,0 +1,5 @@ +/// MemorySpace:进程虚拟地址空间管理器。 +/// +/// 封装了进程的页表、所有虚拟内存区域 (VMA) 列表以及相关的同步和统计信息。 +#[derive(Debug)] +pub struct MemorySpace {} diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index b3f80f0f..0146e34d 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -12,8 +12,9 @@ pub mod address; pub mod frame_allocator; -pub mod heap; pub mod global_allocator; +pub mod heap; +pub mod memory_space; pub mod page_table; pub use frame_allocator::init_frame_allocator; diff --git a/os/src/mm/page_table/mod.rs b/os/src/mm/page_table/mod.rs index b8dcc5b4..f7f448c9 100644 --- a/os/src/mm/page_table/mod.rs +++ b/os/src/mm/page_table/mod.rs @@ -31,4 +31,3 @@ pub enum PagingError { } pub type PagingResult = Result; - From 105453b59dc69e18255e2287f5953f4fe6dd8003 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 06:28:24 +0000 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=E4=B8=BAcpu=E5=92=8Ctask=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=99=9A=E6=8B=9F=E5=86=85=E5=AD=98=E7=A9=BA=E9=97=B4?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9B=B8=E5=85=B3=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/kernel/cpu.rs | 9 +++++++-- os/src/kernel/task.rs | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/os/src/kernel/cpu.rs b/os/src/kernel/cpu.rs index aa1fbba9..825a8b73 100644 --- a/os/src/kernel/cpu.rs +++ b/os/src/kernel/cpu.rs @@ -1,4 +1,6 @@ -use crate::{arch::kernel::context::Context, kernel::task::Task}; +use alloc::sync::Arc; + +use crate::{arch::kernel::context::Context, kernel::task::Task, mm::memory_space::MemorySpace}; /// CPU 结构体 pub struct Cpu { @@ -6,7 +8,9 @@ pub struct Cpu { /// 用于在调度器中保存和恢复 CPU 寄存器状态 pub context: Context, /// 当前运行的任务 - pub current_task: Option, + pub current_task: Option>, + /// 当前内存空间 + pub cur_memory_space: Option>, } impl Cpu { @@ -14,6 +18,7 @@ impl Cpu { Cpu { context: Context::zero_init(), current_task: None, + cur_memory_space: None, } } } diff --git a/os/src/kernel/task.rs b/os/src/kernel/task.rs index a4450bb6..fb39cc9f 100644 --- a/os/src/kernel/task.rs +++ b/os/src/kernel/task.rs @@ -2,9 +2,11 @@ use core::sync::atomic::AtomicPtr; +use alloc::sync::Arc; + use crate::{ arch::{kernel::context::Context, trap::kerneltrap::TrapFrame}, - mm::frame_allocator::FrameTracker, + mm::{frame_allocator::FrameTracker, memory_space::MemorySpace}, }; /// 任务 @@ -38,6 +40,9 @@ pub struct Task { /// 中断上下文。指向当前任务内核栈上的 TrapFrame,仅在任务被中断时有效。 /// XXX: AtomicPtr or *mut? pub trap_frame_ptr: AtomicPtr, + /// 任务的内存空间 + /// 对于内核任务,该字段为 None + pub memory_space: Option>, /// 退出码 pub exit_code: isize, // TODO: 由于部分相关子系统尚未实现,暂时留空 From 7b2d12b0a23e715355caf027585a6f961608c8f5 Mon Sep 17 00:00:00 2001 From: miiyakumo Date: Fri, 24 Oct 2025 06:37:42 +0000 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=E5=AE=9A=E4=B9=89=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=86=85=E6=A0=B8=E4=BB=BB=E5=8A=A1=E7=9A=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- os/src/kernel/task.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/os/src/kernel/task.rs b/os/src/kernel/task.rs index fb39cc9f..a3252d34 100644 --- a/os/src/kernel/task.rs +++ b/os/src/kernel/task.rs @@ -61,6 +61,37 @@ pub enum TaskState { Uninterruptable, } +/// 创建一个新的内核线程并返回其 Arc 包装 +/// +/// 该函数负责: +/// 1. 分配 Task 结构体本身,并用 Arc 包装 +/// 2. 分配内核栈物理页帧 (FrameTracker) +/// 3. 将内核栈映射到虚拟地址空间 (VMM 逻辑) +/// 4. 初始化 Task Context,设置栈指针和入口点 +/// 5. 将新的 Task 加入调度器队列 +/// +/// # 参数 +/// * `entry_point`: 线程开始执行的函数地址 +/// +/// # 返回值 +/// 包含新创建任务的 Arc +pub fn kthread_spawn(_entry_point: fn()) -> Arc { + // 1. 分配内核栈 (假设 FrameTracker::alloc_one() 存在) + // let kstack_tracker = FrameTracker::alloc_one().expect("Failed to allocate kernel stack"); + // let kstack_paddr = kstack_tracker.get_paddr(); + + // 2. 将物理页映射到连续的虚拟地址 (kstack_base) + // NOTE: 内核线程共享内核地址空间,映射逻辑相对简单 + + // 3. 构建 Task 实例 + // let task = Task { /* ... 初始化字段 ... */ }; + + // 4. 将任务加入全局任务队列 + // SCHEDULER.add_task(task.clone()); + + unimplemented!("kthread_spawn 核心逻辑尚未实现") +} + // /// 关于任务的管理信息 // /// 存放与调度器、任务状态、队列相关的、需要高频访问和修改的数据。 // /// 主要由调度器子系统使用。