--- /dev/null
-
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <klibc/compiler.h>
+#include "core.h"
+#include "fs.h"
+#include "disk.h"
+
+#define RETRY_COUNT 6
+
+extern uint16_t MaxTransfer;
+
+static int chs_rdwr_sectors(struct disk *disk, void *buf,
+ sector_t lba, size_t count, bool is_write)
+{
+ char *ptr = buf;
+ char *tptr;
+ size_t chunk, freeseg;
+ int sector_size = disk->sector_size;
+ int sector_shift = disk->sector_shift;
+ uint32_t xlba = lba; /* Truncated LBA (CHS is << 2 TB) */
+ uint32_t t;
+ uint16_t c, h, s;
+ com32sys_t ireg, oreg;
+ size_t done = 0;
+ size_t bytes;
+ int retry;
+
+ memset(&ireg, 0, sizeof ireg);
+
+ ireg.eax.b[1] = 0x02 + is_write;
+ ireg.edx.b[0] = disk->disk_number;
+
+ while (count) {
+ chunk = count;
+ if (chunk > MaxTransfer)
+ chunk = MaxTransfer;
+
+ freeseg = (0x10000 - ((size_t)ptr & 0xffff)) >> sector_shift;
+
+ if ((size_t)buf <= 0xf0000 && freeseg) {
+ /* Can do a direct load */
+ tptr = ptr;
+ } else {
+ /* Either accessing high memory or we're crossing a 64K line */
+ tptr = core_xfer_buf;
+ freeseg = (0x10000 - ((size_t)tptr & 0xffff)) >> sector_shift;
+ }
+ if (chunk > freeseg)
+ chunk = freeseg;
+
+ bytes = chunk << sector_shift;
+
+ if (tptr != ptr && is_write)
+ memcpy(tptr, ptr, bytes);
+
+ s = xlba % disk->s;
+ t = xlba / disk->s;
+ h = t % disk->h;
+ c = t / disk->h;
+
+ ireg.eax.b[0] = chunk;
+ ireg.ecx.b[1] = c;
+ ireg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
+ ireg.edx.b[1] = h;
+ ireg.ebx.w[0] = OFFS(tptr);
+ ireg.es = SEG(tptr);
+
+ retry = RETRY_COUNT;
+
+ for (;;) {
+ __intcall(0x13, &ireg, &oreg);
+ if (!(oreg.eflags.l & EFLAGS_CF))
+ break;
+ if (retry--)
+ continue;
+ chunk >>= 1;
+ if (chunk) {
+ MaxTransfer = chunk;
+ retry = RETRY_COUNT;
+ continue;
+ }
+ return done; /* Failure */
+ }
+
+ bytes = chunk << sector_shift;
+
+ if (tptr != ptr && !is_write)
+ memcpy(ptr, tptr, bytes);
+
+ ptr += bytes;
+ xlba += chunk;
+ count -= chunk;
+ done += chunk;
+ }
+ return done;
+}
+
+struct edd_rdwr_packet {
+ uint16_t size;
+ uint16_t blocks;
+ far_ptr_t buf;
+ uint64_t lba;
+};
+
+static int edd_rdwr_sectors(struct disk *disk, void *buf,
+ sector_t lba, size_t count, bool is_write)
+{
+ static __lowmem struct edd_rdwr_packet pkt;
+ char *ptr = buf;
+ char *tptr;
+ size_t chunk, freeseg;
+ int sector_size = disk->sector_size;
+ int sector_shift = disk->sector_shift;
+ com32sys_t ireg, oreg;
+ size_t done = 0;
+ size_t bytes;
+ int retry;
+
+ memset(&ireg, 0, sizeof ireg);
++
+ ireg.eax.b[1] = 0x42 + is_write;
+ ireg.edx.b[0] = disk->disk_number;
+ ireg.ds = SEG(&pkt);
+ ireg.esi.w[0] = OFFS(&pkt);
+
+ while (count) {
+ chunk = count;
+ if (chunk > MaxTransfer)
+ chunk = MaxTransfer;
+
+ freeseg = (0x10000 - ((size_t)ptr & 0xffff)) >> sector_shift;
+
+ if ((size_t)buf <= 0xf0000 && freeseg) {
+ /* Can do a direct load */
+ tptr = ptr;
+ } else {
+ /* Either accessing high memory or we're crossing a 64K line */
+ tptr = core_xfer_buf;
+ freeseg = (0x10000 - ((size_t)tptr & 0xffff)) >> sector_shift;
+ }
+ if (chunk > freeseg)
+ chunk = freeseg;
+
+ bytes = chunk << sector_shift;
+
+ if (tptr != ptr && is_write)
+ memcpy(tptr, ptr, bytes);
+
+ pkt.size = sizeof pkt;
+ pkt.blocks = chunk;
+ pkt.buf = FAR_PTR(tptr);
+ pkt.lba = lba;
+
+ retry = RETRY_COUNT;
+
+ for (;;) {
+ __intcall(0x13, &ireg, &oreg);
+ if (!(oreg.eflags.l & EFLAGS_CF))
+ break;
+ if (retry--)
+ continue;
+ chunk >>= 1;
+ if (chunk) {
+ MaxTransfer = chunk;
+ retry = RETRY_COUNT;
+ continue;
+ }
+ /*** XXX: Consider falling back to CHS here?! ***/
++ printf("reading sectors error(EDD)\n");
+ return done; /* Failure */
+ }
+
+ bytes = chunk << sector_shift;
+
+ if (tptr != ptr && !is_write)
+ memcpy(ptr, tptr, bytes);
+
+ ptr += bytes;
+ lba += chunk;
+ count -= chunk;
+ done += chunk;
+ }
+ return done;
+}
+struct edd_disk_params {
+ uint16_t len;
+ uint16_t flags;
+ uint32_t phys_c;
+ uint32_t phys_h;
+ uint32_t phys_s;
+ uint64_t sectors;
+ uint16_t sector_size;
+ far_ptr_t dpte;
+ uint16_t devpath_key;
+ uint8_t devpath_len;
+ uint8_t _pad1[3];
+ char bus_type[4];
+ char if_type[8];
+ uint8_t if_path[8];
+ uint8_t dev_path[8];
+ uint8_t _pad2;
+ uint8_t devpath_csum;
+} __attribute__((packed));
+
+static inline bool is_power_of_2(uint32_t x)
+{
+ return !(x & (x-1));
+}
+
+int ilog2(uint32_t num)
+{
+ int i = 0;
+
+ if (!is_power_of_2(num)) {
+ printf("ERROR: the num must be power of 2 when conveting to log2\n");
+ return 0;
+ }
+ while (num >>= 1)
+ i++;
+ return i;
+}
+
+void dump_disk(struct disk *disk)
+{
+ printf("drive number: 0x%x\n", disk->disk_number);
+ printf("disk type: %s(%d)\n", disk->type ? "EDD" : "CHS", disk->type);
+ printf("sector size: %d(%d)\n", disk->sector_size, disk->sector_shift);
+ printf("h: %d\ts: %d\n", disk->h, disk->s);
+ printf("offset: %d\n", disk->part_start);
+ printf("%s\n", disk->rdwr_sectors == edd_rdwr_sectors ? "EDD_RDWR_SECTORS" :
+ "CHS_RDWR_SECTORS");
+ printf("--------------------------------\n");
+ printf("disk->rdwr_sectors@: %p\n", disk->rdwr_sectors);
+ printf("edd_rdwr_sectors @: %p\n", edd_rdwr_sectors);
+ printf("chs_rdwr_sectors @: %p\n", chs_rdwr_sectors);
+}
+
+struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start,
+ uint16_t bsHeads, uint16_t bsSecPerTrack)
+{
+ static struct disk disk;
+ static __lowmem struct edd_disk_params edd_params;
+ com32sys_t ireg, oreg;
+ bool ebios = cdrom;
+ int sector_size = cdrom ? 2048 : 512;
+
+ memset(&ireg, 0, sizeof ireg);
+
+ /* Get EBIOS support */
+ ireg.eax.b[1] = 0x41;
+ ireg.ebx.w[0] = 0x55aa;
+ ireg.edx.b[0] = devno;
+ ireg.eflags.b[0] = 0x3; /* CF set */
+
+ __intcall(0x13, &ireg, &oreg);
+
+ if (cdrom || (!(oreg.eflags.l & EFLAGS_CF) &&
+ oreg.ebx.w[0] == 0xaa55 && (oreg.ecx.b[0] & 1))) {
+ /* Query EBIOS parameters */
+ ireg.eax.b[1] = 0x48;
+ ireg.ds = SEG(&edd_params);
+ ireg.esi.w[0] = OFFS(&edd_params);
+ __intcall(0x13, &ireg, &oreg);
+
+ if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.b[1] == 0) {
+ ebios = true;
+ if (edd_params.sector_size >= 512 &&
+ is_power_of_2(edd_params.sector_size))
+ sector_size = edd_params.sector_size;
+ }
+ }
+
+ /* CBIOS parameters */
+ disk.h = bsHeads;
+ disk.s = bsSecPerTrack;
+
+ if ((int8_t)devno < 0) {
+ /* Get hard disk geometry from BIOS */
+
+ ireg.eax.b[1] = 0x08;
+ __intcall(0x13, &ireg, &oreg);
+
+ if (!(oreg.eflags.l & EFLAGS_CF)) {
+ disk.h = oreg.edx.b[1] + 1;
+ disk.s = oreg.ecx.b[0] & 63;
+ }
+ }
+
+ disk.disk_number = devno;
+ disk.type = ebios;
+ disk.sector_size = sector_size;
+ disk.sector_shift = ilog2(sector_size);
+ disk.part_start = part_start;
+ disk.rdwr_sectors = ebios ? edd_rdwr_sectors : chs_rdwr_sectors;
+
+ dump_disk(&disk);
+
+ return &disk;
+}
--- /dev/null
- getlinsec_cdrom(buf, file->file_sector, sectors);
+ #include <stdio.h>
+ #include <string.h>
+ //#include "cache.h"
+ #include "core.h"
+ #include "disk.h"
+ #include "iso9660_fs.h"
+ #include "fs.h"
+
+ #define DEBUG 1
+
+ #define FILENAME_MAX_LG2 8
+ #define FILENAME_MAX (1 << FILENAME_MAX_LG2)
+ #define MAX_OPEN_LG2 6
+ #define MAX_OPEN (1 << MAX_OPEN_LG2)
+ #define ISO_SECTOR_SHIFT 11
+ #define ISO_SECTOR_SIZE (1 << ISO_SECTOR_SHIFT)
+ #define ROOT_DIR_WORD 0x002f
+ #define TRACKBUF_SIZE 8192
+
+
+ struct open_file_t {
+ uint32_t file_sector;
+ uint32_t file_bytesleft;
+ uint32_t file_left;
+ uint32_t pad;
+ };
+ extern char Files[];
+
+ struct dir_t {
+ uint32_t dir_lba; /* Directory start (LBA) */
+ uint32_t dir_len; /* Length in bytes */
+ uint32_t dir_clust; /* Length in clusters */
+ };
+ struct dir_t RootDir;
+ struct dir_t CurrentDir;
+
+
+ extern char trackbuf[TRACKBUF_SIZE];
+ uint16_t BufSafe = TRACKBUF_SIZE >> ISO_SECTOR_SHIFT;
+ uint16_t BufSafeBytes = TRACKBUF_SIZE;
+
+ char ISOFileName[64]; /* ISO filename canonicalizatin buffer */
+ char *ISOFileNameEnd = &ISOFileName[64];
+
+ uint32_t FirstSecSum; /* checksum of bytes 64-2048 */
+ uint32_t ImageDwords; /* isolinux.bin size, dwords */
+ uint32_t InitStack; /* Initial stack pointer (SS:SP) */
+ uint16_t DiskSys; /* Last INT 13h call */
+ uint16_t ImageSectors; /* isolinux.bin size, sectors */
+
+ /* These following two are accessed as a single dword ... */
+ uint16_t GetlinsecPtr; /* the sector-read pointer */
+ uint16_t BIOSType;
+ uint8_t DiskError; /* Error code for disk I/O */
+ uint8_t DriveNumber; /* CD-ROM BIOS drive number */
+ uint8_t ISOFlags; /* Flags for ISO directory search */
+ uint8_t RetryCount; /* Used for ISO directory search */
+ uint16_t bsSecPerTrack; /* Used in hybrid mode */
+ uint16_t bsHeads; /* Used in hybrid mode */
+
+
+ /**
+ * allocate_file:
+ *
+ * allocate a file structure
+ *
+ */
+ struct open_file_t *allocate_file()
+ {
+ struct open_file_t *file;
+ int i = 0;
+
+ file = (struct open_file_t *)Files;
+ for (; i < MAX_OPEN; i ++ ) {
+ if ( file->file_sector == 0 ) /* found it */
+ return file;
+ file ++;
+ }
+
+ return NULL; /* not found */
+ }
+
+
+ /**
+ * close_file:
+ *
+ * Deallocates a file structure
+ *
+ */
+ void close_file(struct open_file_t *file)
+ {
+ if (file)
+ file->file_sector = 0;
+ }
+
+ void getlinsec_cdrom(char *buf, sector_t sector_num, int sectors)
+ {
+ com32sys_t regs;
+ //static __lowmem char low_buf[65536];
+ /* for safe, we use buf + (sectors << SECTOR_SHIFT) here */
+ int high_addr = (buf + (sectors << ISO_SECTOR_SHIFT)) > (char *)0x100000;
+
+ memset(®s, 0, sizeof regs);
+ regs.eax.l = sector_num;
+ regs.ebp.l = sectors;
+
+ if (high_addr) {
+ regs.es = SEG(core_xfer_buf);
+ regs.ebx.w[0] = OFFS(core_xfer_buf);
+ } else {
+ regs.es = SEG(buf);
+ regs.ebx.w[0] = OFFS(buf);
+ }
+
+ call16(getlinsec, ®s, NULL);
+
+ if (high_addr)
+ memcpy(buf, core_xfer_buf, sectors << ISO_SECTOR_SHIFT);
+ }
+
+
+
+
+ /**
+ * mangle_name:
+ *
+ * Mangle a filename pointed to by src into a buffer pointed
+ * to by dst; ends on encountering any whitespace.
+ * dst is preserved.
+ *
+ * This verifies that a filename is < FilENAME_MAX characters,
+ * doesn't contain whitespace, zero-pads the output buffer,
+ * and removes trailing dots and redumndant slashes, so "repe
+ * cmpsb" can do a compare, and the path-searching routine gets
+ * a bit of an easier job.
+ *
+ */
+ void iso_mangle_name(char *dst, char *src)
+ {
+ char *p = dst;
+ int i = FILENAME_MAX - 1;
+
+ while ( *src > ' ' ) {
+ if ( *src == '/' ) {
+ if ( *(src+1) == '/' ) {
+ i --;
+ src ++;
+ continue;
+ }
+ }
+
+ *dst++ = *src ++;
+ i --;
+ }
+
+ while ( 1 ) {
+ if ( dst == p )
+ break;
+
+ if ( (*(dst-1) != '.') && (*(dst-1) != '/') )
+ break;
+
+ dst --;
+ i ++;
+ }
+
+ i ++;
+ for (; i > 0; i -- )
+ *dst++ = '\0';
+ }
+
+
+ /**
+ * compare the names si and di and report if they are
+ * equal from an ISO 9600 perspective.
+ *
+ * @param: de_name, the name from the file system.
+ * @param: len, the length of de_name, and will return the real name of the de_name
+ * ';' and other terminates excluded.
+ * @param: file_name, the name we want to check, is expected to end with a null
+ *
+ * @return: 1 on match, or 0.
+ *
+ */
+ int iso_compare_names(char *de_name, int *len, char *file_name)
+ {
+ char *p = ISOFileName;
+ char c1, c2;
+
+ int i = 0;
+
+ while ( (i < *len) && *de_name && (*de_name != ';') && (p < ISOFileNameEnd - 1) ) {
+ *p++ = *de_name++;
+ i++;
+ }
+
+ /* Remove terminal dots */
+ while ( *(p-1) == '.' ) {
+ if ( *len <= 2 )
+ break;
+
+ if ( p <= ISOFileName )
+ break;
+ p --;
+ i--;
+ }
+
+ if ( i <= 0 )
+ return 0;
+
+ *p = '\0';
+
+ /* return the 'real' length of de_name */
+ *len = i;
+
+ p = ISOFileName;
+
+ /* i is the 'real' name length of file_name */
+ while ( i ) {
+ c1 = *p++;
+ c2 = *file_name++;
+
+ if ( (c1 == 0) && (c2 == 0) )
+ return 1; /* success */
+
+ else if ( (c1 == 0) || ( c2 == 0 ) )
+ return 0;
+
+ c1 |= 0x20;
+ c2 |= 0x20; /* convert to lower case */
+ if ( c1 != c2 )
+ return 0;
+ i --;
+ }
+
+ return 1;
+ }
+
+
+ /**
+ * iso_getfssec:
+ *
+ * Get multiple clusters from a file, given the file pointer.
+ *
+ * we don't use the fs struct for now
+ *
+ * @param: buf
+ * @param: file, the address of the open file structure
+ * @param: sectors, how many we want to read at once
+ * @param: have_more, to indicate if we have reach the end of the file
+ *
+ */
+ uint32_t iso_getfssec(struct fs_info *fs, char *buf,
+ void *open_file, int sectors, int *have_more)
+ {
+ uint32_t bytes_read = sectors << ISO_SECTOR_SHIFT;
+ struct open_file_t *file = (struct open_file_t *)open_file;
+
+ if ( sectors > file->file_left )
+ sectors = file->file_left;
+
-
++ fs->fs_dev->disk->rdwr_sectors(fs->fs_dev->disk, (void *)buf, file->file_sector, sectors, 0);
+
+ file->file_sector += sectors;
+ file->file_left -= sectors;
+
+ if ( bytes_read >= file->file_bytesleft ) {
+ bytes_read = file->file_bytesleft;
+ *have_more = 0;
+ } else
+ *have_more = 1;
+ file->file_bytesleft -= bytes_read;
+
+ return bytes_read;
+ }
+
+
+
+ /**
+ * do_search_dir:
+ *
+ * find a file or directory with name within the _dir_ directory.
+ *
+ * the return value will tell us what we find, it's a file or dir?
+ * on 1 be dir, 2 be file, 0 be error.
+ *
+ * res will return the result.
+ *
+ */
+ int do_search_dir(struct dir_t *dir, char *name, uint32_t *file_len, void **res)
+ {
+ struct open_file_t *file;
+ struct iso_dir_entry *de;
+ struct iso_dir_entry tmpde;
+
+ uint32_t offset = 0; /* let's start it with the start */
+ uint32_t file_pos = 0;
+ char *de_name;
+ int de_len;
+ int de_name_len;
+ int have_more;
+
+ file = allocate_file();
+ if ( !file )
+ return 0;
+
+ file->file_left = dir->dir_clust;
+ file->file_sector = dir->dir_lba;
+
+ iso_getfssec(NULL, trackbuf, file, BufSafe, &have_more);
+ de = (struct iso_dir_entry *)trackbuf;
+
+ while ( file_pos < dir->dir_len ) {
+ int found = 0;
+
+ if ( (char *)de >= (char *)(trackbuf + TRACKBUF_SIZE) ) {
+ if ( !have_more )
+ return 0;
+
+ iso_getfssec(NULL, trackbuf, file, BufSafe, &have_more);
+ offset = 0;
+ }
+
+ de = (struct iso_dir_entry *) (trackbuf + offset);
+
+ de_len = de->length;
+
+ if ( de_len == 0) {
+ offset = file_pos = (file_pos+ISO_SECTOR_SIZE) & ~(ISO_SECTOR_SIZE-1);
+ continue;
+ }
+
+
+ offset += de_len;
+
+ /* Make sure we have a full directory entry */
+ if ( offset >= TRACKBUF_SIZE ) {
+ int slop = TRACKBUF_SIZE - offset + de_len;
+ memcpy(&tmpde, de, slop);
+ offset &= TRACKBUF_SIZE - 1;
+ file->file_sector ++;
+ if ( offset ) {
+ if ( !have_more )
+ return 0;
+ iso_getfssec(NULL, trackbuf, file, BufSafe, &have_more);
+ memcpy((void*)&tmpde + slop, trackbuf, offset);
+ }
+ de = &tmpde;
+ }
+
+ if ( de_len < 33 ) {
+ printf("Corrutped directory entry in sector %d\n", file->file_sector);
+ return 0;
+ }
+
+ de_name_len = de->name_len;
+ de_name = (char *)((void *)de + 0x21);
+
+
+ if ( (de_name_len == 1) && (*de_name == 0) ) {
+ found = iso_compare_names(".", &de_name_len, name);
+
+ } else if ( (de_name_len == 1) && (*de_name == 1) ) {
+ de_name_len = 2;
+ found = iso_compare_names("..", &de_name_len, name);
+
+ } else
+ found = iso_compare_names(de_name, &de_name_len, name);
+
+ if (found)
+ break;
+
+ file_pos += de_len;
+ }
+
+ if ( file_pos >= dir->dir_len )
+ return 0; /* not found */
+
+
+ if ( *(name+de_name_len) && (*(name+de_name_len) != '/' ) ) {
+ printf("Something wrong happened during searching file %s\n", name);
+
+ *res = NULL;
+ return 0;
+ }
+
+ if ( de->flags & 0x02 ) {
+ /* it's a directory */
+ dir = &CurrentDir;
+ dir->dir_lba = *(uint32_t *)de->extent;
+ dir->dir_len = *(uint32_t *)de->size;
+ dir->dir_clust = (dir->dir_len + ISO_SECTOR_SIZE - 1) >> ISO_SECTOR_SHIFT;
+
+ *file_len = dir->dir_len;
+ *res = dir;
+
+ /* we can close it now */
+ close_file(file);
+
+ /* Mark we got a directory */
+ return 1;
+ } else {
+ /* it's a file */
+ file->file_sector = *(uint32_t *)de->extent;
+ file->file_bytesleft = *(uint32_t *)de->size;
+ file->file_left = (file->file_bytesleft + ISO_SECTOR_SIZE - 1) >> ISO_SECTOR_SHIFT;
+
+ *file_len = file->file_bytesleft;
+ *res = file;
+
+ /* Mark we got a file */
+ return 2;
+ }
+ }
+
+
+ /**
+ * iso_searchdir:
+ *
+ * open a file
+ *
+ * searchdir_iso is a special entry point for ISOLINUX only. In addition
+ * to the above, searchdir_iso passes a file flag mask in AL. This is
+ * useful for searching for directories.
+ *
+ * well, it's not like the searchidr function in EXT fs or FAT fs; it also
+ * can read a diretory.(Just thought of mine, liu)
+ *
+ */
+ void iso_searchdir(char *filename, struct file *file)
+ {
+ struct open_file_t *open_file = NULL;
+ struct dir_t *dir;
+ uint32_t file_len;
+ int ret;
+ void *res;
+
+ dir = &CurrentDir;
+ if ( *filename == '/' ) {
+ dir = &RootDir;
+ filename ++;
+ }
-
++#define DEBUG() printf("go there? %d\n", __LINE__)
+ while ( *filename ) {
-
++ DEBUG();
+ ret = do_search_dir(dir, filename, &file_len, &res);
+ if ( ret == 1 )
+ dir = (struct dir_t *)res;
+ else if ( ret == 2 )
+ break;
+ else
+ goto err;
-
++ DEBUG();
+ /* find the end */
+ while ( *filename && (*filename != '/') )
+ filename ++;
+
+ /* skip the slash */
+ while ( *filename && (*filename == '/') )
+ filename++;
+ }
-int iso_fs_init()
++ DEBUG();
+ /* well , we need recheck it , becuase it can be a directory */
+ if ( ret == 2 ) {
+ open_file = (struct open_file_t *)res;
+ goto found;
+ } else {
+ open_file = allocate_file();
+ if ( !open_file )
+ goto err;
+
+ open_file->file_sector = dir->dir_lba;
+ open_file->file_bytesleft = dir->dir_len;
+ open_file->file_left = (dir->dir_len + ISO_SECTOR_SIZE - 1) >> ISO_SECTOR_SHIFT;
+ goto found;
+ }
+ err:
+ close_file(open_file);
+ file_len = 0;
+ open_file = NULL;
+
+ found:
+ file->file_len = file_len;
+ file->open_file = (void*)open_file;
+
+ #if 0
+ if (open_file) {
+ printf("file bytesleft: %d\n", open_file->file_bytesleft);
+ printf("file sector : %d\n", open_file->file_sector);
+ printf("file in sector: %d\n", open_file->file_in_sec);
+ printf("file offsector: %d\n", open_file->file_in_off);
+ }
+ #endif
+ }
+
+ void iso_load_config(com32sys_t *regs)
+ {
+ char *config_name = "isolinux.cfg";
+ com32sys_t out_regs;
+
+ strcpy(ConfigName, config_name);
+
+ regs->edi.w[0] = OFFS_WRT(ConfigName, 0);
+ memset(&out_regs, 0, sizeof out_regs);
+ call16(core_open, regs, &out_regs);
+ }
+
+
- getlinsec_cdrom(trackbuf, bi_pvd, 1);
++int iso_fs_init(struct fs_info *fs)
+ {
+ char *iso_dir;
+ char *boot_dir = "/boot/isolinux";
+ char *isolinux_dir = "/isolinux";
+
+ struct file file;
+ struct open_file_t *open_file;
+ int len;
+ int bi_pvd = 16;
+
++ fs->fs_dev->disk->rdwr_sectors(fs->fs_dev->disk, (void*)trackbuf, bi_pvd, 1, 0);
+
+ CurrentDir.dir_lba = RootDir.dir_lba = *(uint32_t *)(trackbuf + 156 + 2);
+
+ #ifdef DEBUG
+ printf("Root directory at LBA = 0x%x\n", RootDir.dir_lba);
+ #endif
+
+ CurrentDir.dir_len = RootDir.dir_len = *(uint32_t*)(trackbuf + 156 + 10);
+ CurrentDir.dir_clust = RootDir.dir_clust = (RootDir.dir_len + ISO_SECTOR_SIZE - 1) >> ISO_SECTOR_SHIFT;
+
+ /*
+ * Look for an isolinux directory, and if found,
+ * make it the current directory instead of the
+ * root directory.
+ *
+ * Also copy the name of the directory to CurrrentDirName
+ */
+ *(uint16_t *)CurrentDirName = ROOT_DIR_WORD;
+
+ iso_dir = boot_dir;
+ iso_searchdir(boot_dir, &file); /* search for /boot/isolinux */
+ if ( !file.file_len ) {
+ iso_dir = isolinux_dir;
+ iso_searchdir(isolinux_dir, &file); /* search for /isolinux */
+ if ( !file.file_len ) {
+ printf("No isolinux directory found!\n");
+ return 0;
+ }
+ }
+
+ strcpy(CurrentDirName, iso_dir);
+ len = strlen(CurrentDirName);
+ CurrentDirName[len] = '/';
+ CurrentDirName[len+1] = '\0';
+
+ open_file = (struct open_file_t *)file.open_file;
+ CurrentDir.dir_len = open_file->file_bytesleft;
+ CurrentDir.dir_clust = open_file->file_left;
+ CurrentDir.dir_lba = open_file->file_sector;
+ close_file(open_file);
+
+ #ifdef DEBUG
+ printf("isolinux directory at LBA = 0x%x\n", CurrentDir.dir_lba);
+ #endif
+
+ /* we do not use cache for now, so we can just return 0 */
+ return 0;
+ }
+
+
+ const struct fs_ops iso_fs_ops = {
+ .fs_name = "iso",
+ .fs_init = iso_fs_init,
+ .searchdir = iso_searchdir,
+ .getfssec = iso_getfssec,
+ .mangle_name = iso_mangle_name,
+ .unmangle_name = NULL,
+ .load_config = iso_load_config
+ };