diff options
Diffstat (limited to 'contrib/syslinux-4.02/mbr')
-rw-r--r-- | contrib/syslinux-4.02/mbr/Makefile | 53 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/adjust.h | 53 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/altmbr.S | 304 | ||||
-rwxr-xr-x | contrib/syslinux-4.02/mbr/checksize.pl | 54 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/gptmbr.S | 309 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/isohdpfx.S | 263 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/isohdppx.S | 2 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/mbr.S | 299 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/mbr.ld | 73 | ||||
-rw-r--r-- | contrib/syslinux-4.02/mbr/oldmbr.asm | 230 |
10 files changed, 1640 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/mbr/Makefile b/contrib/syslinux-4.02/mbr/Makefile new file mode 100644 index 0000000..c3eb97a --- /dev/null +++ b/contrib/syslinux-4.02/mbr/Makefile @@ -0,0 +1,53 @@ +## ----------------------------------------------------------------------- +## +## Copyright 2007-2009 H. Peter Anvin - All Rights Reserved +## Copyright 2009 Intel Corporation; author: H. Peter Anvin +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, Inc., 53 Temple Place Ste 330, +## Boston MA 02111-1307, USA; either version 2 of the License, or +## (at your option) any later version; incorporated herein by reference. +## +## ----------------------------------------------------------------------- + +# +# Makefile for MBR +# + +topdir = .. +include $(topdir)/MCONFIG.embedded + +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 + +%.o: %.S + $(CC) $(MAKEDEPS) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $< + +%_c.o: %.S + $(CC) $(MAKEDEPS) $(SFLAGS) -Wa,-a=$*_c.lst -DCTRL_80 -c -o $@ $< + +%_f.o: %.S + $(CC) $(MAKEDEPS) $(SFLAGS) -Wa,-a=$*_f.lst -DFORCE_80 -c -o $@ $< + +.PRECIOUS: %.elf +%.elf: %.o mbr.ld + $(LD) $(LDFLAGS) -T mbr.ld -e _start -o $@ $< + +%.bin: %.elf checksize.pl + $(OBJCOPY) -O binary $< $@ + $(PERL) checksize.pl $@ + $(CHMOD) -x $@ + +mbr_bin.c: mbr.bin + +tidy dist: + rm -f *.o *.elf *.lst .*.d + +clean: tidy + +spotless: clean + rm -f *.bin + +-include .*.d diff --git a/contrib/syslinux-4.02/mbr/adjust.h b/contrib/syslinux-4.02/mbr/adjust.h new file mode 100644 index 0000000..42c12a3 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/adjust.h @@ -0,0 +1,53 @@ +/* -*- asm -*- ----------------------------------------------------------- + * + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * adjust.h + * + * Macros to adjust the drive number + */ + +#ifndef ADJUST_H +#define ADJUST_H + +#ifdef CTRL_80 + .macro ADJUST_DRIVE + testb $0x04, BIOS_kbdflags + jz 1f + movb $0x80, %dl +1: + .endm +#elif defined(FORCE_80) + .macro ADJUST_DRIVE + movb $0x80, %dl + .endm +#else + .macro ADJUST_DRIVE + .endm +#endif + +#endif /* ADJUST_H */ diff --git a/contrib/syslinux-4.02/mbr/altmbr.S b/contrib/syslinux-4.02/mbr/altmbr.S new file mode 100644 index 0000000..794ab62 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/altmbr.S @@ -0,0 +1,304 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include "adjust.h" + + .code16 + .text + + .globl bootsec +stack = 0x7c00 +driveno = (stack-6) +sectors = (stack-8) +secpercyl = (stack-12) + +BIOS_kbdflags = 0x417 +BIOS_page = 0x462 + + /* gas/ld has issues with doing this as absolute addresses... */ + .section ".bootsec", "a", @nobits + .globl bootsec +bootsec: + .space 512 + + .text + .globl _start +_start: + cli + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw $stack, %sp + movw %sp, %si + pushw %es /* es:di -> $PnP header */ + pushw %di + movw %ax, %es + sti + cld + + /* Copy down to 0:0x600 */ + movw $_start, %di + movw $(512/2), %cx + rep; movsw + + 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 */ + movw $0x55aa, %bx + xorw %cx, %cx + xorb %dh, %dh + stc + int $0x13 + jc 1f + cmpw $0xaa55, %bx + jne 1f + shrw %cx /* Bit 0 = fixed disk subset */ + jnc 1f + + /* We have EBIOS; patch in the following code at + read_sector_cbios: movb $0x42, %ah ; jmp read_common */ + movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ + (read_sector_cbios) + +1: + popw %dx + + /* Get (C)HS geometry */ + movb $0x08, %ah + int $0x13 + andw $0x3f, %cx /* Sector count */ + pushw %cx /* 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 /* High word */ + pushw %ax /* Low word */ + + xorl %eax, %eax /* Base */ + cdq /* Root (%edx <- 0) */ + call scan_partition_table + + /* If we get here, we have no OS */ +missing_os: + call error + .ascii "Missing operating system.\r\n" + +/* + * read_sector: read a single sector pointed to by %eax to 0x7c00. + * CF is set on error. All registers saved. + */ +read_sector: + pushal + xorl %edx, %edx + movw $bootsec, %bx + pushl %edx /* MSW of LBA */ + pushl %eax /* LSW of LBA */ + pushw %es /* Buffer segment */ + pushw %bx /* Buffer offset */ + pushw $1 /* Sector count */ + pushw $16 /* Size of packet */ + movw %sp, %si + + /* This chunk is skipped if we have ebios */ + /* Do not clobber %eax before this chunk! */ + /* This also relies on %bx and %edx as set up above. */ +read_sector_cbios: + divl (secpercyl) + shlb $6, %ah + movb %ah, %cl + movb %al, %ch + xchgw %dx, %ax + divb (sectors) + movb %al, %dh + orb %ah, %cl + incw %cx /* Sectors are 1-based */ + movw $0x0201, %ax + +read_common: + movb (driveno), %dl + int $0x13 + leaw 16(%si), %sp /* Drop DAPA */ + popal + ret + +/* + * read_partition_table: + * Read a partition table (pointed to by %eax), and copy + * the partition table into the ptab buffer. + * + * Clobbers %si, %di, and %cx, other registers preserved. + * %cx = 0 on exit. + * + * On error, CF is set and ptab is overwritten with junk. + */ +ptab = _start+446 + +read_partition_table: + call read_sector + movw $bootsec+446, %si + movw $ptab, %di + movw $(16*4/2), %cx + rep ; movsw + ret + +/* + * scan_partition_table: + * Scan a partition table currently loaded in the partition table + * area. Preserve all registers. + * + * On entry: + * %eax - base (location of this partition table) + * %edx - root (offset from MBR, or 0 for MBR) + * + * These get pushed into stack slots: + * 28(%bp) - %eax - base + * 20(%bp) - %edx - root + */ + +scan_partition_table: + pushal + movw %sp, %bp + + /* Scan the primary partition table */ + movw $ptab, %si + movw $4, %cx + /* Is it a primary partition table? */ + andl %edx, %edx + jnz 7f + push %si + push %cx + +5: + decb (partition) + jz boot + addw $16, %bx + loopw 5b + + popw %cx /* %cx <- 4 */ + popw %si /* %si <- ptab */ + + /* No primary partitions found, look for extended/logical partitions */ +7: + movb 4(%si), %al + andb %al, %al + jz 12f /* Not a valid partition */ + cmpb $0x0f, %al /* 0x0f = Win9x extended */ + je 8f + andb $~0x80, %al /* 0x85 = Linux extended */ + cmpb $0x05, %al /* 0x05 = MS-DOS extended */ + jne 9f + + /* It is an extended partition. Read the extended partition and + try to scan it. If the scan returns, re-load the current + partition table and resume scan. */ +8: + movl 8(%si), %eax /* Partition table offset */ + addl %edx, %eax /* Compute location of new ptab */ + andl %edx, %edx /* Is this the MBR? */ + jnz 10f + movl %eax, %edx /* Offset -> root if this was MBR */ +10: + call read_partition_table + jc 11f + call scan_partition_table +11: + /* This returned, so we need to reload the current partition table */ + movl 28(%bp), %eax /* "Base" */ + call read_partition_table + + /* fall through */ +9: + /* Not an extended partition */ + andl %edx, %edx /* Are we inside an extended part? */ + jz 12f + /* If so, this is a logical partition */ + decb (partition) + je boot +12: + addw $16, %si + loopw 7b + + /* Nothing found, return */ + popal + ret + +/* + * boot: invoke the actual bootstrap. (%si) points to the partition + * table entry, and 28(%bp) has the partition table base. + */ +boot: + cmpb $0, 4(%si) + je missing_os + movl 8(%si), %eax + addl 28(%bp), %eax + movl %eax, 8(%si) /* Adjust in-memory partition table entry */ + call read_sector + jc disk_error + cmpw $0xaa55, (bootsec+510) + jne missing_os /* Not a valid boot sector */ + movw $driveno, %sp /* driveno == bootsec-6 */ + popw %dx /* dl -> drive number */ + popw %di /* es:di -> $PnP vector */ + popw %es + cli + jmpw *%sp /* %sp == bootsec */ + +disk_error: + call error + .ascii "Operating system load error.\r\n" + +/* + * Print error messages. This is invoked with "call", with the + * error message at the return address. + */ +error: + popw %si +2: + lodsb + movb $0x0e, %ah + movb (BIOS_page), %bh + movb $0x07, %bl + int $0x10 /* May destroy %bp */ + cmpb $10, %al /* Newline? */ + jne 2b + + int $0x18 /* Boot failure */ +die: + hlt + jmp die + +/* Location of the partition configuration byte */ +partition = _start + 439 diff --git a/contrib/syslinux-4.02/mbr/checksize.pl b/contrib/syslinux-4.02/mbr/checksize.pl new file mode 100755 index 0000000..4b42327 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/checksize.pl @@ -0,0 +1,54 @@ +## ----------------------------------------------------------------------- +## +## Copyright 2007-2009 H. Peter Anvin - All Rights Reserved +## Copyright 2009 Intel Corporation; author: H. Peter Anvin +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, Inc., 53 Temple Place Ste 330, +## Boston MA 02111-1307, USA; either version 2 of the License, or +## (at your option) any later version; incorporated herein by reference. +## +## ----------------------------------------------------------------------- + +## +## checksize.pl +## +## Check the size of a binary file and pad it with zeroes to that size +## + +use bytes; + +($file, $maxsize, $padsize) = @ARGV; + +if (!defined($maxsize)) { + # Defaults based on the filename + if ($file =~ /^mbr[^0-9a-z]/) { + $maxsize = $padsize = 440; + } elsif ($file =~ /^gptmbr[^0-9a-z]/) { + $maxsize = $padsize = 440; + } elsif ($file =~ /^isohdp[fp]x[^0-9a-z]/) { + $maxsize = $padsize = 432; + } elsif ($file =~ /^altmbr[^0-9a-z]/) { + $maxsize = $padsize = 439; + } else { + die "$0: no default size for filename: $file\n"; + } +} + +$padsize = $maxsize unless(defined($padsize)); + +open(FILE, '+<', $file) or die; +@st = stat(FILE); +if (!defined($size = $st[7])) { + die "$0: $file: $!\n"; +} +if ($size > $maxsize) { + print STDERR "$file: too big ($size > $maxsize)\n"; + exit 1; +} elsif ($size < $padsize) { + seek(FILE, $size, 0); + print FILE "\0" x ($padsize-$size); +} + +exit 0; diff --git a/contrib/syslinux-4.02/mbr/gptmbr.S b/contrib/syslinux-4.02/mbr/gptmbr.S new file mode 100644 index 0000000..8ed4cf4 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/gptmbr.S @@ -0,0 +1,309 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include "adjust.h" + + .code16 + .text + + .globl bootsec +stack = 0x7c00 + +/* Partition table header here */ +phdr = stack /* Above the stack, overwritten by bootsect */ +/* Partition table sector here */ +/* To handle > 32K we need to play segment tricks... */ +psec = _phdr + 512 + +/* Where we put DS:SI */ +dssi_out = _start + 0x1be + +BIOS_kbdflags = 0x417 +BIOS_page = 0x462 + + /* gas/ld has issues with doing this as absolute addresses... */ + .section ".bootsec", "a", @nobits + .globl bootsec +bootsec: + .space 512 + + .text + .globl _start +_start: + cli + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw $stack, %sp + movw %sp, %si + pushw %es /* 4(%bp) es:di -> $PnP header */ + pushw %di /* 2(%bp) */ + movw %ax, %es + sti + cld + + /* Copy down to 0:0x600 */ + movw $_start, %di + movw $(512/2), %cx + rep; movsw + + ljmpw $0, $next +next: + + ADJUST_DRIVE + pushw %dx /* 0(%bp) = %dl -> drive number */ + + /* Check to see if we have EBIOS */ + pushw %dx /* drive number */ + movb $0x41, %ah /* %al == 0 already */ + movw $0x55aa, %bx + xorw %cx, %cx + xorb %dh, %dh + stc + int $0x13 + jc 1f + cmpw $0xaa55, %bx + jne 1f + shrw %cx /* Bit 0 = fixed disk subset */ + jnc 1f + + /* We have EBIOS; patch in the following code at + read_sector_cbios: movb $0x42, %ah ; jmp read_common */ + movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ + (read_sector_cbios) + +1: + popw %dx + + /* Get (C)HS geometry */ + movb $0x08, %ah + int $0x13 + andw $0x3f, %cx /* Sector count */ + movw %sp, %bp /* %bp -> frame pointer: LEAVE UNCHANGED */ + pushw %cx /* -2(%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 */ + + /* Load partition table header */ + xorl %eax,%eax + cltd + incw %ax /* %edx:%eax = 1 */ + movw $phdr, %bx + pushw %bx /* -8(%bp) phdr == bootsect */ + call read_sector + + /* Number of partition sectors */ + /* We assume the partition table is 32K or less, and that + the sector size is 512. */ + /* Note: phdr == 6(%bp) */ + movw (80+6)(%bp),%cx /* NumberOfPartitionEntries */ + movw (84+6)(%bp),%ax /* SizeOfPartitionEntry */ + pushw %ax + pushw %cx + mulw %cx + shrw $9,%ax + xchgw %ax,%cx + incw %cx + + /* Starting LBA of partition array */ + movl (72+6)(%bp),%eax + movl (76+6)(%bp),%edx + + pushw %bx +get_ptab: + call read_sector + call inc64 + loopw get_ptab + + /* Find the boot partition */ + xorw %si,%si /* Nothing found yet */ + popw %di /* Partition table in memory */ + popw %cx /* NumberOfPartitionEntries */ + popw %ax /* SizeOfPartitionEntry */ + +find_part: + /* If the PartitionTypeGUID is all zero, it's an empty slot */ + movl (%di),%edx + orl 4(%di),%edx + orl 8(%di),%edx + orl 12(%di),%edx + jz not_this + testb $0x04,48(%di) + jz not_this + andw %si,%si + jnz found_multiple + movw %di,%si +not_this: + addw %ax,%di + loopw find_part + + andw %si,%si + jnz found_part + +missing_os: + call error + .ascii "Missing OS\r\n" + +found_multiple: + call error + .ascii "Multiple active partitions\r\n" + +found_part: + xchgw %ax,%cx /* Set up %cx for rep movsb further down */ + + movw $dssi_out,%di + pushw %di + + /* 80 00 00 00 ee 00 00 00 + - bootable partition, type EFI (EE), no CHS information */ + xorl %eax,%eax + movb $0x80,%al + stosl + movb $0xed,%al + stosl + movl 32(%si),%eax + movl 36(%si),%edx + call saturate_stosl /* Partition start */ + + movl 40(%si),%eax + movl 44(%si),%edx + subl 32(%si),%eax + sbbl 36(%si),%edx + call inc64 + call saturate_stosl /* Partition length */ + + movzwl %cx,%eax /* Length of GPT entry */ + stosl + + rep; movsb /* GPT entry follows MBR entry */ + popw %si + +/* + * boot: invoke the actual bootstrap. %ds:%si points to the + * partition information in memory. The top word on the stack + * is phdr == 0x7c00 == the address of the boot sector. + */ +boot: + movl (32+20)(%si),%eax + movl (36+20)(%si),%edx + popw %bx + call read_sector + cmpw $0xaa55, -2(%bx) + jne missing_os /* Not a valid boot sector */ + movw %bp, %sp /* driveno == bootsec-6 */ + popw %dx /* dl -> drive number */ + popw %di /* es:di -> $PnP vector */ + popw %es + movl $0x54504721,%eax /* !GPT magic number */ + cli + jmpw *%sp /* %sp == bootsec */ + +/* + * Store the value in %eax to %di iff %edx == 0, otherwise store -1. + * Returns the value that was actually written in %eax. + */ +saturate_stosl: + andl %edx,%edx + jz 1f + orl $-1,%eax +1: stosl + ret + +/* + * Increment %edx:%eax + */ +inc64: + addl $1,%eax + adcl $0,%edx + ret + +/* + * read_sector: read a single sector pointed to by %edx:%eax to + * %es:%bx. CF is set on error. All registers saved. + */ +read_sector: + pushal + pushl %edx /* MSW of LBA */ + pushl %eax /* LSW of LBA */ + pushw %es /* Buffer segment */ + pushw %bx /* Buffer offset */ + pushw $1 /* Sector count */ + pushw $16 /* Size of packet */ + movw %sp, %si + + /* 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 */ + shlb $6, %ah + movb %ah, %cl + movb %al, %ch + xchgw %dx, %ax + divb -2(%bp) /* sectors */ + movb %al, %dh + orb %ah, %cl + incw %cx /* Sectors are 1-based */ + movw $0x0201, %ax + +read_common: + movb (%bp), %dl /* driveno */ + int $0x13 + leaw 16(%si), %sp /* Drop DAPA */ + popal + jc disk_error + addb $2, %bh /* bx += 512: point to the next buffer */ + ret + +disk_error: + call error + .ascii "Disk error on boot\r\n" + +/* + * Print error messages. This is invoked with "call", with the + * error message at the return address. + */ +error: + popw %si +2: + lodsb + movb $0x0e, %ah + movb (BIOS_page), %bh + movb $0x07, %bl + int $0x10 /* May destroy %bp */ + cmpb $10, %al /* Newline? */ + jne 2b + + int $0x18 /* Boot failure */ +die: + hlt + jmp die diff --git a/contrib/syslinux-4.02/mbr/isohdpfx.S b/contrib/syslinux-4.02/mbr/isohdpfx.S new file mode 100644 index 0000000..0bf807e --- /dev/null +++ b/contrib/syslinux-4.02/mbr/isohdpfx.S @@ -0,0 +1,263 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * Modified MBR code used on an ISO image in hybrid mode. + * + * This doesn't follow the El Torito spec at all -- it is just a stub + * loader of a hard-coded offset, but that's good enough to load + * ISOLINUX. + */ + +#include "adjust.h" + + .code16 + .text + +HYBRID_MAGIC = 0x7078c0fb +isolinux_hybrid_signature = 0x7c00+64 +isolinux_start_hybrid = 0x7c00+64+4 + + .globl bootsec +/* Important: the top 6 words on the stack are passed to isolinux.bin */ +stack = 0x7c00 +partoffset = (stack-8) +driveno = (stack-14) +heads = (stack-16) +sectors = (stack-18) +ebios_flag = (stack-20) +secpercyl = (stack-24) + +BIOS_kbdflags = 0x417 +BIOS_page = 0x462 + + /* gas/ld has issues with doing this as absolute addresses... */ + .section ".bootsec", "a", @nobits + .globl bootsec +bootsec: + .space 512 + + .text + .globl _start +_start: + + cli + xorw %bp, %bp + movw %bp, %ss + movw $stack, %sp + sti + cld + + /* Check to see if we have a partition table entry */ + xorl %ebx, %ebx + xorl %ecx, %ecx +#ifdef PARTITION_SUPPORT + andw %si, %si /* %si == 0 -> no partition data */ + jz 1f + testb $0x7f, (%si) /* Invalid active flag field? */ + jnz 1f + cmpb %cl, 4(%si) /* Partition type zero == invalid? */ + je 1f + cmpl $0x58504721, %eax /* !GPT signature in EAX? */ + jne 2f + cmpb $0xed, 4(%si) /* EFI partition type? */ + jne 2f + + /* We have GPT partition information */ + movl (32+20)(%si), %ecx + movl (36+20)(%si), %ebx + jmp 1f + + /* We have non-GPT partition information */ +2: + movl 8(%si), %ecx +#endif +1: + /* We have no partition information */ + pushl %ebx /* -4: partoffset_hi */ + pushl %ecx /* -8: partoffset_lo */ + pushw %es /* -10: es:di -> $PnP header */ + pushw %di /* -12: es:di -> $PnP header */ + + movw %bp, %ds + movw %bp, %es + + ADJUST_DRIVE + pushw %dx /* -14: dl -> drive number */ + + /* Copy down to 0:0x600 */ + movw $0x7c00, %si + movw $_start, %di + movw $(512/2), %cx + rep; movsw + + ljmpw $0, $next +next: + + /* Check to see if we have EBIOS */ + pushw %dx /* drive number */ + movb $0x41, %ah /* %al == 0 already */ + movw $0x55aa, %bx + xorw %cx, %cx + xorb %dh, %dh + stc + int $0x13 + jc 1f + cmpw $0xaa55, %bx + jne 1f + andw $1,%cx /* Bit 0 = fixed disk subset */ + jz 1f + + /* We have EBIOS; patch in the following code at + 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 /* EBIOS flag */ + + /* Get (C)HS geometry */ + movb $0x08, %ah + int $0x13 + andw $0x3f, %cx /* Sector count */ + popw %bx /* EBIOS flag */ + pushw %cx /* -16: Save sectors on the stack */ + movzbw %dh, %ax /* dh = max head */ + incw %ax /* From 0-based max to count */ + pushw %ax /* -18: Save heads on the stack */ + mulw %cx /* Heads*sectors -> sectors per cylinder */ + + pushw %bx /* -20: EBIOS flag */ + + /* Save sectors/cylinder on the stack */ + pushw %dx /* -22: High word */ + pushw %ax /* -24: Low word */ + + /* + * Load sectors. We do this one at a time mostly to avoid + * pitfalls and to share code with the stock MBR code. + */ + movw $0x7c00, %bx + movw $4, %cx /* Sector count */ + movl (lba_offset), %eax + +2: + call read_sector + jc disk_error + incl %eax + addb $(512 >> 8), %bh + loopw 2b + + /* + * Okay, that actually worked... update the stack pointer + * and jump into isolinux.bin... + */ + cmpl $HYBRID_MAGIC,(isolinux_hybrid_signature) + jne bad_signature + + cli + movw $ebios_flag, %sp + + /* + * Use a ljmpw here to work around a bug in some unknown version + * of gas or ld when it comes to jumping to an absolute symbol... + * + * Look more closely into it if we ever are short on space. + */ + ljmpw $0, $isolinux_start_hybrid + +bad_signature: + call error + .ascii "isolinux.bin missing or corrupt.\r\n" + +/* + * read_sector: read a single sector pointed to by %eax to %es:%bx. + * CF is set on error. All registers saved. + */ +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 */ + pushw %bx /* Buffer offset */ + pushw $1 /* Sector count */ + pushw $16 /* Size of packet */ + movw %sp, %si + + /* This chunk is skipped if we have ebios */ + /* Do not clobber %eax before this chunk! */ + /* This also relies on %bx and %edx as set up above. */ +read_sector_cbios: + divl (secpercyl) + shlb $6, %ah + movb %ah, %cl + movb %al, %ch + xchgw %dx, %ax + divb (sectors) + movb %al, %dh + orb %ah, %cl + incw %cx /* Sectors are 1-based */ + movw $0x0201, %ax + +read_common: + movb (driveno), %dl + int $0x13 + leaw 16(%si), %sp /* Drop DAPA */ + popal + ret + +disk_error: + call error + .ascii "Operating system load error.\r\n" + +/* + * Print error messages. This is invoked with "call", with the + * error message at the return address. + */ +error: + popw %si +2: + lodsb + movb $0x0e, %ah + movb (BIOS_page), %bh + movb $0x07, %bl + int $0x10 /* May destroy %bp */ + cmpb $10, %al /* Newline? */ + jne 2b + + int $0x18 /* Boot failure */ +die: + hlt + jmp die + + /* Address of pointer to isolinux.bin */ +lba_offset = _start+432 diff --git a/contrib/syslinux-4.02/mbr/isohdppx.S b/contrib/syslinux-4.02/mbr/isohdppx.S new file mode 100644 index 0000000..d5625d7 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/isohdppx.S @@ -0,0 +1,2 @@ +#define PARTITION_SUPPORT 1 +#include "isohdpfx.S" diff --git a/contrib/syslinux-4.02/mbr/mbr.S b/contrib/syslinux-4.02/mbr/mbr.S new file mode 100644 index 0000000..7caf4fc --- /dev/null +++ b/contrib/syslinux-4.02/mbr/mbr.S @@ -0,0 +1,299 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include "adjust.h" + + .code16 + .text + + .globl bootsec +stack = 0x7c00 +driveno = (stack-6) +sectors = (stack-8) +secpercyl = (stack-12) + +BIOS_kbdflags = 0x417 +BIOS_page = 0x462 + + /* gas/ld has issues with doing this as absolute addresses... */ + .section ".bootsec", "a", @nobits + .globl bootsec +bootsec: + .space 512 + + .text + .globl _start +_start: + cli + xorw %ax, %ax + movw %ax, %ds + movw %ax, %ss + movw $stack, %sp + movw %sp, %si + pushw %es /* es:di -> $PnP header */ + pushw %di + movw %ax, %es + sti + cld + + /* Copy down to 0:0x600 */ + movw $_start, %di + movw $(512/2), %cx + rep; movsw + + 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 */ + movw $0x55aa, %bx + xorw %cx, %cx + xorb %dh, %dh + stc + int $0x13 + jc 1f + cmpw $0xaa55, %bx + jne 1f + shrw %cx /* Bit 0 = fixed disk subset */ + jnc 1f + + /* We have EBIOS; patch in the following code at + read_sector_cbios: movb $0x42, %ah ; jmp read_common */ + movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \ + (read_sector_cbios) + +1: + popw %dx + + /* Get (C)HS geometry */ + movb $0x08, %ah + int $0x13 + andw $0x3f, %cx /* Sector count */ + pushw %cx /* 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 /* High word */ + pushw %ax /* Low word */ + + xorl %eax, %eax /* Base */ + cdq /* Root (%edx <- 0) */ + call scan_partition_table + + /* If we get here, we have no OS */ +missing_os: + call error + .ascii "Missing operating system.\r\n" + +/* + * read_sector: read a single sector pointed to by %eax to 0x7c00. + * CF is set on error. All registers saved. + */ +read_sector: + pushal + xorl %edx, %edx + movw $bootsec, %bx + pushl %edx /* MSW of LBA */ + pushl %eax /* LSW of LBA */ + pushw %es /* Buffer segment */ + pushw %bx /* Buffer offset */ + pushw $1 /* Sector count */ + pushw $16 /* Size of packet */ + movw %sp, %si + + /* This chunk is skipped if we have ebios */ + /* Do not clobber %eax before this chunk! */ + /* This also relies on %bx and %edx as set up above. */ +read_sector_cbios: + divl (secpercyl) + shlb $6, %ah + movb %ah, %cl + movb %al, %ch + xchgw %dx, %ax + divb (sectors) + movb %al, %dh + orb %ah, %cl + incw %cx /* Sectors are 1-based */ + movw $0x0201, %ax + +read_common: + movb (driveno), %dl + int $0x13 + leaw 16(%si), %sp /* Drop DAPA */ + popal + ret + +/* + * read_partition_table: + * Read a partition table (pointed to by %eax), and copy + * the partition table into the ptab buffer. + * + * Clobbers %si, %di, and %cx, other registers preserved. + * %cx = 0 on exit. + * + * On error, CF is set and ptab is overwritten with junk. + */ +ptab = _start+446 + +read_partition_table: + call read_sector + movw $bootsec+446, %si + movw $ptab, %di + movw $(16*4/2), %cx + rep ; movsw + ret + +/* + * scan_partition_table: + * Scan a partition table currently loaded in the partition table + * area. Preserve all registers. + * + * On entry: + * %eax - base (location of this partition table) + * %edx - root (offset from MBR, or 0 for MBR) + * + * These get pushed into stack slots: + * 28(%bp) - %eax - base + * 20(%bp) - %edx - root + */ + +scan_partition_table: + pushal + movw %sp, %bp + + /* Search for active partitions */ + movw $ptab, %bx + movw $4, %cx + xorw %ax, %ax + push %bx + push %cx +5: + testb $0x80, (%bx) + jz 6f + incw %ax + movw %bx, %si +6: + addw $16, %bx + loopw 5b + + decw %ax /* Number of active partitions found */ + jz boot + jns too_many_active + + /* No active partitions found, look for extended partitions */ + popw %cx /* %cx <- 4 */ + popw %bx /* %bx <- ptab */ +7: + movb 4(%bx), %al + cmpb $0x0f, %al /* 0x0f = Win9x extended */ + je 8f + andb $~0x80, %al /* 0x85 = Linux extended */ + cmpb $0x05, %al /* 0x05 = MS-DOS extended */ + jne 9f + + /* It is an extended partition. Read the extended partition and + try to scan it. If the scan returns, re-load the current + partition table and resume scan. */ +8: + movl 8(%bx), %eax /* Partition table offset */ + movl 20(%bp), %edx /* "Root" */ + addl %edx, %eax /* Compute location of new ptab */ + andl %edx, %edx /* Is this the MBR? */ + jnz 10f + movl %eax, %edx /* Offset -> root if this was MBR */ +10: + call read_partition_table + jc 11f + call scan_partition_table +11: + /* This returned, so we need to reload the current partition table */ + movl 28(%bp), %eax /* "Base" */ + call read_partition_table + + /* fall through */ +9: + /* Not an extended partition */ + addw $16, %bx + loopw 7b + + /* Nothing found, return */ + popal + ret + +too_many_active: + call error + .ascii "Multiple active partitions.\r\n" + +/* + * boot: invoke the actual bootstrap. (%si) points to the partition + * table entry, and 28(%bp) has the partition table base. + */ +boot: + movl 8(%si), %eax + addl 28(%bp), %eax + movl %eax, 8(%si) /* Adjust in-memory partition table entry */ + call read_sector + jc disk_error + cmpw $0xaa55, (bootsec+510) + jne missing_os /* Not a valid boot sector */ + movw $driveno, %sp /* driveno == bootsec-6 */ + popw %dx /* dl -> drive number */ + popw %di /* es:di -> $PnP vector */ + popw %es + cli + jmpw *%sp /* %sp == bootsec */ + +disk_error: + call error + .ascii "Operating system load error.\r\n" + +/* + * Print error messages. This is invoked with "call", with the + * error message at the return address. + */ +error: + popw %si +2: + lodsb + movb $0x0e, %ah + movb (BIOS_page), %bh + movb $0x07, %bl + int $0x10 /* May destroy %bp */ + cmpb $10, %al /* Newline? */ + jne 2b + + int $0x18 /* Boot failure */ +die: + hlt + jmp die diff --git a/contrib/syslinux-4.02/mbr/mbr.ld b/contrib/syslinux-4.02/mbr/mbr.ld new file mode 100644 index 0000000..d14ba80 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/mbr.ld @@ -0,0 +1,73 @@ +/* + * Linker script for MBR + */ + +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", + "elf32-i386") +OUTPUT_ARCH(i386) +EXTERN(_start) +ENTRY(_start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x600; + .text : + { + *(.text*) + *(.rodata*) + } =0x90909090 + + . = ALIGN(4); + .data : + { + *(.data*) + } + + . = ALIGN(128); + .bss : + { + *(.bss*) + } + + . = 0x7c00; + .bootsec : + { + *(.bootsec) + } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/contrib/syslinux-4.02/mbr/oldmbr.asm b/contrib/syslinux-4.02/mbr/oldmbr.asm new file mode 100644 index 0000000..26fb022 --- /dev/null +++ b/contrib/syslinux-4.02/mbr/oldmbr.asm @@ -0,0 +1,230 @@ +; ----------------------------------------------------------------------- +; +; Copyright 2003-2008 H. Peter Anvin - All Rights Reserved +; +; Permission is hereby granted, free of charge, to any person +; obtaining a copy of this software and associated documentation +; files (the "Software"), to deal in the Software without +; restriction, including without limitation the rights to use, +; copy, modify, merge, publish, distribute, sublicense, and/or +; sell copies of the Software, and to permit persons to whom +; the Software is furnished to do so, subject to the following +; conditions: +; +; The above copyright notice and this permission notice shall +; be included in all copies or substantial portions of the Software. +; +; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +; OTHER DEALINGS IN THE SOFTWARE. +; +; ----------------------------------------------------------------------- + +; +; mbr.asm +; +; Simple Master Boot Record, including support for EBIOS extensions. +; +; The MBR lives in front of the boot sector, and is responsible for +; loading the boot sector of the active partition. The EBIOS support +; is needed if the active partition starts beyond cylinder 1024. +; +; This MBR determines all geometry info at runtime. It uses only the +; linear block field in the partition table. It does, however, pass +; the partition table information unchanged to the target OS. +; +; This MBR should be "8086-clean", i.e. not require a 386. +; + +%include "bios.inc" + +; +; Note: The MBR is actually loaded at 0:7C00h, but we quickly move it down to +; 0600h. +; + section .text + cpu 8086 + org 0600h + +_start: cli + xor ax,ax + mov ds,ax + mov es,ax + mov ss,ax + mov sp,7C00h + sti + cld + mov si,sp ; Start address + mov di,0600h ; Destination address + mov cx,512/2 + rep movsw + +; +; Now, jump to the copy at 0600h so we can load the boot sector at 7C00h. +; Since some BIOSes seem to think 0000:7C00h and 07C0:0000h are the same +; thing, use a far jump to canonicalize the address. This also makes +; sure that it is a code speculation barrier. +; + + jmp 0:next ; Jump to copy at 0600h + +next: + mov [DriveNo], dl ; Drive number stored in DL +; +; Check for CHS parameters. This doesn't work on floppy disks, +; but for an MBR we don't care. +; + mov ah,08h ; Get drive parameters + int 13h + and cx,3Fh ; Max sector number + mov [Sectors],cx + xor ax,ax + mov al,dh + inc ax ; From 0-based to count + mul cx ; Heads*Sectors + mov [SecPerCyl],ax + ; Note: we actually don't care about the number of + ; cylinders, since that's the highest-order division + +; +; Now look for one (and only one) active partition. +; + mov si,PartitionTable + xor ax,ax + mov cx,4 +checkpartloop: + test byte [si],80h + jz .notactive + inc ax + mov di,si +.notactive: add si,byte 16 + loop checkpartloop + + cmp ax,byte 1 ; Better be only one + jnz not_one_partition + +; +; Now we have the active partition partition information in DS:DI. +; Check to see if we support EBIOS. +; + mov dl,[DriveNo] + mov ax,4100h + mov bx,055AAh + xor cx,cx + xor dh,dh + stc + int 13h + jc no_ebios + cmp bx,0AA55h + jne no_ebios + test cl,1 ; LBA device access + jz no_ebios +; +; We have EBIOS. Load the boot sector using LBA. +; + push di + mov si,dapa + mov bx,[di+8] ; Copy the block address + mov [si+8],bx + mov bx,[di+10] + mov [si+10],bx + mov dl,[DriveNo] + mov ah,42h ; Extended Read + jmp short common_tail +; +; No EBIOS. Load the boot sector using CHS. +; +no_ebios: + push di + mov ax,[di+8] + mov dx,[di+10] + div word [SecPerCyl] ; AX = cylinder DX = sec in cyl + ror ah,1 + ror ah,1 + mov cl,ah + mov ch,al ; CL = cyl[9:8], CH = cyl[7:0] + + mov ax,dx + div byte [Sectors] ; AL = head AH = sector + mov dh,al + inc ah + or cl,ah ; CX = cylinder and sector + + mov dl,[DriveNo] + mov bx,7C00h + mov ax,0201h ; Read one sector +common_tail: + int 13h + jc disk_error + pop si ; DS:SI -> partition table entry +; +; Verify that we have a boot sector, jump +; + cmp word [7C00h+510],0AA55h + jne missing_os + cli + jmp 0:7C00h ; Jump to boot sector; far + ; jump is speculation barrier + ; (Probably not neecessary, but + ; there is plenty of space.) + +not_one_partition: + ja too_many_os +missing_os: + mov si,missing_os_msg + jmp short die +too_many_os: +disk_error: + mov si,bad_disk_msg +die: +.msgloop: + lodsb + and al,al + jz .now + mov ah,0Eh ; TTY output + mov bh,[BIOS_page] ; Current page + mov bl,07h + int 10h + jmp short .msgloop +.now: + jmp short .now + + align 4, db 0 ; Begin data area + +; +; EBIOS disk address packet +; +dapa: + dw 16 ; Packet size +.count: dw 1 ; Block count +.off: dw 7C00h ; Offset of buffer +.seg: dw 0 ; Segment of buffer +.lba: dd 0 ; LBA (LSW) + dd 0 ; LBA (MSW) + +; CHS information +SecPerCyl: dw 0 ; Heads*Sectors +Sectors: dw 0 + +; Error messages +missing_os_msg db 'Missing operating system', 13, 10, 0 +bad_disk_msg db 'Operating system loading error', 13, 10, 0 + +; +; Maximum MBR size: 446 bytes; end-of-boot-sector signature also needed. +; Note that some operating systems (NT, DR-DOS) put additional stuff at +; the end of the MBR, so shorter is better. Location 440 is known to +; have a 4-byte attempt-at-unique-ID for some OSes. +; + +PartitionTable equ $$+446 ; Start of partition table + +; +; BSS data; put at 800h +; +DriveNo equ 0800h |