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>
This commit is contained in:
KATO Takenori 1999-02-03 08:39:09 +00:00
parent 03126f3524
commit dccbc08d92
44 changed files with 10185 additions and 3 deletions

View File

@ -2,6 +2,6 @@
SUBDIR+= ficl
# Pick the machine-dependant subdir based on the target architecture.
SUBDIR+= ${MACHINE_ARCH}
SUBDIR+= ${MACHINE}
.include <bsd.subdir.mk>

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: isapnp.h,v 1.1 1998/09/18 00:24:25 msmith Exp $
* $Id: isapnp.h,v 1.2 1998/10/21 20:07:04 msmith Exp $
*/
#ifndef _I386_ISA_PNP_H_
@ -44,7 +44,8 @@
#define MAX_PNP_LDN 20
/* Static ports to access PnP state machine */
#if defined(PC98) && defined(KERNEL)
#ifndef KERNEL
#ifdef PC98
/* pnp.h is included from pnpinfo.c. */
#define _PNP_ADDRESS 0x259
#define _PNP_WRITE_DATA 0xa59
@ -52,6 +53,7 @@
#define _PNP_ADDRESS 0x279
#define _PNP_WRITE_DATA 0xa79
#endif
#endif
/* PnP Registers. Write to ADDRESS and then use WRITE/READ_DATA */
#define SET_RD_DATA 0x00

5
sys/boot/pc98/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $Id: Makefile,v 1.7 1998/10/14 20:40:56 rnordier Exp $
SUBDIR= btx boot2 libpc98 loader
.include <bsd.subdir.mk>

View File

@ -0,0 +1,97 @@
# $Id: Makefile,v 1.22 1999/01/04 08:02:13 kato Exp $
#
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= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
-mno-486 \
-DPC98 -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
CFLAGS+= ${CWARNFLAGS}
CFLAGS+= -I${.CURDIR}/../../.. -aout
# 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
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
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 <bsd.kern.mk>
.include <bsd.prog.mk>

View File

@ -0,0 +1,63 @@
README.srieal.98
シリアルコンソールについて
加藤丈典 (kato@eclogite.eps.nagoya-u.ac.jp)
KATO Takenori
FreeBSD(98)のコンソールとして、内蔵RS-232Cポートに接続されたダム端末を
使用することができます。これにより、FreeBSD(98)をサーバとして使用する
時に、キーボードやモニタを接続しなくてもかまわなくなります。
シリアルコンソールを使用する際は、このドキュメントおよび、IBM-PC用のカー
ネルソースに含まれる、/usr/src/sys/i386/boot/biosboot/READEME.serialを
良く読んで下さい。
FreeBSD(98)でシリアルコンソールを使用する際は、以下の手順を実行して下
さい。
1: ブートコードのコンパイルオプション
PC-9801シリーズの場合キーボードが接続されていない状態と旧型
キーボードが接続されている状態とを区別する方法がありません.も
し,旧型キーボードを使用していて
PROBE_KEYBOARD
が有効になっていると,キーボードが認識されずにシリアルコンソー
ルが使用されます.また,
FORCE_COMCONSOLE
が有効になっていると,キーボードの接続状態に関わらずシリアルコ
ンソールを使用するようになります.
2: キーボードを切り離す
キーボードを接続せずに、本体を起動させた場合、システム領域のキー
ボードタイプが、旧式キーボード(CAPSが機械式のキーボード)と同じ
になります。FreeBSD(98)のブートコードは、これを検出して自動的
にシリアルコンソールモードに移ります。
3: 端末を接続する
内蔵RS-232Cコネクタにダム端末を接続して下さい。ダム端末が無い
場合は、適当なパソコンで通信ソフトウェアを実行させたものや、通
信機能つきのワープロなどを使用して下さい。
FreeBSD(98)のブートコードでは、RS-232Cポートを9600ボー、8ビッ
ト、パリティ無しに設定されています。
4: 本体を起動する
ブートブロックは、起動時にキーボードの接続を検査します。もし、
キーボードが接続されていなければ、端末に以下のメッセージが表示
されます。
No keyboard found.
>> FreeBSD BOOT @0x90000 640/25600 k of memory
Use hd(1,a)/kernel to boot sd0 when wd0 is also installed.
Usage: [[[fd(0,a)]/kernel][-Dabcdhrsv]]
Use ? for file list or press Enter for defaults
Boot:
これは、普段見ているメッセージとほとんど変わりませんが、はじめ
に、`No keyboard found'と表示されています。ここで、ダム端末か
ら、コンソール上で起動している時と同じようにカーネルを立ち上げ
ることができます。起動後のメッセージはダム端末に表示されます。
もし、シリアルコンソールから通常のコンソールに切替えるには、
`-h'オプションをつけて起動して下さい。

244
sys/boot/pc98/boot2/asm.S Normal file
View File

@ -0,0 +1,244 @@
/*
* 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
* $Id: asm.S,v 1.4 1997/09/01 10:38:24 kato 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.
*/
.file "asm.s"
#include "asm.h"
CR0_PE_ON = 0x1
CR0_PE_OFF = 0xfffffffe
.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 */
addr32
data32
lgdt EXT(Gdtr)
/* 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
*/
data32
ljmp $0x18, $xprot
xprot:
/*
* we are in USE32 mode now
* set up the protected mode segment registers : DS, SS, ES, FS
*/
movw $0x20, %ax /* data segment */
mov %ax, %ds /* gas would waste a prefix byte for movw */
mov %ax, %ss
mov %ax, %es
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. */
movw $0x30, %ax
/* Change to use16 mode. */
ljmp $0x28, $x16
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
*/
data32
ljmp $BOOTSEG, $xreal
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)
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
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
mov %bx, %ds
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)
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

144
sys/boot/pc98/boot2/asm.h Normal file
View File

@ -0,0 +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
* $Id: asm.h,v 1.3 1997/02/22 09:43:04 peter Exp $
*/
#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 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)

456
sys/boot/pc98/boot2/bios.S Normal file
View File

@ -0,0 +1,456 @@
/*
* 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
* $Id: bios.S,v 1.9 1998/05/02 02:06:07 kato 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
*/
/*
* 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 <joerg_wunsch@interface-business.de>.
*
* 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)
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
shl $9, %ebx
data32
push %ebx
addr32
data32
mov 0x1c(%ebp), %ebx
data32
mov %ebx, %ebp
data32
pop %ebx
int $0x1b
jc 1f
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)
push %ebp
mov %esp, %ebp
push %ebx /* save %ebx */
push %esi
push %edi
call EXT(prot_to_real)
movb $0x0, %ah
int $0x18
movb %al, %bl /* real_to_prot uses %eax */
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)
push %ebp
mov %esp, %ebp
push %ebx
push %esi
push %edi
call EXT(prot_to_real) /* enter real mode */
xor %ebx, %ebx
movb $0x1, %ah
int $0x18
andb %bh, %bh
data32
jz nochar
movb %al, %bl
nochar:
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)
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 */
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:
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)
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

447
sys/boot/pc98/boot2/boot.c Normal file
View File

@ -0,0 +1,447 @@
/*
* 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, [92/04/03 16:51:14 rvb]
* $Id: boot.c,v 1.19 1998/10/11 15:09:14 kato 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.
*/
#include <sys/param.h>
#include "boot.h"
#include <a.out.h>
#include <sys/reboot.h>
#include <machine/bootinfo.h>
#define ouraddr (BOOTSEG << 4) /* XXX */
#define BOOT_CONFIG_SIZE 512
#define BOOT_HELP_SIZE 2048
#define KERNEL_CONFIG_SIZE 512
#define NAMEBUF_LEN 1024 /* oversized to defend against gets() */
static char boot_config[BOOT_CONFIG_SIZE];
static char boot_help[BOOT_HELP_SIZE];
char *name;
static char kernel_config[KERNEL_CONFIG_SIZE];
static char kernel_config_namebuf[NAMEBUF_LEN + sizeof "config"];
static char linebuf[NAMEBUF_LEN];
static char namebuf[NAMEBUF_LEN];
static struct bootinfo bootinfo;
int loadflags;
static void getbootdev(char *ptr, int *howto);
static void loadprog(void);
static void readfile(char *path, char *buf, size_t nbytes);
/* NORETURN */
void
boot(int drive)
{
int ret;
#ifdef PC98
int i;
unsigned char disk_equips;
#endif
/* Pick up the story from the Bios on geometry of disks */
#ifdef PC98
for(ret = 0; ret < 2; ret ++) {
if (*(unsigned char*)V(0xA155d) & (1 << ret)) {
bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
}
#else /* IBM-PC */
for(ret = 0; ret < N_BIOS_GEOM; ret ++)
bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
#endif /* PC98 */
}
bootinfo.bi_basemem = memsize(0);
bootinfo.bi_extmem = memsize(1);
bootinfo.bi_memsizes_valid = 1;
gateA20();
#ifdef PC98
/* set machine type to PC98_SYSTEM_PARAMETER */
machine_check();
#endif /* PC98 */
/*
* The default boot device is the first partition in the
* compatibility slice on the boot drive.
*/
dosdev = drive;
#ifdef PC98
maj = (drive&0x70) >> 3; /* a good first bet */
if (maj == 4) { /* sd */
disk_equips = *(unsigned char *)V(0xA1482);
unit = 0;
for (i=0; i<(drive&0x0f); i++) {
unit += (disk_equips >> i) & 1;
}
} else {
unit = drive & 0x0f;
}
#else /* IBM-PC */
maj = 2;
unit = drive & 0x7f;
#ifdef dontneed
slice = 0;
part = 0;
#endif
if (drive & 0x80) {
/* Hard drive. Adjust. */
maj = 0;
#if BOOT_HD_BIAS > 0
if (unit >= BOOT_HD_BIAS) {
/*
* The drive is probably a SCSI drive with a unit
* number BOOT_HD_BIAS less than the BIOS drive
* number.
*/
maj = 4;
unit -= BOOT_HD_BIAS;
}
#endif
}
#endif /* PC98 */
name = "/boot/loader";
if (boot_config[0] != '\0') {
printf("boot.config: %s", boot_config);
getbootdev(boot_config, &loadflags);
if (openrd() != 0)
name = "kernel";
}
loadstart:
/* print this all each time.. (saves space to do so) */
/* If we have looped, use the previous entries as defaults */
printf("\r \n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory, %s%s console\n"
"Boot default: %d:%s(%d,%c)%s\n"
"%s\n"
"boot: ",
ouraddr, bootinfo.bi_basemem, bootinfo.bi_extmem,
(loadflags & RB_SERIAL) ? "serial" : "internal",
(loadflags & RB_DUAL) ? "/dual" : "",
#ifdef PC98
dosdev & 0x0f, devs[maj], unit, 'a' + part,
#else
dosdev & 0x7f, devs[maj], unit, 'a' + part,
#endif
name ? name : "*specify_a_kernel_name*",
boot_help);
/*
* Ignore flags from previous attempted boot, if any.
* XXX this is now too strict. Settings given in boot.config should
* not be changed.
*/
loadflags &= (RB_DUAL | RB_SERIAL);
/*
* Be paranoid and make doubly sure that the input buffer is empty.
*/
if (loadflags & (RB_DUAL | RB_SERIAL))
init_serial();
if (!gets(linebuf))
putchar('\n');
else
getbootdev(linebuf, &loadflags);
if (name == NULL)
goto loadstart;
ret = openrd();
if (ret != 0) {
if (ret > 0)
printf("Can't find %s\n", name);
goto loadstart;
}
/* if (inode.i_mode&IEXEC)
loadflags |= RB_KDB;
*/
loadprog();
goto loadstart;
}
static void
loadprog(void)
{
struct exec head;
int startaddr;
int addr; /* physical address.. not directly useable */
int bootdev;
int i;
unsigned pad;
char *s, *t;
read((void *)&head, sizeof(head));
if ( N_BADMAG(head)) {
printf("Invalid format!\n");
return;
}
poff = N_TXTOFF(head);
/*if(poff==0)
poff = 32;*/
/*
* We assume that the entry address is the same as the lowest text
* address and that the kernel startup code handles relocation by
* this address rounded down to a multiple of 16M.
*/
startaddr = head.a_entry & 0x00FFFFFF;
addr = startaddr;
printf("Booting %d:%s(%d,%c)%s @ 0x%x\n"
#ifdef PC98
, dosdev & 0x0f
#else
, dosdev & 0x7f
#endif
, devs[maj]
, unit
, 'a'+part
, name
, addr);
if(addr < 0x00100000)
{
/*
* Bail out, instead of risking to damage the BIOS
* variables, the loader, or the adapter memory area.
* We don't support loading below 1 MB any more.
*/
printf("Start address too low\n");
return;
}
printf("text=0x%x ", head.a_text);
/********************************************************/
/* LOAD THE TEXT SEGMENT */
/********************************************************/
xread((void *)addr, head.a_text);
addr += head.a_text;
/********************************************************/
/* Load the Initialised data after the text */
/********************************************************/
while (addr & PAGE_MASK)
*(char *)addr++ = 0;
printf("data=0x%x ", head.a_data);
xread((void *)addr, head.a_data);
addr += head.a_data;
/********************************************************/
/* Skip over the uninitialised data */
/* (but clear it) */
/********************************************************/
printf("bss=0x%x ", head.a_bss);
/*
* XXX however, we should be checking that we don't load ... into
* nonexistent memory. A full symbol table is unlikely to fit on 4MB
* machines.
*/
/* kzip & kernel will zero their own bss */
addr += head.a_bss;
/* Pad to a page boundary. */
pad = (unsigned)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
}
bootinfo.bi_symtab = addr;
/********************************************************/
/* Copy the symbol table size */
/********************************************************/
pcpy(&head.a_syms, (void *)addr, sizeof(head.a_syms));
addr += sizeof(head.a_syms);
/********************************************************/
/* Load the symbol table */
/********************************************************/
printf("symbols=[+0x%x+0x%x+0x%x", pad, sizeof(head.a_syms),
head.a_syms);
xread((void *)addr, head.a_syms);
addr += head.a_syms;
/********************************************************/
/* Load the string table size */
/********************************************************/
read((void *)&i, sizeof(int));
pcpy(&i, (void *)addr, sizeof(int));
i -= sizeof(int);
addr += sizeof(int);
/********************************************************/
/* Load the string table */
/********************************************************/
printf("+0x%x+0x%x]\n", sizeof(int), i);
xread((void *)addr, i);
addr += i;
bootinfo.bi_esymtab = addr;
/*
* For backwards compatibility, use the previously-unused adaptor
* and controller bitfields to hold the slice number.
*/
bootdev = MAKEBOOTDEV(maj, (slice >> 4), slice & 0xf, unit, part);
bootinfo.bi_version = BOOTINFO_VERSION;
bootinfo.bi_kernelname = (u_int32_t)(name + ouraddr);
bootinfo.bi_nfs_diskless = 0;
bootinfo.bi_size = sizeof(bootinfo);
bootinfo.bi_bios_dev = dosdev;
/*
* Load the kernel config file (if any). Its name is given by
* appending ".config" to the kernel name. Build the name inline
* because no str*() functions are available. The file has to be
* copied to &disklabel for userconfig. It can't be loaded there
* directly because the label is used late in readfile() in some
* unusual cases, e.g., for bad144 handling.
*/
s = name;
t = kernel_config_namebuf;
do
;
while ((*t++ = *s++) != '\0');
s = ".config";
--t;
do
;
while ((*t++ = *s++) != '\0');
readfile(kernel_config_namebuf, kernel_config, KERNEL_CONFIG_SIZE);
pcpy(kernel_config, (char *)&disklabel + ouraddr, KERNEL_CONFIG_SIZE);
printf("total=0x%x entry point=0x%x\n", addr, startaddr);
startprog(startaddr, loadflags | RB_BOOTINFO, bootdev,
(unsigned)&bootinfo + ouraddr);
}
static void
readfile(char *path, char *buf, size_t nbytes)
{
int openstatus;
buf[0] = '\0';
name = path;
openstatus = openrd();
if (openstatus != 0) {
if (openstatus > 0)
printf("Can't find file %s\n", name);
} else {
/* XXX no way to determine file size. */
read(buf, nbytes);
}
buf[nbytes - 1] = '\0';
}
static void
getbootdev(char *ptr, int *howto)
{
char c;
int f;
char *p;
/* Copy the flags to save some bytes. */
f = *howto;
c = *ptr;
for (;;) {
nextarg:
while (c == ' ' || c == '\n')
c = *++ptr;
if (c == '-')
while ((c = *++ptr) != '\0') {
if (c == ' ' || c == '\n')
goto nextarg;
if (c == 'a')
f |= RB_ASKNAME;
if (c == 'C')
f |= RB_CDROM;
if (c == 'c')
f |= RB_CONFIG;
if (c == 'D')
f ^= RB_DUAL;
if (c == 'd')
f |= RB_KDB;
if (c == 'g')
f |= RB_GDB;
if (c == 'h')
f ^= RB_SERIAL;
if (c == 'P')
f |= RB_PROBEKBD;
if (c == 'r')
f |= RB_DFLTROOT;
if (c == 's')
f |= RB_SINGLE;
if (c == 'v')
f |= RB_VERBOSE;
}
if (c == '\0')
break;
p = name = namebuf;
while (c != '\0' && c != ' ' && c != '\n') {
*p++ = c;
c = *++ptr;
}
*p = '\0';
}
if (f & RB_PROBEKBD) {
if (probe_keyboard()) {
f |= RB_DUAL | RB_SERIAL;
printf("No keyboard found\n");
} else
printf("Keyboard found\n");
}
if (f & (RB_DUAL | RB_SERIAL))
init_serial();
*howto = f;
}

