Skip to content

Latest commit

 

History

History
123 lines (80 loc) · 6.94 KB

File metadata and controls

123 lines (80 loc) · 6.94 KB

Development Process

Phase One

Main Task

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.

Specific Tasks

  • Remove the standard library dependency to create a freestanding binary.
  • Implement minimal runtime support (e.g., a panic handler) 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 main function.
  • Initialize the kernel stack.
  • Utilize RustSBI services for basic console output and system shutdown.

Main Implementation Content

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 the panic handler 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.

Phase Two

Main Task

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.

Specific Tasks

  • 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.

Main Implementation Content

  • sync: A synchronization submodule, initially providing UPSafeCell for 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.

Phase Three

Main Task

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.

Specific Tasks

  • 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 yield system call.
  • Implement preemptive multitasking using a timer interrupt to enforce fair CPU allocation and improve system responsiveness.

Main Implementation Content

  • 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.

Phase Four

Main Task

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.

Specific Tasks

  • 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.

Main Implementation Content

  • 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.

Phase Five

Main Task

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.

Specific Tasks

  • Create: Implement the fork system call, allowing a process to create a new child process that is a near-identical copy of itself.
  • Exit: Implement the exit system call for a process to terminate its execution. Resources are not fully reclaimed until a parent process cleans them up.
  • Wait: Implement the waitpid system 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 getpid to retrieve process information.
  • Execute: Implement the exec system call to replace the current process's memory space with a new program.

Main Implementation Content

  • 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 support fork (by copying address spaces) and exec (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.

Phase Six

Main Task

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.

Specific Tasks

  • Develop user applications to test file system operations (e.g., cat, write_file).
  • Implement the easy-fs file system as a self-contained crate, handling inodes, data blocks, and directories.
  • Integrate easy-fs into the kernel by adding a virtual file system (VFS) layer and file-related system calls (open, read, write, close).

Main Implementation Content

  • 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 an easy-fs disk image with user applications.
  • task/syscall: Update the kernel's system call and process modules to handle file descriptors and file-based I/O.