diff --git a/.clang-format b/.clang-format index aeb7d65..2e709f8 100644 --- a/.clang-format +++ b/.clang-format @@ -1,11 +1,13 @@ # options: https://clang.llvm.org/docs/ClangFormatStyleOptions.html BasedOnStyle: Mozilla -IndentWidth: 4 ColumnLimit: 120 +IndentWidth: 4 + AlignAfterOpenBracket: BlockIndent AlignConsecutiveMacros: true AlignTrailingComments: Kind: Always AllowAllArgumentsOnNextLine: true +AllowShortBlocksOnASingleLine: Empty AlwaysBreakAfterReturnType: AllDefinitions InsertBraces: true diff --git a/Makefile b/Makefile index db07599..46d0475 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ copy: hdiutil attach -imagekey diskimage-class=CRawDiskImage -mount required $(BUILD_DIR)/$(OS_IMG) cp ./hello.txt "/Volumes/taiOS BOOT/" cp $(USR_BIN_DIR)/blank/build/blank.bin "/Volumes/taiOS BOOT/" + cp $(USR_BIN_DIR)/syscall/build/syscall.bin "/Volumes/taiOS BOOT/" hdiutil detach `hdiutil info | tail -n 1 | cut -f 1` usr_bin: diff --git a/doc/13_calling_kernel_space_routines_from_user_space.md b/doc/13_calling_kernel_space_routines_from_user_space.md index 8ad9f2f..8f785b7 100644 --- a/doc/13_calling_kernel_space_routines_from_user_space.md +++ b/doc/13_calling_kernel_space_routines_from_user_space.md @@ -26,4 +26,4 @@ print: ``` - Interrupt 0x80 handler [commit](https://github.com/taikiy/kernel/commit/42c0b6374e21e096060d27e3255a2e007c55b0cd) -- Register 0x80 handler in IDT [commit]() +- Register 0x80 handler in IDT [commit](https://github.com/taikiy/kernel/commit/2020d58d9047f2584ab03d95ccfab2b221ff2ced) diff --git a/programs/Makefile b/programs/Makefile index b25a7a0..6a88798 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -1,5 +1,7 @@ all: $(MAKE) -C blank + $(MAKE) -C syscall clean: - $(MAKE) -C blank clean \ No newline at end of file + $(MAKE) -C blank clean + $(MAKE) -C syscall clean \ No newline at end of file diff --git a/programs/syscall/Makefile b/programs/syscall/Makefile new file mode 100644 index 0000000..f523dc3 --- /dev/null +++ b/programs/syscall/Makefile @@ -0,0 +1,35 @@ +TARGET = syscall.bin +OBJ = syscall.o + +BUILD_DIR = ./build +SRC_DIR = ./src + +LINKER_FILE = $(SRC_DIR)/linker.ld + +ASRCS = $(shell find $(SRC_DIR) -name *.asm) + +AOBJS = $(subst $(SRC_DIR),$(BUILD_DIR),$(ASRCS:.asm=.asm.o)) +OBJS = $(AOBJS) + +CC = i686-elf-gcc +ASM = nasm +LD = i686-elf-ld + +AFLAGS = -f elf -g +CFLAGS = -g -ffreestanding -falign-jumps -falign-functions -falign-labels -falign-loops -fstrength-reduce -fomit-frame-pointer -finline-functions -Wno-unused-function -fno-builtin -Werror -Wno-unused-label -Wno-cpp -Wno-unused-parammeter -nostdlib -nostartfiles -nodefaultlibs -Wall -O0 -Iinc -std=gnu99 +LDFLAGS = -g -relocatable + +all: build + +build: $(BUILD_DIR)/$(TARGET) + +$(BUILD_DIR)/$(TARGET): $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $(BUILD_DIR)/$(OBJ) + $(CC) $(CFLAGS) -T $(SRC_DIR)/linker.ld -o $(BUILD_DIR)/$(TARGET) $(BUILD_DIR)/$(OBJ) + +$(BUILD_DIR)/%.asm.o: $(SRC_DIR)/%.asm + mkdir -p $(dir $@) + $(ASM) $(AFLAGS) $< -o $@ + +clean: + rm -rf $(BUILD_DIR) \ No newline at end of file diff --git a/programs/syscall/src/linker.ld b/programs/syscall/src/linker.ld new file mode 100644 index 0000000..6856c5d --- /dev/null +++ b/programs/syscall/src/linker.ld @@ -0,0 +1,31 @@ +ENTRY(_start) +OUTPUT_FORMAT(binary) +SECTIONS +{ + . = 0x400000; /* USER_PROGRAM_VIRTUAL_ADDRESS_START in config.h */ + .text : ALIGN(4096) + { + *(.text) + } + + .rodata : ALIGN(4096) + { + *(.rodata) + } + + .data : ALIGN(4096) + { + *(.data) + } + + .bss : ALIGN(4096) + { + *(COMMON) + *(.bss) + } + + .asm : ALIGN(4096) + { + *(.asm) + } +} \ No newline at end of file diff --git a/programs/syscall/src/syscall.asm b/programs/syscall/src/syscall.asm new file mode 100644 index 0000000..3c4e1c3 --- /dev/null +++ b/programs/syscall/src/syscall.asm @@ -0,0 +1,10 @@ + [BITS 32] + + section .asm + + global _start + +_start: + mov eax, 0 ; sys_print + int 0x80 ; call kernel + jmp $ \ No newline at end of file diff --git a/src/idt/idt.c b/src/idt/idt.c index c17bd8e..4d6a519 100644 --- a/src/idt/idt.c +++ b/src/idt/idt.c @@ -3,14 +3,13 @@ #include "io/io.h" #include "kernel.h" #include "memory/memory.h" +#include "system/syscall.h" #include "task/task.h" #include "terminal/terminal.h" struct idt_desc idt_descriptors[TOTAL_INTERRUPTS]; struct idtr_desc idtr_descriptor; -static SYSCALL_HANDLER syscall_handlers[TOTAL_SYSCALL_COUNT]; - extern void load_idt(struct idtr_desc* ptr); extern void int_noop(); extern void int21h(); @@ -35,37 +34,6 @@ int21h_handler() outb(0x20, 0x20); } -static void* -syscall(int command, struct interrupt_frame* frame) -{ - void* result = 0; - - if (command < 0 || command >= TOTAL_SYSCALL_COUNT) { - return result; - } - - SYSCALL_HANDLER handler = syscall_handlers[command]; - if (handler) { - result = handler(frame); - } - - return result; -} - -void -register_syscall(int command, SYSCALL_HANDLER handler) -{ - if (command < 0 || command >= TOTAL_SYSCALL_COUNT) { - panic("Invalid syscall command"); - } - - if (syscall_handlers[command]) { - panic("Syscall already registered"); - } - - syscall_handlers[command] = handler; -} - void* isr80h_handler(int command, struct interrupt_frame* frame) { diff --git a/src/idt/idt.h b/src/idt/idt.h index 7fa079e..e219eb6 100644 --- a/src/idt/idt.h +++ b/src/idt/idt.h @@ -41,10 +41,7 @@ struct interrupt_frame uint32_t ss; } __attribute__((packed)); -typedef void* (*SYSCALL_HANDLER)(struct interrupt_frame*); - void initialize_idt(); -void register_syscall(int command, SYSCALL_HANDLER handler); void enable_interrupts(); void disable_interrupts(); diff --git a/src/kernel.c b/src/kernel.c index 8f3e377..8a8180c 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -12,6 +12,7 @@ #include "memory/paging/paging.h" #include "status.h" #include "string/string.h" +#include "system/syscall.h" #include "task/process.h" #include "task/task.h" #include "task/tss.h" @@ -21,6 +22,7 @@ extern void set_kernel_segment_registers(); void test_path_parser(); void test_file_system(); void test_user_space(); +void test_syscall(); void panic(const char* message) @@ -28,8 +30,7 @@ panic(const char* message) print("PANIC: "); print(message); print("\n"); - while (1) { - }; + while (1) {}; } static struct paging_map* kernel_page = 0; @@ -65,6 +66,8 @@ kernel_main() print("...IDT\n"); initialize_idt(); + print("...ISR\n"); + initialize_syscall_handlers(); print("...disks and file systems\n"); initialize_file_systems(); @@ -75,7 +78,8 @@ kernel_main() // TESTS // test_path_parser(); // test_file_system(); - test_user_space(); + // test_user_space(); + test_syscall(); print("...enabling interrupts\n"); enable_interrupts(); @@ -83,6 +87,17 @@ kernel_main() print("End of kernel_main\n"); } +void +test_syscall() +{ + struct process* proc = kzalloc(sizeof(struct process)); + status_t result = create_process("0:/syscall.bin", &proc); + if (result != ALL_OK || !proc) { + panic("Failed to create a process!"); + } + start_tasks(); +} + void test_user_space() { diff --git a/src/system/syscall.c b/src/system/syscall.c new file mode 100644 index 0000000..e48308e --- /dev/null +++ b/src/system/syscall.c @@ -0,0 +1,50 @@ +#include "syscall.h" +#include "config.h" +#include "kernel.h" +#include "terminal/terminal.h" + +static SYSCALL_HANDLER syscall_handlers[TOTAL_SYSCALL_COUNT]; + +void* +sys_print(struct interrupt_frame* frame) +{ + print("sys_print\n"); + return 0; +} + +static void +register_syscall_handler(int command, SYSCALL_HANDLER handler) +{ + if (command < 0 || command >= TOTAL_SYSCALL_COUNT) { + panic("Invalid syscall command"); + } + + if (syscall_handlers[command]) { + panic("Syscall already registered"); + } + + syscall_handlers[command] = handler; +} + +void +initialize_syscall_handlers() +{ + register_syscall_handler(SYSCALL_COMMAND_0_PRINT, sys_print); +} + +void* +syscall(int command, struct interrupt_frame* frame) +{ + void* result = 0; + + if (command < 0 || command >= TOTAL_SYSCALL_COUNT) { + return result; + } + + SYSCALL_HANDLER handler = syscall_handlers[command]; + if (handler) { + result = handler(frame); + } + + return result; +} diff --git a/src/system/syscall.h b/src/system/syscall.h new file mode 100644 index 0000000..2f66bc4 --- /dev/null +++ b/src/system/syscall.h @@ -0,0 +1,17 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +#include "idt/idt.h" +#include + +typedef void* (*SYSCALL_HANDLER)(struct interrupt_frame*); + +enum SYSCALL_COMMAND +{ + SYSCALL_COMMAND_0_PRINT = 0, +}; + +void initialize_syscall_handlers(); +void* syscall(int command, struct interrupt_frame* frame); + +#endif