]> 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..392aa78
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#ifndef SYSCALL_H
+#define SYSCALL_H
+
+#include <stdint.h>
+
+void syscall_init(void);
+
+enum {
+    SYSCALL_WRITE = 1,
+};
+
+#endif
index 9ccf62dfb30804aab01dfe0bc2b44ff620782135..71441e21e273aef7a62b5975a18491557ca0400a 100644 (file)
@@ -35,6 +35,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;
@@ -138,6 +140,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));
     
@@ -207,7 +212,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 337391b458026e84bb3a8504a4d20a4131869ae6..2727f0512ba08e26aec6287b0bb384f9815334bd 100644 (file)
@@ -139,3 +139,6 @@ IRQ 12, 44
 IRQ 13, 45
 IRQ 14, 46
 IRQ 15, 47
+
+/* Syscall vector (int 0x80 -> 128) */
+ISR_NOERRCODE 128
index a0ae130341f4423c27808551f79ab8371bed6d69..8ee5dd12a087f4f03a0cc4db92ddf04f001e187d 100644 (file)
@@ -23,6 +23,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"
@@ -67,6 +69,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..ba9bc55
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#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
+}