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]]
|
[[package]]
|
||||||
name = "gila"
|
name = "gila"
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"acid_alloc",
|
"acid_alloc",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gila"
|
name = "gila"
|
||||||
version = "0.3.2"
|
version = "0.4.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
@ -28,6 +28,10 @@ test = false
|
|||||||
doctest = false
|
doctest = false
|
||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "userboot"
|
||||||
|
path = "src/userboot/main.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "libgila"
|
name = "gila"
|
||||||
path = "src/lib/lib.rs"
|
path = "src/lib/lib.rs"
|
||||||
|
|||||||
@ -84,23 +84,35 @@ args = ["build", "--profile", "${PROFILE}", "--lib"]
|
|||||||
[tasks.kernel]
|
[tasks.kernel]
|
||||||
condition = { files_modified = { input = [
|
condition = { files_modified = { input = [
|
||||||
"src/kernel/**/*.rs",
|
"src/kernel/**/*.rs",
|
||||||
"src/kernel/**/*.ld",
|
"src/linker_scripts/**/*.ld",
|
||||||
"${ARTIFACTDIR}/libgila.rlib"
|
"${ARTIFACTDIR}/libgila.rlib"
|
||||||
], output = ["${ARTIFACTDIR}/kernel"] }, fail_message = "(inputs unchanged)" }
|
], output = ["${ARTIFACTDIR}/kernel"] }, fail_message = "(inputs unchanged)" }
|
||||||
dependencies = ["lib"]
|
dependencies = ["lib"]
|
||||||
command = "cargo"
|
command = "cargo"
|
||||||
args = ["build", "--profile", "${PROFILE}", "--bin", "kernel"]
|
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]
|
[tasks.iso]
|
||||||
condition = { files_modified = { input = [
|
condition = { files_modified = { input = [
|
||||||
"${ARTIFACTDIR}/kernel",
|
"${ARTIFACTDIR}/kernel",
|
||||||
|
"${ARTIFACTDIR}/userboot",
|
||||||
"configs/limine.conf",
|
"configs/limine.conf",
|
||||||
|
"resources/wallpaper.png",
|
||||||
"${LIMINEDIR}/limine-bios.sys",
|
"${LIMINEDIR}/limine-bios.sys",
|
||||||
"${LIMINEDIR}/limine-bios-cd.bin",
|
"${LIMINEDIR}/limine-bios-cd.bin",
|
||||||
"${LIMINEDIR}/limine-uefi-cd.bin",
|
"${LIMINEDIR}/limine-uefi-cd.bin",
|
||||||
"${LIMINEDIR}/${LIMINEBIN}"
|
"${LIMINEDIR}/${LIMINEBIN}"
|
||||||
], output = ["build/gila.iso"] }, fail_message = "(inputs unchanged)" }
|
], output = ["build/gila.iso"] }, fail_message = "(inputs unchanged)" }
|
||||||
dependencies = ["kernel"]
|
dependencies = ["kernel", "userboot"]
|
||||||
script = '''
|
script = '''
|
||||||
mkdir -p build/iso/boot/limine
|
mkdir -p build/iso/boot/limine
|
||||||
mkdir -p build/iso/EFI/BOOT
|
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}/limine-uefi-cd.bin build/iso/boot/limine/
|
||||||
cp -f ${LIMINEDIR}/${LIMINEBIN} build/iso/EFI/BOOT
|
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 \
|
xorriso -as mkisofs \
|
||||||
-b boot/limine/limine-bios-cd.bin \
|
-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.
|
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() {
|
fn main() {
|
||||||
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||||
// Tell cargo to pass the linker script to the linker..
|
// 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.
|
// ..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
|
timeout: 1
|
||||||
wallpaper: boot():/bg.png
|
wallpaper: boot():/wallpaper.png
|
||||||
wallpaper_style: centered
|
wallpaper_style: centered
|
||||||
|
|
||||||
/Gila
|
/Gila
|
||||||
protocol: limine
|
protocol: limine
|
||||||
kernel_path: boot():/boot/${ARCH}/gila
|
kernel_path: boot():/boot/${ARCH}/kernel
|
||||||
cmdline: -loglevel=Info -logdev=display,serial -initramfs=/boot/${ARCH}/initramfs.tar.lzma
|
cmdline: -loglevel=Trace -logdev=display,serial
|
||||||
|
module_path: boot():/boot/${ARCH}/userboot
|
||||||
kaslr: yes
|
kaslr: yes
|
||||||
randomize_hhdm_base: yes
|
randomize_hhdm_base: yes
|
||||||
|
|||||||
@ -7,41 +7,43 @@ design details can be found in [SECURITY.md](SECURITY.md).
|
|||||||
|
|
||||||
## Navigating
|
## Navigating
|
||||||
|
|
||||||
- [kernel/src/](../kernel/src/): Kernel-specific code.
|
- [src/kernel/](../src/kernel/): Kernel-specific code.
|
||||||
- [arch/](../kernel/src/arch/): Architecture specific features like the
|
- [arch/](../src/kernel/arch/): Architecture specific features like the
|
||||||
display, serial, and interrupts. Each architecture is a subfolder,
|
display, serial, and interrupts. Each architecture is a subfolder,
|
||||||
containing a file or module for each feature.
|
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.
|
structures. Gila uses Limine. Other bootloaders are NOT supported.
|
||||||
- [params.rs](../kernel/src/boot/params.rs): Command line parameter parsing.
|
- [params.rs](../src/kernel/boot/params.rs): Command line parameter parsing.
|
||||||
- [modules.rs](../kernel/src/boot/modules.rs): Kernel module handling.
|
- [modules.rs](../src/kernel/boot/modules.rs): Kernel module handling.
|
||||||
- [constants.rs](../kernel/src/constants.rs): Constants referenced elsewhere
|
- [constants.rs](../src/kernel/constants.rs): Constants referenced elsewhere
|
||||||
in the kernel.
|
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.
|
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.
|
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.
|
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.
|
allocation.
|
||||||
- [panic.rs](../kernel/src/panic.rs): The panic handler and associated
|
- [panic.rs](../src/kernel/panic.rs): The panic handler and associated
|
||||||
functionality.
|
functionality.
|
||||||
- [process.rs](../kernel/src/process.rs): Process types and functions.
|
- [process.rs](../src/kernel/process.rs): Process types and functions.
|
||||||
- [syscall\_runner.rs](../kernel/src/syscall_runner.rs): Chooses a system call
|
- [syscall\_runner.rs](../src/kernel/syscall_runner.rs): Chooses a system call
|
||||||
by its ID and defers actual syscall execution to code in `/libgila/src/`.
|
by its ID and defers actual syscall execution to code in `/src/lib/`.
|
||||||
- [libgila/src/](../libgila/src/lib.rs): Shared between the kernel and any
|
- [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
|
binaries built for it. Contains any definitions, structures, and types that will
|
||||||
cross the boundary between userspace and kernelspace, including those sent over IPC.
|
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.
|
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.
|
the kernel.
|
||||||
|
|
||||||
## Building and running
|
## Building and running
|
||||||
|
|
||||||
Building a bootable kernel is easy. All you need to do is run
|
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
|
generated. However, it cannot be booted without installing it in a bootable
|
||||||
Limine filesystem, and it cannot do anything useful without an initramfs
|
Limine filesystem, and it cannot do anything useful without an initramfs
|
||||||
containing system servers, such as the init server and device drivers.
|
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).
|
Run `cargo make` to invoke the [Makefile.toml](../Makefile.toml).
|
||||||
|
|
||||||
- `cargo make clean_all`: Cleans all built binaries, libraries, initramfs
|
- `cargo make clean_all`: Cleans all built binaries, libraries, and ISO build files.
|
||||||
files, and ISOs.
|
- `cargo make clean_iso`: Cleans the ISO build directory.
|
||||||
- `cargo make lib`: Builds `libgila`, the library that the kernel and user
|
- `cargo make lib`: Builds `libgila`, the library that the kernel and user
|
||||||
code are linked against.
|
code are linked against.
|
||||||
- `cargo make kernel`: Builds the kernel ELF file.
|
- `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 iso`: Builds the bootable ISO with Limine installed.
|
||||||
- `cargo make run`: Builds the ISO and boots it in QEMU.
|
- `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
|
- `cargo make debug`: Launch the kernel in QEMU with debugging enabled, and
|
||||||
start and connect GDB.
|
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.
|
and `iso` tasks will automatically be rerun if their input files change.
|
||||||
|
|
||||||
### Configuration
|
### 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.
|
- `-logdev`: A sequence of one or more values representing devices to log to.
|
||||||
Current options are `display` and `serial`. This parameter is case
|
Current options are `display` and `serial`. This parameter is case
|
||||||
insensitive.
|
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:
|
The default behavior for each parameter, when not supplied, is:
|
||||||
|
|
||||||
`-loglevel=Info -initramfs=/boot/initramfs.tar.lzma`
|
`-loglevel=Info`
|
||||||
|
|
||||||
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
|
## 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,
|
gdt::dump_gdt,
|
||||||
interrupts::get_lapic_addr,
|
interrupts::get_lapic_addr,
|
||||||
},
|
},
|
||||||
},
|
}, boot::modules::MODULE_RESPONSE, memory::paging::{self, active_root_table, map_page, phys_to_virt},
|
||||||
memory::paging::{self, active_root_table, map_page, phys_to_virt},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -204,5 +203,12 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
let res = map_page(phys_to_virt(lapic), mapping);
|
let res = map_page(phys_to_virt(lapic), mapping);
|
||||||
log_info!("Map status: {:?}", res);
|
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!");
|
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