kernel

hobby kernel
git clone git://git.evenfri.duckdns.org/kernel.git
Log | Files | Refs | README | LICENSE

commit 706e95f994b9d474d9a784683273b55a63c24b2f
parent d4f6abb9a55834c28d95bb2c6d951ec897606c0d
Author: evenfri <evenfri256@gmail.com>
Date:   Sun,  2 Aug 2026 22:46:02 +0800

feat: syscalls, test directory

Diffstat:
Mboot.asm | 11++++++++++-
Mdat.h | 6+++++-
Mfns.h | 3+++
Minit.c | 9+++++++--
Mmkfile | 6++++--
Mqemu.sh | 6++++--
Asyscall.c | 20++++++++++++++++++++
Asyscall_entry.asm | 29+++++++++++++++++++++++++++++
Atest/mkfile | 12++++++++++++
Atest/syscalls.c | 38++++++++++++++++++++++++++++++++++++++
Mvga.c | 1-
11 files changed, 132 insertions(+), 9 deletions(-)

diff --git a/boot.asm b/boot.asm @@ -20,16 +20,25 @@ stack_top: section .text global _start +extern multiboot extern start_kernel _start: ; setup stack mov esp, stack_top - ; enter the high-level kernel + ; set arguments push ebx push eax + call multiboot + + ; reset arguments + add esp, 8 + xor eax, eax + xor ebx, ebx + + ; enter the high-level kernel call start_kernel cli diff --git a/dat.h b/dat.h @@ -7,7 +7,7 @@ /* vga */ #define vga_width 80 #define vga_height 25 -#define vga_start 0xb8000 +#define vga_start 0xb8000 #define vga_ctrl 0x3d4 #define vga_data 0x3d5 @@ -62,4 +62,8 @@ typedef void (*int_handler)(); #define stdin 0 #define stdout 1 +/* syscalls */ +#define sys_read 0 +#define sys_write 1 + #endif /* dat_h */ diff --git a/fns.h b/fns.h @@ -57,4 +57,7 @@ void tty_write(const char* data, size_t size); size_t vfs_read(unsigned int fd, void *buf, size_t size); size_t vfs_write(unsigned int fd, void *buf, size_t size); +/* syscall */ +void syscall_init(); + #endif /* fns_h */ diff --git a/init.c b/init.c @@ -2,6 +2,9 @@ #include <fns.h> #include <keyboard/keyboard.h> +extern void test_syscall_write(); +extern size_t test_syscall_read(); + void multiboot(uint32_t magic, multiboot_info_t *mbi) { if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { return; @@ -19,6 +22,9 @@ void init() { idt_init(); vfs_write(stdout, "idt initialized\n", 16); + syscall_init(); + vfs_write(stdout, "syscalls initialized\n", 21); + keyboard_init(); vfs_write(stdout, "keyboard initialized\n", 21); } @@ -36,8 +42,7 @@ void bin_init_prog() { } } -void start_kernel(uint32_t magic, multiboot_info_t *mbi) { - multiboot(magic, mbi); +void start_kernel() { init(); bin_init_prog(); diff --git a/mkfile b/mkfile @@ -7,8 +7,8 @@ cc = ./build/cc ld = ./build/ld ar = ./build/ar -ldflags = keyboard/built-in.a -dirs = keyboard +ldflags = keyboard/built-in.a test/built-in.a +dirs = keyboard test ofiles = boot.$o \ vga.$o \ @@ -17,6 +17,8 @@ ofiles = boot.$o \ ints.$o \ tty.$o \ vfs.$o \ + syscall_entry.$o \ + syscall.$o \ init.$o \ strlen.$o diff --git a/qemu.sh b/qemu.sh @@ -2,6 +2,8 @@ set -e kernel_bin="o.kernel" +mem="4M" -qemu-system-i386 -kernel "$kernel_bin" - +exec qemu-system-i386 \ + -m "$mem" \ + -kernel "$kernel_bin" \ diff --git a/syscall.c b/syscall.c @@ -0,0 +1,20 @@ +#include <dat.h> +#include <fns.h> + +extern void syscall_asm(); + +void syscall_init() { + idt_register(0x80, syscall_asm); +} + +int syscall_handler(int num, int arg1, int arg2, + int arg3, int arg4, int arg5) { + switch (num) { + case sys_read: + return vfs_read(arg1, (void*) arg2, arg3); + case sys_write: + return vfs_write(arg1, (void*) arg2, arg3); + default: + return -1; + } +} diff --git a/syscall_entry.asm b/syscall_entry.asm @@ -0,0 +1,29 @@ +bits 32 + +section .text +global syscall_asm + +extern syscall_handler + +syscall_asm: + ; save 32-bits regs + pushad + + push edi ; arg5 + push esi ; arg4 + push edx ; arg3 + push ecx ; arg2 + push ebx ; arg1 + push eax ; num + + sti + call syscall_handler + cli + + ; clear stack + add esp, 24 + mov [esp + 28], eax + + popad + iret + diff --git a/test/mkfile b/test/mkfile @@ -0,0 +1,12 @@ +<$kernel/build/mkhdr + +as = ../build/as +cc = ../build/cc +ar = ../build/ar + +ofiles = syscalls.$o \ + +lib = built-in.a + +<$kernel/build/mklib +<$kernel/build/mkcommon diff --git a/test/syscalls.c b/test/syscalls.c @@ -0,0 +1,38 @@ +#include <stddef.h> +#include <dat.h> + +typedef long ssize_t; + +#define syscall3(n, arg1, arg2, arg3) ({ \ + long ret; \ + asm volatile ( \ + "int $0x80" \ + : "=a"(ret) \ + : "a"(n), "b"(arg1), "c"(arg2), "d"(arg3) \ + : "memory" \ + ); \ + ret; \ +}) + +size_t write(int fd, void *buf, size_t size) { + long ret = syscall3(sys_write, fd, buf, size); + return ret; +} + +size_t read(int fd, void *buf, size_t size) { + long ret = syscall3(sys_read, fd, buf, size); + return ret; +} + +size_t test_syscall_read() { + char c; + size_t bytes = read(stdin, &c, 1); + + if (bytes > 0) { + write(stdout, &c, 1); + } else { + asm volatile("hlt"); + } + + return bytes; +} diff --git a/vga.c b/vga.c @@ -1,4 +1,3 @@ -#include <stdint.h> #include <dat.h> #include <fns.h>