Files
osc2025/kernel/lib/shell.c
2025-04-08 07:01:24 +08:00

177 lines
3.4 KiB
C

#include <stddef.h>
#include <errcode.h>
#include <kmalloc.h>
#include <utils.h>
#include <string.h>
#include <uart.h>
#include <mbox.h>
#include <shell.h>
#include <exec.h>
#include <mman.h>
#define INPUT_BUFLEN 1000
#define PM_PASSWORD 0x5a000000
#define PM_RSTC 0x3F10001c
#define PM_WDOG 0x3F100024
static inline
void _help (void)
{
uart_puts(
"help : print this help menu" ENDL
"hello : print Hello World!" ENDL
"hwinfo : print hardware info" ENDL
"memalloc <size>: alloate memory and print" ENDL
"ls : list directory contents" ENDL
"cat <file>: concatenate files and print" ENDL
"exec <file>: execute file in usermode" ENDL
"reboot : reboot the device" ENDL
);
}
static inline
void _hello (void)
{
uart_puts("hello, world" ENDL);
}
static inline
void _hwinfo (void)
{
uart_puts(
"hwinfo: " ENDL
"board revision: "
);
uart_hex(get_board_revision());
uart_puts(
ENDL
"memory base addr: "
);
uart_hex(get_memory_base_addr());
uart_puts(
ENDL
"memory size: "
);
uart_hex(get_memory_size());
uart_puts(ENDL);
}
static inline
void _memalloc(size_t size)
{
void *addr = kmalloc(size);
uart_puts("size: ");
uart_hex(size);
uart_puts(ENDL);
uart_puts("addr: ");
uart_hex((uint64_t)addr);
uart_puts(ENDL);
}
static inline
void _ls_initrd_callback(file_node_t *tr)
{
uart_puts(tr->filename);
uart_puts(ENDL);
}
static inline
void _ls(file_node_t *root)
{
initrd_traverse(root, _ls_initrd_callback);
}
static inline
void _cat(file_node_t *root, const char *filename)
{
file_node_t *tr = initrd_get(root, filename);
if (tr) {
uart_puts((char *)tr->filecontent);
} else {
exit(ERR_NOT_EXIST);
}
}
static inline
void _exec(file_node_t *root, const char *filename)
{
file_node_t *tr = initrd_get(root, filename);
if (tr) {
void *userspace = allocate_page(1 << 6);
memcpy(userspace, tr->filecontent, tr->filesize);
user_exec(userspace, userspace + (1 << (12 + 6)) - 8);
kfree(userspace);
} else {
exit(ERR_NOT_EXIST);
}
}
static inline
void _set(long addr, unsigned int value) {
volatile unsigned int* point = (unsigned int*)addr;
*point = value;
}
static inline
void _reset(int tick) { // reboot after watchdog timer expire
_set(PM_RSTC, PM_PASSWORD | 0x20); // full reset
_set(PM_WDOG, PM_PASSWORD | tick); // number of watchdog tick
}
static inline
void _reboot(void)
{
_reset(1 << 16);
}
int shell(file_node_t *initrd_root)
{
uart_puts("# ");
char buf[INPUT_BUFLEN], ch;
int sz = 0;
while ((ch = uart_getc()) != '\n') {
buf[sz++] = ch;
uart_send(ch);
}
uart_puts(ENDL);
buf[sz] = '\0';
const char *i = buf;
char bin[INPUT_BUFLEN], *j;
for (j = bin; *i != '\0' && !isspace(*i); ++i, ++j)
*j = *i;
*j = '\0';
for (; *i != '\0' && isspace(*i); ++i);
char param[INPUT_BUFLEN];
for (j = param; *i != '\0' && !isspace(*i); ++i, ++j)
*j = *i;
*j = '\0';
if (!strcmp(bin, "help")) {
_help();
} else if (!strcmp(bin, "hello")) {
_hello();
} else if (!strcmp(bin, "hwinfo")) {
_hwinfo();
} else if (!strcmp(bin, "memalloc")){
_memalloc((size_t)atoi32(param));
} else if (!strcmp(bin, "ls")) {
_ls(initrd_root);
} else if (!strcmp(bin, "cat")) {
_cat(initrd_root, param);
} else if (!strcmp(bin, "exec")) {
_exec(initrd_root, param);
} else if (!strcmp(bin, "reboot")) {
_reboot();
}
return true;
}