A hobby x86_64 Operating System kernel written in Rust -- with minimal functionalities like preemptive and cooperative multi-tasking, usermode, framebuffer terminal, basic device drivers like -- ATA-PIO (for Disk I/O), PS/2 Keyboard, Serial UART, RTL8139 networking (in progress), file-system built with VFS that supports devfs and ustar, last but not the least - supports somewhat POSIXish basic system calls.
The name r3
stands for Revision 3
because this is my third attempt to build a hobby Operating System kernel. The kernel barely works on QEMU as of now and some of the functionalities are not optimal or not perfectly implemented. This is an attempt to keep myself occupied, I am not competing with Linux or other rusty operating systems here on GitHub - in fact I got inspired from these operating systems and read their code-bases to understand various possible methods. (I have given credits to some of the rust OS repositories I looked at.)
- Basic x86 Interrupts - both exceptions and hardware interrupts.
- Programmable I/O
- Descriptor tables like GDT, IDT and TSS
- Legacy Programmable Interrupt Controller - (PIC) used for handling interrupts initially
- Legacy Programmable Interval Timer - (PIT) used for initial CPU frequency detection
- CPUID - CPU features identification
- Timestamp Counter (TSC) which is used as the core system timer for events generation
- Linear Physical Memory Manager - Right not it only allocates, never deallocates (LoL this is the biggest drawback as of now, anyways I am planning to write a slab allocator soon)
- DMA Manager - Allocates DMA memory regions for drivers like RTL8139
- Virtual Memory Manager and Paging - Allocate and manage both 4KB pages and 2MB huge-pages.
- Heap Allocator built on top of VMA, this heap allocator is used by rust to manage it's dynamic structures -- uses a linked list allocator underneath.
- Higher half kernel
- ACPI and ACPI x2 support
- Local APIC Interrupts support
- Symmetric Multi-Processing (SMP) - still in very initial stages (in progress)
- Peripheral Component Interconnect - legacy mode with Configuration Registers
- PS/2 Keyboard Driver
- UART serial interface driver
- ATA Disk controller - using PIO mode, where data-transfers take CPU cycles. (DMA mode is in planning stage yet)
- Framebuffer display
- Random Numbers generator
- TTY interface using PS/2 and Framebuffer together
- VFS - Virtual File System implementation (Supports only crucial functionalities as of now)
- Devfs - to manage devices as files (good old UNIX concept - everything is a file)
- USTAR - A simple TAR file-system with read-only capabilities
- System timer and ticks built on top of TSC and LAPIC interrupts
- Multi-processing - ability to run multiple-processes concurrently (not parallely as of now)
- Multi-threading - Still in early stages, as of now, a process can have only one thread
- Software based context switching - ability to save and restore thread states
- Mode switching - From kernel-mode to user-mode and vice-versa
- Non-blocking I/O - for keyboard as of now (will implement the same for networking and disk I/O soon)
- Sysv64 ABI for making System calls
- System calls interface - uses legacy/portable
int 0x80
software based mechanism. - Basic system calls like -
read
,write
,open
,close
,exit
,fstat
,lstat
,lseek
,getpid
,getppid
,fork
,brk
,sbrk
,ioctl
,yield
,gettid
,sleep
,wait
,shutdown
,reboot
,execvp
,uname
,getrandom
,gettime
are implemented, these implementations barely work and are not perfectly POSIX. - Ability to load ELF files from the file-system and execute them as a process - by following the ELF process layout.
- Basic networking - (Still in initial stages of development, as of now you can see a half-baked RTL8139 driver implementation)
- Internal kernel logging via serial port used for debugging
The userland as of now is just a simple program that reads and writes whatever it read to TTY. More features are coming to userland once I finish pending kernel stuff. I have plans to port some C libraries like newlib and write a simple system-calls wrapper in Rust.
In fact, the documentation is yet to be written on how to port libraries on-top this kernel's system-calls (because I am not clear yet about what works and what might not work haha)
- Rust Bootloader - Initial bootloader
- Rust logger - for internal logging on top of UART
- spin - For
Mutex
locks - lazy_static - For runtime lazy initialization of static data
- bit_field - For basic bit level operations
- bitflags - For enum-like abstractions over primitive data-types.
- object - For parsing raw and ELF binaries
- pc-keyboard - For parsing and decoding raw key-events
- rand_xoshiro - Rust implementation of Non-cryptographic randmon number generation algorithm called xoshiro128+
- linked_list_allocator - Heap memory management using linked-list data-structure on-top of raw memory region
- Install all the presequites - QEMU, KVM, rust, cargo, xbuild and OVMF
./tools/setup_env.sh
- Build the userspace tarfs (requires GCC)
./tools/build_tarfs.sh
- Build and run the Kernel:
# with the tar-file mounted
./tools/run_qemu_disk.sh
# without tar-file mounted (will crash anyways lol)
./tools/run_qemu.sh
The emulator will generate a serial.out
file to dump all the logs, also QEMU's debug panel will be launched just after starting the boot.
Credis to the awesome rust-osdev series by Philipp Oppermann and OSDev community.
ECHO client user-program running on QEMU (more to come)
Any contributions in the form of code, issues, discussions are welcome!