diff options
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/gdt.c | 56 | ||||
| -rw-r--r-- | src/utils/gdt.h | 31 |
2 files changed, 78 insertions, 9 deletions
diff --git a/src/utils/gdt.c b/src/utils/gdt.c index e82ebe4..fd86f5f 100644 --- a/src/utils/gdt.c +++ b/src/utils/gdt.c @@ -2,11 +2,14 @@ #include "mem.h" struct GDT_REGISTER GDTR = { 0, 0 }; +GDT_TSS TSS; void gdt_memcpy(){ - GDTR.limit=8*4; // Each entry is 8 bytes and 4 entries + GDTR.limit=8*8; // Each entry is 8 bytes and 8 entries GDTR.base=0x800; - + gdt_write_entry((GDT_ENTRY){0,0,0,0},0); // First one must be null + + // ----- Kernel Segments GDT_ENTRY cs_desc; cs_desc.base=0; cs_desc.limit=0xFFFFF; @@ -26,13 +29,50 @@ void gdt_memcpy(){ ss_desc.access=GDT_PR|GDT_PRVL_0|GDT_S|GDT_RW|GDT_DC; // Write GDT descriptors into memory - gdt_write_entry((GDT_ENTRY){0,0,0,0},GDTR.base); // First one must be null - gdt_write_entry(cs_desc, GDTR.base+8); // Each entry is 64 bits (8 bytes) - gdt_write_entry(ds_desc, GDTR.base+8*2); - gdt_write_entry(ss_desc, GDTR.base+8*3); + gdt_write_entry(cs_desc, 1); + gdt_write_entry(ds_desc, 2); + gdt_write_entry(ss_desc, 3); + + // ----- User Segments + GDT_ENTRY ucs_desc; + ucs_desc.base=0x300000; + ucs_desc.limit=0xFFFFF; + ucs_desc.flags=GDT_SZ|GDT_GR; + ucs_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_EXEC|GDT_RW|GDT_DC; + + GDT_ENTRY uds_desc; + uds_desc.base=0x300000; + uds_desc.limit=0xFFFFF; + uds_desc.flags=GDT_SZ|GDT_GR; + uds_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_RW; + + GDT_ENTRY uss_desc; + uss_desc.base=0; // Not used in stack descriptor + uss_desc.limit=0x64; // Define how much entry it can contains + uss_desc.flags=GDT_SZ|GDT_GR; + uss_desc.access=GDT_PR|GDT_PRVL_3|GDT_S|GDT_RW|GDT_DC; + + // Write GDT descriptors into memory + gdt_write_entry(ucs_desc, 4); // Each entry is 64 bits (8 bytes) + gdt_write_entry(uds_desc, 5); + gdt_write_entry(uss_desc, 6); + + // Init TSS segment + TSS.t_reserved=0; + TSS.io_map=0; + TSS.ss0=0x18; + TSS.esp0=0x50000; + + GDT_ENTRY tss_desc; + tss_desc.base=(u32)&TSS; // Not used in stack descriptor + tss_desc.limit=0x68; // Define how much entry it can contains + tss_desc.flags=0; + tss_desc.access=0x89 | GDT_PRVL_3; // Note that 0x89 is specific to TSS! + gdt_write_entry(tss_desc, 7); + } -void gdt_write_entry(GDT_ENTRY entry, u32 addr){ +void gdt_write_entry(GDT_ENTRY entry, u32 id){ int descriptor[2]; // First row of the descriptor @@ -47,5 +87,5 @@ void gdt_write_entry(GDT_ENTRY entry, u32 addr){ descriptor[1]=base|access<<8|limit<<16|flags<<20|base2<<24; // Copy descriptor into memory - memcpy(descriptor,(void*)addr,8); + memcpy(descriptor,(void*)GDTR.base+8*id,8); // Each entry is 64 bits (8 bytes) } diff --git a/src/utils/gdt.h b/src/utils/gdt.h index 85a75aa..01a01bf 100644 --- a/src/utils/gdt.h +++ b/src/utils/gdt.h @@ -31,6 +31,35 @@ struct GDT_REGISTER { u32 base; } __attribute__((packed)); +typedef struct GDT_TSS { + u16 previous_task,previous_task_unused; + u32 esp0; + u16 ss0, ss0_unused; + u32 esp1; + u16 ss1, ss1_unused; + u32 esp2; + u16 ss2, ss2_unused; + u32 cr3; + u32 eip; + u32 eflags; + u32 eax; + u32 ecx; + u32 edx; + u32 ebx; + u32 esp; + u32 ebp; + u32 esi; + u32 edi; + u16 es, es_reserved; + u16 cs, cs_reserved; + u16 ss, ss_reserved; + u16 ds, ds_reserved; + u16 fs, fs_reserved; + u16 gs, gs_reserved; + u16 ldtss, ldtss_reserved; + u16 t_reserved, io_map; +} __attribute__((packed)) GDT_TSS; + /** * Copy GDT in memory */ @@ -39,6 +68,6 @@ void gdt_memcpy(); /** * Write a GDT entry at address addr */ -void gdt_write_entry(GDT_ENTRY entry, u32 addr); +void gdt_write_entry(GDT_ENTRY entry, u32 id); #endif |
