[shell] Kernel debug shell and all the things I needed to make to support that.

This commit is contained in:
Kevin Lange 2011-02-07 14:30:17 -06:00
parent beaa7fda54
commit afa85d9b39
11 changed files with 270 additions and 31 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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