Initial userboot support
This commit is contained in:
parent
c6e032d9c9
commit
77355d3f25
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -69,7 +69,7 @@ checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe"
|
||||
|
||||
[[package]]
|
||||
name = "gila"
|
||||
version = "0.3.2"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"acid_alloc",
|
||||
"enumflags2",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "gila"
|
||||
version = "0.3.2"
|
||||
version = "0.4.0"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
|
||||
@ -28,6 +28,10 @@ test = false
|
||||
doctest = false
|
||||
bench = false
|
||||
|
||||
[[bin]]
|
||||
name = "userboot"
|
||||
path = "src/userboot/main.rs"
|
||||
|
||||
[lib]
|
||||
name = "libgila"
|
||||
name = "gila"
|
||||
path = "src/lib/lib.rs"
|
||||
|
||||
@ -84,23 +84,35 @@ args = ["build", "--profile", "${PROFILE}", "--lib"]
|
||||
[tasks.kernel]
|
||||
condition = { files_modified = { input = [
|
||||
"src/kernel/**/*.rs",
|
||||
"src/kernel/**/*.ld",
|
||||
"src/linker_scripts/**/*.ld",
|
||||
"${ARTIFACTDIR}/libgila.rlib"
|
||||
], output = ["${ARTIFACTDIR}/kernel"] }, fail_message = "(inputs unchanged)" }
|
||||
dependencies = ["lib"]
|
||||
command = "cargo"
|
||||
args = ["build", "--profile", "${PROFILE}", "--bin", "kernel"]
|
||||
|
||||
[tasks.userboot]
|
||||
condition = { files_modified = { input = [
|
||||
"src/userboot/**/*.rs",
|
||||
"src/linker_scripts/**/*.ld",
|
||||
"${ARTIFACTDIR}/libgila.rlib"
|
||||
], output = ["${ARTIFACTDIR}/userboot"] }, fail_message = "(inputs unchanged)" }
|
||||
dependencies = ["lib"]
|
||||
command = "cargo"
|
||||
args = ["build", "--profile", "${PROFILE}", "--bin", "userboot"]
|
||||
|
||||
[tasks.iso]
|
||||
condition = { files_modified = { input = [
|
||||
"${ARTIFACTDIR}/kernel",
|
||||
"${ARTIFACTDIR}/userboot",
|
||||
"configs/limine.conf",
|
||||
"resources/wallpaper.png",
|
||||
"${LIMINEDIR}/limine-bios.sys",
|
||||
"${LIMINEDIR}/limine-bios-cd.bin",
|
||||
"${LIMINEDIR}/limine-uefi-cd.bin",
|
||||
"${LIMINEDIR}/${LIMINEBIN}"
|
||||
], output = ["build/gila.iso"] }, fail_message = "(inputs unchanged)" }
|
||||
dependencies = ["kernel"]
|
||||
dependencies = ["kernel", "userboot"]
|
||||
script = '''
|
||||
mkdir -p build/iso/boot/limine
|
||||
mkdir -p build/iso/EFI/BOOT
|
||||
@ -113,7 +125,8 @@ script = '''
|
||||
cp -f ${LIMINEDIR}/limine-uefi-cd.bin build/iso/boot/limine/
|
||||
cp -f ${LIMINEDIR}/${LIMINEBIN} build/iso/EFI/BOOT
|
||||
|
||||
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/gila
|
||||
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/kernel
|
||||
cp -f ${ARTIFACTDIR}/userboot build/iso/boot/${ARCH}/userboot
|
||||
|
||||
xorriso -as mkisofs \
|
||||
-b boot/limine/limine-bios-cd.bin \
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Gila v0.3.1 - a Rust Microkernel
|
||||
# Gila v0.4.0 - a Rust Microkernel
|
||||
|
||||

|
||||

