diff options
-rw-r--r-- | src/common/include/fs.h | 3 | ||||
-rw-r--r-- | src/kernel/dev/pciide.c | 11 | ||||
-rw-r--r-- | src/kernel/fs/iso9660.c | 33 | ||||
-rw-r--r-- | src/kernel/include/fs/iso9660.h | 87 |
4 files changed, 129 insertions, 5 deletions
diff --git a/src/common/include/fs.h b/src/common/include/fs.h index 70f0169..b238c03 100644 --- a/src/common/include/fs.h +++ b/src/common/include/fs.h @@ -41,4 +41,7 @@ typedef struct { } dirent_t; +#define IOCTL_BLOCKDEV_GET_BLOCK_SIZE 40 +#define IOCTL_BLOCKDEV_GET_BLOCK_COUNT 41 + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/dev/pciide.c b/src/kernel/dev/pciide.c index 58bccfd..5d79470 100644 --- a/src/kernel/dev/pciide.c +++ b/src/kernel/dev/pciide.c @@ -742,8 +742,7 @@ size_t ide_vfs_write(fs_handle_ptr f, size_t offset, size_t len, const char* buf if (offset % d->block_size != 0) return 0; if (len % d->block_size != 0) return 0; - - uint8_t err = ide_write_sectors(d->c, d->device, +uint8_t err = ide_write_sectors(d->c, d->device, offset / d->block_size, len / d->block_size, (char*)buf); if (err != 0) return 0; @@ -751,7 +750,13 @@ size_t ide_vfs_write(fs_handle_ptr f, size_t offset, size_t len, const char* buf } int ide_vfs_ioctl(fs_handle_ptr f, int command, void* data) { - // TODO + ide_vfs_dev_t *d = (ide_vfs_dev_t*)f; + + if (command == IOCTL_BLOCKDEV_GET_BLOCK_SIZE) + return d->block_size; + if (command == IOCTL_BLOCKDEV_GET_BLOCK_COUNT) + return d->c->devices[d->device].size; + return 0; } diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c index 8780c32..60e9a81 100644 --- a/src/kernel/fs/iso9660.c +++ b/src/kernel/fs/iso9660.c @@ -2,9 +2,38 @@ #include <fs/iso9660.h> +static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t); +static bool iso9660_detect(fs_handle_t *source); + +static fs_driver_ops_t iso9660_driver_ops = { + .make = iso9660_make, + .detect = iso9660_detect, +}; + void register_iso9660_driver() { - dbg_printf("Not implemented ISO9660.\n"); - // TODO + ASSERT(sizeof(iso9660_vdt_entry_t) == 2048); + ASSERT(sizeof(iso9660_dr_t) == 34); + + register_fs_driver("iso9660", &iso9660_driver_ops); +} + +// ============================== // +// FILESYSTEM DETECTION AND SETUP // +// ============================== // + +static bool iso9660_detect(fs_handle_t *source) { + stat_t st; + if (!file_stat(source, &st)) return false; + if ((st.type & FT_BLOCKDEV) != 0) return false; + + uint32_t block_size = file_ioctl(source, IOCTL_BLOCKDEV_GET_BLOCK_SIZE, 0); + if (block_size != 2048) return false; + + return false; // TODO +} + +static bool iso9660_make(fs_handle_t *source, const char* opts, fs_t *t) { + return false; // TODO } /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/fs/iso9660.h b/src/kernel/include/fs/iso9660.h index 227a8da..fcaec1a 100644 --- a/src/kernel/include/fs/iso9660.h +++ b/src/kernel/include/fs/iso9660.h @@ -1,5 +1,92 @@ #pragma once +#include <vfs.h> + +#define ISO9660_VDT_BOOT 0 +#define ISO9660_VDT_PRIMARY 1 +#define ISO9660_VDT_SUPPLEMENTARY 2 +#define ISO9660_VDT_PARTITION 3 +#define ISO9660_VDT_TERMINATOR 255 + +typedef struct { + uint32_t lsb, msb; +} uint32_lsb_msb_t; + +typedef struct { + uint16_t lsb, msb; +} uint16_lsb_msb_t; + +typedef struct { + uint8_t years_since_1990; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t gmt_offset; +} iso9660_dr_date_t; + +typedef struct { // Directory record + uint8_t len; // length of the record + uint8_t ear_len; // length of extended attribute record + uint32_lsb_msb_t lba_loc; // location of extent + uint32_lsb_msb_t size; // size of extent + iso9660_dr_date_t date; + uint8_t flags; + uint8_t interleave_unit_size; + uint8_t interleave_gap_size; + uint16_lsb_msb_t vol_seq_num; + uint8_t name_len; + char name[2]; // we want sizeof(iso9660_dr_t) == 34 +} iso9660_dr_t; + +typedef struct { // Boot record + uint8_t type; + char ident[5]; + uint8_t version; // always 1 + char sys_ident[32]; + char boot_ident[32]; + char reserved[1977]; +} iso9660_bootrecord_t; + +typedef struct { // Primary volume descriptor + uint8_t type; + char ident[5]; + uint8_t version; // always 1 + + uint8_t unused0; + + char sys_ident[32]; + char vol_ident[32]; + + uint8_t unused1[8]; + + uint32_lsb_msb_t volume_size; + uint8_t unused2[32]; + + uint16_lsb_msb_t volume_set_size, volume_seq_number; + uint16_lsb_msb_t block_size; + uint32_lsb_msb_t path_table_size; + uint32_t lpt_loc, olpt_loc, mpt_loc, ompt_loc; // location of path tables + + iso9660_dr_t root_directory; + + // more fields (not interesting...) +} iso9660_pvd_t; + +typedef struct { + uint8_t type; + char ident[5]; + uint8_t version; // always 1 +} iso9660_vdt_terminator_t; // volume descriptor table terminator + +typedef union { + iso9660_bootrecord_t boot; + iso9660_pvd_t prim; + iso9660_vdt_terminator_t term; + char buf[2048]; +} iso9660_vdt_entry_t; + void register_iso9660_driver(); /* vim: set ts=4 sw=4 tw=0 noet :*/ |