172 lines
4.6 KiB
C
172 lines
4.6 KiB
C
/*
|
|
* @author xamidev <xamidev@riseup.net>
|
|
* @brief PepperOS kernel shell
|
|
* @license GPL-3.0-only
|
|
*/
|
|
|
|
#include "fs/initfs.h"
|
|
#include <io/term/term.h>
|
|
#include <config.h>
|
|
#include <io/kbd/ps2.h>
|
|
#include <string/string.h>
|
|
#include <stdint.h>
|
|
#include <kernel.h>
|
|
#include <time/date.h>
|
|
#include <mem/kheap.h>
|
|
#include <sched/process.h>
|
|
|
|
__attribute__((noinline))
|
|
void smash_it()
|
|
{
|
|
char buf[16]; (void)buf;
|
|
for (size_t i=0; i<256; i++) {
|
|
buf[i] = (char)i;
|
|
}
|
|
}
|
|
|
|
extern struct process* processes_list;
|
|
|
|
void ps()
|
|
{
|
|
printf("pid\tname\tstatus\n");
|
|
struct process* curr = processes_list;
|
|
while (curr != NULL) {
|
|
char* status;
|
|
switch (curr->status) {
|
|
case READY: status = "READY"; break;
|
|
case RUNNING: status = "RUNNING"; break;
|
|
case DEAD: status = "DEAD"; break;
|
|
default: status = "N/A"; break;
|
|
}
|
|
printf("%u\t%s\t%s\n", curr->pid, curr->name, status);
|
|
if (curr->next != NULL) {
|
|
curr = curr->next;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void kill()
|
|
{
|
|
char input_buf[11] = {0};
|
|
printf("pid> ");
|
|
keyboard_getline(input_buf, 10);
|
|
int pid = atoi(input_buf);
|
|
|
|
struct process* curr = processes_list;
|
|
while (curr != NULL) {
|
|
if (curr->pid == (size_t)pid) {
|
|
curr->status = DEAD; // equivalent of SIGKILL (no clean termination like SIGTERM)
|
|
printf("killed %d\n", pid);
|
|
break;
|
|
}
|
|
if (curr->next != NULL) {
|
|
curr = curr->next;
|
|
} else {
|
|
printf("couldn't find process with PID %d\n", pid);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* pedicel_main - Kernel shell main function
|
|
* @arg: argument (optional)
|
|
*
|
|
* This is the entry point for the kernel shell process.
|
|
* It is used to start programs and to test different things
|
|
* on different real hardware easily.
|
|
*
|
|
* Named after the root part of the pepper.
|
|
*/
|
|
void pedicel_main(void* arg)
|
|
{
|
|
(void)arg;
|
|
printf("Welcome to the kernel shell!\r\nType 'help' for a list of commands.\r\n");
|
|
|
|
for (;;) {
|
|
char input_buf[PEDICEL_INPUT_SIZE] = {0};
|
|
printf(PEDICEL_PROMPT);
|
|
keyboard_getline(input_buf, PEDICEL_INPUT_SIZE);
|
|
|
|
if (strncmp(input_buf, "help", 4) == 0) {
|
|
printf("++ shell builtins ++\r\n\r\n"
|
|
"\tclear - clear the screen\n"
|
|
"\tpanic - trigger a test panic\n"
|
|
"\tsyscall - trigger int 0x80\n"
|
|
"\tpf - trigger a page fault\n"
|
|
"\tnow - get current date\n"
|
|
"\tsmash - smash the stack\n"
|
|
"\tmem - get used heap info\n"
|
|
"\tload - load an user executable\n"
|
|
"\tlist - list initfs.tar contents\n"
|
|
"\tps - list running processes\n"
|
|
"\tkill - kill a running process by PID\n");
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "", 1) == 0) {
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "clear", 5) == 0) {
|
|
printf("\x1b[2J\x1b[H");
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "panic", 5) == 0) {
|
|
panic(NULL, "test panic");
|
|
}
|
|
|
|
if (strncmp(input_buf, "syscall", 7) == 0) {
|
|
__asm__ volatile("mov $0x00, %rdi");
|
|
__asm__ volatile("int $0x80");
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "pf", 2) == 0) {
|
|
volatile uint64_t* fault = (uint64_t*)0xdeadbeef;
|
|
fault[0] = 1;
|
|
}
|
|
|
|
if (strncmp(input_buf, "now", 3) == 0) {
|
|
struct date now = date_now();
|
|
printf("Now is %02u:%02u:%02u on %u/%u/%u\r\n", now.hour, now.minute,
|
|
now.second, now.day, now.month, now.year);
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "smash", 5) == 0) {
|
|
smash_it();
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "mem", 3) == 0) {
|
|
kheap_info();
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "load", 4) == 0) {
|
|
loader_load_raw();
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "list", 4) == 0) {
|
|
tar_list();
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "ps", 2) == 0) {
|
|
ps();
|
|
continue;
|
|
}
|
|
|
|
if (strncmp(input_buf, "kill", 4) == 0) {
|
|
kill();
|
|
continue;
|
|
}
|
|
|
|
printf("%s: command not found\r\n", input_buf);
|
|
}
|
|
} |