Experiments with GDT
This commit is contained in:
parent
c0cc10becb
commit
b3c92486b3
@ -30,8 +30,6 @@ default_to_workspace = false
|
|||||||
LIMINEDIR = "/usr/share/limine"
|
LIMINEDIR = "/usr/share/limine"
|
||||||
# Compile target
|
# Compile target
|
||||||
TARGET = "x86_64-unknown-none"
|
TARGET = "x86_64-unknown-none"
|
||||||
# Binaries included in the OS initramfs
|
|
||||||
BINS = []
|
|
||||||
|
|
||||||
[env.development]
|
[env.development]
|
||||||
PROFILE = "dev"
|
PROFILE = "dev"
|
||||||
@ -61,7 +59,7 @@ alias = "run"
|
|||||||
|
|
||||||
|
|
||||||
[tasks.clean_all]
|
[tasks.clean_all]
|
||||||
run_task = { name = ["clean_kernel", "clean_initramfs", "clean_iso"] }
|
run_task = { name = ["clean_kernel", "clean_iso"] }
|
||||||
|
|
||||||
[tasks.clean_kernel]
|
[tasks.clean_kernel]
|
||||||
command = "cargo"
|
command = "cargo"
|
||||||
@ -74,10 +72,6 @@ script = "rustup install nightly; rustup target add ${TARGET}"
|
|||||||
command = "rm"
|
command = "rm"
|
||||||
args = ["-rf", "build/iso", "build/gila.iso"]
|
args = ["-rf", "build/iso", "build/gila.iso"]
|
||||||
|
|
||||||
[tasks.clean_initramfs]
|
|
||||||
command = "rm"
|
|
||||||
args = ["-rf", "build/initramfs", "build/initramfs.tar.lzma"]
|
|
||||||
|
|
||||||
[tasks.lib]
|
[tasks.lib]
|
||||||
condition = { files_modified = { input = ["libgila/src/**/*.rs"], output = ["${ARTIFACTDIR}/libgila.rlib"] }, fail_message = "(inputs unchanged)" }
|
condition = { files_modified = { input = ["libgila/src/**/*.rs"], output = ["${ARTIFACTDIR}/libgila.rlib"] }, fail_message = "(inputs unchanged)" }
|
||||||
dependencies = []
|
dependencies = []
|
||||||
@ -94,34 +88,6 @@ dependencies = ["lib"]
|
|||||||
command = "cargo"
|
command = "cargo"
|
||||||
args = ["build", "--profile", "${PROFILE}", "-p", "kernel"]
|
args = ["build", "--profile", "${PROFILE}", "-p", "kernel"]
|
||||||
|
|
||||||
[tasks.bins]
|
|
||||||
dependencies = []
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[tasks.initramfs]
|
|
||||||
condition = { files_modified = { input = [
|
|
||||||
# This will not depend on *every* binary we build.
|
|
||||||
# If we mount a disk later in boot we can store other binaries there.
|
|
||||||
"configs/server_config.toml"
|
|
||||||
], output = ["build/${ARCH}/initramfs.tar.lzma"] }, fail_message = "(inputs unchanged)" }
|
|
||||||
dependencies = ["bins"]
|
|
||||||
script = '''
|
|
||||||
mkdir -p build/initramfs/system/bin
|
|
||||||
mkdir -p build/initramfs/system/cfg
|
|
||||||
mkdir -p build/${ARCH}
|
|
||||||
|
|
||||||
for bin in $(echo ${BINS} | tr ";" " ")
|
|
||||||
do
|
|
||||||
cp ${ARTIFACTDIR}/$bin build/initramfs/system/bin/
|
|
||||||
done
|
|
||||||
cp configs/server_config.toml build/initramfs/system/cfg/
|
|
||||||
|
|
||||||
tar -c --lzma -f build/${ARCH}/initramfs.tar.lzma build/initramfs
|
|
||||||
'''
|
|
||||||
|
|
||||||
[tasks.iso]
|
[tasks.iso]
|
||||||
condition = { files_modified = { input = [
|
condition = { files_modified = { input = [
|
||||||
"${ARTIFACTDIR}/kernel",
|
"${ARTIFACTDIR}/kernel",
|
||||||
@ -131,7 +97,7 @@ condition = { files_modified = { input = [
|
|||||||
"${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", "initramfs"]
|
dependencies = ["kernel"]
|
||||||
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
|
||||||
@ -142,14 +108,9 @@ script = '''
|
|||||||
cp -f ${LIMINEDIR}/limine-bios-cd.bin build/iso/boot/limine/
|
cp -f ${LIMINEDIR}/limine-bios-cd.bin build/iso/boot/limine/
|
||||||
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 build/${ARCH}/initramfs.tar.lzma build/iso/boot/${ARCH}
|
|
||||||
|
|
||||||
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/gila
|
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/gila
|
||||||
|
|
||||||
mkdir -p build/iso/system/bin
|
|
||||||
mkdir -p build/iso/system/tmp
|
|
||||||
mkdir -p build/iso/system/cfg
|
|
||||||
|
|
||||||
xorriso -as mkisofs \
|
xorriso -as mkisofs \
|
||||||
-b boot/limine/limine-bios-cd.bin \
|
-b boot/limine/limine-bios-cd.bin \
|
||||||
-no-emul-boot \
|
-no-emul-boot \
|
||||||
|
|||||||
6
configs/init.toml
Normal file
6
configs/init.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[deployment]
|
||||||
|
libgila_version = "0.1.0"
|
||||||
|
arch = "x86_64"
|
||||||
|
# Optional
|
||||||
|
name = "example"
|
||||||
|
version = "0.1.0"
|
||||||
@ -1,13 +0,0 @@
|
|||||||
# The configuration file detailing which system servers
|
|
||||||
# are responsible for what responsibilities.
|
|
||||||
|
|
||||||
# This configuration file details several tables. Each table
|
|
||||||
# is a category of server the OS will launch to provide
|
|
||||||
# userspace functionality. Each key in the table is a specific
|
|
||||||
# functionality.
|
|
||||||
|
|
||||||
[filesystems]
|
|
||||||
|
|
||||||
[devices]
|
|
||||||
|
|
||||||
[services]
|
|
||||||
28
docs/API.md
Normal file
28
docs/API.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Application Programming Interface
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Gila microkernel has a very limited API surface, but several components
|
||||||
|
developed alongside it expose additional functionality- such as `libgila` and
|
||||||
|
Userboot, which are treated as extensions of the kernel.
|
||||||
|
|
||||||
|
## The libgila Library
|
||||||
|
|
||||||
|
The `libgila` library is shared between the kernel and any binaries built for
|
||||||
|
it, serving to abstract the syscall API and any structures or protocols that
|
||||||
|
pass the kernel-mode boundary. It provides the official kernel API, and its
|
||||||
|
version number is incremented independent of the kernel's.
|
||||||
|
|
||||||
|
## Userboot
|
||||||
|
|
||||||
|
Userboot is an early-boot program which is launched as the first unprivileged
|
||||||
|
process by Gila. The kernel will pass several pieces of data to it, such as the
|
||||||
|
addresses of device tree blobs, framebuffers, and ACPI tables. These addresses
|
||||||
|
will not necessarily be mapped to memory. What the kernel *will* map is the
|
||||||
|
page range containing the initramfs, which Userboot is responsible for
|
||||||
|
decompressing and parsing. If the initramfs's structure & manifest file do not
|
||||||
|
match the specification denoted here, Userboot will fail to complete the boot
|
||||||
|
process.
|
||||||
|
|
||||||
|
## Initramfs Structure
|
||||||
|
|
||||||
@ -42,7 +42,8 @@ pub fn read_gdt() -> GlobalDescriptorTable {
|
|||||||
// x86 gdtr: Lower 2 8-bit bytes (lower 16 bits) is the size of the GDT,
|
// x86 gdtr: Lower 2 8-bit bytes (lower 16 bits) is the size of the GDT,
|
||||||
// in 8-bit bytes, minus one.
|
// in 8-bit bytes, minus one.
|
||||||
// Bits 16 through 79 are the virtual address of the GDT.
|
// Bits 16 through 79 are the virtual address of the GDT.
|
||||||
let (limit, addr) = (addr.bits(0..=15) as usize + 1, addr.bits(16..=79) as u64);
|
let limit = addr.bits(0..=15) as usize + 1;
|
||||||
let gdt_raw: &[u64] = unsafe { core::slice::from_raw_parts(addr as *const u64, limit / 8) };
|
let base = addr.bits(16..=79) as u64;
|
||||||
|
let gdt_raw: &[u64] = unsafe { core::slice::from_raw_parts(base as *const u64, (limit / 8) - 1) };
|
||||||
GlobalDescriptorTable::from_raw_entries(gdt_raw)
|
GlobalDescriptorTable::from_raw_entries(gdt_raw)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@ mod panic;
|
|||||||
mod process;
|
mod process;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
|
use core::{arch::asm, ptr::addr_of};
|
||||||
|
|
||||||
use arch::x86_64::interrupts::IDT;
|
use arch::x86_64::interrupts::IDT;
|
||||||
use arch::x86_64::serial::SerialPort;
|
use arch::x86_64::serial::SerialPort;
|
||||||
use boot::{BASE_REVISION, params, *};
|
use boot::{BASE_REVISION, params, *};
|
||||||
@ -28,7 +30,10 @@ use lazy_static::lazy_static;
|
|||||||
use limine::firmware_type::FirmwareType;
|
use limine::firmware_type::FirmwareType;
|
||||||
use spin::mutex::Mutex;
|
use spin::mutex::Mutex;
|
||||||
|
|
||||||
use crate::{arch::x86_64::cpuid::{CPUID, virt_supported}, memory::HHDM_RESPONSE};
|
use crate::{
|
||||||
|
arch::x86_64::{cpuid::{CPUID, virt_supported}, gdt::GdtEntryRead},
|
||||||
|
memory::HHDM_RESPONSE,
|
||||||
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref SERIAL_3F8: Mutex<SerialPort> = Mutex::new(
|
pub static ref SERIAL_3F8: Mutex<SerialPort> = Mutex::new(
|
||||||
@ -153,9 +158,18 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
|
|
||||||
let l4_start = x86_64::registers::control::Cr3::read().0.start_address();
|
let l4_start = x86_64::registers::control::Cr3::read().0.start_address();
|
||||||
log_info!("Physical address of current L4 table: 0x{:x}", l4_start);
|
log_info!("Physical address of current L4 table: 0x{:x}", l4_start);
|
||||||
log_info!("Virtual address of current L4 table: 0x{:x}", l4_start.as_u64() + HHDM_RESPONSE.offset());
|
log_info!(
|
||||||
|
"Virtual address of current L4 table: 0x{:x}",
|
||||||
|
l4_start.as_u64() + HHDM_RESPONSE.offset()
|
||||||
|
);
|
||||||
|
|
||||||
//iter_table(4, &PML4);
|
//iter_table(4, &PML4);
|
||||||
|
|
||||||
|
let gdt = crate::arch::x86_64::gdt::read_gdt();
|
||||||
|
log_info!("GDT length: {}", gdt.limit() + 1);
|
||||||
|
for entry in gdt.entries() {
|
||||||
|
log_info!("GDT entry: Flags 0b{:b}, Access 0b{:b}", entry.flags(), entry.access());
|
||||||
|
}
|
||||||
|
|
||||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user