*BSD News Article 5516


Return to BSD News archive

Path: sserve!manuel!munnari.oz.au!uunet!portal!lll-winken!sun-barr!ames!agate!tfs.com!tfs.com!julian
From: julian@tfs.com (Julian Elischer)
Newsgroups: comp.unix.bsd
Subject: new boot blocks: beta release part 1 of 2
Message-ID: <1992Sep23.223243.18085@tfs.com>
Date: 23 Sep 92 22:32:43 GMT
Organization: TRW Financial Systems
Lines: 1364

These boot blocks use the BIOS to do all functions.
The allow the user to select the device, partition and filename
of the kernel to boot.
Since the alpha release, bad block handling has been added so that
a kernel lying on remapped blocks can be loaded.
Also some major bugs have been removed Thanks to readers.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	i386/boot
#	i386/boot/asm.h
#	i386/boot/table.c
#	i386/boot/sys.c
#	i386/boot/start.s
#	i386/boot/rmaouthdr
#	i386/boot/io.c
#	i386/boot/disk.c
#	i386/include/pio.h
#
echo c - i386/boot
mkdir i386/boot > /dev/null 2>&1
echo x - i386/boot/asm.h
sed 's/^X//' >i386/boot/asm.h << 'END-of-i386/boot/asm.h'
X/* 
X * Ported to Boot 386BSD by Julian Elsicher (julian@tfs.com) Sept. 1992
X *
X * Mach Operating System
X * Copyright (c) 1991,1990,1989 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X/* 
X * HISTORY
X * $Log:	asm.h,v $
X * Revision 2.7  92/02/29  15:33:41  rpd
X * 	Added ENTRY2.
X * 	[92/02/28            rpd]
X * 
X * Revision 2.6  92/02/19  15:07:52  elf
X * 	Changed #if __STDC__ to #ifdef __STDC__
X * 	[92/01/16            jvh]
X * 
X * Revision 2.5  91/05/14  16:02:45  mrt
X * 	Correcting copyright
X * 
X * Revision 2.4  91/02/05  17:10:42  mrt
X * 	Changed to new Mach copyright
X * 	[91/02/01  17:30:29  mrt]
X * 
X * Revision 2.3  90/12/20  16:35:27  jeffreyh
X * 	changes for __STDC__
X * 	[90/12/06            jeffreyh]
X * 
X * Revision 2.2  90/05/03  15:24:12  dbg
X * 	First checkin.
X * 
X *
X * 	Typo on ENTRY if gprof
X * 	[90/03/29            rvb]
X * 
X * 	fix SVC for "ifdef wheeze" [kupfer]
X * 	Fix the GPROF definitions.
X * 	ENTRY(x) gets profiled iffdef GPROF.
X * 	Entry(x) (and DATA(x)) is NEVER profiled.
X * 	MCOUNT can be used by asm that intends to build a frame,
X * 	after the frame is built.
X *	[90/02/26            rvb]
X *
X * 	Add #define addr16 .byte 0x67
X * 	[90/02/09            rvb]
X * 	Added LBi, SVC and ENTRY
X * 	[89/11/10  09:51:33  rvb]
X * 
X * 	New a.out and coff compatible .s files.
X * 	[89/10/16            rvb]
X */
X
X
X#define S_ARG0	 4(%esp)
X#define S_ARG1	 8(%esp)
X#define S_ARG2	12(%esp)
X#define S_ARG3	16(%esp)
X
X#define FRAME	pushl %ebp; movl %esp, %ebp
X#define EMARF	leave
X
X#define B_ARG0	 8(%ebp)
X#define B_ARG1	12(%ebp)
X#define B_ARG2	16(%ebp)
X#define B_ARG3	20(%ebp)
X
X#ifdef	wheeze
X
X#define ALIGN 4
X#define EXT(x) x
X#define LEXT(x) x:
X#define LCL(x) ./**/x
X
X#define LB(x,n) ./**/x
X#define LBb(x,n) ./**/x
X#define LBf(x,n) ./**/x
X
X#define	SVC lcall $7,$0
X
X#define String .string
X#define Value  .value
X#define Times(a,b) [a\*b]
X#define Divide(a,b) [a\\b]
X
X#define INB	inb	(%dx)
X#define OUTB	outb	(%dx)
X#define INL	inl	(%dx)
X#define OUTL	outl	(%dx)
X
X#else	wheeze
X#define ALIGN 
X#define	LCL(x)	x
X
X#define LB(x,n) n
X#ifdef	__STDC__
X#define EXT(x) _ ## x
X#define LEXT(x) _ ## x ## :
X
X#define LBb(x,n) n ## b
X#define LBf(x,n) n ## f
X#else __STDC__
X#define EXT(x) _/**/x
X#define LEXT(x) _/**/x/**/:
X#define LBb(x,n) n/**/b
X#define LBf(x,n) n/**/f
X#endif __STDC__
X#define SVC .byte 0x9a; .long 0; .word 0x7
X
X#define String	.ascii
X#define Value	.word
X#define Times(a,b) (a*b)
X#define Divide(a,b) (a/b)
X
X#define INB	inb	%dx, %al
X#define OUTB	outb	%al, %dx
X#define INL	inl	%dx, %eax
X#define OUTL	outl	%eax, %dx
X
X#endif	wheeze
X
X#define data32	.byte 0x66
X#define data16	.byte 0x66
X#define addr16	.byte 0x67
X
X
X
X#ifdef GPROF
X#ifdef	__STDC__
X
X#define MCOUNT		.data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount
X#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x) ; \
X			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
X#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
X			.align ALIGN; LEXT(x) LEXT(y) ; \
X			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
X#define	ASENTRY(x) 	.globl x; .align ALIGN; x ## : ; \
X  			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
X
X#else   __STDC__
X
X#define MCOUNT		.data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
X#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x) ; \
X			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
X#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
X			.align ALIGN; LEXT(x) LEXT(y)
X#define	ASENTRY(x) 	.globl x; .align ALIGN; x: ; \
X  			pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
X
X#endif	__STDC__
X#else	GPROF
X#ifdef	__STDC__
X
X#define MCOUNT
X#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x)
X#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
X			.align ALIGN; LEXT(x) LEXT(y)
X#define	ASENTRY(x)	.globl x; .align ALIGN; x ## :
X
X#else 	__STDC__
X
X#define MCOUNT
X#define	ENTRY(x)	.globl EXT(x); .align ALIGN; LEXT(x)
X#define	ENTRY2(x,y)	.globl EXT(x); .globl EXT(y); \
X			.align ALIGN; LEXT(x) LEXT(y)
X#define	ASENTRY(x)	.globl x; .align ALIGN; x:
X
X#endif	__STDC__
X#endif	GPROF
X
X#define	Entry(x)	.globl EXT(x); .align ALIGN; LEXT(x)
X#define	DATA(x)		.globl EXT(x); .align ALIGN; LEXT(x)
END-of-i386/boot/asm.h
echo x - i386/boot/table.c
sed 's/^X//' >i386/boot/table.c << 'END-of-i386/boot/table.c'
X/*
X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X *
X * Mach Operating System
X * Copyright (c) 1992, 1991 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X/*
X * HISTORY
X * $Log:	table.c,v $
X * Revision 2.2  92/04/04  11:36:43  rpd
X * 	Fix Intel Copyright as per B. Davies authorization.
X * 	[92/04/03            rvb]
X * 	Taken from 2.5 bootstrap.
X * 	[92/03/30            rvb]
X * 
X * Revision 2.2  91/04/02  14:42:22  mbj
X * 	Add Intel copyright
X * 	[90/02/09            rvb]
X * 
X */
X
X/*
X  Copyright 1988, 1989, 1990, 1991, 1992 
X   by Intel Corporation, Santa Clara, California.
X
X                All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and
Xits documentation for any purpose and without fee is hereby
Xgranted, provided that the above copyright notice appears in all
Xcopies and that both the copyright notice and this permission notice
Xappear in supporting documentation, and that the name of Intel
Xnot be used in advertising or publicity pertaining to distribution
Xof the software without specific, written prior permission.
X
XINTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
XIN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
XLOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
XNEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
XWITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X*/
X
X#define NGDTENT		6
X#define GDTLIMIT	48	/* NGDTENT * 8 */
X
X/*  Segment Descriptor
X *
X * 31          24         19   16                 7           0
X * ------------------------------------------------------------
X * |             | |B| |A|       | |   |1|0|E|W|A|            |
X * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
X * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
X * ------------------------------------------------------------
X * |                             |                            |
X * |        BASE 15..0           |       LIMIT 15..0          |
X * |                             |                            |
X * ------------------------------------------------------------
X */
X
Xstruct seg_desc {
X	unsigned short	limit_15_0;
X	unsigned short	base_15_0;
X	unsigned char	base_23_16;
X	unsigned char	bit_15_8;
X	unsigned char	bit_23_16;
X	unsigned char	base_31_24;
X	};
X
X
Xstruct seg_desc	Gdt[NGDTENT] = {
X	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* 0x0 : null */
X	{0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0},	/* 0x08 : kernel code */
X	{0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0},	/* 0x10 : kernel data */
X	{0xFFFF, 0x0000, 0x9, 0x9E, 0x40, 0x0},	/* 0x18 : boot code */
X	{0xFFFF, 0x0000, 0x9, 0x92, 0x40, 0x0},	/* 0x20 : boot data */
X	{0xFFFF, 0x0000, 0x9, 0x9E, 0x0, 0x0}	/* 0x28 : boot code, 16 bits */
X	};
X
X
Xstruct pseudo_desc {
X	unsigned short	limit;
X	unsigned short	base_low;
X	unsigned short	base_high;
X	};
X
Xstruct pseudo_desc Gdtr = { GDTLIMIT, 0x0400, 9 };
Xstruct pseudo_desc Gdtr2 = { GDTLIMIT, 0xfe00, 9 };
X			/* boot is loaded at 0x90000, Gdt is at boot+1024 */
END-of-i386/boot/table.c
echo x - i386/boot/sys.c
sed 's/^X//' >i386/boot/sys.c << 'END-of-i386/boot/sys.c'
X/*
X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X *
X * Mach Operating System
X * Copyright (c) 1992, 1991 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X/*
X * HISTORY
X * $Log:	sys.c,v $
X * Revision 2.2  92/04/04  11:36:34  rpd
X * 	Fabricated from 3.0 bootstrap and scratch.
X * 	[92/03/30            mg32]
X * 
X */
X
X#include "boot.h"
X#include <sys/dir.h>
X#include <sys/reboot.h>
X
X/* #define BUFSIZE 4096 */
X#define BUFSIZE MAXBSIZE
X
Xchar buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
X
Xint xread(addr, size)
X	char		* addr;
X	int		size;
X{
X	int count = BUFSIZE;
X	while (size > 0) {
X		if (BUFSIZE > size)
X			count = size;
X		read(buf, count);
X		pcpy(buf, addr, count);
X		size -= count;
X		addr += count;
X	}
X}
X
Xread(buffer, count)
X	int count;
X	char *buffer;
X{
X	int logno, off, size;
X	int cnt2, bnum2;
X
X	while (count) {
X		off = blkoff(fs, poff);
X		logno = lblkno(fs, poff);
X		cnt2 = size = blksize(fs, &inode, logno);
X		bnum2 = fsbtodb(fs, block_map(logno)) + boff;
X		cnt = cnt2;
X		bnum = bnum2;
X		if (	(!off)  && (size <= count))
X		{
X			iodest = buffer;
X			devread();
X		}
X		else
X		{
X			iodest = iobuf;
X			size -= off;
X			if (size > count)
X				size = count;
X			devread();
X			bcopy(iodest+off,buffer,size);
X		}
X		buffer += size;
X		count -= size;
X		poff += size;
X	}
X}
X
Xfind(path)
X     char *path;
X{
X	char *rest, ch;
X	int block, off, loc, ino = ROOTINO;
X	struct direct *dp;
Xloop:	iodest = iobuf;
X	cnt = fs->fs_bsize;
X	bnum = fsbtodb(fs,itod(fs,ino)) + boff;
X	devread();
X	bcopy(&((struct dinode *)iodest)[ino % fs->fs_inopb],
X	      &inode.i_din,
X	      sizeof (struct dinode));
X	if (!*path)
X		return 1;
X	while (*path == '/')
X		path++;
X	if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR))
X		return 0;
X	for (rest = path; (ch = *rest) && ch != '/'; rest++) ;
X	*rest = 0;
X	loc = 0;
X	do {
X		if (loc >= inode.i_size)
X			return 0;
X		if (!(off = blkoff(fs, loc))) {
X			block = lblkno(fs, loc);
X			cnt = blksize(fs, &inode, block);
X			bnum = fsbtodb(fs, block_map(block)) + boff;
X			iodest = iobuf;
X			devread();
X		}
X		dp = (struct direct *)(iodest + off);
X		loc += dp->d_reclen;
X	} while (!dp->d_ino || strcmp(path, dp->d_name));
X	ino = dp->d_ino;
X	*(path = rest) = ch;
X	goto loop;
X}
X
Xchar mapbuf[MAXBSIZE];
Xint mapblock = 0;
X
Xblock_map(file_block)
X     int file_block;
X{
X	if (file_block < NDADDR)
X		return(inode.i_db[file_block]);
X	if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
X		iodest = mapbuf;
X		cnt = fs->fs_bsize;
X		devread();
X		mapblock = bnum;
X	}
X	return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
X}
X
Xopenrd()
X{
X	char **devp, *cp = name;
X	/*******************************************************\
X	* If bracket given look for preceding device name	*
X	\*******************************************************/
X	while (*cp && *cp!='(')
X		cp++;
X	if (!*cp)
X	{
X		cp = name;
X	}
X	else
X	{
X		if (cp++ != name)
X		{
X			for (devp = devs; *devp; devp++)
X				if (name[0] == (*devp)[0] &&
X				    name[1] == (*devp)[1])
X					break;
X			if (!*devp)
X			{
X				printf("Unknown device\n");
X				return 1;
X			}
X			maj = devp-devs;
X		}
X		/*******************************************************\
X		* Look inside brackets for unit number, and partition	*
X		\*******************************************************/
X		if (*cp >= '0' && *cp <= '9')
X			if ((unit = *cp++ - '0') > 1)
X			{
X				printf("Bad unit\n");
X				return 1;
X			}
X		if (!*cp || (*cp == ',' && !*++cp))
X			return 1;
X		if (*cp >= 'a' && *cp <= 'p')
X			part = *cp++ - 'a';
X		while (*cp && *cp++!=')') ;
X		if (!*cp)
X			return 1;
X	}
X	switch(maj)
X	{
X	case 1:
X		dosdev = unit | 0x80;
X		unit = 0;
X		break;
X	case 0:
X	case 4:
X		dosdev = unit | 0x80;
X		break;
X	case 2:
X		dosdev = unit;
X		break;
X	case 3:
X		printf("Wangtek unsupported\n");
X		return 1;
X		break;
X	}
X	inode.i_dev = dosdev;
X	/***********************************************\
X	* Now we know the disk unit and part,		*
X	* Load disk info, (open the device)		*
X	\***********************************************/
X	if (devopen())
X		return 1;
X
X	/***********************************************\
X	* Load Filesystem info (mount the device)	*
X	\***********************************************/
X	iodest = (char *)(fs = (struct fs *)fsbuf);
X	cnt = SBSIZE;
X	bnum = SBLOCK + boff;
X	devread();
X	/***********************************************\
X	* Find the actual FILE on the mounted device	*
X	\***********************************************/
X	if (!find(cp))
X	{
X		return 1;
X	}
X	poff = 0;
X	name = cp;
X	return 0;
X}
END-of-i386/boot/sys.c
echo x - i386/boot/start.s
sed 's/^X//' >i386/boot/start.s << 'END-of-i386/boot/start.s'
X/*
X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X *
X * Mach Operating System
X * Copyright (c) 1992, 1991 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X/*
X * HISTORY
X * $Log:	start.s,v $
X * Revision 2.2  92/04/04  11:36:29  rpd
X * 	Fix Intel Copyright as per B. Davies authorization.
X * 	[92/04/03            rvb]
X * 	Need to zero dh on hd path; at least for an adaptec card.
X * 	[92/01/14            rvb]
X * 
X * 	From 2.5 boot:
X * 	Flush digit printing.
X * 	Fuse floppy and hd boot by using Int 21 to tell
X * 	boot type (slightly dubious since Int 21 is DOS
X * 	not BIOS)
X * 	[92/03/30            mg32]
X * 
X * Revision 2.2  91/04/02  14:42:04  mbj
X * 	Fix the BIG boot bug.  We had missed a necessary data
X * 	before a xor that was clearing a register used later
X * 	as an index register.
X * 	[91/03/01            rvb]
X * 	Remember floppy type for swapgeneric
X * 	Add Intel copyright
X * 	[90/02/09            rvb]
X * 
X */
X 
X
X/*
X  Copyright 1988, 1989, 1990, 1991, 1992 
X   by Intel Corporation, Santa Clara, California.
X
X                All Rights Reserved
X
XPermission to use, copy, modify, and distribute this software and
Xits documentation for any purpose and without fee is hereby
Xgranted, provided that the above copyright notice appears in all
Xcopies and that both the copyright notice and this permission notice
Xappear in supporting documentation, and that the name of Intel
Xnot be used in advertising or publicity pertaining to distribution
Xof the software without specific, written prior permission.
X
XINTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
XIN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
XLOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
XNEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
XWITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X*/
X#include	"asm.h"
X
X	.file	"start.s"
X
XBOOTSEG		=	0x9000	# boot will be loaded at 640k-64k
XBOOTSTACK	=	0xfe00	# boot stack
XSIGNATURE	=	0xaa55
XLOADSZ		=	14	# size of unix boot
XPARTSTART	=	0x1be	# starting address of partition table
XNUMPART		=	4	# number of partitions in partition table
XPARTSZ		=	16	# each partition table entry is 16 bytes
XBSDPART		=	0xA5	# value of boot_ind, means bootable partition
XBOOTABLE	=	0x80	# value of boot_ind, means bootable partition
X
X	.text	
X
XENTRY(boot1)
X
X	# boot1 is loaded at 0x0:0x7c00
X	# ljmp to the next instruction to set up %cs
X	data32
X	ljmp $0x7c0, $start
X
Xstart:
X	# set up %ds
X	mov	%cs, %ax
X	mov	%ax, %ds
X
X
X	# set up %ss and %esp
X	data32
X	mov	$BOOTSEG, %eax
X	mov	%ax, %ss
X	data32
X	mov	$BOOTSTACK, %esp
X
X	/*** set up %es, (where we will load boot2 to) ***/
X	mov	%ax, %es
X
X	# get the boot drive id
X	movb	$0x33, %ah
X	movb	$0x05, %al
X	int	$0x21
X
X	cmpb	$0x80, %dl
X	data32
X	je	hd
X
Xfd:
X#	reset the disk system
X	movb	$0x0, %ah
X	int	$0x13
X	data32
X	mov	$0x0001, %ecx	# cyl 0, sector 1
X	data32
X	jmp load
X
Xhd:	/**** load sector 0 into the BOOTSEG ****/
X	data32
X	mov	$0x0201, %eax
X	xor	%ebx, %ebx	# %bx = 0
X	data32
X	mov	$0x0001, %ecx
X	data32
X	mov	$0x0080, %edx
X	int	$0x13
X	data32
X	jb	read_error
X
X	/***# find the bootable partition *****/
X	data32
X	mov	$PARTSTART, %ebx
X	data32
X	mov	$NUMPART, %ecx
Xagain:
X	addr16
X	movb    %es:4(%ebx), %al
X	cmpb	$BSDPART, %al
X	data32
X	je	found
X	data32
X	add	$PARTSZ, %ebx
X	data32
X	loop	again
X	data32
X	mov	$enoboot, %esi
X	data32
X	jmp	err_stop
X
X
X# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
X#       Call with       %ah = 0x2
X#                       %al = number of sectors
X#                       %ch = cylinder
X#                       %cl = sector
X#                       %dh = head
X#                       %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
X#                       %es:%bx = segment:offset of buffer
X#       Return:
X#                       %al = 0x0 on success; err code on failure
X
Xfound:
X	addr16
X	movb	%es:1(%ebx), %dh /* head */
X	addr16
X	movl	%es:2(%ebx), %ecx /*sect,cyl (+ 2 bytes junk in top word )*/
X
Xload:
X	movb	$0x2, %ah	/* function 2 */
X	movb	$LOADSZ, %al	/* number of blocks */
X	xor	%ebx, %ebx	/* %bx = 0, put it at 0 in the BOOTSEG */
X	int	$0x13
X	data32
X	jb	read_error
X
X	# ljmp to the second stage boot loader (boot2).
X	# After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
X	# as an internal buffer "intbuf".
X
X	data32
X	ljmp	$BOOTSEG, $EXT(boot2)
X
X#
X#	read_error
X#
X
Xread_error:
X
X	data32
X	mov	$eread, %esi
Xerr_stop:
X	data32
X	call	message
X	data32
X	jmp	stop
X
X#
X#	message: write the error message in %ds:%esi to console
X#
X
Xmessage:
X	# Use BIOS "int 10H Function 0Eh" to write character in teletype mode
X	#	%ah = 0xe	%al = character
X	#	%bh = page	%bl = foreground color (graphics modes)
X
X	data32
X	push	%eax
X	data32
X	push	%ebx
X	data32
X	mov	$0x0001, %ebx
X	cld
X
Xnextb:
X	lodsb			# load a byte into %al
X	cmpb	$0x0, %al
X	data32
X	je	done
X	movb	$0xe, %ah
X	int	$0x10		# display a byte
X	data32
X	jmp	nextb
Xdone:
X	data32
X	pop	%ebx
X	data32
X	pop	%eax
X	data32
X	ret
X
Xstop:	hlt
X	data32
X	jmp	stop		# halt doesnt actually halt forever
X#
X/* error messages */
X
Xeread:	String		"Read error\r\n\0"
Xenoboot: String		"No bootable partition\r\n\0"
Xendofcode:
X/* throw in a partition in case we are block0 as well */
X/* flag,head,sec,cyl,typ,ehead,esect,ecyl,start,len */
X	. = EXT(boot1) + PARTSTART
X	.byte 0x0,0,0,0,0,0,0,0
X	.long 0,0
X	.byte 0x0,0,0,0,0,0,0,0
X	.long 0,0
X	.byte 0x0,0,0,0,0,0,0,0
X	.long 0,0
X	.byte BOOTABLE,0,1,0,BSDPART,255,255,255
X	.long 0,50000
X/* the last 2 bytes in the sector 0 contain the signature */
X	. = EXT(boot1) + 0x1fe
X	.value	SIGNATURE
XENTRY(disklabel)
X	. = EXT(boot1) + 0x400	
END-of-i386/boot/start.s
echo x - i386/boot/rmaouthdr
sed 's/^X//' >i386/boot/rmaouthdr << 'END-of-i386/boot/rmaouthdr'
X#!/bin/csh -f
X#  Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X# 
X#
X# HISTORY
X# $Log:	rmaouthdr,v $
X# Revision 2.2  92/04/04  11:36:01  rpd
X# 	From 2.5 boot
X# 	[92/03/30            mg32]
X# 
X#
Xdd if=$1 of=$2 ibs=32 skip=1 obs=1024b
END-of-i386/boot/rmaouthdr
chmod a+x i386/boot/rmaouthdr
echo x - i386/boot/io.c
sed 's/^X//' >i386/boot/io.c << 'END-of-i386/boot/io.c'
X/*
X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X *
X * Mach Operating System
X * Copyright (c) 1992, 1991 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X/*
X * HISTORY
X * $Log:	io.c,v $
X * Revision 2.2  92/04/04  11:35:57  rpd
X * 	Fixed for IBM L40's A20 initialization.
X * 	[92/03/30            rvb]
X * 
X * 	Created.
X * 	[92/03/30            mg32]
X * 
X */
X
X#include <i386/include/pio.h>
X
X#define K_RDWR 		0x60		/* keyboard data & cmds (read/write) */
X#define K_STATUS 	0x64		/* keyboard status */
X#define K_CMD	 	0x64		/* keybd ctlr command (write-only) */
X
X#define K_OBUF_FUL 	0x01		/* output buffer full */
X#define K_IBUF_FUL 	0x02		/* input buffer full */
X
X#define KC_CMD_WIN	0xd0		/* read  output port */
X#define KC_CMD_WOUT	0xd1		/* write output port */
X#define KB_A20		0x9f		/* enable A20,
X					   enable output buffer full interrupt
X					   enable data line
X					   disable clock line */
X
X/*
X * Gate A20 for high memory
X */
Xunsigned char	x_20 = KB_A20;
XgateA20()
X{
X#ifdef	IBM_L40
X	outb(0x92, 0x2);
X#else	IBM_L40
X	while (inb(K_STATUS) & K_IBUF_FUL);
X	while (inb(K_STATUS) & K_OBUF_FUL)
X		(void)inb(K_RDWR);
X
X	outb(K_CMD, KC_CMD_WOUT);
X	while (inb(K_STATUS) & K_IBUF_FUL);
X	outb(K_RDWR, x_20);
X	while (inb(K_STATUS) & K_IBUF_FUL);
X#endif	IBM_L40
X}
X
X/* printf - only handles %d as decimal, %c as char, %s as string */
X
Xprintf(format,data)
X     char *format;
X     int data;
X{
X	int *dataptr = &data;
X	char c;
X	while (c = *format++)
X		if (c != '%')
X			putchar(c);
X		else
X			switch (c = *format++) {
X			      case 'd': {
X				      int num = *dataptr++;
X				      char buf[10], *ptr = buf;
X				      if (num<0) {
X					      num = -num;
X					      putchar('-');
X				      }
X				      do
X					      *ptr++ = '0'+num%10;
X				      while (num /= 10);
X				      do
X					      putchar(*--ptr);
X				      while (ptr != buf);
X				      break;
X			      }
X			      case 'x': {
X				      int num = *dataptr++, dig;
X				      char buf[8], *ptr = buf;
X				      do
X					      *ptr++ = (dig=(num&0xf)) > 9?
X							'a' + dig - 10 :
X							'0' + dig;
X				      while (num >>= 4);
X				      do
X					      putchar(*--ptr);
X				      while (ptr != buf);
X				      break;
X			      }
X			      case 'c': putchar((*dataptr++)&0xff); break;
X			      case 's': {
X				      char *ptr = (char *)*dataptr++;
X				      while (c = *ptr++)
X					      putchar(c);
X				      break;
X			      }
X			}
X}
X
Xputchar(c)
X{
X	if (c == '\n')
X		putc('\r');
X	putc(c);
X}
X
Xgetchar()
X{
X	int c;
X
X	if ((c=getc()) == '\r')
X		c = '\n';
X	if (c == '\b') {
X		putchar('\b');
X		putchar(' ');
X	}
X	putchar(c);
X	return(c);
X}
X
Xgets(buf)
Xchar *buf;
X{
X	int	i;
X	char *ptr=buf;
X
X	for (i = 240000; i>0; i--)
X		if (ischar())
X			for (;;)
X				switch(*ptr = getchar() & 0xff) {
X				      case '\n':
X				      case '\r':
X					*ptr = '\0';
X					return 1;
X				      case '\b':
X					if (ptr > buf) ptr--;
X					continue;
X				      default:
X					ptr++;
X				}
X	return 0;
X}
X
Xstrcmp(s1, s2)
Xchar *s1, *s2;
X{
X	while (*s1 == *s2) {
X		if (!*s1++)
X			return 0;
X		s2++;
X	}
X	return 1;
X}
X
Xbcopy(from, to, len)
Xchar *from, *to;
Xint len;
X{
X	while (len-- > 0)
X		*to++ = *from++;
X}
END-of-i386/boot/io.c
echo x - i386/boot/disk.c
sed 's/^X//' >i386/boot/disk.c << 'END-of-i386/boot/disk.c'
X/*
X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
X *
X * Mach Operating System
X * Copyright (c) 1992, 1991 Carnegie Mellon University
X * All Rights Reserved.
X * 
X * Permission to use, copy, modify and distribute this software and its
X * documentation is hereby granted, provided that both the copyright
X * notice and this permission notice appear in all copies of the
X * software, derivative works or modified versions, and any portions
X * thereof, and that both notices appear in supporting documentation.
X * 
X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
X * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
X * 
X * Carnegie Mellon requests users of this software to return to
X * 
X *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
X *  School of Computer Science
X *  Carnegie Mellon University
X *  Pittsburgh PA 15213-3890
X * 
X * any improvements or extensions that they make and grant Carnegie Mellon
X * the rights to redistribute these changes.
X */
X
X/*
X * HISTORY
X * $Log:	disk.c,v $
X * Revision 2.2  92/04/04  11:35:49  rpd
X * 	Fabricated from 3.0 bootstrap and 2.5 boot disk.c:
X * 	with support for scsi
X * 	[92/03/30            mg32]
X * 
X */
X
X/*
X * 9/20/92
X * Peng-Toh Sim.  sim@cory.berkeley.edu
X * Added bad144 support under 386bsd for wd's
X * So, bad block remapping is done when loading the kernel.
X */
X
X#include "boot.h"
X#ifdef DO_BAD144
X#include <sys/dkbad.h>
X#endif DO_BAD144
X#include <sys/disklabel.h>
X
X#define	BIOS_DEV_FLOPPY	0x0
X#define	BIOS_DEV_WIN	0x80
X
X#define BPS		512
X#define	SPT(di)		((di)&0xff)
X#define	HEADS(di)	((((di)>>8)&0xff)+1)
X
Xchar *devs[] = {"wd", "hd", "fd", "wt", "sd", 0};
X
X#ifdef DO_BAD144
Xstruct dkbad dkb;
Xint do_bad144;
Xint bsize;
X#endif DO_BAD144
X
Xint spt, spc;
X
Xchar *iodest;
Xstruct fs *fs;
Xstruct inode inode;
Xint dosdev,  unit, part, maj, boff, poff, bnum, cnt;
X
X/*#define EMBEDDED_DISKLABEL 1*/
Xextern struct disklabel disklabel;
X/*struct	disklabel disklabel;*/
X
Xdevopen()
X{
X	struct dos_partition *dptr;
X	struct disklabel *dl;
X	int dosdev = inode.i_dev;
X	int i, sector, di;
X	
X	di = get_diskinfo(dosdev);
X	spc = (spt = SPT(di)) * HEADS(di);
X	if (dosdev == 2)
X	{
X		boff = 0;
X		part = (spt == 15 ? 3 : 1);
X	}
X	else
X	{
X#ifdef	EMBEDDED_DISKLABEL
X		dl = &disklabel;
X#else	EMBEDDED_DISKLABEL
X		Bread(dosdev, 0);
X		dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF);
X		for (i = 0; i < NDOSPART; i++, dptr++)
X			if (dptr->dp_typ == DOSPTYP_386BSD)
X				break;
X		sector = dptr->dp_start + LABELSECTOR;
X		Bread(dosdev, sector++);
X		dl=((struct disklabel *)0);
X		disklabel = *dl;	/* structure copy (maybe useful later)*/
X#endif	EMBEDDED_DISKLABEL
X		if (dl->d_magic != DISKMAGIC) {
X			printf("bad disklabel");
X			return 1;
X		}
X		if( (maj == 4) || (maj == 0) || (maj == 1))
X		{
X			if (dl->d_type == DTYPE_SCSI)
X			{
X				maj = 4; /* use scsi as boot dev */
X			}
X			else
X			{
X				maj = 0; /* must be ESDI/IDE */
X			}
X		}
X		boff = dl->d_partitions[part].p_offset;
X#ifdef DO_BAD144
X		bsize = dl->d_partitions[part].p_size;
X		do_bad144 = 0;
X		if (dl->d_flags & D_BADSECT) {
X		    /* this disk uses bad144 */
X		    int i;
X		    int dkbbnum;
X		    struct dkbad *dkbptr;
X
X		    /* find the first readable bad144 sector */
X		    /* some of this code is copied from ufs/disk_subr.c */
X		    /* read a bad sector table */
X		    dkbbnum = dl->d_secperunit - dl->d_nsectors;
X		    if (dl->d_secsize > DEV_BSIZE)
X		      dkbbnum *= dl->d_secsize / DEV_BSIZE;
X		    else
X		      dkbbnum /= DEV_BSIZE / dl->d_secsize;
X		    i = 0;
X		    do_bad144 = 0;
X		    do {
X			/* XXX: what if the "DOS sector" < 512 bytes ??? */
X			Bread(dosdev, dkbbnum + i);
X			dkbptr = (struct dkbad *) 0;
X/* XXX why is this not in <sys/dkbad.h> ??? */
X#define DKBAD_MAGIC 0x4321
X			if (dkbptr->bt_mbz == 0 &&
X			        dkbptr->bt_flag == DKBAD_MAGIC) {
X			    dkb = *dkbptr;	/* structure copy */
X			    do_bad144 = 1;
X			    break;
X			}
X			i += 2;
X		    } while (i < 10 && i < dl->d_nsectors);
X		    if (!do_bad144)
X		      printf("Bad badsect table\n");
X		    else
X		      printf("Using bad144 bad sector at %d\n", dkbbnum+i);
X		}
X#endif DO_BAD144
X	}
X	return 0;
X}
X
Xdevread()
X{
X	int offset, sector = bnum;
X	int dosdev = inode.i_dev;
X	for (offset = 0; offset < cnt; offset += BPS)
X	{
X		Bread(dosdev, badsect(dosdev, sector++));
X		bcopy(0, iodest+offset, BPS);
X	}
X}
X
XBread(dosdev,sector)
X     int dosdev,sector;
X{
X	int cyl = sector/spc, head = (sector%spc)/spt, secnum = sector%spt;
X	while (biosread(dosdev, cyl,head,secnum))
X	{
X		printf("Error: C:%d H:%d S:%d\n",cyl,head,secnum);
X	}
X}
X
Xbadsect(dosdev, sector)
X     int dosdev, sector;
X{
X	int i;
X#ifdef DO_BAD144
X	if (do_bad144) {
X	    u_short cyl;
X	    u_short head;
X	    u_short sec;
X	    int newsec;
X	    struct disklabel *dl = &disklabel;
X
X	    /* XXX */
X	    /* from wd.c */
X	    /* bt_cyl = cylinder number in sorted order */
X	    /* bt_trksec is actually (head << 8) + sec */
X
X	    /* only remap sectors in the partition */
X	    if (sector < boff || sector >= boff + bsize) {
X		goto no_remap;
X	    }
X
X	    cyl = sector / dl->d_secpercyl;
X	    head = (sector % dl->d_secpercyl) / dl->d_nsectors;
X	    sec = sector % dl->d_nsectors;
X	    sec = (head<<8) + sec;
X
X	    /* now, look in the table for a possible bad sector */
X	    for (i=0; i<126; i++) {
X		if (dkb.bt_bad[i].bt_cyl == cyl) {
X		    /* found same cylinder */
X		    if (dkb.bt_bad[i].bt_trksec == sec) {
X			/* FOUND! */
X			break;
X		    }
X		} else if (dkb.bt_bad[i].bt_cyl > cyl) {
X		    i = 126;
X		    break;
X		}
X	    }
X	    if (i == 126) {
X		/* didn't find bad sector */
X		goto no_remap;
X	    }
X	    /* otherwise find replacement sector */
X	    newsec = dl->d_secperunit - dl->d_nsectors - i -1;
X	    return newsec;
X	}
X#endif DO_BAD144
X      no_remap:
X	return sector;
X}
END-of-i386/boot/disk.c
echo x - i386/include/pio.h
sed 's/^X//' >i386/include/pio.h << 'END-of-i386/include/pio.h'
X/* 
X * Mach Operating System
X * Copyright (c) 1990 Carnegie-Mellon University
X * All rights reserved.  The CMU software License Agreement specifies
X * the terms and conditions for use and redistribution.
X */
X/* 
X * HISTORY
X * $Log: pio.h,v $
X * Revision 1.1  1992/05/27  00:48:30  balsup
X * machkern/cor merge
X *
X * Revision 1.1  1991/10/10  20:11:39  balsup
X * Initial revision
X *
X * Revision 2.2  91/04/02  11:52:29  mbj
X * 	[90/08/14            mg32]
X * 
X * 	Now we know how types are factor in.
X * 	Cleaned up a bunch: eliminated ({ for output and flushed unused
X * 	output variables.
X * 	[90/08/14            rvb]
X * 
X * 	This is how its done in gcc:
X * 		Created.
X * 	[90/03/26            rvb]
X * 
X */
X
X
X#define inl(y) \
X({ unsigned long _tmp__; \
X	asm volatile("inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \
X	_tmp__; })
X
X#define inw(y) \
X({ unsigned short _tmp__; \
X	asm volatile(".byte 0x66; inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \
X	_tmp__; })
X
X#define inb(y) \
X({ unsigned char _tmp__; \
X	asm volatile("inb %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \
X	_tmp__; })
X
X
X#define outl(x, y) \
X{ asm volatile("outl %0, %1" : : "a" (y) , "d" ((unsigned short)(x))); }
X
X
X#define outw(x, y) \
X{asm volatile(".byte 0x66; outl %0, %1" : : "a" ((unsigned short)(y)) , "d" ((unsigned short)(x))); }
X
X
X#define outb(x, y) \
X{ asm volatile("outb %0, %1" : : "a" ((unsigned char)(y)) , "d" ((unsigned short)(x))); }
END-of-i386/include/pio.h
exit