]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
x86: add int 0x80 syscall gate and minimal sys_write
authorTulio A M Mendes <[email protected]>
Thu, 5 Feb 2026 19:41:37 +0000 (16:41 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 5 Feb 2026 19:41:37 +0000 (16:41 -0300)
include/syscall.h [new file with mode: 0644]
src/arch/x86/idt.c
src/arch/x86/interrupts.S
src/kernel/main.c
src/kernel/syscall.c [new file with mode: 0644]

diff --git a/include/syscall.h b/include/syscall.h
new file mode 100644 (file)
index 0000000..863f179
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef SYSCALL_H
+#define SYSCALL_H
+
+#include <stdint.h>
+
+void syscall_init(void);
+
+enum {
+    SYSCALL_WRITE = 1,
+};
+
+#endif
index 8bef4bcae60d77a2d703abfac27095892692235f..6b80a80a262e0d1b6cab549918ae5b18b66bb033 100644 (file)
@@ -26,6 +26,8 @@ extern void irq4(); extern void irq5(); extern void irq6(); extern void irq7();
 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;
@@ -129,6 +131,9 @@ void idt_init(void) {
     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));
     
@@ -198,7 +203,7 @@ void isr_handler(struct registers* regs) {
     }
     
     // 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
         }
index 7f9998198bce3c1c60cdc409dce13b998b7a2723..235e31c23b03e8f5748b662b6c53e3e9ffc17cdb 100644 (file)
@@ -130,3 +130,6 @@ IRQ 12, 44
 IRQ 13, 45
 IRQ 14, 46
 IRQ 15, 47
+
+/* Syscall vector (int 0x80 -> 128) */
+ISR_NOERRCODE 128
index 4d9dd9efcbea7fcbdec0182f2e9365146e429107..d418bacfa9d3532a63958d4517361b0c7f4aecbc 100644 (file)
@@ -14,6 +14,8 @@
 #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"
@@ -58,6 +60,8 @@ void kernel_main(unsigned long magic, unsigned long addr) {
     // 5. Initialize Interrupts (x86)
     uart_print("[AdrOS] Initializing IDT...\n");
     idt_init();
+
+    syscall_init();
     
     // 6. Initialize Drivers
     keyboard_init();
diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c
new file mode 100644 (file)
index 0000000..e42d4a3
--- /dev/null
@@ -0,0 +1,34 @@
+#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
+}