模块结构
openos/├── Cargo.toml # 工作区根 + 磁盘镜像构建器├── src/main.rs # 磁盘镜像构建器 (bootloader::BiosBoot)├── kernel/│ ├── Cargo.toml # 内核 crate│ └── src/│ ├── main.rs # 内核入口,panic 处理│ ├── elf.rs # ELF64 解析器和加载器│ ├── initrd.rs # Initrd 归档解析器│ ├── frame_alloc.rs # Bump 帧分配器│ ├── handle.rs # Handle 实现│ ├── arch/ # 架构特定代码│ │ └── x86_64/│ │ ├── mod.rs # 架构初始化编排器│ │ ├── gdt.rs # GDT + TSS│ │ ├── interrupts.rs # IDT, PIC, 中断处理│ │ ├── syscall.rs # SYSCALL/SYSRET│ │ └── linker.ld # 链接脚本│ ├── drivers/ # 设备驱动│ │ ├── vga.rs # VGA 帧缓冲文本渲染│ │ └── serial.rs # UART 16550 串口驱动│ ├── memory/ # 内存管理│ │ └── allocator.rs # 堆分配器│ ├── task/ # 任务管理│ │ ├── task.rs # 任务控制块│ │ └── scheduler.rs # 调度器│ ├── syscall/ # 系统调用│ │ └── mod.rs # 系统调用分发器│ ├── ipc/ # 进程间通信│ │ └── mod.rs # IPC 消息传递│ └── fs/ # 文件系统│ └── mod.rs # VFS 占位符├── sdk/ # 用户态 SDK├── user/ # 用户态程序│ └── hello.asm # 示例用户程序└── tools/ # 工具 └── mkinitrd.py # Initrd 创建工具模块依赖关系
Section titled “模块依赖关系”┌─────────────────────────────────────────────────────────────┐│ main.rs ││ (内核入口点) │└─────────────────────────────────────────────────────────────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ arch/ │ │drivers/ │ │ memory/ │ │ x86_64 │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └────────┬────────┴────────┬────────┘ ▼ ▼ ┌─────────┐ ┌─────────┐ │ task/ │ │ ipc/ │ │ │ │ │ └────┬────┘ └────┬────┘ │ │ └────────┬────────┘ ▼ ┌─────────┐ │syscall/ │ │ │ └─────────┘核心模块详解
Section titled “核心模块详解”1. main.rs - 内核入口
Section titled “1. main.rs - 内核入口”#![no_std]#![no_main]#![warn(missing_docs)]#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
use core::panic::PanicInfo;
/// 内核入口点#[no_mangle]pub extern "C" fn _start() -> ! { // 初始化顺序很重要! drivers::vga::init(); // 1. VGA 输出 drivers::serial::init(); // 2. 串口输出 arch::x86_64::gdt::init(); // 3. GDT + TSS arch::x86_64::interrupts::init(); // 4. IDT + PIC memory::allocator::init_heap(); // 5. 堆分配器 syscall::init(); // 6. 系统调用 ipc::init(); // 7. IPC 子系统 task::scheduler::init(); // 8. 任务调度器
// 进入空闲循环 loop { x86_64::instructions::hlt(); }}
/// Panic 处理函数#[panic_handler]fn panic(info: &PanicInfo) -> ! { println!("[PANIC] {}", info); serial_println!("[PANIC] {}", info); loop { x86_64::instructions::hlt(); }}2. arch/x86_64 - 架构层
Section titled “2. arch/x86_64 - 架构层”gdt.rs - 全局描述符表
Section titled “gdt.rs - 全局描述符表”use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor};use x86_64::structures::tss::TaskStateSegment;
/// GDT 布局/// Index 0: 空描述符/// Index 1: 内核代码 (0x08)/// Index 2: 内核数据 (0x10)/// Index 3: 用户数据 (0x18)/// Index 4: 用户代码 (0x20)/// Index 5-6: TSS
pub fn init() { // 初始化 GDT // 设置 TSS(双重故障栈) // 加载段选择子}interrupts.rs - 中断处理
Section titled “interrupts.rs - 中断处理”use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
/// 异常处理函数extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame);}
extern "x86-interrupt" fn double_fault_handler( stack_frame: InterruptStackFrame, _error_code: u64,) -> ! { panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);}
/// IRQ 处理函数extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) { // 定时器中断处理 unsafe { PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8()); }}3. drivers - 设备驱动
Section titled “3. drivers - 设备驱动”vga.rs - VGA 帧缓冲
Section titled “vga.rs - VGA 帧缓冲”use volatile::Volatile;
/// VGA 颜色#[allow(dead_code)]#[derive(Debug, Clone, Copy, PartialEq, Eq)]#[repr(u8)]pub enum Color { Black = 0, Blue = 1, Green = 2, Cyan = 3, Red = 4, Magenta = 5, Brown = 6, LightGray = 7, DarkGray = 8, LightBlue = 9, LightGreen = 10, LightCyan = 11, LightRed = 12, Pink = 13, Yellow = 14, White = 15,}
/// VGA 字符#[derive(Debug, Clone, Copy, PartialEq, Eq)]#[repr(C)]struct ScreenChar { ascii_character: u8, color_code: ColorCode,}
/// VGA 缓冲区const BUFFER_HEIGHT: usize = 25;const BUFFER_WIDTH: usize = 80;
#[repr(transparent)]struct Buffer { chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],}serial.rs - 串口驱动
Section titled “serial.rs - 串口驱动”use uart_16550::SerialPort;use spin::Mutex;
/// COM1 串口static SERIAL1: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
/// 初始化串口pub fn init() { SERIAL1.lock().init();}
/// 串口打印宏#[macro_export]macro_rules! serial_print { ($($arg:tt)*) => { $crate::drivers::serial::_print(format_args!($($arg)*)); };}4. memory - 内存管理
Section titled “4. memory - 内存管理”allocator.rs - 堆分配器
Section titled “allocator.rs - 堆分配器”use linked_list_allocator::LockedHeap;use x86_64::VirtAddr;
/// 堆起始地址pub const HEAP_START: VirtAddr = VirtAddr::new(0x4444_4444_0000);
/// 堆大小 (100 KiB)pub const HEAP_SIZE: usize = 100 * 1024;
/// 全局分配器#[global_allocator]static ALLOCATOR: LockedHeap = LockedHeap::empty();
/// 初始化堆pub fn init_heap() { unsafe { ALLOCATOR.lock().init(HEAP_START.as_mut_ptr(), HEAP_SIZE); }}5. task - 任务管理
Section titled “5. task - 任务管理”task.rs - 任务控制块
Section titled “task.rs - 任务控制块”use alloc::string::String;use core::sync::atomic::{AtomicU64, Ordering};
/// 任务 ID#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]pub struct TaskId(u64);
impl TaskId { pub fn new() -> Self { static NEXT_ID: AtomicU64 = AtomicU64::new(0); TaskId(NEXT_ID.fetch_add(1, Ordering::Relaxed)) }}
/// 任务状态#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum TaskState { Ready, Running, Blocked, Terminated,}
/// 任务控制块pub struct Task { pub id: TaskId, pub name: String, pub state: TaskState, pub priority: u8,}scheduler.rs - 调度器
Section titled “scheduler.rs - 调度器”use alloc::collections::VecDeque;use spin::Mutex;
/// 调度器pub struct Scheduler { ready_queue: VecDeque<TaskId>, current_task: Option<TaskId>,}
impl Scheduler { pub fn new() -> Self { Scheduler { ready_queue: VecDeque::new(), current_task: None, } }
pub fn add_task(&mut self, task_id: TaskId) { self.ready_queue.push_back(task_id); }
pub fn schedule(&mut self) -> Option<TaskId> { // 轮询调度 let next = self.ready_queue.pop_front(); if let Some(id) = next { self.ready_queue.push_back(id); } self.current_task = next; next }}6. syscall - 系统调用
Section titled “6. syscall - 系统调用”/// 系统调用号#[derive(Debug, Clone, Copy, PartialEq, Eq)]#[repr(u64)]pub enum SyscallNumber { Write = 1, Read = 2, Exit = 3, Yield = 4, PortCreate = 5, Send = 6, Receive = 7,}
/// 系统调用处理函数pub fn handle_syscall( number: u64, arg1: u64, arg2: u64, arg3: u64,) -> i64 { match number { 1 => sys_write(arg1, arg2), 2 => sys_read(arg1, arg2), 3 => sys_exit(arg1), 4 => sys_yield(), _ => -1, // ENOSYS }}7. ipc - 进程间通信
Section titled “7. ipc - 进程间通信”use alloc::collections::BTreeMap;use alloc::vec::Vec;use spin::Mutex;
/// 消息类型#[derive(Debug, Clone)]pub enum MessageData { Text(alloc::string::String), Bytes(Vec<u8>), Request { id: u64, data: Vec<u8> }, Response { id: u64, data: Vec<u8> },}
/// 消息#[derive(Debug, Clone)]pub struct Message { pub sender: u64, pub receiver: u64, pub data: MessageData,}
/// 端口pub struct Port { pub id: u64, pub inbox: VecDeque<Message>,}
/// IPC 管理器pub struct IpcManager { ports: BTreeMap<u64, Port>,}模块间通过函数调用通信:
// 在 syscall 模块中调用 ipc 模块fn sys_send(port_id: u64, msg: *const u8, len: u64) -> i64 { let message = unsafe { core::slice::from_raw_parts(msg, len as usize) }; ipc::send(port_id, message)}使用 spin::Mutex 保护的全局状态:
// 全局调度器static SCHEDULER: Mutex<Scheduler> = Mutex::new(Scheduler::new());
// 全局 IPC 管理器static IPC_MANAGER: Mutex<IpcManager> = Mutex::new(IpcManager::new());中断处理函数通过 EOI 通知 PIC:
extern "x86-interrupt" fn timer_handler(_stack_frame: InterruptStackFrame) { // 处理定时器中断 // ...
// 发送 EOI unsafe { PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8()); }}Cargo.toml 配置
Section titled “Cargo.toml 配置”[package]name = "openos-kernel"version = "0.2.0"edition = "2021"
[dependencies]bootloader_api = "0.11"x86_64 = "0.15"pic8259 = "0.11"uart_16550 = "0.3"spin = "0.9"linked_list_allocator = "0.10"KERNEL_OFFSET = 0xFFFFFFFF80000000
ENTRY(_start)
SECTIONS { . = KERNEL_OFFSET + 0x100000;
.text : AT(ADDR(.text) - KERNEL_OFFSET) { *(.text .text.*) }
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { *(.rodata .rodata.*) }
.data : AT(ADDR(.data) - KERNEL_OFFSET) { *(.data .data.*) }
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) { *(.bss .bss.*) }}-
创建新的目录和文件:
Terminal window mkdir kernel/src/new_moduletouch kernel/src/new_module/mod.rs -
在
mod.rs中定义模块:kernel/src/new_module/mod.rs pub fn init() {// 初始化代码} -
在
main.rs中添加模块声明:pub mod new_module; -
在启动序列中调用初始化:
new_module::init();