From 79a4f79a24905fc323eb3477664482771e6cc657 Mon Sep 17 00:00:00 2001 From: assada Date: Fri, 31 Jan 2025 16:38:38 +0100 Subject: [PATCH] fix userspace? --- boot.s | 23 ++++++++++++++++------- gdt.c | 38 ++++++++++++++++++++++---------------- gdt.h | 38 +++++++++++++++++++++++++++++++++++++- irq.c | 32 ++++++++++++++++---------------- isr.c | 8 +++++++- kernel.c | 37 +++++++++++++++++++++++++++++-------- syscall.c | 35 ++++++++++++++++++++++------------- 7 files changed, 149 insertions(+), 62 deletions(-) diff --git a/boot.s b/boot.s index 792ba00..020043d 100644 --- a/boot.s +++ b/boot.s @@ -1,7 +1,7 @@ .set ALIGN, 1<<0 .set MEMINFO, 1<<1 .set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 /* multiboot 1 */ +.set MAGIC, 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) .section .multiboot @@ -10,7 +10,9 @@ .long FLAGS .long CHECKSUM -.section .stack, "aw", @nobits +.section .bss +.align 16 +.global stack_bottom .global stack_top stack_bottom: .skip 16384 @@ -20,10 +22,17 @@ stack_top: .global _start .type _start, @function _start: - movl $stack_top, %esp + movl $stack_top, %esp + + pushl $0 + popf + + pushl %ebx + + call kernel_main - push %ebx + cli +1: hlt + jmp 1b - call kernel_main -1: - jmp 1b +.size _start, . - _start \ No newline at end of file diff --git a/gdt.c b/gdt.c index a47e4f0..3acdf54 100644 --- a/gdt.c +++ b/gdt.c @@ -25,39 +25,45 @@ static void gdt_set_gate(uint8_t num, uint32_t base, uint32_t limit, uint8_t acc gdt[num].access = access; } -static void tss_install(uint8_t num, uint16_t kernel_ss, uint16_t kernel_esp) +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); + uint32_t limit = sizeof(Tss_entry); memset(&tss, 0, sizeof(Tss_entry)); tss.ss0 = kernel_ss; - tss.esp0 = kernel_esp + 0x1000; // SHIT - - tss.cs = 0x1B; + tss.esp0 = kernel_esp; + + tss.cs = 0x1b; tss.ss = 0x23; - tss.es = 0x23; tss.ds = 0x23; + tss.es = 0x23; tss.fs = 0x23; tss.gs = 0x23; + + tss.iopb_off = sizeof(Tss_entry); + + gdt_set_gate(num, base, limit, I86_GDT_DESC_ACCESS | I86_GDT_DESC_EXEC_CODE | I86_GDT_DESC_DPL | I86_GDT_DESC_MEMORY, 0x00); } void gdt_install() { - gdt_set_gate(0, 0x0, 0x0, 0x0, 0x0); // Null segment - gdt_set_gate(1, 0x0, 0xFFFFFFFF, 0x9A, 0xCF); // 0x08 Kernel code segment - gdt_set_gate(2, 0x0, 0xFFFFFFFF, 0x92, 0xCF); // 0x10 Kernel Data segment - gdt_set_gate(3, 0x0, 0xFFFFFFFF, 0xFA, 0xCF); // 0x18 User code segment - gdt_set_gate(4, 0x0, 0xFFFFFFFF, 0xF2, 0xCF); // 0x20 User data segment - - tss_install(5, 0x10, stack_top); - gdtp.limit = (sizeof(Gdt_entry) * GDT_ENTRY) - 1; gdtp.base = (uint32_t)&gdt; + gdt_set_gate(0, 0, 0, 0, 0); + + gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + + gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + + gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); + + gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); + + tss_install(5, 0x10, (uint32_t)&stack_top); + gdt_flush((uint32_t)&gdtp); tss_flush(); } diff --git a/gdt.h b/gdt.h index c7dc4f9..cd8fdb7 100644 --- a/gdt.h +++ b/gdt.h @@ -3,7 +3,42 @@ #include -extern uint32_t stack_top; +extern void* stack_top; + +//! set access bit +#define I86_GDT_DESC_ACCESS 0x0001 //00000001 + +//! descriptor is readable and writable. default: read only +#define I86_GDT_DESC_READWRITE 0x0002 //00000010 + +//! set expansion direction bit +#define I86_GDT_DESC_EXPANSION 0x0004 //00000100 + +//! executable code segment. Default: data segment +#define I86_GDT_DESC_EXEC_CODE 0x0008 //00001000 + +//! set code or data descriptor. defult: system defined descriptor +#define I86_GDT_DESC_CODEDATA 0x0010 //00010000 + +//! set dpl bits +#define I86_GDT_DESC_DPL 0x0060 //01100000 + +//! set "in memory" bit +#define I86_GDT_DESC_MEMORY 0x0080 //10000000 + +/** gdt descriptor grandularity bit flags ***/ + +//! masks out limitHi (High 4 bits of limit) +#define I86_GDT_GRAND_LIMITHI_MASK 0x0f //00001111 + +//! set os defined bit +#define I86_GDT_GRAND_OS 0x10 //00010000 + +//! set if 32bit. default: 16 bit +#define I86_GDT_GRAND_32BIT 0x40 //01000000 + +//! 4k grandularity. default: none +#define I86_GDT_GRAND_4K 0x80 //10000000 typedef struct gdt_entry_t Gdt_entry; struct gdt_entry_t @@ -58,6 +93,7 @@ struct tss_entry_t uint32_t ldt; uint16_t trap; uint16_t iomap; + uint16_t iopb_off; } __attribute__((packed)); #endif \ No newline at end of file diff --git a/irq.c b/irq.c index 19a9eb4..25b26ef 100644 --- a/irq.c +++ b/irq.c @@ -62,22 +62,22 @@ void irq_install(void) { irq_remap(); - idt_set_gate(32, (uint32_t)irq0, 0x08, 0x8E); - idt_set_gate(33, (uint32_t)irq1, 0x08, 0x8E); - idt_set_gate(34, (uint32_t)irq2, 0x08, 0x8E); - idt_set_gate(35, (uint32_t)irq3, 0x08, 0x8E); - idt_set_gate(36, (uint32_t)irq4, 0x08, 0x8E); - idt_set_gate(37, (uint32_t)irq5, 0x08, 0x8E); - idt_set_gate(38, (uint32_t)irq6, 0x08, 0x8E); - idt_set_gate(39, (uint32_t)irq7, 0x08, 0x8E); - idt_set_gate(40, (uint32_t)irq8, 0x08, 0x8E); - idt_set_gate(41, (uint32_t)irq9, 0x08, 0x8E); - idt_set_gate(42, (uint32_t)irq10, 0x08, 0x8E); - idt_set_gate(43, (uint32_t)irq11, 0x08, 0x8E); - idt_set_gate(44, (uint32_t)irq12, 0x08, 0x8E); - idt_set_gate(45, (uint32_t)irq13, 0x08, 0x8E); - idt_set_gate(46, (uint32_t)irq14, 0x08, 0x8E); - idt_set_gate(47, (uint32_t)irq15, 0x08, 0x8E); + idt_set_gate(32, (uint32_t)irq0, 0x08, 0xEE); + idt_set_gate(33, (uint32_t)irq1, 0x08, 0xEE); + idt_set_gate(34, (uint32_t)irq2, 0x08, 0xEE); + idt_set_gate(35, (uint32_t)irq3, 0x08, 0xEE); + idt_set_gate(36, (uint32_t)irq4, 0x08, 0xEE); + idt_set_gate(37, (uint32_t)irq5, 0x08, 0xEE); + idt_set_gate(38, (uint32_t)irq6, 0x08, 0xEE); + idt_set_gate(39, (uint32_t)irq7, 0x08, 0xEE); + idt_set_gate(40, (uint32_t)irq8, 0x08, 0xEE); + idt_set_gate(41, (uint32_t)irq9, 0x08, 0xEE); + idt_set_gate(42, (uint32_t)irq10, 0x08, 0xEE); + idt_set_gate(43, (uint32_t)irq11, 0x08, 0xEE); + idt_set_gate(44, (uint32_t)irq12, 0x08, 0xEE); + idt_set_gate(45, (uint32_t)irq13, 0x08, 0xEE); + idt_set_gate(46, (uint32_t)irq14, 0x08, 0xEE); + idt_set_gate(47, (uint32_t)irq15, 0x08, 0xEE); sys_enable_interrupts(); } diff --git a/isr.c b/isr.c index 5f69724..6c35ce4 100644 --- a/isr.c +++ b/isr.c @@ -149,7 +149,13 @@ void fault_handler(Stack *registers) terminal_printf("Exception. System Halted!\n"); terminal_printf("Exception: "); terminal_printf(exception_messages[registers->id]); - + terminal_printf("\n"); + terminal_printf("Error code: %d\n", registers->err_code); + terminal_printf("EIP: %x\n", registers->eip); + terminal_printf("CS: %x\n", registers->cs); + terminal_printf("EFLAGS: %x\n", registers->eflags); + terminal_printf("ESP: %x\n", registers->esp); + terminal_printf("SS: %x\n", registers->ss); isr_call_handler(registers); for (;;) diff --git a/kernel.c b/kernel.c index 4d6ce0e..d4af717 100644 --- a/kernel.c +++ b/kernel.c @@ -16,6 +16,7 @@ void kernel_main(void) { + terminal_printf("Kernel start\n"); terminal_initialize(); gdt_install(); @@ -28,22 +29,42 @@ void kernel_main(void) rtc_init(); + terminal_printf("Kernel initialized\n"); + syscall_init(); + terminal_printf("Syscall initialized\n"); + + sys_enable_interrupts(); + terminal_printf("Interrupts enabled\n"); + enter_user_space(); } +enum SYSCALLS { + SYS_GETCHAR = 0, + SYS_GET_TIME, + SYS_HALT, + SYS_PRINTF, + SYS_DELAY, + SYS_CLEAR, + SYS_SHELL_INIT +}; + void main(void) -{ +{ //TODO: Rework user space calls + int ret; for (int i = 1; i < 4; i++) { - terminal_printf("&cTest &7%d\n", i); - delay(200); + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("&cTest &7%d\n"), "c"(i)); + + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_DELAY), "b"(1000)); } - terminal_clear(); - terminal_printf("Welcome to &cDeadOS&7.\n"); - terminal_printf("You are now in user space.\n"); - terminal_printf("Type 'help' for a list of available commands.\n"); + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_CLEAR)); - shell_init(); + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("Welcome to &cDeadOS&7.\n")); + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("You are now in user space.\n")); + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_PRINTF), "b"("Type 'help' for a list of available commands.\n")); + + asm volatile("int $0x80" : "=a"(ret) : "a"(SYS_SHELL_INIT)); } diff --git a/syscall.c b/syscall.c index 1cc0fa2..2957f63 100644 --- a/syscall.c +++ b/syscall.c @@ -7,26 +7,31 @@ #include "tty.h" #include "timer.h" #include "rtc.h" - -#define NB_SYSCALL 3 +#include "shell.h" +#define NB_SYSCALL 7 void *syscalls[NB_SYSCALL] = { keyboard_getchar, get_rtc_time, - - sys_halt}; + sys_halt, + terminal_printf, + delay, + terminal_clear, + shell_init + }; void syscall_handler(Stack *registers) { + if ((registers->cs & 0x3) != 0x3) return; + int sys_index = registers->eax; - - if (sys_index >= NB_SYSCALL) - return; + if (sys_index >= NB_SYSCALL) return; void *function = syscalls[sys_index]; - int ret; - asm volatile(" push %1; \ + int ret; + asm volatile("sti"); + asm volatile (" push %1; \ push %2; \ push %3; \ push %4; \ @@ -37,10 +42,14 @@ void syscall_handler(Stack *registers) 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; + " : "=a" (ret) : + "r" (registers->edi), "r" (registers->esi), + "r" (registers->edx), "r" (registers->ecx), + "r" (registers->ebx), "r" (function)); + + asm volatile("cli"); + + registers->eax = ret; } void syscall_init(void)