diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/drive.c | 79 | ||||
-rw-r--r-- | src/kernel/drive.h | 5 | ||||
-rw-r--r-- | src/kernel/fat.c | 1 | ||||
-rw-r--r-- | src/kernel/idt.c | 111 | ||||
-rw-r--r-- | src/kernel/kbd.c | 9 | ||||
-rw-r--r-- | src/kernel/log.c | 4 | ||||
-rw-r--r-- | src/kernel/main.c | 13 | ||||
-rw-r--r-- | src/kernel/settings.c | 9 | ||||
-rw-r--r-- | src/kernel/window.c | 12 |
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; } |