From 3b9e194e9ea3268aa1383304215af4fc3984370b Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 5 Sep 2004 02:39:31 +0000 Subject: mbr boot manager initial import --- Makefile | 25 +++++ boot.S | 320 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 345 insertions(+) create mode 100644 Makefile create mode 100644 boot.S diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b50225f --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +OC# $Id$ +# + +PROG= boot +SRCS= boot.S +AFLAGS+=-I${.CURDIR} +LD=ld +LDFLAGS=-nostdlib -Ttext 0 -x -N -s -Bstatic -e start + +NOMAN= + +INSTALL_STRIP= +SADIR=${.CURDIR}/.. +S= ${.CURDIR}/../../../.. + +${PROG}: $(OBJS) $(DPADD) + $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDADD) + @size $(PROG) + @if [ -x ${.OBJDIR}/${PROG} ]; then \ + objcopy -O binary ${PROG} ${.OBJDIR}/.tmp;\ + mv -f ${.OBJDIR}/.tmp ${.OBJDIR}/${PROG}; \ + ls -l ${.OBJDIR}/${PROG}; \ + fi + +.include diff --git a/boot.S b/boot.S new file mode 100644 index 0000000..586ea8e --- /dev/null +++ b/boot.S @@ -0,0 +1,320 @@ +/* $Id$ */ +/* + * Copyright (c) 2004 demon + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Inspired by BOOTEASY by Serge Vakulenko + */ +/* + * Copyright (c) 1997 Michael Shalayeff and Tobias Weingartner + * Copyright (c) 2003 Tom Cosgrove + * 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. + * + * 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 REGENTS OR CONTRIBUTORS 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. + * + */ +/* 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 "boot.S" + +#define SCAN_ENTER 0x1c /* scancode of Enter key */ +#define SCAN_F1 0x3b /* scancode of F1 key */ +#define TIMEOUT 5 /* wait up to 5 seconds for replay */ +#define BOOTSEG 0x7c0 /* segment where we are loaded */ +#define RELOCSEG 0x7a0 /* segment where we relocate to */ +#define STACKOFF 0xfffc /* stacks starts here, grows down */ +#define PARTSZ 16 /* each item of pt is 16 bytes long */ +#define NPART 4 /* 4 partitions */ +#define DISKSNUM 0x475 +#define MBRMAGIC 0xaa55 /* MBR magic */ + +#define puts(s) movw $s, %si; call msg + + .text + .code16 + + .globl start +start: + ljmp $BOOTSEG, $1f /* adjust %cs to be right */ +1: + movw %cs, %ax /* set up stack */ + movw %ax, %ss + movw $STACKOFF, %sp + + movw %ax, %ds /* set up data segment */ + + movw $RELOCSEG, %ax /* relocate */ + movw %ax, %es + xorw %si, %si + xorw %di, %di + movw $0x200, %cx + cld + rep + movsb + + ljmp $RELOCSEG, $reloc /* jump to relocated self */ +reloc: + pushw %ds /* set up %es and %ds */ + popw %es /* next boot is at same place as we are loaded */ + pushw %cs + popw %ds /* and %ds is at the %cs */ + +test_drv: + testb $0x80, %dl + jnz drive_ok + movb $0x80, %dl + +drive_ok: + movw %dx, %bp + +menu: + movw $pt, %di + movw $NPART, %cx + +1: /* menu loop */ + movb %ch, (%di) /* clear active flag */ + movb 4(%di), %al + cmpb $0x0, %al /* unused */ + je 4f + cmpb $0x5, %al /* ext DOS */ + je 4f + cmpb $0xf, %al /* ext LBA */ + je 4f + + movb $'1'+4, %al + subb %cl, %al + movb %al, prtnum + + puts(fkey) + + lea namtab-2, %si + +2: /* name loop */ + incw %si + incw %si + movw (%si), %bx + orb %bh, %bh /* check unknown label */ + je 3f + xorb 4(%di), %bh + jne 2b + +3: /* end name loop */ + lea nt(%bx), %si + call msg + +4: /* next */ + addw $PARTSZ, %di + loop 1b + + puts(def) + +wait_key: + xorb %ah, %ah + int $0x1a + movw %dx, %di + addw $182*TIMEOUT/10, %di /* ~18.2 ticks per second */ +1: + movb $1, %ah + int $0x16 + jnz 3f + xorb %ah, %ah + int $0x1a + cmpw %di, %dx + jb 1b + +2: /* default key */ + movb dkey, %al + jmp 4f + +3: /* get key */ + xorb %ah, %ah + int $0x16 + shr $8, %ax /* move %ah to %al, %ah zero */ + cmpb $SCAN_ENTER, %al + je 2b + addb $'1'-SCAN_F1, %al + +4: /* test key */ + puts(crlf) + cmpb $'1', %al + jb menu + cmpb $'4', %al + ja menu + + movb %al, dkey + + subb $'1', %al + movb $PARTSZ, %ah + mul %ah + movw %ax, %bx + lea pt(%bx), %si + + cmpb $0x0, 4(%si) + je menu + cmpb $0x5, 4(%si) + je menu + cmpb $0xf, 4(%si) + je menu + + movb $0x80, (%si) /* set active flag */ + + + movw %bp, %dx + movw $0, %es:magic(,1) + movw $0x55aa, %bx + movb $0x41, %ah + int $0x13 + movw %bp, %dx + jc do_chs + cmpw $MBRMAGIC, %bx + jne do_chs + testb $0x01, %cl + jz do_chs +do_lba: + movl 8(%si), %ecx + movl %ecx, lba_sector + pushw %si + movb $0x42, %ah + movw $lba_command, %si + int $0x13 + popw %si + jnc save +do_chs: + movb 1(%si), %dh + movw 2(%si), %cx + movw $0x201, %ax + xorw %bx, %bx + int $0x13 + jnc save + + jmp menu + +save: + pushw %es + movw $RELOCSEG, %ax + movw %ax, %es + movw $0x301, %ax /* write 1 sector */ + xorw %bx, %bx /* put it at %es:0 */ + movw $0x1, %cx /* cylinder 0, sector 1 */ + movw %bp, %dx /* drive #, head 0 */ + int $0x13 + popw %es + + cmpw $MBRMAGIC, %es:magic(,1) + jne menu + ljmp $0, $BOOTSEG << 4 + /* not reached */ + +msg: + pushw %ax + pushw %bx + movw $1, %bx +1: cld + lodsb + pushw %ax + andb $~0x80, %al + movb $0xe, %ah + int $0x10 + popw %ax + testb $0x80, %al + jz 1b + popw %bx + popw %ax + ret + +/* messages */ +crlf: .ascii "\r"; .byte '\n'|0x80 +fkey: .ascii "\r\nF" /* runs into prtnum... */ +prtnum: .byte '0' + .ascii " -"; .byte ' '|0x80 +def: .ascii "\r\n\nDefault: F" /* runs into dkey... */ +dkey: .byte '?'; .byte ' '|0x80 + +/* namen table */ +namtab: + .byte os_dos -nt, 0x01 + .byte os_dos -nt, 0x04 + .byte os_dos -nt, 0x06 + .byte os_win -nt, 0x07 /* NT/XP */ + .byte os_lnx -nt, 0x83 + .byte os_free -nt, 0xa5 + .byte os_open -nt, 0xa6 + .byte os_net -nt, 0xa9 + .byte os_misc -nt, 0x00 +nt: +os_dos: .ascii "DO"; .byte 'S'|0x80 +os_win: .ascii "Window"; .byte 's'|0x80 +os_lnx: .ascii "Linu"; .byte 'x'|0x80 +os_free: .ascii "FreeBS"; .byte 'D'|0x80 +os_open: .ascii "OpenBS"; .byte 'D'|0x80 +os_net: .ascii "NetBS"; .byte 'D'|0x80 +os_misc: .ascii "nonam"; .byte 'e'|0x80 + + . = 0x1a8 +lba_command: + .byte 0x10 /* size of command packet */ + .byte 0x00 /* reserved */ + .word 0x0001 /* sectors to transfer */ + .word 0 /* target buffer, offset */ + .word BOOTSEG /* target buffer, segment */ +lba_sector: + .long 0, 0 /* sector number */ + +/* NT disk signature offset */ + . = 0x1b8 + .space 4, 0 + +/* partition table */ +/* flag, head, sec, cyl, type, ehead, esect, ecyl, start, len */ + . = 0x1be +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 0x0,0,0,0,0,0,0,0 + .long 0,0 + + . = 0x1fe +magic: .short MBRMAGIC + . = 0x200 -- cgit v1.2.3