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:
parent
0a4c3bb56f
commit
1aa8466f89
@ -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>
|
||||
|
@ -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
|
@ -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)
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
395
sys/boot/pc98/boot2/boot1.S
Normal 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
|
@ -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
842
sys/boot/pc98/boot2/boot2.c
Normal 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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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_ */
|
@ -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
|
@ -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 */
|
||||
}
|
||||
|
@ -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_ */
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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; /* "\-/|" */
|
Loading…
Reference in New Issue
Block a user