109
sys/boot/pc98/boot2/boot.h Normal file
View File

@ -0,0 +1,109 @@
/*
* 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:03 rpd
* $Id: boot.h,v 1.14 1998/10/11 15:08:50 kato Exp $
*/
#include <sys/param.h>
#include <sys/time.h>
#include <ufs/ffs/fs.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#define RB_DUAL 0x40000 /* XXX */
#define RB_PROBEKBD 0x80000 /* XXX */
extern char *devs[];
extern char *name;
extern struct fs *fs;
extern struct inode inode;
extern int dosdev, unit, slice, part, maj, boff, poff;
extern unsigned tw_chars;
extern int loadflags;
extern struct disklabel disklabel;
/* asm.S */
#if ASM_ONLY
void real_to_prot(void);
void prot_to_real(void);
#endif
void startprog(unsigned int physaddr, int howto, int bootdev,
/* XXX struct bootinfo * */ unsigned int bootinfo);
void pcpy(const void *src, void *dst, size_t count);
/* bios.S */
int biosread(int dev, int cyl, int head, int sec, int nsec, void *offset);
void putc(int c);
int getc(void);
int ischar(void);
int get_diskinfo(int drive);
int memsize(int extended);
/* boot.c */
void boot(int drive);
/* boot2.S */
void boot2(void);
/* disk.c */
int devopen(void);
void devread(char *iodest, int sector, int cnt);
/* io.c */
void gateA20(void);
void printf(const char *format, ...);
void putchar(int c);
void delay1ms(void);
int gets(char *buf);
int strcmp(const char *s1, const char *s2);
#ifdef CDBOOT
int strcasecmp(const char *s1, const char *s2);
#endif /* !CDBOOT */
void bcopy(const void *from, void *to, size_t len);
void twiddle(void);
#ifdef PC98
void machine_check(void);
#endif
/* probe_keyboard.c */
int probe_keyboard(void);
/* serial.S */
void serial_putc(int ch);
int serial_getc(void);
int serial_ischar(void);
void init_serial(void);
/* sys.c */
void xread(char *addr, int size);
void read(char *buffer, int count);
int openrd(void);
#ifdef PC98
#define V(ra) (ra - BOOTSEG * 0x10)
#endif

183
sys/boot/pc98/boot2/boot2.S Normal file
View File

@ -0,0 +1,183 @@
/*
* 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
*/
/*
* 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
*/
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) \
addr32; \
movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \
addr32; \
movb %bl, EXT(Gdt)+(8*gdt_index)+4
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
addr32
data32
movl %eax, EXT(Gdtr)+2
#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 */
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

330
sys/boot/pc98/boot2/disk.c Normal file
View File

@ -0,0 +1,330 @@
/*
* 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:49 rpd
* $Id: disk.c,v 1.9 1997/05/28 09:22:59 kato Exp $
*/
/*
* Ported to PC-9801 by Yoshio Kimura
*/
/*
* 93/10/08 bde
* If there is no 386BSD partition, initialize the label sector with
* LABELSECTOR instead of with garbage.
*
* 93/08/22 bde
* Fixed reading of bad sector table. It is at the end of the 'c'
* partition, which is not always at the end of the disk.
*/
#include "boot.h"
#ifdef DO_BAD144
#include <sys/dkbad.h>
#endif DO_BAD144
#include <sys/disklabel.h>
#include <sys/diskslice.h>
#define BIOS_DEV_FLOPPY 0x0
#define BIOS_DEV_WIN 0x80
#define BPS 512
#define SPT(di) ((di)&0xff)
#define HEADS(di) (((di)>>8)&0xff)
#ifdef DO_BAD144
static struct dkbad dkb;
static int do_bad144;
#endif DO_BAD144
static int bsize;
static int spt, spc;
struct fs *fs;
struct inode inode;
int dosdev, unit, slice, part, maj, boff;
/*#define EMBEDDED_DISKLABEL 1*/
/* Read ahead buffer large enough for one track on a 1440K floppy. For
* reading from floppies, the bootstrap has to be loaded on a 64K boundary
* to ensure that this buffer doesn't cross a 64K DMA boundary.
*/
#define RA_SECTORS 18
static char ra_buf[RA_SECTORS * BPS];
static int ra_dev;
static int ra_end;
static int ra_first;
static int badsect(int sector);
static char *Bread(int dosdev, int sector);
int
devopen(void)
{
struct dos_partition *dptr;
struct disklabel *dl;
char *p;
int i, sector = 0, di, dosdev_copy;
dosdev_copy = dosdev;
di = get_diskinfo(dosdev_copy);
spc = (spt = SPT(di)) * HEADS(di);
#ifndef RAWBOOT
if ((dosdev_copy & 0xf0) == 0x90)
{
boff = 0;
part = (spt == 15 ? 0 : 1);
}
else
{
#ifdef EMBEDDED_DISKLABEL
dl = &disklabel;
#else EMBEDDED_DISKLABEL
#ifdef PC98
p = Bread(dosdev_copy, 1);
dptr = (struct dos_partition *)p;
slice = WHOLE_DISK_SLICE;
for (i = 0; i < NDOSPART; i++, dptr++)
if (dptr->dp_mid == DOSPTYP_386BSD) {
slice = BASE_SLICE + i;
sector = dptr->dp_scyl * spc;
break;
}
p = Bread(dosdev, sector + LABELSECTOR);
dl=((struct disklabel *)p);
disklabel = *dl; /* structure copy (maybe useful later)*/
#else
p = Bread(dosdev_copy, 0);
dptr = (struct dos_partition *)(p+DOSPARTOFF);
slice = WHOLE_DISK_SLICE;
for (i = 0; i < NDOSPART; i++, dptr++)
if (dptr->dp_typ == DOSPTYP_386BSD) {
slice = BASE_SLICE + i;
sector = dptr->dp_start;
break;
}
p = Bread(dosdev_copy, sector + LABELSECTOR);
dl=((struct disklabel *)p);
disklabel = *dl; /* structure copy (maybe useful later)*/
#endif /* PC98 */
#endif EMBEDDED_DISKLABEL
if (dl->d_magic != DISKMAGIC) {
printf("bad disklabel\n");
return 1;
}
if( (maj == 4) || (maj == 0) || (maj == 1))
{
if (dl->d_type == DTYPE_SCSI)
{
maj = 4; /* use scsi as boot dev */
}
else
{
maj = 0; /* must be ESDI/IDE */
}
}
/* This little trick is for OnTrack DiskManager disks */
boff = dl->d_partitions[part].p_offset -
dl->d_partitions[2].p_offset + sector;
#ifndef PC98
bsize = dl->d_partitions[part].p_size;
if (bsize == 0) {
printf("empty partition\n");
return 1;
}
#endif
#ifdef DO_BAD144
do_bad144 = 0;
if (dl->d_flags & D_BADSECT) {
/* this disk uses bad144 */
int i;
int dkbbnum;
struct dkbad *dkbptr;
/* find the first readable bad sector table */
/* some of this code is copied from ufs/ufs_disksubr.c */
/* including the bugs :-( */
/* read a bad sector table */
#define BAD144_PART 2 /* XXX scattered magic numbers */
#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
if (dl->d_partitions[BSD_PART].p_offset != 0)
dkbbnum = dl->d_partitions[BAD144_PART].p_offset
+ dl->d_partitions[BAD144_PART].p_size;
else
dkbbnum = dl->d_secperunit;
dkbbnum -= dl->d_nsectors;
if (dl->d_secsize > DEV_BSIZE)
dkbbnum *= dl->d_secsize / DEV_BSIZE;
else
dkbbnum /= DEV_BSIZE / dl->d_secsize;
i = 0;
do_bad144 = 0;
do {
/* XXX: what if the "DOS sector" < 512 bytes ??? */
p = Bread(dosdev_copy, dkbbnum + i);
dkbptr = (struct dkbad *) p;
/* XXX why is this not in <sys/dkbad.h> ??? */
#define DKBAD_MAGIC 0x4321
if (dkbptr->bt_mbz == 0 &&
dkbptr->bt_flag == DKBAD_MAGIC) {
dkb = *dkbptr; /* structure copy */
do_bad144 = 1;
break;
}
i += 2;
} while (i < 10 && (unsigned)i < dl->d_nsectors);
if (!do_bad144)
printf("Bad bad sector table\n");
else
printf("Using bad sector table at %d\n", dkbbnum+i);
}
#endif /* DO_BAD144 */
}
#endif /* RAWBOOT */
return 0;
}
/*
* Be aware that cnt is rounded up to N*BPS
*/
void
devread(char *iodest, int sector, int cnt)
{
int offset;
char *p;
int dosdev_copy;
for (offset = 0; offset < cnt; offset += BPS)
{
dosdev_copy = dosdev;
p = Bread(dosdev_copy, badsect(sector++));
bcopy(p, iodest+offset, BPS);
}
}
static char *
Bread(int dosdev, int sector)
{
if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
{
int cyl, head, sec, nsec;
cyl = sector/spc;
#ifndef PC98
if (cyl > 1023) {
printf("Error: C:%d > 1023 (BIOS limit)\n", cyl);
for(;;); /* loop forever */
}
#endif
head = (sector % spc) / spt;
sec = sector % spt;
nsec = spt - sec;
if (nsec > RA_SECTORS)
nsec = RA_SECTORS;
twiddle();
if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
{
nsec = 1;
twiddle();
while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
printf("Error: D:0x%x C:%d H:%d S:%d\n",
dosdev, cyl, head, sec);
twiddle();
}
}
ra_dev = dosdev;
ra_first = sector;
ra_end = sector + nsec;
}
return (ra_buf + (sector - ra_first) * BPS);
}
static int
badsect(int sector)
{
#if defined(DO_BAD144) && !defined(RAWBOOT)
int i;
if (do_bad144) {
u_short cyl;
u_short head;
u_short sec;
int newsec;
struct disklabel *dl = &disklabel;
/* XXX */
/* from wd.c */
/* bt_cyl = cylinder number in sorted order */
/* bt_trksec is actually (head << 8) + sec */
/* only remap sectors in the partition */
if (sector < boff || sector >= boff + bsize) {
goto no_remap;
}
cyl = (sector-boff) / dl->d_secpercyl;
head = ((sector-boff) % dl->d_secpercyl) / dl->d_nsectors;
sec = (sector-boff) % dl->d_nsectors;
sec = (head<<8) + sec;
/* now, look in the table for a possible bad sector */
for (i=0; i<126; i++) {
if (dkb.bt_bad[i].bt_cyl == cyl) {
/* found same cylinder */
if (dkb.bt_bad[i].bt_trksec == sec) {
/* FOUND! */
break;
}
} else if (dkb.bt_bad[i].bt_cyl > cyl) {
i = 126;
break;
}
}
if (i == 126) {
/* didn't find bad sector */
goto no_remap;
}
/* otherwise find replacement sector */
if (dl->d_partitions[BSD_PART].p_offset != 0)
newsec = dl->d_partitions[BAD144_PART].p_offset
+ dl->d_partitions[BAD144_PART].p_size;
else
newsec = dl->d_secperunit;
newsec -= dl->d_nsectors + i + 1;
return newsec;
}
no_remap:
#endif
return sector;
}

429
sys/boot/pc98/boot2/io.c Normal file
View File

@ -0,0 +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
* $Id: io.c,v 1.13 1997/12/05 11:50:42 kato Exp $
*/
#include "boot.h"
#include <machine/cpufunc.h>
#include <sys/reboot.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#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
* 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;
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) KATO Takenori, 1994-1995. 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 as
* the first lines of this file unmodified.
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 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 AUTHOR 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.
*/
#include "boot.h"
int probe_keyboard(void)
{
/*
* New type (RA and later) keyboard only!
*/
if (*(unsigned char*)V(0xA1481) & 0x48)
return 0;
return 1; /* keyboard not found */
}

View File

@ -0,0 +1,201 @@
/*
* 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
* $Id: serial.S,v 1.8 1999/01/03 05:03:46 kato 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.
*/
/*
* Serial bootblock interface routines
* Copyright (c) 1994, J"org Wunsch
*
* 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.
*
* THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*/
#if COMCONSOLE == 0x238
#include "../../../i386/boot/biosboot/serial.S"
#else
/*
* modified for PC-98 by KATO T. of Nagoya University
*/
.file "serial.S"
#include <i386/isa/sioreg.h>
#include "asm.h"
.text
/*
* The serial port interface routines implement a simple polled i/o
* interface to a standard serial port. Due to the space restrictions
* for the boot blocks, no BIOS support is used (since BIOS requires
* expensive real/protected mode switches), instead the rudimentary
* BIOS support is duplicated here.
*
* The base address for the i/o port is passed from the Makefile in
* the COMCONSOLE preprocessor macro. Console parameters are currently
* hard-coded to 9600 Bd, 8 bit. This can be changed in the
* init_serial() function.
*/
/*
* void serial_putc(char ch)
* send ch to serial port
*
*/
ENTRY(serial_putc)
mov $COMCONSOLE + 2, %edx # line status reg
1: inb %dx, %al
testb $0x01, %al
jz 1b # TX buffer not empty
movb 0x4(%esp), %al
sub $2, %edx # TX output reg
outb %al, %dx # send this one
ret
/*
* int serial_getc(void)
* read a character from serial port
*/
ENTRY(serial_getc)
mov $COMCONSOLE + 2, %edx # line status reg
1:
inb %dx, %al
testb $0x02, %al
jz 1b # no RX char available
xorb %eax, %eax
subb $2, %edx # RX buffer reg
inb %dx, %al # fetch (first) character
cmp $0x7F, %eax # make DEL...
jne 2f
movb $0x08, %eax # look like BS
2:
ret
/*
* int serial_ischar(void)
* if there is a character pending, return true; otherwise return 0
*/
ENTRY(serial_ischar)
xorl %eax, %eax
movl $COMCONSOLE + 2, %edx # line status reg
inb %dx, %al
andb $0x02, %al # RX char available?
ret
/*
* void init_serial(void)
* initialize the serial console port to 9600 Bd, 8 bpc
*/
ENTRY(init_serial)
/* set 8253 */
movb 0xb6, %al
outb %al, $0x77
movl $COMCONSOLE_CLK, %eax
outb %al, $0x75
inb $0x5f, %al
movb %ah, %al
outb %al, $0x75
/* inhibit com int */
inb $0x35, %al
andb $0xf8, %al
movb %al, %ah
inb $0x5f, %al
movb %ah, %al
outb %al, $0x35
inb $0x02, %al
orb $0x10, %al
outb %al, $0x02
/* dummy command */
xorb %al,%al
movl $COMCONSOLE + 2, %edx
outb %al, %dx
inb $0x5f, %al
xorb %al,%al
outb %al, %dx
inb $0x5f, %al
xorb %al,%al
outb %al, %dx
inb $0x5f, %al
/* RESET 8251 */
movb $0x40, %al
outb %al, %dx
movb $COMCONSOLE_MODE , %al
andb $0xfc, %al
orb $0x02, %al /* factor = 1/16 */
outb %al, %dx
inb $0x5f, %al
/* start RS-232C */
movb $0x37, %al
outb %al, %dx
ret
#endif

535
sys/boot/pc98/boot2/start.S Normal file
View File

@ -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

337
sys/boot/pc98/boot2/sys.c Normal file
View File

@ -0,0 +1,337 @@
/*
* 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:34 rpd
* $Id: sys.c,v 1.15 1998/05/02 02:06:08 kato Exp $
*/
/*
* Ported to PC-9801 by Yoshio Kimura
*/
#include "boot.h"
#include <sys/dirent.h>
#include <sys/reboot.h>
#if 0
/* #define BUFSIZE 4096 */
#define BUFSIZE MAXBSIZE
static char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
#endif
static char biosdrivedigit;
#define BUFSIZE 8192
#define MAPBUFSIZE BUFSIZE
static char buf[BUFSIZE], fsbuf[BUFSIZE], iobuf[BUFSIZE];
static char mapbuf[MAPBUFSIZE];
static int mapblock;
int poff;
#ifdef RAWBOOT
#define STARTBYTE 8192 /* Where on the media the kernel starts */
#endif
static int block_map(int file_block);
static int find(char *path);
void
xread(char *addr, int size)
{
int count = BUFSIZE;
while (size > 0) {
if (BUFSIZE > size)
count = size;
read(buf, count);
pcpy(buf, addr, count);
size -= count;
addr += count;
}
}
#ifndef RAWBOOT
void
read(char *buffer, int count)
{
int logno, off, size;
int cnt2, bnum2;
struct fs *fs_copy;
while (count > 0 && poff < inode.i_size) {
fs_copy = fs;
off = blkoff(fs_copy, poff);
logno = lblkno(fs_copy, poff);
cnt2 = size = blksize(fs_copy, &inode, logno);
bnum2 = fsbtodb(fs_copy, block_map(logno)) + boff;
if ( (!off) && (size <= count)) {
devread(buffer, bnum2, cnt2);
} else {
size -= off;
if (size > count)
size = count;
devread(iobuf, bnum2, cnt2);
bcopy(iobuf+off, buffer, size);
}
buffer += size;
count -= size;
poff += size;
}
}
#else
void
read(char *buffer, int count)
{
int cnt, bnum, off, size;
off = STARTBYTE + poff;
poff += count;
/* Read any unaligned bit at the front */
cnt = off & 511;
if (cnt) {
size = 512-cnt;
if (count < size)
size = count;
devread(iobuf, off >> 9, 512);
bcopy(iobuf+cnt, buffer, size);
count -= size;
off += size;
buffer += size;
}
size = count & (~511);
if (size && (off & (~511))) {
devread(buffer, off >> 9, size);
off += size;
count -= size;
buffer += size;
}
if (count) {
devread(iobuf, off >> 9, 512);
bcopy(iobuf, buffer, count);
}
}
#endif
static int
find(char *path)
{
char *rest, ch;
int block, off, loc, ino = ROOTINO;
struct dirent *dp;
char list_only;
list_only = (path[0] == '?' && path[1] == '\0');
loop:
devread(iobuf, fsbtodb(fs, ino_to_fsba(fs, ino)) + boff, fs->fs_bsize);
bcopy((void *)&((struct dinode *)iobuf)[ino % fs->fs_inopb],
(void *)&inode.i_din,
sizeof (struct dinode));
if (!*path)
return 1;
while (*path == '/')
path++;
if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
return 0;
for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
*rest = 0;
loc = 0;
do {
if (loc >= inode.i_size) {
if (list_only) {
putchar('\n');
return -1;
} else {
return 0;
}
}
if (!(off = blkoff(fs, loc))) {
block = lblkno(fs, loc);
devread(iobuf, fsbtodb(fs, block_map(block)) + boff,
blksize(fs, &inode, block));
}
dp = (struct dirent *)(iobuf + off);
loc += dp->d_reclen;
if (dp->d_fileno && list_only)
printf("%s ", dp->d_name);
} while (!dp->d_fileno || strcmp(path, dp->d_name));
ino = dp->d_fileno;
*(path = rest) = ch;
goto loop;
}
static int
block_map(int file_block)
{
int bnum;
if (file_block < NDADDR)
return(inode.i_db[file_block]);
if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
devread(mapbuf, bnum, fs->fs_bsize);
mapblock = bnum;
}
return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
}
int
openrd(void)
{
char **devp, *name0 = name, *cp = name0;
int biosdrive, dosdev_copy, ret;
/*******************************************************\
* If bracket given look for preceding device name *
\*******************************************************/
while (*cp && *cp!='(')
cp++;
if (!*cp)
{
cp = name0;
}
else
{
/*
* Look for a BIOS drive number (a leading digit followed
* by a colon).
*/
biosdrivedigit = '\0';
if (*(name0 + 1) == ':' && *name0 >= '0' && *name0 <= '9') {
biosdrivedigit = *name0;
name0 += 2;
}
if (cp++ != name0)
{
for (devp = devs; *devp; devp++)
if (name0[0] == (*devp)[0] &&
name0[1] == (*devp)[1])
break;
if (!*devp)
{
printf("Unknown device\n");
return 1;
}
maj = devp-devs;
}
/*******************************************************\
* Look inside brackets for unit number, and partition *
\*******************************************************/
/*
* Allow any valid digit as the unit number, as the BIOS
* will complain if the unit number is out of range.
* Restricting the range here prevents the possibilty of using
* BIOSes that support more than 2 units.
* XXX Bad values may cause strange errors, need to check if
* what happens when a value out of range is supplied.
*/
if (*cp >= '0' && *cp <= '9')
unit = *cp++ - '0';
if (!*cp || (*cp == ',' && !*++cp))
return 1;
if (*cp >= 'a' && *cp <= 'p')
part = *cp++ - 'a';
while (*cp && *cp++!=')') ;
if (!*cp)
return 1;
}
biosdrive = biosdrivedigit - '0';
if (biosdrivedigit == '\0') {
#ifdef PC98
biosdrive = dosdev & 0x0f;
#else
biosdrive = unit;
#endif
#if BOOT_HD_BIAS > 0
/* XXX */
if (maj == 4)
biosdrive += BOOT_HD_BIAS;
#endif
}
switch(maj)
{
#ifdef PC98
case 4: /* sd */
dosdev_copy = biosdrive | 0xa0;
#else /* IBM-PC */
case 0:
case 4:
dosdev_copy = biosdrive | 0x80;
#endif
break;
#ifdef PC98
case 0:
case 2:
dosdev_copy = (maj << 3) | unit | 0x80;
#else
case 2:
dosdev_copy = biosdrive;
#endif
break;
#ifdef PC98
case 6:/* 1.44MB FD */
dosdev_copy = (maj << 3) | unit;
break;
#endif
default:
printf("Unknown device\n");
return 1;
}
dosdev = dosdev_copy;
#if 0
/* XXX this is useful, but misplaced. */
printf("dosdev= %x, biosdrive = %d, unit = %d, maj = %d\n",
dosdev_copy, biosdrive, unit, maj);
#endif
/***********************************************\
* Now we know the disk unit and part, *
* Load disk info, (open the device) *
\***********************************************/
if (devopen())
return 1;
#ifndef RAWBOOT
/***********************************************\
* Load Filesystem info (mount the device) *
\***********************************************/
devread((char *)(fs = (struct fs *)fsbuf), SBLOCK + boff, SBSIZE);
/***********************************************\
* Find the actual FILE on the mounted device *
\***********************************************/
ret = find(cp);
name = cp;
if (ret == 0)
return 1;
if (ret < 0) {
name = NULL;
return -1;
}
poff = 0;
#endif /* RAWBOOT */
return 0;
}

149
sys/boot/pc98/boot2/table.c Normal file
View File

