From 2fa39ad85a319b1326710220f95e002587956c6a Mon Sep 17 00:00:00 2001 From: kaguya Date: Tue, 28 Apr 2026 01:31:21 -0400 Subject: [PATCH] input: Implement console input handling and add shell for real this time Self explanatory, we finally have a working ish shell Now we need to do some more stuff or something, probably work on a fork or something Signed-off-by: kaguya Co-authored-by: Copilot --- ext2_root/init.elf | Bin 5384 -> 5912 bytes src/drivers/input/input.c | 33 +++++++++++++++ src/drivers/input/input.h | 4 ++ src/drivers/input/ps2.c | 11 ++++- src/fs/vfs.c | 5 +++ user/build/init.elf | Bin 5384 -> 5912 bytes user/build/init.o | Bin 2040 -> 2640 bytes user/programs/init.c | 85 +++++++++++++++++++++++++++++++++++++- 8 files changed, 135 insertions(+), 3 deletions(-) diff --git a/ext2_root/init.elf b/ext2_root/init.elf index 613b512992b19cca8224e72463b77bd071dfd25b..a45a19bcb5aa212792fc160c16849be7e7f7f0d7 100755 GIT binary patch delta 967 zcmZWoQAkr!7(TmKVb0jyb}!*Ww2SOPR+y8BB{J?p>kN#j6e0*(YeOsVD$a0$HNzPm za51|*^xRu-1tB&}XHveNZe2N})xBpzXywZO;_dEA|-~Zk7|M#9r@3Z!7 zi|aF|AQroKgbLEM_eAFkZ!DrZBFFA?0{|OX+zXKQJv~`V-Ud_~Ay@f>4Nl3DH7`eiIt!TX^k?!^f?0 zTGkOx%>s)S*loT99yw-UQu``pZ>;`GVJ7XF1isrw`n#<}nd~`g#hC#M9^ZLDdNEza zw1DZa9CO2&*M`>Qg(vcdevWLw@G4`~2N$YvCT!AhDTZiCXvB00>PlW^ z9j}#~L(l+|Bt$YY_*=>N7upCWKgqiVLgxUZ*U_6DjDb|Wpc1MOgV{e(_gLe5*!)bflc;f}T zQK9zUdHji`LHpyBTkA)nW`hKnxS%--Tr8$It;@CP{K_m%A!{c^x08K+76q39=!Rx- ziQ1@m$ocQA)Xq+a!OQ`ZgwM<(Sz|64%(m#^Rz$5;3UFJZb`4-q(w<9!rg6zoqjTB| G$^94QsUti9 delta 424 zcmbQC*P%5*Lg+Jt0|N*^NCt)zLKC&jjE*pZ1sPy8g8+oj0;E9LK@h@sU~~X892h5_ zlAE}JLkLr124R3pNzVPV0=h1n~qxp@1XXho) z&KsVcH~Crj2{2AB5HMt7V4S>IAW`b|zZVw&|Nnpe4`Qi)VR>p%Nu^#%Mag7g;Z~D^ zfB*k$L!=l~fV2S+_W;EXgT$Qp1bUg=`6POn9r+a6SlswDnpyq%EGAzNHkr&JqM!ux zKS(VI@B^_B10&E72N0LxFvDaok#~&0CUY{%PmT~35CnMv44^?^HCa$Zcyf=Zj37KP zpfUzvnKM9{0;rw>s7wf0hDS_=>4@NDBQZOs2ZED}fK-Ig #include "mm/memory.h" #include "libk/string.h" +#include /* ------------------------------------------------------------------ * * Event ring-buffer * ------------------------------------------------------------------ */ #define INPUT_BUF_SIZE 512 +#define CONSOLE_BUF_SIZE 256 + +static char s_console_buf[CONSOLE_BUF_SIZE]; +static size_t s_console_rpos = 0; +static size_t s_console_wpos = 0; static input_event_t s_buf[INPUT_BUF_SIZE]; static size_t s_rpos = 0; static size_t s_wpos = 0; static spinlock_t s_lock = SPINLOCK_INIT; +/* Called from IRQ context */ +void input_push_char(char c) +{ + spinlock_acquire_or_wait(&s_lock); + size_t next = (s_console_wpos + 1) % CONSOLE_BUF_SIZE; + if (next != s_console_rpos) { /* drop if full */ + s_console_buf[s_console_wpos] = c; + s_console_wpos = next; + } + spinlock_drop(&s_lock); +} + +int input_read_console(void *buf, size_t len) +{ + uint8_t *p = buf; + size_t count = 0; + + spinlock_acquire_or_wait(&s_lock); + while (count < len && s_console_rpos != s_console_wpos) { + p[count++] = s_console_buf[s_console_rpos]; + s_console_rpos = (s_console_rpos + 1) % CONSOLE_BUF_SIZE; + } + spinlock_drop(&s_lock); + + return (int)count; /* 0 = no data yet (non-blocking) */ +} + static void push_event(const input_event_t *ev) { spinlock_acquire_or_wait(&s_lock); diff --git a/src/drivers/input/input.h b/src/drivers/input/input.h index 2df6d07..fb93fb9 100644 --- a/src/drivers/input/input.h +++ b/src/drivers/input/input.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include /* ------------------------------------------------------------------ * * Generic input event types @@ -53,6 +54,9 @@ void input_push_mouse_rel(int16_t dx, int16_t dy); void input_push_mouse_btn(uint8_t button, bool pressed); void input_push_mouse_wheel(int8_t delta); +void input_push_char(char c); +int input_read_console(void *buf, size_t len); + /* Consumer API */ bool input_poll(input_event_t *out); /* non-blocking; false if empty */ bool input_has_event(void); diff --git a/src/drivers/input/ps2.c b/src/drivers/input/ps2.c index cf54090..fcf0488 100644 --- a/src/drivers/input/ps2.c +++ b/src/drivers/input/ps2.c @@ -6,6 +6,7 @@ #include "arch/x86_64/sys/ioapic.h" #include "arch/x86_64/sys/apic.h" #include "libk/stdio.h" +#include "drivers/video/render.h" /* ── PS/2 I/O ports ───────────────────────────────────────────────────────── */ #define PS2_DATA_PORT 0x60 /* Read: scancode / Write: command data */ @@ -150,9 +151,15 @@ void ps2_kbd_handler(Registers *regs) /* ── Push event ──────────────────────────────────────────────────── */ input_push_key(scancode, ascii, pressed); - /* Optionally echo to debug port for development */ + if (pressed && ascii) { - /* e9_putc(ascii); ← uncomment if you have e9 debug output */ + input_push_char(ascii); + + if (ascii == '\b') { + backspace(); + } else { + putchar(ascii); + } } } diff --git a/src/fs/vfs.c b/src/fs/vfs.c index a0b2783..a496c34 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -5,6 +5,7 @@ #include "libk/stdio.h" #include "mm/memory.h" #include "libk/string.h" +#include "drivers/input/input.h" static spinlock_t s_vfs_lock = SPINLOCK_INIT; static vfs_file_t vfs_fd_table[VFS_MAX_FDS]; @@ -111,6 +112,10 @@ int VFS_Read_internal(fd_t fd, uint8_t* buf, size_t size) if (fd < 0 || fd >= VFS_MAX_FDS) return -1; + if (fd == VFS_FD_STDIN) { + return input_read_console(buf, size); + } + vfs_file_t* file = &vfs_fd_table[fd]; if (!file->used) diff --git a/user/build/init.elf b/user/build/init.elf index 613b512992b19cca8224e72463b77bd071dfd25b..a45a19bcb5aa212792fc160c16849be7e7f7f0d7 100755 GIT binary patch delta 967 zcmZWoQAkr!7(TmKVb0jyb}!*Ww2SOPR+y8BB{J?p>kN#j6e0*(YeOsVD$a0$HNzPm za51|*^xRu-1tB&}XHveNZe2N})xBpzXywZO;_dEA|-~Zk7|M#9r@3Z!7 zi|aF|AQroKgbLEM_eAFkZ!DrZBFFA?0{|OX+zXKQJv~`V-Ud_~Ay@f>4Nl3DH7`eiIt!TX^k?!^f?0 zTGkOx%>s)S*loT99yw-UQu``pZ>;`GVJ7XF1isrw`n#<}nd~`g#hC#M9^ZLDdNEza zw1DZa9CO2&*M`>Qg(vcdevWLw@G4`~2N$YvCT!AhDTZiCXvB00>PlW^ z9j}#~L(l+|Bt$YY_*=>N7upCWKgqiVLgxUZ*U_6DjDb|Wpc1MOgV{e(_gLe5*!)bflc;f}T zQK9zUdHji`LHpyBTkA)nW`hKnxS%--Tr8$It;@CP{K_m%A!{c^x08K+76q39=!Rx- ziQ1@m$ocQA)Xq+a!OQ`ZgwM<(Sz|64%(m#^Rz$5;3UFJZb`4-q(w<9!rg6zoqjTB| G$^94QsUti9 delta 424 zcmbQC*P%5*Lg+Jt0|N*^NCt)zLKC&jjE*pZ1sPy8g8+oj0;E9LK@h@sU~~X892h5_ zlAE}JLkLr124R3pNzVPV0=h1n~qxp@1XXho) z&KsVcH~Crj2{2AB5HMt7V4S>IAW`b|zZVw&|Nnpe4`Qi)VR>p%Nu^#%Mag7g;Z~D^ zfB*k$L!=l~fV2S+_W;EXgT$Qp1bUg=`6POn9r+a6SlswDnpyq%EGAzNHkr&JqM!ux zKS(VI@B^_B10&E72N0LxFvDaok#~&0CUY{%PmT~35CnMv44^?^HCa$Zcyf=Zj37KP zpfUzvnKM9{0;rw>s7wf0hDS_=>4@NDBQZOs2ZED}fK-IgNE6pZDLqKfjgF9a$GX zZ_Rc4PlV&61Rc3P8NNYoxk;QLuZluJa$F4s4I@g_=tS61Bcs>Cb`&$ljOe7HhN9!+ zL1WmSyLrxfcOxqxlv{kl1_XQJErKXu*aGxRfUX4Ssv`AN%H0vgnc{ayd6m-AfPHpy zu}>zxbpK&l&s-Ap=|6YKDV;9sbVa9M3m}U0%*z_LNlTw8Cf?|Dy}YbAlR!bx2ffQx zUYk!SP6US!{T(tqL^Qcjqhtm&nf~;pe#H)yE>x@4NH!92|2O0Zfq7U9LaInS9!xf1 zb^DT=A#yCweZ1paeY93MHQ6a)kSlL0P9N$imY3jtA4*PXwqR@#z)oUCfE{Y=bx$SF ze?`wsX*+fL15DOb)&jJoNIG4Fx#CxKy4D!EfZ)w0N`StHw!FwSw)CEzsVMhvZ&s_^ zssG=X4bXK^Z4xM5HaX@Xoi(K`3=c5an6Qtfg^~TU-0n$7YX+Zj?3oq)4)vbpw8J$m z4Lb576D)g~3qQuQn0>@}QZYGGk6Ty0d?10>G8bpKNQBRRt#}~cgcR}c5T~aU0N-`UgJY6d$r8bp$=Ag1U>7ebKrCxf7t0nl2(V;f4_dso MygB+q_Q>M=3wfdY`v3p{ delta 279 zcmca0@`HbZ2GbAbiCT`_`i14GMJ1JbB^4zTm-#U_zY&=DYmwaRe+=%<&Q=NGTx+2kh+a7b{zV1fvFOg7{&XUb-roW)_s)XoUBTWsuaMB0Cr- mYjN5!88A=I0#X7@lUD($3rv$=aoTYvfGuNSm@)Yyn>+y1e?D>m diff --git a/user/programs/init.c b/user/programs/init.c index bb8eeac..ddd1880 100644 --- a/user/programs/init.c +++ b/user/programs/init.c @@ -1,6 +1,7 @@ #include "../include/syscalls.h" -#define STDOUT 1 +#define STDIN 0 +#define STDOUT 1 unsigned strlen(const char* str) { @@ -13,6 +14,64 @@ unsigned strlen(const char* str) return len; } +static int strcmp(const char* a, const char* b) +{ + while (*a && (*a == *b)) { + a++; + b++; + } + return *(unsigned char*)a - *(unsigned char*)b; +} + +static void print(const char* s) +{ + syscall(SYS_WRITE, STDOUT, (unsigned long)s, strlen(s), 0, 0, 0); +} + +static void readline(char* buf, unsigned long max) +{ + unsigned long i = 0; + + while (i < max - 1) + { + char c; + long n = syscall(SYS_READ, STDIN, (unsigned long)&c, 1, 0, 0, 0); + + if (n <= 0) + continue; + + if (c == '\n') + break; + + if (c == '\b') { + if (i > 0) i--; + continue; + } + + buf[i++] = c; + } + + buf[i] = '\0'; +} + +static void cat(const char* path) +{ + unsigned char buf[256]; + + long fd = syscall(SYS_OPEN, (unsigned long)path, 0, 0, 0, 0, 0); + if (fd < 0) { + print("cat: cannot open file\n"); + return; + } + + long n = syscall(SYS_READ, fd, (unsigned long)buf, sizeof(buf), 0, 0, 0); + syscall(SYS_CLOSE, fd, 0, 0, 0, 0, 0); + + if (n > 0) + syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0); +} + + void main() { const unsigned char* path = "/qwerty.txt"; @@ -41,6 +100,30 @@ void main() // ── print buffer to stdout ─────────────── syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0); + char line[128]; + + while (1) + { + print("> "); + + readline(line, sizeof(line)); + + if (strcmp(line, "exit") == 0) + break; + + // simple "cat " + if (line[0] == 'c' && line[1] == 'a' && line[2] == 't' && line[3] == ' ') + { + cat(&line[4]); + continue; + } + + if (line[0] != '\0') + print("Unknown command\n"); + } + + while (1); + // ── done ──────────────────────────────── while (1); } \ No newline at end of file