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

Re: New MBR code, LBA capable



begin  electrogrammati illius Thorsten Glaser

>Me, earlier this day:

[blah]

>Results are attached:

Thanks to tedu@ who kindly reminded me to actually
attach those files...

Uhm, note that my previous mail contained a diff
to src/sbin/fdisk/Makefile which is not contained
in this diff any more.

//Thorsten
--
Willst Du wegen dummer User immer 'Ja, ich will' nach einem rm an /dev/tty
eingeben müssen?		-- Bodo Eggert in de.alt.sysadmin.recovery
Index: sys/arch/i386/stand/biosboot/biosboot.S
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/biosboot/biosboot.S,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- sys/arch/i386/stand/biosboot/biosboot.S	23 Mar 2003 21:51:55 -0000	1.2
+++ sys/arch/i386/stand/biosboot/biosboot.S	3 May 2003 17:11:50 -0000	1.4
@@ -1,7 +1,8 @@
-/*	$OpenBSD: biosboot.S,v 1.32 2002/08/28 20:15:34 mickey Exp $	*/
+/*	$MirBSD: biosboot.S,v 1.4 2003/05/03 17:12:12 tg Exp $	*/
+/*	$OpenBSD: biosboot.S,v 1.33 2003/04/17 03:43:18 drahn Exp $	*/
 
 /*
- * Copyright (c) 1997 Michael Shalayeff, Tobias Weingartner
+ * Copyright (c) 1997 Michael Shalayeff, Tobias Weingartner, Thorsten Glaser
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,7 +37,7 @@
 #include <machine/asm.h>
 #include <assym.h>
 
-#define	BLKCNT	52
+#define	BLKCNT	36
 
 #define BOOTSEG		0x07c0	/* boot loaded here */
 #define BOOTSTACK	0xfffc	/* stack starts here */
@@ -84,7 +85,11 @@
 	.byte	0x29		/* signature, needed by NT */
 	.space	4, 0		/* volume serial number */
 	.asciz	"UNIX LABEL"
-	.asciz	"UFS 4.4"
+	.ascii	"UFS 4.4"
+	.globl	lba_flag
+	.type lba_flag, @function
+lba_flag:
+	.ascii	"C"		/* L=LBA, everything else=CHS */
 
 	/* boot code */
 	. = _start + 0x3e
@@ -103,11 +108,11 @@
 	mov	%ax, %ss
 	movl	$BOOTSTACK, %esp
 	sti			/* we have stack, do ints */
+	cld
 
 	/* Set up other segment regs */
 	mov	$BOOTSEG, %ax
 	mov	%ax, %ds
-	mov	%ax, %es
 	mov	%ax, %fs
 	mov	%ax, %gs
 
@@ -139,17 +144,39 @@
 1:
 	push	%cx
 	putc('.')		/* show progress indicator */
-	cld
+
+	.intel_syntax noprefix
+	cmp	byte ptr [lba_flag],0x4C /* 'L' */
+	jne	Lloadchs
+	lodsd
+	mov	[Lblknm],eax
+	lodsb
+	mov	[Lblkct],al
+	push	ax		/* for incrementing bx */
+	mov	ax,es
+	shl	eax,16
+	mov	ax,bx
+	mov	[Lblkbf],eax
+	push	si
+	mov	si,offset Llbablk
+	mov	ah,0x42
+	int	0x13
+	pop	si
+	jc	Lrderr
+	jmp	3f
+
+	.att_syntax
+Lloadchs:
 	lodsw	/* word */	/* cylinder/sector */
 	mov	%ax, %cx
-	lodsb			/* head */
+	lodsw			/* head */
 	movb	%al, %dh
 	lodsb			/* # of sectors to load */
 	movb	$0x2, %ah
 	push	%ax
 	int	$0x13
 	jnc	3f
-
+Lrderr:
 	/* read error */
 	puts(2f)
 	jmp	halt
@@ -167,7 +194,6 @@
 	puts(2f)
 
 	xor	%si, %si
-	cld
 	/* check /boot magic */
 	es;lodsw;es;lodsw	/* no need for high word */
 	cmp	$LFMAGIC, %ax
@@ -175,10 +201,11 @@
 
 	puts(1f)
 halt:
-	cli
-99:
-	hlt
-	jmp 99b
+	.intel_syntax noprefix
+	xor	ah,ah
+	int	0x16
+	jmp	0xF000,0xFFF0
+	.att_syntax
 1:	.ascii	"Bad magic"
 2:	.asciz	"\r\n"
 
@@ -206,12 +233,18 @@
 	ljmp $(LINKADDR >> 4), $0
 	/* not reached */
 
+/* LBA parameter block */
+Llbablk:
+	.word	0x0010		/* length, reserved */
+Lblkct:	.word	0x0001		/* num. of sectors */
+Lblkbf:	.long	0x00007C00	/* transfer buffer */
+Lblknm:	.long	0,0		/* LBA block number */
+
 /*
  * Display string
  */
 Lmessage:
 	push	%ax
