[syslinux] [PATCH] disklib: small fixes / addons
Michal Soltys
soltys at ziu.info
Thu Aug 19 06:07:05 PDT 2010
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
More information about the Syslinux
mailing list