diff --git a/headers/private/kernel/arch/x86/descriptors.h b/headers/private/kernel/arch/x86/descriptors.h index 20db3e053a..8615027a16 100644 --- a/headers/private/kernel/arch/x86/descriptors.h +++ b/headers/private/kernel/arch/x86/descriptors.h @@ -86,15 +86,24 @@ set_segment_descriptor(struct segment_descriptor *desc, addr_t base, uint32 limi { set_segment_descriptor_base(desc, base); - desc->limit_00_15 = (addr_t)limit & 0x0ffff; // limit is 20 bits long - desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; + // limit is 20 bits long + if (limit & 0xfff00000) { + desc->limit_00_15 = ((addr_t)limit >> 12) & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 28) & 0xf; + desc->granularity = 1; // 4 KB granularity + } else { + desc->limit_00_15 = (addr_t)limit & 0x0ffff; + desc->limit_19_16 = ((addr_t)limit >> 16) & 0xf; + desc->granularity = 0; // 1 byte granularity + } + limit >>= 12; + desc->type = type; desc->desc_type = DT_CODE_DATA_SEGMENT; desc->privilege_level = privilegeLevel; desc->present = 1; - desc->granularity = 1; // 4 GB size (in page size steps) desc->available = 0; // system available bit is currently not used desc->d_b = 1; // 32-bit code diff --git a/src/kernel/boot/platform/bios_ia32/mmu.cpp b/src/kernel/boot/platform/bios_ia32/mmu.cpp index 05a3654b5e..47cb8d1394 100644 --- a/src/kernel/boot/platform/bios_ia32/mmu.cpp +++ b/src/kernel/boot/platform/bios_ia32/mmu.cpp @@ -379,14 +379,14 @@ mmu_init_for_kernel(void) // put standard segment descriptors in it clear_segment_descriptor(&gdt[0]); - set_segment_descriptor(&gdt[1], 0, 0xfffff, DT_CODE_READABLE, DPL_KERNEL); + set_segment_descriptor(&gdt[1], 0, 0xffffffff, DT_CODE_READABLE, DPL_KERNEL); // seg 0x08 - kernel 4GB code - set_segment_descriptor(&gdt[2], 0, 0xfffff, DT_DATA_WRITEABLE, DPL_KERNEL); + set_segment_descriptor(&gdt[2], 0, 0xffffffff, DT_DATA_WRITEABLE, DPL_KERNEL); // seg 0x10 - kernel 4GB data - set_segment_descriptor(&gdt[3], 0, 0xfffff, DT_CODE_READABLE, DPL_USER); + 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, 0xfffff, DT_DATA_WRITEABLE, DPL_USER); + 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