diff --git a/nanos-lite/src/loader.c b/nanos-lite/src/loader.c index 3e64dc17..7ad2e65 100644 --- a/nanos-lite/src/loader.c +++ b/nanos-lite/src/loader.c @@ -47,3 +47,7 @@ void naive_uload(PCB *pcb, const char *filename) { ((void(*)())entry) (); } +int _execve(const char *fname, char *const argv[], char *const envp[]) { + naive_uload(NULL, fname); + return -1; +} diff --git a/nanos-lite/src/syscall.c b/nanos-lite/src/syscall.c index f5b6bba..4a6608c 100644 --- a/nanos-lite/src/syscall.c +++ b/nanos-lite/src/syscall.c @@ -15,6 +15,8 @@ int _gettimeofday(struct timeval *tv, struct timezone *tz) { return 0; } +int _execve(const char *fname, char *const argv[], char *const envp[]); + #define CASE(syscall, ...) case _SYSCALL_NAME(syscall): __VA_ARGS__; break; void do_syscall(Context *c) { uintptr_t a[4]; @@ -34,9 +36,9 @@ void do_syscall(Context *c) { CASE(close, c->GPRx = fs_close((int)a[1])) CASE(gettimeofday, c->GPRx = _gettimeofday((struct timeval*)a[1], (struct timezone*)a[2])) - + CASE(execve, c->GPRx = _execve((const char*)a[1], (char* const*)a[2], (char* const*)a[3])) CASE(brk, c->GPRx = _brk((void*)a[1])) - CASE(exit, halt(0)) + CASE(exit, _execve("/bin/menu", NULL, NULL)) default: panic("Unhandled syscall ID = %d", a[0]); } } diff --git a/navy-apps/Makefile b/navy-apps/Makefile index 3826cf4..7871880 100644 --- a/navy-apps/Makefile +++ b/navy-apps/Makefile @@ -166,7 +166,7 @@ $(CLEAN_ALL): .PHONY: clean-all $(CLEAN_ALL) ### Build fsimg and ramdisk for Nanos-lite -APPS = nslider menu +APPS = nslider menu nterm TESTS = dummy hello file-test timer-test event-test bmp-test fsimg: $(addprefix apps/, $(APPS)) $(addprefix tests/, $(TESTS)) diff --git a/navy-apps/apps/nterm/src/builtin-sh.cpp b/navy-apps/apps/nterm/src/builtin-sh.cpp index 5703c20..f81d27e 100644 --- a/navy-apps/apps/nterm/src/builtin-sh.cpp +++ b/navy-apps/apps/nterm/src/builtin-sh.cpp @@ -22,7 +22,88 @@ static void sh_prompt() { sh_printf("sh> "); } -static void sh_handle_cmd(const char *cmd) { +static bool p_help(char *name); + +static int cmd_help(char *args) { + /* extract the first argument */ + char *arg = strtok(NULL, " "); + + if (p_help(arg) == false) { + sh_printf("Unknown command '%s'\n", arg); + } + return 0; +} + +static int cmd_ls(char *args) { + sh_printf("ls\n"); + return 0; +} + +static int cmd_echo(char *args) { + sh_printf("%s", args); + return 0; +} + +static int cmd_exit(char *args) { + exit(0); +} + +static struct { + const char *name; + const char *description; + int (*handler) (char *); +} cmd_table [] = { + { "help", "Display information about all supported commands", cmd_help }, + // { "ls", "List all files in current directory", cmd_ls }, + { "echo", "Print the arguments", cmd_echo }, + { "exit", "Exit the built-in shell"} + /* TODO: Add more commands */ +}; +#define ARRLEN(arr) (sizeof(arr) / sizeof(arr[0])) +#define NR_CMD ARRLEN(cmd_table) + +static bool p_help(char *name) { + for (int i = 0; i < NR_CMD; i ++) { + if (name == NULL) { + printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description); + continue; + } + if (strcmp(name, cmd_table[i].name) == 0) { + printf("%s - %s\n", cmd_table[i].name, cmd_table[i].description); + return true; + } + } + return true ? name == NULL : false; +} + +static void sh_handle_cmd(const char *_cmd) { + char str[128]; + strcpy(str, _cmd); + char *str_end = str + strlen(str); + + /* extract the first token as the command */ + char *cmd = strtok(str, " "); + if (cmd == NULL) { return; } + int cmd_len = strlen(cmd); + if (cmd[cmd_len - 1] == '\n') cmd[--cmd_len] = '\0'; + + /* treat the remaining string as the arguments, + * which may need further parsing + */ + char *args = cmd + cmd_len + 1; + if (args >= str_end) { + args = NULL; + } + + int i; + for (i = 0; i < NR_CMD; i ++) { + if (strcmp(cmd, cmd_table[i].name) == 0) { + if (cmd_table[i].handler(args) < 0) { return; } + break; + } + } + + if (i == NR_CMD) { sh_printf("Unknown command '%s'\n", cmd); } } void builtin_sh_run() { diff --git a/navy-apps/apps/nterm/src/main.cpp b/navy-apps/apps/nterm/src/main.cpp index 2d58349..3386c38 100644 --- a/navy-apps/apps/nterm/src/main.cpp +++ b/navy-apps/apps/nterm/src/main.cpp @@ -30,7 +30,7 @@ int main(int argc, char *argv[]) { static void draw_ch(int x, int y, char ch, uint32_t fg, uint32_t bg) { SDL_Surface *s = BDF_CreateSurface(font, ch, fg, bg); - SDL_Rect dstrect = { .x = x, .y = y }; + SDL_Rect dstrect = { .x = (int16_t)x, .y = (int16_t)y }; SDL_BlitSurface(s, NULL, screen, &dstrect); SDL_FreeSurface(s); } diff --git a/navy-apps/libs/libminiSDL/src/event.c b/navy-apps/libs/libminiSDL/src/event.c index 55721c0..d4c3fa9 100644 --- a/navy-apps/libs/libminiSDL/src/event.c +++ b/navy-apps/libs/libminiSDL/src/event.c @@ -9,34 +9,48 @@ static const char *keyname[] = { _KEYS(keyname) }; -int SDL_PushEvent(SDL_Event *ev) { - return 0; -} - -int SDL_PollEvent(SDL_Event *ev) { - return 0; -} - -int SDL_WaitEvent(SDL_Event *event) { - char buf[64]; - while (NDL_PollEvent(buf, sizeof(buf)) == 0); - // printf("SDL_WaitEvent Recv %s", buf); +static int _phase_event(SDL_Event *event, char *buf) { + // printf("SDL_Event Recv %s", buf); if (buf[0] == 'k') { if (buf[1] == 'd') { event->type = SDL_KEYDOWN; } else if (buf[1] == 'u') { event->type = SDL_KEYUP; } - for (int i = 0; i < 83; i ++ ) { - if (strncmp(buf + 3, keyname[i], strlen(buf) - 4) == 0) { - // printf("SDL_WaitEvent Got %s\n", keyname[i]); + int buflen = strlen(buf) - 4; + for (int i = 0; i < sizeof(keyname)/sizeof(keyname[0]); i ++ ) { + if (keyname[i][buflen] != '\0') continue; + if (strncmp(buf + 3, keyname[i], buflen) == 0) { + // printf("SDL_Event Got %s\n", keyname[i]); event->key.keysym.sym = i; return 1; } } event->key.keysym.sym = SDLK_NONE; - // printf("SDL_WaitEvent Unknown %s\n", buf + 3); + // printf("SDL_Event Unknown %s\n", buf + 3); } +} + +int SDL_PushEvent(SDL_Event *ev) { + return 0; +} + +int SDL_PollEvent(SDL_Event *ev) { + char buf[64]; + if (NDL_PollEvent(buf, sizeof(buf)) == 0) { + return 0; + } + _phase_event(ev, buf); + return 1; +} + +int SDL_WaitEvent(SDL_Event *event) { + char buf[64]; + while (NDL_PollEvent(buf, sizeof(buf)) == 0); + // printf("SDL_WaitEvent Recv %s", buf); + _phase_event(event, buf); + + // error return 0 return 1; } diff --git a/navy-apps/libs/libminiSDL/src/general.c b/navy-apps/libs/libminiSDL/src/general.c index d1884d6..7971910 100644 --- a/navy-apps/libs/libminiSDL/src/general.c +++ b/navy-apps/libs/libminiSDL/src/general.c @@ -1,6 +1,8 @@ #include +uint32_t SDL_start_time; int SDL_Init(uint32_t flags) { + SDL_start_time = NDL_GetTicks(); return NDL_Init(flags); } diff --git a/navy-apps/libs/libminiSDL/src/timer.c b/navy-apps/libs/libminiSDL/src/timer.c index ebe3782..ef8cdac 100644 --- a/navy-apps/libs/libminiSDL/src/timer.c +++ b/navy-apps/libs/libminiSDL/src/timer.c @@ -10,8 +10,9 @@ int SDL_RemoveTimer(SDL_TimerID id) { return 1; } +extern uint32_t SDL_start_time; uint32_t SDL_GetTicks() { - return 0; + return NDL_GetTicks() - SDL_start_time; } void SDL_Delay(uint32_t ms) { diff --git a/navy-apps/libs/libos/src/syscall.c b/navy-apps/libs/libos/src/syscall.c index bf2739a..b631fde 100644 --- a/navy-apps/libs/libos/src/syscall.c +++ b/navy-apps/libs/libos/src/syscall.c @@ -98,8 +98,7 @@ int _gettimeofday(struct timeval *tv, struct timezone *tz) { } int _execve(const char *fname, char * const argv[], char *const envp[]) { - _exit(SYS_execve); - return 0; + return _syscall_(SYS_execve, (intptr_t)fname, (intptr_t)argv, (intptr_t)envp); } // Syscalls below are not used in Nanos-lite.