Code: Select all
check_cs: attempt to jump to long mode without enabling EFER.LMA !
Thanks,
-Stephen
Code: Select all
check_cs: attempt to jump to long mode without enabling EFER.LMA !
Code: Select all
[GLOBAL gdt_flush] ; Allows the C code to call gdt_flush().
gdt_flush:
mov eax, [esp+4] ; Get the pointer to the GDT, passed as a parameter.
lgdt [eax] ; Load the new GDT pointer
mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment
mov ds, ax ; Load all data segment selectors
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.flush ; 0x08 is the offset to our code segment: Far jump!
.flush:
ret
Code: Select all
MOV byte [EDI+1*8+GDT_FLAGS_HI], GDT_LIMIT_HIMASK | GDT_FLAG_PAGES | GDT_FLAG_32BIT ; works
MOV byte [EDI+1*8+GDT_FLAGS_HI], GDT_LIMIT_HIMASK | GDT_FLAG_PAGES | GDT_FLAG_32BIT | 0x20 ; causes panic
Code: Select all
void gdt::gate(s32int num, u32int base, u32int limit, u8int access, u8int 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_low = (limit & 0xFFFF);
gdt_entries[num].granularity = (limit >> 16) & 0xFF;
gdt_entries[num].granularity |= gran & 0xF0;
gdt_entries[num].granularity &= 0xDF; // ADDED - Set CS.L to 0
gdt_entries[num].access = access;
}
Code: Select all
struct gdt_entry_struct
{
u16int limit_low;
u16int base_low;
u8int base_middle;
u8int access;
u8int granularity;
u8int base_high;
} __attribute__((packed));
Code: Select all
limit &= 0xFFFFF; // Limit should only be 20 bits long.
It does work for me as well, which makes this problem really weird.JamesM wrote:The mattise kernel has the same base code (I just checked ) and it doesn't crash on x64 boxen: I wonder why only you have this problem??
Code: Select all
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment