Merge pull request #1 from ParrotXray/feat/gdt-refactor
feat: Refactoring the GDT table using the x86 crate
This commit is contained in:
commit
69c2d6e358
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
@ -23,4 +23,5 @@ test-success-exit-code = 33
|
||||
default = []
|
||||
debug = []
|
||||
|
||||
[dependencies]
|
||||
[dependencies]
|
||||
x86 = "0.52.0"
|
||||
@ -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. */
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// src/hal/io.rs
|
||||
use x86::io;
|
||||
|
||||
// :e - 32 位寄存器(如 eax, edx 等)
|
||||
// :x - 16 位寄存器(如 ax, dx 等)
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user