diff --git a/Makefile b/Makefile index f3a9fb5..525510e 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ KERNEL = deados.bin ISO = deados.iso SOURCES_C = kernel.c tty.c idt.c timer.c io.c vga.c gdt.c sys.c irq.c isr.c keyboard.c shell.c string.c user_space.c syscall.c -SOURCES_ASM = boot.s idt_load.s gdt_flush.s pit_handler.s irq_e.s isr_e.s +SOURCES_ASM = boot.s idt_load.s gdt_flush.s pit_handler.s irq_e.s isr_e.s tss.s OBJECTS = $(SOURCES_ASM:.s=.o) $(SOURCES_C:.c=.o) ISO_DIR = isodir diff --git a/gdt.c b/gdt.c index 1d4ca72..eddd3ae 100644 --- a/gdt.c +++ b/gdt.c @@ -1,29 +1,69 @@ #include "gdt.h" +#include "string.h" -struct gdt_entry gdt[3]; -struct gdt_ptr gdtp; +#define GDT_ENTRY 6 + +Gdt_entry gdt[GDT_ENTRY]; +Gdt_ptr gdtp; extern void gdt_flush(uint32_t); -void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { - gdt[num].base_low = (base & 0xFFFF); +Tss_entry tss; +extern void tss_flush(void); + +static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity) +{ + gdt[num].base_low = base & 0xFFFF; gdt[num].base_middle = (base >> 16) & 0xFF; gdt[num].base_high = (base >> 24) & 0xFF; - gdt[num].limit_low = (limit & 0xFFFF); - gdt[num].granularity = (limit >> 16) & 0x0F; + gdt[num].limit_low = limit & 0xFFFF; + + gdt[num].granularity = (limit >> 16) & 0xF; + gdt[num].granularity |= (granularity & 0xF0); - gdt[num].granularity |= gran & 0xF0; gdt[num].access = access; } -void gdt_install() { - gdtp.limit = (sizeof(struct gdt_entry) * 3) - 1; +static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp) +{ + uint32_t base = (uint32_t)&tss; + uint32_t limit = base + sizeof(Tss_entry); + + gdt_set_gate(num, base, limit, 0xE9, 0x0); + + memset(&tss, 0, sizeof(Tss_entry)); + + tss.ss0 = kernel_ss; + tss.esp0 = kernel_esp; + + tss.cs = 0x0B; + tss.ss = 0x13; + tss.es = 0x13; + tss.ds = 0x13; + tss.fs = 0x13; + tss.gs = 0x13; +} + +void set_kernel_stack(uint32_t stack) +{ + tss.esp0 = stack; +} + +void gdt_install() +{ + + gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment + gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // Kernel code segment + gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment + gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // User code segment + gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // User data segment + + tss_install(5, 0x10, 0x0); + + gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1; gdtp.base = (uint32_t)&gdt; - gdt_set_gate(0, 0, 0, 0, 0); // Null segment - gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment - gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment - gdt_flush((uint32_t)&gdtp); + tss_flush(); } diff --git a/gdt.h b/gdt.h index 25c63ca..89946f1 100644 --- a/gdt.h +++ b/gdt.h @@ -3,7 +3,9 @@ #include -struct gdt_entry { +typedef struct gdt_entry_t Gdt_entry; +struct gdt_entry_t +{ uint16_t limit_low; uint16_t base_low; uint8_t base_middle; @@ -12,15 +14,48 @@ struct gdt_entry { uint8_t base_high; } __attribute__((packed)); -struct gdt_ptr { +typedef struct gdt_ptr_t Gdt_ptr; +struct gdt_ptr_t +{ uint16_t limit; uint32_t base; } __attribute__((packed)); -extern struct gdt_entry gdt[3]; -extern struct gdt_ptr gdtp; - -void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran); +static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity); void gdt_install(); +void set_kernel_stack(uint32_t stack); + +typedef struct tss_entry_t Tss_entry; +struct tss_entry_t +{ + uint32_t prevTss; + uint32_t esp0; + uint32_t ss0; + uint32_t esp1; + uint32_t ss1; + uint32_t esp2; + uint32_t ss2; + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t es; + uint32_t cs; + uint32_t ss; + uint32_t ds; + uint32_t fs; + uint32_t gs; + uint32_t ldt; + uint16_t trap; + uint16_t iomap; +} __attribute__((packed)); + #endif \ No newline at end of file diff --git a/grub.cfg b/grub.cfg index 2038825..1ec4b55 100644 --- a/grub.cfg +++ b/grub.cfg @@ -1,3 +1,6 @@ +default=0 +timeout=0 + menuentry "deadOS" { multiboot /boot/deados.bin } \ No newline at end of file diff --git a/idt.c b/idt.c index fbb6bcd..89f3559 100644 --- a/idt.c +++ b/idt.c @@ -1,10 +1,12 @@ #include "idt.h" #include "io.h" +#include "string.h" #include #define IDT_ENTRIES 256 -struct idt_entry { +struct idt_entry +{ uint16_t base_lo; uint16_t sel; uint8_t always0; @@ -12,7 +14,8 @@ struct idt_entry { uint16_t base_hi; } __attribute__((packed)); -struct idt_ptr { +struct idt_ptr +{ uint16_t limit; uint32_t base; } __attribute__((packed)); @@ -20,7 +23,8 @@ struct idt_ptr { struct idt_entry idt[IDT_ENTRIES]; struct idt_ptr idtp; -void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { +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; idt[num].sel = sel; @@ -28,28 +32,12 @@ void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt[num].flags = flags | 0x60; } -void idt_install() { +void idt_install() +{ idtp.limit = (sizeof(struct idt_entry) * IDT_ENTRIES) - 1; idtp.base = (uint32_t)&idt; + + memset(&idt, 0, sizeof(struct idt_entry) * IDT_ENTRIES); + idt_load(); } - -void pic_remap(int offset1, int offset2) { - unsigned char a1, a2; - - a1 = inb(0x21); - a2 = inb(0xA1); - - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, offset1); - outb(0xA1, offset2); - outb(0x21, 0x04); - outb(0xA1, 0x02); - - outb(0x21, 0x01); - outb(0xA1, 0x01); - - outb(0x21, a1); - outb(0xA1, a2); -} \ No newline at end of file diff --git a/kernel.c b/kernel.c index db4538a..d6cccf8 100644 --- a/kernel.c +++ b/kernel.c @@ -18,7 +18,6 @@ void kernel_main(void) gdt_install(); idt_install(); - isr_install(); irq_install(); @@ -26,20 +25,18 @@ void kernel_main(void) keyboard_install(); - sys_enable_interrupts(); - - terminal_printc("Hello, &ekernel &7World!\n&5Magenta String Example\nThis is a &4red string&7.\n"); + terminal_printc("Welcome to &cDeadOS&7.\n"); for (int i = 0; i < 3; i++) { terminal_printc("&cDead &7"); terminal_putchar('0' + (i / 10)); terminal_putchar('0' + (i % 10)); terminal_printc("\n"); - delay(500); + delay(100); } - // syscall_init(); + syscall_init(); - // enter_user_space(); + enter_user_space(); shell_init(); } \ No newline at end of file diff --git a/shell.c b/shell.c index a1869e8..ce8802d 100644 --- a/shell.c +++ b/shell.c @@ -80,7 +80,7 @@ void shell_echo_command(char *input) void shell_parse_input(char *input) { char *command = strtok(input, " \n"); - char *first_param = strtok(NULL, " \n"); + char *args = input + strlen(command) + 1; if (command == NULL || *command == '\0') { @@ -93,7 +93,7 @@ void shell_parse_input(char *input) } else if (strcmp(command, "echo") == 0) { - shell_echo_command(first_param); + shell_echo_command(args); } else if (strcmp(command, "exit") == 0) { diff --git a/string.c b/string.c index 36119de..9b9436c 100644 --- a/string.c +++ b/string.c @@ -1,6 +1,26 @@ #include "string.h" #include +size_t strlen(const char *str) +{ + size_t len = 0; + + while (str[len]) + ++len; + + return len; +} + +void *memset(void *ptr, int value, size_t size) +{ + unsigned char *buf = (unsigned char *)ptr; + + for (size_t i = 0; i < size; ++i) + buf[i] = (unsigned char)value; + + return ptr; +} + int strcmp(const char *str1, const char *str2) { while (*str1 && (*str1 == *str2)) @@ -11,17 +31,17 @@ int strcmp(const char *str1, const char *str2) return *(const unsigned char *)str1 - *(const unsigned char *)str2; } -char *strchr(const char *str, int c) +char *strchr(const char *str, int character) { - while (*str != '\0') + size_t i = 0; + while (str[i] != (char)character) { - if (*str == c) - { - return (char *)str; - } - str++; + if (str[i] == '\0') + return NULL; + ++i; } - return NULL; + + return (char *)(str + i); } char *strtok(char *str, const char *delim) diff --git a/string.h b/string.h index db9d985..048416a 100644 --- a/string.h +++ b/string.h @@ -1,8 +1,13 @@ #ifndef STRING_H #define STRING_H +#include + char *strchr(const char *str, int c); char *strtok(char *str, const char *delim); int strcmp(const char *str1, const char *str2); +size_t strlen(const char *str); + +void *memset(void *ptr, int value, size_t size); #endif \ No newline at end of file diff --git a/syscall.c b/syscall.c index 26eac7b..cad9597 100644 --- a/syscall.c +++ b/syscall.c @@ -1,23 +1,51 @@ #include + #include "interrupts.h" +#include "keyboard.h" +#include "sys.h" #include "syscall.h" #include "tty.h" -void test_syscall() -{ - terminal_printc("Test syscall called\n"); -} +#define NB_SYSCALL 8 + +void *syscalls[NB_SYSCALL] = { + terminal_writestring, + keyboard_getchar, + terminal_printc, + terminal_clear, + terminal_putchar, + terminal_putentryat, + keyboard_clear_buffer, + + sys_halt}; void syscall_handler(Stack *registers) { + terminal_writestring("Syscall\n"); + int sys_index = registers->eax; - if (sys_index != 0) - { + if (sys_index >= NB_SYSCALL) return; - } - test_syscall(); + void *function = syscalls[sys_index]; + + int ret; + asm volatile(" push %1; \ + push %2; \ + push %3; \ + push %4; \ + push %5; \ + call *%6; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + pop %%ebx; \ + " : "=a"(ret) : "r"(registers->edi), "r"(registers->esi), + "r"(registers->edx), "r"(registers->ecx), + "r"(registers->ebx), "r"(function)); + registers->eax = ret; } void syscall_init(void) diff --git a/timer.c b/timer.c index 6a6d1e6..1159cb3 100644 --- a/timer.c +++ b/timer.c @@ -15,6 +15,27 @@ void pit_handler() outb(0x20, 0x20); } +void pic_remap(int offset1, int offset2) +{ + unsigned char a1, a2; + + a1 = inb(0x21); + a2 = inb(0xA1); + + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, offset1); + outb(0xA1, offset2); + outb(0x21, 0x04); + outb(0xA1, 0x02); + + outb(0x21, 0x01); + outb(0xA1, 0x01); + + outb(0x21, a1); + outb(0xA1, a2); +} + void delay(uint32_t milliseconds) { uint32_t end = tick + milliseconds; diff --git a/tss.s b/tss.s new file mode 100644 index 0000000..8e3c53f --- /dev/null +++ b/tss.s @@ -0,0 +1,9 @@ +.section .text +.align 4 + +.global tss_flush +.type tss_flush, @function +tss_flush: + mov $0x2B, %ax + ltr %ax + ret \ No newline at end of file diff --git a/tty.c b/tty.c index 72fb0e9..06420ae 100644 --- a/tty.c +++ b/tty.c @@ -4,14 +4,7 @@ #include #include #include - -size_t strlen(const char *str) -{ - size_t len = 0; - while (str[len]) - len++; - return len; -} +#include "string.h" static const size_t VGA_WIDTH = 80; static const size_t VGA_HEIGHT = 25; diff --git a/user_space.c b/user_space.c index fdc633a..34559bc 100644 --- a/user_space.c +++ b/user_space.c @@ -1,8 +1,10 @@ #include "user_space.h" +#include "gdt.h" void enter_user_space(void) { - asm volatile(" cli; \ + set_kernel_stack(0x110); // 128KB ?? WHY? ?? + asm volatile("cli; \ mov $0x23, %ax; \ mov %ax, %ds; \ mov %ax, %es; \