Merge pull request #1 from ParrotXray/feat/gdt-refactor

feat: Refactoring the GDT table using the x86 crate
This commit is contained in:
ParrotXray 2025-05-08 22:10:28 +08:00 committed by GitHub
commit 69c2d6e358
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 135 additions and 77 deletions

35
Cargo.lock generated
View File

@ -2,6 +2,41 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cure"
version = "0.1.0"
dependencies = [
"x86",
]
[[package]]
name = "raw-cpuid"
version = "10.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
dependencies = [
"bitflags",
]
[[package]]
name = "x86"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
dependencies = [
"bit_field",
"bitflags",
"raw-cpuid",
]

View File

@ -23,4 +23,5 @@ test-success-exit-code = 33
default = []
debug = []
[dependencies]
[dependencies]
x86 = "0.52.0"

View File

@ -30,12 +30,14 @@
call _kernel_init
/* install gdt */
subl $0x6, %esp
movl $_GDT, 2(%esp)
movw _GDT_LIMIT, %ax
movw %ax, (%esp)
lgdt (%esp)
addl $0x6, %esp
call _load_gdt
// call _init_gdt
// subl $0x6, %esp
// movl $_GDT, 2(%esp)
// movw _GDT_LIMIT, %ax
// movw %ax, (%esp)
// lgdt (%esp)
// addl $0x6, %esp
/* processing register (CS, ES, SS, DS, FS, GS) */
movw $0x10, %cx /* 0x10 in binary representation is 0001 0000. If you right-shift this number by 3 bits, you will get 0000 0010, so the index is 2. */

View File

@ -1,4 +1,5 @@
// src/hal/io.rs
use x86::io;
// :e - 32 位寄存器(如 eax, edx 等)
// :x - 16 位寄存器(如 ax, dx 等)

View File

