summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2020-09-13 19:51:09 -0400
committerBenji Dial <benji6283@gmail.com>2020-09-13 19:51:09 -0400
commit143156f63e2448733f1a35a74e629fe0ae9bb567 (patch)
treebcf70a6940038986da2cfb2d6ed380ed8ebb91de
parent54101cf327b7def90636babbadbb66ce697298ee (diff)
downloadportland-os-143156f63e2448733f1a35a74e629fe0ae9bb567.tar.gz
have command shell block while commands are running
-rw-r--r--doc/ints.txt6
-rw-r--r--src/kernel/elf.c12
-rw-r--r--src/kernel/elf.h2
-rw-r--r--src/kernel/idt.c14
-rw-r--r--src/kernel/isrs.asm2
-rw-r--r--src/kernel/kbd.c2
-rw-r--r--src/kernel/task.c22
-rw-r--r--src/kernel/task.h10
-rw-r--r--src/user/highway/highway.c4
-rw-r--r--src/user/include/knob/task.h4
-rw-r--r--src/user/include/pland/syscall.h12
-rw-r--r--src/user/init/init.c2
-rw-r--r--src/user/knob/task.c11
13 files changed, 72 insertions, 31 deletions
diff --git a/doc/ints.txt b/doc/ints.txt
index dd47d81..191d719 100644
--- a/doc/ints.txt
+++ b/doc/ints.txt
@@ -15,7 +15,6 @@ see table 1
file system calls have units of bytes unless otherwise specified
functions returning handles or pointers use 0 to indicate error
-functions returning "success" use 1 for success and 0 for failure
see keys.txt for the return type of the "get key" system call
the edx register of "start task" is a pointer to a null-terminated string.
a pointer to a readonly copy of this string is put into the new task's edx.
@@ -31,11 +30,14 @@ table 1:
close file | 0x1 | | handle | | | |
file read | 0x2 | read | handle | file offset | count | buffer |
get file size | 0x3 | size | handle | | | |
- start task | 0x4 | success | drive number | path | passed sz | |
+ start task | 0x4 | handle | drive number | path | passed sz | |
log string | 0x5 | | sz string | | | |
get key | 0x6 | keycode | | | | |
allocate ram | 0x7 | start pointer | pages | | | |
memory info | 0x8 | see table 2 | see table 2 | | | |
+ wait for task | 0x9 | | handle | | | |
+
+
table 2:
diff --git a/src/kernel/elf.c b/src/kernel/elf.c
index 8113c14..60fa3a9 100644
--- a/src/kernel/elf.c
+++ b/src/kernel/elf.c
@@ -73,10 +73,10 @@ struct ph_entry {
uint32_t align;
} __attribute__ ((packed));
-bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma) {
+uint32_t try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma) {
file_id_t h = d->get_file(d, path);
if (!h)
- return false;
+ return 0;
struct elf_header ehead;
@@ -87,7 +87,7 @@ bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_v
(ehead.endianness != LITTLE_ENDIAN) ||
ehead.os_abi_version) {
d->free_file(d, h);
- return false;
+ return 0;
}
uint32_t phtable_size = ehead.phentry_size * ehead.phtable_count;
@@ -104,7 +104,7 @@ bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_v
continue;
void *pma = pd_user_allocate(pd, entry->vma, (entry->vms - 1) / 4096 + 1, entry->flags & PH_WRITABLE);
fmcpy(pma, d, h, entry->fa, entry->fs);
- for (uint8_t *pma_i = pma + entry->fs; pma_i < pma + entry->vms; ++pma_i)
+ for (uint8_t *pma_i = pma + entry->fs; pma_i < (uint8_t *)pma + entry->vms; ++pma_i)
*pma_i = 0;
}
@@ -128,6 +128,7 @@ bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_v
tstate.page_directory = pd;
tstate.ret_addr = ehead.entry_vma;
tstate.edx = (uint32_t)pass_vma;
+ tstate.wait_mode = NONE;
const char *path_end_start = path;
for (const char *i = path; *i; ++i)
@@ -142,6 +143,5 @@ bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_v
}
tstate.name[i] = '\0';
- new_task(tstate);
- return true;
+ return new_task(tstate);
} \ No newline at end of file
diff --git a/src/kernel/elf.h b/src/kernel/elf.h
index 98489f2..89726c9 100644
--- a/src/kernel/elf.h
+++ b/src/kernel/elf.h
@@ -4,6 +4,6 @@
#include <stdint.h>
#include "drive.h"
-bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma);
+uint32_t try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma);
#endif \ No newline at end of file
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
index b789d42..4ffa1e2 100644
--- a/src/kernel/idt.c
+++ b/src/kernel/idt.c
@@ -54,11 +54,11 @@ static uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t cou
return count;
}
-static bool sc_start_task(uint32_t drive_number, char *path, const char *pass) {
+static uint32_t sc_start_task(uint32_t drive_number, char *path, const char *pass) {
switch_to_kernel_cr3();
- bool result = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass);
+ uint32_t process_id = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass);
switch_to_task_cr3();
- return result;
+ return process_id;
}
static void *sc_allocate_ram(uint32_t pages) {
@@ -91,6 +91,11 @@ static uint32_t sc_memory_info(enum mi_arg arg) {
}
}
+static void sc_wait_for_task(uint32_t handle) {
+ active_task->wait_mode = PROCESS_END;
+ active_task->wait_arg = handle;
+}
+
void const *syscall_table[] = {
&sc_open_file,
&sc_close_file,
@@ -100,7 +105,8 @@ void const *syscall_table[] = {
&logsz,
&get_key_code,
&sc_allocate_ram,
- &sc_memory_info
+ &sc_memory_info,
+ &sc_wait_for_task
};
//these aren't really void ()'s, but gcc complains if we take an address of a void, so we give it a type
diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm
index 4f2d4e2..8a27d57 100644
--- a/src/kernel/isrs.asm
+++ b/src/kernel/isrs.asm
@@ -23,7 +23,7 @@ extern on_kbd_isr
extern make_sure_tasks
extern exception_halt
-n_syscalls equ 0x9
+n_syscalls equ 0xa
;section .bss
;_debug_is_start_task resb 1
diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c
index 73a5ec6..f3eb323 100644
--- a/src/kernel/kbd.c
+++ b/src/kernel/kbd.c
@@ -1,7 +1,5 @@
#include <stdint.h>
-#include <stdbool.h>
#include "panic.h"
-#include "log.h"
#include "util.h"
static uint32_t *kbd_in_pointer;
diff --git a/src/kernel/task.c b/src/kernel/task.c
index 6c53510..942d1c4 100644
--- a/src/kernel/task.c
+++ b/src/kernel/task.c
@@ -64,11 +64,11 @@ void init_tasks() {
: : : "ax");
}
-void new_task(struct task_state state) {
+uint32_t new_task(struct task_state state) {
for (uint8_t n = 0; n < MAX_TASKS; ++n)
if (!tasks[n].page_directory) {
tasks[n] = state;
- return;
+ return n + 1;
}
PANIC("Maximum number of tasks reached.");
}
@@ -77,15 +77,20 @@ void advance_active_task() {
do
if (++active_task == tasks + MAX_TASKS)
active_task = tasks;
- while (!active_task->page_directory);
+ while (!active_task->page_directory || active_task->wait_mode);
}
void make_sure_tasks() {
for (uint8_t n = 0; n < MAX_TASKS; ++n)
if (tasks[n].page_directory)
- return;
+ while (1) {
+ for (uint8_t n = 0; n < MAX_TASKS; ++n)
+ if (tasks[n].page_directory && !tasks[n].wait_mode)
+ return;
+ asm ("hlt");
+ }
set_log_mode(LOG_SYSTEM);
- logsz("No active tasks, halting.");
+ logsz("No tasks, halting.");
while (1)
asm ("hlt");
}
@@ -95,4 +100,11 @@ void delete_task(struct task_state *state) {
free_task_pd(state->page_directory);
switch_to_task_cr3();
state->page_directory = 0;
+
+ uint32_t handle = state - tasks + 1;
+ for (uint8_t n = 0; n < MAX_TASKS; ++n)
+ if (tasks[n].page_directory &&
+ (tasks[n].wait_mode == PROCESS_END) &&
+ (tasks[n].wait_arg == handle))
+ tasks[n].wait_mode = NONE;
} \ No newline at end of file
diff --git a/src/kernel/task.h b/src/kernel/task.h
index 0fa9688..50be93a 100644
--- a/src/kernel/task.h
+++ b/src/kernel/task.h
@@ -6,6 +6,11 @@
#define TASK_NAME_LEN 15
+enum wait_mode {
+ NONE,
+ PROCESS_END,
+};
+
struct task_state {
uint32_t ret_addr;
void *page_directory;
@@ -18,6 +23,9 @@ struct task_state {
uint32_t ebp;
uint32_t esp;
+ enum wait_mode wait_mode;
+ uint32_t wait_arg;
+
char name[TASK_NAME_LEN + 1];
} __attribute__ ((packed));
@@ -25,7 +33,7 @@ extern struct task_state *active_task;
void init_tasks();
-void new_task(struct task_state state);
+uint32_t new_task(struct task_state state);
void advance_active_task();
void delete_task(struct task_state *state);
diff --git a/src/user/highway/highway.c b/src/user/highway/highway.c
index 8dc0080..7e78472 100644
--- a/src/user/highway/highway.c
+++ b/src/user/highway/highway.c
@@ -18,9 +18,7 @@ void main() {
ask_user_line_sz(line_buf, 1023);
if (blockequ(line_buf, "exit", 5))
return;
- if (try_run_command(path_buf))
- yield_task();
- else
+ if (!try_run_command_blocking(path_buf))
tell_user_sz("An error occured trying to run that command.\n");
}
} \ No newline at end of file
diff --git a/src/user/include/knob/task.h b/src/user/include/knob/task.h
index ea5df62..6539a00 100644
--- a/src/user/include/knob/task.h
+++ b/src/user/include/knob/task.h
@@ -1,9 +1,11 @@
#ifndef KNOB_TASK_H
#define KNOB_TASK_H
+#include <stdint.h>
#include <stdbool.h>
-bool try_run_command(const char *path);
+uint32_t run_command(const char *path);
+bool try_run_command_blocking(const char *path);
void yield_task();
#endif \ No newline at end of file
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index c597e2b..75383fc 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -8,6 +8,7 @@ typedef uint32_t _file_handle_t;
typedef uint32_t _task_handle_t;
typedef uint32_t _drive_number_t;
typedef uint32_t _pages_t;
+typedef uint32_t _process_handle_t;
typedef enum {
_KEY_BACKSPACE = '\b',
@@ -43,7 +44,8 @@ enum _scn {
_SCN_LOG_STRING,
_SCN_GET_KEY,
_SCN_ALLOCATE_RAM,
- _SCN_MEMORY_INFO
+ _SCN_MEMORY_INFO,
+ _SCN_WAIT_FOR_TASK
};
static inline uint32_t _sc0(enum _scn eax) {
@@ -124,8 +126,8 @@ static inline uint32_t _file_size(_file_handle_t handle) {
return _sc1(_SCN_FILE_SIZE, handle);
}
-static inline bool _start_task(_drive_number_t drive_number, const char *path, const char *pass) {
- return (bool)_sc3(_SCN_START_TASK, drive_number, (uint32_t)path, (uint32_t)pass);
+static inline _process_handle_t _start_task(_drive_number_t drive_number, const char *path, const char *pass) {
+ return _sc3(_SCN_START_TASK, drive_number, (uint32_t)path, (uint32_t)pass);
}
static inline void _log_string(const char *sz) {
@@ -160,4 +162,8 @@ static inline _pages_t _this_process_memory_left() {
return _sc1(_SCN_MEMORY_INFO, 0x4);
}
+static inline void _wait_for_task(_process_handle_t handle) {
+ _sc1(_SCN_WAIT_FOR_TASK, handle);
+}
+
#endif \ No newline at end of file
diff --git a/src/user/init/init.c b/src/user/init/init.c
index 390b731..e878603 100644
--- a/src/user/init/init.c
+++ b/src/user/init/init.c
@@ -7,7 +7,7 @@ void start(const char *cmd) {
tell_user_sz(cmd);
tell_user_sz(": ");
tell_user_sz(
- try_run_command(cmd)
+ run_command(cmd)
? "Succeded.\n"
: "Failed.\n"
);
diff --git a/src/user/knob/task.c b/src/user/knob/task.c
index 598bee2..df5d38f 100644
--- a/src/user/knob/task.c
+++ b/src/user/knob/task.c
@@ -4,7 +4,7 @@
#include <knob/heap.h>
#include <knob/block.h>
-bool try_run_command(const char *path) {
+_task_handle_t run_command(const char *path) {
uint8_t dn;
path = remove_prefix(path, &dn);
@@ -22,6 +22,15 @@ bool try_run_command(const char *path) {
return _start_task(dn, path, "");
}
+bool try_run_command_blocking(const char *path) {
+ _task_handle_t handle = run_command(path);
+ if (!handle)
+ return false;
+ _wait_for_task(handle);
+ _yield_task();
+ return true;
+}
+
void yield_task() {
_yield_task();
} \ No newline at end of file