Kernel: Add custom stack to double fault handler
This prevents triple faults!
This commit is contained in:
parent
6084aae603
commit
8da4f80453
|
@ -59,10 +59,10 @@ bananboot_start:
|
||||||
bananboot_end:
|
bananboot_end:
|
||||||
|
|
||||||
.section .bss, "aw", @nobits
|
.section .bss, "aw", @nobits
|
||||||
.align 4096
|
.global g_boot_stack_top
|
||||||
boot_stack_bottom:
|
g_boot_stack_bottom:
|
||||||
.skip 4096 * 4
|
.skip 4096 * 4
|
||||||
boot_stack_top:
|
g_boot_stack_top:
|
||||||
|
|
||||||
.global g_kernel_cmdline
|
.global g_kernel_cmdline
|
||||||
g_kernel_cmdline:
|
g_kernel_cmdline:
|
||||||
|
@ -194,7 +194,7 @@ _start:
|
||||||
movl %ebx, V2P(bootloader_info)
|
movl %ebx, V2P(bootloader_info)
|
||||||
|
|
||||||
# load boot stack
|
# load boot stack
|
||||||
movl $V2P(boot_stack_top), %esp
|
movl $V2P(g_boot_stack_top), %esp
|
||||||
|
|
||||||
# load boot GDT
|
# load boot GDT
|
||||||
lgdt V2P(boot_gdtr)
|
lgdt V2P(boot_gdtr)
|
||||||
|
@ -212,7 +212,7 @@ gdt_flush:
|
||||||
call initialize_paging
|
call initialize_paging
|
||||||
|
|
||||||
# load higher half stack pointer
|
# load higher half stack pointer
|
||||||
movl $boot_stack_top, %esp
|
movl $g_boot_stack_top, %esp
|
||||||
|
|
||||||
# jump to higher half
|
# jump to higher half
|
||||||
leal higher_half, %ecx
|
leal higher_half, %ecx
|
||||||
|
|
|
@ -59,9 +59,10 @@ bananboot_start:
|
||||||
bananboot_end:
|
bananboot_end:
|
||||||
|
|
||||||
.section .bss, "aw", @nobits
|
.section .bss, "aw", @nobits
|
||||||
boot_stack_bottom:
|
.global g_boot_stack_top
|
||||||
.skip 4096 * 64
|
g_boot_stack_bottom:
|
||||||
boot_stack_top:
|
.skip 4096 * 4
|
||||||
|
g_boot_stack_top:
|
||||||
|
|
||||||
.global g_kernel_cmdline
|
.global g_kernel_cmdline
|
||||||
g_kernel_cmdline:
|
g_kernel_cmdline:
|
||||||
|
@ -193,7 +194,7 @@ _start:
|
||||||
movl %eax, V2P(bootloader_magic)
|
movl %eax, V2P(bootloader_magic)
|
||||||
movl %ebx, V2P(bootloader_info)
|
movl %ebx, V2P(bootloader_info)
|
||||||
|
|
||||||
movl $V2P(boot_stack_top), %esp
|
movl $V2P(g_boot_stack_top), %esp
|
||||||
|
|
||||||
call check_requirements
|
call check_requirements
|
||||||
call enable_sse
|
call enable_sse
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace Kernel
|
||||||
private:
|
private:
|
||||||
IDT() = default;
|
IDT() = default;
|
||||||
|
|
||||||
void register_interrupt_handler(uint8_t index, void (*handler)());
|
void register_interrupt_handler(uint8_t index, void (*handler)(), uint8_t ist = 0);
|
||||||
void register_syscall_handler(uint8_t index, void (*handler)());
|
void register_syscall_handler(uint8_t index, void (*handler)());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include <kernel/GDT.h>
|
#include <kernel/GDT.h>
|
||||||
|
#include <kernel/Memory/Types.h>
|
||||||
#include <kernel/Processor.h>
|
#include <kernel/Processor.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
extern "C" uint8_t g_boot_stack_top[];
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -62,6 +65,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
memset(&m_tss, 0x00, sizeof(TaskStateSegment));
|
memset(&m_tss, 0x00, sizeof(TaskStateSegment));
|
||||||
m_tss.iopb = sizeof(TaskStateSegment);
|
m_tss.iopb = sizeof(TaskStateSegment);
|
||||||
|
m_tss.ist1 = reinterpret_cast<vaddr_t>(g_boot_stack_top);
|
||||||
|
|
||||||
uintptr_t base = reinterpret_cast<uintptr_t>(&m_tss);
|
uintptr_t base = reinterpret_cast<uintptr_t>(&m_tss);
|
||||||
|
|
||||||
|
|
|
@ -401,7 +401,7 @@ namespace Kernel
|
||||||
Thread::current().load_sse();
|
Thread::current().load_sse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDT::register_interrupt_handler(uint8_t index, void (*handler)())
|
void IDT::register_interrupt_handler(uint8_t index, void (*handler)(), uint8_t ist)
|
||||||
{
|
{
|
||||||
auto& desc = m_idt[index];
|
auto& desc = m_idt[index];
|
||||||
memset(&desc, 0, sizeof(GateDescriptor));
|
memset(&desc, 0, sizeof(GateDescriptor));
|
||||||
|
@ -412,6 +412,7 @@ namespace Kernel
|
||||||
desc.offset2 = (uint32_t)((uintptr_t)handler >> 32);
|
desc.offset2 = (uint32_t)((uintptr_t)handler >> 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
desc.IST = ist;
|
||||||
desc.selector = 0x08;
|
desc.selector = 0x08;
|
||||||
desc.flags = 0x8E;
|
desc.flags = 0x8E;
|
||||||
}
|
}
|
||||||
|
@ -453,6 +454,9 @@ namespace Kernel
|
||||||
ISR_LIST_X
|
ISR_LIST_X
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
|
idt->register_interrupt_handler(DoubleFault, isr8, 1);
|
||||||
|
static_assert(DoubleFault == 8);
|
||||||
|
|
||||||
#define X(num) idt->register_interrupt_handler(IRQ_VECTOR_BASE + num, irq ## num);
|
#define X(num) idt->register_interrupt_handler(IRQ_VECTOR_BASE + num, irq ## num);
|
||||||
IRQ_LIST_X
|
IRQ_LIST_X
|
||||||
#undef X
|
#undef X
|
||||||
|
|
Loading…
Reference in New Issue