summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/boot/i386/mbr/Makefile28
-rw-r--r--sys/boot/i386/mbr/mbr.m451
-rw-r--r--sys/boot/i386/mbr/mbr.s98
3 files changed, 177 insertions, 0 deletions
diff --git a/sys/boot/i386/mbr/Makefile b/sys/boot/i386/mbr/Makefile
new file mode 100644
index 0000000..ef206e5
--- /dev/null
+++ b/sys/boot/i386/mbr/Makefile
@@ -0,0 +1,28 @@
+# $Id: $
+
+PROG= mbr
+NOMAN=
+STRIP=
+BINDIR?= /boot
+BINMODE= 444
+
+M4?= m4
+
+ORG= 0x600
+
+mbr: mbr.o
+.if ${OBJFORMAT} == aout
+ ${LD} -N -s -T ${ORG} -o mbr.out mbr.o
+ dd if=mbr.out of=${.TARGET} ibs=32 skip=1
+.else
+ ${LD} -N -e start -Ttext ${ORG} -o mbr.out mbr.o
+ objcopy -S -O binary mbr.out ${.TARGET}
+.endif
+
+mbr.o: mbr.m4 mbr.s
+ (cd ${.CURDIR}; ${M4} mbr.m4 mbr.s) | \
+ ${AS} ${AFLAGS} -o ${.TARGET}
+
+CLEANFILES+= mbr.out mbr.o
+
+.include <bsd.prog.mk>
diff --git a/sys/boot/i386/mbr/mbr.m4 b/sys/boot/i386/mbr/mbr.m4
new file mode 100644
index 0000000..768e262
--- /dev/null
+++ b/sys/boot/i386/mbr/mbr.m4
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 1999 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $Id: $
+
+define(_al,0x0)dnl
+define(_cl,0x1)dnl
+define(_dl,0x2)dnl
+define(_bl,0x3)dnl
+define(_ah,0x4)dnl
+define(_ch,0x5)dnl
+define(_dh,0x6)dnl
+define(_bh,0x7)dnl
+
+define(_ax,0x0)dnl
+define(_cx,0x1)dnl
+define(_dx,0x2)dnl
+define(_bx,0x3)dnl
+define(_sp,0x4)dnl
+define(_bp,0x5)dnl
+define(_si,0x6)dnl
+define(_di,0x7)dnl
+
+define(_bx_si,0x0)dnl
+define(_bx_di,0x1)dnl
+define(_bp_si,0x2)dnl
+define(_bp_di,0x3)dnl
+define(_si_,0x4)dnl
+define(_di_,0x5)dnl
+define(_bp_,0x6)dnl
+define(_bx_,0x7)dnl
+
+define(cmpbr0,`.byte 0x38; .byte ($1 << 0x3) | $2')dnl
+define(cmpwi2,`.byte 0x81; .byte 0xb8 | $3; .word $2; .word $1')dnl
+define(movb0r,`.byte 0x8a; .byte ($2 << 0x3) | $1')dnl
+define(movb1r,`.byte 0x8a; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
+define(movw1r,`.byte 0x8b; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
+define(movwir,`.byte 0xb8 | $2; .word $1')dnl
+define(jmpnwi,`.byte 0xe9; .word $1 - . - 0x2')dnl
diff --git a/sys/boot/i386/mbr/mbr.s b/sys/boot/i386/mbr/mbr.s
new file mode 100644
index 0000000..9bdb5d5
--- /dev/null
+++ b/sys/boot/i386/mbr/mbr.s
@@ -0,0 +1,98 @@
+#
+# Copyright (c) 1999 Robert Nordier
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are freely
+# permitted provided that the above copyright notice and this
+# paragraph and the following disclaimer are duplicated in all
+# such forms.
+#
+# This software is provided "AS IS" and without any express or
+# implied warranties, including, without limitation, the implied
+# warranties of merchantability and fitness for a particular
+# purpose.
+#
+
+# $Id: $
+
+# Master boot record
+
+ .set LOAD,0x7c00 # Load address
+ .set EXEC,0x600 # Execution address
+ .set PT_OFF,0x1be # Partition table
+ .set MAGIC,0xaa55 # Magic: bootable
+
+ .set NDRIVE,0x8 # Drives to support
+
+ .globl start # Entry point
+
+start: cld # String ops inc
+ xorl %eax,%eax # Zero
+ movl %eax,%es # Address
+ movl %eax,%ds # data
+ cli # Disable interrupts
+ movl %eax,%ss # Set up
+ movwir(LOAD,_sp) # stack
+ sti # Enable interrupts
+ movwir(main-EXEC+LOAD,_si) # Source
+ movwir(main,_di) # Destination
+ movwir(0x200-(main-start),_cx) # Word count
+ rep # Relocate
+ movsb # code
+ jmpnwi(main-LOAD+EXEC) # To relocated code
+
+main: xorl %esi,%esi # No active found
+ movwir(partbl,_bx) # Partition table
+ movb $0x4,%cl # Entries
+main.1: cmpbr0(_ch,_bx_) # Null entry?
+ je main.2 # Yes
+ jg err_pt # If bit 7 unset
+ testl %esi,%esi # Active found?
+ jnz err_pt # Yes
+ movl %ebx,%esi # Keep place
+main.2: addb $0x10,%bl # Till
+ loop main.1 # done
+ testl %esi,%esi # Active found?
+ jnz main.3 # Yes
+ int $0x18 # BIOS: Diskless boot
+
+main.3: cmpb $0x80,%dl # Drive valid?
+ jb main.4 # No
+ cmpb $0x80+NDRIVE,%dl # Within range?
+ jb main.5 # Yes
+main.4: movb0r(_si_,_dl) # Load drive
+main.5: movb1r(0x1,_si_,_dh) # Load head
+ movw1r(0x2,_si_,_cx) # Load cylinder:sector
+ movwir(LOAD,_bx) # Transfer buffer
+ movwir(0x201,_ax) # BIOS: Read from
+ int $0x13 # disk
+ jc err_rd # If error
+ cmpwi2(MAGIC,0x1fe,_bx_) # Bootable?
+ jne err_os # No
+ jmp *%ebx # Invoke bootstrap
+
+err_pt: movwir(msg_pt,_si) # "Invalid partition
+ jmp putstr # table"
+
+err_rd: movwir(msg_rd,_si) # "Error loading
+ jmp putstr # operating system"
+
+err_os: movwir(msg_os,_si) # "Missing operating
+ jmp putstr # system"
+
+putstr.0: movwir(0x7,_bx) # Page:attribute
+ movb $0xe,%ah # BIOS: Display
+ int $0x10 # character
+putstr: lodsb # Get character
+ testb %al,%al # End of string?
+ jnz putstr.0 # No
+putstr.1: jmp putstr.1 # Await reset
+
+msg_pt: .asciz "Invalid partition table"
+msg_rd: .asciz "Error loading operating system"
+msg_os: .asciz "Missing operating system"
+
+ .org PT_OFF
+
+partbl: .fill 0x10,0x4,0x0 # Partition table
+ .word MAGIC # Magic number
OpenPOWER on IntegriCloud