TSS is created and TR loaded in initialize_gdt()
This commit is contained in:
@@ -30,13 +30,39 @@ struct gdt_entry_t
|
||||
unsigned int available : 1;
|
||||
unsigned int long_mode : 1;
|
||||
unsigned int big : 1;
|
||||
unsigned int gran : 1;
|
||||
unsigned int granularity : 1;
|
||||
unsigned int base_high : 8;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_t
|
||||
struct tss_entry_t
|
||||
{
|
||||
|
||||
uint32_t prev_tss;
|
||||
uint32_t esp0;
|
||||
uint32_t ss0;
|
||||
uint32_t esp1;
|
||||
uint32_t ss1;
|
||||
uint32_t esp2;
|
||||
uint32_t ss2;
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t es;
|
||||
uint32_t cs;
|
||||
uint32_t ss;
|
||||
uint32_t ds;
|
||||
uint32_t fs;
|
||||
uint32_t gs;
|
||||
uint32_t ldt;
|
||||
uint16_t trap;
|
||||
uint16_t iomap_base;
|
||||
};
|
||||
|
||||
struct interrupt_descriptor_t
|
||||
@@ -49,7 +75,7 @@ struct interrupt_descriptor_t
|
||||
uint16_t dpl : 2;
|
||||
uint16_t present : 1;
|
||||
uint16_t offset_2;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct descriptor_table_info_t
|
||||
{
|
||||
@@ -57,8 +83,6 @@ struct descriptor_table_info_t
|
||||
void *location;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct tss_t tss;
|
||||
|
||||
void load_gdt(struct gdt_entry_t *gdt)
|
||||
{
|
||||
struct descriptor_table_info_t gdt_info;
|
||||
@@ -87,6 +111,15 @@ void load_idt(struct interrupt_descriptor_t *idt)
|
||||
: "r"(&idt_info));
|
||||
}
|
||||
|
||||
void load_tr(uint16_t gdt_offset)
|
||||
{
|
||||
gdt_offset |= 3;
|
||||
asm("mov %0, %%ax; "
|
||||
"ltr %%ax; "
|
||||
:
|
||||
: "r"(gdt_offset));
|
||||
}
|
||||
|
||||
void create_interrupt_descriptor(struct interrupt_descriptor_t *descriptor, void *isr, enum isr_type_t type, uint32_t privilage)
|
||||
{
|
||||
descriptor->offset_1 = (uint32_t) isr & 0xFFFF;
|
||||
@@ -118,7 +151,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
|
||||
descriptor->available = 0;
|
||||
descriptor->long_mode = 0;
|
||||
descriptor->big = 1;
|
||||
descriptor->gran = 1;
|
||||
descriptor->granularity = 1;
|
||||
break;
|
||||
case SEGMENT_KERNEL_DATA:
|
||||
descriptor->accessed = 0;
|
||||
@@ -130,7 +163,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
|
||||
descriptor->available = 0;
|
||||
descriptor->long_mode = 0;
|
||||
descriptor->big = 1;
|
||||
descriptor->gran = 1;
|
||||
descriptor->granularity = 1;
|
||||
break;
|
||||
case SEGMENT_USER_CODE:
|
||||
descriptor->accessed = 0;
|
||||
@@ -142,7 +175,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
|
||||
descriptor->available = 0;
|
||||
descriptor->long_mode = 0;
|
||||
descriptor->big = 1;
|
||||
descriptor->gran = 1;
|
||||
descriptor->granularity = 1;
|
||||
break;
|
||||
case SEGMENT_USER_DATA:
|
||||
descriptor->accessed = 0;
|
||||
@@ -154,7 +187,7 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
|
||||
descriptor->available = 0;
|
||||
descriptor->long_mode = 0;
|
||||
descriptor->big = 1;
|
||||
descriptor->gran = 1;
|
||||
descriptor->granularity = 1;
|
||||
break;
|
||||
case SEGMENT_TSS:
|
||||
descriptor->accessed = 1;
|
||||
@@ -166,20 +199,25 @@ void create_segment_descriptor(struct gdt_entry_t *descriptor, size_t base, size
|
||||
descriptor->available = 0;
|
||||
descriptor->long_mode = 0;
|
||||
descriptor->big = 0;
|
||||
descriptor->gran = 0;
|
||||
descriptor->granularity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void initialize_gdt()
|
||||
{
|
||||
static struct gdt_entry_t gdt[gdt_size];
|
||||
static struct tss_entry_t tss;
|
||||
memset(gdt, 0, sizeof(struct gdt_entry_t) * gdt_size);
|
||||
create_segment_descriptor(&gdt[1], 0, 0xFFFFF, SEGMENT_KERNEL_CODE);
|
||||
create_segment_descriptor(&gdt[2], 0, 0xFFFFF, SEGMENT_KERNEL_DATA);
|
||||
create_segment_descriptor(&gdt[3], 0, 0xFFFFF, SEGMENT_USER_CODE);
|
||||
create_segment_descriptor(&gdt[4], 0, 0xFFFFF, SEGMENT_USER_DATA);
|
||||
//create_segment_descriptor(&gdt[5], (size_t)&tss, sizeof(struct tss_t), SEGMENT_TSS);
|
||||
create_segment_descriptor(&gdt[5], (size_t)&tss, sizeof(struct tss_entry_t) - 1, SEGMENT_TSS);
|
||||
memset(&tss, 0, sizeof(tss));
|
||||
tss.esp0 = 0xFF800000;
|
||||
tss.ss0 = 0x10;
|
||||
load_gdt(gdt);
|
||||
load_tr(5 * sizeof(struct gdt_entry_t));
|
||||
}
|
||||
|
||||
void initialize_idt()
|
||||
@@ -191,9 +229,10 @@ void initialize_idt()
|
||||
create_interrupt_descriptor(&idt[i], (void*)isr_generic, INTERRPUT_INT32, 0);
|
||||
}
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DIV_BY_0], (void*)isr_division_by_zero, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_GPF], (void*)isr_gp_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_PAGE_FAULT], (void*)isr_page_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[EXCEPTION_DOUBLE_FAULT], (void*)isr_double_fault, INTERRPUT_TRAP32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_PREEMPT], (void*)isr_preempt, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_APIC_TIMER], (void*)isr_timer, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_AP_START], (void*)isr_ap_start, INTERRPUT_INT32, 0);
|
||||
create_interrupt_descriptor(&idt[ISR_SYSCALL], (void*)isr_syscall, INTERRPUT_INT32, 0);
|
||||
|
||||
@@ -25,6 +25,7 @@ enum interrupt_code_t
|
||||
EXCEPTION_VIRTUALIZATION = 20,
|
||||
EXCEPTION_SECURITY = 30,
|
||||
ISR_APIC_TIMER = 64,
|
||||
ISR_PREEMPT = 65,
|
||||
ISR_AP_START = 127,
|
||||
ISR_SYSCALL = 128
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user