From 0ba991750314310a5e53b0d8135aef5b1352b261 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Wed, 20 Nov 2019 22:17:48 +0100 Subject: Began two-stage hdd bootloader and os installer --- src/kernel/fs/iso9660/iso9660.c | 60 +++++++++++++++++++++++++++++++++++++++++ src/kernel/fs/iso9660/iso9660.h | 22 +++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/kernel/fs/iso9660/iso9660.c create mode 100644 src/kernel/fs/iso9660/iso9660.h (limited to 'src/kernel/fs/iso9660') diff --git a/src/kernel/fs/iso9660/iso9660.c b/src/kernel/fs/iso9660/iso9660.c new file mode 100644 index 0000000..728d3cb --- /dev/null +++ b/src/kernel/fs/iso9660/iso9660.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +struct ISO9660_entity *ISO9660_get(char **dirs, uint8_t dirs_sz) { + ATAPI_read(1, 0x10); + uint32_t last_len = *(uint32_t *) ( + ATAPI_PIO_BUFFER + + ISO9660_ROOT_RECORD_OFFSET + + ISO9660_DIR_EAR_LENGTH + ); + uint32_t last_LBA = *(uint32_t *) ( + ATAPI_PIO_BUFFER + + ISO9660_ROOT_RECORD_OFFSET + + ISO9660_DIR_EAR_LBA + ); + + for (uint8_t dirs_i = 0; dirs_i < dirs_sz; dirs_i++) { + ATAPI_read((last_len % 2048 != 0) + (last_len / 2048), last_LBA); + + uint8_t found = 0; + for (uint32_t i = 0; i < last_len && !found;) { + if (!*(uint8_t *) (ATAPI_PIO_BUFFER + i + ISO9660_DIR_RECORD_LENGTH)) + break; + + char *filename = (char *) (ATAPI_PIO_BUFFER + i + ISO9660_DIR_FILENAME); + + for (uint32_t j = 0; j < ISO9660_DIR_FILENAME_LENGTH; j++) { + if (filename[j] == ';') { + filename[j] = 0; + break; + } + } + + if (strcmp(dirs[dirs_i], filename) == 0) { + found = 1; + last_LBA = *(uint32_t *) (ATAPI_PIO_BUFFER + i + ISO9660_DIR_EAR_LBA); + last_len = *(uint32_t *) (ATAPI_PIO_BUFFER + i + ISO9660_DIR_EAR_LENGTH); + } else { + i += *(uint8_t *) (ATAPI_PIO_BUFFER + i + ISO9660_DIR_RECORD_LENGTH); + } + } + + if (!found) { + return (struct ISO9660_entity *) 0; + } + } + + struct ISO9660_entity *ret = (struct ISO9660_entity *) kmalloc(sizeof(struct ISO9660_entity)); + ret->LBA = last_LBA; + ret->length = last_len; + return ret; +} + +uint8_t *ISO9660_read(struct ISO9660_entity *entity) { + ATAPI_read((entity->length % 2048 != 0) + (entity->length / 2048), entity->LBA); + return (uint8_t *) ATAPI_PIO_BUFFER; +} \ No newline at end of file diff --git a/src/kernel/fs/iso9660/iso9660.h b/src/kernel/fs/iso9660/iso9660.h new file mode 100644 index 0000000..3de5d1a --- /dev/null +++ b/src/kernel/fs/iso9660/iso9660.h @@ -0,0 +1,22 @@ +#ifndef MELVIX_ISO9660_H +#define MELVIX_ISO9660_H + +#define ISO9660_ROOT_RECORD_OFFSET 156 +#define ISO9660_DIR_RECORD_LENGTH 0 +#define ISO9660_DIR_EAR_LBA 2 +#define ISO9660_DIR_EAR_LENGTH 10 +#define ISO9660_DIR_FILENAME_LENGTH 32 +#define ISO9660_DIR_FILENAME 33 + +#include + +struct ISO9660_entity { + uint32_t LBA; + uint32_t length; +}; + +struct ISO9660_entity *ISO9660_get(char **dirs, uint8_t dirs_sz); + +uint8_t *ISO9660_read(struct ISO9660_entity *entity); + +#endif -- cgit v1.2.3