@ -0,0 +1,149 @@
/*
* 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:43 rpd
* $Id: table.c,v 1.8 1998/10/11 15:09:36 kato 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.
*/
#include "boot.h"
/* Segment Descriptor
*
* 31 24 19 16 7 0
* ------------------------------------------------------------
* | | |B| |A| | | |1|0|E|W|A| |
* | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 |
* | | |D| |L| 19..16| | |1|1|C|R|A| |
* ------------------------------------------------------------
* | | |
* | BASE 15..0 | LIMIT 15..0 |
* | | |
* ------------------------------------------------------------
*/
struct seg_desc {
unsigned short limit_15_0;
unsigned short base_15_0;
unsigned char base_23_16;
unsigned char p_dpl_type;
unsigned char g_b_a_limit;
unsigned char base_31_24;
};
#define RUN 0 /* not really 0, but filled in at boot time */
struct seg_desc Gdt[] = {
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0x0 : null */
{0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0}, /* 0x08 : kernel code */
/* 0x9E? */
{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */
/* 0x92? */
{0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */
#ifdef PC98
/*
* The limit of boot data should be more than or equal to 0x9FFFF
* for saving BIOS parameter and EPSON machine ID into 2'nd T-VRAM,
* because base address is normally 0x10000.
*/
{0xFFFF, RUN, RUN, 0x92, 0x4F, 0x0}, /* 0x20 : boot data */
#else
{0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* 0x20 : boot data */
#endif
{0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */
{0xFFFF, 0x0, 0x0, 0x92, 0x0, 0x0}, /* 0x30 : boot data, 16 bits */
#ifdef BDE_DEBUGGER
/* More for bdb. */
{}, /* BIOS_TMP_INDEX = 7 : null */
{}, /* TSS_INDEX = 8 : null */
{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* DS_286_INDEX = 9 */
{0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* ES_286_INDEX = 10 */
{}, /* Unused = 11 : null */
{0x7FFF, 0x8000, 0xB, 0xB2, 0x40, 0x0}, /* COLOR_INDEX = 12 */
{0x7FFF, 0x0, 0xB, 0xB2, 0x40, 0x0}, /* MONO_INDEX = 13 */
{0xFFFF, RUN, RUN, 0x9A, 0x40, 0x0}, /* DB_CS_INDEX = 14 */
{0xFFFF, RUN, RUN, 0x9A, 0x0, 0x0}, /* DB_CS16_INDEX = 15 */
{0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* DB_DS_INDEX = 16 */
{8*18-1, RUN, RUN, 0x92, 0x40, 0x0}, /* GDT_INDEX = 17 */
#endif /* BDE_DEBUGGER */
};
#ifdef BDE_DEBUGGER
struct idt_desc {
unsigned short entry_15_0;
unsigned short selector;
unsigned char padding;
unsigned char p_dpl_type;
unsigned short entry_31_16;
};
struct idt_desc Idt[] = {
{}, /* Null (int 0) */
{RUN, 0x70, 0, 0x8E, 0}, /* DEBUG_VECTOR = 1 */
{}, /* Null (int 2) */
{RUN, 0x70, 0, 0xEE, 0}, /* BREAKPOINT_VECTOR = 3 */
};
#endif /* BDE_DEBUGGER */
struct pseudo_desc {
unsigned short limit;
unsigned short base_low;
unsigned short base_high;
};
struct pseudo_desc Gdtr = { sizeof Gdt - 1, RUN, RUN };
#ifdef BDE_DEBUGGER
struct pseudo_desc Idtr_prot = { sizeof Idt - 1, RUN, RUN };
struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0, 0x0 };
#endif
/*
* All initialized data is defined in one file to reduce space wastage from
* fragmentation.
*/
char *devs[] = { "wd", "dk", "fd", "wt", "da", 0 };
unsigned tw_chars = 0x5C2D2F7C; /* "\-/|" */

View File

@ -0,0 +1,5 @@
# $Id: Makefile,v 1.4 1998/09/17 23:52:03 msmith Exp $
SUBDIR= btx btxldr lib # client ldrtst
.include <bsd.subdir.mk>

View File

@ -0,0 +1,25 @@
# $Id: Makefile,v 1.5 1998/10/13 18:29:18 rnordier Exp $
M4?= m4
ORG= 0x9000
AFLAGS+= --defsym PC98=1
all: btx
btx: btx.o
.if ${OBJFORMAT} == aout
${LD} -nostdlib -N -s -T ${ORG} -o btx.out btx.o
dd if=btx.out of=${.TARGET} ibs=32 skip=1
.else
${LD} -N -e start -Ttext ${ORG} -o btx.out btx.o
objcopy -S -O binary btx.out ${.TARGET}
.endif
btx.o: btx.m4 btx.s
(cd ${.CURDIR}; ${M4} btx.m4 btx.s) | ${AS} ${AFLAGS} -o ${.TARGET}
CLEANFILES+= btx btx.out btx.o
.include <bsd.prog.mk>

1071
sys/boot/pc98/btx/btx/btx.S Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
#
# Copyright (c) 1998 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: btx.m4,v 1.1.1.1 1998/09/12 04:29:23 rnordier Exp $
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(o16,`.byte 0x66')dnl
define(addwia,`.byte 0x5; .word $1')dnl
define(lgdtwm,`.byte 0xf; .byte 0x1; .byte 0x16; .word $1')dnl
define(lidtwm,`.byte 0xf; .byte 0x1; .byte 0x1e; .word $1')dnl
define(cmpwmr,`.byte 0x3b; .byte ($2 << 0x3) | 0x6; .word $1')dnl
define(cmpwir,`.byte 0x81; .byte 0xf8 | $2; .word $1')dnl
define(movbr1,`.byte 0x88; .byte 0x40 | ($1 << 0x3) | $3; .byte $2')dnl
define(movwr0,`.byte 0x89; .byte ($1 << 0x3) | $2')dnl
define(leaw1r,`.byte 0x8d; .byte 0x40 | ($3 << 0x3) | $2; .byte $1')dnl
define(movwir,`.byte 0xb8 | $2; .word $1')dnl
define(movbi1,`.byte 0xc6; .byte 0x40 | $3; .byte $2; .byte $1')dnl
define(callwi,`.byte 0xe8; .word $1 - . - 0x2')dnl
define(jmpfwi,`.byte 0xea; .word $2; .word $1')dnl
define(tstbim,`.byte 0xf6; .byte 0x6; .word $2; .byte $1')dnl

1071
sys/boot/pc98/btx/btx/btx.s Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
# $Id: Makefile,v 1.6 1998/10/30 00:11:35 msmith Exp $
ORG=0x100000
#AFLAGS+= -x assembler-with-cpp
#AFLAGS+= --defsym PC98=1 --defsym BTXLDR_VERBOSE=1
AFLAGS+= --defsym PC98=1
all: btxldr
btxldr: btxldr.o
.if ${OBJFORMAT} == aout
${LD} -nostdlib -N -s -T ${ORG} -o btxldr.out btxldr.o
dd if=btxldr.out of=${.TARGET} ibs=32 skip=1
.else
${LD} -N -e start -Ttext ${ORG} -o btxldr.out btxldr.o
objcopy -S -O binary btxldr.out ${.TARGET}
.endif
btxldr.o: btxldr.s
# ${CC} ${AFLAGS} -c -o ${.TARGET} ${.CURDIR}/btxldr.s
${AS} ${AFLAGS} -o ${.TARGET} ${.CURDIR}/btxldr.s
CLEANFILES+= btxldr btxldr.out btxldr.o
.include <bsd.prog.mk>

View File

@ -0,0 +1,459 @@
#
# Copyright (c) 1998 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: btxldr.s,v 1.5 1999/01/22 13:07:17 rnordier Exp $
#
# Prototype BTX loader program, written in a couple of hours. The
# real thing should probably be more flexible, and in C.
#
#
# Memory locations.
#
.set MEM_STUB,0x600 # Real mode stub
.set MEM_ESP,0x1000 # New stack pointer
.set MEM_TBL,0x5000 # BTX page tables
.set MEM_ENTRY,0x9010 # BTX entry point
.set MEM_DATA,0x101000 # Data segment
#
# Segment selectors.
#
.set SEL_SCODE,0x8 # 4GB code
.set SEL_SDATA,0x10 # 4GB data
.set SEL_RCODE,0x18 # 64K code
.set SEL_RDATA,0x20 # 64K data
#
# Paging constants.
#
.set PAG_SIZ,0x1000 # Page size
.set PAG_ENT,0x4 # Page entry size
#
# Screen constants.
#
.ifdef PC98
.set SCR_MAT,0xe1 # Mode/attribute
.else
.set SCR_MAT,0x7 # Mode/attribute
.endif
.set SCR_COL,0x50 # Columns per row
.set SCR_ROW,0x19 # Rows per screen
#
# BIOS Data Area locations.
#
.ifdef PC98
.set BDA_MEM,0xa1501 # Free memory
.set BDA_POS,0xa153e # Cursor position
.else
.set BDA_MEM,0x413 # Free memory
.set BDA_SCR,0x449 # Video mode
.set BDA_POS,0x450 # Cursor position
.endif
#
# Required by aout gas inadequacy.
#
.set SIZ_STUB,0x1a # Size of stub
#
# We expect to be loaded by boot2 at 0x100000.
#
.globl start
#
# BTX program loader for ELF clients.
#
start: cld # String ops inc
.ifdef PC98
cli
gdcwait.1: inb $0x60,%al
testb $0x04,%al
jz gdcwait.1
movb $0xe0,%al
outb %al,$0x62
nop
gdcwait.2: inb $0x60,%al
testb $0x01,%al
jz gdcwait.2
inb $0x62,%al
movb %al,%dl
inb $0x62,%al
movb %al,%dh
inb $0x62,%al
inb $0x62,%al
inb $0x62,%al
shlw $1,%dx
movl $BDA_POS,%ebx
movw %dx,(%ebx)
.endif
movl $m_logo,%esi # Identify
call putstr # ourselves
movzwl BDA_MEM,%eax # Get base memory
.ifdef PC98
andl $0x7,%eax
incl %eax
shll $0x11,%eax # in bytes
.else
shll $0xa,%eax # in bytes
.endif
movl %eax,%ebp # Base of user stack
movl $m_mem,%esi # Display
call dhexout # amount of
call dputstr # base memory
lgdt gdtdesc # Load new GDT
#
# Relocate caller's arguments.
#
movl $m_esp,%esi # Display
movl %esp,%eax # caller's
call dhexout # stack
call dputstr # pointer
movl $m_args,%esi # Format string
leal 0x4(%esp,1),%ebx # First argument
movl $0x6,%ecx # Count
start.1: movl (%ebx),%eax # Get argument and
addl $0x4,%ebx # bump pointer
call dhexout # Display it
loop start.1 # Till done
call dputstr # End message
movl $0x48,%ecx # Allocate space
subl %ecx,%ebp # for bootinfo
movl 0x18(%esp,1),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # it
movl %ebp,0x18(%esp,1) # Update pointer
movl $m_rel_bi,%esi # Display
movl %ebp,%eax # bootinfo
call dhexout # relocation
call dputstr # message
movl $0x18,%ecx # Allocate space
subl %ecx,%ebp # for arguments
leal 0x4(%esp,1),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # them
movl $m_rel_args,%esi # Display
movl %ebp,%eax # argument
call dhexout # relocation
call dputstr # message
#
# Set up BTX kernel.
#
movl $MEM_ESP,%esp # Set up new stack
movl $MEM_DATA,%ebx # Data segment
movl $m_vers,%esi # Display BTX
call putstr # version message
movb 0x5(%ebx),%al # Get major version
addb $'0',%al # Display
call putchr # it
movb $'.',%al # And a
call putchr # dot
movb 0x6(%ebx),%al # Get minor
xorb %ah,%ah # version
movb $0xa,%dl # Divide
divb %dl,%al # by 10
addb $'0',%al # Display
call putchr # tens
movb %ah,%al # Get units
addb $'0',%al # Display
call putchr # units
call putstr # End message
movl %ebx,%esi # BTX image
movzwl 0x8(%ebx),%edi # Compute
orl $PAG_SIZ/PAG_ENT-1,%edi # the
incl %edi # BTX
shll $0x2,%edi # load
addl $MEM_TBL,%edi # address
pushl %edi # Save
movzwl 0xa(%ebx),%ecx # Image size
pushl %ecx # Save
rep # Relocate
movsb # BTX
movl %esi,%ebx # Keep place
movl $m_rel_btx,%esi # Restore
popl %eax # parameters
call dhexout # and
popl %ebp # display
movl %ebp,%eax # the
call dhexout # relocation
call dputstr # message
addl $PAG_SIZ,%ebp # Display
movl $m_base,%esi # the
movl %ebp,%eax # user
call dhexout # base
call dputstr # address
#
# Set up ELF-format client program.
#
cmpl $0x464c457f,(%ebx) # ELF magic number?
je start.3 # Yes
movl $e_fmt,%esi # Display error
call putstr # message
start.2: jmp start.2 # Hang
start.3: movl $m_elf,%esi # Display ELF
call dputstr # message
movl $m_segs,%esi # Format string
movl $0x2,%edi # Segment count
movl 0x1c(%ebx),%edx # Get e_phoff
addl %ebx,%edx # To pointer
movzwl 0x2c(%ebx),%ecx # Get e_phnum
start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
jne start.6 # No
movl 0x4(%edx),%eax # Display
call dhexout # p_offset
movl 0x8(%edx),%eax # Display
call dhexout # p_vaddr
movl 0x10(%edx),%eax # Display
call dhexout # p_filesz
movl 0x14(%edx),%eax # Display
call dhexout # p_memsz
call dputstr # End message
pushl %esi # Save
pushl %edi # working
pushl %ecx # registers
movl 0x4(%edx),%esi # Get p_offset
addl %ebx,%esi # as pointer
movl 0x8(%edx),%edi # Get p_vaddr
addl %ebp,%edi # as pointer
movl 0x10(%edx),%ecx # Get p_filesz
rep # Set up
movsb # segment
movl 0x14(%edx),%ecx # Any bytes
subl 0x10(%edx),%ecx # to zero?
jz start.5 # No
xorb %al,%al # Then
rep # zero
stosb # them
start.5: popl %ecx # Restore
popl %edi # working
popl %esi # registers
decl %edi # Segments to do
je start.7 # If none
start.6: addl $0x20,%edx # To next entry
loop start.4 # Till done
start.7: movl $m_done,%esi # Display done
call dputstr # message
movl $start.8,%esi # Real mode stub
movl $MEM_STUB,%edi # Destination
movl $SIZ_STUB,%ecx # Size
rep # Relocate
movsb # it
ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
start.8: xorl %eax,%eax # Data
movb $SEL_RDATA,%al # selector
movl %eax,%ss # Reload SS
movl %eax,%ds # Reset
movl %eax,%es # other
movl %eax,%fs # segment
movl %eax,%gs # limits
movl %cr0,%eax # Switch to
decl %eax # real
movl %eax,%cr0 # mode
.byte 0xea # Jump to
.word MEM_ENTRY # BTX entry
.word 0x0 # point
start.9:
#
# Output message [ESI] followed by EAX in hex.
#
dhexout:
.ifndef BTXLDR_VERBOSE
ret
.endif
hexout: pushl %eax # Save
call putstr # Display message
popl %eax # Restore
pushl %esi # Save
pushl %edi # caller's
movl $buf,%edi # Buffer
pushl %edi # Save
call hex32 # To hex
xorb %al,%al # Terminate
stosb # string
popl %esi # Restore
hexout.1: lodsb # Get a char
cmpb $'0',%al # Leading zero?
je hexout.1 # Yes
testb %al,%al # End of string?
jne hexout.2 # No
decl %esi # Undo
hexout.2: decl %esi # Adjust for inc
call putstr # Display hex
popl %edi # Restore
popl %esi # caller's
ret # To caller
#
# Output zero-terminated string [ESI] to the console.
#
dputstr:
.ifndef BTXLDR_VERBOSE
ret
.else
jmp putstr
.endif
putstr.0: call putchr # Output char
putstr: lodsb # Load char
testb %al,%al # End of string?
jne putstr.0 # No
ret # To caller
#
# Output character AL to the console.
#
dputchr:
.ifndef BTXLDR_VERBOSE
ret
.endif
putchr: pusha # Save
xorl %ecx,%ecx # Zero for loops
movb $SCR_MAT,%ah # Mode/attribute
movl $BDA_POS,%ebx # BDA pointer
movw (%ebx),%dx # Cursor position
.ifdef PC98
movl $0xa0000,%edi # Regen buffer (color)
.else
movl $0xb8000,%edi # Regen buffer (color)
cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
jne putchr.1 # No
xorw %di,%di # Regen buffer (mono)
.endif
putchr.1: cmpb $0xa,%al # New line?
je putchr.2 # Yes
.ifdef PC98
movw %dx,%cx
movb %al,(%edi,%ecx,1) # Write char
addl $0x2000,%ecx
movb %ah,(%edi,%ecx,1) # Write attr
addw $0x2,%dx
jmp putchr.3
putchr.2: movw %dx,%ax
movb $SCR_COL*2,%dl
div %dl
incb %al
mul %dl
movw %ax,%dx
putchr.3: cmpw $SCR_COL*SCR_ROW*2,%dx
.else
xchgl %eax,%ecx # Save char
movb $SCR_COL,%al # Columns per row
mulb %dh # * row position
addb %dl,%al # + column
adcb $0x0,%ah # position
shll %eax # * 2
xchgl %eax,%ecx # Swap char, offset
movw %ax,(%edi,%ecx,1) # Write attr:char
incl %edx # Bump cursor
cmpb $SCR_COL,%dl # Beyond row?
jb putchr.3 # No
putchr.2: xorb %dl,%dl # Zero column
incb %dh # Bump row
putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
.endif
jb putchr.4 # No
leal 2*SCR_COL(%edi),%esi # New top line
movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
rep # Scroll
movsl # screen
movb $' ',%al # Space
.ifdef PC98
xorb %ah,%ah
.endif
movb $SCR_COL,%cl # Columns to clear
rep # Clear
stosw # line
.ifdef PC98
movw $(SCR_ROW-1)*SCR_COL*2,%dx
putchr.4: movw %dx,(%ebx) # Update position
shrw $1,%dx
gdcwait.3: inb $0x60,%al
testb $0x04,%al
jz gdcwait.3
movb $0x49,%al
outb %al,$0x62
movb %dl,%al
outb %al,$0x60
movb %dh,%al
outb %al,$0x60
.else
movb $SCR_ROW-1,%dh # Bottom line
putchr.4: movw %dx,(%ebx) # Update position
.endif
popa # Restore
ret # To caller
#
# Convert EAX, AX, or AL to hex, saving the result to [EDI].
#
hex32: pushl %eax # Save
shrl $0x10,%eax # Do upper
call hex16 # 16
popl %eax # Restore
hex16: call hex16.1 # Do upper 8
hex16.1: xchgb %ah,%al # Save/restore
hex8: pushl %eax # Save
shrb $0x4,%al # Do upper
call hex8.1 # 4
popl %eax # Restore
hex8.1: andb $0xf,%al # Get lower 4
cmpb $0xa,%al # Convert
sbbb $0x69,%al # to hex
das # digit
orb $0x20,%al # To lower case
stosb # Save char
ret # (Recursive)
.data
.p2align 4
#
# Global descriptor table.
#
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
.word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
.word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
.word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
.word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
gdt.1:
gdtdesc: .word gdt.1-gdt-1 # Limit
.long gdt # Base
#
# Messages.
#
m_logo: .asciz "\nBTX loader 1.00 "
m_vers: .asciz "BTX version is \0\n"
e_fmt: .asciz "Error: Client format not supported\n"
#.ifdef BTXLDR_VERBOSE
m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
m_esp: .asciz "Arguments passed (esp=\0):\n"
m_args: .asciz"<howto="
.asciz" bootdev="
.asciz" junk="
.asciz" "
.asciz" "
.asciz" bootinfo=\0>\n"
m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
m_base: .asciz "Client base address is \0\n"
m_elf: .asciz "Client format is ELF\n"
m_segs: .asciz "text segment: offset="
.asciz " vaddr="
.asciz " filesz="
.asciz " memsz=\0\n"
.asciz "data segment: offset="
.asciz " vaddr="
.asciz " filesz="
.asciz " memsz=\0\n"
m_done: .asciz "Loading complete\n"
#.endif
#
# Uninitialized data area.
#
buf: # Scratch buffer

View File

@ -0,0 +1,459 @@
#
# Copyright (c) 1998 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: btxldr.s,v 1.5 1999/01/22 13:07:17 rnordier Exp $
#
# Prototype BTX loader program, written in a couple of hours. The
# real thing should probably be more flexible, and in C.
#
#
# Memory locations.
#
.set MEM_STUB,0x600 # Real mode stub
.set MEM_ESP,0x1000 # New stack pointer
.set MEM_TBL,0x5000 # BTX page tables
.set MEM_ENTRY,0x9010 # BTX entry point
.set MEM_DATA,0x101000 # Data segment
#
# Segment selectors.
#
.set SEL_SCODE,0x8 # 4GB code
.set SEL_SDATA,0x10 # 4GB data
.set SEL_RCODE,0x18 # 64K code
.set SEL_RDATA,0x20 # 64K data
#
# Paging constants.
#
.set PAG_SIZ,0x1000 # Page size
.set PAG_ENT,0x4 # Page entry size
#
# Screen constants.
#
.ifdef PC98
.set SCR_MAT,0xe1 # Mode/attribute
.else
.set SCR_MAT,0x7 # Mode/attribute
.endif
.set SCR_COL,0x50 # Columns per row
.set SCR_ROW,0x19 # Rows per screen
#
# BIOS Data Area locations.
#
.ifdef PC98
.set BDA_MEM,0xa1501 # Free memory
.set BDA_POS,0xa153e # Cursor position
.else
.set BDA_MEM,0x413 # Free memory
.set BDA_SCR,0x449 # Video mode
.set BDA_POS,0x450 # Cursor position
.endif
#
# Required by aout gas inadequacy.
#
.set SIZ_STUB,0x1a # Size of stub
#
# We expect to be loaded by boot2 at 0x100000.
#
.globl start
#
# BTX program loader for ELF clients.
#
start: cld # String ops inc
.ifdef PC98
cli
gdcwait.1: inb $0x60,%al
testb $0x04,%al
jz gdcwait.1
movb $0xe0,%al
outb %al,$0x62
nop
gdcwait.2: inb $0x60,%al
testb $0x01,%al
jz gdcwait.2
inb $0x62,%al
movb %al,%dl
inb $0x62,%al
movb %al,%dh
inb $0x62,%al
inb $0x62,%al
inb $0x62,%al
shlw $1,%dx
movl $BDA_POS,%ebx
movw %dx,(%ebx)
.endif
movl $m_logo,%esi # Identify
call putstr # ourselves
movzwl BDA_MEM,%eax # Get base memory
.ifdef PC98
andl $0x7,%eax
incl %eax
shll $0x11,%eax # in bytes
.else
shll $0xa,%eax # in bytes
.endif
movl %eax,%ebp # Base of user stack
movl $m_mem,%esi # Display
call dhexout # amount of
call dputstr # base memory
lgdt gdtdesc # Load new GDT
#
# Relocate caller's arguments.
#
movl $m_esp,%esi # Display
movl %esp,%eax # caller's
call dhexout # stack
call dputstr # pointer
movl $m_args,%esi # Format string
leal 0x4(%esp,1),%ebx # First argument
movl $0x6,%ecx # Count
start.1: movl (%ebx),%eax # Get argument and
addl $0x4,%ebx # bump pointer
call dhexout # Display it
loop start.1 # Till done
call dputstr # End message
movl $0x48,%ecx # Allocate space
subl %ecx,%ebp # for bootinfo
movl 0x18(%esp,1),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # it
movl %ebp,0x18(%esp,1) # Update pointer
movl $m_rel_bi,%esi # Display
movl %ebp,%eax # bootinfo
call dhexout # relocation
call dputstr # message
movl $0x18,%ecx # Allocate space
subl %ecx,%ebp # for arguments
leal 0x4(%esp,1),%esi # Source
movl %ebp,%edi # Destination
rep # Copy
movsb # them
movl $m_rel_args,%esi # Display
movl %ebp,%eax # argument
call dhexout # relocation
call dputstr # message
#
# Set up BTX kernel.
#
movl $MEM_ESP,%esp # Set up new stack
movl $MEM_DATA,%ebx # Data segment
movl $m_vers,%esi # Display BTX
call putstr # version message
movb 0x5(%ebx),%al # Get major version
addb $'0',%al # Display
call putchr # it
movb $'.',%al # And a
call putchr # dot
movb 0x6(%ebx),%al # Get minor
xorb %ah,%ah # version
movb $0xa,%dl # Divide
divb %dl,%al # by 10
addb $'0',%al # Display
call putchr # tens
movb %ah,%al # Get units
addb $'0',%al # Display
call putchr # units
call putstr # End message
movl %ebx,%esi # BTX image
movzwl 0x8(%ebx),%edi # Compute
orl $PAG_SIZ/PAG_ENT-1,%edi # the
incl %edi # BTX
shll $0x2,%edi # load
addl $MEM_TBL,%edi # address
pushl %edi # Save
movzwl 0xa(%ebx),%ecx # Image size
pushl %ecx # Save
rep # Relocate
movsb # BTX
movl %esi,%ebx # Keep place
movl $m_rel_btx,%esi # Restore
popl %eax # parameters
call dhexout # and
popl %ebp # display
movl %ebp,%eax # the
call dhexout # relocation
call dputstr # message
addl $PAG_SIZ,%ebp # Display
movl $m_base,%esi # the
movl %ebp,%eax # user
call dhexout # base
call dputstr # address
#
# Set up ELF-format client program.
#
cmpl $0x464c457f,(%ebx) # ELF magic number?
je start.3 # Yes
movl $e_fmt,%esi # Display error
call putstr # message
start.2: jmp start.2 # Hang
start.3: movl $m_elf,%esi # Display ELF
call dputstr # message
movl $m_segs,%esi # Format string
movl $0x2,%edi # Segment count
movl 0x1c(%ebx),%edx # Get e_phoff
addl %ebx,%edx # To pointer
movzwl 0x2c(%ebx),%ecx # Get e_phnum
start.4: cmpl $0x1,(%edx) # Is p_type PT_LOAD?
jne start.6 # No
movl 0x4(%edx),%eax # Display
call dhexout # p_offset
movl 0x8(%edx),%eax # Display
call dhexout # p_vaddr
movl 0x10(%edx),%eax # Display
call dhexout # p_filesz
movl 0x14(%edx),%eax # Display
call dhexout # p_memsz
call dputstr # End message
pushl %esi # Save
pushl %edi # working
pushl %ecx # registers
movl 0x4(%edx),%esi # Get p_offset
addl %ebx,%esi # as pointer
movl 0x8(%edx),%edi # Get p_vaddr
addl %ebp,%edi # as pointer
movl 0x10(%edx),%ecx # Get p_filesz
rep # Set up
movsb # segment
movl 0x14(%edx),%ecx # Any bytes
subl 0x10(%edx),%ecx # to zero?
jz start.5 # No
xorb %al,%al # Then
rep # zero
stosb # them
start.5: popl %ecx # Restore
popl %edi # working
popl %esi # registers
decl %edi # Segments to do
je start.7 # If none
start.6: addl $0x20,%edx # To next entry
loop start.4 # Till done
start.7: movl $m_done,%esi # Display done
call dputstr # message
movl $start.8,%esi # Real mode stub
movl $MEM_STUB,%edi # Destination
movl $SIZ_STUB,%ecx # Size
rep # Relocate
movsb # it
ljmp $SEL_RCODE,$MEM_STUB # To 16-bit code
start.8: xorl %eax,%eax # Data
movb $SEL_RDATA,%al # selector
movl %eax,%ss # Reload SS
movl %eax,%ds # Reset
movl %eax,%es # other
movl %eax,%fs # segment
movl %eax,%gs # limits
movl %cr0,%eax # Switch to
decl %eax # real
movl %eax,%cr0 # mode
.byte 0xea # Jump to
.word MEM_ENTRY # BTX entry
.word 0x0 # point
start.9:
#
# Output message [ESI] followed by EAX in hex.
#
dhexout:
.ifndef BTXLDR_VERBOSE
ret
.endif
hexout: pushl %eax # Save
call putstr # Display message
popl %eax # Restore
pushl %esi # Save
pushl %edi # caller's
movl $buf,%edi # Buffer
pushl %edi # Save
call hex32 # To hex
xorb %al,%al # Terminate
stosb # string
popl %esi # Restore
hexout.1: lodsb # Get a char
cmpb $'0',%al # Leading zero?
je hexout.1 # Yes
testb %al,%al # End of string?
jne hexout.2 # No
decl %esi # Undo
hexout.2: decl %esi # Adjust for inc
call putstr # Display hex
popl %edi # Restore
popl %esi # caller's
ret # To caller
#
# Output zero-terminated string [ESI] to the console.
#
dputstr:
.ifndef BTXLDR_VERBOSE
ret
.else
jmp putstr
.endif
putstr.0: call putchr # Output char
putstr: lodsb # Load char
testb %al,%al # End of string?
jne putstr.0 # No
ret # To caller
#
# Output character AL to the console.
#
dputchr:
.ifndef BTXLDR_VERBOSE
ret
.endif
putchr: pusha # Save
xorl %ecx,%ecx # Zero for loops
movb $SCR_MAT,%ah # Mode/attribute
movl $BDA_POS,%ebx # BDA pointer
movw (%ebx),%dx # Cursor position
.ifdef PC98
movl $0xa0000,%edi # Regen buffer (color)
.else
movl $0xb8000,%edi # Regen buffer (color)
cmpb %ah,BDA_SCR-BDA_POS(%ebx) # Mono mode?
jne putchr.1 # No
xorw %di,%di # Regen buffer (mono)
.endif
putchr.1: cmpb $0xa,%al # New line?
je putchr.2 # Yes
.ifdef PC98
movw %dx,%cx
movb %al,(%edi,%ecx,1) # Write char
addl $0x2000,%ecx
movb %ah,(%edi,%ecx,1) # Write attr
addw $0x2,%dx
jmp putchr.3
putchr.2: movw %dx,%ax
movb $SCR_COL*2,%dl
div %dl
incb %al
mul %dl
movw %ax,%dx
putchr.3: cmpw $SCR_COL*SCR_ROW*2,%dx
.else
xchgl %eax,%ecx # Save char
movb $SCR_COL,%al # Columns per row
mulb %dh # * row position
addb %dl,%al # + column
adcb $0x0,%ah # position
shll %eax # * 2
xchgl %eax,%ecx # Swap char, offset
movw %ax,(%edi,%ecx,1) # Write attr:char
incl %edx # Bump cursor
cmpb $SCR_COL,%dl # Beyond row?
jb putchr.3 # No
putchr.2: xorb %dl,%dl # Zero column
incb %dh # Bump row
putchr.3: cmpb $SCR_ROW,%dh # Beyond screen?
.endif
jb putchr.4 # No
leal 2*SCR_COL(%edi),%esi # New top line
movw $(SCR_ROW-1)*SCR_COL/2,%cx # Words to move
rep # Scroll
movsl # screen
movb $' ',%al # Space
.ifdef PC98
xorb %ah,%ah
.endif
movb $SCR_COL,%cl # Columns to clear
rep # Clear
stosw # line
.ifdef PC98
movw $(SCR_ROW-1)*SCR_COL*2,%dx
putchr.4: movw %dx,(%ebx) # Update position
shrw $1,%dx
gdcwait.3: inb $0x60,%al
testb $0x04,%al
jz gdcwait.3
movb $0x49,%al
outb %al,$0x62
movb %dl,%al
outb %al,$0x60
movb %dh,%al
outb %al,$0x60
.else
movb $SCR_ROW-1,%dh # Bottom line
putchr.4: movw %dx,(%ebx) # Update position
.endif
popa # Restore
ret # To caller
#
# Convert EAX, AX, or AL to hex, saving the result to [EDI].
#
hex32: pushl %eax # Save
shrl $0x10,%eax # Do upper
call hex16 # 16
popl %eax # Restore
hex16: call hex16.1 # Do upper 8
hex16.1: xchgb %ah,%al # Save/restore
hex8: pushl %eax # Save
shrb $0x4,%al # Do upper
call hex8.1 # 4
popl %eax # Restore
hex8.1: andb $0xf,%al # Get lower 4
cmpb $0xa,%al # Convert
sbbb $0x69,%al # to hex
das # digit
orb $0x20,%al # To lower case
stosb # Save char
ret # (Recursive)
.data
.p2align 4
#
# Global descriptor table.
#
gdt: .word 0x0,0x0,0x0,0x0 # Null entry
.word 0xffff,0x0,0x9a00,0xcf # SEL_SCODE
.word 0xffff,0x0,0x9200,0xcf # SEL_SDATA
.word 0xffff,0x0,0x9a00,0x0 # SEL_RCODE
.word 0xffff,0x0,0x9200,0x0 # SEL_RDATA
gdt.1:
gdtdesc: .word gdt.1-gdt-1 # Limit
.long gdt # Base
#
# Messages.
#
m_logo: .asciz "\nBTX loader 1.00 "
m_vers: .asciz "BTX version is \0\n"
e_fmt: .asciz "Error: Client format not supported\n"
#.ifdef BTXLDR_VERBOSE
m_mem: .asciz "Starting in protected mode (base mem=\0)\n"
m_esp: .asciz "Arguments passed (esp=\0):\n"
m_args: .asciz"<howto="
.asciz" bootdev="
.asciz" junk="
.asciz" "
.asciz" "
.asciz" bootinfo=\0>\n"
m_rel_bi: .asciz "Relocated bootinfo (size=48) to \0\n"
m_rel_args: .asciz "Relocated arguments (size=18) to \0\n"
m_rel_btx: .asciz "Relocated kernel (size=\0) to \0\n"
m_base: .asciz "Client base address is \0\n"
m_elf: .asciz "Client format is ELF\n"
m_segs: .asciz "text segment: offset="
.asciz " vaddr="
.asciz " filesz="
.asciz " memsz=\0\n"
.asciz "data segment: offset="
.asciz " vaddr="
.asciz " filesz="
.asciz " memsz=\0\n"
m_done: .asciz "Loading complete\n"
#.endif
#
# Uninitialized data area.
#
buf: # Scratch buffer

View File

@ -0,0 +1,20 @@
# $Id: Makefile,v 1.2 1998/10/11 11:27:48 rnordier Exp $
OBJS= btxcsu.o btxsys.o btxv86.o
AFLAGS+= -elf
LDFLAGS+= -elf
CLEANFILES+= crt0.o
INTERNALLIB= true
NOMAN= true
NOPIC= true
NOPROFILE= true
all: crt0.o
crt0.o: ${OBJS}
${LD} ${LDFLAGS} -i -o ${.TARGET} ${OBJS}
.include <bsd.lib.mk>
.s.o:
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}

View File

@ -0,0 +1,43 @@
#
# Copyright (c) 1998 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: btxcsu.s,v 1.2 1998/10/04 21:15:45 rnordier Exp $
#
# BTX C startup code (ELF).
#
#
# Globals.
#
.global _start
#
# Constants.
#
.set ARGADJ,0xfa0 # Argument adjustment
#
# Client entry point.
#
_start: movl %eax,__base # Set base address
movl %esp,%eax # Set
addl $ARGADJ,%eax # argument
movl %eax,__args # pointer
call main # Invoke client main()
call exit # Invoke client exit()
#
# Data.
#
.comm __base,4 # Client base address
.comm __args,4 # Client arguments

View File

@ -0,0 +1,40 @@
#
# Copyright (c) 1998 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: btxsys.s,v 1.1 1998/09/14 10:37:00 rnordier Exp $
#
# BTX system calls.
#
#
# Globals.
#
.global __exit
.global __exec
#
# Constants.
#
.set INT_SYS,0x30 # Interrupt number
#
# System call: exit
#
__exit: xorl %eax,%eax # BTX system
int $INT_SYS # call 0x0
#
# System call: exec
#
__exec: movl $0x1,%eax # BTX system
int $INT_SYS # call 0x1

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 1998 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: btxv86.h,v 1.4 1998/10/02 20:52:26 msmith Exp $
*/
#ifndef _BTXV86_H_
#define _BTXV86_H_
#include <sys/types.h>
#define V86_ADDR 0x10000 /* Segment:offset address */
#define V86_CALLF 0x20000 /* Emulate far call */
#define V86_FLAGS 0x40000 /* Return flags */
struct __v86 {
uint32_t ctl; /* Control flags */
uint32_t addr; /* Interrupt number or address */
uint32_t es; /* V86 ES register */
uint32_t ds; /* V86 DS register */
uint32_t fs; /* V86 FS register */
uint32_t gs; /* V86 GS register */
uint32_t eax; /* V86 EAX register */
uint32_t ecx; /* V86 ECX register */
uint32_t edx; /* V86 EDX register */
uint32_t ebx; /* V86 EBX register */
uint32_t efl; /* V86 eflags register */
uint32_t ebp; /* V86 EBP register */
uint32_t esi; /* V86 ESI register */
uint32_t edi; /* V86 EDI register */
};
extern struct __v86 __v86; /* V86 interface structure */
void __v86int(void);
#define v86 __v86
#define v86int __v86int
extern u_int32_t __base;
extern u_int32_t __args;
#define PTOV(pa) ((caddr_t)(pa) - __base)
#define VTOP(va) ((vm_offset_t)(va) + __base)
#define VTOPSEG(va) (u_int16_t)(VTOP((caddr_t)va) >> 4)
#define VTOPOFF(va) (u_int16_t)(VTOP((caddr_t)va) & 0xf)
void __exit(int) __attribute__((__noreturn__));
void __exec(caddr_t, ...);
#endif /* !_BTXV86_H_ */

View File

@ -0,0 +1,85 @@
#
# Copyright (c) 1998 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: btxv86.s,v 1.2 1998/10/22 20:22:07 msmith Exp $
#
# BTX V86 interface.
#
#
# Globals.
#
.global __v86int
#
# Fields in V86 interface structure.
#
.set V86_CTL,0x0 # Control flags
.set V86_ADDR,0x4 # Int number/address
.set V86_ES,0x8 # V86 ES
.set V86_DS,0xc # V86 DS
.set V86_FS,0x10 # V86 FS
.set V86_GS,0x14 # V86 GS
.set V86_EAX,0x18 # V86 EAX
.set V86_ECX,0x1c # V86 ECX
.set V86_EDX,0x20 # V86 EDX
.set V86_EBX,0x24 # V86 EBX
.set V86_EFL,0x28 # V86 eflags
.set V86_EBP,0x2c # V86 EBP
.set V86_ESI,0x30 # V86 ESI
.set V86_EDI,0x34 # V86 EDI
#
# Other constants.
#
.set INT_V86,0x31 # Interrupt number
.set SIZ_V86,0x38 # Size of V86 structure
#
# V86 interface function.
#
__v86int: popl __v86ret # Save return address
pushl $__v86 # Push pointer
call __v86_swap # Load V86 registers
int $INT_V86 # To BTX
call __v86_swap # Load user registers
addl $0x4,%esp # Discard pointer
pushl __v86ret # Restore return address
ret # To user
#
# Swap V86 and user registers.
#
__v86_swap: xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
xchgl %eax,V86_EAX(%ebp) # Swap EAX
xchgl %ecx,V86_ECX(%ebp) # Swap ECX
xchgl %edx,V86_EDX(%ebp) # Swap EDX
xchgl %ebx,V86_EBX(%ebp) # Swap EBX
pushl %eax # Save
pushf # Put eflags
popl %eax # in EAX
xchgl %eax,V86_EFL(%ebp) # Swap
pushl %eax # Put EAX
popf # in eflags
movl 0x8(%esp,1),%eax # Load EBP
xchgl %eax,V86_EBP(%ebp) # Swap
movl %eax,0x8(%esp,1) # Save EBP
popl %eax # Restore
xchgl %esi,V86_ESI(%ebp) # Swap ESI
xchgl %edi,V86_EDI(%ebp) # Swap EDI
xchgl %ebp,0x4(%esp,1) # Swap pointer, EBP
ret # To caller
#
# V86 interface structure.
#
.comm __v86,SIZ_V86
.comm __v86ret,4

View File

@ -0,0 +1,42 @@
# $Id: Makefile,v 1.13 1999/01/10 14:48:04 rnordier Exp $
#
LIB= pc98
NOPIC=
NOPROFILE=
INTERNALLIB= true
INTERNALSTATICLIB= true
SRCS= aout_freebsd.c biosdisk.c biosmem.c biospnp.c biospci.c \
bootinfo.c comconsole.c devicename.c elf_freebsd.c gatea20.c \
i386_copy.c i386_module.c time.c vidconsole.c
.PATH: ${.CURDIR}/../../i386/libi386
CFLAGS+= -DPC98
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
-I${.CURDIR}/../../.. -I. -I${.CURDIR}/../../i386/libi386
BOOT_COMCONSOLE_PORT?= 0x238
CFLAGS+= -DCOMPORT=${BOOT_COMCONSOLE_PORT}
BOOT_COMCONSOLE_SPEED?= 9600
CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
# Make the disk code more talkative
#CFLAGS+= -DDISK_DEBUG
# Include simple terminal emulation (cons25-compatible)
CFLAGS+= -DTERM_EMU
# If it's not there, don't consider it a target
.if exists(${.CURDIR}/../../../i386/include)
beforedepend ${OBJS}: machine
machine:
ln -sf ${.CURDIR}/../../../i386/include machine
.endif
CLEANFILES+= machine
.include <bsd.lib.mk>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,59 @@
/*
* mjs copyright
*/
/*
* Obtain memory configuration information from the BIOS
*
* Note that we don't try too hard here; knowing the size of
* base memory and extended memory out to 16 or 64M is enough for
* the requirements of the bootstrap.
*
* We also maintain a pointer to the top of physical memory
* once called to allow rangechecking of load/copy requests.
*/
#include <stand.h>
#include "btxv86.h"
vm_offset_t memtop;
/*
* Return base memory size in kB.
*/
int
getbasemem(void)
{
#ifdef PC98
return ((*(u_char *)PTOV(0xA1501)&0x07)+1)*128;
#else
v86.ctl = 0;
v86.addr = 0x12; /* int 0x12 */
v86int();
return(v86.eax & 0xffff);
#endif
}
/*
* Return extended memory size in kB
*/
int
getextmem(void)
{
int extkb;
#ifdef PC98
extkb = *(u_char *)PTOV(0xA1401)*128 + *(unsigned short *)PTOV(0xA1594)*1024;
#else
v86.ctl = 0;
v86.addr = 0x15; /* int 0x15 function 0x88*/
v86.eax = 0x8800;
v86int();
extkb = v86.eax & 0xffff;
#endif
/* Set memtop to actual top or 16M, whicheve is less */
memtop = min((0x100000 + (extkb * 1024)), (16 * 1024 * 1024));
return(extkb);
}

View File

@ -0,0 +1,331 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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 AND CONTRIBUTORS ``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 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.
*
* $Id: bootinfo.c,v 1.16 1999/01/24 00:12:04 msmith Exp $
*/
#include <stand.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/linker.h>
#include <machine/bootinfo.h>
#include "bootstrap.h"
#include "libi386.h"
#include "btxv86.h"
static struct bootinfo bi;
#ifdef PC98
extern struct bootinfo *initial_bootinfo;
#endif
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
*/
static struct
{
char *ev;
int mask;
} howto_names[] = {
{"boot_askname", RB_ASKNAME},
{"boot_userconfig", RB_CONFIG},
{"boot_ddb", RB_KDB},
{"boot_gdb", RB_GDB},
{"boot_single", RB_SINGLE},
{"boot_verbose", RB_VERBOSE},
{NULL, 0}
};
int
bi_getboothowto(char *kargs)
{
char *cp;
int howto;
int active;
int i;
/* Parse kargs */
howto = 0;
if (kargs != NULL) {
cp = kargs;
active = 0;
while (*cp != 0) {
if (!active && (*cp == '-')) {
active = 1;
} else if (active)
switch (*cp) {
case 'a':
howto |= RB_ASKNAME;
break;
case 'c':
howto |= RB_CONFIG;
break;
case 'd':
howto |= RB_KDB;
break;
case 'g':
howto |= RB_GDB;
break;
case 'h':
howto |= RB_SERIAL;
break;
case 'r':
howto |= RB_DFLTROOT;
break;
case 's':
howto |= RB_SINGLE;
break;
case 'v':
howto |= RB_VERBOSE;
break;
default:
active = 0;
break;
}
cp++;
}
}
/* get equivalents from the environment */
for (i = 0; howto_names[i].ev != NULL; i++)
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
if (!strcmp(getenv("console"), "comconsole"))
howto |= RB_SERIAL;
return(howto);
}
/*
* Copy the environment into the load area starting at (addr).
* Each variable is formatted as <name>=<value>, with a single nul
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
bi_copyenv(vm_offset_t addr)
{
struct env_var *ep;
/* traverse the environment */
for (ep = environ; ep != NULL; ep = ep->ev_next) {
i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
addr += strlen(ep->ev_name);
i386_copyin("=", addr, 1);
addr++;
if (ep->ev_value != NULL) {
i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
addr += strlen(ep->ev_value);
}
i386_copyin("", addr, 1);
addr++;
}
i386_copyin("", addr, 1);
addr++;
return(addr);
}
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
*
* Module data is presented in a self-describing format. Each datum
* is preceeded by a 32-bit identifier and a 32-bit size field.
*
* Currently, the following data are saved:
*
* MOD_NAME (variable) module name (string)
* MOD_TYPE (variable) module type (string)
* MOD_ADDR sizeof(vm_offset_t) module load address
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
#define COPY32(v, a) { \
u_int32_t x = (v); \
i386_copyin(&x, a, sizeof(x)); \
a += sizeof(x); \
}
#define MOD_STR(t, a, s) { \
COPY32(t, a); \
COPY32(strlen(s) + 1, a); \
i386_copyin(s, a, strlen(s) + 1); \
a += roundup(strlen(s) + 1, sizeof(u_long));\
}
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
#define MOD_VAR(t, a, s) { \
COPY32(t, a); \
COPY32(sizeof(s), a); \
i386_copyin(&s, a, sizeof(s)); \
a += roundup(sizeof(s), sizeof(u_long)); \
}
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
#define MOD_METADATA(a, mm) { \
COPY32(MODINFO_METADATA | mm->md_type, a); \
COPY32(mm->md_size, a); \
i386_copyin(mm->md_data, a, mm->md_size); \
a += roundup(mm->md_size, sizeof(u_long));\
}
#define MOD_END(a) { \
COPY32(MODINFO_END, a); \
COPY32(0, a); \
}
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct loaded_module *mp;
struct module_metadata *md;
/* start with the first module on the list, should be the kernel */
for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) {
MOD_NAME(addr, mp->m_name); /* this field must come first */
MOD_TYPE(addr, mp->m_type);
MOD_ADDR(addr, mp->m_addr);
MOD_SIZE(addr, mp->m_size);
for (md = mp->m_metadata; md != NULL; md = md->md_next)
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
MOD_END(addr);
return(addr);
}
/*
* Load the information expected by an i386 kernel.
*
* - The 'boothowto' argument is constructed
* - The 'botdev' argument is constructed
* - The 'bootinfo' struct is constructed, and copied into the kernel space.
* - The kernel environment is copied into kernel space.
* - Module metadata are formatted and placed in kernel space.
*/
int
bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip)
{
struct loaded_module *xp;
struct i386_devdesc *rootdev;
vm_offset_t addr, bootinfo_addr;
char *rootdevname;
int bootdevnr;
u_int pad;
char *kernelname;
const char *kernelpath;
#ifdef PC98
int i;
#endif
*howtop = bi_getboothowto(args);
/*
* Allow the environment variable 'rootdev' to override the supplied device
* This should perhaps go to MI code and/or have $rootdev tested/set by
* MI code before launching the kernel.
*/
rootdevname = getenv("rootdev");
i386_getdev((void **)(&rootdev), rootdevname, NULL);
if (rootdev == NULL) { /* bad $rootdev/$currdev */
printf("can't determine root device\n");
return(EINVAL);
}
switch(rootdev->d_type) {
case DEVT_DISK:
/* pass in the BIOS device number of the current disk */
bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit);
bootdevnr = bd_getdev(rootdev);
if (bootdevnr != -1)
break;
printf("root device %s invalid\n", i386_fmtdev(rootdev));
return(EINVAL);
default:
printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
}
free(rootdev);
*bootdevp = bootdevnr;
/* legacy bootinfo structure */
bi.bi_version = BOOTINFO_VERSION;
bi.bi_kernelname = 0; /* XXX char * -> kernel name */
bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */
bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */
/* bi.bi_bios_geom[] */
#ifdef PC98
for(i = 0; i < N_BIOS_GEOM; i++)
bi.bi_bios_geom[i] = initial_bootinfo->bi_bios_geom[i];
#endif
bi.bi_size = sizeof(bi);
bi.bi_memsizes_valid = 1;
bi.bi_basemem = getbasemem();
bi.bi_extmem = getextmem();
/* find the last module in the chain */
addr = 0;
for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) {
if (addr < (xp->m_addr + xp->m_size))
addr = xp->m_addr + xp->m_size;
}
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy our environment */
bi.bi_envp = addr;
addr = bi_copyenv(addr);
/* pad to a page boundary */
pad = (u_int)addr & PAGE_MASK;
if (pad != 0) {
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy module list and metadata */
bi.bi_modulep = addr;
addr = bi_copymodules(addr);
/* all done copying stuff in, save end of loaded object space */
bi.bi_kernend = addr;
*howtop |= RB_BOOTINFO; /* it's there now */
/*
* Get the kernel name, strip off any device prefix.
*/
kernelname = getenv("kernelname");
i386_getdev(NULL, kernelname, &kernelpath);
bi.bi_kernelname = VTOP(kernelpath);
*bip = VTOP(&bi);
return(0);
}

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
*
* 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 AND CONTRIBUTORS ``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 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.
*
* $Id: comconsole.c,v 1.6 1999/01/10 14:48:05 rnordier Exp $
*/
#include <stand.h>
#include <bootstrap.h>
#include <machine/cpufunc.h>
#include "libi386.h"
/* selected defines from ns16550.h */
#define com_data 0 /* data register (R/W) */
#define com_dlbl 0 /* divisor latch low (W) */
#define com_dlbh 1 /* divisor latch high (W) */
#define com_ier 1 /* interrupt enable (W) */
#define com_iir 2 /* interrupt identification (R) */
#define com_fifo 2 /* FIFO control (W) */
#define com_lctl 3 /* line control register (R/W) */
#define com_cfcr 3 /* line control register (R/W) */
#define com_mcr 4 /* modem control register (R/W) */
#define com_lsr 5 /* line status register (R/W) */
#define com_msr 6 /* modem status register (R/W) */
/* selected defines from sioreg.h */
#define CFCR_DLAB 0x80
#define MCR_RTS 0x02
#define MCR_DTR 0x01
#define LSR_TXRDY 0x20
#define LSR_RXRDY 0x01
#define COMC_FMT 0x3 /* 8N1 */
#define COMC_TXWAIT 0x40000 /* transmit timeout */
#define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */
#ifndef COMPORT
#ifdef PC98
#define COMPORT 0x238
#else
#define COMPORT 0x3f8
#endif
#endif
#ifndef COMSPEED
#define COMSPEED 9600
#endif
static void comc_probe(struct console *cp);
static int comc_init(int arg);
static void comc_putchar(int c);
static int comc_getchar(void);
static int comc_ischar(void);
static int comc_started;
struct console comconsole = {
"comconsole",
"serial port",
0,
comc_probe,
comc_init,
comc_putchar,
comc_getchar,
comc_ischar
};
static void
comc_probe(struct console *cp)
{
/* XXX check the BIOS equipment list? */
cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
}
static int
comc_init(int arg)
{
if (comc_started && arg == 0)
return 0;
comc_started = 1;
outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff);
outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8);
outb(COMPORT + com_cfcr, COMC_FMT);
outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
do
inb(COMPORT + com_data);
while (inb(COMPORT + com_lsr) & LSR_RXRDY);
return(0);
}
static void
comc_putchar(int c)
{
int wait;
for (wait = COMC_TXWAIT; wait > 0; wait--)
if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
outb(COMPORT + com_data, c);
break;
}
}
static int
comc_getchar(void)
{
return(comc_ischar() ? inb(COMPORT + com_data) : -1);
}
static int
comc_ischar(void)
{
return(inb(COMPORT + com_lsr) & LSR_RXRDY);
}

