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 ${LIMINEDIR}/${LIMINEBIN} build/iso/EFI/BOOT
|
||||||
|
|
||||||
cp -f ${ARTIFACTDIR}/kernel build/iso/boot/${ARCH}/kernel
|
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 \
|
xorriso -as mkisofs \
|
||||||
-b boot/limine/limine-bios-cd.bin \
|
-b boot/limine/limine-bios-cd.bin \
|
||||||
@ -147,6 +147,11 @@ dependencies = ["iso"]
|
|||||||
command = "${QEMUCOMMAND}"
|
command = "${QEMUCOMMAND}"
|
||||||
args = ["-drive", "file=build/gila.iso,format=raw,index=0,media=disk"]
|
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]
|
[tasks.run]
|
||||||
dependencies = ["iso"]
|
dependencies = ["iso"]
|
||||||
command = "${QEMUCOMMAND}"
|
command = "${QEMUCOMMAND}"
|
||||||
|
|||||||
@ -1,11 +1,32 @@
|
|||||||
timeout: 1
|
timeout: 2
|
||||||
wallpaper: boot():/wallpaper.png
|
wallpaper: boot():/wallpaper.png
|
||||||
wallpaper_style: centered
|
wallpaper_style: centered
|
||||||
|
default_entry: Gila/Trace
|
||||||
|
serial: yes
|
||||||
|
|
||||||
/Gila
|
/+Gila
|
||||||
|
comment: The Gila microkernel.
|
||||||
|
|
||||||
|
//Trace
|
||||||
protocol: limine
|
protocol: limine
|
||||||
kernel_path: boot():/boot/${ARCH}/kernel
|
kernel_path: boot():/boot/${ARCH}/kernel
|
||||||
cmdline: -loglevel=Trace -logdev=display,serial
|
cmdline: -loglevel=Trace -logdev=display,serial
|
||||||
module_path: boot():/boot/${ARCH}/userboot
|
module_path: boot():/boot/${ARCH}/userboot.bin
|
||||||
kaslr: yes
|
kaslr: yes
|
||||||
randomize_hhdm_base: 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
|
rustup
|
||||||
qemu
|
qemu
|
||||||
cargo-make
|
cargo-make
|
||||||
|
cargo-binutils
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
|
|||||||
@ -5,6 +5,8 @@ use core::arch::asm;
|
|||||||
use core::ptr::addr_of_mut;
|
use core::ptr::addr_of_mut;
|
||||||
|
|
||||||
use intbits::Bits;
|
use intbits::Bits;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use x86_64::PrivilegeLevel::{Ring0, Ring3};
|
||||||
use x86_64::structures::gdt;
|
use x86_64::structures::gdt;
|
||||||
use x86_64::structures::gdt::*;
|
use x86_64::structures::gdt::*;
|
||||||
|
|
||||||
@ -12,6 +14,51 @@ use crate::log::*;
|
|||||||
use crate::memory::alloc::format;
|
use crate::memory::alloc::format;
|
||||||
use crate::{log_info, log_trace};
|
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)]
|
#[allow(dead_code)]
|
||||||
pub trait GdtEntryRead {
|
pub trait GdtEntryRead {
|
||||||
fn base(&self) -> usize;
|
fn base(&self) -> usize;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2025 shibedrill
|
// Copyright (c) 2025 shibedrill
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
use crate::log::*;
|
use crate::{SERIAL_3F8, log::*};
|
||||||
use crate::{format, log_error, memory::alloc::string::String};
|
use crate::{format, log_error, memory::alloc::string::String};
|
||||||
|
|
||||||
pub fn double_fault(info: 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) {
|
pub fn gen_prot_fault(info: String) {
|
||||||
|
SERIAL_3F8.lock().log_writeln("Ohhhhh shit double fault");
|
||||||
log_error!("General protection fault: {}", info);
|
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,
|
FIRMWARE_TYPE_EFI32, FIRMWARE_TYPE_EFI64, FIRMWARE_TYPE_SBI, FIRMWARE_TYPE_X86BIOS,
|
||||||
};
|
};
|
||||||
use spin::mutex::Mutex;
|
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::{
|
use crate::{
|
||||||
arch::{
|
arch::{
|
||||||
asm,
|
asm, x86_64::{
|
||||||
x86_64::{
|
cpuid::{CPUID, virt_supported}, gdt::{GDT, GDT_SELECTOR_USER_CODE, GDT_SELECTOR_USER_DATA, dump_gdt}, interrupts::get_lapic_addr,
|
||||||
cpuid::{CPUID, virt_supported},
|
|
||||||
gdt::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! {
|
lazy_static! {
|
||||||
@ -88,8 +91,19 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
// Initialize all statics so the bootloader memory can be reclaimed
|
// Initialize all statics so the bootloader memory can be reclaimed
|
||||||
memory::init_statics();
|
memory::init_statics();
|
||||||
|
|
||||||
|
log_info!(
|
||||||
|
"Long mode: {}",
|
||||||
|
if asm::long_mode() {
|
||||||
|
"enabled"
|
||||||
|
} else {
|
||||||
|
"disabled"
|
||||||
|
}
|
||||||
|
);
|
||||||
// Ensure IDT exists
|
// Ensure IDT exists
|
||||||
IDT.load();
|
IDT.load();
|
||||||
|
log_info!("IDT loaded!");
|
||||||
|
GDT.load();
|
||||||
|
log_info!("GDT loaded!");
|
||||||
|
|
||||||
log_info!(
|
log_info!(
|
||||||
"Kernel cmdline: {}",
|
"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.
|
// This is an expensive function. Only run it if we're actually logging the results.
|
||||||
let loglevel = LOGGER.lock().level;
|
let loglevel = LOGGER.lock().level;
|
||||||
if loglevel > LogLevel::Trace {
|
if loglevel <= LogLevel::Trace {
|
||||||
paging::walk_tables();
|
paging::walk_tables();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info!("Long mode: {}", asm::long_mode());
|
|
||||||
dump_gdt();
|
dump_gdt();
|
||||||
|
|
||||||
let lapic = get_lapic_addr();
|
let lapic = get_lapic_addr();
|
||||||
@ -206,18 +219,29 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
log_info!("Map status: {:?}", res);
|
log_info!("Map status: {:?}", res);
|
||||||
|
|
||||||
if let Some(modules_list) = *MODULE_RESPONSE
|
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!(
|
let ub = modules_list.modules()[0];
|
||||||
"Found userboot: {} {}",
|
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
||||||
modules_list.modules()[0].path(),
|
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
||||||
modules_list.modules()[0].cmdline()
|
log_info!("Start address: 0x{:x}", start_addr);
|
||||||
);
|
|
||||||
log_info!(
|
// This does not work :/
|
||||||
"Start address: 0x{:x}",
|
unsafe {
|
||||||
modules_list.modules()[0].data().as_ptr() as usize
|
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!");
|
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::modules::MODULE_RESPONSE;
|
||||||
use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
|
use crate::boot::params::EXECUTABLE_FILE_RESPONSE;
|
||||||
use crate::memory::paging::virt_to_phys;
|
|
||||||
use crate::{LOGGER, LogLevel, format};
|
use crate::{LOGGER, LogLevel, format};
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
|
|
||||||
@ -13,7 +12,6 @@ use lazy_static::lazy_static;
|
|||||||
use limine::request::{ExecutableAddressRequest, HhdmRepsonse, HhdmRequest};
|
use limine::request::{ExecutableAddressRequest, HhdmRepsonse, HhdmRequest};
|
||||||
use limine::request::{MemmapRequest, MemmapResponse};
|
use limine::request::{MemmapRequest, MemmapResponse};
|
||||||
use talc::*;
|
use talc::*;
|
||||||
use x86_64::VirtAddr;
|
|
||||||
|
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
|
|
||||||
@ -90,10 +88,6 @@ pub fn log_address() {
|
|||||||
if let Some(resp) = ADDRESS_REQUEST.response() {
|
if let Some(resp) = ADDRESS_REQUEST.response() {
|
||||||
log_info!("Kernel physical start address: 0x{:x}", resp.physical_base);
|
log_info!("Kernel physical start address: 0x{:x}", resp.physical_base);
|
||||||
log_info!("Kernel virtual start address: 0x{:x}", resp.virtual_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 {
|
} else {
|
||||||
log_warning!("No kernel address response provided.");
|
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)
|
VirtAddr::new(phys.as_u64() + HHDM_RESPONSE.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn virt_to_phys(virt: VirtAddr) -> Option<PhysAddr> {
|
pub fn virt_to_phys(virt: VirtAddr) -> Option<PhysAddr> {
|
||||||
let root_table = unsafe { active_root_table() };
|
let root_table = unsafe { active_root_table() };
|
||||||
let mut current_table = root_table;
|
let mut current_table = root_table;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use core::panic::PanicInfo;
|
|||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn main() -> ! {
|
unsafe extern "C" fn main() -> ! {
|
||||||
|
unsafe { x86_64::instructions::port::Port::new(0x3f8).write(9u8) };
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user