微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

加载 GDT 时出现三重故障

如何解决加载 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 举报,一经查实,本站将立刻删除。