@ -1,34 +1,10 @@
// src/kernel/asm/x86/gdt.rs
use core::mem;
#[allow(dead_code)]
pub const fn sd_type(x: u64) -> u64 { x << 8 }
#[allow(dead_code)]
pub const fn sd_code_data(x: u64) -> u64 { x << 12 }
#[allow(dead_code)]
pub const fn sd_dpl(x: u64) -> u64 { x << 13 }
#[allow(dead_code)]
pub const fn sd_present(x: u64) -> u64 { x << 15 }
#[allow(dead_code)]
pub const fn sd_avl(x: u64) -> u64 { x << 20 }
#[allow(dead_code)]
pub const fn sd_64bits(x: u64) -> u64 { x << 21 }
#[allow(dead_code)]
pub const fn sd_32bits(x: u64) -> u64 { x << 22 }
#[allow(dead_code)]
pub const fn sd_4k_gran(x: u64) -> u64 { x << 23 }
#[allow(dead_code)]
pub const fn seg_lim_l(x: u64) -> u64 { x & 0x0ffff }
#[allow(dead_code)]
pub const fn seg_lim_h(x: u64) -> u64 { x & 0xf0000 }
#[allow(dead_code)]
pub const fn seg_base_l(x: u64) -> u64 { (x & 0x0000ffff) << 16 }
#[allow(dead_code)]
pub const fn seg_base_m(x: u64) -> u64 { (x & 0x00ff0000) >> 16 }
#[allow(dead_code)]
pub const fn seg_base_h(x: u64) -> u64 { x & 0xff000000 }
use core::ptr;
use x86::segmentation::{self, Descriptor, DataSegmentType, CodeSegmentType, SegmentSelector};
use x86::segmentation::{SegmentDescriptorBuilder, BuildDescriptor};
use x86::dtables::{DescriptorTablePointer, lgdt};
use x86::Ring;
#[allow(dead_code)]
pub const SEG_DATA_RD: u64 = 0x00; // Read-Only
@ -64,52 +40,93 @@ pub const SEG_CODE_EXRDC: u64 = 0x0E; // Execute/Read, conforming
pub const SEG_CODE_EXRDCA: u64 = 0x0F; // Execute/Read, conforming, accessed
#[allow(dead_code)]
pub const SEG_R0_CODE: u64 =
sd_type(SEG_CODE_EXRD) | sd_code_data(1) | sd_dpl(0) |
sd_present(1) | sd_avl(0) | sd_64bits(0) | sd_32bits(1) |
sd_4k_gran(1);
pub const NULL_SELECTOR: SegmentSelector = SegmentSelector::new(0, Ring::Ring0);
#[allow(dead_code)]
pub const SEG_R0_DATA: u64 =
sd_type(SEG_DATA_RDWR) | sd_code_data(1) | sd_dpl(0) |
sd_present(1) | sd_avl(0) | sd_64bits(0) | sd_32bits(1) |
sd_4k_gran(1);
pub const KERNEL_CODE_SELECTOR: SegmentSelector = SegmentSelector::new(1, Ring::Ring0); // Index 1 in GDT Table, Ring 0 segment selector. 0x8
#[allow(dead_code)]
pub const SEG_R3_CODE: u64 =
sd_type(SEG_CODE_EXRD) | sd_code_data(1) | sd_dpl(3) |
sd_present(1) | sd_avl(0) | sd_64bits(0) | sd_32bits(1) |
sd_4k_gran(1);
pub const KERNEL_DATA_SELECTOR: SegmentSelector = SegmentSelector::new(2, Ring::Ring0);
#[allow(dead_code)]
pub const SEG_R3_DATA: u64 =
sd_type(SEG_DATA_RDWR) | sd_code_data(1) | sd_dpl(3) |
sd_present(1) | sd_avl(0) | sd_64bits(0) | sd_32bits(1) |
sd_4k_gran(1);
pub const GDT_ENTRY: usize = 5;
pub const USER_CODE_SELECTOR: SegmentSelector = SegmentSelector::new(3, Ring::Ring3);
#[allow(dead_code)]
pub const USER_DATA_SELECTOR: SegmentSelector = SegmentSelector::new(4, Ring::Ring3);
#[no_mangle]
pub static mut _GDT: [u64; GDT_ENTRY] = [0; GDT_ENTRY];
pub static KERNEL_CODE_SEL: u16 = KERNEL_CODE_SELECTOR.bits();
#[no_mangle]
pub static KERNEL_DATA_SEL: u16 = KERNEL_DATA_SELECTOR.bits();
#[no_mangle]
pub static USER_CODE_SEL: u16 = USER_CODE_SELECTOR.bits();
#[no_mangle]
pub static USER_DATA_SEL: u16 = USER_DATA_SELECTOR.bits();
pub const GDT_ENTRY_COUNT: usize = 5;
#[no_mangle]
pub static mut _GDT_LIMIT: u16 = (mem::size_of::<[u64; GDT_ENTRY]>() - 1) as u16;
pub static mut _GDT: [Descriptor; GDT_ENTRY_COUNT] = [Descriptor::NULL; GDT_ENTRY_COUNT];
#[no_mangle]
pub fn _set_gdt_entry(index: usize, base: u64, limit: u64, flags: u64) {
pub static mut _GDT_LIMIT: u16 = (mem::size_of::<[Descriptor; GDT_ENTRY_COUNT]>() - 1) as u16;
#[no_mangle]
pub extern "C" fn _init_gdt() {
unsafe {
_GDT[index] = seg_base_h(base) | flags | seg_lim_h(limit) | seg_base_m(base);
_GDT[index] <<= 32;
_GDT[index] |= seg_base_l(base) | seg_lim_l(limit);
_GDT[0] = Descriptor::NULL;
_GDT[1] = segmentation::DescriptorBuilder::code_descriptor(
0,
0xFFFFF,
CodeSegmentType::ExecuteRead
)
.present()
.dpl(Ring::Ring0)
.db()
.limit_granularity_4kb()
.finish();
_GDT[2] = segmentation::DescriptorBuilder::data_descriptor(
0,
0xFFFFF,
DataSegmentType::ReadWrite
)
.present()
.dpl(Ring::Ring0)
.db()
.limit_granularity_4kb()
.finish();
_GDT[3] = segmentation::DescriptorBuilder::code_descriptor(
0,
0xFFFFF,
CodeSegmentType::ExecuteRead
)
.present()
.dpl(Ring::Ring3)
.db()
.limit_granularity_4kb()
.finish();
_GDT[4] = segmentation::DescriptorBuilder::data_descriptor(
0,
0xFFFFF,
DataSegmentType::ReadWrite
)
.present()
.dpl(Ring::Ring3)
.db()
.limit_granularity_4kb()
.finish();
}
}
#[no_mangle]
pub fn _init_gdt() {
_set_gdt_entry(0, 0, 0, 0);
_set_gdt_entry(1, 0, 0xfffff, SEG_R0_CODE);
_set_gdt_entry(2, 0, 0xfffff, SEG_R0_DATA);
_set_gdt_entry(3, 0, 0xfffff, SEG_R3_CODE);
_set_gdt_entry(4, 0, 0xfffff, SEG_R3_DATA);
pub extern "C" fn _load_gdt() {
unsafe {
_init_gdt();
let gdtr = DescriptorTablePointer {
limit: _GDT_LIMIT,
base: ptr::addr_of!(_GDT),
};
lgdt(&gdtr);
}
}

View File

@ -13,8 +13,6 @@ pub extern "C" fn _kernel_init() {
// TODO: 啟用分頁
tty::tty_init(tty::VGA_BUFFER_PADDR);
tty::tty_set_theme(tty::VGA_COLOR_WHITE, tty::VGA_COLOR_BLACK);
gdt::_init_gdt();
}
#[no_mangle]
@ -39,11 +37,15 @@ pub extern "C" fn _kernel_main() {
let value = 42;
println!("10: {}, 16: {:x}", value, value);
unsafe {
let x = gdt::_GDT_LIMIT;
println!("GDT Limit: {}", x);
}
// unsafe {
// core::arch::asm!(
// "movl $0, %eax",
// "movl $0, %ebx",
// "divl %ebx",
// options(att_syntax)
// );
// }
loop {