summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/drive.c79
-rw-r--r--src/kernel/drive.h5
-rw-r--r--src/kernel/fat.c1
-rw-r--r--src/kernel/idt.c111
-rw-r--r--src/kernel/kbd.c9
-rw-r--r--src/kernel/log.c4
-rw-r--r--src/kernel/main.c13
-rw-r--r--src/kernel/settings.c9
-rw-r--r--src/kernel/window.c12
9 files changed, 195 insertions, 48 deletions
diff --git a/src/kernel/drive.c b/src/kernel/drive.c
index bc1c67d..6a1d12e 100644
--- a/src/kernel/drive.c
+++ b/src/kernel/drive.c
@@ -1,5 +1,7 @@
#include "drive.h"
#include "panic.h"
+#include "pmap.h"
+#include "util.h"
#include "fat.h"
#include "log.h"
@@ -40,6 +42,7 @@ static inline void determine_fs(struct drive *d) {
if (try_fat_init_drive(d))
return;
+ d->mapped_to = 0;
d->fs_type = "Unknown";
d->get_file = &unknown_get_file;
d->free_file = &unknown_no_call;
@@ -58,7 +61,83 @@ static inline void determine_fs(struct drive *d) {
//do not need to make ready or done
void commit_drive(struct drive data) {
determine_fs(&data);
+ data.mapped_to = 0;
drives[n_drives] = data;
data.done(drives + n_drives);
++n_drives;
+}
+
+void map_path(const char *full, struct drive **d, const char **path) {
+ *d = 0;
+ *path = 0;
+
+ switch (full[0]) {
+ case '/':
+ for (struct drive *i = drives; i < drives + n_drives; ++i) {
+ if (!i->mapped_to)
+ continue;
+ uint32_t j = 0;
+ while (1) {
+ if (!i->mapped_to[j]) {
+ if (!*path || (j >= *path - full)) {
+ *path = full + j + 1;
+ *d = i;
+ }
+ break;
+ }
+ else if (i->mapped_to[j] != full[j + 1])
+ break;
+ ++j;
+ }
+ }
+ return;
+
+ uint32_t id;
+ case ':':
+ id = 0;
+ for (uint32_t i = 1; i < 9; ++i) {
+ id *= 16;
+ const char c = full[i];
+ if ((c >= '0') && (c <= '9'))
+ id += c - '0';
+ else if ((c >= 'a') && (c <= 'f'))
+ id += c - 'a' + 10;
+ else
+ return;
+ }
+ if (full[9] != ':')
+ return;
+ for (struct drive *i = drives; i < drives + n_drives; ++i)
+ if (i->uid == id) {
+ *d = i;
+ *path = full + 10;
+ return;
+ }
+ }
+}
+
+void map_drives() {
+ for (struct drive *d = drives; d < drives + n_drives; ++d) {
+ file_id_t fid = d->get_file(d, "_fstab");
+ if (!fid)
+ continue;
+
+ const uint32_t len = d->get_file_length(d, fid);
+ void *fstab = allocate_kernel_pages(len / 512 + 1);
+ fmcpy(fstab, d, fid, 0, len);
+ d->free_file(d, fid);
+ const uint32_t n_entries = *(uint32_t *)fstab;
+
+ uint32_t next_id = *(uint32_t *)(fstab + 4);
+ fstab += 8;
+ for (uint32_t i = 0; i < n_entries; ++i) {
+ for (struct drive *dd = drives; dd < drives + n_drives; ++dd)
+ if (dd->uid == next_id)
+ dd->mapped_to = fstab + 4;
+ const uint32_t plen = *(uint32_t *)fstab;
+ next_id = *(uint32_t *)(fstab + 4 + plen);
+ *(char *)(fstab + 4 + plen) = '\0';
+ fstab += 8 + plen;
+ }
+ }
} \ No newline at end of file
diff --git a/src/kernel/drive.h b/src/kernel/drive.h
index d09365d..e307324 100644
--- a/src/kernel/drive.h
+++ b/src/kernel/drive.h
@@ -22,6 +22,8 @@ struct directory_content_info {
struct drive {
char *drive_type;
char *fs_type;
+ char *mapped_to;
+ uint32_t uid;
uint32_t (*read_sectors) (const struct drive *d, uint32_t start, uint32_t count, void *buffer);
uint32_t (*write_sectors)(const struct drive *d, uint32_t start, uint32_t count, const void *buffer);
@@ -43,11 +45,14 @@ struct drive {
fs_id_t fs_id;
};
+void map_path(const char *full, struct drive **d, const char **path);
+
extern uint8_t n_drives;
extern struct drive drives[MAX_DRIVES];
void init_drives();
void commit_drive(struct drive data);
+void map_drives();
extern bool ignore_already_open;
diff --git a/src/kernel/fat.c b/src/kernel/fat.c
index b342267..008988c 100644
--- a/src/kernel/fat.c
+++ b/src/kernel/fat.c
@@ -521,6 +521,7 @@ bool try_fat_init_drive(struct drive *d) {
return false;
d->fs_type = "FAT16";
+ d->uid = next_fi->volume_id;
d->get_file = &fat_get_file;
d->free_file = &fat_free_file;
d->load_sector = &fat_load_sector;
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
index 8de5448..61966e0 100644
--- a/src/kernel/idt.c
+++ b/src/kernel/idt.c
@@ -34,60 +34,95 @@ struct {
.start = (uint32_t)idt
};
-//file handles as (drive_number << 8) + file_id_t
+bool verify_file_handle(uint32_t handle, struct drive **d, uint32_t *f) {
+ *d = drives + (handle >> 24);
+ *f = handle & 0x00ffffff;
-uint32_t sc_open_file(uint32_t drive_number, char *path) {
- return (drive_number << 8) + drives[drive_number].get_file(drives + drive_number, path);
+ if (!*f || (*d >= drives + n_drives)) {
+ logf(LOG_WARN, "syscall with file handle 0x%h", handle);
+ return false;
+ }
+ else
+ return true;
+}
+
+uint32_t sc_open_file(const char *path) {
+ struct drive *did;
+ const char *sub;
+ map_path(path, &did, &sub);
+ if (!did)
+ return 0;
+
+ const file_id_t fid = did->get_file(did, sub);
+ return fid ? ((did - drives) << 24) + fid : 0;
}
void sc_close_file(uint32_t handle) {
- if (!handle)
- return;
- drives[handle >> 8].free_file(drives + (handle >> 8), handle & 0xff);
+ struct drive *d;
+ uint32_t f;
+ if (verify_file_handle(handle, &d, &f))
+ d->free_file(d, f);
}
uint32_t sc_file_get_size(uint32_t handle) {
- if (!handle)
+ struct drive *d;
+ uint32_t f;
+ if (verify_file_handle(handle, &d, &f))
+ return d->get_file_length(d, f);
+ else
return 0;
- return drives[handle >> 8].get_file_length(drives + (handle >> 8), handle & 0xff);
}
void sc_file_set_size(uint32_t handle, uint32_t new_size) {
- if (!handle)
- return;
- drives[handle >> 8].set_file_length(drives + (handle >> 8), handle & 0xff, new_size);
+ struct drive *d;
+ uint32_t f;
+ if (verify_file_handle(handle, &d, &f))
+ d->set_file_length(d, f, new_size);
}
uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t count, void *buffer) {
- if (!handle)
+ struct drive *d;
+ uint32_t f;
+ if (verify_file_handle(handle, &d, &f)) {
+ const uint32_t l = d->get_file_length(d, f);
+ if (file_offset >= l)
+ return 0;
+ if (file_offset + count > l)
+ count = l - file_offset;
+ fmcpy(buffer, d, f, file_offset, count);
+ return count;
+ }
+ else
return 0;
- uint32_t len = sc_file_get_size(handle);
- if (file_offset + count > len)
- count = len - file_offset;
- fmcpy(buffer, drives + (handle >> 8), handle & 0xff, file_offset, count);
- return count;
}
uint32_t sc_file_write(uint32_t handle, uint32_t file_offset, uint32_t count, void *buffer) {
- if (!handle)
+ struct drive *d;
+ uint32_t f;
+ if (verify_file_handle(handle, &d, &f)) {
+ if (!d->is_writable(d, f))
+ return 0;
+ const uint32_t l = d->get_file_length(d, f);
+ if (file_offset >= l)
+ return 0;
+ if (file_offset + count > l)
+ count = l - file_offset;
+ mfcpy(d, f, file_offset, buffer, count);
+ return l;
+ }
+ else
return 0;
- const struct drive *const d = drives + (handle >> 8);
- const fs_id_t fid = handle & 0xff;
+}
- if (!d->is_writable(d, fid))
+uint32_t sc_start_task(char *path, const char *pass, uint32_t io_task) {
+ struct drive *d;
+ const char *f;
+ map_path(path, &d, &f);
+ if (!d)
return 0;
- const uint32_t l = d->get_file_length(d, fid);
- if (file_offset + count > l)
- count = l - file_offset;
-
- mfcpy(d, fid, file_offset, buffer, count);
- return count;
-}
-
-uint32_t sc_start_task(uint32_t drive_number, char *path, const char *pass, uint32_t io_task) {
switch_to_kernel_cr3();
- uint32_t process_id = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass, io_task);
+ uint32_t process_id = try_elf_run(d, vma_to_pma(active_task->page_directory, f), pass, io_task);
switch_to_task_cr3();
return process_id;
}
@@ -126,12 +161,18 @@ void sc_wait_for_task(uint32_t handle) {
add_wait((struct wait){.mode = PROCESS_END, .task = tasks + handle - 1});
}
-uint32_t sc_enumerate_dir(uint32_t drive_number, const char *path, struct directory_content_info *buffer, uint32_t max_entries) { //not static to ensure sysv abi
- return drives[drive_number].enumerate_dir(drives + drive_number, path, buffer, max_entries);
+uint32_t sc_enumerate_dir(const char *path, struct directory_content_info *buffer, uint32_t max_entries) { //not static to ensure sysv abi
+ struct drive *d;
+ const char *f;
+ map_path(path, &d, &f);
+ return d ? d->enumerate_dir(d, f, buffer, max_entries) : 0;
}
-uint32_t sc_count_of_dir(uint32_t drive_number, const char *path) {
- return drives[drive_number].n_dir_entries(drives + drive_number, path);
+uint32_t sc_count_of_dir(const char *path) {
+ struct drive *d;
+ const char *f;
+ map_path(path, &d, &f);
+ return d ? d->n_dir_entries(d, f) : 0;
}
void sc_get_next_window_action(struct window *w, struct window_action *action) {
diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c
index ce25397..3c49382 100644
--- a/src/kernel/kbd.c
+++ b/src/kernel/kbd.c
@@ -10,8 +10,8 @@
#include "kbd.h"
#include "log.h"
-#define SCANTAB_DIR "sys/scantabs/"
-#define SCANTAB_DIR_LEN 13
+#define SCANTAB_DIR "/sys/scantabs/"
+#define SCANTAB_DIR_LEN 14
enum {
PS2_CMD = 0x64,
@@ -97,7 +97,10 @@ void init_kbd() {
scantab_path[SCANTAB_DIR_LEN + layout_len + 3] = 't';
scantab_path[SCANTAB_DIR_LEN + layout_len + 4] = '\0';
logf(LOG_INFO, "Using scantab file at \"%s\".", scantab_path);
- file_id_t stf = drives->get_file(drives, scantab_path);
+ struct drive *d;
+ const char *f;
+ map_path(scantab_path, &d, &f);
+ file_id_t stf = drives->get_file(d, f);
if (!stf)
PANIC("could not load scantab file.");
diff --git a/src/kernel/log.c b/src/kernel/log.c
index 2819a2e..6bdda84 100644
--- a/src/kernel/log.c
+++ b/src/kernel/log.c
@@ -7,8 +7,8 @@
#define LOG_COM COM1
void init_log() {
- //TODO: move old "sys/current.log"
- //TODO: open new "sys/current.log"
+ //TODO: move old "/sys/current.log"
+ //TODO: open new "/sys/current.log"
}
static const char *const log_prefixes[] = {
diff --git a/src/kernel/main.c b/src/kernel/main.c
index 951e37f..24ec58f 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -40,6 +40,8 @@ void main() {
ignore_already_open = true;
+ map_drives();
+
init_log();
init_settings();
@@ -64,10 +66,15 @@ void main() {
logf(LOG_INFO, "");
logf(LOG_INFO, "Drives:");
- for (uint8_t i = 0; i < n_drives; ++i) {
- const struct drive *d = &drives[i];
+ for (struct drive *d = drives; d < drives + n_drives; ++d) {
const uint32_t free = d->get_free_sectors(d);
- logf(LOG_INFO, " %s: %d%sk, %s (%d%sk free)", d->drive_type, d->n_sectors / 2, d->n_sectors % 2 ? ".5" : "", d->fs_type, free / 2, free % 2 ? ".5" : "");
+ logf(LOG_INFO, " :%h:", d->uid);
+ logf(LOG_INFO, " %s (%d%skB free)", d->fs_type, free / 2, free % 2 ? ".5" : "");
+ logf(LOG_INFO, " on %s (%d%skB)", d->drive_type, d->n_sectors / 2, d->n_sectors % 2 ? ".5" : "");
+ if (d->mapped_to)
+ logf(LOG_INFO, " mapped to /%s", d->mapped_to);
+ else
+ logf(LOG_INFO, " not mapped");
}
logf(LOG_INFO, "");
diff --git a/src/kernel/settings.c b/src/kernel/settings.c
index 419341a..77f5ef8 100644
--- a/src/kernel/settings.c
+++ b/src/kernel/settings.c
@@ -5,7 +5,7 @@
#include <stdint.h>
-#define SETTINGS_FILE "sys/settings.pls"
+#define SETTINGS_FILE "/sys/settings.pls"
static struct {
uint32_t main_start;
@@ -41,8 +41,13 @@ void close_settings() {
fid = 0;
}
+#include "log.h"
+
void init_settings() {
- fid = drives->get_file(drives, SETTINGS_FILE);
+ struct drive *d;
+ const char *f;
+ map_path(SETTINGS_FILE, &d, &f);
+ fid = drives->get_file(d, f);
if (!fid)
PANIC("could not open settings file at \"" SETTINGS_FILE "\".");
diff --git a/src/kernel/window.c b/src/kernel/window.c
index 69babe4..9398420 100644
--- a/src/kernel/window.c
+++ b/src/kernel/window.c
@@ -409,7 +409,7 @@ struct window_action next_window_action(struct window *w) {
return *action;
}
-#define RUN_COMMAND_FILE "sys/winspace.rc"
+#define RUN_COMMAND_FILE "/sys/winspace.rc"
enum wm_action {
WM_MOVE_LEFT,
@@ -462,7 +462,10 @@ void init_win() {
mouse_y = (VBE_MODE_INFO->height - MOUSE_HEIGHT) / 2;
blit_mouse();
- const file_id_t fid = drives->get_file(drives, RUN_COMMAND_FILE);
+ const struct drive *d;
+ const char *f;
+ map_path(RUN_COMMAND_FILE, &d, &f);
+ const file_id_t fid = drives->get_file(d, f);
if (!fid)
PANIC("Couldn't open " RUN_COMMAND_FILE ".");
@@ -519,8 +522,11 @@ void on_action(struct window_action packet) {
paint_all();
}
break;
+ const struct drive *d;
+ const char *f;
case WM_RUN_COMMAND:
- if (!try_elf_run(drives, run_command, run_command_pass, 0))
+ map_path(run_command, &d, &f);
+ if (!try_elf_run(d, f, run_command_pass, 0))
logf(LOG_ERROR, "Couldn't run program listed in " RUN_COMMAND_FILE ".");
break;
}