diff --git a/README.md b/README.md index 39daf7c..ba10c71 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,14 @@ Information on the build system, repo structure, features, configuration options ### Complete -- ~~Builds for `aarch64`, `riscv64`, `x86_64`, and `loongarch64`~~ - Valid Limine kernel - Boots on `x86_64` (both UEFI and BIOS) - Kernel command line parameters - initramfs loading - Logging - Serial output +- Page table enumeration +- Processor identification ### In-Progress @@ -61,4 +62,4 @@ Licensed under the MIT License. See [LICENSE](LICENSE) for details. - The linker script stuff is from [limine-rust-template](https://github.com/jasondyoungberg/limine-rust-template), which is available under the BSD 0-Clause License. -- The Gila kernel mascot, Gilbert (prounounced "Hilbert"), was illustrated by LiluTheAlmighty on Tumblr. +- The Gila kernel mascot, Gilbert (prounounced "Hilbert"), was illustrated by @lilu-the-almighty on Tumblr. diff --git a/docs/DESIGN.md b/docs/DESIGN.md index feba886..9763c77 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -68,7 +68,11 @@ will return an error. How the kernel will recognize whether a device is present, is still unknown. Hopefully, a comprehensive enumeration system can be developed which does not -require device definitions to be built into the kernel. +require device definitions to be built into the kernel. I am considering a +system where device driver binaries have "enumerate" entry points in +conjunction with their "main" entry points, and the "enumerate" function +instructs the driver server to search for compatible devices and fork if any +are found. This removes all device-specific code from the kernel. ## Servers vs. Shared Libraries diff --git a/docs/DEVELOPMENT.MD b/docs/DEVELOPMENT.MD index 5732cad..90e4772 100644 --- a/docs/DEVELOPMENT.MD +++ b/docs/DEVELOPMENT.MD @@ -7,38 +7,38 @@ design details can be found in [SECURITY.md](SECURITY.md). ## Navigating -- [kernel/](/src/kernel/): Kernel-specific code. - - [arch/](/src/kernel/arch/): Architecture specific features like the +- [kernel/](../src/kernel/): Kernel-specific code. + - [arch/](../src/kernel/arch/): Architecture specific features like the display, serial, and interrupts. Each architecture is a subfolder, containing a file or module for each feature. - - [boot/](/src/kernel/boot/mod.rs): Handles bootloader-managed data + - [boot/](../src/kernel/boot/mod.rs): Handles bootloader-managed data structures. Gila uses Limine. Other bootloaders are NOT supported. - - [params.rs](/src/kernel/boot/params.rs): Command line parameter parsing. - - [modules.rs](/src/kernel/boot/modules.rs): Kernel module handling. - - [constants.rs](/src/kernel/constants.rs): Constants referenced elsewhere + - [params.rs](../src/kernel/boot/params.rs): Command line parameter parsing. + - [modules.rs](../src/kernel/boot/modules.rs): Kernel module handling. + - [constants.rs](../src/kernel/constants.rs): Constants referenced elsewhere in the kernel. - - [device/](/src/kernel/device/mod.rs): Functions for discovering hardware + - [device/](../src/kernel/device/mod.rs): Functions for discovering hardware and assigning drivers. - - [acpi.rs](/src/kernel/device/acpi.rs): ACPI handling functions and + - [acpi.rs](../src/kernel/device/acpi.rs): ACPI handling functions and structures. - - [log.rs](/src/kernel/log.rs): Logging structures, macros, and singletons + - [log.rs](../src/kernel/log.rs): Logging structures, macros, and singletons for logging to serial or the display. - - [interrupt/](/src/kernel/interrupt/mod.rs): Interrupt handlers with + - [interrupt/](../src/kernel/interrupt/mod.rs): Interrupt handlers with platform-agnostic APIs. - - [main.rs](/src/kernel/main.rs): The entry point that gets called by the + - [main.rs](../src/kernel/main.rs): The entry point that gets called by the bootloader. - - [memory.rs](/src/kernel/memory.rs): Types relating to memory regions and + - [memory.rs](../src/kernel/memory.rs): Types relating to memory regions and allocation. - - [panic.rs](/src/kernel/panic.rs): The panic handler and associated + - [panic.rs](../src/kernel/panic.rs): The panic handler and associated functionality. - - [process.rs](/src/kernel/process.rs): Process types and functions. - - [syscall\_runner.rs](/src/kernel/syscall_runner.rs): Chooses a system call + - [process.rs](../src/kernel/process.rs): Process types and functions. + - [syscall\_runner.rs](../src/kernel/syscall_runner.rs): Chooses a system call by its ID and defers actual syscall execution to code in `src/lib/`. -- [lib/](/src/lib/lib.rs): Library that all Gila's binary programs will be +- [lib/](../src/lib/lib.rs): Library that all Gila's binary programs will be built against. Some of this code is shared with the kernel. - - [arch/](/src/lib/arch/mod.rs): Architecture specific functionality like + - [arch/](../src/lib/arch/mod.rs): Architecture specific functionality like system call register storing/loading. - - [syscall.rs](/src/lib/syscall.rs): System call types common to apps and + - [syscall.rs](../src/lib/syscall.rs): System call types common to apps and the kernel. ## Building and running @@ -59,7 +59,7 @@ install it before you can build an ISO automatically. To do so, you can run - `xorriso` command installed - `qemu-system-{your target architecture}` command installed (for running) -Then run `cargo make` to invoke the [Makefile.toml](Makefile.toml). +Then run `cargo make` to invoke the [Makefile.toml](../Makefile.toml). - `cargo make clean_all`: Cleans all built binaries, libraries, initramfs files, and ISOs. @@ -128,7 +128,7 @@ through BIOS. ## Kernel Parameters Kernel parameters are passed as part of the `cmdline` through -[limine.conf](configs/limine.conf). The parameters are passed as a +[limine.conf](../configs/limine.conf). The parameters are passed as a space-delimited list of keys and values. Keys begin with a hyphen (`-`), and keys are separated from their values with equals signs (`=`). Keys can have a set of multiple values, separated by a comma (`,`). Gila does not currently @@ -151,7 +151,7 @@ The default behavior for each parameter, when not supplied, is: The `.lzma` extension is removed from the default initramfs name when compression is disabled. It must also be changed in -[limine.conf](configs/limine.conf) or else Limine will not load it. +[limine.conf](../configs/limine.conf) or else Limine will not load it. ## Writing Programs for Gila diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 3ad4d8b..8a52d23 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -1,10 +1,20 @@ # Security -Part of the design philosophy that drives my inspiration for Gila is the idea -of creating a new, fast, and safe kernel with security as a central focus. -Kernels such as Linux, Mach, and NT have been around for too long to work -perfectly with today's system security model. Gila is brand-new, and built -almost exclusively in Rust for the utmost memory safety. +## Foreward + +Part of what inspires my design philosophy for Gila is the idea of creating a +new, fast, and safe kernel with security as a central focus. + +Much of today's operating system security discourse comes down to "Sure, you +can harden this, this, and this. But *(insert OS)*'s security model is deeply +flawed." This isn't a dig at any one OS- it applies to all of them. Kernels +such as Linux, Mach, and NT were built long before today's most salient +concepts in computing security were established. Great work is being done on +improving what we already have, but it's counterintuitive to try to establish +a secure system on a flawed foundation. + +Gila aims to start fresh, using modern theories and models, all in a memory +safe language that lends itself well to formal verification. ## Goals @@ -26,19 +36,63 @@ Gila is a microkernel. Only the most important functionality runs at Ring 0 - Scheduling - Memory allocation and management - Inter-process communication -- Hardware communication interfaces +- Minimal IO drivers, only for debugging -User processes perform complex functionality by interacting with server -processes. Servers perform many different things: +Unprivileged user processes perform complex functionality by interacting with +similarly unprivileged server processes via inter-process communication. +Servers can perform many different tasks, such as: - PCI(e) +- ACPI +- AHCI/SATA - USB +- Ethernet +- TCP/IP - Security policy - Filesystems - Logins +- Graphics +- Managing resources + +Servers do one thing each, and one thing well. If a server needs to do a lot of +the same thing, it should fork into several processes, so inter-process +isolation can improve security. For example, if there are multiple of the same +device in the system, the driver server should fork for each instance. This +ensures that any one server can crash or be compromised without crashing or +compromising all the others. + +Another scenario might involve running separate login server processes for +every single user on the system. Running all these servers in one process +introduces a serious security risk, as any compromise or failure of the login +server could result in security failures, resource exhaustion, denial of +service, or other undesirable events, affecting all other users on the system. + +### Namespaces + +Namespaces will be a critical part of how process isolation works. Details are +still TBD, but I want each process to start in its own empty namespace, unless +the parent process specifies that the child should share the parent's +namespace. As device drivers and protocol drivers are simply processes, and +subject to the same namespace rules as any other process, the kernel can +enforce access to any kind of function or resource for any process arbitrarily. +The same could eventually go for virtual machines. + +Namespaces are a way by which the resources available to a process are isolated +and controlled. Mainly, this affects inter-process communication (IPC) as it's +the primary method processes will use to do useful things, but it will also +affect shared memory regions. A process cannot establish IPC unless it is part +of some namespace the target process is also part of. + +Being part of a namespace entails holding a capability object referring to +that namespace, and that capability object will encode rights within that +namespace, such as IPC and shared memory. ### Capability based MAC -Eventually, once Gila is complex enough to need access control, I would like to -implement support for capability-based mandatory access control. Details will -be decided on once more APIs are stabilized. +Namespaces will be enforced using capabilities, where a process holds a +capability object representing the namespace it is in, and the rights it has +within that namespace. By default, processes have no such capabilities, but +a parent process can choose to copy one of its own and delegate it to the +child process. + +Details are still a work in progress. diff --git a/gila_banner.png b/gila_banner.png index cc517fa..c027e51 100644 Binary files a/gila_banner.png and b/gila_banner.png differ diff --git a/src/kernel/arch/x86_64/serial.rs b/src/kernel/arch/x86_64/serial.rs index c0b4605..f071acc 100644 --- a/src/kernel/arch/x86_64/serial.rs +++ b/src/kernel/arch/x86_64/serial.rs @@ -196,7 +196,7 @@ impl SerialPort { port.write_char(0xae as char); // Assert that loopback mode worked - if port.read_char() != (0xae as u8) { + if port.read_char() != (0xae_u8) { return None; } diff --git a/src/lib/syscall/mod.rs b/src/lib/syscall/mod.rs index dbe651f..0a5fc63 100644 --- a/src/lib/syscall/mod.rs +++ b/src/lib/syscall/mod.rs @@ -1,4 +1,3 @@ - use num_derive::FromPrimitive; use num_traits::FromPrimitive; @@ -9,7 +8,7 @@ pub enum Syscall { /// Kill the calling process, and deallocate all /// resources associated, including shared memory channels, /// IPC sessions, handles, etc. - /// Arguments: + /// Arguments: /// 0 - Exit code Exit = 0, /// Get the current PID of the calling process. @@ -51,4 +50,4 @@ impl From for SyscallStatus { pub fn exit(code: u32) -> ! { arch::syscall_impl::caller_syscall_1(Syscall::Exit as u64, code as u64); unreachable!(); -} \ No newline at end of file +}