From 018cf363963ed34781cb49b261f14664eae7b38a Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 15 Jul 2007 00:54:16 +0000 Subject: [PATCH] Clear out/initialize IDT and GDT using their virtual addresses after they have been mapped. The previous method relied on their physical pages living in the identity mapped region, which they wouldn't, when the boot loader allocated enough memory before. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21610 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/boot/platform/bios_ia32/mmu.cpp | 50 +++++++++++++--------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/system/boot/platform/bios_ia32/mmu.cpp b/src/system/boot/platform/bios_ia32/mmu.cpp index 356ea0116b..028de3af28 100644 --- a/src/system/boot/platform/bios_ia32/mmu.cpp +++ b/src/system/boot/platform/bios_ia32/mmu.cpp @@ -428,15 +428,16 @@ mmu_init_for_kernel(void) TRACE(("idt at %p\n", idt)); - // clear it out - for (int32 i = 0; i < IDT_LIMIT / 4; i++) { - idt[i] = 0; - } - // map the idt into virtual space gKernelArgs.arch_args.vir_idt = (uint32)get_next_virtual_page(); map_page(gKernelArgs.arch_args.vir_idt, (uint32)idt, kDefaultPageFlags); + // clear it out + uint32* virtualIDT = (uint32*)gKernelArgs.arch_args.vir_idt; + for (int32 i = 0; i < IDT_LIMIT / 4; i++) { + virtualIDT[i] = 0; + } + // load the idt idtDescriptor.limit = IDT_LIMIT - 1; idtDescriptor.base = (uint32 *)gKernelArgs.arch_args.vir_idt; @@ -458,25 +459,34 @@ mmu_init_for_kernel(void) TRACE(("gdt at %p\n", gdt)); - // put standard segment descriptors in it - clear_segment_descriptor(&gdt[0]); - set_segment_descriptor(&gdt[1], 0, 0xffffffff, DT_CODE_READABLE, DPL_KERNEL); - // seg 0x08 - kernel 4GB code - set_segment_descriptor(&gdt[2], 0, 0xffffffff, DT_DATA_WRITEABLE, DPL_KERNEL); - // seg 0x10 - kernel 4GB data - - set_segment_descriptor(&gdt[3], 0, 0xffffffff, DT_CODE_READABLE, DPL_USER); - // seg 0x1b - ring 3 user 4GB code - set_segment_descriptor(&gdt[4], 0, 0xffffffff, DT_DATA_WRITEABLE, DPL_USER); - // seg 0x23 - ring 3 user 4GB data - - // gdt[5] and above will be filled later by the kernel - // to contain the TSS descriptors, and for TLS (one for every CPU) - // map the gdt into virtual space gKernelArgs.arch_args.vir_gdt = (uint32)get_next_virtual_page(); map_page(gKernelArgs.arch_args.vir_gdt, (uint32)gdt, kDefaultPageFlags); + // put standard segment descriptors in it + segment_descriptor* virtualGDT + = (segment_descriptor*)gKernelArgs.arch_args.vir_gdt; + clear_segment_descriptor(&virtualGDT[0]); + + // seg 0x08 - kernel 4GB code + set_segment_descriptor(&virtualGDT[1], 0, 0xffffffff, DT_CODE_READABLE, + DPL_KERNEL); + + // seg 0x10 - kernel 4GB data + set_segment_descriptor(&virtualGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE, + DPL_KERNEL); + + // seg 0x1b - ring 3 user 4GB code + set_segment_descriptor(&virtualGDT[3], 0, 0xffffffff, DT_CODE_READABLE, + DPL_USER); + + // seg 0x23 - ring 3 user 4GB data + set_segment_descriptor(&virtualGDT[4], 0, 0xffffffff, DT_DATA_WRITEABLE, + DPL_USER); + + // virtualGDT[5] and above will be filled later by the kernel + // to contain the TSS descriptors, and for TLS (one for every CPU) + // load the GDT gdtDescriptor.limit = GDT_LIMIT - 1; gdtDescriptor.base = (uint32 *)gKernelArgs.arch_args.vir_gdt;