#include "../include/gdt.h" #include "../include/string.h" #include "../include/paging.h" struct tss_entry_struct tss; void bss_init() { memset((void *)((int)_edata), 0, KERNEL_BSS_SIZE); } uint32_t get_last_boot_addr() { return ((uint32_t)_end & PAGE_MASK) + PAGE_SIZE; } void load_gdt(uint32_t gdt_ptr) { asm volatile ( "lgdt (%0)\n\t" "movw %1, %%ax\n\t" "movw %%ax, %%ds\n\t" "movw %%ax, %%es\n\t" "movw %%ax, %%fs\n\t" "movw %%ax, %%gs\n\t" "movw %%ax, %%ss\n\t" "ljmp %2, $1f\n\t" "1:\n\t" : : "r" (gdt_ptr), "i" (KERNEL_DS), "i" (KERNEL_CS) : "eax" ); } void flush_tss(void) { asm volatile ( "mov %0, %%ax\n\t" "ltr %%ax\n\t" : : "i" (0x28) : "ax" ); } static void gdt_set_entry(int num, uint32_t base_addr, uint32_t limit, char loflags, char hiflags) { num /= sizeof(struct seg_desc); gdt[num].sd_lolimit = limit & 0xFFFF; gdt[num].sd_lobase = base_addr & 0xFFFFFF; gdt[num].sd_loflags = loflags; gdt[num].sd_hilimit = (limit >> 16) & 0x0F; gdt[num].sd_hiflags = hiflags; gdt[num].sd_hibase = (base_addr >> 24) & 0xFF; } void gdt_init(void) { uint8_t loflags; memset(&tss, 0, sizeof(tss)); tss.ss0 = KERNEL_DS; tss.iomap_base = 0xFFFF; // Disable I/O bitmap tss.esp0 = 0xC0010000; /* kernel stack address (firstly defined in boot.asm)*/ tss.cs = KERNEL_CS; tss.ds = KERNEL_DS; tss.es = KERNEL_DS; tss.fs = KERNEL_DS; tss.gs = KERNEL_DS; tss.ss = KERNEL_DS; gdt_set_entry(0, 0, 0, 0, 0); /* null descriptor */ loflags = SD_CODE | SD_CD | SD_DPL0 | SD_PRESENT; gdt_set_entry(KERNEL_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB); loflags = SD_DATA | SD_CD | SD_DPL0 | SD_PRESENT; gdt_set_entry(KERNEL_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB); loflags = SD_CODE | SD_CD | SD_DPL3 | SD_PRESENT; gdt_set_entry(USER_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB); loflags = SD_DATA | SD_CD | SD_DPL3 | SD_PRESENT; gdt_set_entry(USER_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB); loflags = 0x89; // P=1, DPL=0, S=0 (system), Type=0x9 (32-bit TSS) gdt_set_entry(TSS, (uint32_t)&tss, sizeof(struct tss_entry_struct) - 1, SD_PRESENT | SD_DPL0 | SD_TSSPRESENT, 0); load_gdt((uint32_t)&gdtr); flush_tss(); }