View File

@ -0,0 +1,57 @@
/*
* $Id: gatea20.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
* From: $NetBSD: gatea20.c,v 1.2 1997/10/29 00:32:49 fvdl Exp $
*/
/* extracted from freebsd:sys/i386/boot/biosboot/io.c */
#include <sys/types.h>
#include <machine/cpufunc.h>
#include <stand.h>
#include "libi386.h"
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keyboard status */
#define K_CMD 0x64 /* keybd ctlr command (write-only) */
#define K_OBUF_FUL 0x01 /* output buffer full */
#define K_IBUF_FUL 0x02 /* input buffer full */
#define KC_CMD_WIN 0xd0 /* read output port */
#define KC_CMD_WOUT 0xd1 /* write output port */
#define KB_A20 0x9f /* enable A20,
reset (!),
enable output buffer full interrupt
enable data line
disable clock line */
/*
* Gate A20 for high memory
*/
static unsigned char x_20 = KB_A20;
void gateA20()
{
__asm("pushfl ; cli");
#ifdef PC98
outb(0xf2, 0x00);
outb(0xf6, 0x02);
#else /* IBM PC */
#ifdef IBM_L40
outb(0x92, 0x2);
#else IBM_L40
while (inb(K_STATUS) & K_IBUF_FUL);
while (inb(K_STATUS) & K_OBUF_FUL)
(void)inb(K_RDWR);
outb(K_CMD, KC_CMD_WOUT);
delay(100);
while (inb(K_STATUS) & K_IBUF_FUL);
outb(K_RDWR, x_20);
delay(100);
while (inb(K_STATUS) & K_IBUF_FUL);
#endif IBM_L40
#endif /* IBM PC */
__asm("popfl");
}

