From d60036a4bdcc5e0b2b534446f19171a8ddcc2e08 Mon Sep 17 00:00:00 2001 From: slinky55 Date: Sun, 12 Jul 2026 04:37:46 -0500 Subject: [PATCH] added some useless shell commands --- clean.sh | 1 + kernel/drivers/vga/vga.c | 6 ++++-- kernel/drivers/vga/vga.h | 1 + kernel/kbd.c | 6 ++++-- kernel/kbd.h | 5 ++++- kernel/kmain.c | 5 +++++ kernel/syscall.c | 10 ++++++++++ kernel/vfs.h | 2 ++ programs/lib/rlibc.a | Bin 4408 -> 4470 bytes programs/rocksh/main.c | 33 +++++++++++++++++++++++++++++++++ programs/vga_text_term/main.c | 27 ++++++++++++++++++++++++++- rocklibc/include/syscall.h | 3 ++- rocklibc/src/syscall.c | 4 ++++ 13 files changed, 96 insertions(+), 7 deletions(-) diff --git a/clean.sh b/clean.sh index 8f42b64..9b3b751 100755 --- a/clean.sh +++ b/clean.sh @@ -15,3 +15,4 @@ rm -rf output rm *.elf cd .. +rm *.img \ No newline at end of file diff --git a/kernel/drivers/vga/vga.c b/kernel/drivers/vga/vga.c index ea1f930..f78bd19 100644 --- a/kernel/drivers/vga/vga.c +++ b/kernel/drivers/vga/vga.c @@ -79,13 +79,15 @@ void vga_putchar(char c) { } } -uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) { +uint32_t vga_seek(vfs_node_t* node, uint32_t offset, int whence) { terminal_row = offset / VGA_WIDTH; terminal_column = offset % VGA_WIDTH; + return 0; +} +uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf) { for (uint32_t i = 0; i < size; i++) { vga_putchar((char)buf[i]); } - return size; } \ No newline at end of file diff --git a/kernel/drivers/vga/vga.h b/kernel/drivers/vga/vga.h index 240c836..403f135 100644 --- a/kernel/drivers/vga/vga.h +++ b/kernel/drivers/vga/vga.h @@ -7,5 +7,6 @@ void vga_init(); void vga_putchar(char c); uint32_t vga_write(vfs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buf); +uint32_t vga_seek(vfs_node_t* node, uint32_t offset, int whence); #endif \ No newline at end of file diff --git a/kernel/kbd.c b/kernel/kbd.c index c2c90a6..7e3a3d6 100644 --- a/kernel/kbd.c +++ b/kernel/kbd.c @@ -79,6 +79,8 @@ void kbd_wait() { } } -char kbd_read() { - return kbd_pop(); +uint32_t kbd_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) { + if (!kbd_ready()) return -1; + buffer[0] = kbd_pop(); + return 1; } \ No newline at end of file diff --git a/kernel/kbd.h b/kernel/kbd.h index 5105aa2..d6019f1 100644 --- a/kernel/kbd.h +++ b/kernel/kbd.h @@ -1,6 +1,9 @@ #pragma once -char kbd_read(); +#include +#include + +uint32_t kbd_read(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer); void kbd_push(char c); int kbd_ready(); void kbd_wait(); \ No newline at end of file diff --git a/kernel/kmain.c b/kernel/kmain.c index f5d320f..8a604ca 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -6,6 +6,7 @@ #include "vfs.h" #include "elf.h" #include "gdt.h" +#include "kbd.h" #include #include @@ -135,6 +136,10 @@ void kmain(uint32_t magic, multiboot_info* mbi) { vfs_node_t* vga_dev = devfs->create(devfs, "tvga"); vga_dev->write = vga_write; + vga_dev->seek = vga_seek; + + vfs_node_t* kbd_dev = devfs->create(devfs, "kbd"); + kbd_dev->read = kbd_read; vfs_node_t* dev = vfs_find("/dev"); if (dev) { diff --git a/kernel/syscall.c b/kernel/syscall.c index d10acfe..98bb642 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -196,6 +196,15 @@ static int32_t sys_dup2(int src, int dst) { return dst; } +static int32_t sys_lseek(int fd, size_t offset, int whence) { + if (fd < 0) return 0; + process_t* task = current_task(); + file_t* file = task->fd_table[fd]; + if (!file) return 0; + file->node->seek(file->node, offset, whence); + return 1; +} + void syscall(registers_t* regs) { int32_t ret; switch(regs->eax) { @@ -209,6 +218,7 @@ void syscall(registers_t* regs) { case 21: ret = sys_fork(regs); break; case 22: ret = sys_exec(regs, (const char*)regs->ebx); break; case 23: ret = sys_dup2(regs->ebx, regs->ecx); break; + case 24: ret = sys_lseek(regs->ebx, regs->ecx, regs->edx); break; default: ret = -1; } regs->eax = ret; diff --git a/kernel/vfs.h b/kernel/vfs.h index 281d87a..365e8e7 100644 --- a/kernel/vfs.h +++ b/kernel/vfs.h @@ -14,6 +14,7 @@ struct vfs_node; typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer); typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer); +typedef uint32_t (*seek_type_t)(struct vfs_node* node, uint32_t offset, int whence); typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name); typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name); typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name); @@ -31,6 +32,7 @@ typedef struct vfs_node { finddir_type_t find; mkdir_type_t mkdir; create_type_t create; + seek_type_t seek; struct vfs_node* mnt; void* data; diff --git a/programs/lib/rlibc.a b/programs/lib/rlibc.a index 4f9063b3ad4ebf7c8ee0937e28098f571cb7111e..4a073813e00e19b781e98918c89409052817714b 100644 GIT binary patch delta 350 zcmdm?^i64kT)m}%k%fYSfdU91lL`uk7G_{k1%(7I1_lNpApVCPv*s}{5Q8~qF)(n> z%1zBpE~sPxQn~qM6K5K;<`k!N7*K()>$+avX@+^lsYYig3=Etx z6DK%K=HZZ>_+FI-XtBX&3C0{2IS>nIoq+)|X=Y-gpkQfgrZD*&rv_uqrH z_p_*jN%6_&SOkEq`z-3LF^oXtCUdhYv+^)8Fj!8G=Tv5NovhC)K6w_W7{sYtI1jM{ E0H!89WB>pF diff --git a/programs/rocksh/main.c b/programs/rocksh/main.c index 6283e46..940da0c 100644 --- a/programs/rocksh/main.c +++ b/programs/rocksh/main.c @@ -1,13 +1,46 @@ #include #include +#include const char* shell_prompt = "rocksh> "; +char buf[256]; +size_t buf_offset = 0; + +void parse_cmd() { + if (strcmp(buf, "exit") == 0) { + printf("bye!\n"); + exit(0); + } + + if (strcmp(buf, "motd") == 0) { + printf("rockos is the best!\n"); + } +} + +void reset() { + memset(buf, 0, 256); + buf_offset = 0; +} + int main(int argc, char *argv[]) { (void)argc; (void)argv; printf(shell_prompt); + while (1) { + char c; + int rd = read(0, &c, 1); + if (rd > 0) { + if (c == '\n') { + parse_cmd(); + reset(); + printf(shell_prompt); + continue; + } + buf[buf_offset++] = c; + } + } return 0; } \ No newline at end of file diff --git a/programs/vga_text_term/main.c b/programs/vga_text_term/main.c index 6d2fa2f..7c2f108 100644 --- a/programs/vga_text_term/main.c +++ b/programs/vga_text_term/main.c @@ -1,5 +1,8 @@ #include +#define VGA_TEXT_W 80 +#define VGA_TEXT_H 25 + void term(); int ptys; @@ -30,15 +33,37 @@ int main(int argc, char *argv[]) { return 0; } +void clear(int fd) { + lseek(fd, 0, 0); + size_t bytes = VGA_TEXT_W * VGA_TEXT_H; + char c = ' '; + for (size_t i = 0; i < bytes; i++) { + write(fd, &c, 1); + } + lseek(fd, 0, 0); +} + void term() { int vga_fd = open("/dev/tvga"); if (vga_fd == -1) return; + int kbd_fd = open("/dev/kbd"); + if (kbd_fd == -1) return; + + clear(vga_fd); + + char c; while (1) { - char c; + // first, get shell output int rd = read(0, &c, 1); if (rd > 0) { write(vga_fd, &c, 1); } + + // then read a byte from the kbd. If we got one, pass it to the shell + rd = read(kbd_fd, &c, 1); + if (rd > 0) { + write(1, &c, 1); + } } } \ No newline at end of file diff --git a/rocklibc/include/syscall.h b/rocklibc/include/syscall.h index d03b89c..88fac70 100644 --- a/rocklibc/include/syscall.h +++ b/rocklibc/include/syscall.h @@ -13,13 +13,14 @@ #define SYS_FORK 21 #define SYS_EXEC 22 #define SYS_DUP2 23 +#define SYS_LSEEK 24 int open(const char* path); int write(int fd, const void *buf, size_t count); int read(int fd, void *buf, size_t count); int close(int fd); -size_t lseek(int fd, size_t offset, int whence); +int lseek(int fd, size_t offset, int whence); void exit(int status) __attribute__((noreturn)); diff --git a/rocklibc/src/syscall.c b/rocklibc/src/syscall.c index 486a55b..a7c05d9 100644 --- a/rocklibc/src/syscall.c +++ b/rocklibc/src/syscall.c @@ -39,6 +39,10 @@ int read(int fd, void* buf, size_t cnt) { return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, (uint32_t)cnt); } +int lseek(int fd, size_t offset, int whence) { + return syscall3(SYS_LSEEK, (uint32_t)fd, offset, whence); +} + int close(int fd) { return syscall1(SYS_CLOSE, fd); }