跳转到内容

模块结构

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 创建工具
┌─────────────────────────────────────────────────────────────┐
│ main.rs │
│ (内核入口点) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ arch/ │ │drivers/ │ │ memory/ │
│ x86_64 │ │ │ │ │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└────────┬────────┴────────┬────────┘
▼ ▼
┌─────────┐ ┌─────────┐
│ task/ │ │ ipc/ │
│ │ │ │
└────┬────┘ └────┬────┘
│ │
└────────┬────────┘
┌─────────┐
│syscall/ │
│ │
└─────────┘
kernel/src/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();
}
}
arch/x86_64/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(双重故障栈)
// 加载段选择子
}
arch/x86_64/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());
}
}
drivers/vga.rs
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],
}
drivers/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)*));
};
}
memory/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);
}
}
task/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,
}
task/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
}
}
syscall/mod.rs
/// 系统调用号
#[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
}
}
ipc/mod.rs
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());
}
}
[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/src/arch/x86_64/linker.ld
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.*)
}
}
  1. 创建新的目录和文件:

    Terminal window
    mkdir kernel/src/new_module
    touch kernel/src/new_module/mod.rs
  2. mod.rs 中定义模块:

    kernel/src/new_module/mod.rs
    pub fn init() {
    // 初始化代码
    }
  3. main.rs 中添加模块声明:

    pub mod new_module;
  4. 在启动序列中调用初始化:

    new_module::init();