-	cld
 1:
 	lodsb			# load a byte into %al
 	testb	%al, %al
@@ -252,9 +285,9 @@
 	.byte	BLKCNT	/* entries in block_table */
 block_table:
 	.word	0	/* cylinder/sector */
-	.byte	0	/* head */
+	.word	0	/* head (high), drive (low) UNUSED! */
 	.byte	0	/* nsect */
-	. = block_table + BLKCNT*4
+	. = block_table + BLKCNT*5
 
 	. = 0x200 - 2
 	/* a little signature */
Index: sys/arch/i386/stand/installboot/installboot.8
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/installboot/installboot.8,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -r1.1 -r1.3
--- sys/arch/i386/stand/installboot/installboot.8	22 Mar 2003 17:49:15 -0000	1.1
+++ sys/arch/i386/stand/installboot/installboot.8	3 May 2003 17:12:11 -0000	1.3
@@ -1,3 +1,4 @@
+.\"	$MirBSD: installboot.8,v 1.3 2003/05/03 17:12:33 tg Exp $
 .\"	$OpenBSD: installboot.8,v 1.23 2003/02/07 07:45:12 jmc Exp $
 .\"
 .\" Copyright (c) 1997 Michael Shalayeff
@@ -38,6 +39,7 @@
 .Nd installs a bootstrap on an FFS disk or partition
 .Sh SYNOPSIS
 .Nm installboot
+.Op Fl l
 .Op Fl n
 .Op Fl v
 .Oo Fl s Ar sectors-per-track Oc
@@ -56,6 +58,9 @@
 .Pp
 The options are as follows:
 .Bl -tag -width flag_opt
+.It Fl l
+Use LBA mode instead of default CHS mode.
+Useful when the slice crosses the 1024 cylinder boundary.
 .It Fl n
 Do not actually write anything on the disk.
 .It Fl v
Index: sys/arch/i386/stand/installboot/installboot.c
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/installboot/installboot.c,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- sys/arch/i386/stand/installboot/installboot.c	23 Mar 2003 21:51:55 -0000	1.2
+++ sys/arch/i386/stand/installboot/installboot.c	3 May 2003 17:12:11 -0000	1.4
@@ -1,4 +1,5 @@
-/*	$OpenBSD: installboot.c,v 1.37 2002/05/03 13:59:08 espie Exp $	*/
+/*	$MirBSD: installboot.c,v 1.4 2003/05/03 17:12:33 tg Exp $	*/
+/*	$OpenBSD: installboot.c,v 1.38 2003/04/17 03:43:18 drahn Exp $	*/
 /*	$NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
 
 /*
@@ -43,6 +44,7 @@
 #include <ufs/ufs/dir.h>
 #include <ufs/ffs/fs.h>
 #include <sys/reboot.h>
+#include <sys/errno.h>
 
 #include <uvm/uvm_extern.h>
 #include <sys/sysctl.h>
@@ -69,6 +71,8 @@
 	{{"_block_count"}},
 #define X_BLOCK_TABLE	1
 	{{"_block_table"}},
+#define X_LBA_FLAG	2
+	{{"_lba_flag"}},
 	{{NULL}}
 };
 
@@ -77,6 +81,8 @@
 int	maxblocknum;		/* size of this array */
 
 int biosdev;
+int use_lba = 0;
+u_int8_t *lba_flag_p;
 
 char		*loadprotoblocks(char *, long *);
 int		loadblocknums(char *, int, struct disklabel *);
