Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/apps/init/src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ void init() {

int shell_pid = proc_open("shell", 0, 0);
// printf("Shell got pid %d\n", shell_pid);
// proc_set_foreground(shell_pid);
proc_set_foreground(shell_pid);

for (;;) {
yield();
}
proc_wait_pid(shell_pid, 0);
printf("Shell exited\n");

// for (;;) {
// yield();
// }
}

void __start() {
Expand Down
71 changes: 18 additions & 53 deletions src/apps/shell/src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ int term_last_ret = 0;

void term_run();
static int help_cmd(size_t argc, char ** argv);
static int exit_cmd(size_t argc, char ** argv);
static size_t buff_read(const cb_t * cb, uint8_t * data, size_t count);
static size_t buff_remove(cb_t * cb, size_t count);
static void exec_buff();

int main(size_t argc, char ** argv) {
term_command_add("help", help_cmd);
term_command_add("exit", exit_cmd);
init_commands();

if (cb_create(&keybuff, MAX_CHARS, 1)) {
Expand All @@ -68,48 +70,15 @@ static void dump_buff() {
}
}

static void key_cb(uint8_t code, char c, keyboard_event_t event, keyboard_mod_t mod) {
if ((event == KEY_EVENT_PRESS || event == KEY_EVENT_REPEAT) && c) {
if (cb_len(&keybuff) >= MAX_CHARS) {
ERROR("key buffer overflow");
printf("(%u out of %u)", cb_len(&keybuff), MAX_CHARS);
PANIC("key buffer overflow");
return;
}

if (code == KEY_BACKSPACE) {
if (cb_len(&keybuff) > 0) {
putc(c);
cb_rpop(&keybuff, 0);
}
return;
}

if (cb_push(&keybuff, &c)) {
ERROR("key buffer write error");
return;
}

// kprintf("Circbuff char %x at len %d / %d\n", c, circbuff_len(&keybuff), circbuff_buff_size(&keybuff));
// dump_buff();

if (code == KEY_ENTER) {
command_ready++;
}

putc(c);
}
}

static void key_char_cb(char c) {
static void char_cb(char c) {
if (cb_len(&keybuff) >= MAX_CHARS) {
ERROR("key buffer overflow");
printf("(%u out of %u)", cb_len(&keybuff), MAX_CHARS);
PANIC("key buffer overflow");
return;
}

if (c == KEY_BACKSPACE) {
if (c == '\b') {
if (cb_len(&keybuff) > 0) {
putc(c);
cb_rpop(&keybuff, 0);
Expand All @@ -122,17 +91,13 @@ static void key_char_cb(char c) {
return;
}

if (c == KEY_ENTER) {
if (c == '\n') {
command_ready++;
}

putc(c);
}

static void key_event_handler(const ebus_event_t * event) {
key_cb(event->key.keycode, event->key.c, event->key.event, event->key.mods);
}

static int help_cmd(size_t argc, char ** argv) {
for (size_t i = 0; i < n_commands; i++) {
puts(commands[i].command);
Expand All @@ -141,6 +106,14 @@ static int help_cmd(size_t argc, char ** argv) {
return 0;
}

static int exit_cmd(size_t argc, char ** argv) {
if (argc > 1) {
int status = katoi(argv[1]);
proc_exit(status);
}
proc_exit(0);
}

void term_update() {
if (!command_ready) {
return;
Expand Down Expand Up @@ -197,19 +170,9 @@ void term_run() {
puts("$ ");

for (;;) {
ebus_event_t event;
if (!pull_event(EBUS_EVENT_KEY, &event)) {
// printf("Got event type 0x%04x located at %p\n", event.event_id, &event);
key_cb(event.key.keycode, event.key.c, event.key.event, event.key.mods);
// printf("Got key %c keycode 0x%x scancode 0x%x location %p\n", event.key.c, event.key.keycode, event.key.scancode, &event);
// if (event.key.event == 0) {
// putc(event.key.c);
// }

// char c = getc();
// if (c) {
// key_char_cb(c);
// }
char c;
if (file_read(stdin, 1, 1, &c) == 1) {
char_cb(c);
}
term_update();
}
Expand Down Expand Up @@ -335,11 +298,13 @@ static void exec_buff() {
printf("Unknown command '%s'\n", argv[0]);
term_last_ret = 1;
}
proc_set_foreground(pid);

int exit_status = 0;
if (!proc_wait_pid(pid, &exit_status) && exit_status) {
printf("Process exited with status %d\n", exit_status);
}
proc_set_foreground(getpid());
}

// Free parsed args
Expand Down
1 change: 1 addition & 0 deletions src/ebus/include/ebus.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum EBUS_EVENT {
EBUS_EVENT_EXEC,
EBUS_EVENT_PROC_MADE,
EBUS_EVENT_PROC_CLOSE,
EBUS_EVENT_STDIN_READY,
EBUS_EVENT_CUSTOM,
};

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/kernel/io_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int io_buffer_pop(io_buffer_t * buff, char * c_out) {
return -1;
}

return 0;
return cb_pop(cb, c_out);
}

size_t io_buffer_size(const io_buffer_t * buff) {
Expand Down
3 changes: 3 additions & 0 deletions src/kernel/src/kernel/system_call_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ int sys_call_event_cb(uint32_t call_id, void * args_data, registers_t * regs) {
kernel_switch_task();
KLOG_TRACE("Back from timer %u", timer_id);
} while (proc->next_event.timer.id != timer_id);

proc->filter_event.event_id = 0;
proc->next_event.event_id = 0;
} break;
}

Expand Down
62 changes: 43 additions & 19 deletions src/kernel/src/kernel/system_call_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,40 +67,64 @@ int sys_call_io_cb(uint32_t call_id, void * args_data, registers_t * regs) {
size_t pos;
} * args = (struct _args *)args_data;

if (args->handle < 0 || !args->buff || !args->count) {
if (args->handle < 0) {
KLOG_WARNING("Process %u tried to read from invalid handle", proc->pid);
return 0;
}
if (!args->buff) {
KLOG_WARNING("Process %u tried to read into null buffer", proc->pid);
return 0;
}
if (!args->count) {
KLOG_WARNING("Process %u read with 0 count", proc->pid);
return 0;
}

// TODO get stdin handle and use device read
// TODO add buffer to handle_t

if (args->handle == 0) {
size_t available = io_buffer_length(proc->io_buffer);
size_t count = args->count; // idk if this needs to be copied or can be edited in place
if (count > available) {
count = available;
}
KLOG_TRACE("Process %u reading %u characters from stdin", proc->pid, args->count);

size_t written = 0;
size_t count = args->count; // idk if this needs to be copied or can be edited in place

if (count > 0) {
for (size_t i = 0; i < count; i++) {
if (io_buffer_pop(proc->io_buffer, &args->buff[i])) {
break;
while (count) {
size_t available = io_buffer_length(proc->io_buffer);
// Use available as the number to read, limit to count if greater than
if (available > count) {
available = count;
}

for (size_t i = 0; i < available; i++) {
if (io_buffer_pop(proc->io_buffer, &args->buff[written++])) {
KLOG_WARNING("Failed to pop from io buffer for process %u", proc->pid);
// TODO should this be -1?
return written;
}
}
count -= available;

if (count) {
// yield
proc->next_event.event_id = 0;
proc->filter_event.event_id = EBUS_EVENT_STDIN_READY;
proc->state = PROCESS_STATE_WAITING;

enable_interrupts();
kernel_switch_task();
}
}

return count;
}
proc->filter_event.event_id = 0;
proc->next_event.event_id = 0;

handle_t * h = process_get_handle(proc, args->handle);
if (!h) {
KPANIC("Failed to find handle");
return written;
}
else {
KLOG_WARNING("Process %u trying to read from unsupported handle %d", proc->pid, args->handle);
return 0;
}

// io_device_t * d = h->device;

// return d->read_fn(d->data, args->buff, args->count, args->pos);
} break;

case SYS_CALL_IO_WRITE: {
Expand Down
13 changes: 10 additions & 3 deletions src/kernel/src/kernel/system_call_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) {

enable_interrupts();
kernel_switch_task();

proc->filter_event.event_id = 0;
proc->next_event.event_id = 0;
} break;

case SYS_CALL_PROC_EXEC: {
Expand Down Expand Up @@ -190,11 +193,15 @@ int sys_call_proc_cb(uint32_t call_id, void * args_data, registers_t * regs) {
proc->filter_event.proc_close.pid = args->pid;
proc->state = PROCESS_STATE_WAITING;

do {
for (;;) {
enable_interrupts();
kernel_switch_task();
KLOG_TRACE("Back from timer %u", timer_id);
} while (proc->next_event.proc_close.pid != args->pid);
if (proc->next_event.proc_close.pid == args->pid) {
KLOG_DEBUG("Waited process %u has closed, waiting process is %u", args->pid, proc->pid);
break;
}
proc->next_event.event_id = 0;
}

if (!(proc->next_event.event_id == proc->filter_event.event_id)) {
KPANIC("Tried to resume process but the event does not match filter");
Expand Down
68 changes: 42 additions & 26 deletions src/kernel/src/process_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,36 +203,34 @@ process_t * pm_get_next(proc_man_t * pm) {

process_t * proc = pm->current_task->next;

KLOG_TRACE("Start looking for next process after %u", pm->current_task->pid);

do {
KLOG_TRACE("Looking at pid %u in state %u to see if it's ready", proc->pid, proc->state);

if (proc->state > PROCESS_STATE_LOADED && proc->state < PROCESS_STATE_DEAD) {
if (!proc->filter_event.event_id) {
KLOG_TRACE("Process %u has no filter event, so it's ready", proc->pid);
return proc;
for (;;) {
KLOG_TRACE("Start looking for next process after %u", pm->current_task->pid);

do {
KLOG_TRACE("Looking at pid %u in state %u to see if it's ready", proc->pid, proc->state);

if (proc->state > PROCESS_STATE_LOADED && proc->state < PROCESS_STATE_DEAD) {
if (!proc->filter_event.event_id) {
KLOG_TRACE("Process %u has no filter event, so it's ready", proc->pid);
return proc;
}
// This handles the above case but is split for trace log
if (proc->filter_event.event_id == proc->next_event.event_id) {
KLOG_DEBUG("Process %u has ready event %u", proc->pid, proc->next_event.event_id);
return proc;
}
KLOG_TRACE("Process %u is not ready, waiting for %u", proc->pid, proc->filter_event.event_id);
}
// This handles the above case but is split for trace log
if (proc->filter_event.event_id == proc->next_event.event_id) {
KLOG_TRACE("Process %u has ready event %u", proc->pid, proc->next_event.event_id);
return proc;
else {
KLOG_TRACE("Process with pid %u is not alive", proc->pid);
}
KLOG_TRACE("Process %u is not ready, waiting for %u", proc->pid, proc->filter_event.event_id);
}
else {
KLOG_TRACE("Process with pid %u is not alive", proc->pid);
}

KLOG_TRACE("Going to next process %u, fg is %u", proc->next->pid, pm->current_task->pid);
proc = proc->next;
} while (proc != pm->current_task->next);

KLOG_TRACE("Finish looking for next process");
KLOG_TRACE("Going to next process %u, fg is %u", proc->next->pid, pm->current_task->pid);
proc = proc->next;
} while (proc != pm->current_task->next);

if (PROCESS_STATE_LOADED <= proc->state <= PROCESS_STATE_DEAD) {
KLOG_TRACE("Next process is the foreground process with pid %u", proc->pid);
return proc;
KLOG_TRACE("No process ready to resume. Halting until next event");
asm("hlt");
}

KPANIC("Could not find process to resume");
Expand Down Expand Up @@ -282,5 +280,23 @@ int pm_push_event(proc_man_t * pm, ebus_event_t * event) {

KLOG_TRACE("Finish push event %u", event->event_id);

// TODO this is a temp hack to get keyboard to process until better stdin is created
if (event->event_id == EBUS_EVENT_KEY && (event->key.event == KEY_EVENT_PRESS || event->key.event == KEY_EVENT_REPEAT) && event->key.c) {
process_t * fg = pm->foreground_task;
if (io_buffer_push(fg->io_buffer, event->key.c)) {
KLOG_WARNING("Failed to push keyboard char %c to process %u io buffer", event->key.c, fg->pid);
}
else {
KLOG_TRACE("Process %u currently waiting on %u", fg->pid, fg->filter_event.event_id);
if (fg->filter_event.event_id == EBUS_EVENT_STDIN_READY) {
KLOG_TRACE("Process %u was waiting for stdin, setting next_event to stdin ready", fg->pid);
fg->next_event.event_id = EBUS_EVENT_STDIN_READY;
}
KLOG_TRACE("Pushed char '%c' (0x%02X) to process %u io buffer resulting in length %u", event->key.c, event->key.c, fg->pid, io_buffer_length(fg->io_buffer));
}
}

KLOG_TRACE("Finish stdio %u", event->event_id);

return 0;
}
Loading