如何解决加载 GDT 时出现三重故障
我正在尝试在 rust 和 global asm 中设置 GDT,但是当我尝试加载 GDT 时,它似乎出现了三重故障。
# init_gdt.asm.
.intel_Syntax noprefix
# **Notes**: 0x00: The Kernel Null Segment.
# 0x10: The Kernel Data Segment.
# 0x08: The Kernel Code Segment.
# Load the GDT and set all of the segments.
LoadGDT:
# Use the `lgdt` Load GDT instruction to set the new GDT.
# The rdi register contains the first argument of the function.
lgdt [rdi]
mov ax,0x10
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
pop rdi
mov rax,0x08
push rax
push rdi
retfq
.global LoadGDT
global_asm!(include_str!("load_gdt.asm"));
#[repr(C,packed)]
struct GDTDescriptor {
size: u16,offset: u64,}
impl GDTDescriptor {
#[inline]
pub fn new(size: u16,offset: u64) -> Self {
Self { size,offset }
}
}
#[repr(C)]
struct GDTEntry {
limit_low: u16,base_low: u16,base_middle: u8,access_byte: u8,limit_hi_flags: u8,base_hi: u8,}
impl GDTEntry {
#[inline]
fn new(
limit_low: u16,) -> Self {
Self {
limit_low,base_low,base_middle,access_byte,limit_hi_flags,base_hi,}
}
}
/// The GDT.
#[repr(C,align(0x1000))]
struct GDT {
kernel_null: GDTEntry,kernel_code: GDTEntry,kernel_data: GDTEntry,user_null: GDTEntry,user_code: GDTEntry,user_data: GDTEntry,}
/// Initialize the GDT.
pub fn init() {
unsafe {
let gdt_descriptor = GDTDescriptor::new(
(size_of::<GDT>() - 1) as u16,(&GLOBAL_DESCRIPTOR_TABLE as *const _) as u64,);
LoadGDT(&gdt_descriptor as *const _)
}
}
lazy_static! {
/// The GDT (Global Descriptor Table).
static ref GLOBAL_DESCRIPTOR_TABLE: GDT = GDT {
kernel_null: GDTEntry::new(0,0x00,0),kernel_code: GDTEntry::new(0,0x9a,0xa0,kernel_data: GDTEntry::new(0,0x92,user_null: GDTEntry::new(0,user_code: GDTEntry::new(0,user_data: GDTEntry::new(0,0)
};
}
根据 qemu 日志,它发生在 mov ds,ax
指令处。我遵循了 osdev.org 说明,我很确定我的程序集完全有效。
我也一直在尝试更改并尝试一些随机的 GDTEntries 以查看它们是否有效,但在这里没有运气。
回购:https://github.com/Andy-Python-Programmer/aero
解决方法
我不知道这是一个简单的答案!我只需要 dref(*) GDT,因为它是惰性的静态并且解决了所有问题:D
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。