Index: stable/4/sys/boot/pc98/boot2/Makefile =================================================================== --- stable/4/sys/boot/pc98/boot2/Makefile (revision 84617) +++ stable/4/sys/boot/pc98/boot2/Makefile (revision 84618) @@ -1,97 +1,92 @@ # $FreeBSD$ # PROG= boot # Order is very important on the SRCS line for this prog SRCS= start.S table.c boot2.S boot.c asm.S bios.S serial.S SRCS+= probe_keyboard.c io.c disk.c sys.c BINDIR= /boot BINMODE= 444 -CFLAGS= -Os -malign-functions=0 -malign-jumps=0 -malign-loops=0 \ +CFLAGS= -elf -Os -fno-builtin -fforce-addr -fdata-sections \ + -malign-functions=0 -malign-jumps=0 -malign-loops=0 \ -mpreferred-stack-boundary=2 -mrtd \ -DPC98 -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT} CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK} CFLAGS+= ${CWARNFLAGS} -CFLAGS+= -I${.CURDIR}/../../.. -aout +CFLAGS+= -I${.CURDIR}/../../.. # By default, if a serial port is going to be used as console, use COM1 # (aka /dev/ttyd0). #BOOT_COMCONSOLE_PORT?=0x30 BOOT_COMCONSOLE_PORT?=0x238 BOOT_COMCONSOLE_CLK?=16 BOOT_COMCONSOLE_MODE=0x0c CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \ -DCOMCONSOLE_CLK=${BOOT_COMCONSOLE_CLK} \ -DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE} # feature not implemented BOOT_COMCONSOLE_SPEED?=9600 CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED} # Enable code to take the default boot string from a fixed location on the # disk. See nextboot(8) and README.386BSD for more info. #CFLAGS+= -DNAMEBLOCK #CFLAGS+= -DNAMEBLOCK_WRITEBACK # Bias the conversion from the BIOS drive number to the FreeBSD unit number # for hard disks. This may be useful for people booting in a mixed IDE/SCSI # environment (set BOOT_HD_BIAS to the number of IDE drives). #CFLAGS+= -DBOOT_HD_BIAS=1 # # Details: this only applies if BOOT_HD_BIAS > 0. If the BIOS drive number # for the boot drive is >= BOOT_HD_BIAS, then the boot drive is assumed to # be SCSI and have unit number (BIOS_drive_number - BOOT_HD_BIAS). E.g., # BOOT_HD_BIAS=1 makes BIOS drive 1 correspond to 1:da(0,a) instead of # 1:wd(1,a). If `da' is given explicitly, then the drive is assumed to be # SCSI and have BIOS drive number (da_unit_number + BOOT_HD_BIAS). E.g., # BOOT_HD_BIAS=1 makes da(0,a) correspond to 1:da(0,a) instead of 0:da(0,a). CLEANFILES+= boot.nohdr boot.strip boot1 boot2 sizetest -LDFLAGS+= -N -T 0 -nostdlib +LDFLAGS+= -N -Ttext 0 -nostdlib -e start NOSHARED= YES NOMAN= STRIP= # tunable timeout parameter, waiting for keypress, calibrated in ms BOOTWAIT?= 5000 # tunable timeout during string input, calibrated in ms #TIMEOUT?= 30000 # Location that boot2 is loaded at BOOTSEG= 0x1000 # Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned BOOTSTACK= 0xFFF0 -boot.strip: boot - cp -p boot boot.strip - strip -aout boot.strip - size -aout boot.strip - -boot.nohdr: boot.strip - dd if=boot.strip of=boot.nohdr ibs=32 skip=1 obs=1024b +boot.nohdr: boot + objcopy -S -O binary boot boot.nohdr ls -l boot.nohdr boot1: boot.nohdr dd if=boot.nohdr of=boot1 bs=512 count=1 boot2: boot.nohdr dd if=boot.nohdr of=boot2 bs=512 skip=1 @dd if=boot2 skip=14 of=sizetest 2> /dev/null @if [ -s sizetest ] ; then \ echo "boot2 is too big" >&2 ; \ rm boot2 ; \ exit 2 ; \ fi all: boot1 boot2 install: ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \ boot1 boot2 ${DESTDIR}${BINDIR} - .include .include Index: stable/4/sys/boot/pc98/boot2/asm.S =================================================================== --- stable/4/sys/boot/pc98/boot2/asm.S (revision 84617) +++ stable/4/sys/boot/pc98/boot2/asm.S (revision 84618) @@ -1,244 +1,258 @@ /* * 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:34:13 rpd * $FreeBSD$ */ /* 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. */ .file "asm.s" #include "asm.h" CR0_PE_ON = 0x1 CR0_PE_OFF = 0xfffffffe - + .code16 .text /* * * real_to_prot() * transfer from real mode to protected mode. */ ENTRY(real_to_prot) /* guarantee that interrupt is disabled when in prot mode */ cli /* load the gdtr */ + .code32 addr32 data32 lgdt EXT(Gdtr) + .code16 /* set the PE bit of CR0 */ mov %cr0, %eax - data32 or $CR0_PE_ON, %eax mov %eax, %cr0 /* * make intrasegment jump to flush the processor pipeline and * reload CS register */ + .code32 data32 ljmp $0x18, $xprot + .code16 xprot: /* * we are in USE32 mode now * set up the protected mode segment registers : DS, SS, ES, FS */ + data32 movw $0x20, %ax /* data segment */ mov %ax, %ds /* gas would waste a prefix byte for movw */ mov %ax, %ss mov %ax, %es + data32 movw $0x10, %ax /* flat segment */ mov %ax, %fs #ifdef BDE_DEBUGGER /* load idtr so we can debug */ lidt EXT(Idtr_prot) #endif ret /* * * prot_to_real() * transfer from protected mode to real mode * */ ENTRY(prot_to_real) /* Prepare %ax while we're still in a mode that gas understands. */ + data32 movw $0x30, %ax /* Change to use16 mode. */ + .code32 ljmp $0x28, $x16 + .code16 x16: mov %ax, %ds mov %ax, %ss mov %ax, %es mov %ax, %fs /* clear the PE bit of CR0 */ mov %cr0, %eax - data32 and $CR0_PE_OFF, %eax mov %eax, %cr0 /* * make intersegment jmp to flush the processor pipeline * and reload CS register */ + .code32 data32 ljmp $BOOTSEG, $xreal + .code16 xreal: /* * we are in real mode now * set up the real mode segment registers : DS, SS, ES, FS */ mov %cs, %ax mov %ax, %ds mov %ax, %ss mov %ax, %es mov %ax, %fs #ifdef BDE_DEBUGGER /* load idtr so we can debug */ addr32 data32 lidt EXT(Idtr_real) #endif data32 ret /* * startprog(phyaddr) * start the program on protected mode where phyaddr is the entry point * * XXX This whole mess should go away and we should run the boot code in * flat 32 bit mode with it linked -T BOOTSEG. See the netboot code for * how this is done. */ ENTRY(startprog) + .code32 push %ebp mov %esp, %ebp movl %esp, %eax /* Use eax as the old stack pointer */ /* convert the current stack to a 32 bit flat model */ movw $0x10, %bx + data32 mov %bx, %ss addl $(BOOTSEG<<4),%esp /* copy the arguments from the old stack to the new stack */ pushl 0x14(%eax) /* &bootinfo */ pushl $0 /* was &nfsdiskless */ pushl $0 /* was esym */ pushl $0 /* was cyloffset */ pushl 0x10(%eax) /* bootdev */ pushl 0x0C(%eax) /* howto */ movl $(ourreturn),%ebx addl $(BOOTSEG<<4),%ebx /* Fix it up for flat segments */ pushl %ebx /* our return address */ /* push on our entry address */ pushl $0x08 /* segment selector */ pushl 0x08(%eax) /* kernel entry address */ /* convert over the other data segs */ movw $0x10, %bx + data32 mov %bx, %ds + data32 mov %bx, %es /* convert the PC (and code seg) */ lret ourreturn: /* For now there is not much we can do, just lock in a loop */ jmp ourreturn /* * pcpy(src, dst, cnt) * where src is a virtual address and dst is a physical address */ ENTRY(pcpy) + .code32 push %ebp mov %esp, %ebp push %es push %esi push %edi push %ecx cld /* set %es to point at the flat segment */ movw $0x10, %ax mov %ax, %es mov 0x8(%ebp), %esi /* source */ mov 0xc(%ebp), %edi /* destination */ mov 0x10(%ebp), %ecx /* count */ rep movsb pop %ecx pop %edi pop %esi pop %es pop %ebp ret Index: stable/4/sys/boot/pc98/boot2/asm.h =================================================================== --- stable/4/sys/boot/pc98/boot2/asm.h (revision 84617) +++ stable/4/sys/boot/pc98/boot2/asm.h (revision 84618) @@ -1,144 +1,144 @@ /* * Mach Operating System * Copyright (c) 1991,1990,1989 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.7 92/02/29 15:33:41 rpd * $FreeBSD$ */ #define S_ARG0 4(%esp) #define S_ARG1 8(%esp) #define S_ARG2 12(%esp) #define S_ARG3 16(%esp) #define FRAME pushl %ebp; movl %esp, %ebp #define EMARF leave #define B_ARG0 8(%ebp) #define B_ARG1 12(%ebp) #define B_ARG2 16(%ebp) #define B_ARG3 20(%ebp) #ifdef wheeze #define ALIGN 4 #define EXT(x) x #define LEXT(x) x: #define LCL(x) ./**/x #define LB(x,n) ./**/x #define LBb(x,n) ./**/x #define LBf(x,n) ./**/x #define SVC lcall $7,$0 #define String .string #define Value .value #define Times(a,b) [a\*b] #define Divide(a,b) [a\\b] #define INB inb (%dx) #define OUTB outb (%dx) #define INL inl (%dx) #define OUTL outl (%dx) #else wheeze #define ALIGN #define LCL(x) x #define LB(x,n) n #ifdef __STDC__ -#define EXT(x) _ ## x -#define LEXT(x) _ ## x ## : +#define EXT(x) x +#define LEXT(x) x ## : #define LBb(x,n) n ## b #define LBf(x,n) n ## f #else __STDC__ #define EXT(x) _/**/x #define LEXT(x) _/**/x/**/: #define LBb(x,n) n/**/b #define LBf(x,n) n/**/f #endif __STDC__ #define SVC .byte 0x9a; .long 0; .word 0x7 #define String .ascii #define Value .word #define Times(a,b) (a*b) #define Divide(a,b) (a/b) #define INB inb %dx, %al #define OUTB outb %al, %dx #define INL inl %dx, %eax #define OUTL outl %eax, %dx #endif wheeze #define addr32 .byte 0x67 #define data32 .byte 0x66 #ifdef GPROF #ifdef __STDC__ #define MCOUNT .data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount #define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ .align ALIGN; LEXT(x) LEXT(y) ; \ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; #define ASENTRY(x) .globl x; .align ALIGN; x ## : ; \ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; #else __STDC__ #define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount #define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ .align ALIGN; LEXT(x) LEXT(y) #define ASENTRY(x) .globl x; .align ALIGN; x: ; \ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; #endif __STDC__ #else GPROF #ifdef __STDC__ #define MCOUNT #define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ .align ALIGN; LEXT(x) LEXT(y) #define ASENTRY(x) .globl x; .align ALIGN; x ## : #else __STDC__ #define MCOUNT #define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) #define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ .align ALIGN; LEXT(x) LEXT(y) #define ASENTRY(x) .globl x; .align ALIGN; x: #endif __STDC__ #endif GPROF #define Entry(x) .globl EXT(x); .align ALIGN; LEXT(x) #define DATA(x) .globl EXT(x); .align ALIGN; LEXT(x) Index: stable/4/sys/boot/pc98/boot2/bios.S =================================================================== --- stable/4/sys/boot/pc98/boot2/bios.S (revision 84617) +++ stable/4/sys/boot/pc98/boot2/bios.S (revision 84618) @@ -1,456 +1,466 @@ /* * 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:34:26 rpd * $FreeBSD$ */ /* 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 */ /* * Extensions for El Torito CD-ROM booting: * * Copyright © 1997 Pluto Technologies International, Inc. Boulder CO * Copyright © 1997 interface business GmbH, Dresden. * All rights reserved. * * This code has been written by Jörg Wunsch, Dresden. * Direct comments to . * * 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(S) ``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 AUTHOR(S) 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. * */ .file "bios.s" #include "asm.h" .text #ifndef CDBOOT /* * biosread(dev, cyl, head, sec, nsec, offset) * Read "nsec" sectors from disk to offset "offset" in boot segment * 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: * %al = 0x0 on success; err code on failure */ ENTRY(biosread) + .code32 push %ebp mov %esp, %ebp push %ebx push %esi push %edi movb 0x14(%ebp), %dl /* sector */ movb 0x10(%ebp), %dh /* head */ movw 0x0c(%ebp), %cx /* cylinder */ movb 0x08(%ebp), %al /* DA/UA */ movb $0x06, %ah andb $0xf0, %al cmpb $0x30, %al jz fd cmpb $0x90, %al jnz 1f fd: incb %dl movb $0x02, %ch movb $0xd6, %ah 1: movb 0x08(%ebp), %al movl %eax, %ebx /* prot_to_real will set %es to BOOTSEG */ call EXT(prot_to_real) /* enter real mode */ mov %ebx, %eax xor %ebx, %ebx addr32 movb 0x18(%ebp), %bl /* number of sectors */ - data32 + .code16 shl $9, %ebx - data32 push %ebx + .code32 addr32 data32 mov 0x1c(%ebp), %ebx - data32 + .code16 mov %ebx, %ebp - data32 pop %ebx int $0x1b jc 1f + .code32 xor %eax, %eax 1: /* save return value (actually movw %ax, %bx) */ mov %eax, %ebx data32 call EXT(real_to_prot) /* back to protected mode */ xor %eax, %eax movb %bh, %al /* return value in %ax */ pop %edi pop %esi pop %ebx pop %ebp ret #else /* CDBOOT */ /* * int * getbootspec(struct specpacket *offset) * * Read CD-ROM boot specification packet to "offset". */ ENTRY(getbootspec) push %ebp mov %esp, %ebp push %esi push %ebx movw 0x8(%ebp), %si mov $0x7f, %edx /* prot_to_real will set %es to BOOTSEG */ call EXT(prot_to_real) /* enter real mode */ movw $0x4b01, %ax /* (do not) terminate disk emulation */ movb $0x7f, %dl /* any drive */ sti int $0x13 cli /* save return value (actually movw %ax, %bx) */ mov %eax, %ebx data32 call EXT(real_to_prot) /* back to protected mode */ xor %eax, %eax movb %bh, %al /* return value in %ax */ pop %ebx pop %esi pop %ebp ret /* * int * biosreadlba(struct daddrpacket *daddr) * Read sectors using the BIOS "read extended" function * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory * Call with %ah = 0x42 * %dl = drive (0x0 for floppy disk, or emulated CD) * %ds:%si = ptr to disk address packet * Return: * %ah = 0x0 on success; err code on failure */ ENTRY(biosreadlba) push %ebp mov %esp, %ebp push %ebx push %esi movw 8(%ebp), %si movl $0, %edx /* emulated CD is always drive 0 */ /* prot_to_real will set %es to BOOTSEG */ call EXT(prot_to_real) /* enter real mode */ movw $0x4200, %ax /* subfunction */ movb $0, %dl sti int $0x13 cli /* save return value (actually movw %ax, %bx) */ mov %eax, %ebx data32 call EXT(real_to_prot) /* back to protected mode */ xor %eax, %eax movb %bh, %al /* return value in %ax */ pop %esi pop %ebx pop %ebp ret #endif /* !CDBOOT */ /* * getc() * BIOS call "INT 18H Function 00H" to read character from keyboard * Call with %ah = 0x0 * Return: %ah = keyboard scan code * %al = ASCII character */ ENTRY(getc) + .code32 push %ebp mov %esp, %ebp push %ebx /* save %ebx */ push %esi push %edi call EXT(prot_to_real) + .code16 movb $0x0, %ah int $0x18 movb %al, %bl /* real_to_prot uses %eax */ + .code32 data32 call EXT(real_to_prot) xor %eax, %eax movb %bl, %al pop %edi pop %esi pop %ebx pop %ebp ret /* * ischar() * if there is a character pending, return it; otherwise return 0 * BIOS call "INT 18H Function 01H" to check whether a character is pending * Call with %ah = 0x1 * Return: * If key waiting to be input: * %ah = keyboard scan code * %al = ASCII character * %bh = 1 * else * %bh = 0 */ ENTRY(ischar) + .code32 push %ebp mov %esp, %ebp push %ebx push %esi push %edi call EXT(prot_to_real) /* enter real mode */ xor %ebx, %ebx + .code16 movb $0x1, %ah int $0x18 andb %bh, %bh data32 jz nochar movb %al, %bl nochar: + .code32 data32 call EXT(real_to_prot) xor %eax, %eax movb %bl, %al pop %edi pop %esi pop %ebx pop %ebp ret /* * * get_diskinfo(): return a word that represents the * max number of sectors and heads and drives for this device * */ ENTRY(get_diskinfo) + .code32 push %ebp mov %esp, %ebp push %ebx push %esi push %edi movb 0x8(%ebp), %dl /* diskinfo(drive #) */ call EXT(prot_to_real) /* enter real mode */ + .code16 movb %dl, %al /* ask for disk info */ andb $0xf0, %al cmpb $0x30, %al jz fdd4 cmpb $0x90, %al jz fdd movb %dl, %al movb $0x84, %ah int $0x1b jnc ok /* * Urk. Call failed. It is not supported for floppies by old BIOS's. * Guess it's a 15-sector floppy. */ fdd4: movb $18, %dl jmp 1f fdd: movb $15, %dl /* max sector */ 1: subb %ah, %ah /* %ax = 0 */ movb %al, %al movb %ah, %bh /* %bh = 0 */ movb $2, %bl /* %bl bits 0-3 = drive type, bit 2 = 1.2M */ movb $79, %ch /* max track */ movb $1, %cl /* # floppy drives installed */ movb $2, %dh /* max head */ /* es:di = parameter table */ /* carry = 0 */ ok: - + .code32 data32 call EXT(real_to_prot) /* back to protected mode */ /* * form a longword representing all this gunk: * 16 bit cylinder * 8 bit head * 8 bit sector */ mov %ecx, %eax sall $16,%eax /* << 16 */ movb %dh, %ah /* max head */ movb %dl, %al /* max sector (and # sectors) */ pop %edi pop %esi pop %ebx pop %ebp ret /* * * memsize(i) : return the memory size in KB. i == 0 for conventional memory, * i == 1 for extended memory * Both have the return value in AX. * */ ENTRY(memsize) + .code32 push %ebp mov %esp, %ebp push %ebx push %esi push %edi mov 8(%ebp), %ebx xor %eax, %eax cmpb $0x01, %bl jnz memcnv memext: movb 0xA1401 - BOOTSEG * 0x10, %al shll $7, %eax xorl %ebx, %ebx movw 0xA1594 - BOOTSEG * 0x10, %bx shll $10, %ebx addl %ebx, %eax jmp xdone memcnv: movb 0xA1501 - BOOTSEG * 0x10, %al andb $0x07, %al incl %eax shll $7, %eax xdone: pop %edi pop %esi pop %ebx pop %ebp ret Index: stable/4/sys/boot/pc98/boot2/boot2.S =================================================================== --- stable/4/sys/boot/pc98/boot2/boot2.S (revision 84617) +++ stable/4/sys/boot/pc98/boot2/boot2.S (revision 84618) @@ -1,184 +1,184 @@ /* * 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:35:26 rpd * boot2.S,v 1.6 1995/01/25 21:37:40 bde Exp * $FreeBSD$ */ /* * Ported to PC-9801 by Yoshio Kimura */ #include "asm.h" /* Conventional GDT indexes. */ #define BOOT_CS_INDEX 3 #define BOOT_CS16_INDEX 5 #define BOOT_DS_INDEX 4 #ifdef BDE_DEBUGGER #define DB_CS_INDEX 14 #define DB_CS16_INDEX 15 #define DB_DS_INDEX 16 #define GDT_INDEX 17 #endif /* Vector numbers. */ #define BREAKPOINT_VECTOR 3 #define DEBUG_VECTOR 1 /* * boot2() -- second stage boot * SP points to default string if found */ - + .code16 ENTRY(boot2) - data32 subl %eax, %eax mov %cs, %ax mov %ax, %ds mov %ax, %es - data32 shll $4, %eax /* fix up GDT entries for bootstrap */ #define FIXUP(gdt_index) \ + .code32; \ addr32; \ movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \ addr32; \ - movb %bl, EXT(Gdt)+(8*gdt_index)+4 + movb %bl, EXT(Gdt)+(8*gdt_index)+4; \ + .code16 - data32 shld $16, %eax, %ebx FIXUP(BOOT_CS_INDEX) FIXUP(BOOT_CS16_INDEX) FIXUP(BOOT_DS_INDEX) /* fix up GDT pointer */ - data32 movl %eax, %ecx - data32 addl $ EXT(Gdt), %eax + .code32 addr32 data32 movl %eax, EXT(Gdtr)+2 + .code16 #ifdef BDE_DEBUGGER /* fix up GDT entry for GDT */ data32 shld $16, %eax, %ebx FIXUP(GDT_INDEX) /* fix up IDT pointer */ data32 addl $ EXT(Idt), %ecx addr32 data32 movl %ecx, EXT(Idtr_prot)+2 /* %es = vector table segment for a while */ push %es data32 subl %eax, %eax mov %ax, %es /* fix up GDT entries for bdb */ data32 movl $4*DEBUG_VECTOR, %esi addr32 movl %es: 2(%esi), %eax /* actually movw to %ax */ data32 shll $4, %eax data32 shld $16, %eax, %ebx FIXUP(DB_CS_INDEX) FIXUP(DB_CS16_INDEX) FIXUP(DB_DS_INDEX) /* Fetch entry points of bdb's protected mode trap handlers. These * are stored at 2 before the corresponding entry points for real mode. */ data32 subl %ebx, %ebx addr32 movl %es: (%esi), %ebx /* actually movw to %bx */ data32 subl %ecx, %ecx addr32 movl %es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx /* actually movw to %cx */ /* %es = bdb segment for a while */ data32 shrl $4, %eax mov %ax, %es /* fix up IDT entries for bdb */ data32 subl $2, %ebx /* calculate EA to check it */ jb 1f /* give up if it would trap */ addr32 movl %es: (%ebx), %eax /* actually movw to %ax */ addr32 movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */ 1: data32 subl $2, %ecx jb 1f addr32 movl %es: (%ecx), %eax /* actually movw to %ax */ addr32 movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */ 1: /* finished with groping in real mode segments */ pop %es #endif /* BDE_DEBUGGER */ /* change to protected mode */ + .code32 data32 call EXT(real_to_prot) /* clear the bss */ movl $ EXT(edata), %edi /* no EXT(_edata) - krufty ld */ movl $ EXT(end), %ecx /* or EXT(_end) */ subl %edi, %ecx subb %al, %al rep stosb #ifdef NAMEBLOCK movl %esp, EXT(dflt_name) #endif #ifdef PC98 movb 0xA1584 - BOOTSEG * 0x10, %dl #endif movzbl %dl, %edx /* discard head (%dh) and random high bits */ pushl %edx call EXT(boot) oops: hlt jmp oops Index: stable/4/sys/boot/pc98/boot2/io.c =================================================================== --- stable/4/sys/boot/pc98/boot2/io.c (revision 84617) +++ stable/4/sys/boot/pc98/boot2/io.c (revision 84618) @@ -1,429 +1,429 @@ /* * 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:35:57 rpd * $FreeBSD$ */ #include "boot.h" #include #include #ifdef PC98 #include #endif static int getchar(int in_buf); /* * Gate A20 for high memory */ void gateA20(void) { outb(0xf2, 0x00); outb(0xf6, 0x02); } /* printf - only handles %d as decimal, %c as char, %s as string */ void printf(const char *format, ...) { int *dataptr = (int *)&format; char c; dataptr++; while ((c = *format++)) if (c != '%') putchar(c); else switch (c = *format++) { case 'd': { int num = *dataptr++; char buf[10], *ptr = buf; if (num<0) { num = -num; putchar('-'); } do *ptr++ = '0'+num%10; while (num /= 10); do putchar(*--ptr); while (ptr != buf); break; } case 'x': { unsigned int num = *dataptr++, dig; char buf[8], *ptr = buf; do *ptr++ = (dig=(num&0xf)) > 9? 'a' + dig - 10 : '0' + dig; while (num >>= 4); do putchar(*--ptr); while (ptr != buf); break; } case 'c': putchar((*dataptr++)&0xff); break; case 's': { char *ptr = (char *)*dataptr++; while ((c = *ptr++)) putchar(c); break; } } } void putchar(int c) { if (c == '\n') putchar('\r'); if (loadflags & RB_DUAL) { putc(c); serial_putc(c); } else if (loadflags & RB_SERIAL) serial_putc(c); else putc(c); } static int getchar(int in_buf) { int c; loop: if (loadflags & RB_DUAL) { if (ischar()) c = getc(); else if (serial_ischar()) c = serial_getc(); else goto loop; } else if (loadflags & RB_SERIAL) c = serial_getc(); else c = getc(); if (c == '\r') c = '\n'; if (c == '\b') { if (in_buf != 0) { putchar('\b'); putchar(' '); } else { goto loop; } } putchar(c); return(c); } /* * This routine uses an inb to an unused port, the time to execute that * inb is approximately 1.25uS. This value is pretty constant across * all CPU's and all buses, with the exception of some PCI implentations - * that do not forward this I/O adress to the ISA bus as they know it + * that do not forward this I/O address to the ISA bus as they know it * is not a valid ISA bus address, those machines execute this inb in * 60 nS :-(. * * XXX this should be converted to use bios_tick. */ void delay1ms(void) { #ifdef PC98 int i = 800; while (--i >= 0) (void)outb(0x5f,0); /* about 600ns */ #else int i = 800; while (--i >= 0) (void)inb(0x84); #endif } static __inline int isch(void) { int isc; /* * Checking the keyboard has the side effect of enabling clock * interrupts so that bios_tick works. Check the keyboard to * get this side effect even if we only want the serial status. */ isc = ischar(); if (loadflags & RB_DUAL) { if (isc != 0) return (isc); } else if (!(loadflags & RB_SERIAL)) return (isc); return (serial_ischar()); } static __inline unsigned pword(unsigned physaddr) { #ifdef PC98 static int counter = 0; int i; for (i = 0; i < 512; i++) (void)outb(0x5f, 0); return (counter++); #else unsigned result; /* * Give the fs prefix separately because gas omits it for * "movl %fs:0x46c, %eax". */ __asm __volatile("fs; movl %1, %0" : "=r" (result) : "m" (*(unsigned *)physaddr)); return (result); #endif } int gets(char *buf) { #define bios_tick pword(0x46c) #ifdef PC98 #define BIOS_TICK_MS 1 #else #define BIOS_TICK_MS 55 #endif unsigned initial_bios_tick; char *ptr=buf; #if BOOTWAIT for (initial_bios_tick = bios_tick; bios_tick - initial_bios_tick < BOOTWAIT / BIOS_TICK_MS;) #endif if (isch()) for (;;) { switch(*ptr = getchar(ptr - buf) & 0xff) { case '\n': case '\r': *ptr = '\0'; return 1; case '\b': if (ptr > buf) ptr--; continue; default: ptr++; } #if TIMEOUT + 0 #if !BOOTWAIT #error "TIMEOUT without BOOTWAIT" #endif for (initial_bios_tick = bios_tick;;) { if (isch()) break; if (bios_tick - initial_bios_tick >= TIMEOUT / BIOS_TICK_MS) return 0; } #endif } return 0; } int strcmp(const char *s1, const char *s2) { while (*s1 == *s2) { if (!*s1++) return 0; s2++; } return 1; } #ifdef CDBOOT int strcasecmp(const char *s1, const char *s2) { /* * We only consider ASCII chars and don't anticipate * control characters (they are invalid in filenames * anyway). */ while ((*s1 & 0x5f) == (*s2 & 0x5f)) { if (!*s1++) return 0; s2++; } return 1; } #endif /* !CDBOOT */ void bcopy(const void *from, void *to, size_t len) { char *fp = (char *)from; char *tp = (char *)to; while (len-- > 0) *tp++ = *fp++; } /* To quote Ken: "You are not expected to understand this." :) */ void twiddle(void) { putchar((char)tw_chars); tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24); putchar('\b'); } static unsigned short *Crtat = (unsigned short *)0; static int row; static int col; void putc(int c) { static unsigned short *crtat; unsigned char sys_type; unsigned short *cp; int i, pos; if (Crtat == 0) { sys_type = *(unsigned char *)V(0xA1501); if (sys_type & 0x08) { Crtat = (unsigned short *)V(0xE0000); crtat = Crtat; row = 31; col = 80; } else { Crtat = (unsigned short *)V(0xA0000); crtat = Crtat; row = 25; col = 80; } } switch(c) { case '\t': do { putc(' '); } while ((int)crtat % 16); break; case '\b': crtat--; break; case '\r': crtat -= (crtat - Crtat) % col; break; case '\n': crtat += col; break; default: *crtat = (c == 0x5c ? 0xfc : c); *(crtat++ + 0x1000) = 0xe1; break; } if (crtat >= Crtat + col * row) { cp = Crtat; for (i = 1; i < row; i++) { bcopy((void *)(cp+col), (void *)cp, col*2); cp += col; } for (i = 0; i < col; i++) { *cp++ = ' '; } crtat -= col; } pos = crtat - Crtat; while((inb(0x60) & 0x04) == 0) {} outb(0x62, 0x49); outb(0x60, pos & 0xff); outb(0x60, pos >> 8); } void machine_check(void) { int ret; int i; int data = 0; u_char epson_machine_id = *(unsigned char *)V(0xA1624); /* PC98_SYSTEM_PARAMETER(0x501) */ ret = ((*(unsigned char*)V(0xA1501)) & 0x08) >> 3; /* Wait V-SYNC */ while (inb(0x60) & 0x20) {} while (!(inb(0x60) & 0x20)) {} /* ANK 'A' font */ outb(0xa1, 0x00); outb(0xa3, 0x41); /* M_NORMAL, use CG window (all NEC OK) */ /* sum */ for (i = 0; i < 4; i++) { data += *((unsigned long*)V(0xA4000) + i);/* 0xa4000 */ } if (data == 0x6efc58fc) { /* DA data */ ret |= M_NEC_PC98; } else { ret |= M_EPSON_PC98; } ret |= (inb(0x42) & 0x20) ? M_8M : 0; /* PC98_SYSTEM_PARAMETER(0x400) */ if ((*(unsigned char*)V(0xA1400)) & 0x80) { ret |= M_NOTE; } if (ret & M_NEC_PC98) { /* PC98_SYSTEM_PARAMETER(0x458) */ if ((*(unsigned char*)V(0xA1458)) & 0x80) { ret |= M_H98; } else { ret |= M_NOT_H98; } } else { ret |= M_NOT_H98; switch (epson_machine_id) { case 0x20: /* note A */ case 0x22: /* note W */ case 0x27: /* note AE */ case 0x2a: /* note WR */ ret |= M_NOTE; break; default: break; } } (*(unsigned long *)V(0xA1620)) = ret; } Index: stable/4/sys/boot/pc98/boot2/start.S =================================================================== --- stable/4/sys/boot/pc98/boot2/start.S (revision 84617) +++ stable/4/sys/boot/pc98/boot2/start.S (revision 84618) @@ -1,519 +1,475 @@ /* * 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 * $FreeBSD$ */ /* 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 + .code16 .text .globl start -ENTRY(boot1) - jmp start - +start: + jmp main boot_cyl: .word 0 String "IPL1 " -start: +main: /* 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 %ecx push %dx - data32 mov $0xa000, %eax mov %ax, %es /* 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 */ int $0x18 movb $0x0c, %ah /* text on */ int $0x18 /* cursor home and on */ - xor %edx, %edx + xor %dx, %dx movb $0x13, %ah int $0x18 movb $0x11, %ah int $0x18 /* 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 %ecx pop %es /* bootstrap passes */ mov %cs, %bx - data32 - cmp $0x1fe0, %ebx + cmp $0x1fe0, %bx jz fd - data32 - cmp $0x1fc0, %ebx + cmp $0x1fc0, %bx jnz hd - data32 - mov %ebp, %ecx - data32 - mov %ebp, %edx - addr32 + xor %cx, %cx 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 + mov $0x0200, %cx + mov $0x0001, %dx movb $0xd6, %ah jmp load hd: - data32 - and %ecx, %ecx + and %cx, %cx jnz 1f + .code32 addr32 - data32 - mov %cs: (boot_cyl), %ecx + mov %cs: (boot_cyl), %ecx /* actualy %cx in real mode */ + .code16 1: + xor %dx, %dx 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 */ + xor %bp, %bp /* %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". */ + .code32 data32 ljmp $BOOTSEG, $ EXT(boot2) + .code16 /* * 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 $0xe000, %dx mov 0x501, %al testb $0x08, %al jnz 1f - data32 - mov $0xa000, %eax - mov %ax, %es + mov $0xa000, %dx 1: + mov %dx, %es mov %cs, %ax mov %ax, %ds - addr32 - data32 - mov vram, %edi - data32 - mov $0x00e1, %ebx + mov vram, %di + mov $0x00e1, %bx + mov $160, %cx 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 + movb %bl, %es:0x2000(%di) + stosb + inc %di + jmp move_cursor +lf_code: + add %cx, %di + jmp move_cursor cr_code: - data32 - add $80, %edi + xor %dx, %dx + mov %di, %ax + div %cx + sub %dx, %di +move_cursor: + mov %di, %dx + movb $0x13, %ah + int $0x18 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 + mov %di, 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 + .word 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: - . = EXT(boot1) + 0x1be + . = EXT(start) + 0x1be /* Partition table */ .fill 0x30,0x1,0x0 .byte 0x80, 0x00, 0x01, 0x00 .byte 0xa5, 0xff, 0xff, 0xff .byte 0x00, 0x00, 0x00, 0x00 .byte 0x50, 0xc3, 0x00, 0x00 /* the last 2 bytes in the sector 0 contain the signature */ .value SIGNATURE ENTRY(disklabel) - . = EXT(boot1) + 0x400 + . = EXT(start) + 0x400