操作系统内核在 GDT 初始化时崩溃

问题描述 投票:0回答:1

我一直在开发自己的操作系统,遵循 MULTIBOOT 标头和 GDT 的教程,但是当调用

gdt_flush
函数时,它会跳转到内存中的错误位置,在一个未定义的函数中,崩溃到 GRUB

(gdt.c)

#include "gdt.h"

struct gdt_entry_struct gdt_entries[5];
struct gdt_ptr_struct gdt_ptr;

extern void gdt_flush(addr_t);

void initGdt(){
    gdt_ptr.limit = (sizeof(struct gdt_entry_struct) * 5) -1;
    gdt_ptr.base = &gdt_entries;

    setGdtGate(0,0,0,0,0); //Null Segment
    setGdtGate(1,0,0xFFFFFFFF, 0x9A, 0xCF); //Kernel Code Segment
    setGdtGate(2,0,0xFFFFFFFF, 0x92, 0xCF); //Kernel Data Segment
    setGdtGate(3,0,0xFFFFFFFF, 0xFA, 0xCF); //User Code Segment
    setGdtGate(4,0,0xFFFFFFFF, 0xF2, 0xCF); //User Data Segment

    gdt_flush(&gdt_ptr); //Sends me into a random point in memory
}

void setGdtGate(uint32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran){
    gdt_entries[num].base_low = (base & 0xFFFF);
    gdt_entries[num].base_middle = (base >> 16) & 0xFF;
    gdt_entries[num].base_high = (base >> 24) & 0xFF;

    gdt_entries[num].limit = (limit & 0xFFFF);
    gdt_entries[num].flags = (limit >> 16) & 0x0F;
    gdt_entries[num].flags |= (gran & 0x0F);
    
    gdt_entries[num].access = access;
}

(gdt.s)

global gdt_flush

gdt_flush:
    MOV eax, [esp+4]
    LGDT [eax]

    MOV eax, 0x10 ; Magic Numbers my old friend
    MOV ds, ax
    MOV es, ax
    MOV fs, ax
    MOV gs, ax
    MOV ss, ax
    JMP 0x08:.flush ; Magic Numbers Two Electric Boogaloo
.flush:
    RET

(启动.s)

BITS 32

section .text
ALIGN 4
    header:
    dd 0x1BADB002              ; Magic number
    dd 0x00000000              ; Flags
    dd -(0x1BADB002+0x00000000); Checksum
    dd header
    dd header
    dd data
    dd stack_space
    dd start
    
    

global start
extern kmain

start:
    cli
    mov esp, 0x90000
    call kmain
    hlt

halt_kernel:
    cli
    hlt
    jmp halt_kernel

section .data
data:
section .bss
resb 8192
stack_space:
c assembly operating-system gdt
1个回答
0
投票

setGdtGate 函数上的拼写错误,是

gdt_entries[num].flags |= (gran & 0xF0);
,不是
gdt_entries[num].flags |= (gran & 0x0F);
,已修复

© www.soinside.com 2019 - 2024. All rights reserved.