Functions disk_write_sector() and disk_write_verify_sector() take 64bit lba as an argument now - similary to disk_read_sectors(). Structure disk_info additionally provides cylinders, besides head and sector. Sanity checks during lba -> chs conversions have been adjusted to use cylinders. CX in cbios read/write code was not calculated properly. Minor signed/unsigned changes. Signed-off-by: Michal Soltys <soltys at ziu.info> --- com32/include/syslinux/disk.h | 11 ++++++----- com32/lib/syslinux/disk.c | 22 ++++++++++++---------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/com32/include/syslinux/disk.h b/com32/include/syslinux/disk.h index ff80532..4e8de4f 100644 --- a/com32/include/syslinux/disk.h +++ b/com32/include/syslinux/disk.h @@ -39,14 +39,15 @@ #include <com32.h> #include <stdint.h> -#define SECTOR 512 /* bytes/sector */ +#define SECTOR 512u /* bytes/sector */ struct disk_info { int disk; int ebios; /* EBIOS supported on this disk */ int cbios; /* CHS geometry is valid */ - int head; - int sect; + unsigned int head; + unsigned int sect; + unsigned int cyl; }; struct disk_ebios_dapa { @@ -144,9 +145,9 @@ extern int disk_get_params(int disk, struct disk_info *const diskinfo); extern void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba, uint8_t count); extern int disk_write_sector(const struct disk_info *const diskinfo, - unsigned int lba, const void *data); + uint64_t lba, const void *data); extern int disk_write_verify_sector(const struct disk_info *const diskinfo, - unsigned int lba, const void *buf); + uint64_t lba, const void *buf); extern void disk_dos_part_dump(const struct disk_dos_part_entry *const part); extern void guid_to_str(char *buf, const struct guid *const id); extern int str_to_guid(const char *buf, struct guid *const id); diff --git a/com32/lib/syslinux/disk.c b/com32/lib/syslinux/disk.c index 678e4bd..1efd1ec 100644 --- a/com32/lib/syslinux/disk.c +++ b/com32/lib/syslinux/disk.c @@ -103,6 +103,8 @@ int disk_get_params(int disk, struct disk_info *const diskinfo) diskinfo->head = parm.edx.b[1] + 1; diskinfo->sect = parm.ecx.b[0] & 0x3f; + diskinfo->cyl = (parm.ecx.b[1] | + ((parm.ecx.b[0] & 0xc0u) << 2)) + 1; if (diskinfo->sect == 0) { diskinfo->sect = 1; } else { @@ -161,19 +163,19 @@ void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba, h = 0; c = 0; } else { + if (lba + count > diskinfo->cyl * diskinfo->head * diskinfo->sect) + /* beyond acceptable geometry */ + return NULL; s = (lba % diskinfo->sect) + 1; t = lba / diskinfo->sect; /* Track = head*cyl */ h = t % diskinfo->head; c = t / diskinfo->head; } - if (s > 63 || h > 256 || c > 1023) - return NULL; - inreg.eax.b[0] = count; inreg.eax.b[1] = 0x02; /* Read */ inreg.ecx.b[1] = c & 0xff; - inreg.ecx.b[0] = s + (c >> 6); + inreg.ecx.b[0] = ((c >> 2) & 0xc0u) | s; inreg.edx.b[1] = h; inreg.edx.b[0] = diskinfo->disk; inreg.ebx.w[0] = OFFS(buf); @@ -200,7 +202,7 @@ void *disk_read_sectors(const struct disk_info *const diskinfo, uint64_t lba, * Uses the disk number and information from diskinfo. * Write a sector to a disk drive, starting at lba. */ -int disk_write_sector(const struct disk_info *const diskinfo, unsigned int lba, +int disk_write_sector(const struct disk_info *const diskinfo, uint64_t lba, const void *data) { com32sys_t inreg; @@ -234,18 +236,18 @@ int disk_write_sector(const struct disk_info *const diskinfo, unsigned int lba, h = 0; c = 0; } else { + if (lba >= diskinfo->cyl * diskinfo->head * diskinfo->sect) + /* beyond acceptable geometry */ + return -1; s = (lba % diskinfo->sect) + 1; t = lba / diskinfo->sect; /* Track = head*cyl */ h = t % diskinfo->head; c = t / diskinfo->head; } - if (s > 63 || h > 256 || c > 1023) - return -1; - inreg.eax.w[0] = 0x0301; /* Write one sector */ inreg.ecx.b[1] = c & 0xff; - inreg.ecx.b[0] = s + (c >> 6); + inreg.ecx.b[0] = ((c >> 2) & 0xc0u) | s; inreg.edx.b[1] = h; inreg.edx.b[0] = diskinfo->disk; inreg.ebx.w[0] = OFFS(buf); @@ -271,7 +273,7 @@ int disk_write_sector(const struct disk_info *const diskinfo, unsigned int lba, * to verify it was written correctly. */ int disk_write_verify_sector(const struct disk_info *const diskinfo, - unsigned int lba, const void *buf) + uint64_t lba, const void *buf) { char *rb; int rv; -- 1.7.2.1