Reimplement the boot2 for pc98 completely.

It's based on the newest i386's one and has the advantage of:

 - ELF binary support.
 - UFS2 filesystem support.
 - Many FreeBSD slices support on a disk.

Tested by:	SATOU Tomokazu ( tomo1770 _ maple _ ocn _ ne _ jp ),
		WATANABE Kazuhiro ( CQG00620 _ nifty _ ne _ jp ) and
		nyan

MFC after:	2 week

Happy New Year in Japan!!
This commit is contained in:
nyan 2009-12-31 15:03:33 +00:00
parent 0a4c3bb56f
commit 1aa8466f89
22 changed files with 1312 additions and 4567 deletions

View File

@ -1,119 +1,104 @@
# $FreeBSD$
#
PROG= boot
# Order is very important on the SRCS line for this prog
SRCS= start.S table.c boot2.S boot.c asm.S bios.S serial.S
SRCS+= probe_keyboard.c io.c disk.c sys.c
FILES= boot boot1 boot2
BINMODE= 444
CFLAGS= -Os -mrtd \
-fno-guess-branch-probability \
-fno-unit-at-a-time \
-D_KERNEL -DBOOTWAIT=${BOOTWAIT} -DTIMEOUT=${TIMEOUT}
CFLAGS+= -DBOOTSEG=${BOOTSEG} -DBOOTSTACK=${BOOTSTACK}
CFLAGS+= -I${.CURDIR}/../../.. -I.
NM?= nm
# 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}
BOOT_COMCONSOLE_PORT?= 0x238
BOOT_COMCONSOLE_SPEED?= 9600
B2SIOFMT?= 0x3
# feature not implemented
BOOT_COMCONSOLE_SPEED?=9600
CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
REL1= 0x700
ORG1= 0
ORG2= 0x2000
# Decide level of UFS support.
BOOT2_UFS?= UFS1_AND_UFS2
#BOOT2_UFS?= UFS2_ONLY
#BOOT2_UFS?= UFS1_ONLY
CFLAGS= -Os \
-fno-guess-branch-probability \
-fomit-frame-pointer \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
-mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-D${BOOT2_UFS} \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
-DSIOFMT=${B2SIOFMT} \
-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
-I${.CURDIR}/../../.. \
-I${.CURDIR}/../../i386/boot2 \
-I${.CURDIR}/../../common \
-I${.CURDIR}/../btx/lib -I. \
-Wall -Waggregate-return -Wbad-function-cast -Wcast-align \
-Wmissing-declarations -Wmissing-prototypes -Wnested-externs \
-Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \
-Winline --param max-inline-insns-single=100
# Set machine type to PC98_SYSTEM_PARAMETER
CFLAGS+= -DSET_MACHINE_TYPE
#CFLAGS+= -DSET_MACHINE_TYPE
# Initialize the bi_bios_geom using the BIOS geometry
CFLAGS+= -DGET_BIOSGEOM
#CFLAGS+= -DGET_BIOSGEOM
# 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
LDFLAGS=-static -N --gc-sections
# 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).
# Pick up ../Makefile.inc early.
.include <bsd.init.mk>
CLEANFILES+= boot.nohdr boot.strip boot.ldr boot1 boot2 sizetest
LDFLAGS+= -N -Ttext 0 -e start
NO_SHARED= YES
NO_MAN=
STRIP=
.PATH: ${.CURDIR}/../../i386/boot2
# tunable timeout parameter, waiting for keypress, calibrated in ms
BOOTWAIT?= 5000
# tunable timeout during string input, calibrated in ms
#TIMEOUT?= 30000
CLEANFILES= boot
# Location that boot2 is loaded at
BOOTSEG= 0x1000
boot: boot1 boot2
cat boot1 boot2 > boot
# Offset in BOOTSEG for the top of the stack, keep this 16 byte aligned
BOOTSTACK= 0xFFF0
CLEANFILES+= boot1 boot1.out boot1.o
boot.nohdr: boot
objcopy -S -O binary boot boot.nohdr
ls -l boot.nohdr
boot1: boot1.out
objcopy -S -O binary boot1.out ${.TARGET}
boot.ldr: boot.nohdr
dd if=boot.nohdr of=boot.ldr bs=8192 count=1 conv=sync
boot1.out: boot1.o
${LD} ${LDFLAGS} -e start -Ttext ${ORG1} -o ${.TARGET} boot1.o
boot1: boot.nohdr
dd if=boot.nohdr of=boot1 bs=512 count=1
CLEANFILES+= boot2 boot2.ld boot2.ldr boot2.bin boot2.out boot2.o \
boot2.s boot2.s.tmp boot2.h sio.o
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
boot2: boot2.ld
@set -- `ls -l boot2.ld`; x=$$((7680-$$5)); \
echo "$$x bytes available"; test $$x -ge 0
dd if=boot2.ld of=${.TARGET} obs=7680 conv=osync
all: boot.ldr boot1 boot2
boot2.ld: boot2.ldr boot2.bin ${BTXKERN}
btxld -v -E ${ORG2} -f bin -b ${BTXKERN} -l boot2.ldr \
-o ${.TARGET} -P 1 boot2.bin
install:
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
boot.ldr ${DESTDIR}${BINDIR}/boot
${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
boot1 boot2 ${DESTDIR}${BINDIR}
boot2.ldr:
dd if=/dev/zero of=${.TARGET} bs=276 count=1
# If it's not there, don't consider it a target
.if exists(${.CURDIR}/../../../pc98/include)
beforedepend ${OBJS}: machine
boot2.bin: boot2.out
objcopy -S -O binary boot2.out ${.TARGET}
machine:
ln -sf ${.CURDIR}/../../../pc98/include machine
boot2.out: ${BTXCRT} boot2.o sio.o
${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC}
.endif
boot2.o: boot2.s
.if exists(${.CURDIR}/../../../i386/include)
beforedepend ${OBJS}: i386
SRCS= boot2.c boot2.h
i386:
ln -sf ${.CURDIR}/../../../i386/include i386
boot2.s: boot2.c boot2.h ${.CURDIR}/../../common/ufsread.c
${CC} ${CFLAGS} -S -o boot2.s.tmp ${.CURDIR}/boot2.c
sed -e '/align/d' -e '/nop/d' < boot2.s.tmp > boot2.s
rm -f boot2.s.tmp
.endif
boot2.h: boot1.out
${NM} -t d ${.ALLSRC} | awk '/([0-9])+ T (read|putc)/ \
{ x = $$1 - ORG1; \
printf("#define %sORG %#x\n", toupper($$3), REL1 + x) }' \
ORG1=`printf "%d" ${ORG1}` \
REL1=`printf "%d" ${REL1}` > ${.TARGET}
CLEANFILES+= machine i386
CWARNFLAGS!= ${MAKE} -f bsd.own.mk -f ${.CURDIR}/../../../conf/kern.mk -V CWARNFLAGS
.include <bsd.prog.mk>

View File

@ -1,258 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
* $FreeBSD$
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
.file "asm.s"
#include "asm.h"
CR0_PE_ON = 0x1
CR0_PE_OFF = 0xfffffffe
.code16
.text
/*
*
* real_to_prot()
* transfer from real mode to protected mode.
*/
ENTRY(real_to_prot)
/* guarantee that interrupt is disabled when in prot mode */
cli
/* load the gdtr */
.code32
addr32
data32
lgdt EXT(Gdtr)
.code16
/* set the PE bit of CR0 */
mov %cr0, %eax
or $CR0_PE_ON, %eax
mov %eax, %cr0
/*
* make intrasegment jump to flush the processor pipeline and
* reload CS register
*/
.code32
data32
ljmp $0x18, $xprot
.code16
xprot:
/*
* we are in USE32 mode now
* set up the protected mode segment registers : DS, SS, ES, FS
*/
data32
movw $0x20, %ax /* data segment */
mov %ax, %ds /* gas would waste a prefix byte for movw */
mov %ax, %ss
mov %ax, %es
data32
movw $0x10, %ax /* flat segment */
mov %ax, %fs
#ifdef BDE_DEBUGGER
/* load idtr so we can debug */
lidt EXT(Idtr_prot)
#endif
ret
/*
*
* prot_to_real()
* transfer from protected mode to real mode
*
*/
ENTRY(prot_to_real)
/* Prepare %ax while we're still in a mode that gas understands. */
data32
movw $0x30, %ax
/* Change to use16 mode. */
.code32
ljmp $0x28, $x16
.code16
x16:
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
mov %ax, %fs
/* clear the PE bit of CR0 */
mov %cr0, %eax
and $CR0_PE_OFF, %eax
mov %eax, %cr0
/*
* make intersegment jmp to flush the processor pipeline
* and reload CS register
*/
.code32
data32
ljmp $BOOTSEG, $xreal
.code16
xreal:
/*
* we are in real mode now
* set up the real mode segment registers : DS, SS, ES, FS
*/
mov %cs, %ax
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
mov %ax, %fs
#ifdef BDE_DEBUGGER
/* load idtr so we can debug */
addr32
data32
lidt EXT(Idtr_real)
#endif
data32
ret
/*
* startprog(phyaddr)
* start the program on protected mode where phyaddr is the entry point
*
* XXX This whole mess should go away and we should run the boot code in
* flat 32 bit mode with it linked -T BOOTSEG. See the netboot code for
* how this is done.
*/
ENTRY(startprog)
.code32
push %ebp
mov %esp, %ebp
movl %esp, %eax /* Use eax as the old stack pointer */
/* convert the current stack to a 32 bit flat model */
movw $0x10, %bx
data32
mov %bx, %ss
addl $(BOOTSEG<<4),%esp
/* copy the arguments from the old stack to the new stack */
pushl 0x14(%eax) /* &bootinfo */
pushl $0 /* was &nfsdiskless */
pushl $0 /* was esym */
pushl $0 /* was cyloffset */
pushl 0x10(%eax) /* bootdev */
pushl 0x0C(%eax) /* howto */
movl $(ourreturn),%ebx
addl $(BOOTSEG<<4),%ebx /* Fix it up for flat segments */
pushl %ebx /* our return address */
/* push on our entry address */
pushl $0x08 /* segment selector */
pushl 0x08(%eax) /* kernel entry address */
/* convert over the other data segs */
movw $0x10, %bx
data32
mov %bx, %ds
data32
mov %bx, %es
/* convert the PC (and code seg) */
lret
ourreturn:
/* For now there is not much we can do, just lock in a loop */
jmp ourreturn
/*
* pcpy(src, dst, cnt)
* where src is a virtual address and dst is a physical address
*/
ENTRY(pcpy)
.code32
push %ebp
mov %esp, %ebp
push %es
push %esi
push %edi
push %ecx
cld
/* set %es to point at the flat segment */
movw $0x10, %ax
mov %ax, %es
mov 0x8(%ebp), %esi /* source */
mov 0xc(%ebp), %edi /* destination */
mov 0x10(%ebp), %ecx /* count */
rep
movsb
pop %ecx
pop %edi
pop %esi
pop %es
pop %ebp
ret

View File

@ -1,144 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.7 92/02/29 15:33:41 rpd
* $FreeBSD$
*/
#define S_ARG0 4(%esp)
#define S_ARG1 8(%esp)
#define S_ARG2 12(%esp)
#define S_ARG3 16(%esp)
#define FRAME pushl %ebp; movl %esp, %ebp
#define EMARF leave
#define B_ARG0 8(%ebp)
#define B_ARG1 12(%ebp)
#define B_ARG2 16(%ebp)
#define B_ARG3 20(%ebp)
#ifdef wheeze
#define ALIGN 4
#define EXT(x) x
#define LEXT(x) x:
#define LCL(x) ./**/x
#define LB(x,n) ./**/x
#define LBb(x,n) ./**/x
#define LBf(x,n) ./**/x
#define SVC lcall $7,$0
#define String .string
#define Value .value
#define Times(a,b) [a\*b]
#define Divide(a,b) [a\\b]
#define INB inb (%dx)
#define OUTB outb (%dx)
#define INL inl (%dx)
#define OUTL outl (%dx)
#else /* wheeze */
#define ALIGN
#define LCL(x) x
#define LB(x,n) n
#ifdef __STDC__
#define EXT(x) x
#define LEXT(x) .type EXT(x),@function; EXT(x):
#define LBb(x,n) n ## b
#define LBf(x,n) n ## f
#else /* __STDC__ */
#define EXT(x) _/**/x
#define LEXT(x) .type EXT(x),@function; EXT(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)

View File

@ -1,408 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $FreeBSD$
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Ported to PC-9801 by Yoshio Kimura
*/
/*
* Extensions for El Torito CD-ROM booting:
*
* Copyright © 1997 Pluto Technologies International, Inc. Boulder CO
* Copyright © 1997 interface business GmbH, Dresden.
* All rights reserved.
*
* This code has been written by Jörg Wunsch, Dresden.
* Direct comments to <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
/*
* PC-9801/PC-9821 SCSI MO booting
* 2002/06/05-07/03 Kawanobe Koh <kawanobe@st.rim.or.jp>
*
*/
scsi_hd:
.code16
push %cx
push %ds
mov %bl, %cl /* UA */
and $0x0F, %cl
xor %ax, %ax
mov %ax, %ds
mov (0x0482), %al /* SCSI HD equipment bits */
shr %cl, %al
pop %ds
pop %cx
test $1, %al
ret
/*
* biosread(dev, cyl, head, sec, nsec, offset)
* Read "nsec" sectors from disk to offset "offset" in boot segment
* BIOS call "INT 0x1B Function 0xn6" to read sectors from disk into memory
* Call with %ah = 0xd6(for floppy disk) or 0x06(for hard disk)
* %al = DA/UA
* %bx = data length
* %ch = sector size(for floppy) or cylinder(for hard)
* %cl = cylinder
* %dh = head
* %dl = sector
* %es:%bp = segment:offset of buffer
* Return:
* %al = 0x0 on success; err code on failure
*/
ENTRY(biosread)
.code32
push %ebp
mov %esp, %ebp
push %ebx
push %esi
push %edi
mov 0x08(%ebp), %bl /* (byte) DA/UA */
mov 0x0C(%ebp), %ecx /* (word) cylinder */
mov 0x10(%ebp), %dh /* (byte) head */
mov 0x14(%ebp), %dl /* (byte) sector */
mov 0x18(%ebp), %esi /* (byte) number of sectors */
mov 0x1C(%ebp), %edi /* (word) destination offset */
/* prot_to_real will set %es to BOOTSEG */
call EXT(prot_to_real) /* enter real mode */
.code16
mov $0x06, %bh /* read data function */
mov %bl, %al /* DA */
and $0xF0, %al
cmp $0x30, %al /* 1440KB FD */
jz read_floppy
cmp $0x90, %al /* 1200KB FD */
jz read_floppy
cmp $0xA0, %al /* SCSI HD or MO */
jnz read_next
call scsi_hd
jnz read_next
read_linear:
mov %dh, %al /* change to linear sector */
shl $5, %al /* multiply by 32 sector per track */
add %dl, %al
xor %dh, %dh /* higher 16 bits into %dx */
mov %ch, %dl
mov %cl, %ch /* lower 16 bits into %cx */
mov %al, %cl
and $0x7F, %bl /* linear access DA/UA */
jmp read_next
read_floppy:
inc %dx /* sector address begins from one */
mov $0x02, %ch /* 512 bytes sector */
mov $0xD6, %bh /* MT MFM retry seek */
read_next:
mov %si, %ax /* number of sectors */
shl $9, %ax /* multiply by 512 bytes */
xchg %bx, %ax
mov %di, %bp /* destination offset */
int $0x1B /* disk bios call */
jc read_end
xor %ax, %ax
read_end:
mov %ax, %bx /* save return value */
.code32
data32
call EXT(real_to_prot) /* back to protected mode */
xor %eax, %eax
mov %bh, %al /* return value in %eax */
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
/*
* getc()
* BIOS call "INT 18H Function 00H" to read character from keyboard
* Call with %ah = 0x0
* Return: %ah = keyboard scan code
* %al = ASCII character
*/
ENTRY(getc)
.code32
push %ebp
mov %esp, %ebp
push %ebx /* save %ebx */
push %esi
push %edi
call EXT(prot_to_real)
.code16
movb $0x0, %ah
int $0x18
movb %al, %bl /* real_to_prot uses %eax */
.code32
data32
call EXT(real_to_prot)
xor %eax, %eax
movb %bl, %al
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
/*
* ischar()
* if there is a character pending, return it; otherwise return 0
* BIOS call "INT 18H Function 01H" to check whether a character is pending
* Call with %ah = 0x1
* Return:
* If key waiting to be input:
* %ah = keyboard scan code
* %al = ASCII character
* %bh = 1
* else
* %bh = 0
*/
ENTRY(ischar)
.code32
push %ebp
mov %esp, %ebp
push %ebx
push %esi
push %edi
call EXT(prot_to_real) /* enter real mode */
xor %ebx, %ebx
.code16
movb $0x1, %ah
int $0x18
andb %bh, %bh
data32
jz nochar
movb %al, %bl
nochar:
.code32
data32
call EXT(real_to_prot)
xor %eax, %eax
movb %bl, %al
pop %edi
pop %esi
pop %ebx
pop %ebp
ret
/*
*
* get_diskinfo(): return a word that represents the
* max number of sectors and heads and drives for this device
*
*/
ENTRY(get_diskinfo)
.code32
push %ebp
mov %esp, %ebp
push %ebx
mov 0x08(%ebp), %bl /* (byte) DA/UA */
call EXT(prot_to_real) /* enter real mode */
.code16
mov %bl, %al /* DA */
and $0xf0, %al
mov $18, %dl /* 1440KB FD sectors per track */
cmp $0x30, %al
jz floppy
mov $15, %dl /* 1200KB FD sectors per track */
cmp $0x90, %al
jz floppy
cmp $0xA0, %al /* SCSI HD or MO */
jnz sense
call scsi_hd
jnz sense
push %ds /* SCSI MO or CD ? */
xor %ax, %ax
mov %ax, %ds
and $0x0F, %bx /* UA */
shl $2, %bx /* parameter offset */
add $0x0460, %bx
mov (%bx), %al /* SCSI equipment parameter[0] */
and $0x1F, %al /* peripheral device type */
cmp $7, %al /* SCSI MO */
jnz good
add $3, %bx
mov (%bx), %al /* SCSI equipment parameter[3] */
test $0x30, %al /* sector length from 256 to 2048 */
jnz good
or $0x10, %al /* forced set 512 bytes sector */
mov %al, (%bx)
mov $0xA100, %dx /* refered by C language */
mov %dx, %ds
mov %al, (%bx)
good:
pop %ds
mov $0xFFFE, %cx /* virtual 65535 cylinders setting */
mov $0x0820, %dx /* standard 8 heads and 32 sectors */
jmp ok
sense:
mov $0x84, %ah /* ask for disk info */
mov %bl, %al
int $0x1b
jnc ok /* use %cx and %dx after */
/*
* Urk. Call failed. It is not supported for floppies by old BIOS's.
* Guess it's a 15-sector floppy.
*/
floppy:
mov $79, %cx /* 80 cylinders 1200K and 1440K FD */
mov $2, %dh /* 2 heads as double side */
ok:
.code32
data32
call EXT(real_to_prot) /* back to protected mode */
/*
* form a longword representing all this gunk:
* 16 bit cylinder
* 8 bit head
* 8 bit sector
*/
mov %ecx, %eax
sal $16, %eax /* max cylinder number from zero */
mov %dx, %ax /* number of heads and sectors */
pop %ebx
pop %ebp
ret
/*
*
* memsize(i) : return the memory size in KB. i == 0 for conventional memory,
* i == 1 for extended memory
* Both have the return value in AX.
*
*/
ENTRY(memsize)
.code32
push %ebp
mov %esp, %ebp
push %ebx
push %esi
push %edi
mov 8(%ebp), %ebx
xor %eax, %eax
cmpb $0x01, %bl
jnz memcnv
memext:
movb 0xA1401 - BOOTSEG * 0x10, %al
shll $7, %eax
xorl %ebx, %ebx
movw 0xA1594 - BOOTSEG * 0x10, %bx
shll $10, %ebx
addl %ebx, %eax
jmp xdone
memcnv:
movb 0xA1501 - BOOTSEG * 0x10, %al
andb $0x07, %al
incl %eax
shll $7, %eax
xdone:
pop %edi
pop %esi
pop %ebx
pop %ebp
ret

View File

@ -1,408 +0,0 @@
/*
* 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]
*/
/*
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/cdefs.h>
__FBSDID("$FreeBSD$");
#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];
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 i, ret;
unsigned char disk_equips;
/* Pick up the story from the Bios on geometry of disks */
#ifdef GET_BIOSGEOM
for(ret = 0; ret < 2; ret ++) {
if (*(unsigned char*)V(0xA155d) & (1 << ret)) {
bootinfo.bi_bios_geom[ret] = get_diskinfo(ret + 0x80);
}
}
#endif
bootinfo.bi_basemem = memsize(0);
bootinfo.bi_extmem = memsize(1);
bootinfo.bi_memsizes_valid = 1;
gateA20();
#ifdef SET_MACHINE_TYPE
/* set machine type to PC98_SYSTEM_PARAMETER */
machine_check();
#endif
/*
* The default boot device is the first partition in the
* compatibility slice on the boot drive.
*/
dosdev = drive;
maj = (drive&0x70) >> 3; /* a good first bet */
if (maj == 4) { /* da */
disk_equips = *(unsigned char *)V(0xA1482);
unit = 0;
for (i=0; i<(drive&0x0f); i++) {
int media = ((unsigned *)V(0xA1460))[i] & 0x1F;
if ((disk_equips >> i) & 1) /* HD */
unit++;
else if (media == 7) /* MO */
unit++;
}
} else {
unit = drive & 0x0f;
}
readfile("boot.config", boot_config, BOOT_CONFIG_SIZE);
name = "/boot/loader";
if (boot_config[0] != '\0') {
getbootdev(boot_config, &loadflags);
printf("boot.config: %s", boot_config);
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" : "",
dosdev & 0x0f, devs[maj], unit, 'a' + part,
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"
, dosdev & 0x0f
, 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, 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.
*/
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) {
/* 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 == '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;
}

View File

@ -1,105 +0,0 @@
/*
* 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
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/time.h>
typedef int32_t ufs_daddr_t;
#define MAXFRAG 8
#include "quota.h"
#include "inode.h"
#include "fs.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 */
#ifdef 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);
void memcpy(const void *from, void *to, size_t len);
void twiddle(void);
void machine_check(void);
/* 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);
#define V(ra) (ra - BOOTSEG * 0x10)

395
sys/boot/pc98/boot2/boot1.S Normal file
View File

@ -0,0 +1,395 @@
/*-
* Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
* 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.
*
* $FreeBSD$
*/
/* Memory Locations */
.set STACK_OFF,0x6000 # Stack offset
.set LOAD_SIZE,8192 # Load size
.set DAUA,0x0584 # DA/UA
.set MEM_REL,0x700 # Relocation address
.set MEM_ARG,0x900 # Arguments
.set MEM_BUF,0x8cec # Load area
.set MEM_BTX,0x9000 # BTX start
.set MEM_JMP,0x9010 # BTX entry point
.set MEM_USR,0xa000 # Client start
/* PC98 machine type from sys/pc98/pc98/pc98_machdep.h */
.set MEM_SYS, 0xa100 # System common area segment
.set PC98_MACHINE_TYPE, 0x0620 # PC98 machine type
.set EPSON_ID, 0x0624 # EPSON machine id
.set M_NEC_PC98, 0x0001
.set M_EPSON_PC98, 0x0002
.set M_NOT_H98, 0x0010
.set M_H98, 0x0020
.set M_NOTE, 0x0040
.set M_NORMAL, 0x1000
.set M_8M, 0x8000
/* Partition Constants */
.set PRT_OFF,0x1be # Partition offset
/* Misc. Constants */
.set SIZ_PAG,0x1000 # Page size
.set SIZ_SEC,0x200 # Sector size
.set NSECT,0x10
.globl start
.globl read
.globl putc
.code16
start: jmp main
boot_cyl: .org 4
.ascii "IPL1 "
main: cld
/* Setup the stack */
xor %si,%si
mov %si,%ss
mov $STACK_OFF,%sp
push %cx
/* Relocate ourself to MEM_REL */
push %cs
pop %ds
mov %si,%es
mov $MEM_REL,%di
mov $SIZ_SEC,%cx
rep
movsb
/* Transfer PC-9801 system common area */
xor %ax,%ax
mov %ax,%si
mov %ax,%ds
mov %ax,%di
mov $MEM_SYS,%ax
mov %ax,%es
mov $0x0600,%cx
rep
movsb
/* Transfer EPSON machine type */
mov $0xfd00,%ax
mov %ax,%ds
mov (0x804),%eax
and $0x00ffffff,%eax
mov %eax,%es:(EPSON_ID)
/* Set machine type to PC98_SYSTEM_PARAMETER */
#ifdef SET_MACHINE_TYPE
call set_machine_type
#else
mov $M_NEC_PC98+M_NOT_H98,%eax
mov %eax,%es:(PC98_MACHINE_TYPE)
#endif
/* Setup graphic screen */
mov $0x42,%ah /* 640x400 */
mov $0xc0,%ch
int $0x18
mov $0x40,%ah /* graph on */
int $0x18
/* Setup text screen */
mov $0x0a00,%ax /* 80x25 */
int $0x18
mov $0x0c,%ah /* text on */
int $0x18
mov $0x13,%ah /* cursor home */
xor %dx,%dx
int $0x18
mov $0x11,%ah /* cursor on */
int $0x18
/* Setup keyboard */
mov $0x03,%ah
int $0x18
pop %cx
/* bootstrap passes */
xor %edi,%edi
mov %di,%ds
mov %di,%es
mov %cs,%bx
cmp $0x1fe0,%bx
jz boot_fd
cmp $0x1fc0,%bx
jnz boot_hd
xor %cx,%cx
mov (DAUA),%al
and $0xf0,%al
cmp $0x30,%al
jz boot_fd
cmp $0x90,%al
jnz boot_hd
boot_fd: xor %cx,%cx
jmp boot_load
boot_hd: test %cx,%cx
jnz boot_load
mov %cs:(boot_cyl),%cx
boot_load: mov %cx,MEM_ARG /* Save cylinder number */
mov %cx,%di
xor %dx,%dx
mov $LOAD_SIZE,%bx
mov $MEM_BUF,%bp
push %cs
callw read
jc error
/* Transfer boot2.bin */
mov $MEM_BTX,%bx
mov 0xa(%bx),%si /* BTX size */
add %bx,%si /* start of boot2.bin */
mov $MEM_USR+SIZ_PAG*2,%di
mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx
sub %si,%cx
rep
movsb
/* Enable A20 */
xor %ax,%ax
outb %al,$0xf2
mov $0x02,%al
outb %al,$0xf6
/* Start BTX */
ljmp $0x0000,$MEM_JMP
/*
* Reads sectors from the disk.
* Call with:
*
* %bx - bytes to read
* %cx - cylinder
* %dh - head
* %dl - sector
* %edi - lba
* %es:(%bp) - buffer to read data into
*/
read: xor %ax,%ax
mov %ax,%ds
mov $0x06,%ah
mov (DAUA),%al
mov %ax,%si
and $0xf0,%al
cmp $0x30,%al /* 1.44MB FDD */
jz read_fd
cmp $0x90,%al /* 1MB FDD */
jz read_fd
cmp $0xa0,%al /* Is SCSI device? */
jnz read_load
push %cx
mov %si,%cx
and $0x0f,%cl
inc %cl
mov (0x482),%ah
shr %cl,%ah /* Is SCSI HDD? */
pop %cx
jc read_load
and $0xff7f,%si /* SCSI MO */
mov %di,%cx
shr $16,%di
mov %di,%dx
jmp read_load
read_fd: or $0xd000,%si
or $0x0200,%cx
inc %dx
read_load: mov %si,%ax
int $0x1b
lret
/*
* Print out the error message, wait for a keypress, and then reboot
* the machine.
*/
error: push %cs
pop %ds
mov $msg_eread,%si
call putstr
xor %ax,%ax /* Get keypress */
int $0x18
xor %ax,%ax /* CPU reset */
outb %al,$0xf0
halt: hlt
jmp halt /* Spin */
/*
* Display a null-terminated string.
*/
putstr.0: push %cs
callw putc
putstr: lodsb
test %al,%al
jne putstr.0
ret
/*
* Display a single char.
*/
putc: pusha
xor %dx,%dx
mov %dx,%ds
mov MEM_REL+cursor-start,%di
mov $0xa000,%bx
mov %bx,%es
mov $(80*2),%cx
cmp $0x08,%al
je putc.bs
cmp $0x0d,%al
je putc.cr
cmp $0x0a,%al
je putc.lf
cmp $0x5c,%al /* \ */
jne 1f
mov $0xfc,%al
1: movb $0xe1,%es:0x2000(%di)
stosw
jmp putc.scr
putc.bs: test %di,%di
jz putc.move
dec %di
dec %di
movb $0xe1,%es:0x2000(%di)
movw $0x20,%es:(%di)
jmp putc.move
putc.cr: mov %di,%ax
div %cx
sub %dx,%di
jmp putc.move
putc.lf: add %cx,%di
putc.scr: cmp $(80*2*25),%di /* Scroll screen */
jb putc.move
push %ds
mov %bx,%ds
mov $(80*2),%si
xor %di,%di
mov $(80*24/2),%cx
rep
movsl
xor %ax,%ax
mov $0x20,%al
mov $80,%cl
rep
stosw
pop %ds
mov $(80*24*2),%di
putc.move: mov %di,MEM_REL+cursor-start /* Move cursor */
mov $0x13,%ah
mov %di,%dx
int $0x18
popa
lret
cursor: .word 0
#ifdef SET_MACHINE_TYPE
/*
* Set machine type to PC98_SYSTEM_PARAMETER.
*/
set_machine_type:
xor %edx,%edx
mov %dx,%ds
// mov $MEM_SYS,%ax
// mov %ax,%es
/* Wait V-SYNC */
vsync.1: inb $0x60,%al
test $0x20,%al
jnz vsync.1
vsync.2: inb $0x60,%al
test $0x20,%al
jz vsync.2
/* ANK 'A' font */
xor %al,%al
outb %al,$0xa1
mov $0x41,%al
outb %al,$0xa3
/* Get 'A' font from CG window */
push %ds
mov $0xa400,%ax
mov %ax,%ds
xor %eax,%eax
xor %bx,%bx
mov $4,%cx
font.1: add (%bx),%eax
add $4,%bx
loop font.1
pop %ds
cmp $0x6efc58fc,%eax
jnz m_epson
m_pc98: or $M_NEC_PC98,%edx
mov $0x0458,%bx
mov (%bx),%al
test $0x80,%al
jz m_not_h98
or $M_H98,%edx
jmp 1f
m_epson: or $M_EPSON_PC98,%edx
m_not_h98: or $M_NOT_H98,%edx
1: inb $0x42,%al
test $0x20,%al
jz 1f
or $M_8M,%edx
1: mov $0x0400,%bx
mov (%bx),%al
test $0x80,%al
jz 1f
or $M_NOTE,%edx
1: mov $PC98_MACHINE_TYPE,%bx
mov %edx,%es:(%bx)
ret
#endif
/* Messages */
msg_eread: .asciz "Error\r\n"
.org PRT_OFF,0x90
/* Partition table */
.fill 0x30,0x1,0x0
.byte 0x80, 0x00, 0x01, 0x00
.byte 0xa5, 0xff, 0xff, 0xff
.byte 0x00, 0x00, 0x00, 0x00
.byte 0x50, 0xc3, 0x00, 0x00
.word 0xaa55 # Magic number

View File

@ -1,182 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
* boot2.S,v 1.6 1995/01/25 21:37:40 bde Exp
* $FreeBSD$
*/
/*
* Ported to PC-9801 by Yoshio Kimura
*/
#include "asm.h"
/* Conventional GDT indexes. */
#define BOOT_CS_INDEX 3
#define BOOT_CS16_INDEX 5
#define BOOT_DS_INDEX 4
#ifdef BDE_DEBUGGER
#define DB_CS_INDEX 14
#define DB_CS16_INDEX 15
#define DB_DS_INDEX 16
#define GDT_INDEX 17
#endif
/* Vector numbers. */
#define BREAKPOINT_VECTOR 3
#define DEBUG_VECTOR 1
/*
* boot2() -- second stage boot
* SP points to default string if found
*/
.code16
ENTRY(boot2)
subl %eax, %eax
mov %cs, %ax
mov %ax, %ds
mov %ax, %es
shll $4, %eax
/* fix up GDT entries for bootstrap */
#define FIXUP(gdt_index) \
.code32; \
addr32; \
movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \
addr32; \
movb %bl, EXT(Gdt)+(8*gdt_index)+4; \
.code16
shld $16, %eax, %ebx
FIXUP(BOOT_CS_INDEX)
FIXUP(BOOT_CS16_INDEX)
FIXUP(BOOT_DS_INDEX)
/* fix up GDT pointer */
movl %eax, %ecx
addl $ EXT(Gdt), %eax
.code32
addr32
data32
movl %eax, EXT(Gdtr)+2
.code16
#ifdef BDE_DEBUGGER
/* fix up GDT entry for GDT */
data32
shld $16, %eax, %ebx
FIXUP(GDT_INDEX)
/* fix up IDT pointer */
data32
addl $ EXT(Idt), %ecx
addr32
data32
movl %ecx, EXT(Idtr_prot)+2
/* %es = vector table segment for a while */
push %es
data32
subl %eax, %eax
mov %ax, %es
/* fix up GDT entries for bdb */
data32
movl $4*DEBUG_VECTOR, %esi
addr32
movl %es: 2(%esi), %eax /* actually movw to %ax */
data32
shll $4, %eax
data32
shld $16, %eax, %ebx
FIXUP(DB_CS_INDEX)
FIXUP(DB_CS16_INDEX)
FIXUP(DB_DS_INDEX)
/* Fetch entry points of bdb's protected mode trap handlers. These
* are stored at 2 before the corresponding entry points for real mode.
*/
data32
subl %ebx, %ebx
addr32
movl %es: (%esi), %ebx /* actually movw to %bx */
data32
subl %ecx, %ecx
addr32
movl %es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx
/* actually movw to %cx */
/* %es = bdb segment for a while */
data32
shrl $4, %eax
mov %ax, %es
/* fix up IDT entries for bdb */
data32
subl $2, %ebx /* calculate EA to check it */
jb 1f /* give up if it would trap */
addr32
movl %es: (%ebx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
1:
data32
subl $2, %ecx
jb 1f
addr32
movl %es: (%ecx), %eax /* actually movw to %ax */
addr32
movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
1:
/* finished with groping in real mode segments */
pop %es
#endif /* BDE_DEBUGGER */
/* change to protected mode */
.code32
data32
call EXT(real_to_prot)
/* clear the bss */
movl $ EXT(edata), %edi /* no EXT(_edata) - krufty ld */
movl $ EXT(end), %ecx /* or EXT(_end) */
subl %edi, %ecx
subb %al, %al
rep
stosb
#ifdef NAMEBLOCK
movl %esp, EXT(dflt_name)
#endif
movb 0xA1584 - BOOTSEG * 0x10, %dl
movzbl %dl, %edx /* discard head (%dh) and random high bits */
pushl %edx
call EXT(boot)
oops:
hlt
jmp oops

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

@ -0,0 +1,842 @@
/*-
* Copyright (c) 2008-2009 TAKAHASHI Yoshihiro
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/diskpc98.h>
#include <sys/dirent.h>
#include <sys/reboot.h>
#include <machine/bootinfo.h>
#include <machine/cpufunc.h>
#include <machine/elf.h>
#include <machine/psl.h>
#include <stdarg.h>
#include <a.out.h>
#include <btxv86.h>
#include "boot2.h"
#include "lib.h"
#define IO_KEYBOARD 1
#define IO_SERIAL 2
#define SECOND 1 /* Circa that many ticks in a second. */
#define RBX_ASKNAME 0x0 /* -a */
#define RBX_SINGLE 0x1 /* -s */
/* 0x2 is reserved for log2(RB_NOSYNC). */
/* 0x3 is reserved for log2(RB_HALT). */
/* 0x4 is reserved for log2(RB_INITNAME). */
#define RBX_DFLTROOT 0x5 /* -r */
#define RBX_KDB 0x6 /* -d */
/* 0x7 is reserved for log2(RB_RDONLY). */
/* 0x8 is reserved for log2(RB_DUMP). */
/* 0x9 is reserved for log2(RB_MINIROOT). */
#define RBX_CONFIG 0xa /* -c */
#define RBX_VERBOSE 0xb /* -v */
#define RBX_SERIAL 0xc /* -h */
#define RBX_CDROM 0xd /* -C */
/* 0xe is reserved for log2(RB_POWEROFF). */
#define RBX_GDB 0xf /* -g */
#define RBX_MUTE 0x10 /* -m */
/* 0x11 is reserved for log2(RB_SELFTEST). */
/* 0x12 is reserved for boot programs. */
/* 0x13 is reserved for boot programs. */
#define RBX_PAUSE 0x14 /* -p */
#define RBX_QUIET 0x15 /* -q */
#define RBX_NOINTR 0x1c /* -n */
/* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */
#define RBX_DUAL 0x1d /* -D */
/* 0x1f is reserved for log2(RB_BOOTINFO). */
/* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */
#define RBX_MASK (OPT_SET(RBX_ASKNAME) | OPT_SET(RBX_SINGLE) | \
OPT_SET(RBX_DFLTROOT) | OPT_SET(RBX_KDB ) | \
OPT_SET(RBX_CONFIG) | OPT_SET(RBX_VERBOSE) | \
OPT_SET(RBX_SERIAL) | OPT_SET(RBX_CDROM) | \
OPT_SET(RBX_GDB ) | OPT_SET(RBX_MUTE) | \
OPT_SET(RBX_PAUSE) | OPT_SET(RBX_DUAL))
#define PATH_CONFIG "/boot.config"
#define PATH_BOOT3 "/boot/loader"
#define PATH_KERNEL "/boot/kernel/kernel"
#define ARGS 0x900
#define NOPT 14
#define NDEV 3
#define V86_CY(x) ((x) & PSL_C)
#define V86_ZR(x) ((x) & PSL_Z)
#define DRV_DISK 0xf0
#define DRV_UNIT 0x0f
#define TYPE_AD 0
#define TYPE_DA 1
#define TYPE_FD 2
#define OPT_SET(opt) (1 << (opt))
#define OPT_CHECK(opt) ((opts) & OPT_SET(opt))
extern uint32_t _end;
static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
static const unsigned char flags[NOPT] = {
RBX_DUAL,
RBX_SERIAL,
RBX_ASKNAME,
RBX_CDROM,
RBX_CONFIG,
RBX_KDB,
RBX_GDB,
RBX_MUTE,
RBX_NOINTR,
RBX_PAUSE,
RBX_QUIET,
RBX_DFLTROOT,
RBX_SINGLE,
RBX_VERBOSE
};
static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
static const unsigned char dev_maj[NDEV] = {30, 4, 2};
static const unsigned char dev_daua[NDEV] = {0x80, 0xa0, 0x90};
static struct dsk {
unsigned daua;
unsigned type;
unsigned disk;
unsigned unit;
unsigned head;
unsigned sec;
unsigned slice;
unsigned part;
unsigned start;
} dsk;
static char cmd[512], cmddup[512];
static char kname[1024];
static uint32_t opts;
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
static uint8_t ioctrl = IO_KEYBOARD;
void exit(int);
static void load(void);
static int parse(void);
static int xfsread(ino_t, void *, size_t);
static int dskread(void *, unsigned, unsigned);
static void printf(const char *,...);
static void putchar(int);
static uint32_t memsize(void);
static int drvread(void *, unsigned);
static int keyhit(unsigned);
static int xputc(int);
static int xgetc(int);
static int getc(int);
static void memcpy(void *, const void *, int);
static void
memcpy(void *dst, const void *src, int len)
{
const char *s = src;
char *d = dst;
while (len--)
*d++ = *s++;
}
static inline int
strcmp(const char *s1, const char *s2)
{
for (; *s1 == *s2 && *s1; s1++, s2++);
return (unsigned char)*s1 - (unsigned char)*s2;
}
#define UFS_SMALL_CGBASE
#include "ufsread.c"
static inline int
xfsread(ino_t inode, void *buf, size_t nbyte)
{
if ((size_t)fsread(inode, buf, nbyte) != nbyte) {
printf("Invalid %s\n", "format");
return -1;
}
return 0;
}
static inline uint32_t
memsize(void)
{
u_char *p = (u_char *)PTOV(0);
return *(p + 0x401) * 128 * 1024 + *(u_int16_t *)(p + 0x594) * 1024 * 1024;
}
static inline void
getstr(void)
{
char *s;
int c;
s = cmd;
for (;;) {
switch (c = xgetc(0)) {
case 0:
break;
case '\177':
case '\b':
if (s > cmd) {
s--;
printf("\b \b");
}
break;
case '\n':
case '\r':
*s = 0;
return;
default:
if (s - cmd < sizeof(cmd) - 1)
*s++ = c;
putchar(c);
}
}
}
static inline void
putc(int c)
{
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
v86.addr = PUTCORG; /* call to putc in boot1 */
v86.eax = c;
v86int();
v86.ctl = V86_FLAGS;
}
static inline int
is_scsi_hd(void)
{
if ((*(u_char *)PTOV(0x482) >> dsk.unit) & 0x01)
return 1;
return 0;
}
static inline void
fix_sector_size(void)
{
u_char *p;
p = (u_char *)PTOV(0x460 + dsk.unit * 4); /* SCSI equipment parameter */
if ((p[0] & 0x1f) == 7) { /* SCSI MO */
if (!(p[3] & 0x30)) { /* 256B / sector */
p[3] |= 0x10; /* forced set 512B / sector */
p[3 + 0xa1000] |= 0x10;
}
}
}
static inline uint32_t
get_diskinfo(void)
{
if (dsk.disk == 0x30) { /* 1440KB FD */
/* 80 cylinders, 2 heads, 18 sectors */
return (80 << 16) | (2 << 8) | 18;
} else if (dsk.disk == 0x90) { /* 1200KB FD */
/* 80 cylinders, 2 heads, 15 sectors */
return (80 << 16) | (2 << 8) | 15;
} else if (dsk.disk == 0x80 || is_scsi_hd()) { /* IDE or SCSI HDD */
v86.addr = 0x1b;
v86.eax = 0x8400 | dsk.daua;
v86int();
return (v86.ecx << 16) | v86.edx;
}
/* SCSI MO or CD */
fix_sector_size(); /* SCSI MO */
/* other SCSI devices */
return (65535 << 16) | (8 << 8) | 32;
}
static void
set_dsk(void)
{
uint32_t di;
di = get_diskinfo();
dsk.head = (di >> 8) & 0xff;
dsk.sec = di & 0xff;
dsk.start = 0;
}
#ifdef GET_BIOSGEOM
static uint32_t
bd_getbigeom(int bunit)
{
int hds = 0;
int unit = 0x80; /* IDE HDD */
u_int addr = 0x55d;
while (unit < 0xa7) {
if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f)))
if (hds++ == bunit)
break;
if (unit >= 0xA0) {
int media = ((unsigned *)PTOV(0x460))[unit & 0x0F] & 0x1F;
if (media == 7 && hds++ == bunit) /* SCSI MO */
return(0xFFFE0820); /* C:65535 H:8 S:32 */
}
if (++unit == 0x84) {
unit = 0xA0; /* SCSI HDD */
addr = 0x482;
}
}
if (unit == 0xa7)
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
v86.addr = 0x1b;
v86.eax = 0x8400 | unit;
v86int();
if (v86.efl & 0x1)
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */
return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff);
}
#endif
static int
check_slice(void)
{
struct pc98_partition *dp;
char *sec;
unsigned i, cyl;
sec = dmadat->secbuf;
cyl = *(uint16_t *)PTOV(ARGS);
set_dsk();
if (dsk.type == TYPE_FD)
return (WHOLE_DISK_SLICE);
if (drvread(sec, DOSBBSECTOR + 1))
return (WHOLE_DISK_SLICE); /* Read error */
dp = (void *)(sec + DOSPARTOFF);
for (i = 0; i < NDOSPART; i++) {
if (dp[i].dp_mid == DOSMID_386BSD) {
if (dp[i].dp_scyl <= cyl && cyl <= dp[i].dp_ecyl)
return (BASE_SLICE + i);
}
}
return (WHOLE_DISK_SLICE);
}
int
main(void)
{
#ifdef GET_BIOSGEOM
int i;
#endif
int autoboot;
ino_t ino;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
v86.ctl = V86_FLAGS;
v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
dsk.daua = *(uint8_t *)PTOV(0x584);
dsk.disk = dsk.daua & DRV_DISK;
dsk.unit = dsk.daua & DRV_UNIT;
if (dsk.disk == 0x80)
dsk.type = TYPE_AD;
else if (dsk.disk == 0xa0)
dsk.type = TYPE_DA;
else /* if (dsk.disk == 0x30 || dsk.disk == 0x90) */
dsk.type = TYPE_FD;
dsk.slice = check_slice();
#ifdef GET_BIOSGEOM
for (i = 0; i < N_BIOS_GEOM; i++)
bootinfo.bi_bios_geom[i] = bd_getbigeom(i);
#endif
bootinfo.bi_version = BOOTINFO_VERSION;
bootinfo.bi_size = sizeof(bootinfo);
bootinfo.bi_basemem = 0; /* XXX will be filled by loader or kernel */
bootinfo.bi_extmem = memsize();
bootinfo.bi_memsizes_valid++;
/* Process configuration file */
autoboot = 1;
if ((ino = lookup(PATH_CONFIG)))
fsread(ino, cmd, sizeof(cmd));
if (*cmd) {
memcpy(cmddup, cmd, sizeof(cmd));
if (parse())
autoboot = 0;
if (!OPT_CHECK(RBX_QUIET))
printf("%s: %s", PATH_CONFIG, cmddup);
/* Do not process this command twice */
*cmd = 0;
}
/*
* Try to exec stage 3 boot loader. If interrupted by a keypress,
* or in case of failure, try to load a kernel directly instead.
*/
if (autoboot && !*kname) {
memcpy(kname, PATH_BOOT3, sizeof(PATH_BOOT3));
if (!keyhit(3*SECOND)) {
load();
memcpy(kname, PATH_KERNEL, sizeof(PATH_KERNEL));
}
}
/* Present the user with the boot2 prompt. */
for (;;) {
if (!autoboot || !OPT_CHECK(RBX_QUIET))
printf("\nFreeBSD/pc98 boot\n"
"Default: %u:%s(%u,%c)%s\n"
"boot: ",
dsk.unit, dev_nm[dsk.type], dsk.unit,
'a' + dsk.part, kname);
if (ioctrl & IO_SERIAL)
sio_flush();
if (!autoboot || keyhit(5*SECOND))
getstr();
else if (!autoboot || !OPT_CHECK(RBX_QUIET))
putchar('\n');
autoboot = 0;
if (parse())
putchar('\a');
else
load();
}
}
/* XXX - Needed for btxld to link the boot2 binary; do not remove. */
void
exit(int x)
{
}
static void
load(void)
{
union {
struct exec ex;
Elf32_Ehdr eh;
} hdr;
static Elf32_Phdr ep[2];
static Elf32_Shdr es[2];
caddr_t p;
ino_t ino;
uint32_t addr, x;
int fmt, i, j;
if (!(ino = lookup(kname))) {
if (!ls)
printf("No %s\n", kname);
return;
}
if (xfsread(ino, &hdr, sizeof(hdr)))
return;
if (N_GETMAGIC(hdr.ex) == ZMAGIC)
fmt = 0;
else if (IS_ELF(hdr.eh))
fmt = 1;
else {
printf("Invalid %s\n", "format");
return;
}
if (fmt == 0) {
addr = hdr.ex.a_entry & 0xffffff;
p = PTOV(addr);
fs_off = PAGE_SIZE;
if (xfsread(ino, p, hdr.ex.a_text))
return;
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
if (xfsread(ino, p, hdr.ex.a_data))
return;
p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
bootinfo.bi_symtab = VTOP(p);
memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
p += sizeof(hdr.ex.a_syms);
if (hdr.ex.a_syms) {
if (xfsread(ino, p, hdr.ex.a_syms))
return;
p += hdr.ex.a_syms;
if (xfsread(ino, p, sizeof(int)))
return;
x = *(uint32_t *)p;
p += sizeof(int);
x -= sizeof(int);
if (xfsread(ino, p, x))
return;
p += x;
}
} else {
fs_off = hdr.eh.e_phoff;
for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
if (xfsread(ino, ep + j, sizeof(ep[0])))
return;
if (ep[j].p_type == PT_LOAD)
j++;
}
for (i = 0; i < 2; i++) {
p = PTOV(ep[i].p_paddr & 0xffffff);
fs_off = ep[i].p_offset;
if (xfsread(ino, p, ep[i].p_filesz))
return;
}
p += roundup2(ep[1].p_memsz, PAGE_SIZE);
bootinfo.bi_symtab = VTOP(p);
if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
(hdr.eh.e_shstrndx + 1);
if (xfsread(ino, &es, sizeof(es)))
return;
for (i = 0; i < 2; i++) {
memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
p += sizeof(es[i].sh_size);
fs_off = es[i].sh_offset;
if (xfsread(ino, p, es[i].sh_size))
return;
p += es[i].sh_size;
}
}
addr = hdr.eh.e_entry & 0xffffff;
}
bootinfo.bi_esymtab = VTOP(p);
bootinfo.bi_kernelname = VTOP(kname);
bootinfo.bi_bios_dev = dsk.daua;
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dev_maj[dsk.type], dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));
}
static int
parse()
{
char *arg = cmd;
char *ep, *p, *q;
const char *cp;
unsigned int drv;
int c, i, j;
while ((c = *arg++)) {
if (c == ' ' || c == '\t' || c == '\n')
continue;
for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
ep = p;
if (*p)
*p++ = 0;
if (c == '-') {
while ((c = *arg++)) {
if (c == 'P') {
if (*(uint8_t *)PTOV(0x481) & 0x48) {
cp = "yes";
} else {
opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
cp = "no";
}
printf("Keyboard: %s\n", cp);
continue;
} else if (c == 'S') {
j = 0;
while ((unsigned int)(i = *arg++ - '0') <= 9)
j = j * 10 + i;
if (j > 0 && i == -'0') {
comspeed = j;
break;
}
/* Fall through to error below ('S' not in optstr[]). */
}
for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1)
return -1;
opts ^= OPT_SET(flags[i]);
}
ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
if (ioctrl & IO_SERIAL)
sio_init(115200 / comspeed);
} else {
for (q = arg--; *q && *q != '('; q++);
if (*q) {
drv = -1;
if (arg[1] == ':') {
drv = *arg - '0';
if (drv > 9)
return (-1);
arg += 2;
}
if (q - arg != 2)
return -1;
for (i = 0; arg[0] != dev_nm[i][0] ||
arg[1] != dev_nm[i][1]; i++)
if (i == NDEV - 1)
return -1;
dsk.type = i;
arg += 3;
dsk.unit = *arg - '0';
if (arg[1] != ',' || dsk.unit > 9)
return -1;
arg += 2;
dsk.slice = WHOLE_DISK_SLICE;
if (arg[1] == ',') {
dsk.slice = *arg - '0' + 1;
if (dsk.slice > NDOSPART + 1)
return -1;
arg += 2;
}
if (arg[1] != ')')
return -1;
dsk.part = *arg - 'a';
if (dsk.part > 7)
return (-1);
arg += 2;
if (drv == -1)
drv = dsk.unit;
dsk.disk = dev_daua[dsk.type];
dsk.daua = dsk.disk | dsk.unit;
dsk_meta = 0;
}
if ((i = ep - arg)) {
if ((size_t)i >= sizeof(kname))
return -1;
memcpy(kname, arg, i + 1);
}
}
arg = p;
}
return 0;
}
static int
dskread(void *buf, unsigned lba, unsigned nblk)
{
struct pc98_partition *dp;
struct disklabel *d;
char *sec;
unsigned sl, i;
u_char *p;
if (!dsk_meta) {
sec = dmadat->secbuf;
set_dsk();
if (dsk.type == TYPE_FD)
goto unsliced;
if (drvread(sec, DOSBBSECTOR + 1))
return -1;
dp = (void *)(sec + DOSPARTOFF);
sl = dsk.slice;
if (sl < BASE_SLICE) {
for (i = 0; i < NDOSPART; i++)
if (dp[i].dp_mid == DOSMID_386BSD) {
sl = BASE_SLICE + i;
break;
}
dsk.slice = sl;
}
if (sl != WHOLE_DISK_SLICE) {
dp += sl - BASE_SLICE;
if (dp->dp_mid != DOSMID_386BSD) {
printf("Invalid %s\n", "slice");
return -1;
}
dsk.start = dp->dp_scyl * dsk.head * dsk.sec +
dp->dp_shd * dsk.sec + dp->dp_ssect;
}
if (drvread(sec, dsk.start + LABELSECTOR))
return -1;
d = (void *)(sec + LABELOFFSET);
if (d->d_magic != DISKMAGIC || d->d_magic2 != DISKMAGIC) {
if (dsk.part != RAW_PART) {
printf("Invalid %s\n", "label");
return -1;
}
} else {
if (dsk.part >= d->d_npartitions ||
!d->d_partitions[dsk.part].p_size) {
printf("Invalid %s\n", "partition");
return -1;
}
dsk.start += d->d_partitions[dsk.part].p_offset;
dsk.start -= d->d_partitions[RAW_PART].p_offset;
}
unsliced: ;
}
for (p = buf; nblk; p += 512, lba++, nblk--) {
if ((i = drvread(p, dsk.start + lba)))
return i;
}
return 0;
}
static void
printf(const char *fmt,...)
{
va_list ap;
char buf[10];
char *s;
unsigned u;
int c;
va_start(ap, fmt);
while ((c = *fmt++)) {
if (c == '%') {
c = *fmt++;
switch (c) {
case 'c':
putchar(va_arg(ap, int));
continue;
case 's':
for (s = va_arg(ap, char *); *s; s++)
putchar(*s);
continue;
case 'u':
u = va_arg(ap, unsigned);
s = buf;
do
*s++ = '0' + u % 10U;
while (u /= 10U);
while (--s >= buf)
putchar(*s);
continue;
}
}
putchar(c);
}
va_end(ap);
return;
}
static void
putchar(int c)
{
if (c == '\n')
xputc('\r');
xputc(c);
}
static int
drvread(void *buf, unsigned lba)
{
static unsigned c = 0x2d5c7c2f;
unsigned bpc, x, cyl, head, sec;
bpc = dsk.sec * dsk.head;
cyl = lba / bpc;
x = lba % bpc;
head = x / dsk.sec;
sec = x % dsk.sec;
if (!OPT_CHECK(RBX_QUIET))
printf("%c\b", c = c << 8 | c >> 24);
v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
v86.addr = READORG; /* call to read in boot1 */
v86.ecx = cyl;
v86.edx = (head << 8) | sec;
v86.edi = lba;
v86.ebx = 512;
v86.es = VTOPSEG(buf);
v86.ebp = VTOPOFF(buf);
v86int();
v86.ctl = V86_FLAGS;
if (V86_CY(v86.efl)) {
printf("error %u c/h/s %u/%u/%u lba %u\n", v86.eax >> 8 & 0xff,
cyl, head, sec, lba);
return -1;
}
return 0;
}
static inline void
delay(void)
{
int i;
i = 800;
do {
outb(0x5f, 0); /* about 600ns */
} while (--i >= 0);
}
static int
keyhit(unsigned sec)
{
unsigned i;
if (OPT_CHECK(RBX_NOINTR))
return 0;
for (i = 0; i < sec * 1000; i++) {
if (xgetc(1))
return 1;
delay();
}
return 0;
}
static int
xputc(int c)
{
if (ioctrl & IO_KEYBOARD)
putc(c);
if (ioctrl & IO_SERIAL)
sio_putc(c);
return c;
}
static int
xgetc(int fn)
{
if (OPT_CHECK(RBX_NOINTR))
return 0;
for (;;) {
if (ioctrl & IO_KEYBOARD && getc(1))
return fn ? 1 : getc(0);
if (ioctrl & IO_SERIAL && sio_ischar())
return fn ? 1 : sio_getc();
if (fn)
return 0;
}
}
static int
getc(int fn)
{
v86.addr = 0x18;
v86.eax = fn << 8;
v86int();
if (fn)
return (v86.ebx >> 8) & 0x01;
else
return v86.eax & 0xff;
}

