165 lines
7.3 KiB
Markdown
165 lines
7.3 KiB
Markdown
# Developer Resources
|
|
|
|
## Design Goals & Philosophy
|
|
|
|
General design goals are outlined in [DESIGN.md](DESIGN.md). Security-relevant
|
|
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
|
|
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
|
|
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
|
|
in the kernel.
|
|
- [device/](/src/kernel/device/mod.rs): Functions for discovering hardware
|
|
and assigning drivers.
|
|
-[acpi.rs](/src/kernel/device/acpi.rs): ACPI handling functions and
|
|
structures.
|
|
- [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
|
|
platform-agnostic APIs.
|
|
- [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
|
|
allocation.
|
|
- [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
|
|
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
|
|
built against. Some of this code is shared with the kernel.
|
|
- [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
|
|
the kernel.
|
|
|
|
## Building and running
|
|
|
|
Building a bootable kernel is easy. All you need to do is run
|
|
`cargo build --bin kernel`, and a valid, bootable Limine executable will be
|
|
generated. However, it cannot be booted without installing it in a bootable
|
|
Limine filesystem, and it cannot do anything useful without an initramfs
|
|
containing system servers, such as the init server and device drivers.
|
|
|
|
This project uses [cargo-make](https://github.com/sagiegurari/cargo-make) to
|
|
handle building ISOs and managing files not associated with Cargo. You need to
|
|
install it before you can build an ISO automatically. To do so, you can run
|
|
`cargo install cargo-make`. In addition, you will also need:
|
|
|
|
- `rustup` command installed
|
|
- `limine` command installed
|
|
- `xorriso` command installed
|
|
- `qemu-system-{your target architecture}` command installed (for running)
|
|
|
|
Then run `cargo make` to invoke the [Makefile.toml](Makefile.toml).
|
|
|
|
- `cargo make clean_all`: Cleans all built binaries, libraries, initramfs
|
|
files, and ISOs.
|
|
- `cargo make lib`: Builds `libgila`, the library that the kernel and user
|
|
code are linked against.
|
|
- `cargo make kernel`: Builds the kernel ELF file.
|
|
- `cargo make initramfs`: Build the init archive.
|
|
- `cargo make iso`: Builds the bootable ISO with Limine installed.
|
|
- `cargo make run`: Builds the ISO and boots it in QEMU.
|
|
- `cargo make debug`: Launch the kernel in QEMU with debugging enabled, and
|
|
start and connect GDB.
|
|
|
|
You do not need to clean any files after making changes. The `lib`, `kernel`,
|
|
and `iso` tasks will automatically be rerun if their input files change.
|
|
|
|
### Configuration
|
|
|
|
- Variable `LIMINEDIR`: Location of binary files for limine. Default is
|
|
`/usr/share/limine`.
|
|
- Variable `TARGET`: rustc target triple to compile for. Default is
|
|
`x86_64-unknown-none`. Options are listed [in the targets section](#targets).
|
|
- Argument `-p`: Rust build profile to use. Default is `dev`. Options are
|
|
`dev` and `release`.
|
|
|
|
> [!NOTE]
|
|
> The `-p {profile}` argument must go between `cargo make` and the task
|
|
argument.
|
|
|
|
### Features
|
|
|
|
Gila has four optional features, which I made optional in anticipation of a
|
|
potential future port to older systems which might not support modern
|
|
standards like UEFI or ACPI. They are all enabled by default. Disabling them
|
|
reduces kernel size and forces the kernel to fall back to other
|
|
implementations for some functionality like device discovery.
|
|
|
|
- `acpi`: Advanced Configuration and Power Interface, for device discovery &
|
|
power management
|
|
- `dtb`: Device Tree Blob, for device discovery in embedded systems
|
|
- `compression`: Compressed initramfs archive
|
|
- `uefi`: Universal Extensible Firmware Interface specific bootloader features
|
|
|
|
### Targets
|
|
|
|
Gila ~~currently supports~~ aims to support four different CPU architectures:
|
|
|
|
- `x86_64`
|
|
- `aarch64`
|
|
- `riscv64`
|
|
- `loongarch64`
|
|
|
|
It currently only builds on `x86_64`, and will continue to only support it
|
|
until I can implement support for important features in other architectures.
|
|
|
|
All these architectures are supported by Limine, and the appropriate backends
|
|
are present in the Makefile to compile and build bootable images for each.
|
|
While Limine (the bootloader) and rustc also support `IA32` (also referred to
|
|
as `i686`), the Limine boot protocol cannot work on a 32-bit architecture, as
|
|
it relies heavily on 64-bit pointers. Compilation will fail if a build for an
|
|
unsupported target is attempted.
|
|
|
|
EFI boot is presently supported, at least on `x86_64`. No features depend on
|
|
EFI, and as such, the `uefi` feature can be safely disabled when booting
|
|
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
|
|
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
|
|
support parameter values with spaces. That would require an *actual* parser.
|
|
|
|
List of current extant kernel parameters:
|
|
|
|
- `-loglevel`: Can be a number or string corresponding to a log level. Only
|
|
one value supported. Current options are `Disabled`, `Trace`, `Info`,
|
|
`Warning`, `Error`, and `Critical`. This parameter is case insensitive.
|
|
- `-logdev`: A sequence of one or more values representing devices to log to.
|
|
Current options are `display` and `serial`. This parameter is case
|
|
insensitive.
|
|
- `-initramfs`: A valid path to a module to serve as the initramfs (containing
|
|
the init binary). Only one value supported. This parameter is case sensitive.
|
|
|
|
The default behavior for each parameter, when not supplied, is:
|
|
|
|
`-loglevel=Info -initramfs=/boot/initramfs.tar.lzma`
|
|
|
|
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.
|
|
|
|
## Writing Programs for Gila
|
|
|
|
Gila's system calls will soon be fully defined in `libgila`. The library is
|
|
developed in tandem with, and is used within, the kernel. As Gila does not
|
|
currently support any kind of Rust or C standard library, you must compile
|
|
your programs for the same architecture as Gila itself, bare metal. Userspace
|
|
programs must not use any privileged instructions that would cause an
|
|
exception if running in Ring 3 or any other least-privileged mode of a
|
|
processor.
|