diff --git a/Kernel/Makefile b/Kernel/Makefile index aa0dcdc..1191060 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -84,15 +84,16 @@ hdd.img: kernel.bin emulate-nohdd-debug: kernel.bin @echo "[i] Starting GDB..." - @gnome-terminal -x /bin/bash -c "gdb" + @echo -e "target remote localhost:1234\n" > gdbcommands + @terminal -x /bin/bash -c "sleep 1 && gdb -x gdbcommands && rm gdbcommands" & @echo "[i] Starting QEmu..." - @qemu -kernel kernel.bin -S -gdb tcp::1234 + @qemu-system-x86_64 -S -gdb tcp::1234 -d int -smp 4 -kernel ../Loader/loader.bin -initrd kernel.bin emulate-nohdd: kernel.bin @echo "[i] Building loader..." @pushd ../Loader > /dev/null && $(MAKE) -f Makefile loader.bin && popd > /dev/null @echo "[i] Starting QEMU..." - @qemu-system-x86_64 -smp 4 -kernel ../Loader/loader.bin -initrd kernel.bin + @qemu-system-x86_64 -d int -smp 4 -kernel ../Loader/loader.bin -initrd kernel.bin emulate: hdd.img @echo "[i] Starting QEmu..." diff --git a/Kernel/include/Tier0/interrupts.h b/Kernel/include/Tier0/interrupts.h index b393f5d..a4b6949 100644 --- a/Kernel/include/Tier0/interrupts.h +++ b/Kernel/include/Tier0/interrupts.h @@ -20,7 +20,7 @@ struct S_IDT_ENTRY { u16 OffsetMiddle; u32 OffsetHigh; - u64 Reserved; + u32 Reserved; } __attribute__ ((packed)); typedef struct S_IDT_ENTRY T_IDT_ENTRY; diff --git a/Kernel/include/Tier0/kstdio.h b/Kernel/include/Tier0/kstdio.h index 752b4b3..308462e 100644 --- a/Kernel/include/Tier0/kstdio.h +++ b/Kernel/include/Tier0/kstdio.h @@ -18,7 +18,7 @@ void kprint(const s8 *szString); void kputi(s32 Number); void kprintf(const s8 *Format, ...); void kdump(u8 *bData, u32 Length); -void kprint_hex(u32 Number); +void kprint_hex(u64 Number); void kstdio_set_globals(u8 line, u8 cur_x, u8 cur_y); s32 kmemcmp(u8 *MemA, u8 *MemB, u32 Length); diff --git a/Kernel/include/Tier0/paging.h b/Kernel/include/Tier0/paging.h index b8097c0..aa297af 100644 --- a/Kernel/include/Tier0/paging.h +++ b/Kernel/include/Tier0/paging.h @@ -80,6 +80,8 @@ void paging_set_ml4(u64 ML4Physical); u8 paging_get_physical(u64 Virtual, u64 *Physical); u8 paging_get_physical_ex(u64 Virtual, u64 *Physical,T_PAGING_ML4 *ML4); +void paging_kernel_initialize(u64 KernelVirtualStart, u64 KernelPhysicalStart, u64 KernelSize); + // The temporary page is a page you can use to access some temporary physical // location. There is only one page, 4096 bytes large. Deal with it. void paging_temp_page_setup(T_LOAD_CONTEXT *LoadContext); diff --git a/Kernel/src/Tier0/interrupts.asm b/Kernel/src/Tier0/interrupts.asm index 6ef3300..1b660da 100644 --- a/Kernel/src/Tier0/interrupts.asm +++ b/Kernel/src/Tier0/interrupts.asm @@ -1,11 +1,11 @@ -;BITS 32 -;section .text +BITS 64 +section .text ;global interrupts_lidt -;extern g_idt_ptr +;extern g_Interrupts ;interrupts_lidt: -; lidt [g_idt_ptr] +; lidt [g_Interrupts] ; ret ;global interrupts_irq_sample @@ -13,3 +13,4 @@ ; mov eax, 0xB8000 ; mov byte [eax], 0x45 ; iret + diff --git a/Kernel/src/Tier0/interrupts.c b/Kernel/src/Tier0/interrupts.c index 2c9e6c5..8820da6 100644 --- a/Kernel/src/Tier0/interrupts.c +++ b/Kernel/src/Tier0/interrupts.c @@ -11,7 +11,7 @@ struct { // IRQ/APIC/Whatever T_INTERRUPTS_CHIP Chip; -} g_Interrupts; +} __attribute__((packed)) g_Interrupts; // This shit does nothing void interrupts_set_chip(T_INTERRUPTS_CHIP Chip) @@ -27,54 +27,43 @@ void interrupts_set_chip(T_INTERRUPTS_CHIP Chip) "interrupts.\n"); } +void interrupts_lidt(void) +{ + __asm__ __volatile__("lidt (%0)" : : "p"(&g_Interrupts.IDTPointer)); +} + u8 interrupts_init_idt(void) { g_Interrupts.IDTPointer.Limit = 256 * 16; - - u64 Physical = 0; - u8 Result = paging_get_physical((u64)g_Interrupts.IDTEntries, &Physical); - if (!Result) - return 0; - - kprintf("[i] Setting up IDT at 0x%x (0x%x Virtual).\n", Physical, g_Interrupts.IDTEntries); - - g_Interrupts.IDTPointer.Base = Physical; + g_Interrupts.IDTPointer.Base = (u64)g_Interrupts.IDTEntries; + kprintf("[i] Setting up IDT at 0x%x.\n", g_Interrupts.IDTEntries); + kprintf("[i] IDT Entry size %i bytes.\n", sizeof(T_IDT_ENTRY)); // Null those entries! for (u16 i = 0; i < 256; i++) { // Maybe I should access the struct's members... - // Or i can just cast that to to u64's and null them. + // Or i can just cast that to to u32's and null them. // This will set the Present flag to 0 either way *((u64 *)(&g_Interrupts.IDTEntries[i])) = 0; *(((u64 *)(&g_Interrupts.IDTEntries[i]) + 1)) = 0; - *(((u64 *)(&g_Interrupts.IDTEntries[i]) + 2)) = 0; - *(((u64 *)(&g_Interrupts.IDTEntries[i]) + 3)) = 0; } return 1; } -/* -// This creates an ASM stub for - -// This creates a 12-byte ASM stub for a handler -void interrupts_create_stub(T_ISR_STUB *Destination, u32 Address) +void interrupts_create_stub(T_ISR_STUB *Destination, u64 Address) { - // The ASM code is as follows: - // cli - // pushad - // mov eax, Handler - // call eax - // popad - // sti - // iret - Destination->Code1 = 0x60FA; // pushad, cli - Destination->Code2 = 0xB8; // mov eax, + Destination->Code1 = 0x57565552515350fa; + Destination->Code2 = 0x5341524151415041; + Destination->Code3 = 0x5741564155415441; + Destination->Code4 = 0xb848; Destination->Handler = Address; // Address - Destination->Code3 = 0xFB61D0FF; // sti, popad, call eax - Destination->Code4 = 0xCF; // iret + Destination->Code5 = 0x5d415e415f41d0ff; + Destination->Code6 = 0x59415a415b415c41; + Destination->Code7 = 0x5b595a5d5e5f5841; + Destination->Code8 = 0xcf48fb58; } - +/* void interrupts_setup_irq(u8 IRQ, void *Handler) { if (g_interrupts_chip != E_INTERRUPTS_CHIP_PIC) @@ -96,63 +85,57 @@ void interrupts_dump_idt_ptr(void) kprintf("[i] IDT Pointer structure:\n"); kprintf(" Base: 0x%x.\n", g_idt_ptr.Base); kprintf(" Limit: 0x%x.\n", g_idt_ptr.Limit); -} +}*/ void interrupts_dump_idt_entry(u8 Interrupt) { - u32 *dwEntry = (u32 *)&g_idt_entries[Interrupt]; - kprintf("[i] IDT Entry for interrupt %x:\n", Interrupt); - kprintf(" DW Low : 0x%x.\n", *dwEntry); - kprintf(" DW High: 0x%x.\n", *(dwEntry + 1)); - - T_IDT_ENTRY Entry = g_idt_entries[Interrupt]; - kprintf(" Offset: 0x%x.\n", (Entry.OffsetHigh << 16) + Entry.OffsetLow); + kprintf("[i] IDT Entry for interrupt %x, %x:\n", Interrupt, &g_Interrupts.IDTEntries[Interrupt]); + T_IDT_ENTRY Entry = g_Interrupts.IDTEntries[Interrupt]; + kprintf(" Offset: 0x%x.\n", (u64 )((u64)Entry.OffsetHigh << 32) + ((u64)Entry.OffsetMiddle << 16) + (u64)Entry.OffsetLow); kprintf(" Selector: %u.\n", Entry.Selector); - kprintf(" Zero: %u.\n", Entry.Zero); - kprintf(" P: %u.\n", (Entry.Type >> 7) & 0b1); - kprintf(" DPL: %u.\n", (Entry.Type >> 5) & 0b11); - kprintf(" S: %u.\n", (Entry.Type >> 4) & 0b1); - kprintf(" Gate type: %u.\n", Entry.Type & 0b1111); + kprintf(" P: %u.\n", Entry.Present); + kprintf(" DPL: %u.\n", Entry.DPL); + kprintf(" S: %u.\n", Entry.Selector); + kprintf(" Gate type: %u.\n", Entry.Type); } void interrupts_setup_isr_raw(u8 Interrupt, void *ASMHandler, \ T_INTERRUPTS_RING Ring) { - u32 uASMHandler = (u32)ASMHandler; - g_idt_entries[Interrupt].OffsetLow = uASMHandler & 0xFFFF; - g_idt_entries[Interrupt].OffsetHigh = (uASMHandler >> 16) & 0xFFFF; - g_idt_entries[Interrupt].Selector = 0x08; - g_idt_entries[Interrupt].Zero = 0; - - u8 Type = 0; - Type |= (1 << 7); - Type |= (Ring << 5); - Type |= (0 << 4); - Type |= 0xE; - g_idt_entries[Interrupt].Type = Type; + u64 uASMHandler = (u64)ASMHandler; + g_Interrupts.IDTEntries[Interrupt].OffsetLow = uASMHandler & 0xFFFF; + g_Interrupts.IDTEntries[Interrupt].OffsetMiddle = (uASMHandler >> 16) & 0xFFFF; + g_Interrupts.IDTEntries[Interrupt].OffsetHigh = uASMHandler >> 32; + + g_Interrupts.IDTEntries[Interrupt].Selector = 0x18; + g_Interrupts.IDTEntries[Interrupt].Zero1 = 0; + g_Interrupts.IDTEntries[Interrupt].Zero2 = 0; + g_Interrupts.IDTEntries[Interrupt].DPL = Ring; + g_Interrupts.IDTEntries[Interrupt].Present = 1; + g_Interrupts.IDTEntries[Interrupt].Type = 0b1111; } void interrupts_setup_isr(u8 Interrupt, void *Handler, \ T_INTERRUPTS_RING Ring) { - interrupts_create_stub(&g_isr_stubs[Interrupt], (u32)Handler); + interrupts_create_stub(&g_Interrupts.ISRStubs[Interrupt], (u64)Handler); - u32 ASMHandler = (u32)&g_isr_stubs[Interrupt]; + u64 ASMHandler = (u64)&g_Interrupts.ISRStubs[Interrupt]; interrupts_setup_isr_raw(Interrupt, (void*)ASMHandler, Ring); } -void interrupts_delete_isr(u8 Interrupt) +/*void interrupts_delete_isr(u8 Interrupt) { *((u32*)&g_idt_entries[Interrupt]) = 0; } - +*/ void interrupts_init_simple(void) { interrupts_set_chip(E_INTERRUPTS_CHIP_PIC); interrupts_init_idt(); interrupts_lidt(); } - +/* void interrupts_irq_finish(u8 IRQ) { if (g_interrupts_chip == E_INTERRUPTS_CHIP_PIC) diff --git a/Kernel/src/Tier0/kmain.c b/Kernel/src/Tier0/kmain.c index b63a72d..979ffd9 100644 --- a/Kernel/src/Tier0/kmain.c +++ b/Kernel/src/Tier0/kmain.c @@ -26,6 +26,11 @@ extern u64 _end; u8 test[4096 * 2]; u8 test2[4096 * 2]; +void interrupts_test(void) +{ + kprintf("Hello from an interrupt!\n"); +} + // Real kernel entry point, called from loader void kmain(u32 LoadContextAddress) { @@ -67,6 +72,7 @@ void kmain(u32 LoadContextAddress) kprintf("[i] Loader physical: %x-%x.\n", LoadContext->LoaderPhysicalStart, LoadContext->LoaderPhysicalEnd); kprintf("[i] Kernel virtual: %x-%x.\n", &_start, &_end); + paging_kernel_initialize((u64)&_start, LoadContext->KernelPhysicalStart, LoadContext->KernelPhysicalEnd - LoadContext->KernelPhysicalStart); paging_temp_page_setup(LoadContext); paging_minivmm_setup((u64)&_end, 0xFF000000 + 511 * 4096); @@ -81,7 +87,10 @@ void kmain(u32 LoadContextAddress) apic_enable_lapic(); - //interrupts_init_simple(); + interrupts_init_simple(); + interrupts_setup_isr(0x80, interrupts_test, E_INTERRUPTS_RING0); + interrupts_dump_idt_entry(0x80); + __asm__ volatile("int $0x80"); for (;;) {} /*exceptions_init_simple(); pic_init(0, 0); diff --git a/Kernel/src/Tier0/kstdio.c b/Kernel/src/Tier0/kstdio.c index 0a923b1..1ddda1a 100644 --- a/Kernel/src/Tier0/kstdio.c +++ b/Kernel/src/Tier0/kstdio.c @@ -105,7 +105,7 @@ void kprintf(const s8 *szFormat, ...) break; case 'X': case 'x': - ; u32 bData = va_arg(ap, u32); + ; u64 bData = va_arg(ap, u64); kprint_hex(bData); break; default: @@ -184,9 +184,9 @@ void kdump_nibble(u8 Nibble) kputch(Nibble + 55); } -void kprint_hex(u32 Number) +void kprint_hex(u64 Number) { - for (s8 i = 3; i >= 0; i--) + for (s8 i = 7; i >= 0; i--) { u8 Byte = (Number >> (i << 3)) & 0xFF; //switch i bytes to the right and mask as byte kdump_nibble((Byte >> 4) & 0x0F); //high nibble diff --git a/Kernel/src/Tier0/paging.c b/Kernel/src/Tier0/paging.c index 6a639fe..daaee06 100644 --- a/Kernel/src/Tier0/paging.c +++ b/Kernel/src/Tier0/paging.c @@ -7,6 +7,10 @@ struct { T_PAGING_TAB_ENTRY *TempPage; // For temp page mapping. u64 TempPageVirtual; + + u64 KernelVirtualStart; + u64 KernelPhysicalStart; + u64 KernelSize; } g_KernelPaging; struct { @@ -74,10 +78,23 @@ void paging_temp_page_set_physical(u64 Physical) __asm__ volatile("invlpg %0" :: "m"(*(u32 *)g_KernelPaging.TempPageVirtual)); } +void paging_kernel_initialize(u64 KernelVirtualStart, u64 KernelPhysicalStart, u64 KernelSize) +{ + g_KernelPaging.KernelVirtualStart = KernelVirtualStart; + g_KernelPaging.KernelPhysicalStart = KernelPhysicalStart; + g_KernelPaging.KernelSize = KernelSize; +} + u8 paging_get_physical_ex(u64 Virtual, u64 *Physical, T_PAGING_ML4 *ML4) { - PANIC("not implemented!"); - return 0; + if (Virtual < g_KernelPaging.KernelVirtualStart || Virtual > g_KernelPaging.KernelVirtualStart + g_KernelPaging.KernelSize) + { + PANIC("not implemented"); + return 0; + } + + *Physical = Virtual - g_KernelPaging.KernelVirtualStart + g_KernelPaging.KernelPhysicalStart; + return 1; } u8 paging_get_physical(u64 Virtual, u64 *Physical)