diff options
author | Benji Dial <benji@benjidial.net> | 2024-01-27 23:14:29 -0500 |
---|---|---|
committer | Benji Dial <benji@benjidial.net> | 2024-01-27 23:14:29 -0500 |
commit | a8a80d326de9550b2a25b1255a2093ab43219ede (patch) | |
tree | d42a800f735caf93679d1728e2d5f20004db3b65 | |
parent | 7199e74aa22e592a3b77bdd81f735edca5470596 (diff) | |
download | hilbert-os-a8a80d326de9550b2a25b1255a2093ab43219ede.tar.gz |
keyboard input
-rw-r--r-- | applications/init/main.cpp | 17 | ||||
-rw-r--r-- | documentation/keys.txt | 78 | ||||
-rw-r--r-- | documentation/syscalls.txt | 4 | ||||
-rw-r--r-- | kernel/entry.cpp | 19 | ||||
-rw-r--r-- | kernel/include/hilbert/kernel/input.hpp | 26 | ||||
-rw-r--r-- | kernel/include/hilbert/kernel/panic.hpp | 6 | ||||
-rw-r--r-- | kernel/include/hilbert/kernel/utility.hpp | 50 | ||||
-rw-r--r-- | kernel/include/hilbert/kernel/vfile.hpp | 8 | ||||
-rw-r--r-- | kernel/input.cpp | 13 | ||||
-rw-r--r-- | kernel/interrupts.asm | 96 | ||||
-rw-r--r-- | kernel/interrupts.cpp | 111 | ||||
-rw-r--r-- | kernel/panic.cpp | 10 | ||||
-rw-r--r-- | kernel/syscall.cpp | 44 | ||||
-rw-r--r-- | kernel/vfile.cpp | 12 | ||||
-rw-r--r-- | libraries/euler/include/euler/syscall.hpp | 3 | ||||
-rw-r--r-- | libraries/euler/syscall.asm | 6 | ||||
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | skeleton/init/burdon.ppm (renamed from skeleton/assets/burdon.ppm) | 0 | ||||
-rw-r--r-- | skeleton/init/readme.txt (renamed from skeleton/assets/readme.txt) | 0 |
19 files changed, 459 insertions, 46 deletions
diff --git a/applications/init/main.cpp b/applications/init/main.cpp index 06a8203..57ebd02 100644 --- a/applications/init/main.cpp +++ b/applications/init/main.cpp @@ -15,7 +15,7 @@ int main(int, char **) { daguerre::image<daguerre::color24> img; - std::FILE *file = std::fopen("/assets/burdon.ppm", "r"); + std::FILE *file = std::fopen("/init/burdon.ppm", "r"); assert(file != 0); assert(daguerre::try_load_ppm(file, img)); std::fclose(file); @@ -30,6 +30,21 @@ int main(int, char **) { daguerre::copy_image(img, fb, 0, 0, x_off, y_off, width, height); + while (true) { + + uint32_t kp = _syscall_read_key_packet(); + if ((kp & 0x0400ff) == 0x04005a) { + for (unsigned y = 0; y < img.get_height(); ++y) + for (unsigned x = 0; x < img.get_width(); ++x) { + img.get(x, y).r = ~img.get(x, y).r; + img.get(x, y).g = ~img.get(x, y).g; + img.get(x, y).b = ~img.get(x, y).b; + } + daguerre::copy_image(img, fb, 0, 0, x_off, y_off, width, height); + } + + } + return 0; } diff --git a/documentation/keys.txt b/documentation/keys.txt new file mode 100644 index 0000000..1b92afa --- /dev/null +++ b/documentation/keys.txt @@ -0,0 +1,78 @@ +a key packet, as returned by the kernel, is a 32-bit value. the top +13 bits are currently reserved. the next 11 bits are flags as follows: + 0x040000: break (as opposed to make) + 0x020000: num lock is on + 0x010000: caps lock is on + 0x008000: right windows + 0x004000: left windows + 0x002000: right alt + 0x001000: left alt + 0x000800: right ctrl + 0x000400: left ctrl + 0x000200: right shift + 0x000100: left shift +the bottom 8 bits represent the key. for us qwerty, they are: + 0x00: reserved | 0x40: reserved | 0x80: reserved | 0xc0: reserved + 0x01: f9 | 0x41: , / < | 0x81: reserved | 0xc1: reserved + 0x02: reserved | 0x42: k / K | 0x82: reserved | 0xc2: reserved + 0x03: f5 | 0x43: i / I | 0x83: reserved | 0xc3: reserved + 0x04: f3 | 0x44: o / O | 0x84: reserved | 0xc4: reserved + 0x05: f1 | 0x45: 0 / ) | 0x85: reserved | 0xc5: reserved + 0x06: f2 | 0x46: 9 / ( | 0x86: reserved | 0xc6: reserved + 0x07: f12 | 0x47: reserved | 0x87: f7 | 0xc7: reserved + 0x08: reserved | 0x48: reserved | 0x88: reserved | 0xc8: reserved + 0x09: f10 | 0x49: . / > | 0x89: reserved | 0xc9: reserved + 0x0a: f8 | 0x4a: / / ? | 0x8a: reserved | 0xca: numpad / + 0x0b: f6 | 0x4b: l / L | 0x8b: reserved | 0xcb: reserved + 0x0c: f4 | 0x4c: ; / : | 0x8c: reserved | 0xcc: reserved + 0x0d: tab | 0x4d: p / P | 0x8d: reserved | 0xcd: reserved + 0x0e: ` / ~ | 0x4e: - / _ | 0x8e: reserved | 0xce: reserved + 0x0f: reserved | 0x4f: reserved | 0x8f: reserved | 0xcf: reserved + 0x10: reserved | 0x50: reserved | 0x90: reserved | 0xd0: reserved + 0x11: left alt | 0x51: reserved | 0x91: right alt | 0xd1: reserved + 0x12: left shift | 0x52: ' / " | 0x92: | 0xd2: reserved + 0x13: reserved | 0x53: reserved | 0x93: reserved | 0xd3: reserved + 0x14: left ctrl | 0x54: [ / { | 0x94: right ctrl | 0xd4: reserved + 0x15: q / Q | 0x55: = / + | 0x95: reserved | 0xd5: reserved + 0x16: 1 / ! | 0x56: reserved | 0x96: reserved | 0xd6: reserved + 0x17: reserved | 0x57: reserved | 0x97: reserved | 0xd7: reserved + 0x18: reserved | 0x58: caps lock | 0x98: reserved | 0xd8: reserved + 0x19: reserved | 0x59: right shift | 0x99: reserved | 0xd9: reserved + 0x1a: z / Z | 0x5a: enter | 0x9a: reserved | 0xda: numpad enter + 0x1b: s / S | 0x5b: ] / } | 0x9b: reserved | 0xdb: reserved + 0x1c: a / A | 0x5c: reserved | 0x9c: reserved | 0xdc: reserved + 0x1d: w / W | 0x5d: \ / | | 0x9d: reserved | 0xdd: reserved + 0x1e: 2 / @ | 0x5e: reserved | 0x9e: reserved | 0xde: reserved + 0x1f: reserved | 0x5f: reserved | 0x9f: left win | 0xdf: reserved + 0x20: reserved | 0x60: reserved | 0xa0: reserved | 0xe0: print screen + 0x21: c / C | 0x61: reserved | 0xa1: reserved | 0xe1: pause + 0x22: x / X | 0x62: reserved | 0xa2: reserved | 0xe2: reserved + 0x23: d / D | 0x63: reserved | 0xa3: reserved | 0xe3: reserved + 0x24: e / E | 0x64: reserved | 0xa4: reserved | 0xe4: reserved + 0x25: 4 / $ | 0x65: reserved | 0xa5: reserved | 0xe5: reserved + 0x26: 3 / # | 0x66: backspace | 0xa6: reserved | 0xe6: reserved + 0x27: reserved | 0x67: reserved | 0xa7: right win | 0xe7: reserved + 0x28: reserved | 0x68: reserved | 0xa8: reserved | 0xe8: reserved + 0x29: space | 0x69: numpad 1 | 0xa9: reserved | 0xe9: end + 0x2a: v / V | 0x6a: reserved | 0xaa: reserved | 0xea: reserved + 0x2b: f / F | 0x6b: numpad 4 | 0xab: reserved | 0xeb: cursor left + 0x2c: t / T | 0x6c: numpad 7 | 0xac: reserved | 0xec: home + 0x2d: r / R | 0x6d: reserved | 0xad: reserved | 0xed: reserved + 0x2e: 5 / % | 0x6e: reserved | 0xae: reserved | 0xee: reserved + 0x2f: reserved | 0x6f: reserved | 0xaf: menu | 0xef: reserved + 0x30: reserved | 0x70: numpad 0 | 0xb0: reserved | 0xf0: insert + 0x31: n / N | 0x71: numpad . | 0xb1: reserved | 0xf1: delete + 0x32: b / B | 0x72: numpad 2 | 0xb2: reserved | 0xf2: cursor down + 0x33: h / H | 0x73: numpad 5 | 0xb3: reserved | 0xf3: reserved + 0x34: g / G | 0x74: numpad 6 | 0xb4: reserved | 0xf4: cursor right + 0x35: y / Y | 0x75: numpad 8 | 0xb5: reserved | 0xf5: cursor up + 0x36: 6 / ^ | 0x76: escape | 0xb6: reserved | 0xf6: reserved + 0x37: reserved | 0x77: num lock | 0xb7: reserved | 0xf7: reserved + 0x38: reserved | 0x78: f11 | 0xb8: reserved | 0xf8: reserved + 0x39: reserved | 0x79: numpad + | 0xb9: reserved | 0xf9: reserved + 0x3a: m / M | 0x7a: numpad 3 | 0xba: reserved | 0xfa: page down + 0x3b: j / J | 0x7b: numpad - | 0xbb: reserved | 0xfb: reserved + 0x3c: u / U | 0x7c: numpad * | 0xbc: reserved | 0xfc: reserved + 0x3d: 7 / & | 0x7d: numpad 9 | 0xbd: reserved | 0xfd: page up + 0x3e: 8 / * | 0x7e: scroll lock | 0xbe: reserved | 0xfe: reserved + 0x3f: reserved | 0x7f: reserved | 0xbf: reserved | 0xff: reserved diff --git a/documentation/syscalls.txt b/documentation/syscalls.txt index 10bf2a9..15aabfa 100644 --- a/documentation/syscalls.txt +++ b/documentation/syscalls.txt @@ -66,3 +66,7 @@ get new pages: close file: rax in: 7 rdi in: file handle + +read key packet: + rax in: 8 + eax out: key packet diff --git a/kernel/entry.cpp b/kernel/entry.cpp index 3a42df7..cc74e69 100644 --- a/kernel/entry.cpp +++ b/kernel/entry.cpp @@ -4,6 +4,8 @@ #include <hilbert/kernel/framebuffer.hpp> #include <hilbert/kernel/terminal.hpp> #include <hilbert/kernel/paging.hpp> +#include <hilbert/kernel/input.hpp> +#include <hilbert/kernel/panic.hpp> #include <hilbert/kernel/vfile.hpp> #include "../limine/limine.h" @@ -184,12 +186,6 @@ extern "C" [[noreturn]] void entry() { } -[[noreturn]] static void print_and_halt(const char *msg) { - terminal::put_string_sz(msg); - while (1) - asm ("hlt"); -} - extern "C" [[noreturn]] void start_user_mode( uint64_t rip, uint64_t rsp, uint64_t p4_paddr); @@ -208,22 +204,25 @@ extern "C" [[noreturn]] void start_user_mode( if (initfs_fs->get_root_node(initfs_root.dir_entry.node) != storage::fs_result::success) - print_and_halt("failed to get root node of initfs."); + panic("failed to get root node of initfs."); vfile::set_root(initfs_root); + input::init_input(); + utility::string init_path_string("/bin/init.elf", 13); vfile::canon_path init_path; vfile::canonize_path(init_path_string, init_path); vfile::vfile init_file; - if (vfile::lookup_path(init_path, init_file) != storage::fs_result::success) - print_and_halt("failed to look up /bin/init.elf."); + if (vfile::lookup_path(init_path, init_file, true) != + storage::fs_result::success) + panic("failed to look up /bin/init.elf."); application::app_instance *init; if (application::create_app(init_file, init, initfs_root) != application::create_app_result::success) - print_and_halt("failed to parse /bin/init.elf."); + panic("failed to parse /bin/init.elf."); application::running_app = init; start_user_mode(init->saved_regs.rip, init->saved_regs.rsp, init->p4_paddr); diff --git a/kernel/include/hilbert/kernel/input.hpp b/kernel/include/hilbert/kernel/input.hpp new file mode 100644 index 0000000..cccb71f --- /dev/null +++ b/kernel/include/hilbert/kernel/input.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <hilbert/kernel/utility.hpp> + +namespace hilbert::kernel::input { + + enum : uint32_t { + LEFT_SHIFT = 1 << 8, + RIGHT_SHIFT = 1 << 9, + LEFT_CTRL = 1 << 10, + RIGHT_CTRL = 1 << 11, + LEFT_ALT = 1 << 12, + RIGHT_ALT = 1 << 13, + LEFT_WIN = 1 << 14, + RIGHT_WIN = 1 << 15, + CAPS_LOCK = 1 << 16, + NUM_LOCK = 1 << 17, + BREAK = 1 << 18, + }; + + extern utility::queue<uint32_t> *key_queue; + + //must be post switch to kernel page tables and mounting of file systems + void init_input(); + +} diff --git a/kernel/include/hilbert/kernel/panic.hpp b/kernel/include/hilbert/kernel/panic.hpp new file mode 100644 index 0000000..545d703 --- /dev/null +++ b/kernel/include/hilbert/kernel/panic.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace hilbert::kernel { + //prints to terminal and then halts. + [[noreturn]] void panic(const char *string_sz); +} diff --git a/kernel/include/hilbert/kernel/utility.hpp b/kernel/include/hilbert/kernel/utility.hpp index 2df1d65..47f78ea 100644 --- a/kernel/include/hilbert/kernel/utility.hpp +++ b/kernel/include/hilbert/kernel/utility.hpp @@ -294,4 +294,54 @@ namespace hilbert::kernel::utility { }; + template <class value_t> + struct queue { + + value_t *buffer; + unsigned buffer_len; + unsigned count; + unsigned next_read_index; + + queue(unsigned initial_len = 1024) : buffer(new value_t[initial_len]), + buffer_len(initial_len), count(0), next_read_index(0) { } + + ~queue() { + delete[] buffer; + } + + void insert(const value_t &v) { + + if (count == buffer_len) { + value_t *new_buffer = new value_t[buffer_len * 2]; + for (unsigned i = 0; i < buffer_len - next_read_index; ++i) + new_buffer[i] = move(buffer[i + next_read_index]); + for (unsigned i = buffer_len - next_read_index; i < buffer_len; ++i) + new_buffer[i] = move(buffer[i + next_read_index - buffer_len]); + delete[] buffer; + buffer = new_buffer; + buffer_len *= 2; + next_read_index = 0; + } + + buffer[(count + next_read_index) % buffer_len] = v; + ++count; + + } + + //assumes not empty + const value_t &peek() const { + return buffer[next_read_index]; + } + + //assumes not empty + value_t &&take() { + value_t &&ret = move(buffer[next_read_index]); + if (++next_read_index == buffer_len) + next_read_index = 0; + --count; + return move(ret); + } + + }; + } diff --git a/kernel/include/hilbert/kernel/vfile.hpp b/kernel/include/hilbert/kernel/vfile.hpp index f8a387d..b64ae63 100644 --- a/kernel/include/hilbert/kernel/vfile.hpp +++ b/kernel/include/hilbert/kernel/vfile.hpp @@ -55,9 +55,9 @@ namespace hilbert::kernel::vfile { //TODO: see comment at top of file. void set_root(const vfile &root); - //path must be absolute. follows symlinks on all but the last node. - //relative_to should be a directory to do the lookup inside; e.g., - //if relative_to is /a/b and path is c, then out becomes /a/b/c. - storage::fs_result lookup_path(const canon_path &path, vfile &out); + //path must be absolute. follows symlinks on all but the last node + //always, and on the last node when follow_final_symlink is true. + storage::fs_result lookup_path( + const canon_path &path, vfile &out, bool follow_final_symlink); } diff --git a/kernel/input.cpp b/kernel/input.cpp new file mode 100644 index 0000000..6bed7f5 --- /dev/null +++ b/kernel/input.cpp @@ -0,0 +1,13 @@ +#include <hilbert/kernel/input.hpp> +#include <hilbert/kernel/panic.hpp> +#include <hilbert/kernel/vfile.hpp> + +namespace hilbert::kernel::input { + + utility::queue<uint32_t> *key_queue; + + void init_input() { + key_queue = new utility::queue<uint32_t>(); + } + +} diff --git a/kernel/interrupts.asm b/kernel/interrupts.asm index 4827cfd..c096ddb 100644 --- a/kernel/interrupts.asm +++ b/kernel/interrupts.asm @@ -220,27 +220,111 @@ gdt: .tss: dq 0x0000e90000000067 dq 0;tss is 2 qwords wide - dq 0x00209b0000000000 - dq 0x00009b0000000000 - dq 0x0000fb0000000000 - dq 0x0020fb0000000000 + dq 0x002f98000000ffff + dq 0x002f92000000ffff + dq 0x002ff2000000ffff + dq 0x002ff8000000ffff + +section .bss section .text +write_keyboard_byte: + in al, 0x64 + test al, 0x02 + jnz write_keyboard_byte + mov al, dil + out 0x60, al + ret + +extern on_keyboard_interrupt + +keyboard_isr: + + push r11 + push r10 + push r9 + push r8 + push rsi + push rdi + push rdx + push rcx + push rax + + in al, 0x60 + mov dil, al + + call on_keyboard_interrupt + + mov al, 0x20 + out 0x20, al + + pop rax + pop rcx + pop rdx + pop rdi + pop rsi + pop r8 + pop r9 + pop r10 + pop r11 + + iretq + load_gdt_and_idt: + ;fill exception entries in idt + mov rcx, 16 .loop: mov rdi, rcx dec rdi - mov sil, 0 + mov sil, 1 mov rdx, qword [exception_isrs + rdi * 8] call set_isr loop .loop + ;reset pic and map irqs to 0x20 - 0x2f + + mov al, 0x11 + out 0x20, al + mov al, 0x20 + out 0x21, al + mov al, 0x04 + out 0x21, al + mov al, 0x01 + out 0x21, al + mov al, 0xfd ;mask all but irq 1 + out 0x21, al + + mov al, 0x11 + out 0xa0, al + mov al, 0x28 + out 0xa1, al + mov al, 0x02 + out 0xa1, al + mov al, 0x01 + out 0xa1, al + mov al, 0xff ;mask all + out 0xa1, al + + mov rdi, 0x21 + xor sil, sil + mov rdx, keyboard_isr + call set_isr + + ;set keyboard config + + mov al, 0x60 + out 0x64, al + mov dil, 0x01 + call write_keyboard_byte + + ;make tss entry in gdt + mov rax, tss mov word [gdt.tss + 2], ax @@ -250,6 +334,8 @@ load_gdt_and_idt: shr rax, 16 mov dword [gdt.tss + 8], eax + ;load gdt, idt, tss + lgdt [gdtr] lidt [idtr] mov ax, 0x18 diff --git a/kernel/interrupts.cpp b/kernel/interrupts.cpp index 1a95f22..cd57c4f 100644 --- a/kernel/interrupts.cpp +++ b/kernel/interrupts.cpp @@ -1,4 +1,6 @@ #include <hilbert/kernel/terminal.hpp> +#include <hilbert/kernel/input.hpp> +#include <hilbert/kernel/panic.hpp> using namespace hilbert::kernel; @@ -34,7 +36,7 @@ struct [[gnu::packed]] exception_info_t { extern exception_info_t exception_info; -const char *exception_types[] = { +static const char *exception_types[] = { "division error", "", "non-maskable interrupt", @@ -53,7 +55,7 @@ const char *exception_types[] = { "" }; -const char *flag_names[] = { +static const char *flag_names[] = { " cf", "", " pf", @@ -72,7 +74,7 @@ const char *flag_names[] = { " md" }; -void print_line(const char *r1, const char *r2, uint64_t r1v, uint64_t r2v) { +static void print_line(const char *r1, const char *r2, uint64_t r1v, uint64_t r2v) { terminal::put_string_sz("\n "); terminal::put_string_sz(r1); terminal::put_string_sz(": 0x"); @@ -123,3 +125,106 @@ extern "C" [[noreturn]] void print_exception() { asm ("hlt"); } + +static uint32_t current_flags = 0; + +#define SETBIT(field, bit, cond) \ + field = (cond) ? (field | (bit)) : (field & ~(bit)); + +static void got_key(uint32_t key) { + + input::key_queue->insert(current_flags | key); + + if (key == (input::BREAK | 0x77)) + current_flags ^= input::NUM_LOCK; + + else if (key == (input::BREAK | 0x58)) + current_flags ^= input::CAPS_LOCK; + + else if ((key & 0xff) == 0xa7) + SETBIT(current_flags, input::RIGHT_WIN, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x9f) + SETBIT(current_flags, input::LEFT_WIN, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x91) + SETBIT(current_flags, input::RIGHT_ALT, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x11) + SETBIT(current_flags, input::LEFT_ALT, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x94) + SETBIT(current_flags, input::RIGHT_CTRL, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x14) + SETBIT(current_flags, input::LEFT_CTRL, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x59) + SETBIT(current_flags, input::RIGHT_SHIFT, !(key & input::BREAK)) + + else if ((key & 0xff) == 0x12) + SETBIT(current_flags, input::LEFT_SHIFT, !(key & input::BREAK)) + +} + +static uint8_t key_so_far[8]; +uint8_t key_so_far_len = 0; + +extern "C" void on_keyboard_interrupt(uint8_t byte) { + + key_so_far[key_so_far_len++] = byte; + + if (key_so_far_len == 1) { + if (byte != 0xe0 && byte != 0xe1 && byte != 0xf0) { + got_key(byte); + key_so_far_len = 0; + } + } + + else if (key_so_far_len == 2) { + if (key_so_far[0] == 0xe0 && byte != 0xf0 && byte != 0x12) { + got_key(byte | 0x80); + key_so_far_len = 0; + } + else if (key_so_far[0] == 0xf0) { + got_key(input::BREAK | byte); + key_so_far_len = 0; + } + } + + else if (key_so_far_len == 3) { + if (key_so_far[0] == 0xe0 && key_so_far[1] == 0xf0 && byte != 0x7c) { + got_key(input::BREAK | byte | 0x80); + key_so_far_len = 0; + } + } + + else if (key_so_far_len == 4) { + if (key_so_far[0] == 0xe0 && key_so_far[1] == 0x12 && + key_so_far[2] == 0xe0 && byte == 0x7c) { + got_key(0xe0); + key_so_far_len = 0; + } + } + + else if (key_so_far_len == 6) { + if (key_so_far[0] == 0xe0 && key_so_far[1] == 0xf0 && + key_so_far[2] == 0x7c && key_so_far[3] == 0xe0 && + key_so_far[4] == 0xf0 && byte == 0x12) { + got_key(input::BREAK | 0xe0); + key_so_far_len = 0; + } + } + + else if (key_so_far_len == 8) { + if (key_so_far[0] == 0xe1 && key_so_far[1] == 0x14 && + key_so_far[2] == 0x77 && key_so_far[3] == 0xe1 && + key_so_far[2] == 0xf0 && key_so_far[3] == 0x14 && + key_so_far[4] == 0xf0 && byte == 0x77) { + got_key(0xe1); + got_key(input::BREAK | 0xe1); + } + key_so_far_len = 0; + } + +} diff --git a/kernel/panic.cpp b/kernel/panic.cpp new file mode 100644 index 0000000..233fcf4 --- /dev/null +++ b/kernel/panic.cpp @@ -0,0 +1,10 @@ +#include <hilbert/kernel/terminal.hpp> +#include <hilbert/kernel/panic.hpp> + +namespace hilbert::kernel { + [[noreturn]] void panic(const char *string_sz) { + terminal::put_string_sz(string_sz); + while (1) + asm ("hlt"); + } +} diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index 3c72d23..e194eb1 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -1,6 +1,7 @@ #include <hilbert/kernel/application.hpp> #include <hilbert/kernel/framebuffer.hpp> #include <hilbert/kernel/paging.hpp> +#include <hilbert/kernel/input.hpp> #include <hilbert/kernel/vfile.hpp> namespace hilbert::kernel::syscall { @@ -82,7 +83,7 @@ namespace hilbert::kernel::syscall { set_zero(rax, rdi, rsi, rdx); vfile::vfile file; - switch (vfile::lookup_path(cp, file)) { + switch (vfile::lookup_path(cp, file, true)) { case storage::fs_result::success: break; case storage::fs_result::device_error: @@ -96,28 +97,13 @@ namespace hilbert::kernel::syscall { return; } - vfile::vfile real_file; - switch (file.follow_symlinks(real_file)) { - case storage::fs_result::success: - break; - case storage::fs_result::device_error: - rax = file_result_device_error; - return; - case storage::fs_result::fs_corrupt: - rax = file_result_file_system_corrupt; - return; - case storage::fs_result::does_not_exist: - rax = file_result_does_not_exist; - return; - } - - if (real_file.dir_entry.type != storage::file_type::regular_file) { + if (file.dir_entry.type != storage::file_type::regular_file) { rax = file_result_directory; return; } unsigned handler = - application::running_app->open_files.add_new(utility::move(real_file)); + application::running_app->open_files.add_new(utility::move(file)); rax = file_result_success; rdi = (uint64_t)handler; @@ -226,6 +212,23 @@ namespace hilbert::kernel::syscall { } + void read_key_packet_syscall( + uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx + ) { + + set_zero(rax, rdi, rsi, rdx); + + asm ("cli"); + + while (input::key_queue->count == 0) + asm ("sti\nhlt\ncli"); + + rax = (uint64_t)input::key_queue->take(); + + asm ("sti"); + + } + typedef void (*syscall_handler)( uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx); @@ -237,10 +240,11 @@ namespace hilbert::kernel::syscall { &read_from_file_syscall, &end_this_process_syscall, &get_new_pages_syscall, - &close_file_syscall + &close_file_syscall, + &read_key_packet_syscall }; - static constexpr int max_syscall_number = 7; + static constexpr int max_syscall_number = 8; } diff --git a/kernel/vfile.cpp b/kernel/vfile.cpp index 028db6d..89c95e6 100644 --- a/kernel/vfile.cpp +++ b/kernel/vfile.cpp @@ -94,7 +94,7 @@ namespace hilbert::kernel::vfile { full_path.rel(target_path); vfile next; - RET_NOT_SUC(lookup_path(full_path, next)) + RET_NOT_SUC(lookup_path(full_path, next, false)) next.path = path; return next.follow_symlinks(out); @@ -175,7 +175,9 @@ namespace hilbert::kernel::vfile { kernel::vfile::root = new vfile(root); } - storage::fs_result lookup_path(const canon_path &path, vfile &out) { + storage::fs_result lookup_path( + const canon_path &path, vfile &out, bool follow_final_symlink + ) { //assume path is absolute. @@ -191,6 +193,12 @@ namespace hilbert::kernel::vfile { } + if (follow_final_symlink) { + vfile result; + RET_NOT_SUC(out.follow_symlinks(result)) + out = utility::move(result); + } + return storage::fs_result::success; } diff --git a/libraries/euler/include/euler/syscall.hpp b/libraries/euler/include/euler/syscall.hpp index 781d444..2dc88b8 100644 --- a/libraries/euler/include/euler/syscall.hpp +++ b/libraries/euler/include/euler/syscall.hpp @@ -7,6 +7,7 @@ namespace euler::syscall { typedef uint32_t encoded_color; typedef int32_t exit_code; typedef uint64_t file_handle; + typedef uint32_t key_packet; enum [[nodiscard]] file_result : uint64_t { success, @@ -45,4 +46,6 @@ extern "C" { void _syscall_close_file(euler::syscall::file_handle file); + euler::syscall::key_packet _syscall_read_key_packet(); + } diff --git a/libraries/euler/syscall.asm b/libraries/euler/syscall.asm index f7fe735..c76a641 100644 --- a/libraries/euler/syscall.asm +++ b/libraries/euler/syscall.asm @@ -80,3 +80,9 @@ _syscall_close_file: mov rax, 7 syscall ret + +global _syscall_read_key_packet +_syscall_read_key_packet: + mov rax, 8 + syscall + ret @@ -46,7 +46,7 @@ obj/kernel/%.asm.o: kernel/%.asm KERNEL_OBJECTS = allocator.cpp application.cpp entry.cpp framebuffer.cpp \ paging.asm paging.cpp storage.cpp storage/bd/memory.cpp terminal.cpp \ storage/fs/tarfs.cpp utility.cpp vfile.cpp syscall.asm syscall.cpp \ - interrupts.asm interrupts.cpp + interrupts.asm interrupts.cpp input.cpp panic.cpp obj/kernel.elf: ${KERNEL_OBJECTS:%=obj/kernel/%.o} ld ${KLD_ARGS} $^ -o $@ diff --git a/skeleton/assets/burdon.ppm b/skeleton/init/burdon.ppm index fe4a66a..fe4a66a 100644 --- a/skeleton/assets/burdon.ppm +++ b/skeleton/init/burdon.ppm diff --git a/skeleton/assets/readme.txt b/skeleton/init/readme.txt index 294909f..294909f 100644 --- a/skeleton/assets/readme.txt +++ b/skeleton/init/readme.txt |