summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-01-27 23:14:29 -0500
committerBenji Dial <benji@benjidial.net>2024-01-27 23:14:29 -0500
commita8a80d326de9550b2a25b1255a2093ab43219ede (patch)
treed42a800f735caf93679d1728e2d5f20004db3b65
parent7199e74aa22e592a3b77bdd81f735edca5470596 (diff)
downloadhilbert-os-a8a80d326de9550b2a25b1255a2093ab43219ede.tar.gz
keyboard input
-rw-r--r--applications/init/main.cpp17
-rw-r--r--documentation/keys.txt78
-rw-r--r--documentation/syscalls.txt4
-rw-r--r--kernel/entry.cpp19
-rw-r--r--kernel/include/hilbert/kernel/input.hpp26
-rw-r--r--kernel/include/hilbert/kernel/panic.hpp6
-rw-r--r--kernel/include/hilbert/kernel/utility.hpp50
-rw-r--r--kernel/include/hilbert/kernel/vfile.hpp8
-rw-r--r--kernel/input.cpp13
-rw-r--r--kernel/interrupts.asm96
-rw-r--r--kernel/interrupts.cpp111
-rw-r--r--kernel/panic.cpp10
-rw-r--r--kernel/syscall.cpp44
-rw-r--r--kernel/vfile.cpp12
-rw-r--r--libraries/euler/include/euler/syscall.hpp3
-rw-r--r--libraries/euler/syscall.asm6
-rw-r--r--makefile2
-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
diff --git a/makefile b/makefile
index bff2b4e..cf8405e 100644
--- a/makefile
+++ b/makefile
@@ -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