[syslinux:pathbased] iso9660: use boot_info_table and fix hybrid mode

syslinux-bot for H. Peter Anvin hpa at zytor.com
Fri Feb 26 13:21:25 PST 2010


Commit-ID:  3e89b30bfa7b90d785d8f97ea5638a7b63e12c94
Gitweb:     http://syslinux.zytor.com/commit/3e89b30bfa7b90d785d8f97ea5638a7b63e12c94
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Fri, 26 Feb 2010 13:18:26 -0800
Committer:  H. Peter Anvin <hpa at zytor.com>
CommitDate: Fri, 26 Feb 2010 13:18:26 -0800

iso9660: use boot_info_table and fix hybrid mode

In hybrid disk mode, one block will generally *not* equal one sector.
Use the boot_info_table to find the primary volume descriptor.
Remove the now-unused cdrom_read_blocks().

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/fs/iso9660/iso9660.c    |   31 +++++++++++++++++++------------
 core/fs/iso9660/iso9660_fs.h |   11 +++++++++++
 core/isolinux.asm            |    2 ++
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index c32c3a0..995cd21 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -134,12 +134,6 @@ static bool iso_compare_name(const char *de_name, size_t len,
     return true;
 }
 
-static inline int cdrom_read_blocks(struct disk *disk, void *buf, 
-				    int block, int blocks)
-{
-    return disk->rdwr_sectors(disk, buf, block, blocks, 0);
-}
-
 /*
  * Find a entry in the specified dir with name _dname_.
  */
@@ -314,25 +308,38 @@ static int iso_load_config(void)
     return 0;
 }
 
-
 static int iso_fs_init(struct fs_info *fs)
 {
     struct iso_sb_info *sbi;
-    
+    char pvd[2048];		/* Primary Volume Descriptor */
+    uint32_t pvd_lba;
+    struct disk *disk = fs->fs_dev->disk;
+    int blktosec;
+
     sbi = malloc(sizeof(*sbi));
     if (!sbi) {
 	malloc_error("iso_sb_info structure");
 	return 1;
     }
     fs->fs_info = sbi;
-    
-    cdrom_read_blocks(fs->fs_dev->disk, trackbuf, 16, 1);
-    memcpy(&sbi->root, trackbuf + ROOT_DIR_OFFSET, sizeof(sbi->root));
 
+    /* 
+     * XXX: handling iso9660 in hybrid mode on top of a 4K-logical disk
+     * will really, really hurt...
+     */
     fs->sector_shift = fs->fs_dev->disk->sector_shift;
-    fs->block_shift  = 11;
+    fs->block_shift  = 11;	/* A CD-ROM block is always 2K */
     fs->sector_size  = 1 << fs->sector_shift;
     fs->block_size   = 1 << fs->block_shift;
+    blktosec = fs->block_shift - fs->sector_shift;
+
+    pvd_lba = iso_boot_info.pvd;
+    if (!pvd_lba)
+	pvd_lba = 16;		/* Default if not otherwise defined */
+
+    disk->rdwr_sectors(disk, pvd, (sector_t)pvd_lba << blktosec,
+		       1 << blktosec, false);
+    memcpy(&sbi->root, pvd + ROOT_DIR_OFFSET, sizeof(sbi->root));
 
     /* Initialize the cache */
     cache_init(fs->fs_dev, fs->block_shift);
diff --git a/core/fs/iso9660/iso9660_fs.h b/core/fs/iso9660/iso9660_fs.h
index 6e9d495..a365fa1 100644
--- a/core/fs/iso9660/iso9660_fs.h
+++ b/core/fs/iso9660/iso9660_fs.h
@@ -4,6 +4,17 @@
 #include <klibc/compiler.h>
 #include <stdint.h>
 
+/* Boot info table */
+struct iso_boot_info {
+    uint32_t pvd;		/* LBA of primary volume descriptor */
+    uint32_t file;		/* LBA of boot file */
+    uint32_t length;		/* Length of boot file */
+    uint32_t csum;		/* Checksum of boot file */
+    uint32_t reserved[10];	/* Currently unused */
+};
+
+extern struct iso_boot_info iso_boot_info; /* In isolinux.asm */
+
 /* The root dir entry offset in the primary volume descriptor */
 #define ROOT_DIR_OFFSET   156
 
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 078f7ca..7329f14 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -200,6 +200,8 @@ _start:		; Far jump makes sure we canonicalize the address
 		; -boot-info-table option.  If not, the values in this
 		; table are default values that we can use to get us what
 		; we need, at least under a certain set of assumptions.
+		global iso_boot_info
+iso_boot_info:
 bi_pvd:		dd 16				; LBA of primary volume descriptor
 bi_file:	dd 0				; LBA of boot file
 bi_length:	dd 0xdeadbeef			; Length of boot file



More information about the Syslinux-commits mailing list