View File

@ -1,126 +0,0 @@
/*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* 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.
* 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.
*
* @(#)dinode.h 8.3 (Berkeley) 1/21/94
* %FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.7 1999/08/28 00:52:27 peter Exp %
* $FreeBSD$
*/
#ifndef _UFS_UFS_DINODE_H_
#define _UFS_UFS_DINODE_H_
/*
* The root inode is the root of the file system. Inode 0 can't be used for
* normal purposes and historically bad blocks were linked to inode 1, thus
* the root inode is 2. (Inode 1 is no longer used for this purpose, however
* numerous dump tapes make this assumption, so we are stuck with it).
*/
#define ROOTINO ((ino_t)2)
/*
* The Whiteout inode# is a dummy non-zero inode number which will
* never be allocated to a real file. It is used as a place holder
* in the directory entry which has been tagged as a DT_W entry.
* See the comments about ROOTINO above.
*/
#define WINO ((ino_t)1)
/*
* A dinode contains all the meta-data associated with a UFS file.
* This structure defines the on-disk format of a dinode. Since
* this structure describes an on-disk structure, all its fields
* are defined by types with precise widths.
*/
/* typedef int32_t ufs_daddr_t; */
#define NDADDR 12 /* Direct addresses in inode. */
#define NIADDR 3 /* Indirect addresses in inode. */
struct dinode {
u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
int16_t di_nlink; /* 2: File link count. */
union {
u_int16_t oldids[2]; /* 4: Ffs: old user and group ids. */
int32_t inumber; /* 4: Lfs: inode number. */
} di_u;
u_int64_t di_size; /* 8: File byte count. */
int32_t di_atime; /* 16: Last access time. */
int32_t di_atimensec; /* 20: Last access time. */
int32_t di_mtime; /* 24: Last modified time. */
int32_t di_mtimensec; /* 28: Last modified time. */
int32_t di_ctime; /* 32: Last inode change time. */
int32_t di_ctimensec; /* 36: Last inode change time. */
ufs_daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */
ufs_daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */
u_int32_t di_flags; /* 100: Status flags (chflags). */
int32_t di_blocks; /* 104: Blocks actually held. */
int32_t di_gen; /* 108: Generation number. */
u_int32_t di_uid; /* 112: File owner. */
u_int32_t di_gid; /* 116: File group. */
int32_t di_spare[2]; /* 120: Reserved; currently unused */
};
/*
* The di_db fields may be overlaid with other information for
* file types that do not have associated disk storage. Block
* and character devices overlay the first data block with their
* dev_t value. Short symbolic links place their path in the
* di_db area.
*/
#define di_inumber di_u.inumber
#define di_ogid di_u.oldids[1]
#define di_ouid di_u.oldids[0]
#define di_rdev di_db[0]
#define di_shortlink di_db
#define MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(ufs_daddr_t))
/* File permissions. */
#define IEXEC 0000100 /* Executable. */
#define IWRITE 0000200 /* Writeable. */
#define IREAD 0000400 /* Readable. */
#define ISVTX 0001000 /* Sticky bit. */
#define ISGID 0002000 /* Set-gid. */
#define ISUID 0004000 /* Set-uid. */
/* File types. */
#define IFMT 0170000 /* Mask of file type. */
#define IFIFO 0010000 /* Named pipe (fifo). */
#define IFCHR 0020000 /* Character device. */
#define IFDIR 0040000 /* Directory file. */
#define IFBLK 0060000 /* Block device. */
#define IFREG 0100000 /* Regular file. */
#define IFLNK 0120000 /* Symbolic link. */
#define IFSOCK 0140000 /* UNIX domain socket. */
#define IFWHT 0160000 /* Whiteout. */
#endif

