🆕 pwd命令

This commit is contained in:
fslongjin 2022-05-24 16:37:28 +08:00
parent afeca18206
commit 8246c1c9e2
9 changed files with 474 additions and 73 deletions

View File

@ -99,7 +99,8 @@
"arch.h": "c",
"elf.h": "c",
"stdio.h": "c",
"wait_queue.h": "c"
"wait_queue.h": "c",
"stddef.h": "c"
},
"C_Cpp.errorSquiggles": "Enabled",
"esbonio.sphinx.confDir": ""

View File

@ -119,6 +119,7 @@ void auto_newline()
if (pos.x > pos.max_x)
{
#ifdef DEBUG
uart_send(COM1, '\r');
uart_send(COM1, '\n');
#endif
pos.x = 0;
@ -127,6 +128,7 @@ void auto_newline()
if (pos.y > pos.max_y)
{
#ifdef DEBUG
uart_send(COM1, '\r');
uart_send(COM1, '\n');
#endif
pos.y = pos.max_y;

View File

@ -24,7 +24,7 @@ all:
$(shell if [ ! -e $(tmp_output_dir) ];then mkdir -p $(tmp_output_dir); fi)
$(shell if [ ! -e $(output_dir) ];then mkdir -p $(output_dir); fi)
$(MAKE) sys_api_lib
# $(MAKE) sys_api_lib
$(MAKE) shell
# objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O binary sys_api_lib $(ROOT_PATH)/bin/user/init.bin
#objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 sys_api_lib $(ROOT_PATH)/bin/user/init.bin
@ -35,7 +35,7 @@ sys_api_lib:
#ld -b elf64-x86-64 -z muldefs -o sys_api_lib init.o $(shell find . -name "*.o") -T init.lds
shell:
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/shell $(shell find ./apps/shell -name "*.o") $(shell find ./libs -name "*.o")
ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/shell $(shell find ./apps/shell -name "*.o") $(shell find ./libs -name "*.o") -T ./apps/shell/shell.lds
objcopy -I elf64-x86-64 -S -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/shell $(output_dir)/shell.elf
clean:

View File

@ -1,4 +1,7 @@
all: shell.o
all: shell.o cmd.o
shell.o: shell.c
gcc $(CFLAGS) -c shell.c -o shell.o
gcc $(CFLAGS) -c shell.c -o shell.o
cmd.o: cmd.c
gcc $(CFLAGS) -c cmd.c -o cmd.o

166
user/apps/shell/cmd.c Normal file
View File

@ -0,0 +1,166 @@
#include "cmd.h"
#include <libc/string.h>
#include <libc/stdio.h>
#include <libc/stddef.h>
// 当前工作目录在main_loop中初始化
char *shell_current_path = NULL;
/**
* @brief shell
*
*/
struct built_in_cmd_t shell_cmds[] =
{
{"cd", shell_cmd_cd},
{"cat", shell_cmd_cat},
{"exec", shell_cmd_exec},
{"ls", shell_cmd_ls},
{"mkdir", shell_cmd_mkdir},
{"pwd", shell_cmd_pwd},
{"rm", shell_cmd_rm},
{"rmdir", shell_cmd_rmdir},
{"reboot", shell_cmd_reboot},
{"touch", shell_cmd_touch},
};
// 总共的内建命令数量
const static int total_built_in_cmd_num = sizeof(shell_cmds) / sizeof(struct built_in_cmd_t);
/**
* @brief
*
* @param main_cmd
* @return int
* -1
*/
int shell_find_cmd(char *main_cmd)
{
for (int i = 0; i < total_built_in_cmd_num; ++i)
{
if (strcmp(main_cmd, shell_cmds[i].name) == 0) // 找到对应的命令号
return i;
}
// 找不到该命令
return -1;
}
/**
* @brief shell内建的命令
*
* @param index
* @param argc
* @param argv
*/
void shell_run_built_in_command(int index, int argc, char **argv)
{
if (index >= total_built_in_cmd_num)
return;
// printf("run built-in command : %s\n", shell_cmds[index].name);
shell_cmds[index].func(argc, argv);
}
/**
* @brief cd命令:
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_cd(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_ls(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_pwd(int argc, char **argv)
{
if (shell_current_path)
printf("%s\n", shell_current_path);
}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_cat(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_touch(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_rm(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_mkdir(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_rmdir(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_exec(int argc, char **argv) {}
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
// todo:
int shell_cmd_reboot(int argc, char **argv) {}

120
user/apps/shell/cmd.h Normal file
View File

@ -0,0 +1,120 @@
#pragma once
/**
* @brief shell内建命令结构体
*
*/
struct built_in_cmd_t
{
char *name;
int (*func)(int argc, char **argv);
};
extern struct built_in_cmd_t shell_cmds[];
/**
* @brief
*
* @param main_cmd
* @return int
*/
int shell_find_cmd(char *main_cmd);
/**
* @brief shell内建的命令
*
* @param index
* @param argc
* @param argv
*/
void shell_run_built_in_command(int index, int argc, char **argv);
/**
* @brief cd命令:
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cd(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_ls(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_pwd(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_cat(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_touch(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rm(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_mkdir(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_rmdir(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_exec(int argc, char **argv);
/**
* @brief
*
* @param argc
* @param argv
* @return int
*/
int shell_cmd_reboot(int argc, char **argv);

View File

@ -3,81 +3,159 @@
#include <libc/fcntl.h>
#include <libc/stdlib.h>
#include <libKeyboard/keyboard.h>
int main()
#include <libc/string.h>
#include <libc/stddef.h>
#include "cmd.h"
#define pause_cpu() asm volatile("pause\n\t");
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
#define INPUT_BUFFER_SIZE 512
int shell_readline(int fd, char *buf);
extern char *shell_current_path;
/**
* @brief shell命令
*
* @param buf
* @param argc
* @param argv
* @return int
*/
int parse_command(char *buf, int *argc, char ***argv);
/**
* @brief shell主循环
*
* @param kb_fd
*/
static void main_loop(int kb_fd)
{
char string[] = "/333.txt";
uint8_t buf[128] = {0};
char tips_str[] = "The first application 'init.bin' started successfully!\n";
put_string(tips_str, COLOR_GREEN, COLOR_BLACK);
unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0};
printf("test printf: %s size: %d\n", string, sizeof(string));
// 初始化当前工作目录的路径
shell_current_path = (char *)malloc(256);
memset(shell_current_path, 0, 256);
shell_current_path = "/";
char kb_file_path[] = "/dev/keyboard.dev";
int kb_fd = open(kb_file_path, 0);
printf("keyboard fd = %d\n", kb_fd);
// shell命令行的主循环
while (true)
{
int key = keyboard_analyze_keycode(kb_fd);
if(key)
printf("%c", (char)key);
int argc = 0;
char **argv;
printf("[DragonOS] # ");
memset(input_buffer, 0, INPUT_BUFFER_SIZE);
// 循环读取每一行到buffer
shell_readline(kb_fd, input_buffer);
int cmd_num = parse_command(input_buffer, &argc, &argv);
printf("\n");
if (cmd_num >= 0)
shell_run_built_in_command(cmd_num, argc, argv);
}
/*
int fd = open(string, 0);
printf("fd=%d\n", fd);
}
read(fd, buf, 128);
int main()
{
// 打开键盘文件
char kb_file_path[] = "/dev/keyboard.dev";
int kb_fd = open(kb_file_path, 0);
// printf("keyboard fd = %d\n", kb_fd);
put_string(buf, COLOR_ORANGE, COLOR_BLACK);
lseek(fd, 0, SEEK_SET);
write(fd, tips_str, sizeof(tips_str)-1);
lseek(fd, 0, SEEK_SET);
// 由于暂时没有实现用户态的memset因此先手动清零
for(int i=0;i<128;++i)
buf[i] = 0;
read(fd, buf, 128);
put_string(buf, COLOR_YELLOW, COLOR_BLACK);
close(fd);
void *ptr[256] = {0};
for (int k = 0; k < 2; ++k)
{
printf("try to malloc 256*1M=256MB\n");
uint64_t js = 0;
for (int i = 0; i < 256; ++i)
{
ptr[i] = malloc(1024 * 1024);
js += *(uint64_t *)((uint64_t)(ptr[i]) - sizeof(uint64_t));
// if (*(uint64_t *)((uint64_t)(ptr[i]) - sizeof(uint64_t)) > 0x4008)
// printf("[%ld] start_addr = %#018lx, len = %#010lx\n", i, (uint64_t)(ptr[i]) - 8, *(uint64_t *)((uint64_t)(ptr[i]) - sizeof(uint64_t)));
}
// printf("ptr[0]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[0] - sizeof(uint64_t)));
// printf("ptr[1]->len=%lld\n", *(uint64_t *)((uint64_t)ptr[1] - sizeof(uint64_t)));
// printf("ptr[24]->len=%lld\n", *(uint64_t*)((uint64_t)ptr[24] - sizeof(uint64_t)));
printf("alloc done. total used: %lld bytes\n", js);
printf("try to free...\n");
for (int i = 0; i < 256; ++i)
{
free(ptr[i]);
}
printf("free done!\n");
}
*/
// *p = 'a';
/*
pid_t p = fork();
if(p == 0)
put_string("subproc\n", COLOR_PURPLE, COLOR_BLACK);
else put_string("parent proc\n", COLOR_ORANGE, COLOR_BLACK);
*/
main_loop(kb_fd);
while (1)
;
}
/**
* @brief
*
* @param fd
* @param buf
* @return
*/
int shell_readline(int fd, char *buf)
{
int key = 0;
int count = 0;
while (1)
{
key = keyboard_analyze_keycode(fd);
if (key == '\n')
return count;
if (key)
{
buf[count++] = key;
printf("%c", key);
}
// 输入缓冲区满了之后,直接返回
if (count >= INPUT_BUFFER_SIZE - 1)
return count;
pause_cpu();
}
}
/**
* @brief shell命令
*
* @param buf
* @param argc
* @param argv
* @return int
*/
int parse_command(char *buf, int *argc, char ***argv)
{
int index = 0; // 当前访问的是buf的第几位
// 去除命令前导的空格
while (index < INPUT_BUFFER_SIZE && buf[index] == ' ')
++index;
// 计算参数数量
for (int i = index; i < INPUT_BUFFER_SIZE - 1; ++i)
{
// 到达了字符串末尾
if (!buf[i])
break;
if (buf[i] != ' ' && (buf[i + 1] == ' ' || buf[i + 1] == '\0'))
++(*argc);
}
// printf("\nargc=%d\n", *argc);
// 为指向每个指令的指针分配空间
*argv = (char **)malloc(sizeof(char **) * (*argc));
memset(*argv, 0, sizeof(char **) * (*argc));
// 将每个命令都单独提取出来
for (int i = 0; i < *argc && index < INPUT_BUFFER_SIZE; ++i)
{
// 提取出命令,以空格作为分割
*((*argv) + i) = &buf[index];
while (index < INPUT_BUFFER_SIZE - 1 && buf[index] && buf[index] != ' ')
++index;
buf[index++] = '\0';
// 删除命令间多余的空格
while (index < INPUT_BUFFER_SIZE && buf[index] == ' ')
++index;
// printf("%s\n", (*argv)[i]);
}
// 以第一个命令作为主命令,查找其在命令表中的编号
return shell_find_cmd(**argv);
}

View File

@ -13,7 +13,7 @@ SECTIONS
{
_text = .;
init.o(.text)
*(.text)
_etext = .;
}

View File

@ -34,4 +34,35 @@ size_t strlen(const char *s)
++__res;
}
return __res;
}
/*
FirstPart and SecondPart
FirstPart = SecondPart => 0
FirstPart > SecondPart => 1
FirstPart < SecondPart => -1
*/
int strcmp(const char *FirstPart, const char *SecondPart)
{
register int __res;
__asm__ __volatile__("cld \n\t"
"1: \n\t"
"lodsb \n\t"
"scasb \n\t"
"jne 2f \n\t"
"testb %%al, %%al \n\t"
"jne 1b \n\t"
"xorl %%eax, %%eax \n\t"
"jmp 3f \n\t"
"2: \n\t"
"movl $1, %%eax \n\t"
"jl 3f \n\t"
"negl %%eax \n\t"
"3: \n\t"
: "=a"(__res)
: "D"(FirstPart), "S"(SecondPart)
:);
return __res;
}