[shell] Kernel debug shell and all the things I needed to make to support that.
This commit is contained in:
parent
beaa7fda54
commit
afa85d9b39
7
Makefile
7
Makefile
@ -2,7 +2,7 @@ include Makefile.inc
|
||||
|
||||
DIRS = core
|
||||
|
||||
.PHONY: all clean install run curses initrd
|
||||
.PHONY: all clean install run curses initrd core
|
||||
|
||||
all: kernel
|
||||
|
||||
@ -23,7 +23,7 @@ run: bootdisk.img
|
||||
curses: bootdisk.img
|
||||
@qemu -curses -fda bootdisk.img
|
||||
|
||||
kernel: start.o link.ld main.o core.d
|
||||
kernel: start.o link.ld main.o core
|
||||
@${ECHO} -n "\e[32m LD $<\e[0m"
|
||||
@${LD} -T link.ld -o kernel *.o core/*.o core/fs/*.o
|
||||
@${ECHO} "\r\e[32;1m LD $<\e[0m"
|
||||
@ -38,9 +38,8 @@ start.o: start.asm
|
||||
@${CC} ${CFLAGS} -I./include -c -o $@ $<
|
||||
@${ECHO} "\r\e[32;1m CC $<\e[0m"
|
||||
|
||||
core.d:
|
||||
core:
|
||||
@cd core; ${MAKE} ${MFLAGS}
|
||||
@touch core.d
|
||||
|
||||
initrd: fs
|
||||
@${ECHO} -n "\e[32m initrd Generating initial RAM disk\e[0m"
|
||||
|
@ -3,7 +3,7 @@ DIRS = fs
|
||||
|
||||
.PHONY: all clean install fs
|
||||
|
||||
all: system.o multiboot.o gdt.o idt.o irq.o isrs.o kbd.o kprintf.o timer.o vga.o mem.o panic.o alloc.o vfs.o fs
|
||||
all: system.o multiboot.o gdt.o idt.o irq.o isrs.o kbd.o kprintf.o timer.o vga.o mem.o panic.o alloc.o vfs.o shell.o fs
|
||||
|
||||
%.o: %.c
|
||||
@${ECHO} -n "\e[32m CC core/$<\e[0m"
|
||||
|
@ -98,6 +98,7 @@ readdir_initrd(
|
||||
uint32_t index
|
||||
) {
|
||||
ext2_inodetable_t * inode = ext2_get_inode(node->inode);
|
||||
assert(inode->mode & EXT2_S_IFDIR);
|
||||
ext2_dir_t * direntry = ext2_get_direntry(inode, index);
|
||||
if (!direntry) {
|
||||
return NULL;
|
||||
@ -135,7 +136,7 @@ finddir_initrd(
|
||||
dir_offset = 0;
|
||||
/*
|
||||
* Look through the requested entries until we find what we're looking for
|
||||
i*/
|
||||
*/
|
||||
while (dir_offset < inode->size) {
|
||||
ext2_dir_t * d_ent = (ext2_dir_t *)((uintptr_t)block + dir_offset);
|
||||
#if 0
|
||||
@ -341,7 +342,7 @@ ext2_get_direntry(
|
||||
uint32_t index
|
||||
) {
|
||||
void * block;
|
||||
block = (void *)ext2_get_block(inode->block[0]);
|
||||
block = (void *)ext2_get_inode_block(inode,0);
|
||||
uint32_t dir_offset;
|
||||
dir_offset = 0;
|
||||
uint32_t dir_index;
|
||||
|
16
core/kbd.c
16
core/kbd.c
@ -159,9 +159,25 @@ void
|
||||
keyboard_install() {
|
||||
/* IRQ installer */
|
||||
irq_install_handler(1, keyboard_handler);
|
||||
keyboard_buffer_handler = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
keyboard_wait() {
|
||||
while(inportb(0x64) & 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* putch
|
||||
*/
|
||||
void
|
||||
putch(
|
||||
unsigned char c
|
||||
) {
|
||||
if (keyboard_buffer_handler) {
|
||||
keyboard_buffer_handler(c);
|
||||
} else {
|
||||
writech(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,3 +103,41 @@ kprintf(
|
||||
args_end(args);
|
||||
puts(buf);
|
||||
}
|
||||
|
||||
char * kgets_buffer = NULL;
|
||||
int kgets_collected = 0;
|
||||
int kgets_want = 0;
|
||||
int kgets_newline = 0;
|
||||
|
||||
void
|
||||
kgets_handler(
|
||||
char ch
|
||||
) {
|
||||
writech(ch);
|
||||
if (ch == '\n') {
|
||||
kgets_newline = 1;
|
||||
return;
|
||||
}
|
||||
if (kgets_collected < kgets_want) {
|
||||
kgets_buffer[kgets_collected] = ch;
|
||||
kgets_collected++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kgets(
|
||||
char *buffer,
|
||||
int size
|
||||
) {
|
||||
kgets_buffer = buffer;
|
||||
kgets_collected = 0;
|
||||
kgets_want = size;
|
||||
kgets_newline = 0;
|
||||
keyboard_buffer_handler = kgets_handler;
|
||||
while ((kgets_collected < size) && (!kgets_newline)) {
|
||||
// spin spin spin
|
||||
}
|
||||
buffer[kgets_collected] = '\0';
|
||||
keyboard_buffer_handler = NULL;
|
||||
return kgets_collected;
|
||||
}
|
||||
|
102
core/shell.c
Normal file
102
core/shell.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* ToAruOS Kernel Shell
|
||||
*/
|
||||
#include <system.h>
|
||||
#include <fs.h>
|
||||
|
||||
void
|
||||
start_shell() {
|
||||
char path[1024];
|
||||
fs_node_t * node = fs_root;
|
||||
path[0] = '/';
|
||||
path[1] = '\0';
|
||||
while (1) {
|
||||
char buffer[1024];
|
||||
int size;
|
||||
kprintf("kernel %s> ", path);
|
||||
size = kgets((char *)&buffer, 1023);
|
||||
if (size < 1) {
|
||||
continue;
|
||||
} else {
|
||||
/*
|
||||
* Tokenize the command
|
||||
*/
|
||||
char * pch;
|
||||
char * cmd;
|
||||
char * save;
|
||||
pch = strtok_r(buffer," ",&save);
|
||||
cmd = pch;
|
||||
char * argv[1024];
|
||||
int tokenid = 0;
|
||||
while (pch != NULL) {
|
||||
argv[tokenid] = (char *)pch;
|
||||
++tokenid;
|
||||
pch = strtok_r(NULL," ",&save);
|
||||
}
|
||||
argv[tokenid] = NULL;
|
||||
/*
|
||||
* Execute the command
|
||||
*/
|
||||
if (!strcmp(cmd, "cd")) {
|
||||
if (tokenid < 2) {
|
||||
kprintf("cd: argument expected\n");
|
||||
continue;
|
||||
} else {
|
||||
if (argv[1][0] == '/') {
|
||||
fs_node_t * chd = kopen(argv[1], 0);
|
||||
if (chd) {
|
||||
node = chd;
|
||||
memcpy(path, argv[1], strlen(argv[1]));
|
||||
path[strlen(argv[1])] = '\0';
|
||||
} else {
|
||||
kprintf("cd: could not change directory\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(cmd, "cat")) {
|
||||
if (tokenid < 2) {
|
||||
kprintf("cat: argument expected\n");
|
||||
continue;
|
||||
} else {
|
||||
if (argv[1][0] == '/') {
|
||||
fs_node_t * file = kopen(argv[1],0);
|
||||
if (!file) {
|
||||
kprintf("cat: could not open file `%s`\n", argv[1]);
|
||||
continue;
|
||||
}
|
||||
char *bufferb = malloc(file->length + 200);
|
||||
size_t bytes_read = read_fs(file, 0, file->length, (uint8_t *)bufferb);
|
||||
size_t i = 0;
|
||||
for (i = 0; i < bytes_read; ++i) {
|
||||
writech(bufferb[i]);
|
||||
}
|
||||
free(bufferb);
|
||||
close_fs(file);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(cmd, "echo")) {
|
||||
if (tokenid < 2) {
|
||||
continue;
|
||||
} else {
|
||||
int i = 1;
|
||||
for (i = 1; i < tokenid; ++i) {
|
||||
kprintf("%s ", argv[i]);
|
||||
}
|
||||
kprintf("\n");
|
||||
}
|
||||
} else if (!strcmp(cmd, "ls")) {
|
||||
struct dirent * entry = NULL;
|
||||
int i = 0;
|
||||
entry = readdir_fs(node, i);
|
||||
while (entry != NULL) {
|
||||
kprintf("%s\n", entry->name);
|
||||
free(entry);
|
||||
i++;
|
||||
entry = readdir_fs(node, i);
|
||||
}
|
||||
} else {
|
||||
kprintf("Unrecognized command: %s\n", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -116,3 +116,80 @@ outportb(
|
||||
__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data));
|
||||
}
|
||||
|
||||
char *
|
||||
strtok_r(
|
||||
char * str,
|
||||
const char * delim,
|
||||
char ** saveptr
|
||||
) {
|
||||
char * token;
|
||||
if (str == NULL) {
|
||||
str = *saveptr;
|
||||
}
|
||||
str += strspn(str, delim);
|
||||
if (*str == '\0') {
|
||||
*saveptr = str;
|
||||
return NULL;
|
||||
}
|
||||
token = str;
|
||||
str = strpbrk(token, delim);
|
||||
if (str == NULL) {
|
||||
*saveptr = (char *)lfind(token, '\0');
|
||||
} else {
|
||||
*str = '\0';
|
||||
*saveptr = str + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
size_t
|
||||
lfind(
|
||||
const char * str,
|
||||
const char accept
|
||||
) {
|
||||
size_t i = 0;
|
||||
while ( str[i] != accept) {
|
||||
i++;
|
||||
}
|
||||
return (size_t)(str) + i;
|
||||
}
|
||||
|
||||
size_t
|
||||
strspn(
|
||||
const char * str,
|
||||
const char * accept
|
||||
) {
|
||||
const char * ptr;
|
||||
const char * acc;
|
||||
size_t size = 0;
|
||||
for (ptr = str; *ptr != '\0'; ++ptr) {
|
||||
for (acc = accept; *acc != '\0'; ++acc) {
|
||||
if (*ptr == *acc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*acc == '\0') {
|
||||
return size;
|
||||
} else {
|
||||
++size;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
char *
|
||||
strpbrk(
|
||||
const char * str,
|
||||
const char * accept
|
||||
) {
|
||||
while (*str != '\0') {
|
||||
const char *acc = accept;
|
||||
while (*acc != '\0') {
|
||||
if (*acc++ == *str) {
|
||||
return (char *) str;
|
||||
}
|
||||
}
|
||||
++str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
16
core/vfs.c
16
core/vfs.c
@ -32,7 +32,7 @@ void close_fs(fs_node_t *node) {
|
||||
}
|
||||
|
||||
struct dirent * readdir_fs(fs_node_t *node, uint32_t index) {
|
||||
if ((node->flags & 0x07) == FS_DIRECTORY && node->readdir != 0) {
|
||||
if ((node->flags & FS_DIRECTORY) && node->readdir != NULL) {
|
||||
return node->readdir(node, index);
|
||||
} else {
|
||||
return (struct dirent *)NULL;
|
||||
@ -40,7 +40,7 @@ struct dirent * readdir_fs(fs_node_t *node, uint32_t index) {
|
||||
}
|
||||
|
||||
fs_node_t *finddir_fs(fs_node_t *node, char *name) {
|
||||
if ((node->flags & FS_DIRECTORY) && node->readdir != 0) {
|
||||
if ((node->flags & FS_DIRECTORY) && node->readdir != NULL) {
|
||||
return node->finddir(node, name);
|
||||
} else {
|
||||
return (fs_node_t *)NULL;
|
||||
@ -59,11 +59,17 @@ kopen(
|
||||
if (!fs_root) {
|
||||
HALT_AND_CATCH_FIRE("Attempted to kopen() without a filesystem in place.");
|
||||
}
|
||||
if (!filename[0] == '/') {
|
||||
if (!filename) {
|
||||
HALT_AND_CATCH_FIRE("Attempted to kopen() without a filename.");
|
||||
}
|
||||
if (filename[0] != '/') {
|
||||
HALT_AND_CATCH_FIRE("Attempted to kopen() a non-absolute path.");
|
||||
}
|
||||
uint32_t path_len = strlen(filename);
|
||||
char * path = (char *)malloc(sizeof(char) * (path_len));
|
||||
size_t path_len = strlen(filename);
|
||||
if (path_len == 1) {
|
||||
return fs_root;
|
||||
}
|
||||
char * path = (char *)malloc(sizeof(char) * (path_len + 1));
|
||||
memcpy(path, filename, path_len);
|
||||
char * path_offset = path;
|
||||
uint32_t path_depth = 0;
|
||||
|
@ -67,13 +67,13 @@ cls() {
|
||||
}
|
||||
|
||||
/*
|
||||
* putch
|
||||
* Puts a character to the screen
|
||||
* writech
|
||||
* Write a character to the screen.
|
||||
*/
|
||||
void
|
||||
putch(
|
||||
writech(
|
||||
unsigned char c
|
||||
) {
|
||||
) {
|
||||
unsigned short *where;
|
||||
unsigned att = attrib << 8;
|
||||
if (c == 0x08) {
|
||||
|
@ -29,7 +29,11 @@ extern unsigned short *memsetw(unsigned short *dest, unsigned short val, int cou
|
||||
extern int strlen(const char *str);
|
||||
extern unsigned char inportb(unsigned short _port);
|
||||
extern void outportb(unsigned short _port, unsigned char _data);
|
||||
int strcmp(const char *a, const char *b);
|
||||
extern int strcmp(const char *a, const char *b);
|
||||
extern char * strtok_r(char * str, const char * delim, char ** saveptr);
|
||||
extern size_t lfind(const char * str, const char accept);
|
||||
extern size_t strspn(const char * str, const char * accept);
|
||||
extern char * strpbrk(const char * str, const char * accept);
|
||||
|
||||
/* Panic */
|
||||
#define HALT_AND_CATCH_FIRE(mesg) halt_and_catch_fire(mesg, __FILE__, __LINE__)
|
||||
@ -40,11 +44,11 @@ void assert_failed(const char *file, uint32_t line, const char *desc);
|
||||
|
||||
/* VGA driver */
|
||||
extern void cls();
|
||||
extern void putch(unsigned char c);
|
||||
extern void puts(char *str);
|
||||
extern void settextcolor(unsigned char forecolor, unsigned char backcolor);
|
||||
extern void resettextcolor();
|
||||
extern void init_video();
|
||||
extern void writech(unsigned char c);
|
||||
|
||||
/* GDT */
|
||||
extern void gdt_install();
|
||||
@ -82,11 +86,15 @@ extern long timer_ticks;
|
||||
extern void timer_wait(int ticks);
|
||||
|
||||
/* Keyboard */
|
||||
typedef void (*keyboard_buffer_t)(char ch);
|
||||
keyboard_buffer_t keyboard_buffer_handler;
|
||||
extern void keyboard_install();
|
||||
extern void keyboard_wait();
|
||||
extern void putch(unsigned char c);
|
||||
|
||||
/* kprintf */
|
||||
extern void kprintf(const char *fmt, ...);
|
||||
extern int kgets(char *buf, int size);
|
||||
|
||||
/* Memory Management */
|
||||
extern uintptr_t placement_pointer;
|
||||
@ -133,4 +141,7 @@ void * __attribute__ ((malloc)) realloc(void *ptr, size_t size);
|
||||
void * __attribute__ ((malloc)) calloc(size_t nmemb, size_t size);
|
||||
void free(void *ptr);
|
||||
|
||||
/* shell */
|
||||
extern void start_shell();
|
||||
|
||||
#endif
|
||||
|
15
main.c
15
main.c
@ -109,19 +109,8 @@ int main(struct multiboot *mboot_ptr)
|
||||
close_fs(test_file);
|
||||
free(test_file);
|
||||
free(buffer);
|
||||
#if 0
|
||||
test_file = kopen("/usr/docs/README.md", NULL);
|
||||
char *bufferb = malloc(test_file->length + 200);
|
||||
bytes_read = read_fs(test_file, 100, test_file->length, bufferb);
|
||||
for (i = 0; i < bytes_read; ++i) {
|
||||
kprintf("%c", (char)bufferb[i]);
|
||||
if (i % 500 == 0) {
|
||||
timer_wait(10);
|
||||
}
|
||||
}
|
||||
free(bufferb);
|
||||
close_fs(test_file);
|
||||
#endif
|
||||
|
||||
start_shell();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user