diff options
author | Benji Dial <benji6283@gmail.com> | 2020-09-06 00:48:07 -0400 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2020-09-06 00:48:07 -0400 |
commit | e8c6577617bffa4402c07c7aa20e3c24f03c1c20 (patch) | |
tree | 2fb9230b62d2344a44453117de9e656892219788 /src/kernel/idt.c | |
parent | 7ff724fe8f709440da9c730fdb8dcbaa4f989ed5 (diff) | |
download | portland-os-e8c6577617bffa4402c07c7aa20e3c24f03c1c20.tar.gz |
program loading, others
big kernel additions: paging, elf loading, separate kernel and user page allocation
it now properly loads and runs sd0:bin/init.elf
still need to determine which disk was booted from, and start the init on that disk
Diffstat (limited to 'src/kernel/idt.c')
-rw-r--r-- | src/kernel/idt.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/kernel/idt.c b/src/kernel/idt.c new file mode 100644 index 0000000..460cfb0 --- /dev/null +++ b/src/kernel/idt.c @@ -0,0 +1,116 @@ +#include "drive.h" +#include "elf.h" +#include "util.h" +#include "idt.h" +#include "log.h" +#include "panic.h" +#include "task.h" +#include "paging.h" + +enum { + IDT_PRESENT = 0x80, + + IDT_INT = 0x0e, + IDT_TRAP = 0x0f +}; + +struct idt_entry { + uint16_t addr_low; + uint16_t cs; + uint8_t zero; + uint8_t flags; + uint16_t addr_high; +} __attribute__ ((packed)); + +struct idt_entry idt[256]; + +struct { + uint16_t limit; + uint32_t start; +} __attribute__ ((packed)) idtr = { + .limit = 256 * sizeof(struct idt_entry) - 1, + .start = (uint32_t)idt +}; + +//file handles as (drive_number << 8) + file_id_t + +static uint32_t sc_open_file(uint32_t drive_number, char *path) { + return (drive_number << 8) + drives[drive_number].get_file(drives + drive_number, path); +} + +static void sc_close_file(uint32_t handle) { + drives[handle >> 8].free_file(drives + (handle >> 8), handle & 0xff); +} + +static uint32_t sc_file_get_size(uint32_t handle) { + return drives[handle >> 8].get_file_length(drives + (handle >> 8), handle & 0xff); +} + +static uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t count, void *buffer) { + uint32_t len = sc_file_get_size(handle); + if (file_offset + count > len) + count = len - file_offset; + fmcpy(buffer, drives + (handle >> 8), handle & 0xff, file_offset, count); + return count; +} + +static bool sc_start_task(uint32_t drive_number, char *path) { + switch_to_kernel_cr3(); + bool result = try_elf_run(drives + drive_number, path); + switch_to_task_cr3(); + return result; +} + +static void sc_log_string(char *sz) { + logsz(sz); +} + +static char sc_get_key() { + panic("TODO: get key system call"); +} + +static void *sc_allocate_ram(uint32_t pages) { +//switch_to_kernel_cr3(); + void *result = pd_user_allocate_anywhere_writable(active_task->page_directory, pages); +//switch_to_task_cr3(); +} + +void const *syscall_table[] = { + &sc_open_file, + &sc_close_file, + &sc_file_read, + &sc_file_get_size, + &sc_start_task, + &sc_log_string, + &sc_get_key, + &sc_allocate_ram +}; + +extern void syscall_isr; +extern void quit_isr; +extern void yield_isr; + +void register_int(uint8_t n, void *isr, uint8_t dpl) { + idt[n].addr_low = (uint32_t)isr & 0xffff; + idt[n].addr_high = (uint32_t)isr >> 16; + idt[n].cs = 0x10; + idt[n].flags = IDT_PRESENT | (dpl << 5) | IDT_INT; +} + +void init_idt() { + for (uint16_t i = 0; i < 256; ++i) { + idt[i].flags = 0; + idt[i].zero = 0; + } + + register_int(0x30, &syscall_isr, 3); + register_int(0x38, &quit_isr, 3); + register_int(0x39, &yield_isr, 3); + + outb(0x0021, 0xff); + outb(0x00a1, 0xff); + + asm volatile ( + "lidt %0" + : : "m" (idtr) : "al"); +}
\ No newline at end of file |