TSS is created and TR loaded in initialize_gdt()

This commit is contained in:
2021-04-18 02:07:00 -05:00
parent 979344e942
commit 0b84658a61
2 changed files with 55 additions and 15 deletions

View File

@@ -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);

View File

@@ -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
};