|
||||
|
||||
Gila is a Rust microkernel OS, inspired by microkernel projects such as seL4, Zircon, and Redox. I aim to implement multitasking, userspace drivers, IPC, and sandboxing. I do not aim to make it POSIX-compatible, but it will likely end up sharing many features with POSIX operating systems. Its design philosophy is focused around simplicity, isolation, modularity, and minimal privilege.
|
||||
|
||||
|
||||
4
build.rs
4
build.rs
@ -1,7 +1,7 @@
|
||||
fn main() {
|
||||
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
// Tell cargo to pass the linker script to the linker..
|
||||
println!("cargo:rustc-link-arg=-Tsrc/kernel/arch/{arch}/linker.ld");
|
||||
println!("cargo:rustc-link-arg=-Tsrc/linker_scripts/{arch}/linker.ld");
|
||||
// ..and to re-run if it changes.
|
||||
println!("cargo:rerun-if-changed=src/kernel/arch/{arch}linker.ld");
|
||||
println!("cargo:rerun-if-changed=src/linker_scripts/{arch}linker.ld");
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
[deployment]
|
||||
libgila_version = "0.1.0"
|
||||
arch = "x86_64"
|
||||
# Optional
|
||||
name = "example"
|
||||
version = "0.1.0"
|
||||
@ -1,10 +1,11 @@
|
||||
timeout: 1
|
||||
wallpaper: boot():/bg.png
|
||||
wallpaper: boot():/wallpaper.png
|
||||
wallpaper_style: centered
|
||||
|
||||
/Gila
|
||||
protocol: limine
|
||||
kernel_path: boot():/boot/${ARCH}/gila
|
||||
cmdline: -loglevel=Info -logdev=display,serial -initramfs=/boot/${ARCH}/initramfs.tar.lzma
|
||||
kernel_path: boot():/boot/${ARCH}/kernel
|
||||
cmdline: -loglevel=Trace -logdev=display,serial
|
||||
module_path: boot():/boot/${ARCH}/userboot
|
||||
kaslr: yes
|
||||
randomize_hhdm_base: yes
|
||||
|
||||
@ -7,41 +7,43 @@ design details can be found in [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Navigating
|
||||
|
||||
- [kernel/src/](../kernel/src/): Kernel-specific code.
|
||||
- [arch/](../kernel/src/arch/): Architecture specific features like the
|
||||
- [src/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/](../kernel/src/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](../kernel/src/boot/params.rs): Command line parameter parsing.
|
||||
- [modules.rs](../kernel/src/boot/modules.rs): Kernel module handling.
|
||||
- [constants.rs](../kernel/src/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.
|
||||
- [log.rs](../kernel/src/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/](../kernel/src/interrupt/mod.rs): Interrupt handlers with
|
||||
- [interrupt/](../src/kernel/interrupt/mod.rs): Interrupt handlers with
|
||||
platform-agnostic APIs.
|
||||
- [main.rs](../kernel/src/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](../kernel/src/memory.rs): Types relating to memory regions and
|
||||
- [memory.rs](../src/kernel/memory.rs): Types relating to memory regions and
|
||||
allocation.
|
||||
- [panic.rs](../kernel/src/panic.rs): The panic handler and associated
|
||||
- [panic.rs](../src/kernel/panic.rs): The panic handler and associated
|
||||
functionality.
|
||||
- [process.rs](../kernel/src/process.rs): Process types and functions.
|
||||
- [syscall\_runner.rs](../kernel/src/syscall_runner.rs): Chooses a system call
|
||||
by its ID and defers actual syscall execution to code in `/libgila/src/`.
|
||||
- [libgila/src/](../libgila/src/lib.rs): Shared between the kernel and any
|
||||
- [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/`.
|
||||
- [src/userboot/](../src/userboot/): The first Ring 3 binary to run.
|
||||
- [src/linker_scripts](../src/linker_scripts/): Linker scripts for binaries.
|
||||
- [src/lib/](../src/lib/lib.rs): Shared between the kernel and any
|
||||
binaries built for it. Contains any definitions, structures, and types that will
|
||||
cross the boundary between userspace and kernelspace, including those sent over IPC.
|
||||
- [arch/](../libgila/src/arch/mod.rs): Architecture specific functionality like
|
||||
- [arch/](../src/lib/arch/mod.rs): Architecture specific functionality like
|
||||
system call register storing/loading.
|
||||
- [syscall.rs](../libgila/src/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
|
||||
|
||||
Building a bootable kernel is easy. All you need to do is run
|
||||
`cargo build -p kernel`, and a valid, bootable Limine executable will be
|
||||
`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.
|
||||
@ -72,18 +74,19 @@ If not, the following dependencies will need to be manually installed:
|
||||
|
||||
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 clean_all`: Cleans all built binaries, libraries, and ISO build files.
|
||||
- `cargo make clean_iso`: Cleans the ISO build directory.
|
||||
- `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 userboot`: Build the userspace init binary.
|
||||
- `cargo make iso`: Builds the bootable ISO with Limine installed.
|
||||
- `cargo make run`: Builds the ISO and boots it in QEMU.
|
||||
- `cargo make gui_run`: Same as above, but with QEMU in GUI mode.
|
||||
- `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`,
|
||||
You do not need to clean any files after making changes. The `lib`, `kernel`, `userboot`,
|
||||
and `iso` tasks will automatically be rerun if their input files change.
|
||||
|
||||
### Configuration
|
||||
@ -139,16 +142,10 @@ one value supported. Current options are `Disabled`, `Trace`, `Info`,
|
||||
- `-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.
|
||||
`-loglevel=Info`
|
||||
|
||||
## Writing Programs for Gila
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "libgila"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
num-derive = { version = "0.4.2", default-features = false }
|
||||
num-traits = { version = "0.2.19", default-features = false }
|
||||
|
||||
[lib]
|
||||
# Stop appending lib to artifact names!!! it's already a library!!!
|
||||
name = "gila"
|
||||
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 320 KiB |
@ -41,8 +41,7 @@ use crate::{
|
||||
gdt::dump_gdt,
|
||||
interrupts::get_lapic_addr,
|
||||
},
|
||||
},
|
||||
memory::paging::{self, active_root_table, map_page, phys_to_virt},
|
||||
}, boot::modules::MODULE_RESPONSE, memory::paging::{self, active_root_table, map_page, phys_to_virt},
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
@ -204,5 +203,12 @@ unsafe extern "C" fn main() -> ! {
|
||||
let res = map_page(phys_to_virt(lapic), mapping);
|
||||
log_info!("Map status: {:?}", res);
|
||||
|
||||
if let Some(modules_list) = *MODULE_RESPONSE {
|
||||
if modules_list.modules()[0].path().ends_with("/userboot") {
|
||||
log_info!("Found userboot: {} {}", modules_list.modules()[0].path(), modules_list.modules()[0].cmdline());
|
||||
log_info!("Start address: 0x{:x}", modules_list.modules()[0].data().as_ptr() as usize);
|
||||
}
|
||||
}
|
||||
|
||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||
}
|
||||
|
||||
14
src/userboot/main.rs
Normal file
14
src/userboot/main.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn main() -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
pub fn panic(info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user