summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>1997-08-01 18:39:46 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>1997-08-01 18:39:46 +0000
commitf845857b83e80683aadccf3e21c66dd9ff23ef69 (patch)
tree862ef08729ba8e439bad967155c707542fba7218
parent0d3dc4ca85a5ba9a0d9ed002021035f158f2ca7f (diff)
First pass at MBR. Couple of bugs yet, but I can't work
them out until I get my SCSI disks up. Note: There are currently 4 bytes left with the debugging version. Be careful.
-rw-r--r--sys/arch/i386/stand/mbr/mbr.S245
1 files changed, 157 insertions, 88 deletions
diff --git a/sys/arch/i386/stand/mbr/mbr.S b/sys/arch/i386/stand/mbr/mbr.S
index 2b48f580e96..f7b3e1407d3 100644
--- a/sys/arch/i386/stand/mbr/mbr.S
+++ b/sys/arch/i386/stand/mbr/mbr.S
@@ -1,7 +1,7 @@
-/* $OpenBSD: mbr.S,v 1.1 1997/03/31 03:12:19 weingart Exp $ */
+/* $OpenBSD: mbr.S,v 1.2 1997/08/01 18:39:45 weingart Exp $ */
/*
- * Copyright (c) 1997 Michael Shalayeff
+ * Copyright (c) 1997 Michael Shalayeff and Tobias Weingartner
*/
/* Copyright (c) 1996 VaX#n8 (vax@linkdead.paranoia.com)
@@ -13,22 +13,7 @@
* this copyright notice in the file.
*/
-/* $OpenBSD: mbr.S,v 1.1 1997/03/31 03:12:19 weingart Exp $ */
-
-/*
- * Copyright (c) 1996 Michael Shalayeff
- */
-
-/* Copyright (c) 1996 VaX#n8 (vax@linkdead.paranoia.com)
- * last edited 9 July 1996
- * many thanks to Erich Boleyn (erich@uruk.org) for putting up with
- * all my questions, and for his work on GRUB
- * You may use this code or fragments thereof in a manner consistent
- * with the other copyrights as long as you retain my pseudonym and
- * this copyright notice in the file.
- */
-
- .file "start.S"
+ .file "mbr.S"
#include <machine/asm.h>
#include <machine/specialreg.h>
@@ -42,14 +27,12 @@
#define NUMPART 4 /* number of partitions in partition table */
#define PARTSZ 16 /* each partition table entry is 16 bytes */
#define BSDPART 0xA6 /* OpenBSD partition */
-#define OLDBSDPART 0xA5 /* {386,Net,Free}BSD partition */
#define BOOTABLE 0x80 /* bootable partition */
#ifdef DEBUG
#define CHAR_S 'S' /* started */
-#define CHAR_L 'L' /* looking up bootable partition */
-#define CHAR_P 'P' /* partition table corrupted */
-#define CHAR_O 'O' /* force OpenBSD load */
+#define CHAR_R 'R' /* relocated */
+#define CHAR_L 'L' /* looking for bootable partition */
#define CHAR_B 'B' /* loading boot */
#define CHAR_G 'G' /* jumping to boot */
@@ -65,131 +48,203 @@
.globl start
start:
+ /* Adjust %cs to be right */
+ data32
+ ljmp $BOOTBIOS, $1f
+1:
+ /* Set up stack */
movl %cs, %ax
- # set up stack(%ss:%esp)
- cli /* disable interrupts w/o stack */
+ cli
movl %ax, %ss
data32
movl $0xfffc, %esp
- sti /* we have stack, do ints */
- /* setup %ds */
+ sti
+
+ /* Set up data segment */
movl %ax, %ds
+ DBGMSG(CHAR_S)
- /* relocate the code to leave the space for boot stage */
+ /* Relocate 512 bytes so we can load PBS here */
data32
movl $BOOTRELOC, %eax
movl %ax, %es
+ data32
xorl %si, %si
+ data32
xorl %di, %di
- xorl %cx, %cx
- incb %ch /* movl $0x100, %ecx */
+ data32
+ movl $0x200, %ecx
cld
rep
- movsw
+ movsb
- # jump to the relocated code
+ /* Jump to relocated self */
data32
- ljmp $BOOTRELOC, $1f
-1:
- DBGMSG(CHAR_S)
+ ljmp $BOOTRELOC, $reloc
+reloc:
+ DBGMSG(CHAR_R)
- /* setup %es, %ds */
+ /* Set up %es and %ds */
pushl %ds
popl %es /* next boot is at the same place as we were loaded */
pushl %cs
popl %ds /* and %ds is at the %cs */
#ifdef SERIAL
- # Initialize the serial port to 9600 baud, 8N1.
+ /* Initialize the serial port to 9600 baud, 8N1. */
+ * Do we need to do this? Most things at this level
+ * do not know or care (on a PC) where the output is
+ * happening to go. I think if we are headless,
+ * /boot should figure (as it does now) that out.
+ *
+ * If there is a problem with this stage of the boot
+ * process, connect up a monitor and kbd, and see what
+ * is going on. Left here for the time being.
+ *
+ * --Toby.
+ */
xorl %ax, %ax
- movb $0xe3, %ax
+ movb $0xe3, %ax
data32
movl $SERIAL, %dx
int $0x14
#endif
- /* bootstrap passes us drive number in %dl */
+ /* bootstrap passes us drive number in %dl
+ *
+ * XXX - This is not always true. We currently
+ * check if %dl points to a HD, and if not we
+ * complain, and set it to point to the first
+ * HDD. Note, this is not 100% correct, since
+ * there is a possibility that you boot of of
+ * HD #2, and still get (%dl & 0x80) == 0x00,
+ * these type of systems will loose. I don't
+ * know of any like this, but I've come to the
+ * conclusion, that if it can exists, it will,
+ * someplace in the PC world. If anyone knows
+ * how to fix this, speak up!
+ *
+ * Toby - Thu Jul 31 21:01:00 CDT 1997
+ */
testb $0x80, %dl
jnz 1f
- /* mbr on floppy ??? */
+ /* MBR on floppy or old BIOS
+ * Note: MBR (this code) should never
+ * be on a floppy. It does not belong
+ * there, so %dl should never be 0x00.
+ *
+ * Here we simply complain (should we?),
+ * and then hardcode the boot drive to
+ * 0x80.
+ */
data32
movl $fdmbr, %esi
data32
call message
+ /* If we are passed bogus data, set it to HD #1.
+ * We should load the value from a hard coded
+ * location in this sector. Maybe I'll write
+ * that next, since my machines seem to be one
+ * of the weird ones...
+ */
+ movb $0x80, %dl
+
+ /* Do we need to check our signature? The BIOS will
+ * check it for us, I doubt there is a need for us to
+ * do the same thing over again. If we fail here,
+ * something terrible is wrong. However, I doubt we
+ * can recover anyways. The message might be nice
+ * for the (l)user though.
+ */
1: xorl %bx, %bx
# cmpw $SIGNATURE, (%bx)
.byte 0x81, 0xbf
.word signature
.word SIGNATURE
- je 1f
- DBGMSG(CHAR_P)
+ je sigok
+ data32
+ movl $esig, %esi
+ data32
+ call message
- /* find the first active partition */
-1: DBGMSG(CHAR_L)
+ /* find the first active partition
+ * Note: this should be the only active
+ * partition. We currently don't check
+ * for that, but we really should. If
+ * and when I feel up to it, I'll add
+ * that code.
+ */
+sigok:
data32
movl $pt, %esi
data32
movl $NUMPART, %cx
1:
+ DBGMSG(CHAR_L)
# movb (%si), %al
.byte 0x8a, 0x44, 0x00
cmpb $BOOTABLE, %al
- je 2f
+ je found
data32
addl $PARTSZ, %esi
loop 1b
- jmp 1f /* no bootable -- find $BSDPART */
-2: # test if bootable is ours
- # movb 4(%si), %al # partition type
- .byte 0x8a, 0x44, 0x04
- cmpb $BSDPART, %al
- je found
-
- /* else: ask! */
+ /* No bootable partition */
+no_part:
data32
- movl $prompt, %esi
+ movl $noboot, %esi
data32
call message
+err_stop:
+ cli
+ hlt
+ /* Just to make sure */
+ jmp err_stop
- # BIOS call: read char from kbd
- # return: %ah == scancode, %al == ascii
- xorl %ax, %ax
- int $0x16
+ /* Found bootable partition */
+found:
+ DBGMSG(CHAR_B)
+ pushl %eax
+ pushl %edx
+ pushl %esi
+ pushl %ecx
- /* load active, if not */
- cmpb 'n', %al
- je found
- cmpb 'N', %al
- je found
+ /* Print out drive and partition */
+ data32
+ movl $drive, %esi
+ data32
+ call message
-1:
- /* else: find OpenBSD partition */
- DBGMSG(CHAR_O)
+ movl %dx, %ax
+ andl $0x0F, %ax
+ orl $0x30, %ax
data32
- movl $pt, %esi
+ call chr
+
data32
- movl $NUMPART, %ecx
-1:
- # movb (%si), %al
- .byte 0x8a, 0x44, 0x00
- cmpb $BSDPART, %al
- je found
+ movl $partn, %esi
data32
- addl $PARTSZ, %esi
- loop 1b
+ call message
+
+ popl %eax
+ andl $0x0F, %ax
+ orl $0x30, %ax
data32
- movl $enoboot, %esi
-err_stop:
+ call chr
+
+ data32
+ movl $newln, %esi
data32
call message
- cli
- hlt
-found:
- DBGMSG(CHAR_B)
+ /* Restore %esi and %edx */
+ popl %esi
+ popl %edx
+ popl %eax
+
+ /* Load values from active partition table entry */
# movb 1(%si), %dh # head
.byte 0x8a, 0x74, 0x01
# movw 2(%si), %cx # sect, cyl
@@ -213,10 +268,15 @@ found:
movl $0x200 | 1, %eax /* number of blocks */
xorl %bx, %bx /* put it at %es:0 */
int $0x13
+ jnc 1f
data32
movl $eread, %si
- jc err_stop
+ data32
+ call message
+ jmp err_stop
+
+1:
DBGMSG(CHAR_G)
# jump to the new code (%ds:%si is at he right point)
@@ -259,7 +319,7 @@ chr:
int $0x14
popl %edx
#endif
- popl %ax
+ popl %eax
data32
ret
@@ -280,17 +340,25 @@ message:
popl %ax
ret
-/* error messages */
+/* Info messages */
+drive: .asciz "Using Drive: "
+partn: .asciz " Partition: "
+newln: .asciz "\r\n"
-fdmbr: .asciz "MBR on fd?\r\n"
+/* Error messages */
+fdmbr: .asciz "MBR on floppy or old BIOS\r\n"
eread: .asciz "Read error\r\n"
-enoboot: .asciz "No partition to boot\r\n"
-prompt: .asciz "OpenBSD? "
+noboot: .asciz "No active partition\r\n"
+esig: .asciz "Invalid Signature\r\n"
endofcode:
nop
-/* throw in a partition table */
+/* (MBR) NT registry offset */
+ . = 0x1b8
+ .space 4, 0
+
+/* partition table */
/* flag, head, sec, cyl, type, ehead, esect, ecyl, start, len */
. = 0x1be # starting address of partition table
pt:
@@ -301,9 +369,10 @@ pt:
.byte 0x0,0,0,0,0,0,0,0
.long 0,0
.byte BOOTABLE,0,1,0,BSDPART,255,255,255
- .long 0,50000
+ .long 0,0x7FFFFFFF
/* the last 2 bytes in the sector 0 contain the signature */
. = 0x1fe
signature:
.short SIGNATURE
. = 0x200
+