2 * Mach Operating System
3 * Copyright (c) 1992, 1991 Carnegie Mellon University
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
26 * from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
27 * $FreeBSD: src/sys/boot/pc98/boot2/start.S,v 1.5 2002/05/14 12:34:03 nyan Exp $
28 * $DragonFly: src/sys/boot/pc98/boot2/Attic/start.S,v 1.3 2003/11/10 06:08:38 dillon Exp $
32 Copyright 1988, 1989, 1990, 1991, 1992
33 by Intel Corporation, Santa Clara, California.
37 Permission to use, copy, modify, and distribute this software and
38 its documentation for any purpose and without fee is hereby
39 granted, provided that the above copyright notice appears in all
40 copies and that both the copyright notice and this permission notice
41 appear in supporting documentation, and that the name of Intel
42 not be used in advertising or publicity pertaining to distribution
43 of the software without specific, written prior permission.
45 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
46 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
47 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
48 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
49 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
50 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
51 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54 * Ported to PC-9801 by Yoshio Kimura
62 LOADSZ= 8192 /* size of unix boot */
64 NAMEBLOCKMAGIC= 0xfadefeed /* value of magicnumebr for block2 */
67 * This DEBUGMSG(msg) macro may be useful for debugging. Its use is
68 * restricted to this file since it only works in real mode.
70 #define DEBUGMSG(msg) \
91 /* set up %ss and %esp */
95 * make a little room on the stack for
96 * us to save the default bootstring we might find..
97 * effectively, we push the bootstring.
99 mov $BOOTSTACK-64, %esp
101 /* set up %es, (where we will load boot2 to) */
111 /* set up graphic screen */
118 mov $0x0a00, %eax /* 80 x 25 mode */
121 movb $0x0c, %ah /* text on */
124 /* cursor home and on */
135 /* transfer PC-9801 system common area to 0xa1000 */
143 /* transfer EPSON machine type to 0xa1200 */
148 and $0x00ffffff, %eax
149 mov %eax, %es: (0x1624)
156 /* bootstrap passes */
179 mov %cs: (boot_cyl), %ecx /* actualy %cx in real mode */
186 * BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
187 * Call with %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
190 * %ch = sector size(for floppy) or cylinder(for hard)
194 * %es:%bp = segment:offset of buffer
196 * %ah = 0x0 on success; err code on failure
202 * Load the second sector and see if it is a boot instruction block.
203 * If it is then scan the contents for the first valid string and copy it to
204 * the location of the default boot string.. then zero it out.
205 * Finally write the block back to disk with the zero'd out entry..
206 * I hate writing at this stage but we need this to be persistant.
207 * If the boot fails, then the next boot will get the next string.
208 * /etc/rc will regenerate a complete block2 iff the boot succeeds.
210 * Format of block 2 is:
211 * [NAMEBLOCKMAGIC] <--0xdeafc0de
213 * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.experimental
214 * [bootstring]NULL <---e.g. 0:wd(0,a)/kernel.old
216 * [bootstring]NULL <---e.g. 0:wd(0,f)/kernel
221 * save things we might smash
222 * (that are not smashed immedatly after us anyway.)
225 push %ecx /* preserve 'cyl,sector ' */
229 * Load the second sector
230 * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
231 * Call with %ah = 0x2
232 * %al = number of sectors
236 * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
237 * %es:%bx = segment:offset of buffer
239 * %al = 0x0 on success; err code on failure
242 movl $0x0201, %eax /function 2 (read) 1 sector */
243 xor %ebx, %ebx /* %bx = 0 */ /* buffer address (ES:0) */
245 movl $0x0002, %ecx /* sector 2, cylinder 0 */
247 andl $0x00ff, %edx /* head 0, drive N */
252 * confirm that it is one for us
255 xorl %ebx, %ebx /* magic number at start of buffer */
258 movl %es:(%ebx), %eax
260 cmpl $NAMEBLOCKMAGIC, %eax
262 jne notours /* not ours so return to caller */
264 * scan for a bootstring
265 * Skip the magic number, and scan till we find a non-null,
268 incl %ebx /* quicker and smaller */
274 movb %es:(%ebx), %al /* load the next byte */
275 testb %al, %al /* and if it is null */
276 data32 /* keep scanning (past deleted entries) */
278 incb %al /* now look for -1 */
280 jz notours /* if we reach the 0xFF then we have finished */
283 * save our settings.. we need them twice..
288 * copy it to the default string location
289 * which is just above the stack for 64 bytes.
292 movl $BOOTSTACK-64, %ecx /* 64 bytes at the top of the stack */
295 movb %es:(%ebx), %al /* get the next byte in */
297 movb %al, %es:(%ecx) /* and transfer it to the name buffer */
298 incl %ebx /* get on with the next byte */
299 incl %ecx /* get on with the next byte */
300 testb %al, %al /* if it was 0 then quit this */
302 jnz nxtbyte /* and looop if more to do */
305 * restore the saved settings and
306 * zero it out so next time we don't try it again
309 pop %ebx /* get back our starting location */
310 #ifdef NAMEBLOCK_WRITEBACK
313 movb %es:(%ebx), %al /* get the byte */
315 movb $0, %es:(%ebx) /* zero it out */
317 incl %ebx /* point to the next byte */
318 testb %al, %al /* check if we have finished.. */
322 * Write the second sector back
323 * Load the second sector
324 * BIOS call "INT 0x13 Function 0x3" to write sectors from memory to disk
325 * Call with %ah = 0x3
326 * %al = number of sectors
330 * %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
331 * %es:%bx = segment:offset of buffer
333 * %al = 0x0 on success; err code on failure
336 movl $0x0301, %eax /* write 1 sector */
337 xor %ebx, %ebx /* buffer is at offset 0 */
339 movl $0x0002, %ecx /* block 2 */
341 andl $0xff, %edx /* head 0 */
348 #endif /* NAMEBLOCK_WRITEBACK */
350 * return to the main-line
360 xor %bp, %bp /* %bp = 0, put it at 0 in the BOOTSEG */
365 * ljmp to the second stage boot loader (boot2).
366 * After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
367 * as an internal buffer "intbuf".
372 ljmp $BOOTSEG, $ EXT(boot2)
385 * message: write the error message in %ds:%esi to console
408 lodsb /* load a byte into %al */
415 movb %bl, %es:0x2000(%di)
441 jmp stop /* halt doesnt actually halt forever */
455 #ifdef NAMEBLOCK_WRITEBACK
456 ewrite: String "Write error\r\n\0"
457 #endif /* NAMEBLOCK_WRITEBACK */
458 eread: String "Read error\r\n\0"
459 enoboot: String "No bootable partition\r\n\0"
462 . = EXT(start) + 0x1be
464 /* Partition table */
467 .byte 0x80, 0x00, 0x01, 0x00
468 .byte 0xa5, 0xff, 0xff, 0xff
469 .byte 0x00, 0x00, 0x00, 0x00
470 .byte 0x50, 0xc3, 0x00, 0x00
472 /* the last 2 bytes in the sector 0 contain the signature */
476 . = EXT(start) + 0x400