diff options
author | Benji Dial <benji6283@gmail.com> | 2020-09-06 00:48:07 -0400 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2020-09-06 00:48:07 -0400 |
commit | e8c6577617bffa4402c07c7aa20e3c24f03c1c20 (patch) | |
tree | 2fb9230b62d2344a44453117de9e656892219788 /src/user/knob/file.c | |
parent | 7ff724fe8f709440da9c730fdb8dcbaa4f989ed5 (diff) | |
download | portland-os-e8c6577617bffa4402c07c7aa20e3c24f03c1c20.tar.gz |
program loading, others
big kernel additions: paging, elf loading, separate kernel and user page allocation
it now properly loads and runs sd0:bin/init.elf
still need to determine which disk was booted from, and start the init on that disk
Diffstat (limited to 'src/user/knob/file.c')
-rw-r--r-- | src/user/knob/file.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/user/knob/file.c b/src/user/knob/file.c new file mode 100644 index 0000000..8ab7acd --- /dev/null +++ b/src/user/knob/file.c @@ -0,0 +1,82 @@ +#include <pland/syscall.h> +#include <knob/format.h> +#include <knob/heap.h> +#include <knob/env.h> + +struct file { + _file_handle_t handle; + uint32_t position; + uint32_t length; +}; + +static const char *try_remove_prefix(const char *path, uint8_t *dn_out) { + if ((path[0] != 's') || (path[1] != 'd')) + return 0; + + const char *num_part = path + 2; + for (uint32_t i = 0; num_part[i]; ++i) + if (num_part[i] == ':') { + + uint32_t dn_large; + if (!try_sntoi(num_part, i, &dn_large) || dn_large > 255) + return 0; + + *dn_out = (uint8_t)dn_large; + return num_part + i + 1; + } + + return 0; +} + +struct file *open_file(const char *path) { + uint8_t dn; + const char *path_part = try_remove_prefix(path, &dn); + if (path_part) + path = path_part; + else + dn = current_drive; + + _file_handle_t h = _open_file(dn, path); + if (!h) + return 0; + + struct file *f = get_block(sizeof(struct file)); + f->handle = h; + f->position = 0; + f->length = _file_size(h); + + return f; +} + +void close_file(struct file *f) { + _close_file(f->handle); + free_block(f); +} + +uint32_t read_from_file(struct file *f, uint32_t max, void *buf) { + if (f->position + max > f->length) + max = f->length - f->position; + + uint32_t read = _file_read(f->handle, f->position, max, buf); + + f->position += read; + return read; +} + +uint32_t seek_file_to(struct file *f, uint32_t to) { + if (to > f->length) + to = f->length; + return f->position = to; +} + +int32_t seek_file_by(struct file *f, int32_t by) { + uint32_t old = f->position; + uint32_t to = old + by > f->length ? f->length : old + by; + f->position = to; + return to - old; +} + +__attribute__ ((pure)) +uint32_t file_size(struct file *f) { + return f->length; +}
\ No newline at end of file |