Interrupts are working!!!!111!!!!! zomg
parent
6f065bc9b2
commit
b67c670e38
|
@ -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..."
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue