Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/stand/mbr Master Boot Record (mbr) code:



details:   https://anonhg.NetBSD.org/src/rev/87ba7e8c2705
branches:  trunk
changeset: 546413:87ba7e8c2705
user:      dsl <dsl%NetBSD.org@localhost>
date:      Mon Apr 28 12:19:05 2003 +0000

description:
Master Boot Record (mbr) code:
mbr:            boots active partition
mbr_bootsel:    menu selection for partitions 1 to 4
mbr_ext:        menu selection for partitions 1 to 4 and extended partitions
Based on code from sbin/fdisk/mbr_bootsel.
Needs a new fdisk to configure mbr_ext and correctly set default menu selection.(Not yet built by defaulat)

diffstat:

 sys/arch/i386/stand/mbr/Makefile             |    5 +
 sys/arch/i386/stand/mbr/Makefile.mbr         |   34 +
 sys/arch/i386/stand/mbr/mbr.S                |  557 +++++++++++++++++++++++++++
 sys/arch/i386/stand/mbr/mbr/Makefile         |    5 +
 sys/arch/i386/stand/mbr/mbr_bootsel/Makefile |    8 +
 sys/arch/i386/stand/mbr/mbr_ext/Makefile     |    8 +
 6 files changed, 617 insertions(+), 0 deletions(-)

diffs (truncated from 641 to 300 lines):

diff -r f8a5ebf39e0d -r 87ba7e8c2705 sys/arch/i386/stand/mbr/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/mbr/Makefile  Mon Apr 28 12:19:05 2003 +0000
@@ -0,0 +1,5 @@
+#      $NetBSD: Makefile,v 1.1 2003/04/28 12:19:05 dsl Exp $
+
+SUBDIR=                mbr mbr_bootsel mbr_ext
+
+.include <bsd.subdir.mk>
diff -r f8a5ebf39e0d -r 87ba7e8c2705 sys/arch/i386/stand/mbr/Makefile.mbr
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/mbr/Makefile.mbr      Mon Apr 28 12:19:05 2003 +0000
@@ -0,0 +1,34 @@
+#      $NetBSD: Makefile.mbr,v 1.1 2003/04/28 12:19:05 dsl Exp $
+
+S=     ${.CURDIR}/../../../../../
+
+NOMAN= # defined
+STRIPFLAG=
+
+.include <bsd.own.mk>
+
+SRCS?= mbr.S
+
+BINDIR=        /usr/mdec
+BINMODE=444
+
+.PATH: ${.CURDIR}/..
+
+LDFLAGS+= -e start
+CPPFLAGS+= -I ${.CURDIR}/../../lib
+
+.if ${MACHINE} == "amd64"
+LDFLAGS+=  -m elf_i386
+AFLAGS+=   -m32
+.endif
+
+CLEANFILES+= ${PROG}.tmp
+
+${PROG}: ${OBJS}
+       ${LD} -o ${PROG}.tmp ${LDFLAGS} -Ttext 0x600 ${OBJS}
+       @ set -- $$( ${NM} -t d ${PROG}.tmp | grep '\<mbr_space\>' ); \
+               echo "#### There are $$(($$1)) free bytes in ${PROG}"
+       ${OBJCOPY} -O binary ${PROG}.tmp ${PROG}
+       rm -f ${PROG}.tmp
+
+.include <bsd.prog.mk>
diff -r f8a5ebf39e0d -r 87ba7e8c2705 sys/arch/i386/stand/mbr/mbr.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/mbr/mbr.S     Mon Apr 28 12:19:05 2003 +0000
@@ -0,0 +1,557 @@
+/*     $NetBSD: mbr.S,v 1.1 2003/04/28 12:19:05 dsl Exp $      */
+
+/*
+ * Copyright (c) 1999-2003 The NetBSD Foundation, Inc. 
+ * All rights reserved.
+ *     
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank van der Linden.
+ * Major surgery performed by David Laight.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * i386 master boot code
+ */
+
+/* Compile options:
+ * BOOTSEL     - bootselector code
+ * BOOT_EXTENDED - scan extended partition list (LBA reads)
+ * TERSE_ERROR - terse error messages
+ * NO_CHS      - all reads are LBA
+ * NO_LBA_CHECK        - no check if bios supports LBA reads
+ */
+
+#include <machine/asm.h>
+#include <sys/disklabel_mbr.h>
+
+#define BOOTADDR       0x7c00
+#define LOADADDR       0x0600          /* address were are linked to */
+
+#define TABENTRYSIZE   (PARTNAMESIZE + 1)
+#define NAMETABSIZE    (NMBRPART * TABENTRYSIZE)
+
+/*
+ * Minimum and maximum drive number that is considered to be valid.
+ */
+#define MINDRV         0x80
+#define MAXDRV         0x87
+
+#ifdef TERSE_ERROR
+/*
+ * Error codes. Done this way to save space.
+ */
+#define ERR_INVPART    '1'             /* Invalid partition table */
+#define ERR_READ       '2'             /* Read error */
+#define ERR_NOOS       '3'             /* Magic no. check failed for part. */
+#define        ERR_KEY         '?'             /* unknown key press */
+#define        ERR_NO_LBA      'L'             /* sector above chs limit */
+
+#define        set_err(err)    movb    $err, %al
+
+#else
+#define        set_err(err)    mov     $err, %ax
+#endif
+
+       .text
+       .code16
+/*
+ * Move ourselves out of the way first.
+ * (to the address we are linked at - 0x600)
+ * and zero our bss
+ */
+ENTRY(start)
+       xor     %ax, %ax
+       mov     %ax, %ss
+       movw    $BOOTADDR, %sp
+       mov     %ax, %es
+       mov     %ax, %ds
+       mov     %sp, %si
+       movw    $start, %di
+       movw    $(bss_start - start)/2, %cx
+       rep
+       movsw
+       mov     $(bss_end - bss_start + 1)/2, %cx
+       rep
+       stosw
+       ljmp    $0, $mbr                /* leap into copy of code */
+
+/*
+ * Sanity check the drive number passed by the BIOS. Some BIOSs may not
+ * do this and pass garbage.
+ */
+mbr:
+       cmpb    $MAXDRV, %dl            /* relies on MINDRV being 0x80 */
+       jle     1f
+       movb    $MINDRV, %dl            /* garbage in, boot disk 0 */
+1:
+       push    %dx                     /* save drive number */
+       push    %dx                     /* twice - for err_msg loop */
+
+#ifdef BOOTSEL
+/*
+ * Walk through the selector (name) table printing used entries.
+ */
+bootsel_menu:
+       movw    $nametab, %bx
+#ifdef BOOT_EXTENDED
+       xorl    %ecx, %ecx              /* base of extended partition */
+next_extended:
+       xorl    %edx, %edx              /* for next extended partition */
+#endif
+       lea     parttab - nametab(%bx), %bp
+next_ptn:
+       movb    4(%bp), %al             /* partition type */
+#ifdef BOOT_EXTENDED
+       movl    8(%bp), %edi            /* partition sector number */
+       cmpb    $MBR_PTYPE_EXT, %al     /* Extended partition */
+       je      1f
+       cmpb    $MBR_PTYPE_EXT_LBA, %al /* Extended LBA partition */
+       je      1f
+       cmpb    $MBR_PTYPE_EXT_LNX, %al /* Linux extended partition */
+       jne     2f
+1:     movl    %edi, %edx              /* save next extended ptn */
+       jmp     3f
+2:
+#endif
+       test    %al, %al                /* undefined partition */
+       je      3f
+       cmpb    $0, (%bx)               /* check for prompt */
+       jz      3f
+
+       /* output menu item */
+       movw    $prefix, %si
+       incb    (%si)
+       call    message                 /* menu number */
+       mov     (%si), %si              /* ':' << 8 | '1' + count */
+       shl     $2, %si                 /* const + count * 4 */
+#define        CONST   (4 * ((':' << 8) + '1' - ((SCAN_1 - SCAN_F1) & 0xff)))
+#ifdef NO_CHS
+       addl    lba_sector, %edi
+       movl    %edi, ptn_list - CONST(%si)     /* sector to read */
+#else
+       mov     %bp, ptn_list - CONST(%si)      /* partition info */
+#endif
+#undef CONST
+       mov     %bx, %si
+       call    message                 /* prompt */
+       movw    $crlf, %si
+       call    message
+3:
+       add     $0x10, %bp
+       add     $TABENTRYSIZE, %bx
+       cmpb    $(nametab - start - 0x100) + 4 * TABENTRYSIZE, %bl
+       jne     next_ptn
+
+#ifdef BOOT_EXTENDED
+/*
+ * Now check extended partition chain
+ */
+       testl   %edx, %edx
+       je      wait_key
+       testl   %ecx, %ecx
+       jne     1f
+       xchg    %ecx, %edx              /* save base of ext ptn chain */
+1:     addl    %ecx, %edx              /* sector to read */
+       movl    %edx, lba_sector
+       movw    $lba_info, %si
+       movb    $0x42, %ah
+       pop     %dx                     /* recover drive # */
+       push    %dx                     /* save drive */
+       int     $0x13
+       jc      wait_key                /* abort menu on read fail */
+       cmpw    $MBR_MAGIC, LOADADDR + MBR_MAGICOFF
+       movw    $nametab - LOADADDR + BOOTADDR, %bx
+       je      next_extended
+#endif
+
+/*
+ * Get the initial time value for the timeout comparison. It is returned
+ * by int 1a in cx:dx. We do sums modulo 2^16 so it doesn't matter if
+ * the counter wraps (which it does every hour) - so we can safely
+ * ignore 'cx'.
+ *
+ * Loop around checking for a keypress until we have one, or timeout is
+ * reached.
+ */
+wait_key:
+       xorb    %ah, %ah
+       int     $0x1a
+       mov     %dx, %di                /* start time to di */
+3:
+       movb    $1, %ah                 /* looks to see if a */
+       int     $0x16                   /* key has been pressed */
+       jnz     get_key
+       xorb    %ah, %ah
+       int     $0x1a                   /* current time to cx:dx */
+       sub     %di, %dx
+       movw    timeout, %ax
+       cmp     %ax, %dx                /* always wait for 1 tick... */
+       jbe     3b                      /* 0xffff means never timeout */
+def_key:
+       movb    defkey, %al             /* timedout - pick default key */
+       jmp     check_key
+get_key:
+       xorb    %ah, %ah
+       int     $0x16                   /* 'read key', code ah, ascii al */
+       shr     $8, %ax                 /* code in %al, %ah zero */
+
+/*
+ * We have a keycode, see what it means.
+ * If we don't know we generate error '?' and go ask again
+ */
+check_key:
+/*
+ * <enter> -> boot active partition.
+ */
+       cmpb    $SCAN_ENTER, %al
+       jne     boot_disk
+#endif /* BOOTSEL */
+
+/*
+ * Scan MBR for first active partition, and boot it.
+ */
+       mov     $NMBRPART, %cx
+       mov     $parttab, %si
+1:
+       cmpb    $0x80, (%si)
+#ifdef NO_CHS
+       jne     10f                     /* not active */
+       movl    8(%si), %ebp            /* sector number of ptn */
+       jmp     boot_lba
+10:
+#else
+       je      boot_si
+#endif



Home | Main Index | Thread Index | Old Index