View File

@ -0,0 +1,83 @@
/*
* mjs copyright
*/
#include <stand.h>
#include <btxv86.h>
#ifdef PC98
#include <machine/cpufunc.h>
#endif
/*
* Return the time in seconds since the beginning of the day.
*
* If we pass midnight, don't wrap back to 0.
*
* XXX uses undocumented BCD support from libstand.
*/
time_t
time(time_t *t)
{
static time_t lasttime, now;
int hr, min, sec;
#ifdef PC98
unsigned char bios_time[6];
#endif
v86.ctl = 0;
#ifdef PC98
v86.addr = 0x1c; /* int 0x1c, function 0 */
v86.eax = 0x0000;
v86.es = VTOPSEG(bios_time);
v86.ebx = VTOPOFF(bios_time);
#else
v86.addr = 0x1a; /* int 0x1a, function 2 */
v86.eax = 0x0200;
#endif
v86int();
#ifdef PC98
hr = bcd2bin(bios_time[3]);
min = bcd2bin(bios_time[4]);
sec = bcd2bin(bios_time[5]);
#else
hr = bcd2bin((v86.ecx & 0xff00) >> 8); /* hour in %ch */
min = bcd2bin(v86.ecx & 0xff); /* minute in %cl */
sec = bcd2bin((v86.edx & 0xff00) >> 8); /* second in %dh */
#endif
now = hr * 3600 + min * 60 + sec;
if (now < lasttime)
now += 24 * 3600;
lasttime = now;
if (t != NULL)
*t = now;
return(now);
}
/*
* Use the BIOS Wait function to pause for (period) microseconds.
*
* Resolution of this function is variable, but typically around
* 1ms.
*/
void
delay(int period)
{
#ifdef PC98
int i;
period = (period + 500) / 1000;
for( ; period != 0 ; period--)
for(i=800;i != 0; i--)
outb(0x5f,0); /* wait 600ns */
#else
v86.ctl = 0;
v86.addr = 0x15; /* int 0x15, function 0x86 */
v86.eax = 0x8600;
v86.ecx = period >> 16;
v86.edx = period & 0xffff;
v86int();
#endif
}

View File

@ -0,0 +1,800 @@
/*
* Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
* Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
* 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 AND CONTRIBUTORS ``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 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.
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
* $Id: vidconsole.c,v 1.11 1999/01/04 18:45:08 peter Exp $
*/
#include <stand.h>
#include <bootstrap.h>
#include <btxv86.h>
#include <machine/psl.h>
#include "libi386.h"
#ifdef PC98
#include <machine/cpufunc.h>
#endif
#if KEYBOARD_PROBE
#include <machine/cpufunc.h>
static int probe_keyboard(void);
#endif
static void vidc_probe(struct console *cp);
static int vidc_init(int arg);
static void vidc_putchar(int c);
static int vidc_getchar(void);
static int vidc_ischar(void);
static int vidc_started;
#ifdef TERM_EMU
void end_term();
void bail_out(int c);
void vidc_term_emu(int c);
void get_pos(void);
void curs_move(int x, int y);
void write_char(int c, int fg, int bg);
void scroll_up(int rows, int fg, int bg);
void AB(void);
void AF(void);
void CD(void);
void CM(void);
void HO(void);
void ME(void);
static int args[2],argc,br;
static int fg,bg,dig;
static int fg_c,bg_c,curx,cury;
static int esc;
#endif
#ifdef PC98
static unsigned short *crtat, *Crtat;
static int row = 25, col = 80;
#ifdef TERM_EMU
unsigned int at2pc98(unsigned int fg_at, unsigned int bg_at);
#endif
#endif
struct console vidconsole = {
"vidconsole",
"internal video/keyboard",
0,
vidc_probe,
vidc_init,
vidc_putchar,
vidc_getchar,
vidc_ischar
};
static void
vidc_probe(struct console *cp)
{
/* look for a keyboard */
#if KEYBOARD_PROBE
if (probe_keyboard())
#endif
{
cp->c_flags |= C_PRESENTIN;
}
/* XXX for now, always assume we can do BIOS screen output */
cp->c_flags |= C_PRESENTOUT;
}
static int
vidc_init(int arg)
{
int i;
#ifdef PC98
int hw_cursor;
#endif
if (vidc_started && arg == 0)
return;
vidc_started = 1;
#ifdef PC98
Crtat = (unsigned short *)PTOV(0xA0000);
while((inb(0x60) & 0x04) == 0);
outb(0x62, 0xe0);
while((inb(0x60) & 0x01) == 0);
hw_cursor = inb(0x62);
hw_cursor |= (inb(0x62) << 8);
inb(0x62);
inb(0x62);
inb(0x62);
crtat = Crtat + hw_cursor;
#endif
#ifdef TERM_EMU
/* Init terminal emulator */
end_term();
get_pos();
curs_move(curx,cury);
fg_c=7;
bg_c=0;
#endif
for(i = 0; i < 10 && vidc_ischar(); i++)
(void)vidc_getchar();
return(0); /* XXX reinit? */
}
static void
vidc_biosputchar(int c)
{
#ifdef PC98
unsigned short *cp;
int i, pos;
#ifdef TERM_EMU
*crtat = (c == 0x5c ? 0xfc : c);
*(crtat + 0x1000) = at2pc98(fg, bg);
#else
switch(c) {
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);
#endif
#else
v86.ctl = 0;
v86.addr = 0x10;
v86.eax = 0xe00 | (c & 0xff);
v86.ebx = 0x7;
v86int();
#endif
}
static void
vidc_rawputchar(int c)
{
int i;
if(c == '\t')
/* lame tab expansion */
for (i = 0; i < 8; i++)
vidc_rawputchar(' ');
else {
#ifndef TERM_EMU
vidc_biosputchar(c);
#else
/* Emulate AH=0eh (teletype output) */
switch(c) {
case '\a':
vidc_biosputchar(c);
return;
case '\r':
curx=0;
curs_move(curx,cury);
return;
case '\n':
cury++;
if(cury>24) {
scroll_up(1,fg_c,bg_c);
cury--;
} else {
curs_move(curx,cury);
}
return;
case '\b':
if(curx>0) {
curx--;
curs_move(curx,cury);
/* write_char(' ',fg_c,bg_c); XXX destructive(!) */
return;
}
return;
default:
write_char(c,fg_c,bg_c);
curx++;
if(curx>79) {
curx=0;
cury++;
}
if(cury>24) {
curx=0;
scroll_up(1,fg_c,bg_c);
cury--;
}
}
curs_move(curx,cury);
#endif
}
}
#ifdef TERM_EMU
/* Get cursor position on the screen. Result is in edx. Sets
* curx and cury appropriately.
*/
void
get_pos(void)
{
#ifdef PC98
int pos = crtat - Crtat;
curx = pos % col;
cury = pos / col;
#else
v86.ctl = 0;
v86.addr = 0x10;
v86.eax = 0x0300;
v86.ebx = 0x0;
v86int();
curx=v86.edx & 0x00ff;
cury=(v86.edx & 0xff00)>>8;
#endif
}
/* Move cursor to x rows and y cols (0-based). */
void
curs_move(int x, int y)
{
#ifdef PC98
int pos;
pos = x + y*col;
crtat = Crtat + pos;
pos = crtat - Crtat;
while((inb(0x60) & 0x04) == 0) {}
outb(0x62, 0x49);
outb(0x60, pos & 0xff);
outb(0x60, pos >> 8);
curx=x;
cury=y;
#define isvisible(c) (((c)>32) && ((c)<255))
if(!isvisible(*crtat & 0x00ff)) {
write_char(' ',fg_c,bg_c);
}
#else
v86.ctl = 0;
v86.addr = 0x10;
v86.eax = 0x0200;
v86.ebx = 0x0;
v86.edx = ((0x00ff & y)<<8)+(0x00ff & x);
v86int();
curx=x;
cury=y;
/* If there is ctrl char at this position, cursor would be invisible.
* Make it a space instead.
*/
v86.ctl=0;
v86.addr = 0x10;
v86.eax = 0x0800;
v86.ebx= 0x0;
v86int();
#define isvisible(c) (((c)>32) && ((c)<255))
if(!isvisible(v86.eax & 0x00ff)) {
write_char(' ',fg_c,bg_c);
}
#endif
}
/* Scroll up the whole window by a number of rows. If rows==0,
* clear the window. fg and bg are attributes for the new lines
* inserted in the window.
*/
void
scroll_up(int rows, int fg, int bg)
{
#ifdef PC98
unsigned short *cp;
int i;
if(rows==0) rows=25;
cp = Crtat;
for (i = rows ; i < row; i++) {
bcopy((void *)(cp+col), (void *)cp, col*2);
cp += col;
}
for (i = 0; i < col; i++) {
*(cp + 0x1000) = at2pc98(fg, bg);
*cp++ = ' ';
}
#else
if(rows==0) rows=25;
v86.ctl = 0;
v86.addr = 0x10;
v86.eax = 0x0600+(0x00ff & rows);
v86.ebx = (bg<<12)+(fg<<8);
v86.ecx = 0x0;
v86.edx = 0x184f;
v86int();
#endif
}
/* Write character and attribute at cursor position. */
void
write_char(int c, int fg, int bg)
{
#ifdef PC98
*crtat = c;
*(crtat + 0x1000) = at2pc98(fg, bg);
#else
v86.ctl=0;
v86.addr = 0x10;
v86.eax = 0x0900+(0x00ff & c);
v86.ebx = (bg<<4)+fg;
v86.ecx = 0x1;
v86int();
#endif
}
/* Calculate power of 10 */
int
pow10(int i)
{
int res=1;
while(i-->0) {
res*=10;
}
return res;
}
/**************************************************************/
/*
* Screen manipulation functions. They use accumulated data in
* args[] and argc variables.
*
*/
/* Set background color */
void
AB(void){
bg_c=args[0];
end_term();
}
/* Set foreground color */
void
AF(void)
{
fg_c=args[0];
end_term();
}
/* Clear display from current position to end of screen */
void
CD(void)
{
get_pos();
#ifdef PC98
for(;crtat <= Crtat + col*row; crtat++){
*crtat = ' ';
*(crtat + 0x1000) = at2pc98(fg_c, bg_c);
}
#else
v86.ctl = 0;
v86.addr = 0x10;
v86.eax = 0x0600;
v86.ebx = (bg_c<<4)+fg_c;
v86.ecx = v86.edx;
v86.edx = 0x184f;
v86int();
#endif
curx=0;
curs_move(curx,cury);
end_term();
}
/* Absolute cursor move to args[0] rows and args[1] columns
* (the coordinates are 1-based).
*/
void
CM(void)
{
if(args[0]>0) args[0]--;
if(args[1]>0) args[1]--;
curs_move(args[1],args[0]);
end_term();
}
/* Home cursor (left top corner) */
void
HO(void)
{
argc=1;
args[0]=args[1]=1;
CM();
}
/* Exit attribute mode (reset fore/back-ground colors to defaults) */
void
ME(void)
{
fg_c=7;
bg_c=0;
end_term();
}
/* Clear internal state of the terminal emulation code */
void
end_term(void)
{
esc=0;
argc=-1;
fg=bg=br=0;
args[0]=args[1]=0;
dig=0;
}
/* Gracefully exit ESC-sequence processing in case of misunderstanding */
void
bail_out(int c)
{
char buf[6],*ch;
if(esc) vidc_rawputchar('\033');
if(br) vidc_rawputchar('[');
if(argc>-1) {
sprintf(buf,"%d",args[0]);
ch=buf;
while(*ch) vidc_rawputchar(*ch++);
if(argc>0) {
vidc_rawputchar(';');
sprintf(buf,"%d",args[1]);
ch=buf;
while(*ch) vidc_rawputchar(*ch++);
}
}
vidc_rawputchar(c);
end_term();
}
/* Emulate basic capabilities of cons25 terminal */
void
vidc_term_emu(int c)
{
if(!esc) {
if(c=='\033') {
esc=1;
} else {
vidc_rawputchar(c);
}
return;
}
/* Do ESC sequences processing */
switch(c) {
case '\033':
/* ESC in ESC sequence - error */
bail_out(c);
break;
case '[':
/* Check if it's first char after ESC */
if(argc<0) {
br=1;
} else {
bail_out(c);
}
break;
case 'H':
/* Emulate \E[H (cursor home) and
* \E%d;%dH (cursor absolute move) */
if(br) {
switch(argc) {
case -1:
HO();
break;
case 1:
if(fg) args[0]+=pow10(dig)*3;
if(bg) args[0]+=pow10(dig)*4;
CM();
break;
default:
bail_out(c);
}
} else bail_out(c);
break;
case 'J':
/* Emulate \EJ (clear to end of screen) */
if(br && argc<0) {
CD();
} else bail_out(c);
break;
case ';':
/* perhaps args separator */
if(br && (argc>-1)) {
argc++;
} else bail_out(c);
break;
case 'm':
/* Change char attributes */
if(br) {
switch(argc) {
case -1:
ME();
break;
case 0:
if(fg) AF();
else AB();
break;
default:
bail_out(c);
}
} else bail_out(c);
break;
default:
if(isdigit(c)) {
/* Carefully collect numeric arguments */
/* XXX this is ugly. */
if(br) {
if(argc==-1) {
argc=0;
args[argc]=0;
dig=0;
/* in case we're in error... */
if(c=='3') {
fg=1;
return;
}
if(c=='4') {
bg=1;
return;
}
args[argc]=(int)(c-'0');
dig=1;
args[argc+1]=0;
} else {
args[argc]=args[argc]*10+(int)(c-'0');
if(argc==0) dig++;
}
} else bail_out(c);
} else bail_out(c);
break;
}
}
#endif
static void
vidc_putchar(int c)
{
#ifdef TERM_EMU
vidc_term_emu(c);
#else
vidc_rawputchar(c);
#endif
}
static int
vidc_getchar(void)
{
if (vidc_ischar()) {
v86.ctl = 0;
#ifdef PC98
v86.addr = 0x18;
#else
v86.addr = 0x16;
#endif
v86.eax = 0x0;
v86int();
return(v86.eax & 0xff);
} else {
return(-1);
}
}
static int
vidc_ischar(void)
{
#ifdef PC98
v86.ctl = 0;
v86.addr = 0x18;
v86.eax = 0x100;
v86int();
return((v86.ebx >> 8) & 0x1);
#else
v86.ctl = V86_FLAGS;
v86.addr = 0x16;
v86.eax = 0x100;
v86int();
return(!(v86.efl & PSL_Z));
#endif
}
#if KEYBOARD_PROBE
#ifdef PC98
static int
probe_keyboard(void)
{
return (*(u_char *)PTOV(0xA1481) & 0x48);
}
#else /* PC98 */
#define PROBE_MAXRETRY 5
#define PROBE_MAXWAIT 400
#define IO_DUMMY 0x84
#define IO_KBD 0x060 /* 8042 Keyboard */
/* selected defines from kbdio.h */
#define KBD_STATUS_PORT 4 /* status port, read */
#define KBD_DATA_PORT 0 /* data port, read/write
* also used as keyboard command
* and mouse command port
*/
#define KBDC_ECHO 0x00ee
#define KBDS_ANY_BUFFER_FULL 0x0001
#define KBDS_INPUT_BUFFER_FULL 0x0002
#define KBD_ECHO 0x00ee
/* 7 microsec delay necessary for some keyboard controllers */
static void
delay7(void)
{
/*
* I know this is broken, but no timer is available yet at this stage...
* See also comments in `delay1ms()'.
*/
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
inb(IO_DUMMY); inb(IO_DUMMY);
}
/*
* 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
* is not a valid ISA bus address, those machines execute this inb in
* 60 nS :-(.
*
*/
static void
delay1ms(void)
{
int i = 800;
while (--i >= 0)
(void)inb(0x84);
}
/*
* We use the presence/absence of a keyboard to determine whether the internal
* console can be used for input.
*
* Perform a simple test on the keyboard; issue the ECHO command and see
* if the right answer is returned. We don't do anything as drastic as
* full keyboard reset; it will be too troublesome and take too much time.
*/
static int
probe_keyboard(void)
{
int retry = PROBE_MAXRETRY;
int wait;
int i;
while (--retry >= 0) {
/* flush any noise */
while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
delay1ms();
}
/* wait until the controller can accept a command */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (((i = inb(IO_KBD + KBD_STATUS_PORT))
& (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
break;
if (i & KBDS_ANY_BUFFER_FULL) {
delay7();
inb(IO_KBD + KBD_DATA_PORT);
}
delay1ms();
}
if (wait <= 0)
continue;
/* send the ECHO command */
outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
/* wait for a response */
for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
break;
delay1ms();
}
if (wait <= 0)
continue;
delay7();
i = inb(IO_KBD + KBD_DATA_PORT);
#ifdef PROBE_KBD_BEBUG
printf("probe_keyboard: got 0x%x.\n", i);
#endif
if (i == KBD_ECHO) {
/* got the right answer */
return (0);
}
}
return (1);
}
#endif
#endif /* KEYBOARD_PROBE */
#ifdef TERM_EMU
#ifdef PC98
static u_char ibmpc_to_pc98[16] =
{ 0x01,0x21,0x81,0xa1,0x41,0x61,0xc1,0xe1, 0x09,0x29,0x89,0xa9,0x49,0x69,0xc9,0xe9 };
static u_char ibmpc_to_pc98rev[16] =
{ 0x05,0x25,0x85,0xa5,0x45,0x65,0xc5,0xe5, 0x0d,0x2d,0x8d,0xad,0x4d,0x6d,0xcd,0xed };
unsigned int
at2pc98(unsigned int fg_at, unsigned int bg_at)
{
unsigned int at;
if (bg_at) {
if (bg_at & 0x80) {
if (bg_at & 0x70) {
/* reverse & blink */
at = ibmpc_to_pc98rev[bg_at >> 4] | 0x02;
} else {
/* normal & blink */
at = ibmpc_to_pc98[fg_at] | 0x02;
}
} else {
/* reverse */
at = ibmpc_to_pc98rev[bg_at >> 4];
}
} else {
/* normal */
at = ibmpc_to_pc98[fg_at];
}
at |= ((fg_at|bg_at) << 8);
return (at);
}
#endif
#endif

