summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/mbr/mbr.S
diff options
context:
space:
mode:
authorTobias Weingartner <weingart@cvs.openbsd.org>1997-03-31 03:12:20 +0000
committerTobias Weingartner <weingart@cvs.openbsd.org>1997-03-31 03:12:20 +0000
commitdb37cd8003c371210064ba9f9a9c279f13a175d2 (patch)
tree95a740b2174d900a416d0fd7fac0895c9e3972ab /sys/arch/i386/stand/mbr/mbr.S
parent1dc40aae41ae95a97b3d0955f1cf85385b6de1a4 (diff)
Initial /boot stuff (from Mickey)
Diffstat (limited to 'sys/arch/i386/stand/mbr/mbr.S')
-rw-r--r--sys/arch/i386/stand/mbr/mbr.S309
1 files changed, 309 insertions, 0 deletions
diff --git a/sys/arch/i386/stand/mbr/mbr.S b/sys/arch/i386/stand/mbr/mbr.S
new file mode 100644
index 00000000000..2b48f580e96
--- /dev/null
+++ b/sys/arch/i386/stand/mbr/mbr.S
@@ -0,0 +1,309 @@
+/* $OpenBSD: mbr.S,v 1.1 1997/03/31 03:12:19 weingart Exp $ */
+
+/*
+ * Copyright (c) 1997 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.
+ */
+
+/* $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"
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+
+#define data32 .byte 0x66
+#define addr32 .byte 0x67
+
+#define BOOTBIOS 0x7c0 /* segment where we are loaded */
+#define BOOTRELOC 0x7a0 /* segment where to relocate */
+#define SIGNATURE 0xaa55 /* MBR signature */
+#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_B 'B' /* loading boot */
+#define CHAR_G 'G' /* jumping to boot */
+
+#define DBGMSG(msg) \
+ movb $msg, %al; \
+ data32; \
+ call chr
+#else /* !DEBUG */
+#define DBGMSG(msg)
+#endif /* !DEBUG */
+
+ .text
+
+ .globl start
+start:
+ movl %cs, %ax
+ # set up stack(%ss:%esp)
+ cli /* disable interrupts w/o stack */
+ movl %ax, %ss
+ data32
+ movl $0xfffc, %esp
+ sti /* we have stack, do ints */
+ /* setup %ds */
+ movl %ax, %ds
+
+ /* relocate the code to leave the space for boot stage */
+ data32
+ movl $BOOTRELOC, %eax
+ movl %ax, %es
+ xorl %si, %si
+ xorl %di, %di
+ xorl %cx, %cx
+ incb %ch /* movl $0x100, %ecx */
+ cld
+ rep
+ movsw
+
+ # jump to the relocated code
+ data32
+ ljmp $BOOTRELOC, $1f
+1:
+ DBGMSG(CHAR_S)
+
+ /* setup %es, %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.
+ xorl %ax, %ax
+ movb $0xe3, %ax
+ data32
+ movl $SERIAL, %dx
+ int $0x14
+#endif
+
+ /* bootstrap passes us drive number in %dl */
+ testb $0x80, %dl
+ jnz 1f
+
+ /* mbr on floppy ??? */
+ data32
+ movl $fdmbr, %esi
+ data32
+ call message
+
+1: xorl %bx, %bx
+ # cmpw $SIGNATURE, (%bx)
+ .byte 0x81, 0xbf
+ .word signature
+ .word SIGNATURE
+ je 1f
+ DBGMSG(CHAR_P)
+
+ /* find the first active partition */
+1: DBGMSG(CHAR_L)
+ data32
+ movl $pt, %esi
+ data32
+ movl $NUMPART, %cx
+1:
+ # movb (%si), %al
+ .byte 0x8a, 0x44, 0x00
+ cmpb $BOOTABLE, %al
+ je 2f
+ 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! */
+ data32
+ movl $prompt, %esi
+ data32
+ call message
+
+ # BIOS call: read char from kbd
+ # return: %ah == scancode, %al == ascii
+ xorl %ax, %ax
+ int $0x16
+
+ /* load active, if not */
+ cmpb 'n', %al
+ je found
+ cmpb 'N', %al
+ je found
+
+1:
+ /* else: find OpenBSD partition */
+ DBGMSG(CHAR_O)
+ data32
+ movl $pt, %esi
+ data32
+ movl $NUMPART, %ecx
+1:
+ # movb (%si), %al
+ .byte 0x8a, 0x44, 0x00
+ cmpb $BSDPART, %al
+ je found
+ data32
+ addl $PARTSZ, %esi
+ loop 1b
+ data32
+ movl $enoboot, %esi
+err_stop:
+ data32
+ call message
+ cli
+ hlt
+
+found:
+ DBGMSG(CHAR_B)
+ # movb 1(%si), %dh # head
+ .byte 0x8a, 0x74, 0x01
+ # movw 2(%si), %cx # sect, cyl
+ .byte 0x8b, 0x4c, 0x02
+ # movb 4(%si), %al # partition type
+ .byte 0x8a, 0x44, 0x04
+
+/*
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+ data32
+ movl $0x200 | 1, %eax /* number of blocks */
+ xorl %bx, %bx /* put it at %es:0 */
+ int $0x13
+ data32
+ movl $eread, %si
+ jc err_stop
+
+ DBGMSG(CHAR_G)
+
+ # jump to the new code (%ds:%si is at he right point)
+ data32
+ ljmp $0, $BOOTBIOS << 4
+ /* not reached */
+
+#
+# message: write the error message in %ds:%si to console
+#
+chr:
+/*
+#ifndef SERIAL
+# BIOS call "INT 10H Function 0Eh" to write character to console
+# Call with %ah = 0x0e
+# %al = character
+# %bh = page
+# %bl = foreground color
+#else
+# BIOS call "INT 14H Function 01h" to write character to console
+# Call with %ah = 0x01
+# %al = character
+# %dx = port number
+#endif
+*/
+ pushl %eax
+
+#ifndef SERIAL
+ pushl %ebx
+ movb $0x0e, %ah
+ xorl %bx, %bx
+ incl %bx /* movw $0x01, %bx */
+ int $0x10
+ popl %ebx
+#else
+ pushl %edx
+ movb $0x01, %ah
+ data32
+ movl SERIAL, %dx
+ int $0x14
+ popl %edx
+#endif
+ popl %ax
+ data32
+ ret
+
+/*
+ * Display string
+ */
+message:
+ pushl %ax
+ cld
+1:
+ lodsb # load a byte into %al
+ testb %al, %al
+ jz 1f
+ data32
+ call chr
+ jmp 1b
+1:
+ popl %ax
+ ret
+
+/* error messages */
+
+fdmbr: .asciz "MBR on fd?\r\n"
+eread: .asciz "Read error\r\n"
+enoboot: .asciz "No partition to boot\r\n"
+prompt: .asciz "OpenBSD? "
+
+endofcode:
+ nop
+
+/* throw in a partition table */
+/* flag, head, sec, cyl, type, ehead, esect, ecyl, start, len */
+ . = 0x1be # starting address of partition table
+pt:
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte BOOTABLE,0,1,0,BSDPART,255,255,255
+ .long 0,50000
+/* the last 2 bytes in the sector 0 contain the signature */
+ . = 0x1fe
+signature:
+ .short SIGNATURE
+ . = 0x200