diff options
author | Marvin Borner | 2019-12-04 20:38:10 +0100 |
---|---|---|
committer | Marvin Borner | 2019-12-04 20:38:10 +0100 |
commit | ed3da12bb378d82878fff1d50e5e9e7af3d7265d (patch) | |
tree | 53200ca859511e5464bfd50923a3229590997607 | |
parent | e9407b091b34d93014b89660601da62f13df37aa (diff) |
More-working syscall logic (parameters work!)
-rw-r--r-- | src/kernel/boot.asm | 6 | ||||
-rw-r--r-- | src/kernel/fs/install.c | 2 | ||||
-rw-r--r-- | src/kernel/interrupts/idt.asm | 37 | ||||
-rw-r--r-- | src/kernel/interrupts/idt.c | 2 | ||||
-rw-r--r-- | src/kernel/interrupts/interrupts.h | 95 | ||||
-rw-r--r-- | src/kernel/interrupts/irq.asm | 167 | ||||
-rw-r--r-- | src/kernel/interrupts/irq.c | 8 | ||||
-rw-r--r-- | src/kernel/interrupts/isr.asm | 11 | ||||
-rw-r--r-- | src/kernel/interrupts/isr.c | 90 | ||||
-rw-r--r-- | src/kernel/syscall/actions/sys_write.c | 9 | ||||
-rw-r--r-- | src/kernel/syscall/syscall.c | 23 | ||||
-rw-r--r-- | src/kernel/syscall/syscall.h | 4 | ||||
-rw-r--r-- | src/userspace/main.c | 13 | ||||
-rw-r--r-- | src/userspace/start.asm | 13 |
14 files changed, 190 insertions, 290 deletions
diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index fc5a859..8241786 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -50,11 +50,17 @@ section .text push 0x23 push eax pushf + pop eax + or eax, 0x200 + push eax push 0x1B + push ebx mov ebp, ebx iret + pop ebp + ret section .end_section global ASM_KERNEL_END diff --git a/src/kernel/fs/install.c b/src/kernel/fs/install.c index 1d8fe2e..dfb6587 100644 --- a/src/kernel/fs/install.c +++ b/src/kernel/fs/install.c @@ -85,7 +85,7 @@ void install_melvix() info("Installation successful!"); serial_write("Installation successful!\nRebooting...\n"); - timer_wait(200); + // timer_wait(200); acpi_poweroff(); halt_loop(); }
\ No newline at end of file diff --git a/src/kernel/interrupts/idt.asm b/src/kernel/interrupts/idt.asm index f30ead1..cec0e95 100644 --- a/src/kernel/interrupts/idt.asm +++ b/src/kernel/interrupts/idt.asm @@ -3,39 +3,4 @@ global idt_load extern idtp idt_load: lidt [idtp] - ret - -global idt_syscall -extern syscall_handler -idt_syscall: - push ds - push es - push fs - push gs - pushad - - push ecx - push edx - push esi - push edi - push eax - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - - call syscall_handler - - lea ebx, [5 * 4] - add esp, ebx - - mov dword [esp + (7*4)], eax - - popad - pop gs - pop fs - pop es - pop ds - iret + ret
\ No newline at end of file diff --git a/src/kernel/interrupts/idt.c b/src/kernel/interrupts/idt.c index f405ca9..de17c72 100644 --- a/src/kernel/interrupts/idt.c +++ b/src/kernel/interrupts/idt.c @@ -45,4 +45,4 @@ void idt_install() idt_load(); vga_log("Installed Interrupt Descriptor Table", 5); -} +}
\ No newline at end of file diff --git a/src/kernel/interrupts/interrupts.h b/src/kernel/interrupts/interrupts.h index cb30492..10612c0 100644 --- a/src/kernel/interrupts/interrupts.h +++ b/src/kernel/interrupts/interrupts.h @@ -2,6 +2,7 @@ #define MELVIX_INTERRUPTS_H #include <stdint.h> +#include <stddef.h> /** * Initialize the Interrupt Descriptor Table with 256 entries @@ -18,11 +19,6 @@ void idt_install(); void idt_set_gate(unsigned char num, unsigned long base, unsigned short sel, unsigned char flags); /** - * Install 32 exception ISRs into the IDT - */ -void isrs_install(); - -/** * Registers that get passed into an IRQ handler */ struct regs { @@ -33,6 +29,26 @@ struct regs { }; /** + * Install 32 exception ISRs into the IDT + */ +void isrs_install(); + +/** + * Add a new Interrupt Request Handler + * @param irq The index of the IRQ routine + * @param handler The interrupt handler function + */ +typedef void (*irq_handler_t)(struct regs *); + +void isr_install_handler(size_t isr, irq_handler_t handler); + +/** + * Uninstall a handler by index + * @param irq The index of the IRQ routine that should be removed + */ +void isr_uninstall_handler(size_t isr); + +/** * Initialize the Interrupt Requests by mapping the ISRs to the correct * entries in the IDT (install the exception handlers) */ @@ -64,4 +80,71 @@ void irq_handler(struct regs *r); */ int irq_is_installed(int irq); -#endif +// Defined in isr.asm +extern void isr0(); + +extern void isr1(); + +extern void isr2(); + +extern void isr3(); + +extern void isr4(); + +extern void isr5(); + +extern void isr6(); + +extern void isr7(); + +extern void isr8(); + +extern void isr9(); + +extern void isr10(); + +extern void isr11(); + +extern void isr12(); + +extern void isr13(); + +extern void isr14(); + +extern void isr15(); + +extern void isr16(); + +extern void isr17(); + +extern void isr18(); + +extern void isr19(); + +extern void isr20(); + +extern void isr21(); + +extern void isr22(); + +extern void isr23(); + +extern void isr24(); + +extern void isr25(); + +extern void isr26(); + +extern void isr27(); + +extern void isr28(); + +extern void isr29(); + +extern void isr30(); + +extern void isr31(); + +extern void isr128(); + +#endif
\ No newline at end of file diff --git a/src/kernel/interrupts/irq.asm b/src/kernel/interrupts/irq.asm index c485613..f616944 100644 --- a/src/kernel/interrupts/irq.asm +++ b/src/kernel/interrupts/irq.asm @@ -1,136 +1,33 @@ -global irq0 -global irq1 -global irq2 -global irq3 -global irq4 -global irq5 -global irq6 -global irq7 -global irq8 -global irq9 -global irq10 -global irq11 -global irq12 -global irq13 -global irq14 -global irq15 - -; 32: IRQ0 -irq0: - cli - push byte 0 - push byte 32 - jmp irq_common_stub - -; 33: IRQ1 -irq1: - cli - push byte 0 - push byte 33 - jmp irq_common_stub - -; 34: IRQ2 -irq2: - cli - push byte 0 - push byte 34 - jmp irq_common_stub - -; 35: IRQ3 -irq3: - cli - push byte 0 - push byte 35 - jmp irq_common_stub - -; 36: IRQ4 -irq4: - cli - push byte 0 - push byte 36 - jmp irq_common_stub - -; 37: IRQ5 -irq5: - cli - push byte 0 - push byte 37 - jmp irq_common_stub - -; 38: IRQ6 -irq6: - cli - push byte 0 - push byte 38 - jmp irq_common_stub - -; 39: IRQ7 -irq7: - cli - push byte 0 - push byte 39 - jmp irq_common_stub - -; 40: IRQ8 -irq8: - cli - push byte 0 - push byte 40 - jmp irq_common_stub - -; 41: IRQ9 -irq9: - cli - push byte 0 - push byte 41 - jmp irq_common_stub - -; 42: IRQ10 -irq10: - cli - push byte 0 - push byte 42 - jmp irq_common_stub - -; 43: IRQ11 -irq11: - cli - push byte 0 - push byte 43 - jmp irq_common_stub - -; 44: IRQ12 -irq12: - cli - push byte 0 - push byte 44 - jmp irq_common_stub - -; 45: IRQ13 -irq13: - cli - push byte 0 - push byte 45 - jmp irq_common_stub - -; 46: IRQ14 -irq14: - cli - push byte 0 - push byte 46 - jmp irq_common_stub - -; 47: IRQ15 -irq15: - cli - push byte 0 - push byte 47 - jmp irq_common_stub +%macro IRQ 2 + global irq%1 + irq%1: + cli + push byte 0 + push byte %2 + jmp irq_common_stub +%endmacro + +IRQ 0, 32 +IRQ 1, 33 +IRQ 2, 34 +IRQ 3, 35 +IRQ 4, 36 +IRQ 5, 37 +IRQ 6, 38 +IRQ 7, 39 +IRQ 8, 40 +IRQ 9, 41 +IRQ 10, 42 +IRQ 11, 43 +IRQ 12, 44 +IRQ 13, 45 +IRQ 14, 46 +IRQ 15, 47 extern irq_handler - irq_common_stub: pusha + push ds push es push fs @@ -141,17 +38,17 @@ irq_common_stub: mov es, ax mov fs, ax mov gs, ax - mov eax, esp + cld - push eax - mov eax, irq_handler - call eax - pop eax + push esp + call irq_handler + add esp, 4 pop gs pop fs pop es pop ds popa + add esp, 8 - iret + iret
\ No newline at end of file diff --git a/src/kernel/interrupts/irq.c b/src/kernel/interrupts/irq.c index a0a396d..2fae9de 100644 --- a/src/kernel/interrupts/irq.c +++ b/src/kernel/interrupts/irq.c @@ -102,15 +102,13 @@ void irq_handler(struct regs *r) // Execute custom handler if exists handler = irq_routines[r->int_no - 32]; - if (handler) { + if (handler) handler(r); - } // Send end of interrupt to second (slave) IRQ controller - if (r->int_no >= 40) { + if (r->int_no >= 40) outb(0xA0, 0x20); - } // Send end of interrupt to master interrupt controller outb(0x20, 0x20); -} +}
\ No newline at end of file diff --git a/src/kernel/interrupts/isr.asm b/src/kernel/interrupts/isr.asm index adabac6..00d986a 100644 --- a/src/kernel/interrupts/isr.asm +++ b/src/kernel/interrupts/isr.asm @@ -47,28 +47,33 @@ ISR_NOERRCODE 28 ISR_NOERRCODE 29 ISR_NOERRCODE 30 ISR_NOERRCODE 31 +ISR_NOERRCODE 128 extern fault_handler isr_common_stub: -push ds + pusha + + push ds push es push fs push gs - pusha mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax + cld push esp call fault_handler add esp, 4 - popa pop gs pop fs pop es pop ds + popa + + add esp, 8 iret
\ No newline at end of file diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c index 106cac8..7a4d3f4 100644 --- a/src/kernel/interrupts/isr.c +++ b/src/kernel/interrupts/isr.c @@ -5,73 +5,6 @@ #include <kernel/io/io.h> #include <mlibc/string.h> -// Defined in isr.asm -extern void isr0(); - -extern void isr1(); - -extern void isr2(); - -extern void isr3(); - -extern void isr4(); - -extern void isr5(); - -extern void isr6(); - -extern void isr7(); - -extern void isr8(); - -extern void isr9(); - -extern void isr10(); - -extern void isr11(); - -extern void isr12(); - -extern void isr13(); - -extern void isr14(); - -extern void isr15(); - -extern void isr16(); - -extern void isr17(); - -extern void isr18(); - -extern void isr19(); - -extern void isr20(); - -extern void isr21(); - -extern void isr22(); - -extern void isr23(); - -extern void isr24(); - -extern void isr25(); - -extern void isr26(); - -extern void isr27(); - -extern void isr28(); - -extern void isr29(); - -extern void isr30(); - -extern void isr31(); - -uint32_t ignored_isr[8] = {0}; - // Install ISRs in IDT void isrs_install() { @@ -111,9 +44,25 @@ void isrs_install() idt_set_gate(30, (unsigned) isr30, 0x08, 0x8E); idt_set_gate(31, (unsigned) isr31, 0x08, 0x8E); + idt_set_gate(0x80, (unsigned) isr128, 0x08, 0xEE); + vga_log("Installed Interrupt Service Routines", 6); } +irq_handler_t isr_routines[256] = {0}; + +// Install custom IRQ handler +void isr_install_handler(size_t isr, irq_handler_t handler) +{ + isr_routines[isr] = handler; +} + +// Removes the custom IRQ handler +void isr_uninstall_handler(size_t isr) +{ + isr_routines[isr] = 0; +} + // Error exception messages const char *exception_messages[] = { "Division By Zero", @@ -156,7 +105,10 @@ const char *exception_messages[] = { // Master exception/interrupt/fault handler - halt via panic void fault_handler(struct regs *r) { - if (r->int_no < 32) { + irq_handler_t handler = isr_routines[r->int_no]; + if (handler) { + handler(r); + } else { uint32_t faulting_address; asm ("mov %%cr2, %0" : "=r" (faulting_address)); @@ -187,4 +139,4 @@ void fault_handler(struct regs *r) strcat(message, " Exception"); panic(message); } -} +}
\ No newline at end of file diff --git a/src/kernel/syscall/actions/sys_write.c b/src/kernel/syscall/actions/sys_write.c index fceaaab..19c35fa 100644 --- a/src/kernel/syscall/actions/sys_write.c +++ b/src/kernel/syscall/actions/sys_write.c @@ -2,10 +2,11 @@ #include <mlibc/stdio.h> #include <kernel/io/io.h> -uint32_t sys_write(char *buf, uint32_t count) +uint32_t sys_write(unsigned int buf, unsigned int count) { - serial_write("WRITE"); - for (uint32_t i = 0; i < count; i++) - writec(*(buf++)); + serial_write("\n"); + serial_write_dec(count); + serial_write("WRITE: \n"); + serial_write((const char *) buf); return count; }
\ No newline at end of file diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c index bb32965..08b4d49 100644 --- a/src/kernel/syscall/syscall.c +++ b/src/kernel/syscall/syscall.c @@ -3,20 +3,19 @@ #include <kernel/interrupts/interrupts.h> #include <kernel/io/io.h> -void syscalls_install() -{ - // 11100111 - idt_set_gate(0x80, (unsigned) idt_syscall, 0x08, 0xEE); -} +typedef uint32_t (*syscall_func)(unsigned int, ...); -uint32_t syscall_handler(uint32_t id, uint32_t arg0, uint32_t arg1, uint32_t arg2) +void syscall_handler(struct regs *r) { serial_write("Received syscall!\n"); + serial_write_dec(r->eax); + serial_write("\n"); + serial_write_dec(r->ecx); + syscall_func location = (syscall_func) sys_write; + location(r->ebx, r->ecx, r->edx, r->esi, r->edi); +} - switch (id) { - case 1: - return sys_write((char *) arg0, arg1); - } - - return -1; +void syscalls_install() +{ + isr_install_handler(0x80, syscall_handler); }
\ No newline at end of file diff --git a/src/kernel/syscall/syscall.h b/src/kernel/syscall/syscall.h index 304008d..8730dbf 100644 --- a/src/kernel/syscall/syscall.h +++ b/src/kernel/syscall/syscall.h @@ -5,6 +5,6 @@ extern void idt_syscall(); void syscalls_install(); -uint32_t sys_write(char *buf, uint32_t count); +uint32_t sys_write(unsigned int buf, unsigned int count); -#endif +#endif
\ No newline at end of file diff --git a/src/userspace/main.c b/src/userspace/main.c index 22bb42a..5df961f 100644 --- a/src/userspace/main.c +++ b/src/userspace/main.c @@ -1,10 +1,15 @@ -#include <stddef.h> - -extern void syscall(); +void write(const char *str, int len) +{ + int ret; + asm volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (ret) \ + : "0" (1), "b" ((int) (str)), "c"((int) (len))); +} void user_main() { - syscall(); + const char hello[] = "Switched to usermode!\n"; + write(hello, sizeof(hello)); while (1) {}; }
\ No newline at end of file diff --git a/src/userspace/start.asm b/src/userspace/start.asm index 498f5f5..488101c 100644 --- a/src/userspace/start.asm +++ b/src/userspace/start.asm @@ -8,15 +8,4 @@ section .text _start: mov esp, ebp call user_main - - global syscall - syscall: - mov eax, 1 - lea edi, [ebp+welcome] - mov esi, welcome_sz - int 0x80 - ret - -section .data - welcome db "Welcome to the userspace", 0x0A, 0x0A - welcome_sz equ $ - welcome
\ No newline at end of file + jmp $
\ No newline at end of file |