@@ -87,7 +93,7 @@
 static void
 usage()
 {
-	fprintf(stderr, "usage: %s [-n] [-v] [-s sec-per-track] [-h track-per-cyl] "
+	fprintf(stderr, "usage: %s [-n] [-l] [-v] [-s sec-per-track] [-h track-per-cyl] "
 	    "boot biosboot device\n", __progname);
 	exit(1);
 }
@@ -112,8 +118,11 @@
 	bios_diskinfo_t di;
 
 	nsectors = nheads = -1;
-	while ((c = getopt(argc, argv, "vnh:s:")) != -1) {
+	while ((c = getopt(argc, argv, "lvnh:s:")) != -1) {
 		switch (c) {
+		case 'l':
+			use_lba = 1;
+			break;
 		case 'h':
 			nheads = atoi(optarg);
 			userspec = 1;
@@ -203,7 +212,7 @@
 		}
 	}
 
-	if (nheads == -1 || nsectors == -1)
+	if (((nheads == -1) || (nsectors == -1)) && (use_lba == 0))
 		errx(1, "Unable to get BIOS geometry, must specify -h and -s");
 
 	/* Extract and load block numbers */
@@ -339,13 +348,19 @@
 	/* Calculate the symbols' locations within the proto file */
 	block_count_p = (u_int8_t *) (bp + nl[X_BLOCK_COUNT].n_value);
 	block_table_p = (u_int8_t *) (bp + nl[X_BLOCK_TABLE].n_value);
+	lba_flag_p = (u_int8_t *) (bp + nl[X_LBA_FLAG].n_value);
 	maxblocknum = *block_count_p;
 
+	/* Patch the LBA flag if necessary */
+	if (use_lba != 0)
+		*lba_flag_p = 0x4C;
+
 	if (verbose) {
 		fprintf(stderr, "%s: entry point %#x\n", fname, eh.e_entry);
 		fprintf(stderr, "proto bootblock size %ld\n", *size);
 		fprintf(stderr, "room for %d filesystem blocks at %#lx\n",
 			maxblocknum, nl[X_BLOCK_TABLE].n_value);
+		fprintf(stderr, "LBA flag set to %c\n", *lba_flag_p);
 	}
 
 	close(fd);
@@ -392,9 +407,6 @@
 	struct dinode	*ip;
 	int		ndb;
 	u_int8_t	*bt;
-#if 0
-	Elf_Ehdr	eh;
-#endif
 	int mib[4];
 	size_t		size;
 	dev_t dev;
@@ -487,7 +499,7 @@
 		dl->d_secpercyl = dl->d_nsectors * nheads;
 	}
 
-	if (verbose)
+	if (verbose && !use_lba)
 		fprintf(stderr, "Using disk geometry of %u sectors and %u heads.\n",
 			dl->d_nsectors, dl->d_secpercyl/dl->d_nsectors);
 
@@ -545,6 +557,8 @@
 	static u_int ss = 0, l = 0, i = 0; /* start and len of group */
 	int ret = 0;
 
+    if (!use_lba) {
+
 	/* printf("%u, %u\n", blk, bs); */
 	if (ss == 0) { /* very beginning */
 		ss = blk;
@@ -561,9 +575,9 @@
 
 		/* nsectors */
 		if ((ss % dl->d_nsectors + l) >= dl->d_nsectors)
-			bt[3] = dl->d_nsectors - s + 1;
+			bt[4] = dl->d_nsectors - s + 1;
 		else
-			bt[3] = l; /* non-contig or last block piece */
+			bt[4] = l; /* non-contig or last block piece */
 
 		bt[2] = (ss % dl->d_secpercyl) / dl->d_nsectors; /* head */
 		*(u_int16_t *)bt = (s & 0x3f) | /* sect, cyl */
@@ -571,24 +585,41 @@
 
 		if (verbose)
 			fprintf(stderr, "%2d: %2d @(%d %d %d) (%d-%d)\n",
-				i, bt[3], c, bt[2], s, ss, ss + bt[3] - 1);
+				i, bt[4], c, bt[2], s, ss, ss + bt[4] - 1);
 		i++;
 
-		ss += bt[3];
-		l -= bt[3];
+		ss += bt[4];
+		l -= bt[4];
 		if ((ss + l) != blk) {
 			/* printf ("l=%u\n", l); */
 		 	if (l)
-				ret += record_block(bt + 4, 0, 0, dl);
+				ret += record_block(bt + 5, 0, 0, dl);
 			ss = blk;
 			l = bs;
 		} else
 			l += bs;
 
-		ret += 4;
+		ret += 5;
 	} else {
 		l += bs;
 	}
 
 	return ret;
+
+  } else { /* use_lba */
+
+	if ((!blk) || (!bt))
+		return 0;
+
+	*((u_int32_t *)bt) = blk;
+	bt[4] = bs;
+
+	if (verbose)
+		fprintf(stderr, "%2d: %2d @%d (0x%08X) LBA\n",
+		    i, bt[4], *((u_int32_t *)bt), *((u_int32_t *)bt));
+
+	++i;
+	return 5;
+
+  }
 }
Index: sys/arch/i386/stand/libsa/biosdev.c
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/libsa/biosdev.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sys/arch/i386/stand/libsa/biosdev.c	24 Apr 2003 11:05:08 -0000	1.3
+++ sys/arch/i386/stand/libsa/biosdev.c	3 May 2003 18:32:13 -0000	1.4
@@ -1,3 +1,4 @@
+/*	$MirBSD: biosdev.c,v 1.4 2003/05/03 18:32:35 tg Exp $	*/
 /*	$OpenBSD: biosdev.c,v 1.55 2003/04/17 03:43:18 drahn Exp $	*/
 
 /*
@@ -123,6 +124,7 @@
 	pdi->bios_cylinders++;
 
 #if 0
+/* XXX this code is not accepted by gcc XXX */
 	/* NOTE:
 	 * This currently hangs/reboots some machines
 	 * The IBM Thinkpad 750ED for one.
@@ -227,19 +229,21 @@
  * Read given sector, handling retry/errors/etc.
  */
 int
-biosd_io(rw, dev, cyl, head, sect, nsect, buf)
+biosd_io(rw, dev, cyl, head, sect, nsect, buf, use_edd)
 	int rw, dev, cyl, head;
 	int sect, nsect;
 	void * buf;
+	int use_edd;
 {
 	int j, error;
 	void *bb;
 
 #ifdef BIOS_DEBUG
 	if (debug)
-		printf("biosd_io(%s,%X,%u,%u,%u,%u,%p)\n",
+		printf("biosd_io(%s,%X,%u,%u,%u,%u,%p,%s)\n",
 		       (rw==F_READ?"reading":"writing"), dev,
-			   cyl, head, sect, nsect, buf);
+			   cyl, head, sect, nsect, buf,
+			   (use_edd==0?"CHS":"LBA"));
 #endif
 
 	/* use a bounce buffer to not cross 64k DMA boundary */
@@ -260,7 +264,11 @@
 #endif
 	/* Try to do operation up to 5 times */
 	for (error = 1, j = 5; j-- && error;)
-		switch (error = biosd_rw(rw, dev, cyl, head, sect, nsect, bb)) {
+		switch (error = (
+		    (use_edd == 0)
+		    ? (biosd_rw(rw, dev, cyl, head, sect, nsect, bb))
+		    : (EDD_rw(rw, dev, cyl, head, sect, nsect, bb))
+		    )) {
 		case 0x00:	/* No errors */
 		case 0x11:	/* ECC corrected */
 			error = 0;
@@ -273,6 +281,8 @@
 					error, biosdisk_err(error));
 #endif
 			biosdreset(dev);
+			if (j == 2)
+				use_edd = 0; /* fall back */
 			break;
 		}
 
@@ -315,7 +325,8 @@
 		       bd->bios_heads, bd->bios_sectors);
 
 		error = biosd_io(F_READ, bd->bios_number,
-				 cyl, head, sect, 1, &mbr);
+				 cyl, head, sect, 1, &mbr,
+				 (bd->bios_edd>0)?1:0);
 		if(error)
 			return(biosdisk_err(error));
 
@@ -347,7 +358,8 @@
 #endif
 	/* read disklabel */
 	btochs(off, cyl, head, sect, bd->bios_heads, bd->bios_sectors);
-	error = biosd_io(F_READ, bd->bios_number, cyl, head, sect, 1, buf);
+	error = biosd_io(F_READ, bd->bios_number, cyl, head, sect, 1, buf,
+	    (bd->bios_edd>0)?1:0);
 
 	if(error)
 		return("failed to read disklabel");
@@ -587,7 +599,8 @@
 		else
 			n = nsect - i;
 		
-		error = biosd_io(rw, dev, cyl, hd, sect, n, buf);
+		error = biosd_io(rw, dev, cyl, hd, sect, n, buf,
+		    (dip->bios_info.bios_edd>0)?1:0);
 	}
 
 #ifdef BIOS_DEBUG
Index: sys/arch/i386/stand/libsa/biosdev.h
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/libsa/biosdev.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sys/arch/i386/stand/libsa/biosdev.h	22 Mar 2003 17:49:15 -0000	1.1
+++ sys/arch/i386/stand/libsa/biosdev.h	3 May 2003 18:32:13 -0000	1.2
@@ -1,3 +1,4 @@
+/*	$MirBSD: biosdev.h,v 1.2 2003/05/03 18:32:35 tg Exp $	*/
 /*	$OpenBSD: biosdev.h,v 1.27 2002/03/14 03:15:54 millert Exp $	*/
 
 /*
@@ -42,7 +43,7 @@
 int biosclose(struct open_file *);
 int biosioctl(struct open_file *, u_long, void *);
 int bios_getdiskinfo(int, bios_diskinfo_t *);
-int biosd_io(int, int, int, int, int, int, void *);
+int biosd_io(int, int, int, int, int, int, void *, int);
 const char * bios_getdisklabel(bios_diskinfo_t *, struct disklabel *);
 
 /* diskprobe.c */
Index: sys/arch/i386/stand/libsa/cmd_i386.c
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/libsa/cmd_i386.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sys/arch/i386/stand/libsa/cmd_i386.c	24 Apr 2003 11:05:08 -0000	1.3
+++ sys/arch/i386/stand/libsa/cmd_i386.c	3 May 2003 18:32:13 -0000	1.4
@@ -1,3 +1,4 @@
+/*	$MirBSD: cmd_i386.c,v 1.4 2003/05/03 18:32:35 tg Exp $	*/
 /*	$OpenBSD: cmd_i386.c,v 1.24 2002/03/14 03:15:54 millert Exp $	*/
 
 /*
@@ -141,7 +142,7 @@
 		printf("[%X]\n", dev);
 
 	/* Read boot sector from device */
-	st = biosd_io(F_READ, dev, 0, 0, 0, 1, buf);
+	st = biosd_io(F_READ, dev, 0, 0, 0, 1, buf, 0);
 	if(st) goto bad;
 
 	/* Frob boot flag in buffer from HD */