View File

@ -0,0 +1,117 @@
# $Id: Makefile,v 1.28 1999/01/18 19:05:27 msmith Exp $
BASE= loader
PROG= ${BASE}
NOMAN=
STRIP=
NEWVERSWHAT= "bootstrap loader"
BINDIR?= /boot
CFLAGS+= -DPC98
# architecture-specific loader code
SRCS= main.c conf.c
.PATH: ${.CURDIR}/../../i386/loader
# Enable PnP and ISA-PnP code.
HAVE_PNP= yes
HAVE_ISABUS= yes
# Enable BootForth
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
.if exists(${.OBJDIR}/../../ficl/libficl.a)
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.else
LIBFICL= ${.CURDIR}/../../ficl/libficl.a
.endif
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include <${.CURDIR}/../../common/Makefile.inc>
CFLAGS+= -I${.CURDIR}/../../common
CFLAGS+= -I${.CURDIR}/../../.. -I. -I${.CURDIR}/../../i386
CLEANFILES+= vers.c vers.o ${BASE}.list ${BASE}.bin ${BASE}.sym ${BASE}.help
CFLAGS+= -Wall
LDFLAGS= -nostdlib -static -Ttext 0x1000
# pc98 standalone support library
LIBPC98= ${.OBJDIR}/../libpc98/libpc98.a
CFLAGS+= -I${.CURDIR}/..
# where to get libstand from
LIBSTAND= -lstand
#LIBSTAND= ${.CURDIR}/../../../lib/libstand/libstand.a
#CFLAGS+= -I${.CURDIR}/../../../lib/libstand/
# BTX components
.if exists(${.OBJDIR}/../btx)
BTXDIR= ${.OBJDIR}/../btx
.else
BTXDIR= ${.CURDIR}/../btx
.endif
BTXLDR= ${BTXDIR}/btxldr/btxldr
BTXKERN= ${BTXDIR}/btx/btx
BTXCRT= ${BTXDIR}/lib/crt0.o
CFLAGS+= -I${.CURDIR}/../btx/lib
# BTX is expecting ELF components
CFLAGS+= -elf
# New linker set code
CFLAGS+= -DNEW_LINKER_SET
# Debug me!
#CFLAGS+= -g
#LDFLAGS+= -g
vers.o:
sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
${CC} -c vers.c
${BASE}: ${BASE}.bin ${BTXLDR} ${BTXKERN} ${BTXCRT} ${BASE}.help
btxld -v -f aout -e 0x100000 -o ${.TARGET} -l ${BTXLDR} -b ${BTXKERN} \
${BASE}.bin
# /usr/bin/kzip ${.TARGET}
# mv ${.TARGET}.kz ${.TARGET}
${BASE}.bin: ${BASE}.sym
cp ${.ALLSRC} ${.TARGET}
strip ${.TARGET}
${BASE}.help: help.common help.pc98
cat ${.ALLSRC} | awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
beforeinstall:
.if exists(${DESTDIR}/boot/loader)
mv ${DESTDIR}/boot/loader ${DESTDIR}/boot/loader.old
.endif
.if exists(${.OBJDIR}/loader.help)
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${.OBJDIR}/${BASE}.help ${DESTDIR}/boot
.else
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
${.CURDIR}/${BASE}.help ${DESTDIR}/boot
.endif
# Cannot use ${OBJS} above this line
.include <bsd.prog.mk>
${BASE}.sym: ${OBJS} ${LIBPC98} ${LIBSTAND} ${LIBFICL} vers.o
${CC} ${LDFLAGS} -o ${.TARGET} ${BTXCRT} ${OBJS} vers.o \
${LIBFICL} ${LIBSTAND} ${LIBPC98} ${LIBSTAND}
# If it's not there, don't consider it a target
.if exists(${.CURDIR}/../../../i386/include)
beforedepend ${OBJS}: machine
machine:
ln -sf ${.CURDIR}/../../../i386/include machine
.endif
CLEANFILES+= machine

View File

@ -0,0 +1,46 @@
################################################################################
# Treboot DReboot the system
reboot
Causes the system to immediately reboot.
################################################################################
# Theap DDisplay memory management statistics
heap
Requests debugging output from the heap manager. For debugging use
only.
################################################################################
# Tset Snum_ide_disks DSet the number of IDE disks
NOTE: this variable is deprecated, use root_disk_unit instead.
set num_ide_disks=<value>
When booting from a SCSI disk on a system with one or more IDE disks,
and where the IDE disks are the default boot device, it is necessary
to tell the kernel how many IDE disks there are in order to have it
correctly locate the SCSI disk you are booting from.
################################################################################
# Tset Sboot_userconfig DStart Userconfig
set boot_userconfig
Requests that the kernel's interactive device configuration program
be run when the kernel is booted.
################################################################################
# Tset Sroot_disk_unit DForce the root disk unit number.
set root_disk_unit=<value>
If the code which detects the disk unit number for the root disk is
confused, eg. by a mix of SCSI and IDE disks, or IDE disks with
gaps in the sequence (eg. no primary slave), the unit number can be
forced by setting this variable.
################################################################################

244
sys/boot/pc98/loader/main.c Normal file
View File

@ -0,0 +1,244 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* 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 AND CONTRIBUTORS ``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 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.
*
* $Id: main.c,v 1.14 1998/11/02 23:28:11 msmith Exp $
*/
/*
* MD bootstrap main() and assorted miscellaneous
* commands.
*/
#include <stand.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <sys/reboot.h>
#include "bootstrap.h"
#include "../../i386/libi386/libi386.h"
#include "btxv86.h"
/* Arguments passed in from the boot1/boot2 loader */
static struct
{
u_int32_t howto;
u_int32_t bootdev;
u_int32_t res0;
u_int32_t res1;
u_int32_t res2;
u_int32_t bootinfo;
} *kargs;
static u_int32_t initial_howto;
static u_int32_t initial_bootdev;
#ifdef PC98
struct bootinfo *initial_bootinfo;
#else
static struct bootinfo *initial_bootinfo;
#endif
struct arch_switch archsw; /* MI/MD interface boundary */
static void extract_currdev(void);
static int isa_inb(int port);
static void isa_outb(int port, int value);
/* from vers.c */
extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
/* XXX debugging */
extern char end[];
void
main(void)
{
int i;
/* Pick up arguments */
kargs = (void *)__args;
initial_howto = kargs->howto;
initial_bootdev = kargs->bootdev;
initial_bootinfo = (struct bootinfo *)PTOV(kargs->bootinfo);
/*
* Initialise the heap as early as possible. Once this is done, malloc() is usable.
*
* XXX better to locate end of memory and use that
*/
setheap((void *)end, (void *)(end + (384 * 1024)));
/*
* XXX Chicken-and-egg problem; we want to have console output early, but some
* console attributes may depend on reading from eg. the boot device, which we
* can't do yet.
*
* We can use printf() etc. once this is done.
* If the previous boot stage has requested a serial console, prefer that.
*/
if (initial_howto & RB_SERIAL)
setenv("console", "comconsole", 1);
cons_probe();
/*
* Initialise the block cache
*/
bcache_init(32, 512); /* 16k cache XXX tune this */
/*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
printf("\n");
printf("%s, Revision %s %d/%dkB\n", bootprog_name, bootprog_rev, getbasemem(), getextmem());
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
extract_currdev(); /* set $currdev and $loaddev */
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = i386_autoload;
archsw.arch_getdev = i386_getdev;
archsw.arch_copyin = i386_copyin;
archsw.arch_copyout = i386_copyout;
archsw.arch_readin = i386_readin;
archsw.arch_isainb = isa_inb;
archsw.arch_isaoutb = isa_outb;
interact(); /* doesn't return */
}
/*
* Set the 'current device' by (if possible) recovering the boot device as
* supplied by the initial bootstrap.
*
* XXX should be extended for netbooting.
*/
static void
extract_currdev(void)
{
struct i386_devdesc currdev;
int major, biosdev;
/* We're booting from a BIOS disk, try to spiff this */
currdev.d_dev = devsw[0]; /* XXX presumes that biosdisk is first in devsw */
currdev.d_type = currdev.d_dev->dv_type;
if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
/* The passed-in boot device is bad */
currdev.d_kind.biosdisk.slice = -1;
currdev.d_kind.biosdisk.partition = 0;
biosdev = -1;
} else {
currdev.d_kind.biosdisk.slice = (B_ADAPTOR(initial_bootdev) << 4) + B_CONTROLLER(initial_bootdev) - 1;
currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
biosdev = initial_bootinfo->bi_bios_dev;
major = B_TYPE(initial_bootdev);
/*
* If we are booted by an old bootstrap, we have to guess at the BIOS
* unit number. We will loose if there is more than one disk type
* and we are not booting from the lowest-numbered disk type
* (ie. SCSI when IDE also exists).
*/
#ifdef PC98
if (major == 6)
biosdev = 0x30 + B_UNIT(initial_bootdev);
else
biosdev = (major << 3) + 0x80 + B_UNIT(initial_bootdev);
#else
if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */
biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
#endif
}
if ((currdev.d_kind.biosdisk.unit = bd_bios2unit(biosdev)) == -1) {
printf("Can't work out which disk we are booting from.\n"
"Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
currdev.d_kind.biosdisk.unit = 0;
}
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev), i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset, env_nounset);
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
command_reboot(int argc, char *argv[])
{
printf("Rebooting...\n");
delay(1000000);
__exit(0);
}
/* provide this for panic, as it's not in the startup code */
void
exit(int code)
{
__exit(code);
}
COMMAND_SET(heap, "heap", "show heap usage", command_heap);
static int
command_heap(int argc, char *argv[])
{
mallocstats();
printf("heap base at %p, top at %p\n", end, sbrk(0));
return(CMD_OK);
}
/* ISA bus access functions for PnP, derived from <machine/cpufunc.h> */
static int
isa_inb(int port)
{
u_char data;
if (__builtin_constant_p(port) &&
(((port) & 0xffff) < 0x100) &&
((port) < 0x10000)) {
__asm __volatile("inb %1,%0" : "=a" (data) : "id" ((u_short)(port)));
} else {
__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
}
return(data);
}
static void
isa_outb(int port, int value)
{
u_char al = value;
if (__builtin_constant_p(port) &&
(((port) & 0xffff) < 0x100) &&
((port) < 0x10000)) {
__asm __volatile("outb %0,%1" : : "a" (al), "id" ((u_short)(port)));
} else {
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
}
}

View File

@ -0,0 +1,46 @@
#!/bin/sh -
#
# $NetBSD: newvers.sh,v 1.1 1997/07/26 01:50:38 thorpej Exp $
#
# Copyright (c) 1984, 1986, 1990, 1993
# The Regents of the University of California. 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.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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.
#
# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
LC_TIME=C; export LC_TIME
u=${USER-root} h=`hostname` t=`date`
#r=`head -n 6 $1 | tail -n 1 | awk -F: ' { print $1 } '`
r=`awk -F: ' /^[0-9]\.[0-9]+:/ { print $1; exit }' $1`
echo "char bootprog_name[] = \"FreeBSD/i386 ${2}\";" > vers.c
echo "char bootprog_rev[] = \"${r}\";" >> vers.c
echo "char bootprog_date[] = \"${t}\";" >> vers.c
echo "char bootprog_maker[] = \"${u}@${h}\";" >> vers.c

View File

@ -0,0 +1,8 @@
$Id: version,v 1.2 1998/09/17 23:52:16 msmith Exp $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
0.2: Initial integration with BTX
0.1: Initial i386 version, inspiration and some structure from the
NetBSD version.