GDT crash after reload
Posted: Mon Dec 19, 2016 2:13 pm
Hi everyone,
actually I'm trying to reload GDT after exitBootServices but I have a problem with it because qemu is showing an error or is restarting after long jump.
OS loader loads kernel by loadImage and starts it by startImage. After that my kernel gets necessary data, calls exitBootServices and calls initGDT.
some code:
Creating descriptor from tutorial
Some memory dump from qemu:
Before load GDT:
Registers:
GDT:
Before jump:
Registers:
GDT:
Sometimes qemu shows an error after long jump:
actually I'm trying to reload GDT after exitBootServices but I have a problem with it because qemu is showing an error or is restarting after long jump.
OS loader loads kernel by loadImage and starts it by startImage. After that my kernel gets necessary data, calls exitBootServices and calls initGDT.
some code:
Creating descriptor from tutorial
Code: Select all
void
create_descriptor(uint32_t base, uint32_t limit, uint16_t flag, void* position)
{
uint64_t* descriptor = position;
// Create the high 32 bit segment
descriptor[0] = limit & 0x000F0000; // set limit bits 19:16
descriptor[0] |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
descriptor[0] |= (base >> 16) & 0x000000FF; // set base bits 23:16
descriptor[0] |= base & 0xFF000000; // set base bits 31:24
// Shift by 32 to allow for low part of segment
descriptor[0] <<= 32;
// Create the low 32 bit segment
descriptor[0] |= base << 16; // set base bits 15:0
descriptor[0] |= limit & 0x0000FFFF; // set limit bits 15:0
}
Code: Select all
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_ptr
{
UINT16 limit;
UINT32 base;
} __attribute__((packed));
struct gdt_entry gdt[5] __attribute__((aligned(8)));
struct gdt_ptr gp;
void genereateGDT() {
gp.limit = (sizeof(struct gdt_entry) * 5) - 1;
gp.base = &gdt[0];
create_descriptor(0, 0, 0, &gdt[0]);
create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0), &gdt[1]);
create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0), &gdt[2]);
create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3), &gdt[3]);
create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3), &gdt[4]);
}
void loadGDTR() {
__asm__ __volatile__ (
"cli \n\t"
"lgdt %0 \n\t"
:
: "m" (gp)
);
}
void initGDT() {
genereateGDT();
loadGDTR();
__asm__ __volatile__ (
"pushl 0x08\n"
"pushl $1f\n"
"lret \n"
"1:\n"
"movw $0x10, %%ax \n\t"
"movw %%ax, %%es \n\t"
"movw %%ax, %%fs \n\t"
"movw %%ax, %%gs \n\t"
"movw %%ax, %%ss \n\t"
"movw %%ax, %%ds \n\t"
:
:
);
}
Before load GDT:
Registers:
Code: Select all
EIP=064fb560 EFL=00000016 [----AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
DS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
FS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
GS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 07f7ed90 0000003f
IDT= 07c5d010 000007ff
Code: Select all
0000000007f7ed90: 0x00000000 0x00000000 0x0000ffff 0x00cf9300
0000000007f7eda0: 0x0000ffff 0x00cf9b00 0x0000ffff 0x00cf9200
0000000007f7edb0: 0x0000ffff 0x00cf9a00 0x0000ffff 0x00af9b00
0000000007f7edc0: 0x00000000 0x00000000
Registers:
Code: Select all
ES =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
CS =0010 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
DS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
FS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
GS =0008 00000000 ffffffff 00c09300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 06504010 00000027
IDT= 07c5d010 000007ff
Code: Select all
0000000006504010: 0x00000000 0x00000000 0x0000ffff 0x00cf9a00
0000000006504020: 0x0000ffff 0x00cf9200 0x0000ffff 0x00cffa00
0000000006504030: 0x0000ffff 0x00cff200 0x00000000 0x00000000
where all registers(cs, ds...) are 0x08qemu: fatal: Trying to execute code outside RAM or ROM