saving before I sleep
This commit is contained in:
parent
cd24c63e84
commit
76b7e7b93c
39
Cargo.lock
generated
39
Cargo.lock
generated
@ -106,16 +106,23 @@ dependencies = [
|
||||
"enumflags2",
|
||||
"fdt",
|
||||
"flagset",
|
||||
"intbits",
|
||||
"lazy_static",
|
||||
"limine",
|
||||
"lzma-rs",
|
||||
"once_cell",
|
||||
"raw-cpuid",
|
||||
"spin 0.10.0",
|
||||
"talc",
|
||||
"tar-no-std",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intbits"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5170c2c8ecda29c1bccb9d95ccbe107bc75fa084dc0c9c6087e719f9d46330e5"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
@ -166,6 +173,15 @@ version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@ -200,15 +216,6 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "raw-cpuid"
|
||||
version = "11.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.20"
|
||||
@ -256,6 +263,18 @@ dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar-no-std"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15574aa79d3c04a12f3cb53ff976d5571e53b9d8e0bdbe4021df0a06473dd1c9"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"log",
|
||||
"memchr",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
|
@ -8,14 +8,14 @@ acpi = "5.1.0"
|
||||
enumflags2 = "0.7.11"
|
||||
fdt = { git = "https://github.com/repnop/fdt", version = "0.2.0-alpha1" }
|
||||
flagset = "0.4.7"
|
||||
intbits = "0.2.0"
|
||||
lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] }
|
||||
limine = "0.4.0"
|
||||
lzma-rs = { git = "https://github.com/glaeqen/lzma-no-std-rs/", version = "0.2.0", default-features = false }
|
||||
once_cell = { version = "1.20.3", default-features = false, features = ["alloc", "critical-section"] }
|
||||
raw-cpuid = "11.5.0"
|
||||
spin = "0.10.0"
|
||||
talc = "4.4.2"
|
||||
x86_64 = "0.15.2"
|
||||
tar-no-std = "0.3.4"
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
x86_64 = "0.15.2"
|
||||
|
44
README.md
44
README.md
@ -7,7 +7,7 @@ Gila is a Rust microkernel OS, inspired by the Xinu embedded OS, as well as Linu
|
||||
|
||||
### Complete
|
||||
|
||||
- Builds for multiple architectures
|
||||
- Builds for AArch64, RISCV64, x86_64, and LoongArch64
|
||||
- Valid Limine kernel
|
||||
- Boots on `x86_64`
|
||||
- Kernel command line parameters
|
||||
@ -17,25 +17,34 @@ Gila is a Rust microkernel OS, inspired by the Xinu embedded OS, as well as Linu
|
||||
|
||||
### In-Progress
|
||||
|
||||
- Multi-architecture feature support
|
||||
- Display console
|
||||
- Serial console
|
||||
- Device discovery & APIs
|
||||
- Power management
|
||||
- Paging
|
||||
|
||||
### Future/Desired
|
||||
|
||||
- Code execution
|
||||
- Userspace binaries/processes
|
||||
- Interprocess communication
|
||||
- Driver server interface
|
||||
- Interrupts and timers
|
||||
- Context switching
|
||||
- Process scheduling
|
||||
- Shell and CLI
|
||||
- System calls (multi-convention?)
|
||||
- Multi-user support and access control
|
||||
- Capability access control
|
||||
- Simultaneous multiprocessing support
|
||||
- ACPI, USB, PCI(e), SATA
|
||||
- Filesystem support (FAT32)
|
||||
- Application sandboxing/permissions control
|
||||
- Graphical desktop environment
|
||||
- Networking support
|
||||
- Hypervisor functionality
|
||||
|
||||
### Additional Future Features (Userspace)
|
||||
|
||||
- Device drivers
|
||||
- Filesystem drivers
|
||||
- Shell
|
||||
- Standard system API
|
||||
- Rust and C stdlib port
|
||||
- Display/windowing
|
||||
- Application sandboxing
|
||||
|
||||
## Licensing
|
||||
|
||||
@ -64,7 +73,7 @@ Licensed under the GNU Public License v3. See [LICENSE](LICENSE) for details.
|
||||
|
||||
## 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
|
||||
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:
|
||||
@ -76,20 +85,13 @@ This project uses [cargo-make](https://github.com/sagiegurari/cargo-make) to han
|
||||
|
||||
Then run `cargo make` to invoke the [Makefile.toml](Makefile.toml).
|
||||
|
||||
- `cargo make prepare`: Installs needed Rust toolchain.
|
||||
- `cargo make clean_all`: Cleans all built binaries, libraries, initramfs files, and ISOs.
|
||||
- `cargo make clean_iso`: Clean only files involved in building the ISO.
|
||||
- `cargo make clean_initramfs`: Clean only files involved in building the initramfs.
|
||||
- `cargo make clean_kernel`: Clean only kernel binaries and libraries.
|
||||
- `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 bins`: Builds all binaries included in the system.
|
||||
- `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.
|
||||
- `cargo make debug_run`: Launch the kernel in QEMU for debugging.
|
||||
- `cargo make debug_view`: Attach to a running QEMU process to debug.
|
||||
|
||||
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.
|
||||
|
||||
@ -108,9 +110,9 @@ Kernel parameters are passed as part of the `cmdline` through [limine.conf](limi
|
||||
|
||||
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`.
|
||||
- `-logdev`: A sequence of one or more values representing devices to log to. Current options are `display` and `serial`.
|
||||
- `-initramfs`: A valid path to a module to serve as the initramfs (containing the init binary). Only one value supported.
|
||||
- `-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:
|
||||
|
||||
|
@ -1,25 +1,18 @@
|
||||
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable};
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use core::arch::asm;
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
use crate::log::{LOGGER, LogLevel};
|
||||
use crate::{critical_section, format, log_trace};
|
||||
use intbits::Bits;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GDT: GlobalDescriptorTable = {
|
||||
let mut gdt = GlobalDescriptorTable::new();
|
||||
gdt.append(Descriptor::kernel_code_segment());
|
||||
gdt
|
||||
};
|
||||
pub unsafe fn gdt() -> (u8, u64) {
|
||||
let mut addr: u128 = 0;
|
||||
unsafe {
|
||||
asm! {
|
||||
"sgdt [rax]",
|
||||
in("rax") addr_of_mut!(addr),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn setup_gdt() {
|
||||
critical_section!({
|
||||
GDT.load();
|
||||
log_trace!(
|
||||
"GDT: Setting up global descriptor table at 0x{:x}",
|
||||
core::ptr::addr_of!(GDT) as usize
|
||||
);
|
||||
});
|
||||
}
|
||||
(addr.bits(0..=15) as u8, addr.bits(16..=79) as u64)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use limine::{BaseRevision, request::*};
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests_start_marker")]
|
||||
static _START_MARKER: RequestsStartMarker = RequestsStartMarker::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests_end_marker")]
|
||||
static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
|
||||
@ -16,28 +17,15 @@ static _END_MARKER: RequestsEndMarker = RequestsEndMarker::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static BASE_REVISION: BaseRevision = limine::BaseRevision::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static MP_REQUEST: MpRequest = limine::request::MpRequest::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static FILE_REQUEST: ExecutableFileRequest = limine::request::ExecutableFileRequest::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static RSDP_REQUEST: RsdpRequest = limine::request::RsdpRequest::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static MODULE_REQUEST: ModuleRequest = limine::request::ModuleRequest::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static ADDRESS_REQUEST: ExecutableAddressRequest =
|
||||
limine::request::ExecutableAddressRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static FRAMEBUFFER_REQUEST: FramebufferRequest = limine::request::FramebufferRequest::new();
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static MEMMAP_REQUEST: MemoryMapRequest = limine::request::MemoryMapRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static DTB_REQUEST: DeviceTreeBlobRequest = limine::request::DeviceTreeBlobRequest::new();
|
||||
|
@ -2,9 +2,18 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use limine::response::ModuleResponse;
|
||||
use limine::{
|
||||
request::{ExecutableFileRequest, ModuleRequest},
|
||||
response::ModuleResponse,
|
||||
};
|
||||
|
||||
use crate::boot::MODULE_REQUEST;
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static FILE_REQUEST: ExecutableFileRequest = limine::request::ExecutableFileRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static MODULE_REQUEST: ModuleRequest = limine::request::ModuleRequest::new();
|
||||
|
||||
lazy_static! {
|
||||
pub static ref MODULE_RESPONSE: &'static ModuleResponse = MODULE_REQUEST
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use crate::boot::FILE_REQUEST;
|
||||
use crate::boot::modules::FILE_REQUEST;
|
||||
use crate::memory::alloc;
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
|
@ -2,3 +2,9 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// TODO: Implement per-arch memory handlers for ACPI memory map regions
|
||||
|
||||
use limine::request::RsdpRequest;
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static RSDP_REQUEST: RsdpRequest = limine::request::RsdpRequest::new();
|
||||
|
@ -6,21 +6,12 @@ mod acpi;
|
||||
use fdt::*;
|
||||
use lazy_static::lazy_static;
|
||||
use limine::response::{DeviceTreeBlobResponse, RsdpResponse};
|
||||
use raw_cpuid::native_cpuid::CpuIdReaderNative;
|
||||
use raw_cpuid::*;
|
||||
|
||||
use crate::boot::{DTB_REQUEST, RSDP_REQUEST};
|
||||
use crate::boot::DTB_REQUEST;
|
||||
use crate::device::acpi::RSDP_REQUEST;
|
||||
use crate::log::{LOGGER, LogLevel};
|
||||
use crate::{format, log_info, log_trace, log_warning};
|
||||
|
||||
pub fn log_cpuid() {
|
||||
let cpuid: CpuId<CpuIdReaderNative> = CpuId::with_cpuid_reader(CpuIdReaderNative);
|
||||
log_trace!(
|
||||
"Device: CPU vendor: {}",
|
||||
cpuid.get_processor_brand_string().unwrap().as_str()
|
||||
)
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref DTB: Option<&'static DeviceTreeBlobResponse> = match DTB_REQUEST.get_response() {
|
||||
Some(resp) => {
|
||||
|
@ -1,3 +1,6 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
pub fn double_fault(info: &str) -> ! {
|
||||
panic!("Double fault: {}", info);
|
||||
}
|
||||
|
@ -19,17 +19,21 @@ mod process;
|
||||
#[macro_use]
|
||||
mod util;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use arch::x86_64::gdt::gdt;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use arch::x86_64::serial::Serialport;
|
||||
|
||||
use arch::asm::*;
|
||||
use boot::{modules::*, params, *};
|
||||
use constants::*;
|
||||
use device::*;
|
||||
use log::*;
|
||||
use memory::{MEMMAP_REQUEST, HHDM_RESPONSE};
|
||||
use memory::alloc::{format, string::*, vec};
|
||||
use params::*;
|
||||
|
||||
use intbits::{self, Bits};
|
||||
use limine::file::File;
|
||||
use limine::memory_map::EntryType;
|
||||
#[allow(unused_imports)]
|
||||
@ -195,8 +199,7 @@ unsafe extern "C" fn main() -> ! {
|
||||
panic!("Memory map contains no entries");
|
||||
}
|
||||
|
||||
//#[cfg(target_arch = "x86_64")]
|
||||
//gdt::setup_gdt();
|
||||
log_info!("HHDM offset: 0x{:x}", HHDM_RESPONSE.offset());
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
@ -208,9 +211,22 @@ unsafe extern "C" fn main() -> ! {
|
||||
"Boot: Paging enable: {}",
|
||||
unsafe { cr0() & (0b1 << 31) } == 1
|
||||
);
|
||||
let pd_addr = {
|
||||
let cr3: u64;
|
||||
unsafe {
|
||||
asm! {
|
||||
"mov {}, cr3",
|
||||
out(reg) cr3,
|
||||
}
|
||||
}
|
||||
log_trace!("Boot: cr3 value: 0b{:b}", cr3);
|
||||
cr3.bits(12..=31)
|
||||
};
|
||||
log_trace!("Boot: Physical address of page directory: 0x{:x}", pd_addr);
|
||||
log_trace!("Boot: Virtual address of page directory: 0x{:x}", pd_addr + HHDM_RESPONSE.offset());
|
||||
log_trace!("Boot: GDT: 0x{:x} bytes @ 0x{:x}", unsafe { gdt().0 }, unsafe { gdt().1} );
|
||||
log_trace!("Boot: GDT: 0x{:x}", unsafe { *((gdt().1 + 0x0) as *const u64) })
|
||||
}
|
||||
|
||||
log_cpuid();
|
||||
|
||||
panic!("Bailing");
|
||||
|
||||
|
@ -4,12 +4,31 @@
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use enumflags2::*;
|
||||
use lazy_static::lazy_static;
|
||||
use limine::{request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest}, response::HhdmResponse};
|
||||
|
||||
use core::alloc::{Allocator, Layout};
|
||||
use talc::*;
|
||||
|
||||
pub extern crate alloc;
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static ADDRESS_REQUEST: ExecutableAddressRequest =
|
||||
limine::request::ExecutableAddressRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static MEMMAP_REQUEST: MemoryMapRequest = limine::request::MemoryMapRequest::new();
|
||||
|
||||
#[used]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
pub static HHDM_REQUEST: HhdmRequest = limine::request::HhdmRequest::new();
|
||||
|
||||
lazy_static! {
|
||||
pub static ref HHDM_RESPONSE: &'static HhdmResponse = HHDM_REQUEST.get_response().expect("Did not get HHDM response from bootloader");
|
||||
}
|
||||
|
||||
static mut ARENA: [u8; 10000] = [0; 10000];
|
||||
|
||||
#[global_allocator]
|
||||
|
@ -1,3 +1,6 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! critical_section {
|
||||
($b:block) => {
|
||||
|
Loading…
Reference in New Issue
Block a user