diff options
author | kato <kato@FreeBSD.org> | 1999-02-03 08:39:09 +0000 |
---|---|---|
committer | kato <kato@FreeBSD.org> | 1999-02-03 08:39:09 +0000 |
commit | c40db6cc734847f5d3013132b80d70a078c16615 (patch) | |
tree | 8460f4832d3da04f82cedbd05be800e5fd9063e4 /sys/boot/pc98/boot2/start.S | |
parent | 850544e5d8903343f0bdde5c29f0147851ea1b4b (diff) | |
download | FreeBSD-src-c40db6cc734847f5d3013132b80d70a078c16615.zip FreeBSD-src-c40db6cc734847f5d3013132b80d70a078c16615.tar.gz |
PC98 version of new boot loader. Because boot2 has not yet ported,
files in boot2 directory are copies from legacy biosboot.
Submitted by: IMAI Takeshi <take-i@ceres.dti.ne.jp>
Diffstat (limited to 'sys/boot/pc98/boot2/start.S')
-rw-r--r-- | sys/boot/pc98/boot2/start.S | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/sys/boot/pc98/boot2/start.S b/sys/boot/pc98/boot2/start.S new file mode 100644 index 0000000..24459cd --- /dev/null +++ b/sys/boot/pc98/boot2/start.S @@ -0,0 +1,535 @@ +/* + * Mach Operating System + * Copyright (c) 1992, 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + * + * from: Mach, Revision 2.2 92/04/04 11:36:29 rpd + * $Id: start.S,v 1.6 1998/07/30 02:27:41 alex Exp $ + */ + +/* + Copyright 1988, 1989, 1990, 1991, 1992 + by Intel Corporation, Santa Clara, California. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appears in all +copies and that both the copyright notice and this permission notice +appear in supporting documentation, and that the name of Intel +not be used in advertising or publicity pertaining to distribution +of the software without specific, written prior permission. + +INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, +NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/* + * Ported to PC-9801 by Yoshio Kimura + */ + +#include "asm.h" + + .file "start.S" + +SIGNATURE= 0xaa55 +LOADSZ= 8192 /* size of unix boot */ + +NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2 */ + +/* + * This DEBUGMSG(msg) macro may be useful for debugging. Its use is + * restricted to this file since it only works in real mode. + */ +#define DEBUGMSG(msg) \ + data32 ; \ + mov $msg, %esi ; \ + data32 ; \ + call message + + .text + .globl start + +ENTRY(boot1) + jmp start + +boot_cyl: + .word 0 + String "IPL1 " + +start: + /* set up %ds */ + xor %ax, %ax + mov %ax, %ds + + /* set up %ss and %esp */ + data32 + mov $BOOTSEG, %eax + mov %ax, %ss + /* + * make a little room on the stack for + * us to save the default bootstring we might find.. + * effectively, we push the bootstring. + */ + data32 + mov $BOOTSTACK-64, %esp + + /* set up %es, (where we will load boot2 to) */ + mov %ax, %es + + push %es + push %cx + push %dx + + data32 + mov $0xa000, %eax + mov %ax, %es + + addr32 + movb 0x501, %al + testb $0x08, %al + jnz hireso +normal: + /* set up graphic screen */ + movb $0x42, %ah + movb $0xc0, %ch + int $0x18 + movb $0x40, %ah + int $0x18 + + data32 + mov $0x0a00, %eax /* 80 x 25 mode */ + jmp 1f +hireso: + movb $0x08, %al /* set up RAM window */ + outb %al, $0x91 + movb $0x0a, %al + outb %al, $0x93 + data32 + mov $0x0a10, %ax /* 80 x 31 mode */ +1: + int $0x18 + movb $0x0c, %ah /* text on */ + int $0x18 + + /* cursor home and on */ + xor %edx, %edx + movb $0x13, %ah + int $0x18 + movb $0x11, %ah + int $0x18 + + /* highreso no supported */ + addr32 + movb 0x501, %al + testb $0x08, %al + jz nothireso + + data32 + mov $ehireso, %esi + data32 + call message + hlt + +nothireso: + /* keyboad reset */ + movb $0x03, %ah + int $0x18 + + /* transfer PC-9801 system common area to 0xa1000 */ + data32 + mov $0x0000, %esi + data32 + mov $0x1000, %edi + data32 + mov $0x0630, %ecx + cld + rep + movsb + + /* transfer EPSON machine type to 0xa1200 */ + push %ds + data32 + mov $0xfd00, %eax + mov %ax, %ds + addr32 + data32 + mov 0x804, %eax + data32 + and $0x00ffffff, %eax + addr32 + data32 + .byte 0x26 + mov %eax, %es: (0x1624) + + pop %ds + pop %dx + pop %cx + pop %es + + /* bootstrap passes */ + mov %cs, %bx + data32 + cmp $0x1fe0, %ebx + jz fd + data32 + cmp $0x1fc0, %ebx + jnz hd + data32 + mov %ebp, %ecx + data32 + mov %ebp, %edx + addr32 + movb 0x584, %al + andb $0xf0, %al + cmpb $0x30, %al + jz fd + cmpb $0x90, %al + jnz hd +fd: + data32 + mov $0x0200, %ecx + data32 + mov $0x0001, %edx + movb $0xd6, %ah + jmp load +hd: + data32 + and %ecx, %ecx + jnz 1f + addr32 + data32 + mov %cs: (boot_cyl), %ecx +1: + movb $0x06, %ah + +/* + * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory + * Call with %ah = 0xd6(for floppy disk) or 0x06(for hard disk) + * %al = DA/UA + * %bx = data length + * %ch = sector size(for floppy) or cylinder(for hard) + * %cl = cylinder + * %dh = head + * %dl = sector + * %es:%bp = segment:offset of buffer + * Return: + * %ah = 0x0 on success; err code on failure + */ + +load: +#ifdef NAMEBLOCK +/* + * Load the second sector and see if it is a boot instruction block. + * If it is then scan the contents for the first valid string and copy it to + * the location of the default boot string.. then zero it out. + * Finally write the block back to disk with the zero'd out entry.. + * I hate writing at this stage but we need this to be persistant. + * If the boot fails, then the next boot will get the next string. + * /etc/rc will regenerate a complete block2 iff the boot succeeds. + * + * Format of block 2 is: + * [NAMEBLOCKMAGIC] <--0xdeafc0de + * [nulls] + * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.experimental + * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.old + * .... + * [bootstring]NULL <---e.g. 0:wd(0,f)/kernel + * FF FF FF + */ +where: + /* + * save things we might smash + * (that are not smashed immedatly after us anyway.) + */ + data32 + push %ecx /* preserve 'cyl,sector ' */ + data32 + push %edx +/* + * Load the second sector + * 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 $0x0201, %eax /function 2 (read) 1 sector */ + xor %ebx, %ebx /* %bx = 0 */ /* buffer address (ES:0) */ + data32 + movl $0x0002, %ecx /* sector 2, cylinder 0 */ + data32 + andl $0x00ff, %edx /* head 0, drive N */ + int $0x13 + data32 + jb read_error + /* + * confirm that it is one for us + */ + data32 + xorl %ebx, %ebx /* magic number at start of buffer */ + data32 + addr32 + movl %es:(%ebx), %eax + data32 + cmpl $NAMEBLOCKMAGIC, %eax + data32 + jne notours /* not ours so return to caller */ + /* + * scan for a bootstring + * Skip the magic number, and scan till we find a non-null, + * or a -1 + */ + incl %ebx /* quicker and smaller */ + incl %ebx + incl %ebx +scan: + incl %ebx + addr32 + movb %es:(%ebx), %al /* load the next byte */ + testb %al, %al /* and if it is null */ + data32 /* keep scanning (past deleted entries) */ + jz scan + incb %al /* now look for -1 */ + data32 + jz notours /* if we reach the 0xFF then we have finished */ + + /* + * save our settings.. we need them twice.. + */ + data32 + push %ebx + /* + * copy it to the default string location + * which is just above the stack for 64 bytes. + */ + data32 + movl $BOOTSTACK-64, %ecx /* 64 bytes at the top of the stack */ +nxtbyte: + addr32 + movb %es:(%ebx), %al /* get the next byte in */ + addr32 + movb %al, %es:(%ecx) /* and transfer it to the name buffer */ + incl %ebx /* get on with the next byte */ + incl %ecx /* get on with the next byte */ + testb %al, %al /* if it was 0 then quit this */ + data32 + jnz nxtbyte /* and looop if more to do */ + + /* + * restore the saved settings and + * zero it out so next time we don't try it again + */ + data32 + pop %ebx /* get back our starting location */ +#ifdef NAMEBLOCK_WRITEBACK +nxtbyte2: + addr32 + movb %es:(%ebx), %al /* get the byte */ + addr32 + movb $0, %es:(%ebx) /* zero it out */ + data32 + incl %ebx /* point to the next byte */ + testb %al, %al /* check if we have finished.. */ + data32 + jne nxtbyte2 +/* + * Write the second sector back + * Load the second sector + * BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk + * Call with %ah = 0x3 + * %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 $0x0301, %eax /* write 1 sector */ + xor %ebx, %ebx /* buffer is at offset 0 */ + data32 + movl $0x0002, %ecx /* block 2 */ + data32 + andl $0xff, %edx /* head 0 */ + int $0x13 + data32 + jnb notours + data32 + mov $eread, %esi + jmp err_stop +#endif /* NAMEBLOCK_WRITEBACK */ + /* + * return to the main-line + */ +notours: + data32 + pop %edx + data32 + pop %ecx +#endif + data32 + mov $LOADSZ, %ebx + addr32 + movb 0x584, %al + xor %ebp, %ebp /* %bp = 0, put it at 0 in the BOOTSEG */ + int $0x1b + jc read_error + + /* + * ljmp to the second stage boot loader (boot2). + * After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used + * as an internal buffer "intbuf". + */ + + data32 + ljmp $BOOTSEG, $ EXT(boot2) + +/* + * read_error + */ +read_error: + data32 + mov $eread, %esi +err_stop: + data32 + call message + data32 + jmp stop + +/* + * message: write the error message in %ds:%esi to console + */ +message: + + data32 + push %eax + data32 + push %ebx + push %ds + push %es + data32 + mov $0xe000, %eax + mov %ax, %es + addr32 + mov 0x501, %al + testb $0x08, %al + jnz 1f + data32 + mov $0xa000, %eax + mov %ax, %es +1: + mov %cs, %ax + mov %ax, %ds + addr32 + data32 + mov vram, %edi + data32 + mov $0x00e1, %ebx + cld + +nextb: + lodsb /* load a byte into %al */ + cmpb $0x0, %al + je done + cmpb $0x0d, %al + je cr_code + cmpb $0x0a, %al + je lf_code + addr32 + movb %al, (%edi) + addr32 + movb %bl, 0x2000(%edi) + data32 + inc %edi + data32 + inc %edi + jmp nextb +cr_code: + data32 + add $80, %edi + jmp nextb +lf_code: + data32 + mov %edi, %eax + data32 + mov $80, %edx + data32 + div %ebx + data32 + sub %ebx, %edi + jmp nextb +done: + addr32 + data32 + mov %edi, vram + pop %es + pop %ds + data32 + pop %ebx + data32 + pop %eax + data32 + ret + +stop: hlt + data32 + jmp stop /* halt doesnt actually halt forever */ + +vram: + .long 0 + +/* error messages */ + + +#ifdef DEBUG +one: String "1-\0" +two: String "2-\0" +three: String "3-\0" +four: String "4-\0" +#endif DEBUG +#ifdef NAMEBLOCK_WRITEBACK +ewrite: String "Write error\r\n\0" +#endif /* NAMEBLOCK_WRITEBACK */ +eread: String "Read error\r\n\0" +enoboot: String "No bootable partition\r\n\0" +endofcode: +ehireso: String "Highreso not supported\r\n\0" +/* the last 2 bytes in the sector 0 contain the signature */ + . = EXT(boot1) + 0x1fe + .value SIGNATURE +ENTRY(disklabel) + . = EXT(boot1) + 0x400 |