I'm trying to make a guest OS that can run on an existing type-1 hypervisor. I have reviewed many documents, but I could not come to any conclusion, so I wanted to ask here. The codes I wrote work on Ring 1. First of all, I made the GDT settings for the user code. Then I try to jump in ring 3 using iret, but I keep getting General Protection error.
Code: Select all
my_gdt_table[us_cs].limitLow = 0xbfff;
my_gdt_table[us_cs].baseLow = 0x0;
my_gdt_table[us_cs].baseMed = 0x0;
my_gdt_table[us_cs].access = 0xFA;
my_gdt_table[us_cs].limitHigh = 0xf;
my_gdt_table[us_cs].granularity = 0xc;
my_gdt_table[us_cs].baseHigh = 0x0;
my_gdt_table[us_ds].limitLow = 0xbfff;
my_gdt_table[us_ds].baseLow = 0x0;
my_gdt_table[us_ds].baseMed = 0x0;
my_gdt_table[us_ds].access = 0xF2;
my_gdt_table[us_ds].limitHigh = 0xf;
my_gdt_table[us_ds].granularity = 0xc;
my_gdt_table[us_ds].baseHigh = 0x0;
update_hypercall(UPDATE_GDT, 0x3, &my_gdt_table[us_cs]); // 0x18
update_hypercall(UPDATE_GDT, 0x4, &my_gdt_table[us_ds]); // 0x20
Code: Select all
void jump_user(){
disable_cli_hypercall();
asm volatile("\
mov $0x23, %ax; \
mov %ax, %ds; \
mov %ax, %es; \
mov %ax, %fs; \
mov %ax, %gs; \
mov %esp, %eax; \
pushl $0x23; \
pushl %eax; \
pushf; \
pushl $0x1B; \
push $1f; \
iret; \n \
1: \n \
jmp 1; \
");
}