GDT enumeration
All checks were successful
Continuous Integration / Check (push) Successful in 1m5s
Continuous Integration / Clippy (push) Successful in 47s

This commit is contained in:
August 2026-06-23 06:23:25 +00:00
parent a2eb0c8a25
commit 629ba0f6ce
Signed by: shibedrill
SSH Key Fingerprint: SHA256:M0m3JW1s38BgO2t0fG146Yxd9OJ2IOqkvCAsuRHQ6Pw
3 changed files with 85 additions and 15 deletions

View File

@ -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)
}

View File

@ -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<Self, ()> {
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(()),
}
}
}
}

View File

@ -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!");
}