diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/src/kernel/interrupts/interruptDescriptors.asm b/src/kernel/interrupts/interruptDescriptors.asm new file mode 100644 index 0000000..6ec652c --- /dev/null +++ b/src/kernel/interrupts/interruptDescriptors.asm @@ -0,0 +1,56 @@ +section .sharedFunctions + +handleInterrupt: + mov eax, 8 + jmp $ + +%macro interruptHandler 1 + ALIGN 4 + global idtHandler%1 +idtHandler%1: + mov ebx, %1 + xor ecx, ecx + jmp handleInterrupt +%endmacro + +%macro interruptHandlerError 1 + align 4 + global idtHandler%1 +idtHandler%1: + pop ecx + mov ebx, %1 + jmp handleInterrupt +%endmacro + +interruptHandler 0 +interruptHandler 1 +interruptHandler 2 +interruptHandler 3 +interruptHandler 4 +interruptHandler 5 +interruptHandler 6 +interruptHandler 7 +interruptHandlerError 8 +interruptHandler 9 +interruptHandlerError 10 +interruptHandlerError 11 +interruptHandlerError 12 +interruptHandlerError 13 +interruptHandlerError 14 +interruptHandler 15 +interruptHandler 16 +interruptHandlerError 17 +interruptHandler 18 +interruptHandler 19 +interruptHandler 20 +interruptHandler 21 +interruptHandler 22 +interruptHandler 23 +interruptHandler 24 +interruptHandler 25 +interruptHandler 26 +interruptHandler 27 +interruptHandler 28 +interruptHandler 29 +interruptHandlerError 30 +interruptHandler 31 diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/src/kernel/interrupts/interruptDescriptors.asm b/src/kernel/interrupts/interruptDescriptors.asm new file mode 100644 index 0000000..6ec652c --- /dev/null +++ b/src/kernel/interrupts/interruptDescriptors.asm @@ -0,0 +1,56 @@ +section .sharedFunctions + +handleInterrupt: + mov eax, 8 + jmp $ + +%macro interruptHandler 1 + ALIGN 4 + global idtHandler%1 +idtHandler%1: + mov ebx, %1 + xor ecx, ecx + jmp handleInterrupt +%endmacro + +%macro interruptHandlerError 1 + align 4 + global idtHandler%1 +idtHandler%1: + pop ecx + mov ebx, %1 + jmp handleInterrupt +%endmacro + +interruptHandler 0 +interruptHandler 1 +interruptHandler 2 +interruptHandler 3 +interruptHandler 4 +interruptHandler 5 +interruptHandler 6 +interruptHandler 7 +interruptHandlerError 8 +interruptHandler 9 +interruptHandlerError 10 +interruptHandlerError 11 +interruptHandlerError 12 +interruptHandlerError 13 +interruptHandlerError 14 +interruptHandler 15 +interruptHandler 16 +interruptHandlerError 17 +interruptHandler 18 +interruptHandler 19 +interruptHandler 20 +interruptHandler 21 +interruptHandler 22 +interruptHandler 23 +interruptHandler 24 +interruptHandler 25 +interruptHandler 26 +interruptHandler 27 +interruptHandler 28 +interruptHandler 29 +interruptHandlerError 30 +interruptHandler 31 diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c new file mode 100644 index 0000000..4976243 --- /dev/null +++ b/src/kernel/interrupts/interrupts.c @@ -0,0 +1,30 @@ +#include "interrupts.h" +#include +#include + +#define IDT_ENTRY(i) \ + idtEntries[i].offsetLow = U32(&idtHandler##i) & 0xFFFF; \ + idtEntries[i].offsetHigh = U32(&idtHandler##i) >> 16; + +extern void *idt; + +__attribute__((section(".sharedFunction"))) __attribute__((aligned(0x10))) +IdtEntry idtEntries[256] = {}; + +void registerInterrupts() { + for (uint16_t i = 0; i < 16; i++) { + idtEntries[i].reserved = 0; + idtEntries[i].type = 0x8E; + idtEntries[i].segment = 0x8; + } + TIMES(IDT_ENTRY); + InterruptTablePointer pointer = { + .base = U32(&idtEntries), + .limit = sizeof(idtEntries) - 1, + }; + asm("lidt %0" ::"m"(pointer)); + asm("mov $0xFF, %%al" ::); + asm("out %%al, $0xA1" ::); + asm("out %%al, $0x21" ::); + asm("sti"); +} diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/src/kernel/interrupts/interruptDescriptors.asm b/src/kernel/interrupts/interruptDescriptors.asm new file mode 100644 index 0000000..6ec652c --- /dev/null +++ b/src/kernel/interrupts/interruptDescriptors.asm @@ -0,0 +1,56 @@ +section .sharedFunctions + +handleInterrupt: + mov eax, 8 + jmp $ + +%macro interruptHandler 1 + ALIGN 4 + global idtHandler%1 +idtHandler%1: + mov ebx, %1 + xor ecx, ecx + jmp handleInterrupt +%endmacro + +%macro interruptHandlerError 1 + align 4 + global idtHandler%1 +idtHandler%1: + pop ecx + mov ebx, %1 + jmp handleInterrupt +%endmacro + +interruptHandler 0 +interruptHandler 1 +interruptHandler 2 +interruptHandler 3 +interruptHandler 4 +interruptHandler 5 +interruptHandler 6 +interruptHandler 7 +interruptHandlerError 8 +interruptHandler 9 +interruptHandlerError 10 +interruptHandlerError 11 +interruptHandlerError 12 +interruptHandlerError 13 +interruptHandlerError 14 +interruptHandler 15 +interruptHandler 16 +interruptHandlerError 17 +interruptHandler 18 +interruptHandler 19 +interruptHandler 20 +interruptHandler 21 +interruptHandler 22 +interruptHandler 23 +interruptHandler 24 +interruptHandler 25 +interruptHandler 26 +interruptHandler 27 +interruptHandler 28 +interruptHandler 29 +interruptHandlerError 30 +interruptHandler 31 diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c new file mode 100644 index 0000000..4976243 --- /dev/null +++ b/src/kernel/interrupts/interrupts.c @@ -0,0 +1,30 @@ +#include "interrupts.h" +#include +#include + +#define IDT_ENTRY(i) \ + idtEntries[i].offsetLow = U32(&idtHandler##i) & 0xFFFF; \ + idtEntries[i].offsetHigh = U32(&idtHandler##i) >> 16; + +extern void *idt; + +__attribute__((section(".sharedFunction"))) __attribute__((aligned(0x10))) +IdtEntry idtEntries[256] = {}; + +void registerInterrupts() { + for (uint16_t i = 0; i < 16; i++) { + idtEntries[i].reserved = 0; + idtEntries[i].type = 0x8E; + idtEntries[i].segment = 0x8; + } + TIMES(IDT_ENTRY); + InterruptTablePointer pointer = { + .base = U32(&idtEntries), + .limit = sizeof(idtEntries) - 1, + }; + asm("lidt %0" ::"m"(pointer)); + asm("mov $0xFF, %%al" ::); + asm("out %%al, $0xA1" ::); + asm("out %%al, $0x21" ::); + asm("sti"); +} diff --git a/src/kernel/interrupts/interrupts.h b/src/kernel/interrupts/interrupts.h new file mode 100644 index 0000000..dbac9d8 --- /dev/null +++ b/src/kernel/interrupts/interrupts.h @@ -0,0 +1,282 @@ +#ifndef INTERRUPTS_PRIVATE_H +#define INTERRUPTS_PRIVATE_H + +#include + +typedef struct InterruptDescriptor32 { + uint16_t offsetLow; + uint16_t segment; + uint8_t reserved; + uint8_t type; + uint16_t offsetHigh; +} __attribute__((packed)) IdtEntry; + +typedef struct { + uint16_t limit; + uint32_t base; +} __attribute__((packed)) InterruptTablePointer; + +// sorry +#define TIMES(x) \ + x(0); \ + x(1); \ + x(2); \ + x(3); \ + x(4); \ + x(5); \ + x(6); \ + x(7); \ + x(8); \ + x(9); \ + x(10); \ + x(11); \ + x(12); \ + x(13); \ + x(14); \ + x(15); \ + x(16); \ + x(17); \ + x(18); \ + x(19); \ + x(20); \ + x(21); \ + x(22); \ + x(23); \ + x(24); \ + x(25); \ + x(26); \ + x(27); \ + x(28); \ + x(29); \ + x(30); \ + x(31); \ + x(32); \ + x(33); \ + x(34); \ + x(35); \ + x(36); \ + x(37); \ + x(38); \ + x(39); \ + x(40); \ + x(41); \ + x(42); \ + x(43); \ + x(44); \ + x(45); \ + x(46); \ + x(47); \ + x(48); \ + x(49); \ + x(50); \ + x(51); \ + x(52); \ + x(53); \ + x(54); \ + x(55); \ + x(56); \ + x(57); \ + x(58); \ + x(59); \ + x(60); \ + x(61); \ + x(62); \ + x(63); \ + x(64); \ + x(65); \ + x(66); \ + x(67); \ + x(68); \ + x(69); \ + x(70); \ + x(71); \ + x(72); \ + x(73); \ + x(74); \ + x(75); \ + x(76); \ + x(77); \ + x(78); \ + x(79); \ + x(80); \ + x(81); \ + x(82); \ + x(83); \ + x(84); \ + x(85); \ + x(86); \ + x(87); \ + x(88); \ + x(89); \ + x(90); \ + x(91); \ + x(92); \ + x(93); \ + x(94); \ + x(95); \ + x(96); \ + x(97); \ + x(98); \ + x(99); \ + x(100); \ + x(101); \ + x(102); \ + x(103); \ + x(104); \ + x(105); \ + x(106); \ + x(107); \ + x(108); \ + x(109); \ + x(110); \ + x(111); \ + x(112); \ + x(113); \ + x(114); \ + x(115); \ + x(116); \ + x(117); \ + x(118); \ + x(119); \ + x(120); \ + x(121); \ + x(122); \ + x(123); \ + x(124); \ + x(125); \ + x(126); \ + x(127); \ + x(128); \ + x(129); \ + x(130); \ + x(131); \ + x(132); \ + x(133); \ + x(134); \ + x(135); \ + x(136); \ + x(137); \ + x(138); \ + x(139); \ + x(140); \ + x(141); \ + x(142); \ + x(143); \ + x(144); \ + x(145); \ + x(146); \ + x(147); \ + x(148); \ + x(149); \ + x(150); \ + x(151); \ + x(152); \ + x(153); \ + x(154); \ + x(155); \ + x(156); \ + x(157); \ + x(158); \ + x(159); \ + x(160); \ + x(161); \ + x(162); \ + x(163); \ + x(164); \ + x(165); \ + x(166); \ + x(167); \ + x(168); \ + x(169); \ + x(170); \ + x(171); \ + x(172); \ + x(173); \ + x(174); \ + x(175); \ + x(176); \ + x(177); \ + x(178); \ + x(179); \ + x(180); \ + x(181); \ + x(182); \ + x(183); \ + x(184); \ + x(185); \ + x(186); \ + x(187); \ + x(188); \ + x(189); \ + x(190); \ + x(191); \ + x(192); \ + x(193); \ + x(194); \ + x(195); \ + x(196); \ + x(197); \ + x(198); \ + x(199); \ + x(200); \ + x(201); \ + x(202); \ + x(203); \ + x(204); \ + x(205); \ + x(206); \ + x(207); \ + x(208); \ + x(209); \ + x(210); \ + x(211); \ + x(212); \ + x(213); \ + x(214); \ + x(215); \ + x(216); \ + x(217); \ + x(218); \ + x(219); \ + x(220); \ + x(221); \ + x(222); \ + x(223); \ + x(224); \ + x(225); \ + x(226); \ + x(227); \ + x(228); \ + x(229); \ + x(230); \ + x(231); \ + x(232); \ + x(233); \ + x(234); \ + x(235); \ + x(236); \ + x(237); \ + x(238); \ + x(239); \ + x(240); \ + x(241); \ + x(242); \ + x(243); \ + x(244); \ + x(245); \ + x(246); \ + x(247); \ + x(248); \ + x(249); \ + x(250); \ + x(251); \ + x(252); \ + x(253); \ + x(254); \ + x(255); + +#define defineExtern(i) extern void *idtHandler##i; + +TIMES(defineExtern) + +#endif diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/src/kernel/interrupts/interruptDescriptors.asm b/src/kernel/interrupts/interruptDescriptors.asm new file mode 100644 index 0000000..6ec652c --- /dev/null +++ b/src/kernel/interrupts/interruptDescriptors.asm @@ -0,0 +1,56 @@ +section .sharedFunctions + +handleInterrupt: + mov eax, 8 + jmp $ + +%macro interruptHandler 1 + ALIGN 4 + global idtHandler%1 +idtHandler%1: + mov ebx, %1 + xor ecx, ecx + jmp handleInterrupt +%endmacro + +%macro interruptHandlerError 1 + align 4 + global idtHandler%1 +idtHandler%1: + pop ecx + mov ebx, %1 + jmp handleInterrupt +%endmacro + +interruptHandler 0 +interruptHandler 1 +interruptHandler 2 +interruptHandler 3 +interruptHandler 4 +interruptHandler 5 +interruptHandler 6 +interruptHandler 7 +interruptHandlerError 8 +interruptHandler 9 +interruptHandlerError 10 +interruptHandlerError 11 +interruptHandlerError 12 +interruptHandlerError 13 +interruptHandlerError 14 +interruptHandler 15 +interruptHandler 16 +interruptHandlerError 17 +interruptHandler 18 +interruptHandler 19 +interruptHandler 20 +interruptHandler 21 +interruptHandler 22 +interruptHandler 23 +interruptHandler 24 +interruptHandler 25 +interruptHandler 26 +interruptHandler 27 +interruptHandler 28 +interruptHandler 29 +interruptHandlerError 30 +interruptHandler 31 diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c new file mode 100644 index 0000000..4976243 --- /dev/null +++ b/src/kernel/interrupts/interrupts.c @@ -0,0 +1,30 @@ +#include "interrupts.h" +#include +#include + +#define IDT_ENTRY(i) \ + idtEntries[i].offsetLow = U32(&idtHandler##i) & 0xFFFF; \ + idtEntries[i].offsetHigh = U32(&idtHandler##i) >> 16; + +extern void *idt; + +__attribute__((section(".sharedFunction"))) __attribute__((aligned(0x10))) +IdtEntry idtEntries[256] = {}; + +void registerInterrupts() { + for (uint16_t i = 0; i < 16; i++) { + idtEntries[i].reserved = 0; + idtEntries[i].type = 0x8E; + idtEntries[i].segment = 0x8; + } + TIMES(IDT_ENTRY); + InterruptTablePointer pointer = { + .base = U32(&idtEntries), + .limit = sizeof(idtEntries) - 1, + }; + asm("lidt %0" ::"m"(pointer)); + asm("mov $0xFF, %%al" ::); + asm("out %%al, $0xA1" ::); + asm("out %%al, $0x21" ::); + asm("sti"); +} diff --git a/src/kernel/interrupts/interrupts.h b/src/kernel/interrupts/interrupts.h new file mode 100644 index 0000000..dbac9d8 --- /dev/null +++ b/src/kernel/interrupts/interrupts.h @@ -0,0 +1,282 @@ +#ifndef INTERRUPTS_PRIVATE_H +#define INTERRUPTS_PRIVATE_H + +#include + +typedef struct InterruptDescriptor32 { + uint16_t offsetLow; + uint16_t segment; + uint8_t reserved; + uint8_t type; + uint16_t offsetHigh; +} __attribute__((packed)) IdtEntry; + +typedef struct { + uint16_t limit; + uint32_t base; +} __attribute__((packed)) InterruptTablePointer; + +// sorry +#define TIMES(x) \ + x(0); \ + x(1); \ + x(2); \ + x(3); \ + x(4); \ + x(5); \ + x(6); \ + x(7); \ + x(8); \ + x(9); \ + x(10); \ + x(11); \ + x(12); \ + x(13); \ + x(14); \ + x(15); \ + x(16); \ + x(17); \ + x(18); \ + x(19); \ + x(20); \ + x(21); \ + x(22); \ + x(23); \ + x(24); \ + x(25); \ + x(26); \ + x(27); \ + x(28); \ + x(29); \ + x(30); \ + x(31); \ + x(32); \ + x(33); \ + x(34); \ + x(35); \ + x(36); \ + x(37); \ + x(38); \ + x(39); \ + x(40); \ + x(41); \ + x(42); \ + x(43); \ + x(44); \ + x(45); \ + x(46); \ + x(47); \ + x(48); \ + x(49); \ + x(50); \ + x(51); \ + x(52); \ + x(53); \ + x(54); \ + x(55); \ + x(56); \ + x(57); \ + x(58); \ + x(59); \ + x(60); \ + x(61); \ + x(62); \ + x(63); \ + x(64); \ + x(65); \ + x(66); \ + x(67); \ + x(68); \ + x(69); \ + x(70); \ + x(71); \ + x(72); \ + x(73); \ + x(74); \ + x(75); \ + x(76); \ + x(77); \ + x(78); \ + x(79); \ + x(80); \ + x(81); \ + x(82); \ + x(83); \ + x(84); \ + x(85); \ + x(86); \ + x(87); \ + x(88); \ + x(89); \ + x(90); \ + x(91); \ + x(92); \ + x(93); \ + x(94); \ + x(95); \ + x(96); \ + x(97); \ + x(98); \ + x(99); \ + x(100); \ + x(101); \ + x(102); \ + x(103); \ + x(104); \ + x(105); \ + x(106); \ + x(107); \ + x(108); \ + x(109); \ + x(110); \ + x(111); \ + x(112); \ + x(113); \ + x(114); \ + x(115); \ + x(116); \ + x(117); \ + x(118); \ + x(119); \ + x(120); \ + x(121); \ + x(122); \ + x(123); \ + x(124); \ + x(125); \ + x(126); \ + x(127); \ + x(128); \ + x(129); \ + x(130); \ + x(131); \ + x(132); \ + x(133); \ + x(134); \ + x(135); \ + x(136); \ + x(137); \ + x(138); \ + x(139); \ + x(140); \ + x(141); \ + x(142); \ + x(143); \ + x(144); \ + x(145); \ + x(146); \ + x(147); \ + x(148); \ + x(149); \ + x(150); \ + x(151); \ + x(152); \ + x(153); \ + x(154); \ + x(155); \ + x(156); \ + x(157); \ + x(158); \ + x(159); \ + x(160); \ + x(161); \ + x(162); \ + x(163); \ + x(164); \ + x(165); \ + x(166); \ + x(167); \ + x(168); \ + x(169); \ + x(170); \ + x(171); \ + x(172); \ + x(173); \ + x(174); \ + x(175); \ + x(176); \ + x(177); \ + x(178); \ + x(179); \ + x(180); \ + x(181); \ + x(182); \ + x(183); \ + x(184); \ + x(185); \ + x(186); \ + x(187); \ + x(188); \ + x(189); \ + x(190); \ + x(191); \ + x(192); \ + x(193); \ + x(194); \ + x(195); \ + x(196); \ + x(197); \ + x(198); \ + x(199); \ + x(200); \ + x(201); \ + x(202); \ + x(203); \ + x(204); \ + x(205); \ + x(206); \ + x(207); \ + x(208); \ + x(209); \ + x(210); \ + x(211); \ + x(212); \ + x(213); \ + x(214); \ + x(215); \ + x(216); \ + x(217); \ + x(218); \ + x(219); \ + x(220); \ + x(221); \ + x(222); \ + x(223); \ + x(224); \ + x(225); \ + x(226); \ + x(227); \ + x(228); \ + x(229); \ + x(230); \ + x(231); \ + x(232); \ + x(233); \ + x(234); \ + x(235); \ + x(236); \ + x(237); \ + x(238); \ + x(239); \ + x(240); \ + x(241); \ + x(242); \ + x(243); \ + x(244); \ + x(245); \ + x(246); \ + x(247); \ + x(248); \ + x(249); \ + x(250); \ + x(251); \ + x(252); \ + x(253); \ + x(254); \ + x(255); + +#define defineExtern(i) extern void *idtHandler##i; + +TIMES(defineExtern) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f8b6f03..40bb13c 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -48,9 +49,11 @@ // multiboot-loaded stuff loadAndScheduleLoader(multibootInfo); setupSyscalls(); + registerInterrupts(); while (1) { Syscall *call = listPopFirst(&callsToProcess); if (!call) { + int x = 1 / 0; asm("hlt"); continue; } diff --git a/.gitignore b/.gitignore index 8998d08..1a7bb4a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ .vscode *.log initrd +bochsrc diff --git a/link.ld b/link.ld index 1afc715..c4875c1 100644 --- a/link.ld +++ b/link.ld @@ -18,7 +18,7 @@ .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { *(.sharedFunctions) } - . = ALIGN(4k); + functionsEnd = .; . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { diff --git a/src/include/syscalls.h b/src/include/syscalls.h index dd3cc12..9fb0b69 100644 --- a/src/include/syscalls.h +++ b/src/include/syscalls.h @@ -13,6 +13,7 @@ SYS_LOAD_INITRD = 5, SYS_GET_SERVICE = 6, SYS_GET_PROVIDER = 7, + SYS_INTERRUPT = 8, } SyscallIds; #endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index 0c50e6d..f0fdbae 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -130,7 +130,11 @@ dd gdt32 section .text +newGDT: + dw gdt32.end - gdt32 - 1 + dd gdt32 + 0xFFB00000 higherKernelEntry: + lgdt [newGDT] mov ebx, [ebxStart] push ebx .cleanOriginalEntryCode: diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..83d6d16 --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,6 @@ +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +extern void registerInterrupts(); + +#endif diff --git a/src/kernel/interrupts/interruptDescriptors.asm b/src/kernel/interrupts/interruptDescriptors.asm new file mode 100644 index 0000000..6ec652c --- /dev/null +++ b/src/kernel/interrupts/interruptDescriptors.asm @@ -0,0 +1,56 @@ +section .sharedFunctions + +handleInterrupt: + mov eax, 8 + jmp $ + +%macro interruptHandler 1 + ALIGN 4 + global idtHandler%1 +idtHandler%1: + mov ebx, %1 + xor ecx, ecx + jmp handleInterrupt +%endmacro + +%macro interruptHandlerError 1 + align 4 + global idtHandler%1 +idtHandler%1: + pop ecx + mov ebx, %1 + jmp handleInterrupt +%endmacro + +interruptHandler 0 +interruptHandler 1 +interruptHandler 2 +interruptHandler 3 +interruptHandler 4 +interruptHandler 5 +interruptHandler 6 +interruptHandler 7 +interruptHandlerError 8 +interruptHandler 9 +interruptHandlerError 10 +interruptHandlerError 11 +interruptHandlerError 12 +interruptHandlerError 13 +interruptHandlerError 14 +interruptHandler 15 +interruptHandler 16 +interruptHandlerError 17 +interruptHandler 18 +interruptHandler 19 +interruptHandler 20 +interruptHandler 21 +interruptHandler 22 +interruptHandler 23 +interruptHandler 24 +interruptHandler 25 +interruptHandler 26 +interruptHandler 27 +interruptHandler 28 +interruptHandler 29 +interruptHandlerError 30 +interruptHandler 31 diff --git a/src/kernel/interrupts/interrupts.c b/src/kernel/interrupts/interrupts.c new file mode 100644 index 0000000..4976243 --- /dev/null +++ b/src/kernel/interrupts/interrupts.c @@ -0,0 +1,30 @@ +#include "interrupts.h" +#include +#include + +#define IDT_ENTRY(i) \ + idtEntries[i].offsetLow = U32(&idtHandler##i) & 0xFFFF; \ + idtEntries[i].offsetHigh = U32(&idtHandler##i) >> 16; + +extern void *idt; + +__attribute__((section(".sharedFunction"))) __attribute__((aligned(0x10))) +IdtEntry idtEntries[256] = {}; + +void registerInterrupts() { + for (uint16_t i = 0; i < 16; i++) { + idtEntries[i].reserved = 0; + idtEntries[i].type = 0x8E; + idtEntries[i].segment = 0x8; + } + TIMES(IDT_ENTRY); + InterruptTablePointer pointer = { + .base = U32(&idtEntries), + .limit = sizeof(idtEntries) - 1, + }; + asm("lidt %0" ::"m"(pointer)); + asm("mov $0xFF, %%al" ::); + asm("out %%al, $0xA1" ::); + asm("out %%al, $0x21" ::); + asm("sti"); +} diff --git a/src/kernel/interrupts/interrupts.h b/src/kernel/interrupts/interrupts.h new file mode 100644 index 0000000..dbac9d8 --- /dev/null +++ b/src/kernel/interrupts/interrupts.h @@ -0,0 +1,282 @@ +#ifndef INTERRUPTS_PRIVATE_H +#define INTERRUPTS_PRIVATE_H + +#include + +typedef struct InterruptDescriptor32 { + uint16_t offsetLow; + uint16_t segment; + uint8_t reserved; + uint8_t type; + uint16_t offsetHigh; +} __attribute__((packed)) IdtEntry; + +typedef struct { + uint16_t limit; + uint32_t base; +} __attribute__((packed)) InterruptTablePointer; + +// sorry +#define TIMES(x) \ + x(0); \ + x(1); \ + x(2); \ + x(3); \ + x(4); \ + x(5); \ + x(6); \ + x(7); \ + x(8); \ + x(9); \ + x(10); \ + x(11); \ + x(12); \ + x(13); \ + x(14); \ + x(15); \ + x(16); \ + x(17); \ + x(18); \ + x(19); \ + x(20); \ + x(21); \ + x(22); \ + x(23); \ + x(24); \ + x(25); \ + x(26); \ + x(27); \ + x(28); \ + x(29); \ + x(30); \ + x(31); \ + x(32); \ + x(33); \ + x(34); \ + x(35); \ + x(36); \ + x(37); \ + x(38); \ + x(39); \ + x(40); \ + x(41); \ + x(42); \ + x(43); \ + x(44); \ + x(45); \ + x(46); \ + x(47); \ + x(48); \ + x(49); \ + x(50); \ + x(51); \ + x(52); \ + x(53); \ + x(54); \ + x(55); \ + x(56); \ + x(57); \ + x(58); \ + x(59); \ + x(60); \ + x(61); \ + x(62); \ + x(63); \ + x(64); \ + x(65); \ + x(66); \ + x(67); \ + x(68); \ + x(69); \ + x(70); \ + x(71); \ + x(72); \ + x(73); \ + x(74); \ + x(75); \ + x(76); \ + x(77); \ + x(78); \ + x(79); \ + x(80); \ + x(81); \ + x(82); \ + x(83); \ + x(84); \ + x(85); \ + x(86); \ + x(87); \ + x(88); \ + x(89); \ + x(90); \ + x(91); \ + x(92); \ + x(93); \ + x(94); \ + x(95); \ + x(96); \ + x(97); \ + x(98); \ + x(99); \ + x(100); \ + x(101); \ + x(102); \ + x(103); \ + x(104); \ + x(105); \ + x(106); \ + x(107); \ + x(108); \ + x(109); \ + x(110); \ + x(111); \ + x(112); \ + x(113); \ + x(114); \ + x(115); \ + x(116); \ + x(117); \ + x(118); \ + x(119); \ + x(120); \ + x(121); \ + x(122); \ + x(123); \ + x(124); \ + x(125); \ + x(126); \ + x(127); \ + x(128); \ + x(129); \ + x(130); \ + x(131); \ + x(132); \ + x(133); \ + x(134); \ + x(135); \ + x(136); \ + x(137); \ + x(138); \ + x(139); \ + x(140); \ + x(141); \ + x(142); \ + x(143); \ + x(144); \ + x(145); \ + x(146); \ + x(147); \ + x(148); \ + x(149); \ + x(150); \ + x(151); \ + x(152); \ + x(153); \ + x(154); \ + x(155); \ + x(156); \ + x(157); \ + x(158); \ + x(159); \ + x(160); \ + x(161); \ + x(162); \ + x(163); \ + x(164); \ + x(165); \ + x(166); \ + x(167); \ + x(168); \ + x(169); \ + x(170); \ + x(171); \ + x(172); \ + x(173); \ + x(174); \ + x(175); \ + x(176); \ + x(177); \ + x(178); \ + x(179); \ + x(180); \ + x(181); \ + x(182); \ + x(183); \ + x(184); \ + x(185); \ + x(186); \ + x(187); \ + x(188); \ + x(189); \ + x(190); \ + x(191); \ + x(192); \ + x(193); \ + x(194); \ + x(195); \ + x(196); \ + x(197); \ + x(198); \ + x(199); \ + x(200); \ + x(201); \ + x(202); \ + x(203); \ + x(204); \ + x(205); \ + x(206); \ + x(207); \ + x(208); \ + x(209); \ + x(210); \ + x(211); \ + x(212); \ + x(213); \ + x(214); \ + x(215); \ + x(216); \ + x(217); \ + x(218); \ + x(219); \ + x(220); \ + x(221); \ + x(222); \ + x(223); \ + x(224); \ + x(225); \ + x(226); \ + x(227); \ + x(228); \ + x(229); \ + x(230); \ + x(231); \ + x(232); \ + x(233); \ + x(234); \ + x(235); \ + x(236); \ + x(237); \ + x(238); \ + x(239); \ + x(240); \ + x(241); \ + x(242); \ + x(243); \ + x(244); \ + x(245); \ + x(246); \ + x(247); \ + x(248); \ + x(249); \ + x(250); \ + x(251); \ + x(252); \ + x(253); \ + x(254); \ + x(255); + +#define defineExtern(i) extern void *idtHandler##i; + +TIMES(defineExtern) + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f8b6f03..40bb13c 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -48,9 +49,11 @@ // multiboot-loaded stuff loadAndScheduleLoader(multibootInfo); setupSyscalls(); + registerInterrupts(); while (1) { Syscall *call = listPopFirst(&callsToProcess); if (!call) { + int x = 1 / 0; asm("hlt"); continue; } diff --git a/src/kernel/service/services.c b/src/kernel/service/services.c index db0251e..f15c6fd 100644 --- a/src/kernel/service/services.c +++ b/src/kernel/service/services.c @@ -6,6 +6,7 @@ #include extern void *functionsStart; +extern void *functionsEnd; extern void(runFunction)(); ListElement *services, *callsToProcess; @@ -29,8 +30,12 @@ memset(service, 0, sizeof(Service)); service->pagingInfo.pageDirectory = malloc(0x1000); service->name = serviceName; - // todo: make this unwritable! - sharePage(&(service->pagingInfo), &functionsStart, &functionsStart); + void *current = &functionsStart; + while (current <= (void *)&functionsEnd) { + // todo: make this unwritable! + sharePage(&(service->pagingInfo), current, current); + current += 0x1000; + } for (uint32_t i = 0; i < header->programHeaderEntryCount; i++) { for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) {