From de79713c048a5737a6ed3c1e7885c6513b27a198 Mon Sep 17 00:00:00 2001 From: xiaoyi1212 Date: Sun, 1 Sep 2024 11:56:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=94=A8=E6=88=B7=E7=A8=8B?= =?UTF-8?q?=E5=BA=8Fshell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/include/syscall.h | 6 +- apps/libs/syscall.c | 11 +- apps/shell/shell.c | 77 ++++++++++++- src/driver/keyboard.c | 251 ++++++++--------------------------------- src/include/common.h | 2 +- src/include/io.h | 21 ---- src/include/keyboard.h | 21 +--- src/include/syscall.h | 3 +- src/include/tty.h | 11 +- src/kernel/kernel.c | 10 +- src/kernel/syscall.c | 17 ++- src/kernel/task.c | 8 +- src/kernel/tty.c | 2 + src/sysapp/shell.c | 7 +- 14 files changed, 178 insertions(+), 269 deletions(-) diff --git a/apps/include/syscall.h b/apps/include/syscall.h index 58326ed..443c822 100644 --- a/apps/include/syscall.h +++ b/apps/include/syscall.h @@ -3,21 +3,23 @@ #define SYSCALL_PUTC 1 #define SYSCALL_PRINT 2 -#define SYSCALL_GETC 3 +#define SYSCALL_GETCH 3 #define SYSCALL_MALLOC 4 #define SYSCALL_FREE 5 #define SYSCALL_EXIT 6 #define SYSCALL_G_CLEAN 7 +#define SYSCALL_GET_CD 8 #include #include void syscall_print(char* c); void syscall_putchar(char c); -char syscall_getc(); +char syscall_getch(); void* syscall_malloc(size_t size); void syscall_free(void *ptr); void syscall_exit(int code); void syscall_g_clean(); +void syscall_get_cd(char *buffer); #endif diff --git a/apps/libs/syscall.c b/apps/libs/syscall.c index 07b5a09..76fe300 100644 --- a/apps/libs/syscall.c +++ b/apps/libs/syscall.c @@ -14,9 +14,9 @@ void syscall_putchar(char c){ asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_PUTC), "r"(ebx) : "memory", "cc"); } -char syscall_getc(){ +char syscall_getch(){ uint32_t rets; - asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_GETC) : "memory", "cc"); + asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_GETCH) : "memory", "cc"); return rets; } @@ -45,4 +45,11 @@ void syscall_exit(int code){ void syscall_g_clean(){ uint32_t rets; asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_G_CLEAN) : "memory", "cc"); +} + +void syscall_get_cd(char *buffer){ + uint32_t rets; + uint32_t __arg1 = (uint32_t)(buffer); + register uint32_t ebx asm("ebx") = __arg1; + asm volatile("int $31\n\t" : "=a"(rets) : "0"(SYSCALL_GET_CD), "r"(ebx) : "memory", "cc"); } \ No newline at end of file diff --git a/apps/shell/shell.c b/apps/shell/shell.c index 5c79966..18e7001 100644 --- a/apps/shell/shell.c +++ b/apps/shell/shell.c @@ -1,11 +1,86 @@ #include #include "../include/syscall.h" +#include "../include/string.h" + +static int gets(char *buf, int buf_size) { + int index = 0; + char c; + while ((c = syscall_getch()) != '\n') { + if (c == '\b') { + if (index > 0) { + index--; + syscall_print("\b \b"); + } + } else { + buf[index++] = c; + printf("%c",c); + } + } + buf[index] = '\0'; + printf("%c",c); + return index; +} + +static int cmd_parse(char *cmd_str, char **argv, char token) { + int arg_idx = 0; + while (arg_idx < 50) { + argv[arg_idx] = NULL; + arg_idx++; + } + char *next = cmd_str; + int argc = 0; + + while (*next) { + while (*next == token) *next++; + if (*next == 0) break; + argv[argc] = next; + while (*next && *next != token) *next++; + if (*next) *next++ = 0; + if (argc > 50) return -1; + argc++; + } + + return argc; +} int main(){ - syscall_g_clean(); printf("CoolPotOS UserShell v0.0.1\n"); + char com[100]; + char *argv[50]; + int argc = -1; + char *buffer[255]; while (1){ + syscall_get_cd(buffer); + printf("%s$ ",buffer); + if (gets(com, 100) <= 0) continue; + argc = cmd_parse(com, argv, ' '); + + if (argc == -1) { + printf("[Shell]: Error: out of arguments buffer\n"); + continue; + } + + if (!strcmp("version", argv[0])) + printf("CoolPotOS for x86 [v0.3.1]\n"); + else if (!strcmp("help", argv[0]) || !strcmp("?", argv[0]) || !strcmp("h", argv[0])) { + printf("-=[CoolPotShell Helper]=-\n"); + printf("help ? h Print shell help info.\n"); + printf("version Print os version.\n"); + printf("type Read a file.\n"); + printf("ls List all files.\n"); + printf("mkdir Make a directory.\n"); + printf("del rm Delete a file.\n"); + printf("sysinfo Print system info.\n"); + printf("proc [kill|list] Lists all running processes.\n"); + printf("reset Reset OS.\n"); + printf("shutdown exit Shutdown OS.\n"); + printf("debug Print os debug info.\n"); + printf("disk[list||cg]List or view disks.\n"); + printf("cd Change shell top directory.\n"); + printf("sb3 Player a wav sound file.\n"); + printf("exec Execute a application.\n"); + } else printf("\033ff3030;[Shell]: Unknown command '%s'.\033c6c6c6;\n", argv[0]); } return 0; } \ No newline at end of file diff --git a/src/driver/keyboard.c b/src/driver/keyboard.c index 08e55f2..437ba45 100644 --- a/src/driver/keyboard.c +++ b/src/driver/keyboard.c @@ -3,91 +3,13 @@ #include "../include/memory.h" #include "../include/queue.h" #include "../include/io.h" +#include "../include/task.h" #include "../include/klog.h" -KEY_STATUS *key_status; -Queue *key_char_queue; -struct key_listener* head_listener; +static int caps_lock, shift, e0_flag = 0, ctrl = 0; +int disable_flag = 0; -unsigned char keyboard_map[128] = - { - 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */ - '9', '0', '-', '=', '\b', /* Backspace */ - '\t', /* Tab */ - 'q', 'w', 'e', 'r', /* 19 */ - 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */ - 0, /* 29 - Control */ - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */ - '\'', '`', -1, /* Left shift */ - '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ - 'm', ',', '.', '/', -1, /* Right shift */ - '*', - 0, /* Alt */ - ' ', /* Space bar */ - 0, /* Caps lock */ - 0, /* 59 - F1 key ... > */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, /* < ... F10 */ - 0, /* 69 - Num lock*/ - 0, /* Scroll Lock */ - 0, /* Home key */ - 0, /* Up Arrow */ - 0, /* Page Up */ - '-', - 0, /* Left Arrow */ - 0, - 0, /* Right Arrow */ - '+', - 0, /* 79 - End key*/ - 0, /* Down Arrow */ - 0, /* Page Down */ - 0, /* Insert Key */ - 0, /* Delete Key */ - 0, 0, 0, - 0, /* F11 Key */ - 0, /* F12 Key */ - 0, /* All other keys are undefined */ - }; - -unsigned char shift_keyboard_map[128] = - { - 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */ - '(', ')', '_', '+', '\b', /* Backspace */ - '\t', /* Tab */ - 'Q', 'W', 'E', 'R', /* 19 */ - 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', /* Enter key */ - 0, /* 29 - Control */ - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */ - '"', '~', -1, /* Left shift */ - '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 49 */ - 'M', '<', '>', '?', -1, /* Right shift */ - '*', - 0, /* Alt */ - ' ', /* Space bar */ - 0, /* Caps lock */ - 0, /* 59 - F1 key ... > */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, /* < ... F10 */ - 0, /* 69 - Num lock*/ - 0, /* Scroll Lock */ - 0, /* Home key */ - 0, /* Up Arrow */ - 0, /* Page Up */ - '-', - 0, /* Left Arrow */ - 0, - 0, /* Right Arrow */ - '+', - 0, /* 79 - End key*/ - 0, /* Down Arrow */ - 0, /* Page Down */ - 0, /* Insert Key */ - 0, /* Delete Key */ - 0, 0, 0, - 0, /* F11 Key */ - 0, /* F12 Key */ - 0, /* All other keys are undefined */ - }; +static int handle_keyboard_input(registers_t *reg); char keytable[0x54] = { // 按下Shift 0, 0x01, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', @@ -104,47 +26,7 @@ char keytable1[0x54] = { // 未按下Shift 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.'}; -static void default_handle(uint32_t key,int release,char c){ - if(!release) { - if(key == 42) { - key_status->is_shift = 1; - return 0; - } - - if(key == 29){ - key_status->is_ctrl = 1; - return 0; - } - - if(c == 0) return 0; - - if(key == 0x81) queue_push(key_char_queue,-5); - - queue_push(key_char_queue,(char)c); - } else { - if(key == -86){ - key_status->is_shift = 0; - } - - if(key == 29){ - key_status->is_ctrl = 0; - return 0; - } - } -} - void init_keyboard(){ - key_status = (KEY_STATUS*) alloc(sizeof(KEY_STATUS)); - if(key_status == NULL) goto error; - key_status->is_shift = 0; - - key_char_queue = create_queue(); - head_listener = (struct key_listener*) kmalloc(sizeof(struct key_listener)); - if(head_listener == NULL) goto error; - head_listener->func = default_handle; - head_listener->lid = 0; - head_listener->next = NULL; - register_interrupt_handler(0x21,handle_keyboard_input); klogf(true,"Load PS/2 Keyboard device.\n"); @@ -154,88 +36,55 @@ void init_keyboard(){ } int handle_keyboard_input(registers_t *reg){ - unsigned char status = read_port(KEYBOARD_STATUS_PORT); - uint32_t key = read_port(KEYBOARD_DATA_PORT); - int release = key & 0xb10000000; - char c = key_status->is_shift ? shift_keyboard_map[(unsigned char )key] : keyboard_map[(unsigned char )key]; + uint8_t data = 0; + io_out8(0x0020,0x61); + data = io_in8(0x0060); - io_cli(); + if (data == 0xe0) { + e0_flag = 1; + return; + } + if (data == 0x2a || data == 0x36) { // Shift按下 + shift = 1; + } + if (data == 0x1d) { // Ctrl按下 + ctrl = 1; + } + if (data == 0x3a) { // Caps Lock按下 + caps_lock = caps_lock ^ 1; + } + if (data == 0xaa || data == 0xb6) { // Shift松开 + shift = 0; + } + if (data == 0x9d) { // Ctrl按下 + ctrl = 0; + } - struct key_listener* h = head_listener; - while (1){ - h->func(key,release,c); - h = h->next; - if(h == NULL) break; + extern struct task_struct *running_proc_head; + if (data < 0x80) { + struct task_struct *task = running_proc_head; + while (1){ + if(task->tty != NULL){ + fifo8_put(task->tty->fifo,data); + } + task = task->next; + if(task == NULL || task == running_proc_head) break; + } } return 0; } -static void found_listener(int lid,struct key_listener *head,struct key_listener *base,struct key_listener **argv,int first){ - struct key_listener *t = base; - if(t == NULL){ - argv = NULL; - return; - } - if(t->lid == lid){ - *argv = t; - return; - } else{ - if(!first) - if(head->lid == t->lid){ - argv = NULL; - return; - } - found_listener(lid,head,t->next,argv,0); - } -} - -struct key_listener* found_listener_id(int lid){ - struct task_struct *argv = NULL; - found_listener(lid,head_listener,head_listener,&argv,1); - if(argv == NULL){ - printf("Cannot found key listener id:[%d].\n",lid); - return NULL; - } - return argv; -} - -void remove_listener(int lid){ - struct key_listener *argv = found_listener_id(lid); - if(argv == NULL){ - printf("Cannot found listener id:[%d].\n",lid); - return; - } - if(argv->lid == 0){ - printf("[\033driver\036]: Cannot remove default listener.\n"); - return; - } - - kfree(argv); - struct key_listener *head = head_listener; - struct key_listener *last = NULL; - while (1){ - if(head->lid == argv->lid){ - last->next = argv->next; - return; - } - last = head; - head = head->next; - } -} - -void add_listener(struct key_listener* listener){ - if(listener == NULL) return; - - struct key_listener* h = head_listener,*buf = NULL; - while (1){ - buf = h; - h = h->next; - if(h == NULL){ - buf->next = listener; - break; - } +int input_char_inSM() { + int i; + struct task_struct *task = get_current(); + if (task->tty->is_using == false) { + } else { + do{ + i = fifo8_get(task->tty->fifo); + } while (i == -1); } + return i; } int kernel_getch() { @@ -244,16 +93,16 @@ int kernel_getch() { if (ch == 0xe0) { // keytable之外的键(↑,↓,←,→) ch = input_char_inSM(); if (ch == 0x48) { // ↑ - return -1; - } else if (ch == 0x50) { // ↓ return -2; - } else if (ch == 0x4b) { // ← + } else if (ch == 0x50) { // ↓ return -3; - } else if (ch == 0x4d) { // → + } else if (ch == 0x4b) { // ← return -4; + } else if (ch == 0x4d) { // → + return -5; } } - // 返回扫描码(keytable之内)对应的ASCII码 + // 返回扫描码(keytable之内)对应的ASCII码 if (keytable[ch] == 0x00) { return 0; } else if (shift == 0 && caps_lock == 0) { diff --git a/src/include/common.h b/src/include/common.h index 0ca613c..2578464 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -2,7 +2,7 @@ #define CRASHPOWEROS_COMMON_H #define OS_NAME "CoolPotOS" -#define OS_VERSION "v0.3.0" +#define OS_VERSION "v0.3.1" // b 0x211972 // b 0x20d0a6 diff --git a/src/include/io.h b/src/include/io.h index d6be39e..0e14dd8 100644 --- a/src/include/io.h +++ b/src/include/io.h @@ -9,27 +9,6 @@ typedef struct { unsigned short gs, fs, es, ds, eflags; } regs16_t; -struct tty { - int using1; // 使用标志 - void *vram; // 显存(也可以当做图层) - int x, y; // 目前的 x y 坐标 - int xsize, ysize; // x 坐标大小 y 坐标大小 - int Raw_y; // 换行次数 - int cur_moving; // 光标需要移动吗 - unsigned char color; // 颜色 - void (*putchar)(struct tty *res, int c); // putchar函数 - void (*MoveCursor)(struct tty *res, int x, int y); // MoveCursor函数 - void (*clear)(struct tty *res); // clear函数 - void (*screen_ne)(struct tty *res); // screen_ne函数 - void (*gotoxy)(struct tty *res, int x, int y); // gotoxy函数 - void (*print)(struct tty *res, const char *string); // print函数 - void (*Draw_Box)(struct tty *res, int x, int y, int x1, int y1, - unsigned char color); // Draw_Box函数 - int (*fifo_status)(struct tty *res); - int (*fifo_get)(struct tty *res); - unsigned int reserved[4]; // 保留项 -}; - void gdt_flush(uint32_t gdtr); void io_hlt(void); diff --git a/src/include/keyboard.h b/src/include/keyboard.h index c716187..b4979b7 100644 --- a/src/include/keyboard.h +++ b/src/include/keyboard.h @@ -6,26 +6,7 @@ #include -typedef struct { - int is_shift; - int is_ctrl; - int is_esc; -}KEY_STATUS; - -typedef struct { - unsigned char *keyboard_map[128]; - unsigned char *shift_keyboard_map[128]; -}KEY_MAP; - -typedef struct key_listener{ - int lid; - void (*func)(uint32_t key,int release,char c); - struct key_listener *next; -}kl_t; - void init_keyboard(); -int handle_keyboard_input(); -void add_listener(struct key_listener* listener); -void remove_listener(int lid); +int kernel_getch(); #endif //CRASHPOWEROS_KEYBOARD_H diff --git a/src/include/syscall.h b/src/include/syscall.h index d590426..3e191e3 100644 --- a/src/include/syscall.h +++ b/src/include/syscall.h @@ -7,11 +7,12 @@ #define SYSCALL_PUTC 1 #define SYSCALL_PRINT 2 -#define SYSCALL_GETC 3 +#define SYSCALL_GETCH 3 #define SYSCALL_MALLOC 4 #define SYSCALL_FREE 5 #define SYSCALL_EXIT 6 #define SYSCALL_G_CLEAN 7 +#define SYSCALL_GET_CD 8 void syscall_install(); diff --git a/src/include/tty.h b/src/include/tty.h index 0eee023..f688263 100644 --- a/src/include/tty.h +++ b/src/include/tty.h @@ -4,12 +4,17 @@ #include "common.h" #include "fifo.h" +typedef void (*key_lis) (uint8_t); + typedef struct tty{ - uint32_t *frame_buffer; // 图形缓冲区映射 + uint32_t *frame_buffer; // 图形缓冲区映射 uint32_t width; uint32_t height; - bool is_default_frame; // 是否为根缓冲区 - struct FIFO8 *fifo; // 键盘输出缓冲区 + bool is_default_frame; // 是否为根缓冲区 + bool is_using; // 是否可以接受输入 + struct FIFO8 *fifo; // 键盘输出缓冲区 + key_lis keyboard_press; // 键盘按下 + key_lis keyboard_release; // 键盘松开 }tty_t; #include "task.h" diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 2c4504f..7a28cf0 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -137,13 +137,13 @@ void kernel_main(multiboot_t *multiboot) { clock_sleep(25); - //vfs_change_path("apps"); - //klogf(user_process("shell.bin","Shell") != -1,"Shell process init.\n"); + vfs_change_path("apps"); + klogf(user_process("shell.bin","Shell") != -1,"Shell process init.\n"); //klogf(user_process("init.bin","Init") != -1,"Init base process init.\n"); - int pid = kernel_thread(setup_shell,NULL,"CPOS-Shell"); - klogf(pid != -1,"Launch kernel shell.\n"); - kernel_thread(check_task,&pid,"CPOS-CK"); + //int pid = kernel_thread(setup_shell,NULL,"CPOS-Shell"); + //klogf(pid != -1,"Launch kernel shell.\n"); + //kernel_thread(check_task,&pid,"CPOS-CK"); //panic_pane("System out of memory error!",OUT_OF_MEMORY); diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 70b38e2..dd60064 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -6,7 +6,7 @@ #include "../include/io.h" #include "../include/shell.h" #include "../include/heap.h" - +#include "../include/keyboard.h" static void syscall_puchar(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){ printf("%c",ebx); @@ -16,10 +16,9 @@ static void syscall_print(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,ui printf("%s",ebx); } -static char syscall_getc(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){ +static char syscall_getch(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){ io_sti(); - char c = getc(); - printf("SYSCALL: %c\n",c); + char c = kernel_getch(); return c; } @@ -41,14 +40,22 @@ static void syscall_g_clean(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi, screen_clear(); } +static void syscall_get_cd(uint32_t ebx,uint32_t ecx,uint32_t edx,uint32_t esi,uint32_t edi){ + char* buf = ebx; + extern bool hasFS; + if(hasFS) vfs_getPath(buf); + else buf = "nofs"; +} + void *sycall_handlers[MAX_SYSCALLS] = { [SYSCALL_PUTC] = syscall_puchar, [SYSCALL_PRINT] = syscall_print, - [SYSCALL_GETC] = syscall_getc, + [SYSCALL_GETCH] = syscall_getch, [SYSCALL_MALLOC] = syscall_malloc, [SYSCALL_FREE] = syscall_free, [SYSCALL_EXIT] = syscall_exit, [SYSCALL_G_CLEAN] = syscall_g_clean, + [SYSCALL_GET_CD] = syscall_get_cd, }; typedef size_t (*syscall_t)(size_t, size_t, size_t, size_t, size_t); diff --git a/src/kernel/task.c b/src/kernel/task.c index 410ca60..a1c46fa 100644 --- a/src/kernel/task.c +++ b/src/kernel/task.c @@ -145,7 +145,7 @@ void task_kill(int pid) { } argv->state = TASK_DEATH; printf("Taskkill process PID:%d Name:%s\n", argv->pid, argv->name); - free_tty(*argv); + free_tty(argv); struct task_struct *head = running_proc_head; struct task_struct *last = NULL; while (1) { @@ -217,7 +217,7 @@ int32_t user_process(char *path, char *name){ // 用户进程创建 new_task->name = name; new_task->isUser = 1; new_task->tty = kmalloc(sizeof(tty_t)); - init_default_tty(*new_task); + init_default_tty(new_task); extern char root_disk; vfs_change_disk(new_task,root_disk); @@ -303,9 +303,11 @@ int32_t kernel_thread(int (*fn)(void *), void *arg, char *name) { // 内核进 current->tail = tail; current->program_break = program_break; current->program_break_end = program_break_end; - new_task->name = name; + new_task->tty = kmalloc(sizeof(tty_t)); + init_default_tty(new_task); + uint32_t *stack_top = (uint32_t * )((uint32_t) new_task + STACK_SIZE); *(--stack_top) = (uint32_t) arg; diff --git a/src/kernel/tty.c b/src/kernel/tty.c index a51e8b5..7d579fa 100644 --- a/src/kernel/tty.c +++ b/src/kernel/tty.c @@ -1,4 +1,5 @@ #include "../include/tty.h" +#include "../include/task.h" extern uint32_t *screen; extern uint32_t width, height; @@ -11,6 +12,7 @@ void init_default_tty(struct task_struct *task){ task->tty->width = width; task->tty->height = height; task->tty->is_default_frame = true; + task->tty->is_using = true; fifo8_init(task->tty->fifo,256,buffer); } diff --git a/src/sysapp/shell.c b/src/sysapp/shell.c index c5b0601..8abdc6e 100644 --- a/src/sysapp/shell.c +++ b/src/sysapp/shell.c @@ -9,16 +9,15 @@ #include "../include/common.h" #include "../include/sb16.h" #include "../include/elf.h" +#include "../include/keyboard.h" extern Queue *key_char_queue; extern vdisk vdisk_ctl[10]; extern bool hasFS; char getc() { - while (key_char_queue->size == 0x00) { - printf(""); - } - return queue_pop(key_char_queue); + char c = kernel_getch(); + return c; } int gets(char *buf, int buf_size) {