aboutsummaryrefslogtreecommitdiffstats
path: root/mbr/gptmbr.S
diff options
context:
space:
mode:
authorFrediano Ziglio <frediano.ziglio@citrix.com>2013-02-08 12:58:36 +0000
committerMatt Fleming <matt.fleming@intel.com>2013-02-11 12:39:27 +0000
commit6f7b0e4a33e4064c8e814cbebeacf7206c9fb850 (patch)
treef099c36bb6b2b7b3b9d614769a149b612e0ba394 /mbr/gptmbr.S
parent8b94ab8751d98c0355d0a0d60453c151e22d6fbb (diff)
downloadsyslinux-6f7b0e4a33e4064c8e814cbebeacf7206c9fb850.tar.gz
syslinux-6f7b0e4a33e4064c8e814cbebeacf7206c9fb850.tar.xz
syslinux-6f7b0e4a33e4064c8e814cbebeacf7206c9fb850.zip
4k_sector: Support sectors >512
If EBIOS is detected for this drive it tries to read sector size and use it. If error or no EBIOS 512 is assumed. Buffer to read sector size is always allocated into the stack. CHS informations are not readed as not needed and save space not restoring %dl for drive number. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'mbr/gptmbr.S')
-rw-r--r--mbr/gptmbr.S41
1 files changed, 27 insertions, 14 deletions
diff --git a/mbr/gptmbr.S b/mbr/gptmbr.S
index 9efa342e..7f450d30 100644
--- a/mbr/gptmbr.S
+++ b/mbr/gptmbr.S
@@ -77,6 +77,12 @@ next:
ADJUST_DRIVE
pushw %dx /* 0(%bp) = %dl -> drive number */
+ movw %sp, %bp /* %bp -> frame pointer: LEAVE UNCHANGED */
+
+ /* prepare to read sector size */
+ sub $0x1c, %sp /* -28(%bp) == %sp */
+ pushw $0x1e /* -30(%bp) == %sp */
+ movw $0x200, -6(%bp) /* -6(%bp) sector size */
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
@@ -86,6 +92,8 @@ next:
xorb %dh, %dh
stc
int $0x13
+ popw %dx /* restore drive */
+ movb $0x08, %ah /* get CHS geometry */
jc 1f
cmpw $0xaa55, %bx
jne 1f
@@ -97,22 +105,28 @@ next:
movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
(read_sector_cbios)
-1:
- popw %dx
+ /*
+ * read sector size.
+ * Should not fail but if it does I assume that at least
+ * previous 512 value is not overridden
+ */
+ movb $0x48, %ah
+ movw %sp, %si
+1:
/* Get (C)HS geometry */
- movb $0x08, %ah
int $0x13
+
+ /* here we computer CHS values or just do some dummy computation for EBIOS */
andw $0x3f, %cx /* Sector count */
- movw %sp, %bp /* %bp -> frame pointer: LEAVE UNCHANGED */
- pushw %cx /* -2(%bp) Save sectors on the stack */
+ pushw %cx /* -32(%bp) Save sectors on the stack */
movzbw %dh, %ax /* dh = max head */
incw %ax /* From 0-based max to count */
mulw %cx /* Heads*sectors -> sectors per cylinder */
/* Save sectors/cylinder on the stack */
- pushw %dx /* -4(%bp) High word */
- pushw %ax /* -6(%bp) Low word */
+ pushw %dx /* -34(%bp) High word */
+ pushw %ax /* -36(%bp) Low word */
/* Load partition table header */
xorl %eax,%eax
@@ -121,14 +135,13 @@ next:
call read_sector_phdr
/* Number of partition sectors */
- /* We assume the partition table is 32K or less, and that
- the sector size is 512. */
+ /* We assume the partition table is 32K or less */
movw (80+6)(%bp),%cx /* NumberOfPartitionEntries */
movw (84+6)(%bp),%ax /* SizeOfPartitionEntry */
pushw %ax
pushw %cx
mulw %cx
- shrw $9,%ax
+ divw -6(%bp) /* %dx == 0 here */
xchgw %ax,%cx
incw %cx
@@ -213,7 +226,7 @@ boot:
movl (32+20)(%si),%eax
movl (36+20)(%si),%edx
call read_sector_phdr
- cmpw $0xaa55, -2(%bx)
+ cmpw $0xaa55, (0x7c00+0x1fe)
jne missing_os /* Not a valid boot sector */
movw %bp, %sp /* driveno == bootsec-6 */
popw %dx /* dl -> drive number */
@@ -257,12 +270,12 @@ read_sector:
/* This chunk is skipped if we have ebios */
/* Do not clobber %es:%bx or %edx:%eax before this chunk! */
read_sector_cbios:
- divl -6(%bp) /* secpercyl */
+ divl -36(%bp) /* secpercyl */
shlb $6, %ah
movb %ah, %cl
movb %al, %ch
xchgw %dx, %ax
- divb -2(%bp) /* sectors */
+ divb -32(%bp) /* sectors */
movb %al, %dh
orb %ah, %cl
incw %cx /* Sectors are 1-based */
@@ -274,7 +287,7 @@ read_common:
leaw 16(%si), %sp /* Drop DAPA */
popal
jc disk_error
- addb $2, %bh /* bx += 512: point to the next buffer */
+ addb -5(%bp), %bh /* bx += sector size: point to the next buffer */
/* fall through and increment sector number */