From 629ba0f6ce3161680868341642cdec856b5b22ff Mon Sep 17 00:00:00 2001 From: August Date: Tue, 23 Jun 2026 06:23:25 +0000 Subject: [PATCH] GDT enumeration --- kernel/src/arch/x86_64/asm.rs | 14 ++++++++ kernel/src/arch/x86_64/gdt.rs | 66 +++++++++++++++++++++++++++++++++++ kernel/src/main.rs | 20 +++-------- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/kernel/src/arch/x86_64/asm.rs b/kernel/src/arch/x86_64/asm.rs index 47a42d6..5a70055 100644 --- a/kernel/src/arch/x86_64/asm.rs +++ b/kernel/src/arch/x86_64/asm.rs @@ -1,6 +1,20 @@ // Copyright (c) 2025 shibedrill // SPDX-License-Identifier: MIT +use core::arch::asm; + +use intbits::Bits; + pub fn nop() { ::x86_64::instructions::nop(); } + +pub fn long_mode() -> bool { + let mut output: u32; + unsafe { asm!( + "mov eax, 0x80000001", + "cpuid", + out("edx") output, + ) } + output.bit(29) +} \ No newline at end of file diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs index b9b98dd..54d9651 100644 --- a/kernel/src/arch/x86_64/gdt.rs +++ b/kernel/src/arch/x86_64/gdt.rs @@ -5,8 +5,13 @@ use core::arch::asm; use core::ptr::addr_of_mut; use intbits::Bits; +use x86_64::structures::gdt; use x86_64::structures::gdt::*; +use crate::log_info; +use crate::log::*; +use crate::memory::alloc::format; + #[allow(dead_code)] pub trait GdtEntryRead { fn base(&self) -> usize; @@ -48,3 +53,64 @@ pub fn read_gdt() -> GlobalDescriptorTable { unsafe { core::slice::from_raw_parts(base as *const u64, (limit / 8) - 1) }; GlobalDescriptorTable::from_raw_entries(gdt_raw) } + +pub fn dump_gdt() { + let gdt = crate::arch::x86_64::gdt::read_gdt(); + log_info!("GDT length: {}", gdt.limit() + 1); + for entry in gdt.entries() { + let flags = x86_64::structures::gdt::DescriptorFlags::from_bits_retain(entry.raw()); + let seg_type = SegmentType::try_from(entry); + log_info!( + "GDT entry: type: {:?}, size: {}, raw flags: 0b{:04b}, access: 0b{:08b}", + seg_type.unwrap(), + if flags.contains(gdt::DescriptorFlags::DEFAULT_SIZE) { + "32-bit" + } else if flags.contains(gdt::DescriptorFlags::LONG_MODE) { + "64-bit" + } else { + "16-bit" + }, + entry.raw().bits(52..=55), + entry.access() + ); + } + +} + +#[derive(Debug)] +enum SegmentType { + Null, + Code, + Data, + Ldt, + Tss16Avail, + Tss16Busy, + Tss32Avail, + Tss32Busy, + Tss64Avail, + Tss64Busy, +} + +impl TryFrom<&gdt::Entry> for SegmentType { + type Error = (); + fn try_from(value: &gdt::Entry) -> Result { + let flags = x86_64::structures::gdt::DescriptorFlags::from_bits_retain(value.raw()); + if value.access().bit(4) { + if value.access().bit(3) { + Ok(SegmentType::Code) + } else { + Ok(SegmentType::Data) + } + } else { + match value.access().bits(0..=3) { + 0b0000 => Ok(SegmentType::Null), + 0b0001 => Ok(SegmentType::Tss16Avail), + 0b0010 => Ok(SegmentType::Ldt), + 0b0011 => Ok(SegmentType::Tss16Busy), + 0b1001 => {if flags.contains(gdt::DescriptorFlags::LONG_MODE) { Ok(SegmentType::Tss64Avail) } else { Ok(SegmentType::Tss32Avail) }}, + 0b1011 => {if flags.contains(gdt::DescriptorFlags::LONG_MODE) { Ok(SegmentType::Tss64Busy) } else { Ok(SegmentType::Tss32Busy) }}, + _ => Err(()), + } + } + } +} \ No newline at end of file diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 66454e2..1a84a86 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -29,11 +29,9 @@ use limine::firmware_type::FirmwareType; use spin::mutex::Mutex; use crate::{ - arch::x86_64::{ - cpuid::{CPUID, virt_supported}, - gdt::GdtEntryRead, - }, - memory::HHDM_RESPONSE, + arch::{asm, x86_64::{ + cpuid::{CPUID, virt_supported}, gdt::dump_gdt, + }}, memory::HHDM_RESPONSE, }; lazy_static! { @@ -165,16 +163,8 @@ unsafe extern "C" fn main() -> ! { ); //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() - ); - } + log_info!("Long mode: {}", asm::long_mode()); + dump_gdt(); panic!("Finished boot, but cannot start init because processes not implemented!"); }