diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-05-21 15:36:50 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-05-21 15:36:50 -0700 |
commit | e462c28ffaca0132c1761736bc93cb06a41dc7a6 (patch) | |
tree | 24edb9f85175bdd6cc30bf270f3e59571bca71ae /mbr | |
parent | d4d9f190900d31b5e9428401a0175012957d7cb7 (diff) | |
download | syslinux-e462c28ffaca0132c1761736bc93cb06a41dc7a6.tar.gz |
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/Makefile | 9 | ||||
-rwxr-xr-x | mbr/checksize.pl | 2 | ||||
-rw-r--r-- | mbr/isohdpfx.S | 69 |
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 */ |