实现用户程序shell

This commit is contained in:
XIAOYI12 2024-09-01 11:56:39 +08:00
parent 520c393187
commit de79713c04
14 changed files with 178 additions and 269 deletions

View File

@ -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 <stdint.h>
#include <stddef.h>
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

View File

@ -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");
}

View File

@ -1,11 +1,86 @@
#include <stdio.h>
#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 <name> Read a file.\n");
printf("ls List all files.\n");
printf("mkdir <name> Make a directory.\n");
printf("del rm <name> Delete a file.\n");
printf("sysinfo Print system info.\n");
printf("proc [kill<pid>|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|<ID>|cg<ID>]List or view disks.\n");
printf("cd <path> Change shell top directory.\n");
printf("sb3 <name> Player a wav sound file.\n");
printf("exec <path> Execute a application.\n");
} else printf("\033ff3030;[Shell]: Unknown command '%s'.\033c6c6c6;\n", argv[0]);
}
return 0;
}

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -6,26 +6,7 @@
#include <stdint.h>
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

View File

@ -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();

View File

@ -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"

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {