Skip to content
Merged
23 changes: 12 additions & 11 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ run-uefi: build ovmf
{{QEMU_FLAGS}}

run-bios: build
qemu-system-{{ARCH}} \
-M q35 \
-cdrom {{IMAGE_NAME}}.iso \
-d int \
-no-reboot \
-rtc base=localtime,clock=host \
-no-shutdown \
-boot d \
--enable-kvm \
-cpu host \
{{QEMU_FLAGS}}
qemu-system-{{ARCH}} \
-M q35 \
-no-reboot \
-no-shutdown \
--enable-kvm \
-device qemu-xhci \
-cpu host \
-d int \
-rtc base=localtime,clock=host \
-cdrom {{IMAGE_NAME}}.iso \
{{QEMU_FLAGS}}


run-sound:
QEMU_FLAGS="-audiodev pa,id=snd0 -machine pcspk-audiodev=snd0" just
Expand Down
2 changes: 1 addition & 1 deletion crates/acpi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use x86_64::{
};

use crate::{
hpet::{HpetHeader, HpetInfo, init_hpet},
hpet::{HpetHeader, init_hpet},
table::{AcpiTables, FadtHeader, RsdpHeader, SdtHeader},
};

Expand Down
55 changes: 53 additions & 2 deletions crates/paging/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use x86_64::{
registers::control::Cr3,
structures::paging::{
Mapper, OffsetPageTable, Page, PageSize, PageTable, PageTableFlags, PhysFrame, Size2MiB,
Size4KiB, mapper::MapToError,
Size4KiB,
mapper::{MapToError, UnmapError},
},
};

Expand Down Expand Up @@ -65,6 +66,56 @@ where
}
}

pub fn umap<P: PageSize + core::fmt::Debug>(page: Page<P>) -> Result<(), UnmapError>
where
OffsetPageTable<'static>: Mapper<P>,
{
let mapper = get_kernel_map();

let a = mapper.unmap(page)?;

a.1.flush();

Ok(())
}

#[allow(clippy::similar_names)]
pub fn umap_range(virt: VirtAddr, amount: usize) {
assert!(u16::from(virt.page_offset()) == 0);
let size = usize::try_from(Size4KiB::SIZE).unwrap();

let aligned_amount = align_up(amount, size);
let mut offset = 0;

let pages_4kb = (virt.align_up(Size2MiB::SIZE).as_u64() - virt.as_u64()) / Size4KiB::SIZE;

for _ in 0..pages_4kb {
if offset >= aligned_amount as u64 {
break;
}

umap::<Size4KiB>(Page::from_start_address(virt + offset).unwrap()).unwrap();

offset += Size4KiB::SIZE;
}

let pages_2mb = align_down(aligned_amount as u64 - offset, Size2MiB::SIZE) / Size2MiB::SIZE;

for _ in 0..pages_2mb {
umap::<Size2MiB>(Page::from_start_address(virt + offset).unwrap()).unwrap();

offset += Size2MiB::SIZE;
}

let pages_4kb = align_up(aligned_amount - usize::try_from(offset).unwrap(), size) / size;

for _ in 0..pages_4kb {
umap::<Size4KiB>(Page::from_start_address(virt + offset).unwrap()).unwrap();

offset += Size4KiB::SIZE;
}
}

// based from https://github.com/anubis-rs/xernel/blob/main/kernel/src/mem/paging.rs#L177
#[allow(clippy::similar_names)]
pub fn map_range(
Expand Down Expand Up @@ -133,7 +184,7 @@ fn get_mapper() -> OffsetPageTable<'static> {
unsafe { OffsetPageTable::new(get_page_table(addr), addr) }
}

