From b42cf60c1018f6fe99f2f7e2bd323deeba6fde9c Mon Sep 17 00:00:00 2001 From: Liu Aleaxander Date: Mon, 13 Jul 2009 14:34:52 +0800 Subject: [PATCH] Core: fix the HD-mode error in isolinux error fixed. Just as what hpa told, deal with that might simply be to consider a 2K CD sector a "block" rather than a "sector". so, in cdrom mode, we have 2K blocksize and 2k sector size, while in hybrid mode we have 2k blocksize and 512 bytes sector size. --- core/diskio.c | 14 ++++++++++++-- core/iso9660.c | 19 ++++++++++++++++--- core/isolinux.asm | 10 +++++----- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/core/diskio.c b/core/diskio.c index bb5b34c..7d3ec3f 100644 --- a/core/diskio.c +++ b/core/diskio.c @@ -17,7 +17,7 @@ static int chs_rdwr_sectors(struct disk *disk, void *buf, char *tptr; size_t chunk, freeseg; int sector_shift = disk->sector_shift; - uint32_t xlba = lba; /* Truncated LBA (CHS is << 2 TB) */ + uint32_t xlba = lba + disk->part_start; /* Truncated LBA (CHS is << 2 TB) */ uint32_t t; uint16_t c, h, s; com32sys_t ireg, oreg; @@ -124,6 +124,7 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf, ireg.ds = SEG(&pkt); ireg.esi.w[0] = OFFS(&pkt); + lba += disk->part_start; while (count) { chunk = count; if (chunk > MaxTransfer) @@ -151,7 +152,7 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf, pkt.blocks = chunk; pkt.buf = FAR_PTR(tptr); pkt.lba = lba; - + retry = RETRY_COUNT; for (;;) { @@ -245,6 +246,15 @@ struct disk *disk_init(uint8_t devno, bool cdrom, sector_t part_start, bool ebios = cdrom; int sector_size = cdrom ? 2048 : 512; + /* + * set the size be 512 when we are in iso_hybrid mode. + * we estimate it by the devno, As far as I know, the + * cdrom will use 0xe0 and above as the devno, well I'm + * not sure it's right or not. + */ + if (devno < 0xe0) + sector_size = 512; + memset(&ireg, 0, sizeof ireg); /* Get EBIOS support */ diff --git a/core/iso9660.c b/core/iso9660.c index 7bf82e6..ed5e013 100644 --- a/core/iso9660.c +++ b/core/iso9660.c @@ -57,6 +57,12 @@ uint8_t RetryCount; /* Used for ISO directory search */ uint16_t bsSecPerTrack; /* Used in hybrid mode */ uint16_t bsHeads; /* Used in hybrid mode */ +/* + * use to store the block shift, since we treat the hd-mode as 512 bytes + * sector size, 2048 bytes block size. we still treat the cdrom as 2048 + * bytes sector size and also the block size. + */ +int block_shift; /** * allocate_file: @@ -235,6 +241,13 @@ int iso_compare_names(char *de_name, int *len, char *file_name) return 1; } +static inline int cdrom_read_sectors(struct disk *disk, void *buf, int block, int count) +{ + /* changed those to _sector_ */ + block <<= block_shift; + count <<= block_shift; + return disk->rdwr_sectors(disk, buf, block, count, 0); +} /** * iso_getfssec: @@ -257,7 +270,7 @@ uint32_t iso_getfssec(struct fs_info *fs, char *buf, if ( sectors > file->file_left ) sectors = file->file_left; - disk->rdwr_sectors(disk, buf, file->file_sector, sectors, 0); + cdrom_read_sectors(disk, buf, file->file_sector, sectors); file->file_sector += sectors; file->file_left -= sectors; @@ -515,8 +528,8 @@ int iso_fs_init(struct fs_info *fs) struct open_file_t *open_file; struct disk *disk = fs->fs_dev->disk; - disk->rdwr_sectors(disk, trackbuf, bi_pvd, 1, 0); - + block_shift = ISO_SECTOR_SHIFT - disk->sector_shift; + cdrom_read_sectors(disk, trackbuf, bi_pvd, 1); CurrentDir.dir_lba = RootDir.dir_lba = *(uint32_t *)(trackbuf + 156 + 2); #ifdef DEBUG diff --git a/core/isolinux.asm b/core/isolinux.asm index ddd4594..4b11b43 100644 --- a/core/isolinux.asm +++ b/core/isolinux.asm @@ -1165,12 +1165,12 @@ all_read: ; we should be able to find the rest of what we need to know. ; pushad - extern iso_fs_ops - mov eax,iso_fs_ops - mov dl,[DriveNumber] + extern iso_fs_ops + mov eax,iso_fs_ops + mov dl,[DriveNumber] mov dh,1 ; it's cdrom - mov ecx,[bsHidden] - mov ebx,[bsHidden+4] + mov ecx,[bsHidden] + mov ebx,[bsHidden+4] mov si,[bsHeads] mov di,[bsSecPerTrack] pm_call fs_init -- 2.7.4