diff options
Diffstat (limited to 'src/kernel/drive.c')
-rw-r--r-- | src/kernel/drive.c | 79 |
1 files changed, 79 insertions, 0 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 |