# API Usage Guide This guide provides detailed documentation for the kernel's public APIs. It covers the main modules, their interfaces, and how to use them correctly. ## Table of Contents 1. [Core APIs](#core-apis) 2. [Memory Management APIs](#memory-management-apis) 3. [Task Management APIs](#task-management-apis) 4. [VFS APIs](#vfs-apis) 5. [System Call APIs](#system-call-apis) 6. [Error Handling APIs](#error-handling-apis) 7. [Common Patterns](#common-patterns) --- ## Core APIs ### Kernel State Management #### `kernel::init_kernel()` Initializes the global kernel instance. ```rust use crate::error::KernelResult; pub fn init_kernel() -> KernelResult<()> ``` **Usage:** ```rust if let Err(e) = init_kernel() { panic!("Failed to initialize kernel: {}", e); } ``` **Notes:** - Must be called once during early boot - Panics if called multiple times - Initializes scheduler and idle task #### `kernel::kernel()` Returns a mutable reference to the global kernel instance. ```rust pub fn kernel() -> &'static mut Kernel ``` **Usage:** ```rust let kernel = kernel(); let pmm = kernel.pmm(); let scheduler = kernel.scheduler_mut(); ``` **Safety:** - Only safe to call after `init_kernel()` - Returns a static mutable reference #### `kernel::is_initialized()` Checks if the kernel has been initialized. ```rust pub fn is_initialized() -> bool ``` **Usage:** ```rust if !is_initialized() { init_kernel().expect("Kernel initialization failed"); } ``` --- ## Memory Management APIs ### Physical Memory Manager (PMM) #### `pmm::PhysicalMemoryManager` Manages physical page allocation. ```rust pub struct PhysicalMemoryManager { // Internal state } impl PhysicalMemoryManager { pub fn new() -> Self; /// Allocates a physical page pub fn alloc(&mut self) -> KernelResult; /// Frees a physical page pub fn free(&mut self, addr: PhysicalAddress) -> KernelResult<()> /// Gets available memory statistics pub fn stats(&self) -> MemoryStats; } ``` **Usage:** ```rust let pmm = kernel().pmm_mut(); let page = pmm.alloc()?; // Use page pmm.free(page)?; ``` #### `memory::init::init_memory()` Initializes the memory subsystem. ```rust pub fn init_memory(multiboot_info: usize, allocator: &PmmAllocator) -> KernelResult<()> ``` **Usage:** ```rust memory::init::init_memory(multiboot_info, &ALLOCATOR)?; ``` --- ### Virtual Memory Manager (VMM) #### `vmm::VirtualMemoryManager` Manages virtual memory mappings. ```rust pub struct VirtualMemoryManager { // Internal state } impl VirtualMemoryManager { pub fn new() -> Self; /// Maps a virtual address to physical address pub fn map(&mut self, virt: VirtualAddress, phys: PhysicalAddress) -> KernelResult<()> /// Unmaps a virtual address pub fn unmap(&mut self, virt: VirtualAddress) -> KernelResult<()> /// Handles page faults pub fn handle_page_fault(&mut self, addr: VirtualAddress) -> KernelResult<()> } ``` **Usage:** ```rust let vmm = kernel().vmm_mut().unwrap(); vmm.map(virt_addr, phys_addr)?; ``` --- ## Task Management APIs ### Task Structure #### `task::Task` Represents a task (process/thread). ```rust pub struct Task { pub id: TaskId, pub state: TaskState, pub stack: PhysicalAddress, pub entry_point: VirtualAddress, pub name: String, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum TaskState { New, Ready, Running, Blocked, Zombie, } ``` **Usage:** ```rust let task = Task { id: TaskId::new(), state: TaskState::Ready, stack: stack_addr, entry_point: entry_addr, name: "my_task".to_string(), }; ``` ### Scheduler #### `task::scheduler::Scheduler` Manages task scheduling. ```rust pub struct Scheduler { // Internal state } impl Scheduler { pub fn new() -> Self; /// Initializes the scheduler pub fn init(&mut self); /// Spawns a new task pub fn spawn(&mut self, func: fn(), name: &str) -> KernelResult; /// Runs the scheduler (main loop) pub fn run(&mut self) -> !; /// Yields the current task pub fn yield_task(&mut self); /// Gets current task pub fn current_task(&self) -> Option<&Task>>; } ``` **Usage:** ```rust let scheduler = kernel().scheduler_mut(); scheduler.spawn(my_function, "my_task")?; scheduler.run(); // Never returns ``` ### Task Functions #### `task::spawn()` Convenience function to spawn a task. ```rust pub fn spawn(func: fn(), name: &str) -> KernelResult ``` **Usage:** ```rust task::spawn(my_function, "my_task")?; ``` --- ## VFS APIs ### Inode Interface #### `vfs::inode::Inode` The main interface for file system objects. ```rust pub trait Inode { fn read(&self, offset: u64, buffer: &mut [u8]) -> KernelResult; fn write(&self, offset: u64, buffer: &[u8]) -> KernelResult; fn read_dir(&self, offset: u64) -> KernelResult>; fn create(&self, name: &str, mode: FileMode) -> KernelResult>; fn remove(&self, name: &str) -> KernelResult<()> fn get_attr(&self) -> KernelResult>; fn set_attr(&self, attr: &FileAttr) -> KernelResult<()> } ``` **Usage:** ```rust let inode = get_inode(path)?; let mut buffer = [0u8; 512]; inode.read(0, &mut buffer)?; ``` ### File Operations #### `vfs::file::File` Represents an open file. ```rust pub struct File { inode: InodeId, offset: u64, flags: OpenFlags, } impl File { pub fn read(&mut self, buffer: &mut [u8]) -> KernelResult; pub fn write(&mut self, buffer: &[u8]) -> KernelResult; pub fn seek(&mut self, pos: u64) -> KernelResult<()> pub fn close(&mut self) -> KernelResult<()> pub fn get_attr(&self) -> KernelResult>; } ``` **Usage:** ```rust let mut file = File::open(path, OpenFlags::RDWR)?; let mut buffer = [0u8; 1024]; let bytes_read = file.read(&mut buffer)?; ``` ### Mount Namespace #### `vfs::mount::MountNamespace` Manages mount points. ```rust pub struct MountNamespace { // Internal state } impl MountNamespace { pub fn new() -> Self; /// Mounts a filesystem pub fn mount(&mut self, source: &str, target: &str, fstype: &str, flags: u32) -> KernelResult<()> /// Unmounts a filesystem pub fn unmount(&mut self, target: &str, flags: u32) -> KernelResult<()> /// Gets mount information pub fn get_mount(&self, path: &str) -> Option<&Mount>>; } ``` **Usage:** ```rust let mut mount_ns = MountNamespace::new(); mount_ns.mount("tmpfs", "/tmp", "tmpfs", 0)?; ``` --- ## System Call APIs ### Syscall Numbers #### `syscall::numbers::SyscallNumber` Enum of available system calls. ```rust #[repr(u32)] pub enum SyscallNumber { Exit = 1, Write = 4, Read = 3, Open = 5, Close = 6, GetPid = 20, GetPpid = 39, Fork = 57, Execve = 59, GetUid = 24, GetGid = 47, SetUid = 23, SetGid = 46, } ``` ### Syscall Handler #### `syscall::handler::handle_syscall()` Handles system calls from user mode. ```rust pub fn handle_syscall(num: u32, args: &[usize; 6]) -> SyscallResult ``` **Usage:** ```rust // Called from interrupt handler let result = handle_syscall(syscall_num, &args); ``` ### Available System Calls #### `sys_exit()` Terminates the current task. ```rust pub fn sys_exit(status: i32) -> !; ``` #### `sys_write()` Writes to a file descriptor. ```rust pub fn sys_write(fd: u32, buf: *const u8, count: usize) -> isize; ``` #### `sys_read()` Reads from a file descriptor. ```rust pub fn sys_read(fd: u32, buf: *mut u8, count: usize) -> isize; ``` #### `sys_open()` Opens a file. ```rust pub fn sys_open(path: *const u8, flags: u32) -> u32; ``` --- ## Error Handling APIs ### KernelError #### `error::KernelError` The unified error type for the kernel. ```rust #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum KernelError { // Memory errors OutOfMemory, InvalidAddress, PageFault, // VFS errors NotFound, PermissionDenied, Exists, // Task errors TaskNotFound, TaskAlreadyRunning, InvalidTaskState, // System call errors InvalidSyscall, SyscallNotImplemented, InvalidArgument, // Initialization errors InitFailed(&'static str), DriverFailed(&'static str), // Architecture errors TssInitFailed, GdtInitFailed, IdtInitFailed, // Generic errors NotImplemented, InvalidState, Unknown, } ``` #### `error::KernelResult` Result type alias for kernel operations. ```rust pub type KernelResult = Result; ``` **Usage:** ```rust fn read_file(path: &str) -> KernelResult> { if path.is_empty() { return Err(KernelError::InvalidArgument); } // Implementation Ok(data) } ``` --- ## Common Patterns ### Error Propagation Use the `?` operator for error propagation: ```rust fn complex_operation() -> KernelResult<()> { let pmm = kernel().pmm_mut(); let page = pmm.alloc()?; let vmm = kernel().vmm_mut().unwrap(); vmm.map(virt_addr, page)?; Ok(()) } ``` ### Resource Management Use RAII patterns for resource management: ```rust struct FileHandle { file: File, } impl Drop for FileHandle { fn drop(&mut self) { self.file.close().unwrap_or_else(|e| { serial::write_string(&format!("Failed to close file: {}\n", e)); }); } } ``` ### Initialization Patterns Use the initialization pattern for modules: ```rust pub mod my_module { use crate::error::KernelResult; static INIT: spin::Once> = spin::Once::new(); pub fn init() -> KernelResult<()> { INIT.call_once(|| { // Initialization code Ok(()) }) } pub fn is_initialized() -> bool { INIT.is_completed() } } ``` ### Thread Safety Use spin locks for thread-safe access: ```rust use spin::Mutex; static COUNTER: Mutex = Mutex::new(0); pub fn increment_counter() { let mut counter = COUNTER.lock(); *counter += 1; } ``` --- ## Best Practices for API Usage 1. **Always handle errors** - Never ignore `KernelResult` 2. **Use RAII** - Implement `Drop` for resource cleanup 3. **Document unsafe code** - Use `// SAFETY:` comments 4. **Prefer safe abstractions** - Use safe Rust when possible 5. **Check initialization** - Verify modules are initialized before use 6. **Use appropriate lifetimes** - Avoid unnecessary static references 7. **Validate inputs** - Never trust external data This API guide covers the most commonly used interfaces. For more detailed documentation, refer to the source code comments and module documentation.