mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🆕 pwd命令
This commit is contained in:
parent
afeca18206
commit
8246c1c9e2
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -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": ""
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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
166
user/apps/shell/cmd.c
Normal 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
120
user/apps/shell/cmd.h
Normal 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);
|
@ -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);
|
||||
}
|
@ -13,7 +13,7 @@ SECTIONS
|
||||
{
|
||||
_text = .;
|
||||
|
||||
init.o(.text)
|
||||
*(.text)
|
||||
|
||||
_etext = .;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user