extern void irq8(); extern void irq9(); extern void irq10(); extern void irq11();
extern void irq12(); extern void irq13(); extern void irq14(); extern void irq15();
+extern void isr128();
+
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) {
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E);
idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E);
+ // Syscall gate (int 0x80) must be callable from user mode (DPL=3)
+ idt_set_gate(128, (uint32_t)isr128, 0x08, 0xEE);
+
// Load IDT
__asm__ volatile("lidt %0" : : "m"(idtp));
}
// Send EOI (End of Interrupt) to PICs for IRQs (32-47)
- if (regs->int_no >= 32) {
+ if (regs->int_no >= 32 && regs->int_no <= 47) {
if (regs->int_no >= 40) {
outb(0xA0, 0x20); // Slave EOI
}
#include "initrd.h"
#include "fs.h"
+#include "syscall.h"
+
/* Check if the compiler thinks we are targeting the wrong operating system. */
#if defined(__linux__)
#error "You are not using a cross-compiler, you will run into trouble"
// 5. Initialize Interrupts (x86)
uart_print("[AdrOS] Initializing IDT...\n");
idt_init();
+
+ syscall_init();
// 6. Initialize Drivers
keyboard_init();
--- /dev/null
+#include "syscall.h"
+#include "idt.h"
+#include "uart_console.h"
+
+static void syscall_handler(struct registers* regs) {
+ uint32_t syscall_no = regs->eax;
+
+ if (syscall_no == SYSCALL_WRITE) {
+ uint32_t fd = regs->ebx;
+ const char* buf = (const char*)regs->ecx;
+ uint32_t len = regs->edx;
+
+ if (fd != 1 && fd != 2) {
+ regs->eax = (uint32_t)-1;
+ return;
+ }
+
+ for (uint32_t i = 0; i < len; i++) {
+ char c = buf[i];
+ uart_put_char(c);
+ }
+
+ regs->eax = len;
+ return;
+ }
+
+ regs->eax = (uint32_t)-1;
+}
+
+void syscall_init(void) {
+#if defined(__i386__)
+ register_interrupt_handler(128, syscall_handler);
+#endif
+}