aboutsummaryrefslogtreecommitdiffstats
path: root/mbr
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-05-21 15:36:50 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-05-21 15:36:50 -0700
commite462c28ffaca0132c1761736bc93cb06a41dc7a6 (patch)
tree24edb9f85175bdd6cc30bf270f3e59571bca71ae /mbr
parentd4d9f190900d31b5e9428401a0175012957d7cb7 (diff)
downloadsyslinux-e462c28ffaca0132c1761736bc93cb06a41dc7a6.tar.gz
syslinux-e462c28ffaca0132c1761736bc93cb06a41dc7a6.tar.xz
syslinux-e462c28ffaca0132c1761736bc93cb06a41dc7a6.zip
isohybrid: support booting from partition; fix CBIOS booting
Fix CBIOS in isohybrid mode. Also allow an isohybrid image to be booted from a partition. Unfortunately this breaks compatibility between differing versions of isohybrid and isolinux.bin. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'mbr')
-rw-r--r--mbr/Makefile9
-rwxr-xr-xmbr/checksize.pl2
-rw-r--r--mbr/isohdpfx.S69
3 files changed, 55 insertions, 25 deletions
diff --git a/mbr/Makefile b/mbr/Makefile
index 3140132a..c3eb97a7 100644
--- a/mbr/Makefile
+++ b/mbr/Makefile
@@ -18,11 +18,10 @@
topdir = ..
include $(topdir)/MCONFIG.embedded
-all: mbr.bin altmbr.bin gptmbr.bin isohdpfx.bin \
- mbr_c.bin altmbr_c.bin gptmbr_c.bin isohdpfx_c.bin \
- mbr_f.bin altmbr_f.bin gptmbr_f.bin isohdpfx_f.bin
+all: mbr.bin altmbr.bin gptmbr.bin isohdpfx.bin isohdppx.bin \
+ mbr_c.bin altmbr_c.bin gptmbr_c.bin isohdpfx_c.bin isohdppx_c.bin \
+ mbr_f.bin altmbr_f.bin gptmbr_f.bin isohdpfx_f.bin isohdppx_f.bin
-.PRECIOUS: %.o
%.o: %.S
$(CC) $(MAKEDEPS) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $<
@@ -50,3 +49,5 @@ clean: tidy
spotless: clean
rm -f *.bin
+
+-include .*.d
diff --git a/mbr/checksize.pl b/mbr/checksize.pl
index 4648c95c..7d61bdfd 100755
--- a/mbr/checksize.pl
+++ b/mbr/checksize.pl
@@ -27,7 +27,7 @@ if (!defined($maxsize)) {
$maxsize = $padsize = 440;
} elsif ($file =~ /^gptmbr[^0-9a-z]/) {
$maxsize = $padsize = 424;
- } elsif ($file =~ /^isohdpfx[^0-9a-z]/) {
+ } elsif ($file =~ /^isohdp[fp]x[^0-9a-z]/) {
$maxsize = $padsize = 432;
} elsif ($file =~ /^altmbr[^0-9a-z]/) {
$maxsize = 439; $padsize = 440;
diff --git a/mbr/isohdpfx.S b/mbr/isohdpfx.S
index f42b4b5b..53e1ed6b 100644
--- a/mbr/isohdpfx.S
+++ b/mbr/isohdpfx.S
@@ -39,7 +39,7 @@
.code16
.text
-HYBRID_MAGIC = 0x7078c0fb
+HYBRID_MAGIC = 0x0defe3f7
isolinux_hybrid_signature = 0x7c00+64
isolinux_start_hybrid = 0x7c00+64+4
@@ -47,10 +47,11 @@ isolinux_start_hybrid = 0x7c00+64+4
/* Important: the top 6 words on the stack are passed to isolinux.bin */
stack = 0x7c00
driveno = (stack-6)
-ebios_flag = (stack-8)
-sectors = (stack-10)
-heads = (stack-12)
-secpercyl = (stack-16)
+partoffset = (stack-14)
+ebios_flag = (stack-16)
+sectors = (stack-18)
+heads = (stack-20)
+secpercyl = (stack-24)
BIOS_kbdflags = 0x417
BIOS_page = 0x462
@@ -66,18 +67,47 @@ bootsec:
_start:
cli
- xorw %ax, %ax
- movw %ax, %ds
- movw %ax, %ss
+ xorw %bx, %bx
+ movw %bx, %ds
+ movw %bx, %ss
movw $stack, %sp
- movw %sp, %si
- pushw %es /* es:di -> $PnP header */
+ pushw %es /* -4: es:di -> $PnP header */
pushw %di
- movw %ax, %es
+ movw %bx, %es
sti
cld
+ ADJUST_DRIVE
+ pushw %dx /* -6: dl -> drive number */
+
+ /* Check to see if we have a partition table entry */
+#ifdef PARTITION_SUPPORT
+ andw %si, %si /* %si == 0 -> no partition data */
+ jz 1f
+ testb $0x7f, (%si) /* Invalid active flag field? */
+ jnz 1f
+ cmpl $0x58504721, %eax /* !GPT signature in EAX? */
+ jne 2f
+ cmpb $0xee, 4(%si) /* EFI partition type? */
+ jne 2f
+ /* We have GPT partition information */
+ pushl (36+16)(%si) /* -10: partoffset_hi */
+ pushl (32+16)(%si) /* -14: partoffset_lo */
+ jmp 3f
+2:
+ /* We have non-GPT partition information */
+ pushl $0 /* -10: partoffset_hi */
+ pushl 8(%si) /* -14: partoffset_lo */
+ jmp 3f
+#endif
+1:
+ /* We have no partition information */
+ pushl $0 /* -10: partoffset_hi */
+ pushl $0 /* -14: partoffset_lo */
+3:
+
/* Copy down to 0:0x600 */
+ movw $0x7c00, %si
movw $_start, %di
movw $(512/2), %cx
rep; movsw
@@ -85,9 +115,6 @@ _start:
ljmpw $0, $next
next:
- ADJUST_DRIVE
- pushw %dx /* dl -> drive number */
-
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
@@ -106,24 +133,24 @@ next:
read_sector_cbios: movb $0x42, %ah ; jmp read_common */
movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
(read_sector_cbios)
-
+ jmp 1f
1:
popw %dx
- pushw %cx /* Save EBIOS flag */
+ pushw %cx /* -16: Save EBIOS flag */
/* Get (C)HS geometry */
movb $0x08, %ah
int $0x13
andw $0x3f, %cx /* Sector count */
- pushw %cx /* Save sectors on the stack */
+ pushw %cx /* -18: Save sectors on the stack */
movzbw %dh, %ax /* dh = max head */
incw %ax /* From 0-based max to count */
- pushw %ax /* Save heads on the stack */
+ pushw %ax /* -20: Save heads on the stack */
mulw %cx /* Heads*sectors -> sectors per cylinder */
/* Save sectors/cylinder on the stack */
- pushw %dx /* High word */
- pushw %ax /* Low word */
+ pushw %dx /* -22: High word */
+ pushw %ax /* -24: Low word */
/*
* Load sectors. We do this one at a time mostly to avoid
@@ -169,6 +196,8 @@ bad_signature:
read_sector:
pushal
xorl %edx, %edx
+ addl (partoffset), %eax
+ adcl (partoffset+4), %edx
pushl %edx /* MSW of LBA */
pushl %eax /* LSW of LBA */
pushw %es /* Buffer segment */