GDT 刷新导致整个内核失败

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

我正在用C从头开始编写一个x86_32位内核,在编写了VGA驱动程序之后,我一直在尝试实现GDT以及键盘驱动程序的中断。但是,从程序集调用的 GDT_flush() 函数失败并导致引导循环。评论该函数,它启动得很好(但显然没有 GDT)。 我正在 Qemu 上模拟内核,并使用特定于目标的工具链来编译所有文件并将其链接在一起。

GDT.c:

struct gdt_entry{ unsigned short limit_low; unsigned short base_low; unsigned char base_middle; unsigned char access; unsigned char granularity; unsigned char base_high; }__attribute__((packed)); struct gdt_pointer{ unsigned short limit; unsigned int base; }__attribute__((packed)); struct gdt_entry gdt[3]; struct gdt_pointer gdtptr; //extern void flush_gdt(unsigned char gdtptr); extern void flush_gdt(); void set_gdt_gate(int num, unsigned long base, unsigned long limit,unsigned char access,unsigned char gran){ gdt[num].base_low = (base & 0xFFFF); gdt[num].base_middle = (base >> 16) & 0xFF; gdt[num].base_high = (base >> 24) & 0xFF; gdt[num].limit_low = (limit & 0xFFFF); gdt[num].granularity = (limit >> 16) & 0x0F; gdt[num].granularity |= (gran & 0x0F); gdt[num].access = access; } void init_gdt(){ gdtptr.limit = (sizeof(struct gdt_entry) * 3) - 1; gdtptr.base = (uint32_t)&gdt; print_string("setting up kernel segments \n"); set_gdt_gate(0, 0, 0, 0, 0); //Null segment set_gdt_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //Code segment set_gdt_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //data segment print_string("kernel segments have been setup hehehhehehe\n"); //flush_gdt((unsigned char)&gdtptr); flush_gdt(); }

描述符.asm:

global flush_gdt [extern gdtptr] flush_gdt: ;mov eax, [esp + 4] ;lgdt[eax] lgdt[gdtptr] mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax jmp 0x08: .flush_two .flush_two: ret

我查找了其他类似的项目,我的实现并没有太大不同。我已经尝试解决这个问题几周了,非常感谢任何帮助。

谢谢:)

我尝试将描述符指针作为参数传递给被调用的函数,但这也会导致引导循环。

assembly x86 kernel osdev gdt
1个回答
0
投票
您将粒度位和限制位合并为相同的 4 位。第二行可能应该是:

gdt[num].granularity |= (gran & 0xF0);

但是然后:

set_gdt_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //Code segment set_gdt_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //data segment

“0xCF”值是多少?由于上面提到的掩蔽,无论如何你都会扔掉一半。如果是 
0xC-

部分打算进入粒度位,则它缺少“AVL”(“可用”)位,因此加载它会导致错误。值

0xD-
将设置 AVL 位。
    

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