Try spawning a process (doesn't work)
This commit is contained in:
parent
c3280cbbfc
commit
7efb4ee901
@ -126,7 +126,7 @@ script = '''
|
||||
cp -f ${LIMINEDIR}/${LIMINEBIN} build/iso/EFI/BOOT
|
||||
|
||||
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/kernel
|
||||
cp -f ${ARTIFACTDIR}/userboot build/iso/boot/${ARCH}/userboot
|
||||
cargo objcopy --release --bin userboot -- -O binary build/iso/boot/${ARCH}/userboot.bin
|
||||
|
||||
xorriso -as mkisofs \
|
||||
-b boot/limine/limine-bios-cd.bin \
|
||||
@ -147,6 +147,11 @@ dependencies = ["iso"]
|
||||
command = "${QEMUCOMMAND}"
|
||||
args = ["-drive", "file=build/gila.iso,format=raw,index=0,media=disk"]
|
||||
|
||||
[tasks.monitor_run]
|
||||
dependencies = ["iso"]
|
||||
command = "${QEMUCOMMAND}"
|
||||
args = ["-display", "none", "-drive", "file=build/gila.iso,format=raw,index=0,media=disk", "-monitor", "stdio"]
|
||||
|
||||
[tasks.run]
|
||||
dependencies = ["iso"]
|
||||
command = "${QEMUCOMMAND}"
|
||||
|
||||
@ -1,11 +1,32 @@
|
||||
timeout: 1
|
||||
timeout: 2
|
||||
wallpaper: boot():/wallpaper.png
|
||||
wallpaper_style: centered
|
||||
default_entry: Gila/Trace
|
||||
serial: yes
|
||||
|
||||
/Gila
|
||||
/+Gila
|
||||
comment: The Gila microkernel.
|
||||
|
||||
//Trace
|
||||
protocol: limine
|
||||
kernel_path: boot():/boot/${ARCH}/kernel
|
||||
cmdline: -loglevel=Trace -logdev=display,serial
|
||||
module_path: boot():/boot/${ARCH}/userboot
|
||||
module_path: boot():/boot/${ARCH}/userboot.bin
|
||||
kaslr: yes
|
||||
randomize_hhdm_base: yes
|
||||
|
||||
//Info
|
||||
protocol: limine
|
||||
kernel_path: boot():/boot/${ARCH}/kernel
|
||||
cmdline: -loglevel=Info -logdev=display,serial
|
||||
module_path: boot():/boot/${ARCH}/userboot.bin
|
||||
kaslr: yes
|
||||
randomize_hhdm_base: yes
|
||||
|
||||
//Warn
|
||||
protocol: limine
|
||||
kernel_path: boot():/boot/${ARCH}/kernel
|
||||
cmdline: -loglevel=Warning -logdev=display,serial
|
||||
module_path: boot():/boot/${ARCH}/userboot.bin
|
||||
kaslr: yes
|
||||
randomize_hhdm_base: yes
|
||||
@ -12,6 +12,7 @@ pkgs.mkShell {
|
||||
rustup
|
||||
qemu
|
||||
cargo-make
|
||||
cargo-binutils
|
||||
];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
|
||||
@ -5,6 +5,8 @@ use core::arch::asm;
|
||||
use core::ptr::addr_of_mut;
|
||||
|
||||
use intbits::Bits;
|
||||
use lazy_static::lazy_static;
|
||||
use x86_64::PrivilegeLevel::{Ring0, Ring3};
|
||||
use x86_64::structures::gdt;
|
||||
use x86_64::structures::gdt::*;
|
||||
|
||||
@ -12,6 +14,51 @@ use crate::log::*;
|
||||
use crate::memory::alloc::format;
|
||||
use crate::{log_info, log_trace};
|
||||
|
||||
trait ModifyFlags {
|
||||
fn set_flags(self, flags: DescriptorFlags) -> Self;
|
||||
}
|
||||
|
||||
// All this is necessary because there's no fucking method to change the
|
||||
// flags in a segment descriptor. WHY??????
|
||||
impl ModifyFlags for Descriptor {
|
||||
fn set_flags(self, flags: DescriptorFlags) -> Descriptor {
|
||||
match self {
|
||||
Descriptor::UserSegment(a) => {
|
||||
Descriptor::UserSegment(a.with_bits(52..=55, flags.bits().bits(0..=3)))
|
||||
}
|
||||
Descriptor::SystemSegment(a, b) => {
|
||||
log_trace!("0b{:b}", flags.bits().bits(0..=3));
|
||||
Descriptor::SystemSegment(a.with_bits(52..=55, flags.bits().bits(0..=3)), b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref TSS: x86_64::structures::tss::TaskStateSegment =
|
||||
x86_64::structures::tss::TaskStateSegment::new();
|
||||
pub static ref GDT: x86_64::structures::gdt::GlobalDescriptorTable<64> = {
|
||||
let mut g = GlobalDescriptorTable::empty();
|
||||
g.append(Descriptor::kernel_code_segment());
|
||||
g.append(
|
||||
Descriptor::kernel_data_segment().set_flags(DescriptorFlags::from_bits_retain(0b1010)),
|
||||
);
|
||||
g.append(Descriptor::user_code_segment());
|
||||
g.append(
|
||||
Descriptor::user_data_segment().set_flags(DescriptorFlags::from_bits_retain(0b1010)),
|
||||
);
|
||||
g.append(
|
||||
Descriptor::tss_segment(&TSS).set_flags(DescriptorFlags::from_bits_retain(0b1010)),
|
||||
);
|
||||
g
|
||||
};
|
||||
}
|
||||
pub const GDT_SELECTOR_KERNEL_CODE: SegmentSelector = SegmentSelector::new(1, Ring0);
|
||||
pub const GDT_SELECTOR_KERNEL_DATA: SegmentSelector = SegmentSelector::new(2, Ring0);
|
||||
pub const GDT_SELECTOR_USER_CODE: SegmentSelector = SegmentSelector::new(3, Ring3);
|
||||
pub const GDT_SELECTOR_USER_DATA: SegmentSelector = SegmentSelector::new(4, Ring3);
|
||||
pub const GDT_SELECTOR_TSS: SegmentSelector = SegmentSelector::new(5, Ring0);
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub trait GdtEntryRead {
|
||||
fn base(&self) -> usize;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2025 shibedrill
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::log::*;
|
||||
use crate::{SERIAL_3F8, log::*};
|
||||
use crate::{format, log_error, memory::alloc::string::String};
|
||||
|
||||
pub fn double_fault(info: String) -> ! {
|
||||
@ -13,5 +13,6 @@ pub fn page_fault_fatal(addr: usize, info: String) -> ! {
|
||||
}
|
||||
|
||||
pub fn gen_prot_fault(info: String) {
|
||||
SERIAL_3F8.lock().log_writeln("Ohhhhh shit double fault");
|
||||
log_error!("General protection fault: {}", info);
|
||||
}
|
||||
|
||||
@ -31,19 +31,22 @@ use limine::firmware::{
|
||||
FIRMWARE_TYPE_EFI32, FIRMWARE_TYPE_EFI64, FIRMWARE_TYPE_SBI, FIRMWARE_TYPE_X86BIOS,
|
||||
};
|
||||
use spin::mutex::Mutex;
|
||||
use x86_64::structures::paging::{PageTableFlags, page_table::PageTableEntry};
|
||||
use x86_64::{
|
||||
PhysAddr, VirtAddr,
|
||||
registers::rflags::RFlags,
|
||||
structures::{
|
||||
gdt::SegmentSelector,
|
||||
idt::InterruptStackFrameValue,
|
||||
paging::{PageTableFlags, page_table::PageTableEntry},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
asm,
|
||||
x86_64::{
|
||||
cpuid::{CPUID, virt_supported},
|
||||
gdt::dump_gdt,
|
||||
interrupts::get_lapic_addr,
|
||||
asm, x86_64::{
|
||||
cpuid::{CPUID, virt_supported}, gdt::{GDT, GDT_SELECTOR_USER_CODE, GDT_SELECTOR_USER_DATA, dump_gdt}, interrupts::get_lapic_addr,
|
||||
},
|
||||
},
|
||||
boot::modules::MODULE_RESPONSE,
|
||||
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! {
|
||||
@ -88,8 +91,19 @@ unsafe extern "C" fn main() -> ! {
|
||||
// Initialize all statics so the bootloader memory can be reclaimed
|
||||
memory::init_statics();
|
||||
|
||||
log_info!(
|
||||
"Long mode: {}",
|
||||
if asm::long_mode() {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
}
|
||||
);
|
||||
// Ensure IDT exists
|
||||
IDT.load();
|
||||
log_info!("IDT loaded!");
|
||||
GDT.load();
|
||||
log_info!("GDT loaded!");
|
||||
|
||||
log_info!(
|
||||
"Kernel cmdline: {}",
|
||||
@ -188,12 +202,11 @@ unsafe extern "C" fn main() -> ! {
|
||||
);
|
||||
// This is an expensive function. Only run it if we're actually logging the results.
|
||||
let loglevel = LOGGER.lock().level;
|
||||
if loglevel > LogLevel::Trace {
|
||||
if loglevel <= LogLevel::Trace {
|
||||
paging::walk_tables();
|
||||
}
|
||||
}
|
||||
|
||||
log_info!("Long mode: {}", asm::long_mode());
|
||||
dump_gdt();
|
||||
|
||||
let lapic = get_lapic_addr();
|
||||
@ -206,18 +219,29 @@ unsafe extern "C" fn main() -> ! {
|
||||
log_info!("Map status: {:?}", res);
|
||||
|
||||
if let Some(modules_list) = *MODULE_RESPONSE
|
||||
&& modules_list.modules()[0].path().ends_with("/userboot")
|
||||
&& modules_list.modules()[0].path().ends_with("/userboot.bin")
|
||||
{
|
||||
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
|
||||
);
|
||||
let ub = modules_list.modules()[0];
|
||||
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
||||
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
||||
log_info!("Start address: 0x{:x}", start_addr);
|
||||
|
||||
// This does not work :/
|
||||
unsafe {
|
||||
InterruptStackFrameValue::new(
|
||||
start_addr,
|
||||
GDT_SELECTOR_USER_CODE,
|
||||
RFlags::empty(),
|
||||
phys_to_virt(PhysAddr::new(0x1000)),
|
||||
GDT_SELECTOR_USER_DATA,
|
||||
)
|
||||
.iretq()
|
||||
};
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - Map APIC
|
||||
// - Create an interrupt stack frame, push it to stack, and iret to userboot
|
||||
|
||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@ const PAGE_SIZE: usize = 4096;
|
||||
|
||||
use crate::boot::modules::MODULE_RESPONSE;
|
||||
use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
|
||||
use crate::memory::paging::virt_to_phys;
|
||||
use crate::{LOGGER, LogLevel, format};
|
||||
use alloc::string::String;
|
||||
|
||||
@ -13,7 +12,6 @@ use lazy_static::lazy_static;
|
||||
use limine::request::{ExecutableAddressRequest, HhdmRepsonse, HhdmRequest};
|
||||
use limine::request::{MemmapRequest, MemmapResponse};
|
||||
use talc::*;
|
||||
use x86_64::VirtAddr;
|
||||
|
||||
pub extern crate alloc;
|
||||
|
||||
@ -90,10 +88,6 @@ pub fn log_address() {
|
||||
if let Some(resp) = ADDRESS_REQUEST.response() {
|
||||
log_info!("Kernel physical start address: 0x{:x}", resp.physical_base);
|
||||
log_info!("Kernel virtual start address: 0x{:x}", resp.virtual_base);
|
||||
log_info!("Testing virt_to_phys(): 0x{:x}", resp.virtual_base);
|
||||
let hhdm_vaddr = VirtAddr::new(resp.virtual_base);
|
||||
let hhdm_paddr = virt_to_phys(hhdm_vaddr);
|
||||
log_info!("Result: 0x{:x}", hhdm_paddr.unwrap());
|
||||
} else {
|
||||
log_warning!("No kernel address response provided.");
|
||||
}
|
||||
|
||||
@ -144,6 +144,7 @@ pub fn phys_to_virt(phys: PhysAddr) -> VirtAddr {
|
||||
VirtAddr::new(phys.as_u64() + HHDM_RESPONSE.offset)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn virt_to_phys(virt: VirtAddr) -> Option<PhysAddr> {
|
||||
let root_table = unsafe { active_root_table() };
|
||||
let mut current_table = root_table;
|
||||
|
||||
@ -5,6 +5,7 @@ use core::panic::PanicInfo;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "C" fn main() -> ! {
|
||||
unsafe { x86_64::instructions::port::Port::new(0x3f8).write(9u8) };
|
||||
panic!()
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user