Index: sys/arch/i386/stand/libsa/diskprobe.c
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/libsa/diskprobe.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- sys/arch/i386/stand/libsa/diskprobe.c	24 Apr 2003 11:05:08 -0000	1.3
+++ sys/arch/i386/stand/libsa/diskprobe.c	3 May 2003 18:32:13 -0000	1.4
@@ -1,3 +1,4 @@
+/*	$MirBSD: diskprobe.c,v 1.4 2003/05/03 18:32:35 tg Exp $	*/
 /*	$OpenBSD: diskprobe.c,v 1.18 2002/03/14 01:26:34 millert Exp $	*/
 
 /*
@@ -284,7 +285,8 @@
 
 		/* Adler32 checksum */
 		btochs(blk, cyl, head, sect, hpc, spt);
-		st = biosd_io(F_READ, dev, cyl, head, sect, 1, buf);
+		st = biosd_io(F_READ, dev, cyl, head, sect, 1, buf,
+		    (bdi->bios_edd>0)?1:0);
 		if (st) {
 			bdi->flags |= BDI_INVALID;
 			continue;
Index: sbin/fdisk/mbrcode.h
===================================================================
RCS file: /lcvs/src/sbin/fdisk/mbrcode.h,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -r1.1 -r1.3
--- sbin/fdisk/mbrcode.h	22 Mar 2003 17:48:01 -0000	1.1
+++ sbin/fdisk/mbrcode.h	3 May 2003 18:32:45 -0000	1.3
@@ -1,90 +1,61 @@
-/* $OpenBSD: mbrcode.h,v 1.1 2001/06/23 01:56:02 kjell Exp $ */
-/*
- * Copyright (c) 2000 Tobias Weingartner
- * All rights reserved.
- *
- * 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 Tobias Weingartner.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
- */
 /* Largely generated by:
  * hexdump -ve '8/1 "0x%02x, " "\n"' /usr/mdec/mbr
+ * Thanks to Toby Weingartner for the hint.
  */
-0xfa, 0xea, 0x06, 0x00, 0xc0, 0x07, 0x8c, 0xc8,
-0x8e, 0xd8, 0x8e, 0xd0, 0xbc, 0xfc, 0xff, 0xfb,
-0xb0, 0x53, 0xe8, 0xe2, 0x00, 0xb8, 0xa0, 0x07,
-0x8e, 0xc0, 0x31, 0xf6, 0x31, 0xff, 0xb9, 0x00,
-0x02, 0xfc, 0xf2, 0xa4, 0xea, 0x29, 0x00, 0xa0,
-0x07, 0xb0, 0x52, 0xe8, 0xc9, 0x00, 0x1e, 0x07,
-0x0e, 0x1f, 0xf6, 0xc2, 0x80, 0x75, 0x0b, 0x66,
-0xbe, 0x13, 0x01, 0x00, 0x00, 0xe8, 0xab, 0x00,
-0xb2, 0x80, 0x66, 0xbe, 0xbe, 0x01, 0x00, 0x00,
-0x66, 0xb9, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x4c,
-0xe8, 0xa4, 0x00, 0x8a, 0x44, 0x00, 0x3c, 0x80,
-0x74, 0x18, 0x66, 0x83, 0xc6, 0x10, 0xe2, 0xee,
-0x66, 0xbe, 0x3c, 0x01, 0x00, 0x00, 0xe8, 0x82,
-0x00, 0xfa, 0xf4, 0xb0, 0x2e, 0xe8, 0x87, 0x00,
-0xeb, 0xf7, 0xb0, 0x42, 0xe8, 0x80, 0x00, 0x8b,
-0x14, 0x8b, 0x4c, 0x02, 0x66, 0xb8, 0x01, 0x02,
-0x00, 0x00, 0x31, 0xdb, 0xcd, 0x13, 0x73, 0x13,
-0x80, 0xfa, 0x80, 0x75, 0xaa, 0x66, 0xbe, 0x2f,
-0x01, 0x00, 0x00, 0xe8, 0x55, 0x00, 0xe8, 0x33,
-0x00, 0xeb, 0xce, 0xb0, 0x43, 0xe8, 0x57, 0x00,
-0x66, 0x31, 0xc0, 0x66, 0xbb, 0xfe, 0x01, 0x00,
-0x00, 0x67, 0x8b, 0x03, 0x66, 0x3d, 0x55, 0xaa,
-0x00, 0x00, 0x74, 0x0b, 0x66, 0xbe, 0x52, 0x01,
-0x00, 0x00, 0xe8, 0x2e, 0x00, 0xeb, 0xaa, 0xb0,
-0x47, 0xe8, 0x33, 0x00, 0x66, 0xea, 0x00, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x50, 0x53, 0x66, 0xbb,
-0x03, 0x01, 0x00, 0x00, 0x50, 0x88, 0xe0, 0x66,
-0x83, 0xe0, 0x0f, 0xd7, 0xe8, 0x18, 0x00, 0x58,
-0x66, 0x83, 0xe0, 0x0f, 0xd7, 0xe8, 0x0f, 0x00,
-0x5b, 0x58, 0xc3, 0x50, 0xfc, 0xac, 0x84, 0xc0,
-0x74, 0x0f, 0xe8, 0x02, 0x00, 0xeb, 0xf6, 0x50,
-0x53, 0xb4, 0x0e, 0x31, 0xdb, 0x43, 0xcd, 0x10,
-0x5b, 0x58, 0xc3, 0x30, 0x31, 0x32, 0x33, 0x34,
-0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
-0x44, 0x45, 0x46, 0x4d, 0x42, 0x52, 0x20, 0x6f,
-0x6e, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79,
-0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6c, 0x64, 0x20,
-0x42, 0x49, 0x4f, 0x53, 0x0d, 0x0a, 0x00, 0x52,
-0x65, 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f,
-0x72, 0x0d, 0x0a, 0x00, 0x4e, 0x6f, 0x20, 0x61,
-0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x70, 0x61,
-0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0d,
-0x0a, 0x00, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69,
-0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
-0x75, 0x72, 0x65, 0x0d, 0x0a, 0x00, 0x90, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x31, 0xc0, 0x66, 0x50, 0x66, 0x9d, 0xb8,
+0xa0, 0x07, 0x8e, 0xd0, 0x66, 0xbc, 0x00, 0x10,
+0x00, 0x00, 0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x00,
+0x02, 0xbf, 0x00, 0x00, 0xb9, 0x00, 0x01, 0xf3,
+0xa5, 0xea, 0x26, 0x00, 0xa0, 0x07, 0xbe, 0xd2,
+0x00, 0xe8, 0x41, 0x00, 0xbe, 0xe4, 0x00, 0xe8,
+0x3b, 0x00, 0x30, 0xe4, 0xcd, 0x16, 0x3c, 0x0d,
+0x74, 0x0a, 0x3c, 0x1b, 0x74, 0x06, 0x2c, 0x30,
+0x3c, 0x03, 0x77, 0xee, 0x3c, 0x1b, 0x74, 0x7c,
+0x3c, 0x0d, 0x75, 0x30, 0x30, 0xc0, 0xbb, 0xbe,
+0x01, 0x80, 0x3f, 0x80, 0x74, 0x26, 0x40, 0x80,
+0xc3, 0x10, 0x3c, 0x04, 0x72, 0xf3, 0xbe, 0x36,
+0x01, 0xe8, 0x09, 0x00, 0x30, 0xe4, 0xcd, 0x16,
+0xea, 0xf0, 0xff, 0x00, 0xf0, 0xac, 0x08, 0xc0,
+0x74, 0x09, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd,
+0x10, 0xeb, 0xf2, 0xc3, 0xbb, 0xbe, 0x01, 0xc0,
+0xe0, 0x04, 0x00, 0xc3, 0x53, 0xb4, 0x41, 0xbb,
+0xaa, 0x55, 0xb2, 0x80, 0xcd, 0x13, 0x72, 0x2a,
+0x81, 0xfb, 0x55, 0xaa, 0x75, 0x24, 0x80, 0xe1,
+0x01, 0x74, 0x1f, 0x5b, 0xbe, 0xa3, 0x01, 0x66,
+0x8b, 0x47, 0x08, 0x66, 0xa3, 0xab, 0x01, 0x8b,
+0x47, 0x02, 0xa3, 0xb3, 0x01, 0x8b, 0x17, 0xb2,
+0x80, 0x89, 0x16, 0xb5, 0x01, 0xb4, 0x42, 0xe9,
+0xa2, 0x00, 0x5b, 0x8b, 0x4f, 0x02, 0x8b, 0x17,
+0xb2, 0x80, 0xeb, 0x05, 0xb9, 0x01, 0x00, 0x31,
+0xd2, 0xbb, 0x00, 0x02, 0xb8, 0x01, 0x02, 0xe9,
+0x8a, 0x00, 0x4d, 0x69, 0x72, 0x42, 0x53, 0x44,
+0x20, 0x6d, 0x62, 0x72, 0x20, 0x31, 0x2e, 0x30,
+0x31, 0x0d, 0x0a, 0x00, 0x43, 0x68, 0x6f, 0x6f,
+0x73, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
+0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20,
+0x62, 0x6f, 0x6f, 0x74, 0x3a, 0x0d, 0x0a, 0x30,
+0x2c, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x20, 0x62,
+0x79, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
+0x0d, 0x0a, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e,
+0x3a, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65,
+0x3b, 0x20, 0x45, 0x53, 0x43, 0x3a, 0x20, 0x66,
+0x6c, 0x6f, 0x70, 0x70, 0x79, 0x20, 0x64, 0x72,
+0x69, 0x76, 0x65, 0x0d, 0x0a, 0x00, 0x42, 0x6f,
+0x6f, 0x74, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65,
+0x64, 0x2e, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73,
+0x20, 0x61, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x74,
+0x6f, 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74,
+0x2e, 0x0d, 0x0a, 0x00, 0x31, 0xed, 0x60, 0xb8,
+0x2e, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0x61,
+0x60, 0xcd, 0x13, 0x61, 0x72, 0x0b, 0xbe, 0x59,
+0x01, 0xe8, 0xf9, 0xfe, 0xea, 0x00, 0x7c, 0x00,
+0x00, 0x60, 0x31, 0xc0, 0xcd, 0x13, 0x61, 0x45,
+0x83, 0xfd, 0x01, 0x75, 0x16, 0x31, 0xff, 0x39,
+0x3e, 0xb5, 0x01, 0x74, 0x0e, 0x8b, 0x0e, 0xb3,
+0x01, 0x8b, 0x16, 0xb5, 0x01, 0xbb, 0x00, 0x02,
+0xb8, 0x01, 0x02, 0x83, 0xfd, 0x10, 0x72, 0xbe,
+0xe9, 0xbb, 0xfe, 0x10, 0x00, 0x01, 0x00, 0x00,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Index: sys/arch/i386/stand/mbr/Makefile
===================================================================
RCS file: /lcvs/src/sys/arch/i386/stand/mbr/Makefile,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- sys/arch/i386/stand/mbr/Makefile	23 Mar 2003 21:51:56 -0000	1.2
+++ sys/arch/i386/stand/mbr/Makefile	3 May 2003 11:53:09 -0000	1.4
@@ -1,11 +1,11 @@
-#	$OpenBSD: Makefile,v 1.13 2000/06/08 00:56:08 mickey Exp $
-#
+#	$MirBSD: Makefile,v 1.4 2003/05/03 11:53:31 tg Exp $
+#	$OpenBSD: Makefile,v 1.14 2003/04/17 03:43:19 drahn Exp $
 
 PROG=	mbr
-SRCS=	mbr.S
+SRCS=	mbrldr.S
 AFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../.. #-Wa,-a
 LD=ld
-LDFLAGS=-nostdlib -Ttext 0 -x -N -s -Bstatic
+LDFLAGS=-nostdlib -Ttext 0 -x -N -s -Bstatic -e start
 
 NOMAN=
 #MAN+=	mbr.8
@@ -14,9 +14,12 @@
 SADIR=${.CURDIR}/..
 S=	${.CURDIR}/../../../..
 
-# Uncomment this to make mbr talk to a serial port.
+# Uncomment this to make mbr.S talk to a serial port.
 #CPPFLAGS+=-DSERIAL=0
 
+# Uncomment this to make mbrldr.S a bootmanager
+CPPFLAGS+=-DBOOTMANAGER
+
 ${PROG}: $(OBJS) $(DPADD)
 	$(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD)
 	@size $(PROG)
@@ -27,3 +30,9 @@
 	fi
 
 .include <bsd.prog.mk>
+
+mbrldr.E:	mbrldr.S
+	${CC} ${AFLAGS} ${CPPFLAGS} ${.CURDIR}/mbrldr.S -E -o mbrldr.E
+
+disasm:	${PROG}
+	ndisasm -b 16 ${PROG} >${.CURDIR}/mbr~disasm
Index: sys/arch/i386/stand/mbr/mbrldr.S
===================================================================
RCS file: sys/arch/i386/stand/mbr/mbrldr.S
diff -N sys/arch/i386/stand/mbr/mbrldr.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sys/arch/i386/stand/mbr/mbrldr.S	3 May 2003 17:12:23 -0000	1.3
@@ -0,0 +1,185 @@
+/*	$MirBSD: mbrldr.S,v 1.3 2003/05/03 17:12:45 tg Stab $	*/
+/*-
+ * Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de>
+ *
+ * Anyone who obtained a copy of this work is hereby permitted to freely use,
+ * distribute, modify, merge, sublicence, give away or sell it as long as the
+ * authors are given due credit and the following notice is retained:
+ *
+ * This work is provided "as is", with no explicit or implicit warranty what-
+ * soever. Use it only at your own risk. In no event may an author or contri-
+ * butor be held liable for any damage, directly or indirectly, that origina-
+ * ted through or is caused by creation or modification of this work.
+ */
+
+	.file	"mbrldr.S"
+	.intel_syntax noprefix
+
+	.text
+	.code16
+	.globl	start
+start:	xor	eax,eax
+	push	eax
+	popfd
+	mov	ax,0x07A0
+	mov	ss,ax
+	mov	esp,0x1000
+	mov	ds,ax
+	mov	es,ax
+	mov	si,0x0200	/* 7A0:0200 = 0:7C00 */
+	mov	di,0x0000	/* 7A0:0000 = 0:7A00 */
+	mov	cx,0x0100
+	rep	movsw
+	jmp	0x07A0,offset doit
+	/* we are relocated now */
+doit:	/*
+	 * a) Output "Hello" Text
+	 * b) if BOOTMANAGER
+	 *	Output "Choose" Text
+	 *	Handle input (0,1,2,3,RET,ESC)
+	 *    else
+	 *	Fake input RET
+	 *    endif
+	 * c) load sector (RET=0x80-Partition, ESC=Floppy, 0-3=Partition)
+	 * d) jump to sector
+	 */
+	mov	si,offset tHelo
+	call	_otxt
+#ifdef	BOOTMANAGER
+	mov	si,offset tBmgr
+	call	_otxt
+ilp1:	xor	ah,ah
+	int	0x16
+	cmp	al,13
+	je	ilok
+	cmp	al,27
+	je	ilok
+	sub	al,0x30
+	cmp	al,3
+	ja	ilp1
+ilok:	/* al=13,27,0,1,2,3 */
+#else
+	mov	al,13
+#endif
+	cmp	al,27
+	je	floppy
+	cmp	al,13
+	jne	partok
+	xor	al,al
+	mov	bx,offset ptbl
+cklp:	cmp	byte ptr [bx],0x80
+	je	partok
+	inc	ax
+	add	bl,0x10		/* sizeof ptbl-ent */
+	cmp	al,4
+	jb	cklp
+bootfl:	mov	si,offset tFail
+	call	_otxt
+	xor	ah,ah
+	int	0x16
+	jmp	0xF000,0xFFF0
+_otxt:	lodsb
+	or	al,al
+	je	raus
+	mov	ah,0x0E
+	mov	bx,7
+	int	0x10
+	jmp	_otxt
+raus:	ret
+partok:	mov	bx,offset ptbl
+	shl	al,4		/* log_2 sizeof ptbl-ent */
+	add	bl,al		/* can't overflow */
+	push	bx
+	/* Test for LBA support */
+	mov	ah,0x41
+	mov	bx,0x55AA
+	mov	dl,0x80
+	int	0x13
+	jc	l_chs
+	cmp	bx,0xAA55
+	jne	l_chs
+	and	cl,1
+	je	l_chs
+l_lba:	pop	bx
+	/* Load the boot structure (LBA) */
+	mov	si,offset lbapbl
+	mov	eax,[bx+8]
+	mov	[blknum],eax
+	mov	ax,[bx+2]
+	mov	[savecx],ax
+	mov	dx,[bx]
+	mov	dl,0x80
+	mov	[savedx],dx
+	mov	ah,0x42
+	jmp	boot_loop
+l_chs:	pop	bx
+	/* Load the boot structure (CHS) */
+	mov	cx,[bx+2]
+	mov	dx,[bx]
+	mov	dl,0x80
+	jmp	boot_chs
+floppy:	mov	cx,1
+	xor	dx,dx
+boot_chs:
+	mov	bx,offset bsec
+	mov	ax,0x0201
+	jmp	boot_loop
+tHelo:	.asciz	"MirBSD mbr 1.01\r\n"
+#ifdef	BOOTMANAGER
+tBmgr:	.ascii	"Choose partition to boot:\r\n"
+	.ascii	"0,1,2,3 by number\r\n"
+	.ascii	"RETURN: active; "
+	.asciz	"ESC: floppy drive\r\n"
+#endif
+tFail:	.ascii	"Boot failed. Press a key to reboot."
+	/* fall through */
+tCRLF:	.asciz	"\r\n"
+boot_loop:
+	xor	bp,bp
+blp1:	pusha
+	mov	ax,0x0E2E
+	mov	bx,7
+	int	0x10
+	popa
+	pusha
+	int	0x13
+	popa
+	jc	blp2
+	mov	si,offset tCRLF
+	call	_otxt
+	jmp	0,0x7C00	/* offset flat bsec */
+blp2:	pusha
+	xor	ax,ax
+	int	0x13
+	popa
+	inc	bp
+	cmp	bp,1		/* first time it failed? */
+	jne	blp3
+	xor	di,di
+	cmp	[savedx],di	/* if so, check if we were LBA */
+	je	blp3
+	mov	cx,[savecx]	/* if so, fall back to CHS */
+	mov	dx,[savedx]
+	mov	bx,offset bsec
+	mov	ax,0x0201
+blp3:	cmp	bp,16		/* 16 retries should be enough for everyone */
+	jb	blp1
+	jmp	bootfl		/* failed */
+lbapbl:	/* Parameter block for LBA */
+	.word	0x0010		/* length, reserved */
+	.word	0x0001		/* num. of sectors */
+	.long	0x00007C00	/* transfer buffer */
+blknum:	.long	0,0		/* LBA block number */
+savecx:	.word	0
+savedx:	.word	0
+
+	/* Trailer: partition table, signature */
+	. = 0x01B8
+	.long	0		/* some NT stuff */
+	.word	0		/* space */
+ptbl:	.long	0,0,0,0
+	.long	0,0,0,0
+	.long	0,0,0,0
+	.long	0x00010080,0xFFFFFFA6,0,0x7FFFFFFF
+	.word	0xAA55		/* signature */
+bsec:	/* 0x0200 is where the new boot sector is loaded */