The primary goal is to abstract the hardware from applications, thereby simplifying hardware access. In this model, the OS acts as a library, providing a clean interface for applications to interact with the underlying hardware.
- Remove the standard library dependency to create a freestanding binary.
- Implement minimal runtime support (e.g., a
panichandler) to allow the code to compile without a host OS. - The result is a bare-metal program that compiles but has no I/O capabilities, establishing the foundation for kernel development.
- Implement an assembly entry point to set up the initial environment and transfer control to the Rust
mainfunction. - Initialize the kernel stack.
- Utilize RustSBI services for basic console output and system shutdown.
A single kernel was implemented, consisting of the following source code:
console.rs: Encapsulates the raw SBI character printing interface to provide formatted output capabilities (e.g.,println!).entry.asm: The assembly entry point responsible for setting up the initial kernel stack and execution environment.lang_items.rs: Provides language items required by the Rust compiler, such as thepanichandler for freestanding environments.linker-qemu.ld: A linker script that defines the kernel's memory layout for the QEMU target.main.rs: The kernel's main function.sbi.rs: Provides a safe wrapper around the Supervisor Binary Interface (SBI) calls.
Implement a batch processing system capable of running multiple applications sequentially. The kernel loads and executes one application, and upon its completion, automatically loads and runs the next one.
- Bundle the kernel and multiple user applications into a single executable image.
- Implement a loader to run applications one after another from the bundled image.
- Utilize hardware privilege levels (Supervisor vs. User mode) to protect the kernel from user applications.
- Implement the mechanisms for transitioning between user mode and supervisor mode (traps).
- Introduce a system call interface to allow user applications to request services from the kernel.
sync: A synchronization submodule, initially providingUPSafeCellfor safe interior mutability on a uniprocessor system.syscall: The system call handling module.trap: The trap handling module, responsible for managing exceptions, interrupts, and system calls.usr: The user-space library and applications.
Implement a multiprogramming and time-sharing system. This allows multiple applications to reside in memory concurrently. The kernel manages processor time, switching between applications to give the illusion of simultaneous execution on a single CPU core.
- Pre-load all applications into memory at boot time to minimize context switching overhead.
- Implement cooperative multitasking, allowing applications to voluntarily yield the CPU via a
yieldsystem call. - Implement preemptive multitasking using a timer interrupt to enforce fair CPU allocation and improve system responsiveness.
task: The task management submodule, responsible for creating and scheduling tasks.timer.rs: Manages timer interrupts for preemptive scheduling.build.py: A build script to ensure that applications are loaded into non-overlapping physical memory regions.
Introduce virtual memory to provide each application with its own isolated address space. This is achieved through page-based memory management. Each application sees a large, contiguous address space starting from zero, while the kernel ensures it is securely mapped to non-contiguous physical memory, providing isolation between applications and the kernel.
- Support dynamic memory allocation for applications.
- Use page tables to map an application's virtual address space, simplifying the linking process and memory layout.
- Leverage page tables to enforce strict memory isolation between applications, and between applications and the kernel, enhancing overall system security.
mm: The memory management submodule, implementing page tables, frame allocators, and address space management.task: Update the task module to associate each task with its own memory space (MemorySet).trap: Update the trap handler to manage page faults and switch page tables during context switches.
Evolve the task abstraction into a full-fledged process model. This enables dynamic process management from user space through a set of powerful system calls, allowing for more complex application behavior.
- Create: Implement the
forksystem call, allowing a process to create a new child process that is a near-identical copy of itself. - Exit: Implement the
exitsystem call for a process to terminate its execution. Resources are not fully reclaimed until a parent process cleans them up. - Wait: Implement the
waitpidsystem call, allowing a parent process to wait for a child's termination, collect its exit code, and release its remaining resources. - Info: Implement system calls like
getpidto retrieve process information. - Execute: Implement the
execsystem call to replace the current process's memory space with a new program.
task: Refactor the task module to support the process model, including parent-child relationships and process lifecycle states (Running, Ready, Zombie).mm: Enhance the memory management module to supportfork(by copying address spaces) andexec(by creating new address spaces from an ELF file).syscall: Implement the new process-related system calls (fork,exec,waitpid, etc.).usr: Add new user programs to test the process management features.
Implement a simple, disk-based file system, named easy-fs, to manage persistent storage. The kernel will support standard file operations on regular files and directories, which are organized on a block device.
- Develop user applications to test file system operations (e.g.,
cat,write_file). - Implement the
easy-fsfile system as a self-contained crate, handling inodes, data blocks, and directories. - Integrate
easy-fsinto the kernel by adding a virtual file system (VFS) layer and file-related system calls (open,read,write,close).
easy-fs: A standalone crate implementing a simple, inode-based file system.easy-fs-fuse: A host-side tool using FUSE to create and pack aneasy-fsdisk image with user applications.task/syscall: Update the kernel's system call and process modules to handle file descriptors and file-based I/O.