fn get_page_table(virt_addr: VirtAddr) -> &'static mut PageTable {
pub fn get_page_table(virt_addr: VirtAddr) -> &'static mut PageTable {
let (frame, _) = Cr3::read();
let phys_addr = frame.start_address().as_u64();
let virt = virt_addr.as_u64() + phys_addr;
Expand Down
17 changes: 7 additions & 10 deletions crates/pci/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ pub struct PciInfo {
pub fn xhci_scan() -> PciDevice {
for bus in 0u8..=255 {
for device in 0u8..32 {
if let Some(info) = check_device(bus, device) {
if info.class == 3075 {
return info;
}
if let Some(info) = check_device(bus, device)
&& info.class == 3075
{
return info;
}
}
}
Expand All @@ -44,10 +44,8 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDevice> {
let mut supported_fns = [true, false, false, false, false, false, false, false];
if (header_type & 0x80) != 0 {
for function in 0u8..8 {
if get_ids(info, 0).1 != 0xFFFF {
if check_func(info, function) {
supported_fns[function as usize] = true;
}
if get_ids(info, 0).1 != 0xFFFF && check_func(info, function) {
supported_fns[function as usize] = true;
}
}
}
Expand Down Expand Up @@ -83,8 +81,7 @@ pub fn pci_read(info: PciInfo, func: u8, offset: u8) -> u32 {
let func = func as u32;
let offset = offset as u32;

let address =
((bus << 16) | (device << 11) | (func << 8) | (offset & 0xfc) | 0x80000000) as u32;
let address = (bus << 16) | (device << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

unsafe {
Port::<u32>::new(CONFIG_ADDRESS).write(address);
Expand Down
21 changes: 11 additions & 10 deletions crates/timers/src/tsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,18 @@ pub fn sleep(time: Duration) {
}

pub fn calibrate_tsc() {
reset_rtc();
let mut time = 0;

let start = rdtsc();
if ACPI_TABLE.hpet.is_some() {
sleep_hpet(Duration::from_millis(10));
time = 10;
} else {
sleep_rtc(5);
time = 5000;
}
let time = {
if ACPI_TABLE.hpet.is_some() {
sleep_hpet(Duration::from_millis(10));
10
} else {
reset_rtc();

sleep_rtc(5);
5000
}
};
let end = rdtsc();

let ticks_per_ms = (end.wrapping_sub(start)) / time;
Expand Down
48 changes: 46 additions & 2 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,19 @@ use timers::rtc::restore_rtc;
use timers::tsc::{Instant, TSC_TICKS_PER_MS, calibrate_tsc, rdtsc, sleep};
use ui::sections::cpu_info::CpuInfoSection;
use ui::sections::loading::LoadingSection;
use x86_64::structures::paging::page_table::PageTableEntry;
use x86_64::structures::paging::{PageTableFlags, PageTableIndex};

use ui::sections::test_info::TestInfoSection;
use ui::{
RenderSection, Section, UiState, get_ui_state, init_ui_state, render_section, render_ui_state,
};

use x86_64::VirtAddr;
use x86_64::{PhysAddr, VirtAddr};

use crate::idt::{TIMER_VECTOR, init_idt};
use allocators::frame::init_frame_allocator;
use paging::init_page_map;
use paging::{get_page_table, init_page_map, map_range, umap_range};
use x2apic::{X2APIC, X2Apic, init_x2apic};

use boot::HIGHER_HALF_OFFSET;
Expand Down Expand Up @@ -112,14 +114,56 @@ extern "C" fn kmain() -> ! {

render_ui_state();

let table = get_page_table(VirtAddr::new(*HIGHER_HALF_OFFSET));
let index = PageTableIndex::new(((*HIGHER_HALF_OFFSET >> 39) as u16) & 0x1FF);
let entry_pml4 = &mut table[index];

X2APIC.oneshot(TIMER_VECTOR, Duration::from_secs(1));

let mut reports = Vec::new();

let flags_pml4 = entry_pml4.flags();

let entry_pdpt = unsafe {
&mut *((entry_pml4.addr().as_u64() + *HIGHER_HALF_OFFSET) as *mut PageTableEntry)
};

let flags_pdpt = entry_pdpt.flags();

let entry_pd = unsafe {
&mut *((entry_pdpt.addr().as_u64() + *HIGHER_HALF_OFFSET) as *mut PageTableEntry)
};

let flags_pd = entry_pd.flags();

let entry_pt =
unsafe { &mut *((entry_pd.addr().as_u64() + *HIGHER_HALF_OFFSET) as *mut PageTableEntry) };

let flags_pt = entry_pt.flags();

let flags = PageTableFlags::WRITABLE | PageTableFlags::PRESENT | PageTableFlags::NO_CACHE;
entry_pml4.set_flags(flags);
entry_pdpt.set_flags(flags);
entry_pd.set_flags(flags);
entry_pt.set_flags(flags);

unsafe {
core::arch::asm!("invlpg [{0}]", in(reg) *HIGHER_HALF_OFFSET);
}

load_memtest::<MarchC>(&mut reports);
load_memtest::<ModuloN>(&mut reports);
get_ui_state().test_info_section.time.enabled = false;

entry_pml4.set_flags(flags_pml4);
entry_pdpt.set_flags(flags_pdpt);
entry_pd.set_flags(flags_pd);
entry_pt.set_flags(flags_pt);

unsafe {
core::arch::asm!("invlpg [{0}]", in(reg) *HIGHER_HALF_OFFSET);
}

beep();

color_print!(Rgb888::CYAN, "It works! {}", reports.is_empty());
Expand Down
6 changes: 3 additions & 3 deletions ovmf_sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "nightly-2025-10-04",
"sha256": {
"vars": "sha256-btmHrzo8FVvnFmX1EOrj4Aftqbi5Sv1Z1F6RxKEVZcw=",
"code": "sha256-VqTC0QTBF/GPn8vEsGH/9iEo40TqLdaATPduaXA3W8w="
"code": "sha256-85hnVSdErdnG/2bO7mrLKDoiMcD5xqmhfcSH21QPgHc="
},
"url": [
"https://github.com/osdev0/edk2-ovmf-nightly/releases/download/nightly-2025-10-04/ovmf-vars-x86_64.fd",
Expand All @@ -15,7 +15,7 @@
"version": "nightly-2025-10-04",
"sha256": {
"vars": "sha256-i2NMHmvRFgeFC2kRH2xNvRWD270UYNrHLbrL3BpKEwo=",
"code": "sha256-ivWvHCYNwa0oA5+YJFIGxrjdZ183V2ziuTbpcGBhOQk="
"code": "sha256-DIotwGIqPLkjTi9x5I4LGjJako4sFUeHJUJ2oBi6RIM="
},
"url": [
"https://github.com/osdev0/edk2-ovmf-nightly/releases/download/nightly-2025-10-04/ovmf-vars-aarch64.fd",
Expand All @@ -26,7 +26,7 @@
"version": "nightly-2025-10-04",
"sha256": {
"vars": "sha256-i2NMHmvRFgeFC2kRH2xNvRWD270UYNrHLbrL3BpKEwo=",
"code": "sha256-li06gc7/ujv9By/AriwSgcWayoJ+XYun9Lvmtl05mlM="
"code": "sha256-QITx9ek7B10lFswi6Ee7R8e08rMYqLdPwXHTLTYWozc="
},
"url": [
"https://github.com/osdev0/edk2-ovmf-nightly/releases/download/nightly-2025-10-04/ovmf-vars-riscv64.fd",
Expand Down
Loading