View File

@ -1,174 +0,0 @@
/*
* 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
*/
/*
* 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "boot.h"
#include <sys/disklabel.h>
#include <sys/diskpc98.h>
#include <machine/bootinfo.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)
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 char *Bread(int dosdev, int sector);
int
devopen(void)
{
struct pc98_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);
if ((dosdev_copy & 0xf0) == 0x90)
{
boff = 0;
part = (spt == 15 ? 0 : 1);
}
else
{
#ifdef EMBEDDED_DISKLABEL
dl = &disklabel;
#else /* EMBEDDED_DISKLABEL */
p = Bread(dosdev_copy, 1);
dptr = (struct pc98_partition *)p;
slice = WHOLE_DISK_SLICE;
for (i = 0; i < NDOSPART; i++, dptr++)
if (dptr->dp_mid == DOSMID_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)*/
#endif /* EMBEDDED_DISKLABEL */
if (dl->d_magic != DISKMAGIC) {
printf("bad disklabel\n");
return 1;
}
/* This little trick is for OnTrack DiskManager disks */
boff = dl->d_partitions[part].p_offset -
dl->d_partitions[2].p_offset + sector;
}
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, sector++);
memcpy(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;
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);
}

View File

@ -1,551 +0,0 @@
/*
* Copyright (c) 1982, 1986, 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.
* 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.
*
* @(#)fs.h 8.13 (Berkeley) 3/21/95
* %FreeBSD: src/sys/ufs/ffs/fs.h,v 1.14.2.3 2001/09/21 19:15:22 dillon Exp %
* $FreeBSD$
*/
#ifndef _UFS_FFS_FS_H_
#define _UFS_FFS_FS_H_
/*
* Each disk drive contains some number of file systems.
* A file system consists of a number of cylinder groups.
* Each cylinder group has inodes and data.
*
* A file system is described by its super-block, which in turn
* describes the cylinder groups. The super-block is critical
* data and is replicated in each cylinder group to protect against
* catastrophic loss. This is done at `newfs' time and the critical
* super-block data does not change, so the copies need not be
* referenced further unless disaster strikes.
*
* For file system fs, the offsets of the various blocks of interest
* are given in the super block as:
* [fs->fs_sblkno] Super-block
* [fs->fs_cblkno] Cylinder group block
* [fs->fs_iblkno] Inode blocks
* [fs->fs_dblkno] Data blocks
* The beginning of cylinder group cg in fs, is given by
* the ``cgbase(fs, cg)'' macro.
*
* The first boot and super blocks are given in absolute disk addresses.
* The byte-offset forms are preferred, as they don't imply a sector size.
*/
#define BBSIZE 8192
#define SBSIZE 8192
#define BBOFF ((off_t)(0))
#define SBOFF ((off_t)(BBOFF + BBSIZE))
#define BBLOCK ((ufs_daddr_t)(0))
#define SBLOCK ((ufs_daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
/*
* Addresses stored in inodes are capable of addressing fragments
* of `blocks'. File system blocks of at most size MAXBSIZE can
* be optionally broken into 2, 4, or 8 pieces, each of which is
* addressable; these pieces may be DEV_BSIZE, or some multiple of
* a DEV_BSIZE unit.
*
* Large files consist of exclusively large data blocks. To avoid
* undue wasted disk space, the last data block of a small file may be
* allocated as only as many fragments of a large block as are
* necessary. The file system format retains only a single pointer
* to such a fragment, which is a piece of a single large block that
* has been divided. The size of such a fragment is determinable from
* information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
*
* The file system records space availability at the fragment level;
* to determine block availability, aligned fragments are examined.
*/
/*
* MINBSIZE is the smallest allowable block size.
* In order to insure that it is possible to create files of size
* 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
* MINBSIZE must be big enough to hold a cylinder group block,
* thus changes to (struct cg) must keep its size within MINBSIZE.
* Note that super blocks are always of size SBSIZE,
* and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
*/
#define MINBSIZE 4096
/*
* The path name on which the file system is mounted is maintained
* in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in
* the super block for this name.
*/
#define MAXMNTLEN 512
/*
* There is a 128-byte region in the superblock reserved for in-core
* pointers to summary information. Originally this included an array
* of pointers to blocks of struct csum; now there are just three
* pointers and the remaining space is padded with fs_ocsp[].
*
* NOCSPTRS determines the size of this padding. One pointer (fs_csp)
* is taken away to point to a contiguous array of struct csum for
* all cylinder groups; a second (fs_maxcluster) points to an array
* of cluster sizes that is computed as cylinder groups are inspected,
* and the third points to an array that tracks the creation of new
* directories.
*/
#define NOCSPTRS ((128 / sizeof(void *)) - 3)
/*
* A summary of contiguous blocks of various sizes is maintained
* in each cylinder group. Normally this is set by the initial
* value of fs_maxcontig. To conserve space, a maximum summary size
* is set by FS_MAXCONTIG.
*/
#define FS_MAXCONTIG 16
/*
* MINFREE gives the minimum acceptable percentage of file system
* blocks which may be free. If the freelist drops below this level
* only the superuser may continue to allocate blocks. This may
* be set to 0 if no reserve of free blocks is deemed necessary,
* however throughput drops by fifty percent if the file system
* is run at between 95% and 100% full; thus the minimum default
* value of fs_minfree is 5%. However, to get good clustering
* performance, 10% is a better choice. hence we use 10% as our
* default value. With 10% free space, fragmentation is not a
* problem, so we choose to optimize for time.
*/
#define MINFREE 8
#define DEFAULTOPT FS_OPTTIME
/*
* Grigoriy Orlov <gluk@ptci.ru> has done some extensive work to fine
* tune the layout preferences for directories within a filesystem.
* His algorithm can be tuned by adjusting the following parameters
* which tell the system the average file size and the average number
* of files per directory. These defaults are well selected for typical
* filesystems, but may need to be tuned for odd cases like filesystems
* being used for sqiud caches or news spools.
*/
#define AVFILESIZ 16384 /* expected average file size */
#define AFPDIR 64 /* expected number of files per directory */
/*
* The maximum number of snapshot nodes that can be associated
* with each filesystem. This limit affects only the number of
* snapshot files that can be recorded within the superblock so
* that they can be found when the filesystem is mounted. However,
* maintaining too many will slow the filesystem performance, so
* having this limit is a good idea.
*
* VALUE NOT IMPLEMENTED IN 4.x YET, RESERVED FROM -CURRENT SO SUPERBLOCKS
* REMAIN COMPATIBLE.
*/
#define FSMAXSNAP 20
/*
* Per cylinder group information; summarized in blocks allocated
* from first cylinder group data blocks. These blocks have to be
* read in from fs_csaddr (size fs_cssize) in addition to the
* super block.
*/
struct csum {
int32_t cs_ndir; /* number of directories */
int32_t cs_nbfree; /* number of free blocks */
int32_t cs_nifree; /* number of free inodes */
int32_t cs_nffree; /* number of free frags */
};
/*
* Super block for an FFS file system.
*/
struct fs {
int32_t fs_firstfield; /* historic file system linked list, */
int32_t fs_unused_1; /* used for incore super blocks */
ufs_daddr_t fs_sblkno; /* addr of super-block in filesys */
ufs_daddr_t fs_cblkno; /* offset of cyl-block in filesys */
ufs_daddr_t fs_iblkno; /* offset of inode-blocks in filesys */
ufs_daddr_t fs_dblkno; /* offset of first data after cg */
int32_t fs_cgoffset; /* cylinder group offset in cylinder */
int32_t fs_cgmask; /* used to calc mod fs_ntrak */
time_t fs_time; /* last time written */
int32_t fs_size; /* number of blocks in fs */
int32_t fs_dsize; /* number of data blocks in fs */
int32_t fs_ncg; /* number of cylinder groups */
int32_t fs_bsize; /* size of basic blocks in fs */
int32_t fs_fsize; /* size of frag blocks in fs */
int32_t fs_frag; /* number of frags in a block in fs */
/* these are configuration parameters */
int32_t fs_minfree; /* minimum percentage of free blocks */
int32_t fs_rotdelay; /* num of ms for optimal next block */
int32_t fs_rps; /* disk revolutions per second */
/* these fields can be computed from the others */
int32_t fs_bmask; /* ``blkoff'' calc of blk offsets */
int32_t fs_fmask; /* ``fragoff'' calc of frag offsets */
int32_t fs_bshift; /* ``lblkno'' calc of logical blkno */
int32_t fs_fshift; /* ``numfrags'' calc number of frags */
/* these are configuration parameters */
int32_t fs_maxcontig; /* max number of contiguous blks */
int32_t fs_maxbpg; /* max number of blks per cyl group */
/* these fields can be computed from the others */
int32_t fs_fragshift; /* block to frag shift */
int32_t fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
int32_t fs_sbsize; /* actual size of super block */
int32_t fs_csmask; /* csum block offset (now unused) */
int32_t fs_csshift; /* csum block number (now unused) */
int32_t fs_nindir; /* value of NINDIR */
int32_t fs_inopb; /* value of INOPB */
int32_t fs_nspf; /* value of NSPF */
/* yet another configuration parameter */
int32_t fs_optim; /* optimization preference, see below */
/* these fields are derived from the hardware */
int32_t fs_npsect; /* # sectors/track including spares */
int32_t fs_interleave; /* hardware sector interleave */
int32_t fs_trackskew; /* sector 0 skew, per track */
/* fs_id takes the space of the unused fs_headswitch and fs_trkseek fields */
int32_t fs_id[2]; /* unique filesystem id */
/* sizes determined by number of cylinder groups and their sizes */
ufs_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
int32_t fs_cssize; /* size of cyl grp summary area */
int32_t fs_cgsize; /* cylinder group size */
/* these fields are derived from the hardware */
int32_t fs_ntrak; /* tracks per cylinder */
int32_t fs_nsect; /* sectors per track */
int32_t fs_spc; /* sectors per cylinder */
/* this comes from the disk driver partitioning */
int32_t fs_ncyl; /* cylinders in file system */
/* these fields can be computed from the others */
int32_t fs_cpg; /* cylinders per group */
int32_t fs_ipg; /* inodes per group */
int32_t fs_fpg; /* blocks per group * fs_frag */
/* this data must be re-computed after crashes */
struct csum fs_cstotal; /* cylinder summary information */
/* these fields are cleared at mount time */
int8_t fs_fmod; /* super block modified flag */
int8_t fs_clean; /* file system is clean flag */
int8_t fs_ronly; /* mounted read-only flag */
int8_t fs_flags; /* see FS_ flags below */
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
/* these fields retain the current block allocation info */
int32_t fs_cgrotor; /* last cg searched */
void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */
u_int8_t *fs_contigdirs; /* # of contiguously allocated dirs */
struct csum *fs_csp; /* cg summary info buffer for fs_cs */
int32_t *fs_maxcluster; /* max cluster in each cyl group */
int32_t fs_cpc; /* cyl per cycle in postbl */
int16_t fs_opostbl[16][8]; /* old rotation block list head */
int32_t fs_snapinum[FSMAXSNAP];/* RESERVED FROM 5.x */
int32_t fs_avgfilesize; /* expected average file size */
int32_t fs_avgfpdir; /* expected # of files per directory */
int32_t fs_sparecon[26]; /* reserved for future constants */
int32_t fs_pendingblocks; /* RESERVED FROM 5.x */
int32_t fs_pendinginodes; /* RESERVED FROM 5.x */
int32_t fs_contigsumsize; /* size of cluster summary array */
int32_t fs_maxsymlinklen; /* max length of an internal symlink */
int32_t fs_inodefmt; /* format of on-disk inodes */
u_int64_t fs_maxfilesize; /* maximum representable file size */
int64_t fs_qbmask; /* ~fs_bmask for use with 64-bit size */
int64_t fs_qfmask; /* ~fs_fmask for use with 64-bit size */
int32_t fs_state; /* validate fs_clean field */
int32_t fs_postblformat; /* format of positional layout tables */
int32_t fs_nrpos; /* number of rotational positions */
int32_t fs_postbloff; /* (u_int16) rotation block list head */
int32_t fs_rotbloff; /* (u_int8) blocks for each rotation */
int32_t fs_magic; /* magic number */
u_int8_t fs_space[1]; /* list of blocks for each rotation */
/* actually longer */
};
/*
* Filesystem identification
*/
#define FS_MAGIC 0x011954 /* the fast filesystem magic number */
#define FS_OKAY 0x7c269d38 /* superblock checksum */
#define FS_42INODEFMT -1 /* 4.2BSD inode format */
#define FS_44INODEFMT 2 /* 4.4BSD inode format */
/*
* Preference for optimization.
*/
#define FS_OPTTIME 0 /* minimize allocation time */
#define FS_OPTSPACE 1 /* minimize disk fragmentation */
/*
* Filesystem flags.
*/
#define FS_UNCLEAN 0x01 /* filesystem not clean at mount */
#define FS_DOSOFTDEP 0x02 /* filesystem using soft dependencies */
/*
* Rotational layout table format types
*/
#define FS_42POSTBLFMT -1 /* 4.2BSD rotational table format */
#define FS_DYNAMICPOSTBLFMT 1 /* dynamic rotational table format */
/*
* Macros for access to superblock array structures
*/
#define fs_postbl(fs, cylno) \
(((fs)->fs_postblformat == FS_42POSTBLFMT) \
? ((fs)->fs_opostbl[cylno]) \
: ((int16_t *)((u_int8_t *)(fs) + \
(fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
#define fs_rotbl(fs) \
(((fs)->fs_postblformat == FS_42POSTBLFMT) \
? ((fs)->fs_space) \
: ((u_int8_t *)((u_int8_t *)(fs) + (fs)->fs_rotbloff)))
/*
* The size of a cylinder group is calculated by CGSIZE. The maximum size
* is limited by the fact that cylinder groups are at most one block.
* Its size is derived from the size of the maps maintained in the
* cylinder group and the (struct cg) size.
*/
#define CGSIZE(fs) \
/* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \
/* blktot size */ (fs)->fs_cpg * sizeof(int32_t) + \
/* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(int16_t) + \
/* inode map */ howmany((fs)->fs_ipg, NBBY) + \
/* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY) +\
/* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \
/* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \
/* cluster map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY)))
/*
* Convert cylinder group to base address of its global summary info.
*/
#define fs_cs(fs, indx) fs_csp[indx]
/*
* Cylinder group block for a file system.
*/
#define CG_MAGIC 0x090255
struct cg {
int32_t cg_firstfield; /* historic cyl groups linked list */
int32_t cg_magic; /* magic number */
time_t cg_time; /* time last written */
int32_t cg_cgx; /* we are the cgx'th cylinder group */
int16_t cg_ncyl; /* number of cyl's this cg */
int16_t cg_niblk; /* number of inode blocks this cg */
int32_t cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
int32_t cg_rotor; /* position of last used block */
int32_t cg_frotor; /* position of last used frag */
int32_t cg_irotor; /* position of last used inode */
int32_t cg_frsum[MAXFRAG]; /* counts of available frags */
int32_t cg_btotoff; /* (int32) block totals per cylinder */
int32_t cg_boff; /* (u_int16) free block positions */
int32_t cg_iusedoff; /* (u_int8) used inode map */
int32_t cg_freeoff; /* (u_int8) free block map */
int32_t cg_nextfreeoff; /* (u_int8) next available space */
int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */
int32_t cg_clusteroff; /* (u_int8) free cluster map */
int32_t cg_nclusterblks; /* number of clusters this cg */
int32_t cg_sparecon[13]; /* reserved for future use */
u_int8_t cg_space[1]; /* space for cylinder group maps */
/* actually longer */
};
/*
* Macros for access to cylinder group array structures
*/
#define cg_blktot(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_btot) \
: ((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_btotoff)))
#define cg_blks(fs, cgp, cylno) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_b[cylno]) \
: ((int16_t *)((u_int8_t *)(cgp) + \
(cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
#define cg_inosused(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_iused) \
: ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_iusedoff)))
#define cg_blksfree(cgp) \
(((cgp)->cg_magic != CG_MAGIC) \
? (((struct ocg *)(cgp))->cg_free) \
: ((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_freeoff)))
#define cg_chkmagic(cgp) \
((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
#define cg_clustersfree(cgp) \
((u_int8_t *)((u_int8_t *)(cgp) + (cgp)->cg_clusteroff))
#define cg_clustersum(cgp) \
((int32_t *)((u_int8_t *)(cgp) + (cgp)->cg_clustersumoff))
/*
* The following structure is defined
* for compatibility with old file systems.
*/
struct ocg {
int32_t cg_firstfield; /* historic linked list of cyl groups */
int32_t cg_unused_1; /* used for incore cyl groups */
time_t cg_time; /* time last written */
int32_t cg_cgx; /* we are the cgx'th cylinder group */
int16_t cg_ncyl; /* number of cyl's this cg */
int16_t cg_niblk; /* number of inode blocks this cg */
int32_t cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
int32_t cg_rotor; /* position of last used block */
int32_t cg_frotor; /* position of last used frag */
int32_t cg_irotor; /* position of last used inode */
int32_t cg_frsum[8]; /* counts of available frags */
int32_t cg_btot[32]; /* block totals per cylinder */
int16_t cg_b[32][8]; /* positions of free blocks */
u_int8_t cg_iused[256]; /* used inode map */
int32_t cg_magic; /* magic number */
u_int8_t cg_free[1]; /* free block map */
/* actually longer */
};
/*
* Turn file system block numbers into disk block addresses.
* This maps file system blocks to device size blocks.
*/
#define fsbtodb(fs, b) ((b) << (fs)->fs_fsbtodb)
#define dbtofsb(fs, b) ((b) >> (fs)->fs_fsbtodb)
/*
* Cylinder group macros to locate things in cylinder groups.
* They calc file system addresses of cylinder group data structures.
*/
#define cgbase(fs, c) ((ufs_daddr_t)((fs)->fs_fpg * (c)))
#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
#define cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno) /* super blk */
#define cgtod(fs, c) (cgstart(fs, c) + (fs)->fs_cblkno) /* cg block */
#define cgstart(fs, c) \
(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
/*
* Macros for handling inode numbers:
* inode number to file system block offset.
* inode number to cylinder group number.
* inode number to file system block address.
*/
#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg)
#define ino_to_fsba(fs, x) \
((ufs_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \
(blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
#define ino_to_fsbo(fs, x) ((x) % INOPB(fs))
/*
* Give cylinder group number for a file system block.
* Give cylinder group block number for a file system block.
*/
#define dtog(fs, d) ((d) / (fs)->fs_fpg)
#define dtogd(fs, d) ((d) % (fs)->fs_fpg)
/*
* Extract the bits for a block from a map.
* Compute the cylinder and rotational position of a cyl block addr.
*/
#define blkmap(fs, map, loc) \
(((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
#define cbtocylno(fs, bno) \
((bno) * NSPF(fs) / (fs)->fs_spc)
#define cbtorpos(fs, bno) \
(((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
(bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
(fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
/*
* The following macros optimize certain frequently calculated
* quantities by using shifts and masks in place of divisions
* modulos and multiplications.
*/
#define blkoff(fs, loc) /* calculates (loc % fs->fs_bsize) */ \
((loc) & (fs)->fs_qbmask)
#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
((loc) & (fs)->fs_qfmask)
#define lblktosize(fs, blk) /* calculates ((off_t)blk * fs->fs_bsize) */ \
((off_t)(blk) << (fs)->fs_bshift)
/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
#define smalllblktosize(fs, blk) /* calculates (blk * fs->fs_bsize) */ \
((blk) << (fs)->fs_bshift)
#define lblkno(fs, loc) /* calculates (loc / fs->fs_bsize) */ \
((loc) >> (fs)->fs_bshift)
#define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \
((loc) >> (fs)->fs_fshift)
#define blkroundup(fs, size) /* calculates roundup(size, fs->fs_bsize) */ \
(((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
#define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
((frags) >> (fs)->fs_fragshift)
#define blkstofrags(fs, blks) /* calculates (blks * fs->fs_frag) */ \
((blks) << (fs)->fs_fragshift)
#define fragnum(fs, fsb) /* calculates (fsb % fs->fs_frag) */ \
((fsb) & ((fs)->fs_frag - 1))
#define blknum(fs, fsb) /* calculates rounddown(fsb, fs->fs_frag) */ \
((fsb) &~ ((fs)->fs_frag - 1))
/*
* Determine the number of available frags given a
* percentage to hold in reserve.
*/
#define freespace(fs, percentreserved) \
(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
(fs)->fs_cstotal.cs_nffree - \
((off_t)((fs)->fs_dsize) * (percentreserved) / 100))
/*
* Determining the size of a file block in the file system.
*/
#define blksize(fs, ip, lbn) \
(((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (ip)->i_size))))
#define dblksize(fs, dip, lbn) \
(((lbn) >= NDADDR || (dip)->di_size >= smalllblktosize(fs, (lbn) + 1)) \
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (dip)->di_size))))
#define sblksize(fs, size, lbn) \
(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
? (fs)->fs_bsize \
: (fragroundup(fs, blkoff(fs, (size)))))
/*
* Number of disk sectors per block/fragment; assumes DEV_BSIZE byte
* sector size.
*/
#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift)
#define NSPF(fs) ((fs)->fs_nspf)
/*
* Number of inodes in a secondary storage block/fragment.
*/
#define INOPB(fs) ((fs)->fs_inopb)
#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
/*
* Number of indirects in a file system block.
*/
#define NINDIR(fs) ((fs)->fs_nindir)
extern int inside[], around[];
extern u_char *fragtbl[];
#endif

View File

@ -1,161 +0,0 @@
/*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* 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.
* 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.
*
* @(#)inode.h 8.9 (Berkeley) 5/14/95
* %FreeBSD: src/sys/ufs/ufs/inode.h,v 1.28.2.2 2001/09/29 12:52:52 iedowse Exp %
* $FreeBSD$
*/
#ifndef _UFS_UFS_INODE_H_
#define _UFS_UFS_INODE_H_
#include <sys/lock.h>
#include <sys/lockmgr.h>
#include <sys/queue.h>
#include "dinode.h"
/*
* The size of a logical block number.
*/
typedef long ufs_lbn_t;
/*
* This must agree with the definition in <ufs/ufs/dir.h>.
*/
#define doff_t int32_t
/*
* The inode is used to describe each active (or recently active) file in the
* UFS filesystem. It is composed of two types of information. The first part
* is the information that is needed only while the file is active (such as
* the identity of the file and linkage to speed its lookup). The second part
* is the permanent meta-data associated with the file which is read in
* from the permanent dinode from long term storage when the file becomes
* active, and is put back when the file is no longer being used.
*/
struct inode {
struct lock i_lock; /* Inode lock. >Keep this first< */
LIST_ENTRY(inode) i_hash;/* Hash chain. */
struct vnode *i_vnode;/* Vnode associated with this inode. */
struct vnode *i_devvp;/* Vnode for block I/O. */
u_int32_t i_flag; /* flags, see below */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
int i_effnlink; /* i_nlink when I/O completes */
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
struct ext2_sb_info *e2fs; /* EXT2FS */
} inode_u;
#define i_fs inode_u.fs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
struct lockf *i_lockf;/* Head of byte-level lock list. */
/*
* Side effects; used during directory lookup.
*/
int32_t i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* Inode number of found directory. */
u_int32_t i_reclen; /* Size of found directory entry. */
u_int32_t i_spare[3]; /* XXX actually non-spare (for ext2fs). */
struct dirhash *i_dirhash; /* Hashing for large directories */
/*
* The on-disk dinode itself.
*/
struct dinode i_din; /* 128 bytes of the on-disk dinode. */
};
#define i_atime i_din.di_atime
#define i_atimensec i_din.di_atimensec
#define i_blocks i_din.di_blocks
#define i_ctime i_din.di_ctime
#define i_ctimensec i_din.di_ctimensec
#define i_db i_din.di_db
#define i_flags i_din.di_flags
#define i_gen i_din.di_gen
#define i_gid i_din.di_gid
#define i_ib i_din.di_ib
#define i_mode i_din.di_mode
#define i_mtime i_din.di_mtime
#define i_mtimensec i_din.di_mtimensec
#define i_nlink i_din.di_nlink
#define i_rdev i_din.di_rdev
#define i_shortlink i_din.di_shortlink
#define i_size i_din.di_size
#define i_uid i_din.di_uid
/* These flags are kept in i_flag. */
#define IN_ACCESS 0x0001 /* Access time update request. */
#define IN_CHANGE 0x0002 /* Inode change time update request. */
#define IN_UPDATE 0x0004 /* Modification time update request. */
#define IN_MODIFIED 0x0008 /* Inode has been modified. */
#define IN_RENAME 0x0010 /* Inode is being renamed. */
#define IN_SHLOCK 0x0020 /* File has shared lock. */
#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
#define IN_HASHED 0x0080 /* Inode is on hash list */
#define IN_LAZYMOD 0x0100 /* Modified, but don't write yet. */
#ifdef _KERNEL
/*
* Structure used to pass around logical block paths generated by
* ufs_getlbns and used by truncate and bmap code.
*/
struct indir {
ufs_daddr_t in_lbn; /* Logical block number. */
int in_off; /* Offset in buffer. */
int in_exists; /* Flag if the block exists. */
};
/* Convert between inode pointers and vnode pointers. */
#define VTOI(vp) ((struct inode *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
/* Determine if soft dependencies are being done */
#define DOINGSOFTDEP(vp) ((vp)->v_mount->mnt_flag & MNT_SOFTDEP)
#define DOINGASYNC(vp) ((vp)->v_mount->mnt_kern_flag & MNTK_ASYNC)
/* This overlays the fid structure (see mount.h). */
struct ufid {
u_int16_t ufid_len; /* Length of structure. */
u_int16_t ufid_pad; /* Force 32-bit alignment. */
ino_t ufid_ino; /* File number (ino). */
int32_t ufid_gen; /* Generation number. */
};
#endif /* _KERNEL */
#endif /* !_UFS_UFS_INODE_H_ */

View File

@ -1,380 +0,0 @@
/*
* 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
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "boot.h"
#include <machine/cpufunc.h>
#include <sys/reboot.h>
#include <pc98/pc98/pc98_machdep.h>
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 = (void *)&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 address to the ISA bus as they know it
* is not a valid ISA bus address, those machines execute this inb in
* 60 nS :-(.
*
* XXX this should be converted to use bios_tick.
*/
void
delay1ms(void)
{
int i = 800;
while (--i >= 0)
(void)outb(0x5f,0); /* about 600ns */
}
static 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 unsigned
pword(unsigned physaddr)
{
static int counter = 0;
int i;
for (i = 0; i < 512; i++)
(void)outb(0x5f, 0);
return (counter++);
}
int
gets(char *buf)
{
#define bios_tick pword(0x46c)
#define BIOS_TICK_MS 1
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;
}
void
memcpy(const void *from, void *to, size_t len)
{
const char *fp = (const 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++) {
memcpy((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);
}
#ifdef SET_MACHINE_TYPE
void machine_check(void)
{
int ret;
int i;
int data = 0;
/* 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;
(*(unsigned long *)V(0xA1620)) = ret;
}
#endif

View File

@ -1,42 +0,0 @@
/*
* 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 <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#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

@ -1,201 +0,0 @@
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Robert Elz at The University of Melbourne.
*
* 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.
* 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.
*
* @(#)quota.h 8.3 (Berkeley) 8/19/94
* %FreeBSD: src/sys/ufs/ufs/quota.h,v 1.15 1999/12/29 04:55:05 peter Exp %
* $FreeBSD$
*/
#ifndef _UFS_UFS_QUOTA_H_
#define _UFS_UFS_QUOTA_H_
/*
* Definitions for disk quotas imposed on the average user
* (big brother finally hits UNIX).
*
* The following constants define the amount of time given a user before the
* soft limits are treated as hard limits (usually resulting in an allocation
* failure). The timer is started when the user crosses their soft limit, it
* is reset when they go below their soft limit.
*/
#define MAX_IQ_TIME (7*24*60*60) /* seconds in 1 week */
#define MAX_DQ_TIME (7*24*60*60) /* seconds in 1 week */
/*
* The following constants define the usage of the quota file array in the
* ufsmount structure and dquot array in the inode structure. The semantics
* of the elements of these arrays are defined in the routine getinoquota;
* the remainder of the quota code treats them generically and need not be
* inspected when changing the size of the array.
*/
#define MAXQUOTAS 2
#define USRQUOTA 0 /* element used for user quotas */
#define GRPQUOTA 1 /* element used for group quotas */
/*
* Definitions for the default names of the quotas files.
*/
#define INITQFNAMES { \
"user", /* USRQUOTA */ \
"group", /* GRPQUOTA */ \
"undefined", \
}
#define QUOTAFILENAME "quota"
#define QUOTAGROUP "operator"
/*
* Command definitions for the 'quotactl' system call. The commands are
* broken into a main command defined below and a subcommand that is used
* to convey the type of quota that is being manipulated (see above).
*/
#define SUBCMDMASK 0x00ff
#define SUBCMDSHIFT 8
#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
#define Q_QUOTAON 0x0100 /* enable quotas */
#define Q_QUOTAOFF 0x0200 /* disable quotas */
#define Q_GETQUOTA 0x0300 /* get limits and usage */
#define Q_SETQUOTA 0x0400 /* set limits and usage */
#define Q_SETUSE 0x0500 /* set usage */
#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
/*
* The following structure defines the format of the disk quota file
* (as it appears on disk) - the file is an array of these structures
* indexed by user or group number. The setquota system call establishes
* the vnode for each quota file (a pointer is retained in the ufsmount
* structure).
*/
struct dqblk {
u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */
u_int32_t dqb_curblocks; /* current block count */
u_int32_t dqb_ihardlimit; /* maximum # allocated inodes + 1 */
u_int32_t dqb_isoftlimit; /* preferred inode limit */
u_int32_t dqb_curinodes; /* current # allocated inodes */
time_t dqb_btime; /* time limit for excessive disk use */
time_t dqb_itime; /* time limit for excessive files */
};
#ifdef _KERNEL
#include <sys/queue.h>
/*
* The following structure records disk usage for a user or group on a
* filesystem. There is one allocated for each quota that exists on any
* filesystem for the current user or group. A cache is kept of recently
* used entries.
*/
struct dquot {
LIST_ENTRY(dquot) dq_hash; /* hash list */
TAILQ_ENTRY(dquot) dq_freelist; /* free list */
u_int16_t dq_flags; /* flags, see below */
u_int16_t dq_cnt; /* count of active references */
u_int16_t dq_spare; /* unused spare padding */
u_int16_t dq_type; /* quota type of this dquot */
u_int32_t dq_id; /* identifier this applies to */
struct ufsmount *dq_ump; /* filesystem that this is taken from */
struct dqblk dq_dqb; /* actual usage & quotas */
};
/*
* Flag values.
*/
#define DQ_LOCK 0x01 /* this quota locked (no MODS) */
#define DQ_WANT 0x02 /* wakeup on unlock */
#define DQ_MOD 0x04 /* this quota modified since read */
#define DQ_FAKE 0x08 /* no limits here, just usage */
#define DQ_BLKS 0x10 /* has been warned about blk limit */
#define DQ_INODS 0x20 /* has been warned about inode limit */
/*
* Shorthand notation.
*/
#define dq_bhardlimit dq_dqb.dqb_bhardlimit
#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
#define dq_curblocks dq_dqb.dqb_curblocks
#define dq_ihardlimit dq_dqb.dqb_ihardlimit
#define dq_isoftlimit dq_dqb.dqb_isoftlimit
#define dq_curinodes dq_dqb.dqb_curinodes
#define dq_btime dq_dqb.dqb_btime
#define dq_itime dq_dqb.dqb_itime
/*
* If the system has never checked for a quota for this file, then it is
* set to NODQUOT. Once a write attempt is made the inode pointer is set
* to reference a dquot structure.
*/
#define NODQUOT NULL
/*
* Flags to chkdq() and chkiq()
*/
#define FORCE 0x01 /* force usage changes independent of limits */
#define CHOWN 0x02 /* (advisory) change initiated by chown */
/*
* Macros to avoid subroutine calls to trivial functions.
*/
#ifdef DIAGNOSTIC
#define DQREF(dq) dqref(dq)
#else
#define DQREF(dq) (dq)->dq_cnt++
#endif
struct inode;
struct mount;
struct proc;
struct ucred;
struct vnode;
int chkdq __P((struct inode *, long, struct ucred *, int));
int chkiq __P((struct inode *, long, struct ucred *, int));
void dqinit __P((void));
void dqrele __P((struct vnode *, struct dquot *));
int getinoquota __P((struct inode *));
int getquota __P((struct mount *, u_long, int, caddr_t));
int qsync __P((struct mount *mp));
int quotaoff __P((struct proc *, struct mount *, int));
int quotaon __P((struct proc *, struct mount *, int, caddr_t));
int setquota __P((struct mount *, u_long, int, caddr_t));
int setuse __P((struct mount *, u_long, int, caddr_t));
int ufs_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
#else /* !_KERNEL */
#include <sys/cdefs.h>
__BEGIN_DECLS
int quotactl __P((const char *, int, int, void *));
__END_DECLS
#endif /* _KERNEL */
#endif /* !_UFS_UFS_QUOTA_H_ */

View File

@ -1,57 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $FreeBSD$
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if COMCONSOLE == 0x238
#include "serial_16550.S"
#else
#include "serial_8251.S"
#endif

View File

@ -1,180 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $FreeBSD$
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* 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.
*/
.file "serial.S"
#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 and speed for the i/o port are passed from the
* Makefile in the COMCONSOLE and COMSPEED preprocessor macros. The
* line control parameters are currently hard-coded to 8 bits, no
* parity, 1 stop bit (8N1). This can be changed in init_serial().
*/
/*
* void serial_putc(int ch);
* Write character `ch' to port COMCONSOLE.
*/
ENTRY(serial_putc)
movl $10000, %ecx # timeout
movl $COMCONSOLE + 5, %edx # line status reg
1:
decl %ecx
je 2f
inb %dx, %al
testb $0x20, %al
je 1b # TX buffer not empty
movb 4(%esp), %al
subl $5, %edx # TX output reg
outb %al, %dx # send this one
2:
ret
/*
* int serial_getc(void);
* Read a character from port COMCONSOLE.
*/
ENTRY(serial_getc)
mov $COMCONSOLE + 5, %edx # line status reg
1:
inb %dx, %al
testb $0x01, %al
je 1b # no rx char available
xorl %eax, %eax
subl $5, %edx # rx buffer reg
inb %dx, %al # fetch (first) character
andb $0x7F, %al # remove any parity bits we get
cmpb $0x7F, %al # make DEL...
jne 2f
movb $0x08, %al # look like BS
2:
ret
/*
* int serial_ischar(void);
* If there is a character in the input buffer of port COMCONSOLE,
* return nonzero; otherwise return 0.
*/
ENTRY(serial_ischar)
xorl %eax, %eax
movl $COMCONSOLE + 5, %edx # line status reg
inb %dx, %al
andb $0x01, %al # rx char available?
ret
/*
* void init_serial(void);
* Initialize port COMCONSOLE to speed COMSPEED, line settings 8N1.
*/
ENTRY(init_serial)
movl $COMCONSOLE + 3, %edx # line control reg
movb $0x80, %al
outb %al, %dx # enable DLAB
subl $3, %edx # divisor latch, low byte
movb (1843200 / (16*(COMSPEED))) & 0xff, %al
outb %al, %dx
incl %edx # divisor latch, high byte
movb (1843200 / (16*(COMSPEED))) >> 8, %al
outb %al, %dx
incl %edx # fifo control register (if any)
xorl %eax,%eax
outb %al, %dx # disable fifo to reduce worst-case busy-wait
incl %edx # line control reg
movb $0x03, %al
outb %al, %dx # 8N1
incl %edx # modem control reg
outb %al, %dx # enable DTR/RTS
/* Flush the input buffer. */
incl %edx # line status reg
1:
subl $5, %edx # rx buffer reg
inb %dx, %al # throw away (unconditionally the first time)
addl $5, %edx # line status reg
inb %dx, %al
testb $0x01, %al
jne 1b # more
ret

View File

@ -1,198 +0,0 @@
/*
* Mach Operating System
* Copyright (c) 1992, 1991 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
* $FreeBSD$
*/
/*
Copyright 1988, 1989, 1990, 1991, 1992
by Intel Corporation, Santa Clara, California.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appears in all
copies and that both the copyright notice and this permission notice
appear in supporting documentation, and that the name of Intel
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* 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.
*/
/*
* modified for PC-98 by KATO T. of Nagoya University
*/
.file "serial.S"
#include <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

View File

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

View File

@ -1,281 +0,0 @@
/*
* 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
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Ported to PC-9801 by Yoshio Kimura
*/
#include "boot.h"
#include <ufs/ufs/dir.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;
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;
}
}
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);
memcpy(iobuf+off, buffer, size);
}
buffer += size;
count -= size;
poff += size;
}
}
static int
find(char *path)
{
char *rest, ch;
int block, off, loc, ino = ROOTINO;
struct direct *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);
memcpy((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 direct *)(iobuf + off);
loc += dp->d_reclen;
if (dp->d_ino && list_only)
printf("%s ", dp->d_name);
} while (!dp->d_ino || strcmp(path, dp->d_name));
ino = dp->d_ino;
*(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') {
biosdrive = dosdev & 0x0f;
#if defined(BOOT_HD_BIAS) && (BOOT_HD_BIAS > 0)
/* XXX */
if (maj == 4)
biosdrive += BOOT_HD_BIAS;
#endif
}
switch(maj)
{
case 4: /* da */
dosdev_copy = biosdrive | 0xA0; /* SCSI HD or MO */
break;
case 0: /* wd */
case 2: /* 1200KB fd */
dosdev_copy = (maj << 3) | unit | 0x80;
break;
case 6: /* 1440KB fd */
dosdev_copy = (maj << 3) | unit;
break;
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;
/***********************************************\
* 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;
return 0;
}

View File

@ -1,146 +0,0 @@
/*
* 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
*/
/*
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/cdefs.h>
__FBSDID("$FreeBSD$");
#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 */
/*
* 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 */
{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", "dk", "fd", 0 };
unsigned tw_chars = 0x5C2D2F7C; /* "\-/|" */