From 5bf39b04c71817f7c2fef40dc5141c0411dad898 Mon Sep 17 00:00:00 2001 From: Julian Barathieu Date: Wed, 8 May 2019 15:09:16 +0200 Subject: [PATCH] Shell --- Makefile | 2 +- include/extras/buf.h | 3 +- kaleid/kernel/io/keyb.c | 15 ++++--- kaleid/kernel/ke/shell.c | 84 +++++++++++++++++++++++++++++++-------- kaleid/kernel/ke/shell.h | 72 +++++++++++++++++++++++++++++++++ kaleid/kernel/po/shtdwn.c | 7 ++-- kaleid/libbuf/bflush.c | 12 ++++++ kaleid/libbuf/bputc.c | 10 +++-- kaleid/libbuf/bread.c | 7 +--- 9 files changed, 177 insertions(+), 35 deletions(-) create mode 100644 kaleid/kernel/ke/shell.h diff --git a/Makefile b/Makefile index 4566daa..149978c 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ CCNAME=x86_64-elf-gcc ASMFLAGS=-f elf64 LDFLAGS=-melf_x86_64 COPTIM=-O2 -CWARNS=-Wall -Wextra -Wno-unused-parameter -Werror=implicit-function-declaration +CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration CINCLUDES=-Iinclude CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2 diff --git a/include/extras/buf.h b/include/extras/buf.h index 147a040..3c85537 100644 --- a/include/extras/buf.h +++ b/include/extras/buf.h @@ -167,6 +167,7 @@ error_t bread(Buffer_t *, uchar *, size_t); error_t bscanf(Buffer_t *, const char *, ...); error_t vbscanf(Buffer_t *, const char *, va_list); -error_t bscrolldown(Buffer_t *buf); +error_t bemptybuf(Buffer_t *); +error_t bscrolldown(Buffer_t *); #endif diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c index 446e364..3ac2884 100644 --- a/kaleid/kernel/io/keyb.c +++ b/kaleid/kernel/io/keyb.c @@ -36,11 +36,13 @@ void KeybPrint(char code) { uchar ch = ScanCodes[(int)code]; - bputc(BStdIn, ch); - if (code && Invisible[(int)code] == 0) { - bputc(BStdOut, ScanCodes[(int)code]); - //bprintf(BStdOut, "%x ", code); - BStdOut->flusher(BStdOut); + if (ch != 0) { + bputc(BStdIn, ch); + if (code && Invisible[(int)code] == 0) { + bputc(BStdOut, ScanCodes[(int)code]); + //bprintf(BStdOut, "%x ", code); + BStdOut->flusher(BStdOut); + } } } @@ -146,7 +148,8 @@ void IoCreateInputBuffer(void) if (rc) KeStartPanic("[Keyb] Couldn't create BStdIn"); - BEnableLineBuffering(BStdIn); + //BEnableLineBuffering(BStdIn); + BStdIn->flusher = bemptybuf; } void IoEnableKeyb(void) diff --git a/kaleid/kernel/ke/shell.c b/kaleid/kernel/ke/shell.c index 3c7b320..a45b6cf 100644 --- a/kaleid/kernel/ke/shell.c +++ b/kaleid/kernel/ke/shell.c @@ -1,7 +1,7 @@ //----------------------------------------------------------------------------// // GNU GPL OS/K // // // -// Desc: Kernel "shell" entry point // +// Desc: Kernel shell // // // // // // Copyright © 2018-2019 The OS/K Team // @@ -22,25 +22,61 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -#include -#include -#include -#include -#include -#include +#include "shell.h" -extern void IoScrollDown(void); -extern void IoScrollUp(void); +void ExecuteCommand(char *cmdbuf) +{ + error_t rc; + Command_t *cmd; + bool found = false; + + memzero(*shargv, ARG_MAX); + rc = KalCmdLineToArgVec(cmdbuf, &shargc, shargv); + if (rc) KeStartPanic("Shell: Couldn't parse command line: %d", rc); + + for (cmd = cmdtable; cmd->name != NULL; cmd++) { + if (!strcmp(cmd->name, shargv[0])) { + cmd->func(shargc, shargv); + found = true; + break; + } + } + + if (found == false) { + KernLog("err: command not found: '%s'\n", shargv[0]); + } +} void KeStartShell(void) { uchar ch; error_t rc; + + char cmdbuf[CMDBUFSIZE] = { 0 }; + char *bufptr = cmdbuf; - KernLog("\nshell > "); + argv0 = malloc(ARG_MAX); + shargv = &argv0; + + KernLog("\nshell> "); BFlushBuf(BStdOut); - while ((rc = bgetc(BStdIn, &ch)) == EOK) { + while ((rc = bgetc(BStdIn, &ch)) == EOK || rc == EENDF) { + // Reset BStdIn's content + if (rc == EENDF) { + if (!(BStdIn->flags & BF_ERR)) { + *bufptr = 0; + bufptr = cmdbuf; + ExecuteCommand(cmdbuf); + + memzero(cmdbuf, sizeof(cmdbuf)); + BFlushBuf(BStdIn); + KernLog("shell> "); + BFlushBuf(BStdOut); + } + else break; + } + switch (ch) { case KEY_BEL: @@ -48,9 +84,6 @@ void KeStartShell(void) IoDoStarWars(); } else IoDoBeep(); - KernLog("beep"); - KernLog("\nshell > "); - BFlushBuf(BStdOut); break; case KEY_DC1: @@ -64,11 +97,30 @@ void KeStartShell(void) case KEY_ESC: PoShutdownQemu(); break; - case '\n': - KernLog("shell > "); + + default: + *bufptr++ = (char)ch; + + // End of buffer? + if (bufptr != cmdbuf+CMDBUFSIZE-1) { + break; // No + } + + KernLog("\n"); + // Else, fallthrough to case '\n' + + case '\n': + *bufptr = 0; + bufptr = cmdbuf; + ExecuteCommand(cmdbuf); + + memzero(cmdbuf, sizeof(cmdbuf)); + KernLog("shell> "); + BFlushBuf(BStdIn); BFlushBuf(BStdOut); break; } + KePauseCPU(); } } diff --git a/kaleid/kernel/ke/shell.h b/kaleid/kernel/ke/shell.h new file mode 100644 index 0000000..d118db3 --- /dev/null +++ b/kaleid/kernel/ke/shell.h @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Kernel shell // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include +#include +#include +#include +#include +#include +#include + +extern void IoScrollDown(void); +extern void IoScrollUp(void); + +static int shargc = 0; +static char *argv0 = 0; +static char **shargv = 0; + +#define CMDBUFSIZE 256 + +error_t CmdBeep(int argc, char **argv) +{ + if (rand() % 16 == 0) { + IoDoStarWars(); + } + else IoDoBeep(); + + return EOK; +} + +error_t CmdQuit(int argc, char **argv) +{ + PoShutdownQemu(); + return EOK; +} + +typedef struct Command_t Command_t; + +struct Command_t +{ + const char *name; + error_t (*func)(int argc, char **argv); +}; + +Command_t cmdtable[] = +{ + { "beep", CmdBeep }, + { "exit", CmdQuit }, + { "quit", CmdQuit }, + { NULL, NULL } +}; diff --git a/kaleid/kernel/po/shtdwn.c b/kaleid/kernel/po/shtdwn.c index 9af6ad4..7d405d3 100644 --- a/kaleid/kernel/po/shtdwn.c +++ b/kaleid/kernel/po/shtdwn.c @@ -35,7 +35,7 @@ noreturn void PoShutdownQemu(void) IoWriteWordOnPort(0x604, 0x2000); __builtin_unreachable(); -}; +} noreturn void PoShutdownVirtualbox(void) { @@ -46,7 +46,7 @@ noreturn void PoShutdownVirtualbox(void) IoWriteWordOnPort(0x4004, 0x3400); __builtin_unreachable(); -}; +} noreturn void PoShutdownBochs(void) { @@ -57,4 +57,5 @@ noreturn void PoShutdownBochs(void) IoWriteWordOnPort(0xB004, 0x2000); __builtin_unreachable(); -}; +} + diff --git a/kaleid/libbuf/bflush.c b/kaleid/libbuf/bflush.c index e852cdc..dd6158f 100644 --- a/kaleid/libbuf/bflush.c +++ b/kaleid/libbuf/bflush.c @@ -25,6 +25,18 @@ #include #include +// +// Erases buf's content +// Can be given as a flusher +// +error_t bemptybuf(Buffer_t *buf) +{ + buf->wp = buf->rp = buf->buf; + buf->lastLF = 0; + + return EOK; +} + // // Flushes a buffer, returns EBADF when not possible // diff --git a/kaleid/libbuf/bputc.c b/kaleid/libbuf/bputc.c index 42d6e26..344b6bb 100644 --- a/kaleid/libbuf/bputc.c +++ b/kaleid/libbuf/bputc.c @@ -98,14 +98,18 @@ error_t bputc(Buffer_t *buf, uchar ch) // Backspace else if (ch == 8) { - if (buf->wp > buf->buf) { + if (buf->wp > buf->buf && buf->lastLF > 0) { buf->wp--; + buf->lastLF--; rc = bputc(buf, ' '); - if (!rc) buf->wp--; + if (!rc) { + buf->wp--; + buf->lastLF--; + } } } - // DEL character + // DEL character, XXX lastLF else if (ch == 127) { rc = bputc(buf, ' '); if (!rc) buf->wp--; diff --git a/kaleid/libbuf/bread.c b/kaleid/libbuf/bread.c index 38cbc21..32299e2 100644 --- a/kaleid/libbuf/bread.c +++ b/kaleid/libbuf/bread.c @@ -24,16 +24,13 @@ #include #include - +#if 0 error_t BReadBuf(Buffer_t *buf, uchar *out, size_t n) { - error_t rc; - - } error_t bread(Buffer_t *buf, uchar * out, size_t n) { - } +#endif