diff --git a/kernel/idt.c b/kernel/idt.c index 8dd4a26..41f11e6 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -4,6 +4,7 @@ #define IDT_MAX_DESCRIPTORS 256 #define ATTR_KERN_32 0x8E // active(1), ring 0 (00), interrupt gate(0), 32 bit (1110) +#define ATTR_USER_32 0xEE // active, ring 3, 32bit #define SEGMENT_KERN 0x08 @@ -31,11 +32,11 @@ void* isr_stub_table[256] = { idt_entry idt[IDT_MAX_DESCRIPTORS]; idt_ptr idtr; -void set_idtr(uint8_t vector, void* isr, uint8_t attributes) { +void set_idtr(uint8_t vector, void* isr, uint16_t sel, uint8_t attributes) { idt_entry* desc = &idt[vector]; desc->isr_low = (uint32_t)isr & 0xFFFF; - desc->kernel_cs = SEGMENT_KERN; + desc->selector = SEGMENT_KERN; desc->reserved = 0; desc->attributes = attributes; desc->isr_high = ((uint32_t)isr >> 16) & 0xFFFF; @@ -47,11 +48,14 @@ void init_idt() { for (int i = 0; i < IDT_MAX_DESCRIPTORS; i++) { if (isr_stub_table[i] != 0) { - set_idtr(i, isr_stub_table[i], ATTR_KERN_32); + set_idtr(i, isr_stub_table[i], SEGMENT_KERN, ATTR_KERN_32); } else { - set_idtr(i, 0, 0); + set_idtr(i, 0, SEGMENT_KERN, 0); } } + extern void syscall_handler(); + set_idtr(0x80, syscall_handler, SEGMENT_KERN, ATTR_USER_32); + load_idt(); } \ No newline at end of file diff --git a/kernel/idt.h b/kernel/idt.h index 6f48e90..bba6043 100644 --- a/kernel/idt.h +++ b/kernel/idt.h @@ -4,11 +4,11 @@ #include typedef struct __attribute__((packed)){ - uint16_t isr_low; // The lower 16 bits of the ISR's address - uint16_t kernel_cs; // The GDT segment selector the CPU will load into CS - uint8_t reserved; // Set to 0 - uint8_t attributes;// Type and attributes flags - uint16_t isr_high; // The higher 16 bits of the ISR's address + uint16_t isr_low; + uint16_t selector; + uint8_t reserved; + uint8_t attributes; + uint16_t isr_high; } idt_entry; typedef struct __attribute__((packed)){ diff --git a/kernel/kmain.c b/kernel/kmain.c index 92aff0e..07fa931 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -88,7 +88,7 @@ void load_origin_program(multiboot_info* mbi) { kprintf("program loaded into memory @ [virt] 0x%x\n", elf->e_entry); extern void liftoff(uint32_t entry, uint32_t stack_top); - kprintf("launching origin process"); + kprintf("launching origin process\n"); uint32_t stack_top = 0xBFFFF000 + 4095; liftoff(elf->e_entry, stack_top); } diff --git a/kernel/memory/mm.c b/kernel/memory/mm.c index 494e1c5..d212725 100644 --- a/kernel/memory/mm.c +++ b/kernel/memory/mm.c @@ -25,7 +25,7 @@ static uint8_t memory_bitmap[BITMAP_SIZE]; static void mark_free(uint32_t addr) { uint32_t page_index = addr / PAGE_SIZE; - uint32_t byte_index = page_index / 8; + uint32_t byte_index = page_index / 8; uint32_t bit_index = page_index % 8; memory_bitmap[byte_index] &= ~(1 << bit_index); } diff --git a/kernel/syscall.c b/kernel/syscall.c new file mode 100644 index 0000000..ef4e60e --- /dev/null +++ b/kernel/syscall.c @@ -0,0 +1,27 @@ +#include + +#include "lib/print.h" + +typedef struct registers { + uint32_t gs, fs, es, ds; // Pushed manually + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha + uint32_t int_no, err_code; // Pushed manually + uint32_t eip, cs, eflags, useresp, ss; // Pushed automatically by CPU +} registers_t; + +int32_t sys_vga_text_write(char* buf); + +int32_t syscall(registers_t* regs) { + switch(regs->eax) { + case 1: { + return sys_vga_text_write((char*)regs->ebx); + } + default: + return -1; + } +} + +int32_t sys_vga_text_write(char* buf) { + kprintf(buf); + return 0; +} \ No newline at end of file diff --git a/kernel/syscall_stubs.S b/kernel/syscall_stubs.S new file mode 100644 index 0000000..931e612 --- /dev/null +++ b/kernel/syscall_stubs.S @@ -0,0 +1,36 @@ +.code32 +.global syscall_handler +.extern syscall +syscall_handler: + cli + + push $0 + push $0x80 + + pusha + + push %ds + push %es + push %fs + push %gs + + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + push %esp + call syscall + add $4, %esp + + mov 28(%esp), %eax + + pop %gs + pop %fs + pop %es + pop %ds + + popa + add $8, %esp + iret \ No newline at end of file diff --git a/libc/arch/i686/crt0.S b/libc/arch/i686/crt0.S new file mode 100644 index 0000000..e69de29 diff --git a/libc/include/rock.h b/libc/include/rock.h new file mode 100644 index 0000000..59f6303 --- /dev/null +++ b/libc/include/rock.h @@ -0,0 +1,17 @@ +#ifndef LIBC_ROCK_H +#define LIBC_ROCK_H + +#include + +static inline int32_t syscall(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) { + int32_t ret; + __asm__ __volatile__ ( + "int $0x80" + : "=a" (ret) + : "0" (num), "b" (arg1), "c" (arg2), "d" (arg3) + : "memory" + ); + return ret; +} + +#endif \ No newline at end of file diff --git a/libc/include/string.h b/libc/include/string.h new file mode 100644 index 0000000..ed43a62 --- /dev/null +++ b/libc/include/string.h @@ -0,0 +1,11 @@ +#ifndef LIBC_STRING_H +#define LIBC_STRING_H + +#include + +void* memcpy(void* dst, const void* src, size_t n); +void* memset(void* dst, int c, size_t n); +void* memmove(void* dst, const void* src, size_t n); +int memcmp(const void* s1, const void* s2, size_t n); + +#endif \ No newline at end of file diff --git a/libc/makefile b/libc/makefile new file mode 100644 index 0000000..e69de29 diff --git a/programs/origin.S b/programs/origin.S index b4b9469..049de3c 100644 --- a/programs/origin.S +++ b/programs/origin.S @@ -1,8 +1,16 @@ .code32 + .section .text .global _start _start: mov $1, %eax - add $1, %eax + mov $(message), %ebx + mov $0, %ecx + mov $0, %edx + int $0x80 loop: - jmp loop \ No newline at end of file + jmp loop + +.section .data +message: + .asciz "Hello, Userland!\n"; \ No newline at end of file