Skip to content

Commit

Permalink
First syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
taikiy committed Dec 29, 2023
1 parent 2020d58 commit 459b80a
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 42 deletions.
4 changes: 3 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion doc/13_calling_kernel_space_routines_from_user_space.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
4 changes: 3 additions & 1 deletion programs/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
all:
$(MAKE) -C blank
$(MAKE) -C syscall

clean:
$(MAKE) -C blank clean
$(MAKE) -C blank clean
$(MAKE) -C syscall clean
35 changes: 35 additions & 0 deletions programs/syscall/Makefile
Original file line number Diff line number Diff line change
@@ -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)
31 changes: 31 additions & 0 deletions programs/syscall/src/linker.ld
Original file line number Diff line number Diff line change
@@ -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)
}
}
10 changes: 10 additions & 0 deletions programs/syscall/src/syscall.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[BITS 32]

section .asm

global _start

_start:
mov eax, 0 ; sys_print
int 0x80 ; call kernel
jmp $
34 changes: 1 addition & 33 deletions src/idt/idt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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)
{
Expand Down
3 changes: 0 additions & 3 deletions src/idt/idt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
21 changes: 18 additions & 3 deletions src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -21,15 +22,15 @@ 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)
{
print("PANIC: ");
print(message);
print("\n");
while (1) {
};
while (1) {};
}

static struct paging_map* kernel_page = 0;
Expand Down Expand Up @@ -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();
Expand All @@ -75,14 +78,26 @@ kernel_main()
// TESTS
// test_path_parser();
// test_file_system();
test_user_space();
// test_user_space();
test_syscall();

print("...enabling interrupts\n");
enable_interrupts();

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()
{
Expand Down
50 changes: 50 additions & 0 deletions src/system/syscall.c
Original file line number Diff line number Diff line change
@@ -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;
}
17 changes: 17 additions & 0 deletions src/system/syscall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef SYSCALL_H
#define SYSCALL_H

#include "idt/idt.h"
#include <stdint.h>

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

0 comments on commit 459b80a

Please sign in to comment.