summaryrefslogtreecommitdiffstats
path: root/sys/i386/boot/dosboot
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-02-15 04:45:50 +0000
committerphk <phk@FreeBSD.org>1995-02-15 04:45:50 +0000
commit36a85bcce01a8be23fccd4205860d103742b6aee (patch)
tree8d35f9cebd3159a98d6a4966367305150718678d /sys/i386/boot/dosboot
parent10626775340c7115d44808f91e05f7fb19e03e01 (diff)
downloadFreeBSD-src-36a85bcce01a8be23fccd4205860d103742b6aee.zip
FreeBSD-src-36a85bcce01a8be23fccd4205860d103742b6aee.tar.gz
This is a MS-DOS program, but is does something useful for us:
It boots FreeBSD from a running MS-DOS system. It's compiled using some MS-DOS tools, but there is a binary hidden in the uuencoded file. (Go ahead, flame me if you can come up with a solution for the problem. Just saying "this is bad" doesn't count!) Rod, you were right: one would have to deal with weird interfaces to the memory managers, and it seems that Christian found them all, and made them work. Thanks Christian! Reviewed by: phk Submitted by: DI. Christian Gusenbauer <cg@fimp01.fim.uni-linz.ac.at> Christians README: ------------------ Hi Everybody! This is version 1.5 of "fbsdboot", a program that allows you to boot a kernel from a MS-DOS partition or a FreeBSD partition. This program runs using DOS. It works with various memory managers (like EMM386, 386MAX) under certain circumstances. First, a FreeBSD kernel is always loaded to memory starting at 0x100000. To assure that loading the kernel *does not* overwrite memory used by memory managers, high memory for the kernel is allocated and after loading the kernel it's moved to 0x100000. Second, there are many ways to switch to protected mode which is necessary to start the kernel. Each BIOS gives you the possibility to use INT15H (AH=89H) to do that. But some memory-managers like 386max does not allow you to use this method. An other way to do the switch is to use DPMI services, but they do not guarantee, that the protected mode application is executed with privilege level 0. Therefore this method is *not* used. VCPI services offer another way to switch to protected mode, and VCPI servers are built into "emm386.exe", "386max" and "qemm". That's why, this method is implemented in fbsdboot.exe. Fbsdboot.exe tries to switch to protected mode using VCPI services. If they're not available INT15H is used to do the switch. If that fails, it's not possible for this version of fbsdboot.exe to boot a kernel :-(. You can get commandline options of fbsdboot if you start it with "-?" as option! I don't know, if fbsdboot works with QEMM, as I don't have the possibility to test it. Enjoy and have fun! Christian. cg@fimp01.fim.uni-linz.ac.at PS: Many thanks to Bruce Evans for his assistance!
Diffstat (limited to 'sys/i386/boot/dosboot')
-rw-r--r--sys/i386/boot/dosboot/ansi.h58
-rw-r--r--sys/i386/boot/dosboot/boot.c236
-rw-r--r--sys/i386/boot/dosboot/boot.h42
-rw-r--r--sys/i386/boot/dosboot/bootinfo.h50
-rw-r--r--sys/i386/boot/dosboot/cdefs.h100
-rw-r--r--sys/i386/boot/dosboot/dinode.h111
-rw-r--r--sys/i386/boot/dosboot/dir.h62
-rw-r--r--sys/i386/boot/dosboot/dirent.h108
-rw-r--r--sys/i386/boot/dosboot/disk.c295
-rw-r--r--sys/i386/boot/dosboot/disklabe.h415
-rw-r--r--sys/i386/boot/dosboot/dkbad.h99
-rw-r--r--sys/i386/boot/dosboot/dosboot.c192
-rw-r--r--sys/i386/boot/dosboot/dosboot.h18
-rw-r--r--sys/i386/boot/dosboot/endian.h120
-rw-r--r--sys/i386/boot/dosboot/exec.h88
-rw-r--r--sys/i386/boot/dosboot/fbsdboot.c92
-rw-r--r--sys/i386/boot/dosboot/fbsdboot.exe.uu494
-rw-r--r--sys/i386/boot/dosboot/fbsdboot.mak177
-rw-r--r--sys/i386/boot/dosboot/fs.h465
-rw-r--r--sys/i386/boot/dosboot/imgact.h146
-rw-r--r--sys/i386/boot/dosboot/inode.h281
-rw-r--r--sys/i386/boot/dosboot/mexec.h44
-rw-r--r--sys/i386/boot/dosboot/param.h170
-rw-r--r--sys/i386/boot/dosboot/protmod.c591
-rw-r--r--sys/i386/boot/dosboot/protmod.h34
-rw-r--r--sys/i386/boot/dosboot/quota.h208
-rw-r--r--sys/i386/boot/dosboot/readme41
-rw-r--r--sys/i386/boot/dosboot/reboot.h96
-rw-r--r--sys/i386/boot/dosboot/sys.c173
-rw-r--r--sys/i386/boot/dosboot/syslimit.h59
-rw-r--r--sys/i386/boot/dosboot/sysparam.h225
-rw-r--r--sys/i386/boot/dosboot/types.h175
32 files changed, 5465 insertions, 0 deletions
diff --git a/sys/i386/boot/dosboot/ansi.h b/sys/i386/boot/dosboot/ansi.h
new file mode 100644
index 0000000..4acad94
--- /dev/null
+++ b/sys/i386/boot/dosboot/ansi.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)ansi.h 7.1 (Berkeley) 3/9/91
+ * $Id: ansi.h,v 1.2 1993/10/16 14:39:05 rgrimes Exp $
+ */
+
+#ifndef _ANSI_H_
+#define _ANSI_H_
+
+/*
+ * Types which are fundamental to the implementation and may appear in
+ * more than one standard header are defined here. Standard headers
+ * then use:
+ * #ifdef _SIZE_T_
+ * typedef _SIZE_T_ size_t;
+ * #undef _SIZE_T_
+ * #endif
+ *
+ * Thanks, ANSI!
+ */
+#define _CLOCK_T_ unsigned long /* clock() */
+#define _PTRDIFF_T_ int /* ptr1 - ptr2 */
+#define _SIZE_T_ unsigned int /* sizeof() */
+#define _TIME_T_ long /* time() */
+#define _VA_LIST_ char * /* va_list */
+#define _WCHAR_T_ unsigned short /* wchar_t */
+
+#endif /* _ANSI_H_ */
diff --git a/sys/i386/boot/dosboot/boot.c b/sys/i386/boot/dosboot/boot.c
new file mode 100644
index 0000000..d80e171
--- /dev/null
+++ b/sys/i386/boot/dosboot/boot.c
@@ -0,0 +1,236 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, [92/04/03 16:51:14 rvb]
+ * $Id: boot.c,v 1.9.2.1 1994/05/01 05:14:49 rgrimes Exp $
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+#include <stdio.h>
+#include <conio.h>
+#include <process.h>
+#include <memory.h>
+
+#include "protmod.h"
+#include "param.h"
+#include "boot.h"
+#include "bootinfo.h"
+#include "reboot.h"
+
+#include "exec.h"
+
+int openrd(char *kernel);
+void ufs_read(char *buffer, long count);
+void xread(unsigned long addr, long size);
+
+static struct exec head;
+static long argv[10];
+static char buf[__LDPGSZ];
+static long int startaddr;
+
+void pbzero(unsigned long addr, unsigned long size)
+{
+ long s;
+
+ memset(buf, 0, __LDPGSZ);
+ while (size) {
+ s = size > __LDPGSZ ? __LDPGSZ : size;
+ pm_copy(buf, addr, s);
+ size -= s;
+ addr += s;
+ }
+}
+
+static long loadprog(int howto, long *hsize)
+{
+ long int addr; /* physical address.. not directly useable */
+ long int hmaddress;
+ int i;
+ static int (*x_entry)() = 0;
+
+ argv[3] = 0;
+ argv[4] = 0;
+ ufs_read(&head, (long) sizeof(head));
+ if ( N_BADMAG(head)) {
+ printf("Invalid format!\n");
+ exit(0);
+ }
+
+ poff = N_TXTOFF(head);
+
+ startaddr = (long)head.a_entry;
+ addr = (startaddr & 0x00ffffffl); /* some MEG boundary */
+ printf("Booting @ 0x%lx\n", addr);
+ if(addr < 0x100000l)
+ {
+ printf("kernel linked for wrong address!\n");
+ printf("Only hope is to link the kernel for > 1MB\n");
+ exit(0);
+ }
+
+ *hsize = head.a_text+head.a_data+head.a_bss;
+ addr=hmaddress=get_high_memory(*hsize);
+ if (!hmaddress) {
+ printf("Sorry, can't allocate enough memory!\n");
+ exit(0);
+ }
+
+ /********************************************************/
+ /* LOAD THE TEXT SEGMENT */
+ /********************************************************/
+ printf("text=0x%lx ", head.a_text);
+ xread(addr, head.a_text);
+ addr += head.a_text;
+
+ /********************************************************/
+ /* Load the Initialised data after the text */
+ /********************************************************/
+ while (addr & CLOFSET)
+ pm_copy("\0", addr++, 1);
+
+ printf("data=0x%lx ", head.a_data);
+ xread(addr, head.a_data);
+ addr += head.a_data;
+
+ /********************************************************/
+ /* Skip over the uninitialised data */
+ /* (but clear it) */
+ /********************************************************/
+ printf("bss=0x%lx ", head.a_bss);
+ pbzero(addr, head.a_bss);
+ argv[3] = (addr += head.a_bss);
+ argv[3] += -hmaddress+0x100000l;
+
+ /********************************************************/
+ /* and note the end address of all this */
+ /********************************************************/
+
+ addr = addr-hmaddress+0x100000l;
+ argv[4] = ((addr+(long) sizeof(long)-1l))&~((long)sizeof(long)-1l);
+ printf("total=0x%lx ",argv[4]);
+
+ /*
+ * We now pass the various bootstrap parameters to the loaded
+ * image via the argument list
+ * (THIS IS A BIT OF HISTORY FROM MACH.. LEAVE FOR NOW)
+ * arg1 = boot flags
+ * arg2 = boot device
+ * arg3 = start of symbol table (0 if not loaded)
+ * arg4 = end of symbol table (0 if not loaded)
+ * arg5 = transfer address from image
+ * arg6 = transfer address for next image pointer
+ */
+ switch(maj)
+ {
+ case 2:
+ printf("\n\nInsert file system floppy in drive A or B\n");
+ printf("Press 'A', 'B' or any other key for the default ");
+ printf("%c: ", unit+'A');
+ i = _getche();
+ if (i=='0' || i=='A' || i=='a')
+ unit = 0;
+ if (i=='1' || i=='B' || i=='b')
+ unit = 1;
+ printf("\n");
+ break;
+ case 4:
+ break;
+ }
+ argv[1] = howto;
+ argv[2] = (MAKEBOOTDEV(maj, (slice>>4), (slice&0xf), unit, part)) ;
+ argv[5] = (head.a_entry &= 0xfffffff);
+ argv[6] = (long) &x_entry;
+ argv[0] = 8;
+
+ printf("entry point=0x%lx\n" ,((long)startaddr) & 0xffffff);
+ return hmaddress;
+}
+
+static unsigned int memsize(int x)
+{
+ unsigned int rt=0;
+
+ switch (x) {
+ case 1:
+ _asm {
+ mov bl,1
+ mov ah,88h
+ int 15h
+ mov rt,ax
+ }
+ break;
+ default:
+ _asm {
+ int 12h
+ mov rt,ax
+ }
+ break;
+ }
+ return rt;
+}
+
+void bsdboot(int drive, int loadflags, char *kernel)
+{
+ long hmaddress, size;
+
+ argv[7] = memsize(0);
+ argv[8] = memsize(1);
+
+ /***************************************************************\
+ * As a default set it to the first partition of the first *
+ * floppy or hard drive *
+ \***************************************************************/
+ part = unit = 0;
+ maj = (drive&0x80 ? 0 : 2); /* a good first bet */
+
+ if (openrd(kernel)) {
+ printf("Can't find %s\n", kernel);
+ exit(0);
+ }
+ hmaddress = loadprog(loadflags, &size);
+ startprog(hmaddress, size, ((long)startaddr & 0xffffffl), argv);
+}
diff --git a/sys/i386/boot/dosboot/boot.h b/sys/i386/boot/dosboot/boot.h
new file mode 100644
index 0000000..6ed3463
--- /dev/null
+++ b/sys/i386/boot/dosboot/boot.h
@@ -0,0 +1,42 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:03 rpd
+ * $Id: boot.h,v 1.3 1993/10/16 19:11:32 rgrimes Exp $
+ */
+
+#include "types.h"
+#include "param.h"
+#include "quota.h"
+#include "fs.h"
+#include "inode.h"
+
+extern char *devs[], *name, *iodest;
+extern struct fs *fs;
+extern struct inode inode;
+extern long dosdev, slice, unit, part, maj, boff, poff, bnum, cnt;
+
+extern void bsdboot(int d, int howto, char *kernel);
+extern void pbzero(unsigned long addr, unsigned long size);
diff --git a/sys/i386/boot/dosboot/bootinfo.h b/sys/i386/boot/dosboot/bootinfo.h
new file mode 100644
index 0000000..996870a
--- /dev/null
+++ b/sys/i386/boot/dosboot/bootinfo.h
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (C) 1994 by Rodney W. Grimes, Milwaukie, Oregon 97222
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Rodney W. Grimes.
+ * 4. 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 RODNEY W. GRIMES ``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 RODNEY W. GRIMES BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: bootinfo.h,v 1.3 1994/11/18 05:26:52 phk Exp $
+ */
+
+#ifndef _MACHINE_BOOTINFO_H_
+#define _MACHINE_BOOTINFO_H_
+
+#define N_BIOS_GEOM 8
+struct bootinfo_t {
+ unsigned long version;
+ unsigned char *kernelname;
+ void *nfs_diskless;
+ unsigned long n_bios_used;
+ unsigned long bios_geom[N_BIOS_GEOM];
+};
+
+#ifdef KERNEL
+extern struct bootinfo_t bootinfo;
+#endif
+#endif /* _MACHINE_BOOTINFO_H_ */
diff --git a/sys/i386/boot/dosboot/cdefs.h b/sys/i386/boot/dosboot/cdefs.h
new file mode 100644
index 0000000..09995d4
--- /dev/null
+++ b/sys/i386/boot/dosboot/cdefs.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)cdefs.h 8.1 (Berkeley) 6/2/93
+ * $Id: cdefs.h,v 1.6 1993/10/16 17:16:24 rgrimes Exp $
+ */
+
+#ifndef _CDEFS_H_
+#define _CDEFS_H_
+
+#if defined(__cplusplus)
+#define __BEGIN_DECLS extern "C" {
+#define __END_DECLS };
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments. __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#if defined(__P)
+#undef __P
+#endif /* defined(__P) */
+#define __P(protos) protos /* full-blown ANSI C */
+#define __CONCAT(x,y) x ## y
+#define __STRING(x) #x
+
+#else /* !(__STDC__ || __cplusplus) */
+#if defined(__P)
+#undef __P
+#endif /* defined(__P) */
+#define __P(protos) () /* traditional C preprocessor */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+
+/* delete ANSI C keywords */
+#define const
+#define inline
+#define signed
+#define volatile
+#endif /* !(__STDC__ || __cplusplus) */
+
+/*
+ * GCC has extensions for declaring functions as const (`pure' - always returns
+ * the same value given the same inputs, i.e., has no external state and
+ * no side effects) and volatile (nonreturning or `dead').
+ * These mainly affect optimization and warnings.
+ *
+ * To facilitate portability of a non-standard extension we define __pure
+ * and __dead and use these for qualifying functions. Non-gcc compilers
+ * which have similar extensions can then define these appropriately.
+ *
+ * Unfortunately, GCC complains if these are used under strict ANSI mode
+ * (`gcc -ansi -pedantic'), hence we need to define them only if compiling
+ * without this.
+ */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define __dead __volatile
+#define __pure __const
+#else
+#define __dead
+#define __pure
+#endif
+
+#endif /* !_CDEFS_H_ */
diff --git a/sys/i386/boot/dosboot/dinode.h b/sys/i386/boot/dosboot/dinode.h
new file mode 100644
index 0000000..adfac17
--- /dev/null
+++ b/sys/i386/boot/dosboot/dinode.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1982, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)dinode.h 7.10 (Berkeley) 5/8/91
+ * $Id: dinode.h,v 1.5 1993/12/19 22:51:07 alm Exp $
+ */
+
+#ifndef _UFS_DINODE_H_
+#define _UFS_DINODE_H_ 1
+
+/*
+ * A dinode contains all the meta-data associated with a UFS file.
+ * This structure defines the on-disk format of a dinode.
+ */
+
+#define NDADDR 12 /* direct addresses in inode */
+#define NIADDR 3 /* indirect addresses in inode */
+
+#define MAXFASTLINK (((NDADDR+NIADDR) * sizeof(daddr_t)) - 1)
+
+struct dinode {
+ u_short di_mode; /* 0: mode and type of file */
+ short di_nlink; /* 2: number of links to file */
+ uid_t di_uid; /* 4: owner's user id */
+ gid_t di_gid; /* 6: owner's group id */
+ union {
+/* u_quad_t v;*/
+ u_long val[2];
+ } di_qsize; /* 8: number of bytes in file */
+ time_t di_atime; /* 16: time last accessed */
+ long di_atspare;
+ time_t di_mtime; /* 24: time last modified */
+ long di_mtspare;
+ time_t di_ctime; /* 32: last time inode changed */
+ long di_ctspare;
+ union {
+ struct {
+ daddr_t di_udb[NDADDR]; /* 40: disk block addresses */
+ daddr_t di_uib[NIADDR]; /* 88: indirect blocks */
+ } di_addr;
+ char di_usymlink[MAXFASTLINK+1];
+ } di_un;
+ long di_flags; /* 100: status, currently unused */
+ long di_blocks; /* 104: blocks actually held */
+ long di_gen; /* 108: generation number */
+#define DI_SPARE_SZ 4 /* 112: spare for 4 longs */
+ u_long di_spare[DI_SPARE_SZ]; /* reserved (unused) */
+};
+
+#define di_db di_un.di_addr.di_udb
+#define di_ib di_un.di_addr.di_uib
+#define di_symlink di_un.di_usymlink
+
+#if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */
+#define di_size di_qsize.val[0]
+#else /* BYTE_ORDER == BIG_ENDIAN */
+#define di_size di_qsize.val[1]
+#endif
+#define di_rdev di_db[0]
+
+/* file modes */
+#define IFMT 0170000 /* mask of file type */
+#define IFIFO 0010000 /* named pipe (fifo) */
+#define IFCHR 0020000 /* character special device */
+#define IFDIR 0040000 /* directory */
+#define IFBLK 0060000 /* block special device */
+#define IFREG 0100000 /* regular file */
+#define IFLNK 0120000 /* symbolic link */
+#define IFSOCK 0140000 /* UNIX domain socket */
+
+#define ISUID 04000 /* set user identifier when exec'ing */
+#define ISGID 02000 /* set group identifier when exec'ing */
+#define ISVTX 01000 /* save execution information on exit */
+#define IREAD 0400 /* read permission */
+#define IWRITE 0200 /* write permission */
+#define IEXEC 0100 /* execute permission */
+
+#define DFASTLINK(di) \
+ ((((di).di_mode & IFMT) == IFLNK) && \
+ ((di).di_size <= MAXFASTLINK) && \
+ ((di).di_size == (di).di_spare[0]))
+#endif /* _UFS_DINODE_H_ */
diff --git a/sys/i386/boot/dosboot/dir.h b/sys/i386/boot/dosboot/dir.h
new file mode 100644
index 0000000..bc02fde
--- /dev/null
+++ b/sys/i386/boot/dosboot/dir.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)dir.h 7.3 (Berkeley) 2/5/91
+ * $Id: dir.h,v 1.2 1993/10/16 17:16:31 rgrimes Exp $
+ */
+
+/*
+ * The information in this file should be obtained from <dirent.h>
+ * and is provided solely (and temporarily) for backward compatibility.
+ */
+
+#ifndef _DIR_H_
+#define _DIR_H_
+
+#include "dirent.h"
+
+/*
+ * Backwards compatibility.
+ */
+#define direct dirent
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry. This requires the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ */
+#undef DIRSIZ
+#define DIRSIZ(dp) \
+ ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+
+#endif /* !_DIR_H_ */
diff --git a/sys/i386/boot/dosboot/dirent.h b/sys/i386/boot/dosboot/dirent.h
new file mode 100644
index 0000000..5c6463b
--- /dev/null
+++ b/sys/i386/boot/dosboot/dirent.h
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)dirent.h 5.18 (Berkeley) 2/23/91
+ */
+
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+/*
+ * A directory entry has a struct dirent at the front of it, containing its
+ * inode number, the length of the entry, and the length of the name
+ * contained in the entry. These are followed by the name padded to a 4
+ * byte boundary with null bytes. All names are guaranteed null terminated.
+ * The maximum length of a name in a directory is MAXNAMLEN.
+ */
+
+struct dirent {
+ u_long d_fileno; /* file number of entry */
+ u_short d_reclen; /* length of this record */
+ u_short d_namlen; /* length of string in d_name */
+#ifdef _POSIX_SOURCE
+ char d_name[255 + 1]; /* name must be no longer than this */
+#else
+#define MAXNAMLEN 255
+ char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
+#endif
+};
+
+#ifdef _POSIX_SOURCE
+typedef void * DIR;
+#else
+
+#define d_ino d_fileno /* backward compatibility */
+
+/* definitions for library routines operating on directories. */
+#define DIRBLKSIZ 1024
+
+/* structure describing an open directory. */
+typedef struct _dirdesc {
+ long dd_fd; /* file descriptor associated with directory */
+ long dd_loc; /* offset in current buffer */
+ long dd_size; /* amount of data returned by getdirentries */
+ char *dd_buf; /* data buffer */
+ long dd_len; /* size of data buffer */
+ long dd_seek; /* magic cookie returned by getdirentries */
+ void *dd_ddloc; /* Linked list of ddloc structs for telldir/seekdir */
+} DIR;
+
+#define dirfd(dirp) ((dirp)->dd_fd)
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#endif /* _POSIX_SOURCE */
+
+#ifndef KERNEL
+
+#include "cdefs.h"
+
+__BEGIN_DECLS
+DIR *opendir __P((const char *));
+struct dirent *readdir __P((DIR *));
+void rewinddir __P((DIR *));
+int closedir __P((DIR *));
+#ifndef _POSIX_SOURCE
+long telldir __P((const DIR *));
+void seekdir __P((DIR *, long));
+int scandir __P((const char *, struct dirent ***,
+ int (*)(struct dirent *), int (*)(const void *, const void *)));
+int alphasort __P((const void *, const void *));
+int getdirentries __P((int, char *, int, long *));
+#endif /* not POSIX */
+__END_DECLS
+
+#endif /* !KERNEL */
+
+#endif /* !_DIRENT_H_ */
diff --git a/sys/i386/boot/dosboot/disk.c b/sys/i386/boot/dosboot/disk.c
new file mode 100644
index 0000000..263d3e9
--- /dev/null
+++ b/sys/i386/boot/dosboot/disk.c
@@ -0,0 +1,295 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:49 rpd
+ * $Id: disk.c,v 1.4 1994/02/22 22:59:40 rgrimes Exp $
+ */
+#include <stdio.h>
+#include <memory.h>
+
+#define bcopy(a,b,c) memcpy(b,a,c)
+
+#include "boot.h"
+#ifdef DO_BAD144
+#include "dkbad.h"
+#endif
+#include "disklabe.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)+1)
+
+static char i_buf[BPS];
+#define I_ADDR ((void *) i_buf) /* XXX where all reads go */
+
+#ifdef DO_BAD144
+struct dkbad dkb;
+int do_bad144;
+long bsize;
+#endif
+
+static int spt, spc;
+
+char *iodest;
+struct fs *fs;
+struct inode inode;
+long dosdev, slice, unit, part, maj, boff, poff, bnum, cnt;
+
+extern int biosread(int dev, int track, int head, int sector, int cnt, unsigned char far *buffer);
+
+/*#define EMBEDDED_DISKLABEL 1*/
+/*extern struct disklabel disklabel;*/
+struct disklabel disklabel;
+
+static void Bread(int dosdev, long sector);
+static long badsect(int dosdev, long sector);
+
+unsigned long get_diskinfo(int drive)
+{
+ char dr = (char) drive;
+ unsigned long rt;
+
+ _asm {
+ mov ah,8 ; get diskinfo
+ mov dl,dr ; drive
+ int 13h
+ cmp ah,0
+ je ok
+ ;
+ ; Failure! We assume it's a floppy!
+ ;
+ sub ax,ax
+ mov bh,ah
+ mov bl,2
+ mov ch,79
+ mov cl,15
+ mov dh,1
+ mov dl,1
+ ok:
+ mov ah,dh
+ mov al,cl
+ and al,3fh
+ mov word ptr rt,ax
+
+ xor bx,bx
+ mov bl,cl
+ and bl,0c0h
+ shl bx,2
+ mov bl,ch
+ mov word ptr rt+2,bx
+ }
+ return rt;
+}
+
+int devopen(void)
+{
+ struct dos_partition *dptr;
+ struct disklabel *dl;
+ int dosdev = (int) inode.i_dev;
+ int i;
+ long di, sector;
+
+ di = get_diskinfo(dosdev);
+ spc = (spt = (int)SPT(di)) * (int)HEADS(di);
+ if (dosdev == 2)
+ {
+ boff = 0;
+ part = (spt == 15 ? 3 : 1);
+ }
+ else
+ {
+#ifdef EMBEDDED_DISKLABEL
+ dl = &disklabel;
+#else EMBEDDED_DISKLABEL
+ Bread(dosdev, 0);
+ dptr = (struct dos_partition *)(((char *)I_ADDR)+DOSPARTOFF);
+ sector = LABELSECTOR;
+ for (i = 0; i < NDOSPART; i++, dptr++)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start + LABELSECTOR;
+ slice = i+1;
+ break;
+ }
+ Bread(dosdev, sector++);
+ dl=((struct disklabel *)I_ADDR);
+ disklabel = *dl; /* structure copy (maybe useful later)*/
+#endif EMBEDDED_DISKLABEL
+ if (dl->d_magic != DISKMAGIC) {
+ printf("bad disklabel");
+ return 1;
+ }
+
+ if( (maj == 4) || (maj == 0) || (maj == 1)) {
+ if (dl->d_type == DTYPE_SCSI)
+ maj = 4; /* use scsi as boot dev */
+ else
+ maj = 0; /* must be ESDI/IDE */
+ }
+
+ boff = dl->d_partitions[part].p_offset;
+#ifdef DO_BAD144
+ bsize = dl->d_partitions[part].p_size;
+ do_bad144 = 0;
+ if (dl->d_flags & D_BADSECT) {
+ /* this disk uses bad144 */
+ int i;
+ long dkbbnum;
+ struct dkbad *dkbptr;
+
+ /* find the first readable bad144 sector */
+ /* some of this code is copied from ufs/disk_subr.c */
+ /* read a bad sector table */
+ dkbbnum = dl->d_secperunit - dl->d_nsectors;
+ if (dl->d_secsize > DEV_BSIZE)
+ dkbbnum *= dl->d_secsize / DEV_BSIZE;
+ else
+ dkbbnum /= DEV_BSIZE / dl->d_secsize;
+ i = 0;
+ do_bad144 = 0;
+ do {
+ /* XXX: what if the "DOS sector" < 512 bytes ??? */
+ Bread(dosdev, dkbbnum + i);
+ dkbptr = (struct dkbad *) I_ADDR;
+/* XXX why is this not in <sys/dkbad.h> ??? */
+#define DKBAD_MAGIC 0x4321
+ if (dkbptr->bt_mbz == 0 &&
+ dkbptr->bt_flag == DKBAD_MAGIC) {
+ dkb = *dkbptr; /* structure copy */
+ do_bad144 = 1;
+ break;
+ }
+ i += 2;
+ } while (i < 10 && (u_long) i < dl->d_nsectors);
+ if (!do_bad144)
+ printf("Bad badsect table\n");
+ else
+ printf("Using bad144 bad sector at %ld\n", dkbbnum+i);
+ }
+#endif
+ }
+ return 0;
+}
+
+void devread(void)
+{
+ long offset, sector = bnum;
+ int dosdev = (int) inode.i_dev;
+ for (offset = 0; offset < cnt; offset += BPS)
+ {
+ Bread(dosdev, badsect(dosdev, sector++));
+ bcopy(I_ADDR, iodest+offset, BPS);
+ }
+}
+
+/* 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 long ra_end;
+static long ra_first;
+
+static void Bread(int dosdev, long sector)
+{
+ if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
+ {
+ int cyl, head, sec, nsec;
+
+ cyl = (int) (sector/(long)spc);
+ head = (int) ((sector % (long) spc) / (long) spt);
+ sec = (int) (sector % (long) spt);
+ nsec = spt - sec;
+ if (nsec > RA_SECTORS)
+ nsec = RA_SECTORS;
+ if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
+ {
+ nsec = 1;
+ while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
+ printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
+ }
+ ra_dev = dosdev;
+ ra_first = sector;
+ ra_end = sector + nsec;
+ }
+ bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);
+}
+
+static long badsect(int dosdev, long sector)
+{
+#ifdef DO_BAD144
+ int i;
+
+ if (do_bad144) {
+ u_short cyl;
+ u_short head;
+ u_short sec;
+ long newsec;
+ struct disklabel *dl = &disklabel;
+
+ /* XXX */
+ /* from wd.c */
+ /* bt_cyl = cylinder number in sorted order */
+ /* bt_trksec is actually (head << 8) + sec */
+
+ /* only remap sectors in the partition */
+ if (sector < boff || sector >= boff + bsize) {
+ goto no_remap;
+ }
+
+ cyl = (u_short) (sector / dl->d_secpercyl);
+ head = (u_short) ((sector % dl->d_secpercyl) / dl->d_nsectors);
+ sec = (u_short) (sector % dl->d_nsectors);
+ sec = (head<<8) + sec;
+
+ /* now, look in the table for a possible bad sector */
+ for (i=0; i<126; i++) {
+ if (dkb.bt_bad[i].bt_cyl == cyl) {
+ /* found same cylinder */
+ if (dkb.bt_bad[i].bt_trksec == sec) {
+ /* FOUND! */
+ break;
+ }
+ } else if (dkb.bt_bad[i].bt_cyl > cyl) {
+ i = 126;
+ break;
+ }
+ }
+ if (i == 126) {
+ /* didn't find bad sector */
+ goto no_remap;
+ }
+ /* otherwise find replacement sector */
+ newsec = dl->d_secperunit - dl->d_nsectors - i -1;
+ return newsec;
+ }
+ no_remap:
+#endif
+ return sector;
+}
diff --git a/sys/i386/boot/dosboot/disklabe.h b/sys/i386/boot/dosboot/disklabe.h
new file mode 100644
index 0000000..c155df5
--- /dev/null
+++ b/sys/i386/boot/dosboot/disklabe.h
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 1987, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)disklabel.h 8.1 (Berkeley) 6/2/93
+ * $Id: disklabel.h,v 1.8 1994/11/14 13:08:44 bde Exp $
+ */
+
+#ifndef _SYS_DISKLABEL_H_
+#define _SYS_DISKLABEL_H_
+
+/*
+ * Disk description table, see disktab(5)
+ */
+#define _PATH_DISKTAB "/etc/disktab"
+#define DISKTAB "/etc/disktab" /* deprecated */
+
+/*
+ * Each disk has a label which includes information about the hardware
+ * disk geometry, filesystem partitions, and drive specific information.
+ * The label is in block 0 or 1, possibly offset from the beginning
+ * to leave room for a bootstrap, etc.
+ */
+
+/* XXX these should be defined per controller (or drive) elsewhere, not here! */
+#ifdef __i386__
+#define LABELSECTOR 1 /* sector containing label */
+#define LABELOFFSET 0 /* offset of label in sector */
+#define OURPART 2 /* partition is 'all BSD' */
+#define RAWPART 3 /* partition is 'all device' */
+#define readMSPtolabel readMBRtolabel
+#endif
+
+#ifndef readMSPtolabel
+#define readMSPtolabel(a,b,c,d,e) /* zap calls if irrelevant */
+#endif
+
+#ifdef tahoe
+#define RAWPART 0
+#endif
+
+#ifndef RAWPART
+#define RAWPART 2
+#endif
+
+#ifndef OURPART
+#define OURPART RAWPART /* by default it's all ours */
+#endif
+
+#ifndef LABELSECTOR
+#define LABELSECTOR 0 /* sector containing label */
+#endif
+
+#ifndef LABELOFFSET
+#define LABELOFFSET 64 /* offset of label in sector */
+#endif
+
+#define DISKMAGIC ((u_long) 0x82564557ul) /* The disk magic number */
+#ifndef MAXPARTITIONS
+#define MAXPARTITIONS 8
+#endif
+
+
+#ifndef LOCORE
+struct disklabel {
+ u_long d_magic; /* the magic number */
+ short d_type; /* drive type */
+ short d_subtype; /* controller/d_type specific */
+ char d_typename[16]; /* type name, e.g. "eagle" */
+ /*
+ * d_packname contains the pack identifier and is returned when
+ * the disklabel is read off the disk or in-core copy.
+ * d_boot0 and d_boot1 are the (optional) names of the
+ * primary (block 0) and secondary (block 1-15) bootstraps
+ * as found in /usr/mdec. These are returned when using
+ * getdiskbyname(3) to retrieve the values from /etc/disktab.
+ */
+#if defined(KERNEL) || defined(STANDALONE)
+ char d_packname[16]; /* pack identifier */
+#else
+ union {
+ char un_d_packname[16]; /* pack identifier */
+ struct {
+ char *un_d_boot0; /* primary bootstrap name */
+ char *un_d_boot1; /* secondary bootstrap name */
+ } un_b;
+ } d_un;
+#define d_packname d_un.un_d_packname
+#define d_boot0 d_un.un_b.un_d_boot0
+#define d_boot1 d_un.un_b.un_d_boot1
+#endif /* ! KERNEL or STANDALONE */
+ /* disk geometry: */
+ u_long d_secsize; /* # of bytes per sector */
+ u_long d_nsectors; /* # of data sectors per track */
+ u_long d_ntracks; /* # of tracks per cylinder */
+ u_long d_ncylinders; /* # of data cylinders per unit */
+ u_long d_secpercyl; /* # of data sectors per cylinder */
+ u_long d_secperunit; /* # of data sectors per unit */
+ /*
+ * Spares (bad sector replacements) below
+ * are not counted in d_nsectors or d_secpercyl.
+ * Spare sectors are assumed to be physical sectors
+ * which occupy space at the end of each track and/or cylinder.
+ */
+ u_short d_sparespertrack; /* # of spare sectors per track */
+ u_short d_sparespercyl; /* # of spare sectors per cylinder */
+ /*
+ * Alternate cylinders include maintenance, replacement,
+ * configuration description areas, etc.
+ */
+ u_long d_acylinders; /* # of alt. cylinders per unit */
+
+ /* hardware characteristics: */
+ /*
+ * d_interleave, d_trackskew and d_cylskew describe perturbations
+ * in the media format used to compensate for a slow controller.
+ * Interleave is physical sector interleave, set up by the formatter
+ * or controller when formatting. When interleaving is in use,
+ * logically adjacent sectors are not physically contiguous,
+ * but instead are separated by some number of sectors.
+ * It is specified as the ratio of physical sectors traversed
+ * per logical sector. Thus an interleave of 1:1 implies contiguous
+ * layout, while 2:1 implies that logical sector 0 is separated
+ * by one sector from logical sector 1.
+ * d_trackskew is the offset of sector 0 on track N
+ * relative to sector 0 on track N-1 on the same cylinder.
+ * Finally, d_cylskew is the offset of sector 0 on cylinder N
+ * relative to sector 0 on cylinder N-1.
+ */
+ u_short d_rpm; /* rotational speed */
+ u_short d_interleave; /* hardware sector interleave */
+ u_short d_trackskew; /* sector 0 skew, per track */
+ u_short d_cylskew; /* sector 0 skew, per cylinder */
+ u_long d_headswitch; /* head switch time, usec */
+ u_long d_trkseek; /* track-to-track seek, usec */
+ u_long d_flags; /* generic flags */
+#define NDDATA 5
+ u_long d_drivedata[NDDATA]; /* drive-type specific information */
+#define NSPARE 5
+ u_long d_spare[NSPARE]; /* reserved for future use */
+ u_long d_magic2; /* the magic number (again) */
+ u_short d_checksum; /* xor of data incl. partitions */
+
+ /* filesystem and partition information: */
+ u_short d_npartitions; /* number of partitions in following */
+ u_long d_bbsize; /* size of boot area at sn0, bytes */
+ u_long d_sbsize; /* max size of fs superblock, bytes */
+ struct partition { /* the partition table */
+ u_long p_size; /* number of sectors in partition */
+ u_long p_offset; /* starting sector */
+ u_long p_fsize; /* filesystem basic fragment size */
+ u_char p_fstype; /* filesystem type, see below */
+ u_char p_frag; /* filesystem fragments per block */
+ union {
+ u_short cpg; /* UFS: FS cylinders per group */
+ u_short sgs; /* LFS: FS segment shift */
+ } __partition_u1;
+#define p_cpg __partition_u1.cpg
+#define p_sgs __partition_u1.sgs
+ } d_partitions[MAXPARTITIONS]; /* actually may be more */
+};
+/*
+struct cpu_disklabel {
+};
+*/
+#else /* LOCORE */
+ /*
+ * offsets for asm boot files.
+ */
+ .set d_secsize,40
+ .set d_nsectors,44
+ .set d_ntracks,48
+ .set d_ncylinders,52
+ .set d_secpercyl,56
+ .set d_secperunit,60
+ .set d_end_,276 /* size of disk label */
+#endif /* LOCORE */
+
+/* d_type values: */
+#define DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
+#define DTYPE_MSCP 2 /* MSCP */
+#define DTYPE_DEC 3 /* other DEC (rk, rl) */
+#define DTYPE_SCSI 4 /* SCSI */
+#define DTYPE_ESDI 5 /* ESDI interface */
+#define DTYPE_ST506 6 /* ST506 etc. */
+#define DTYPE_HPIB 7 /* CS/80 on HP-IB */
+#define DTYPE_HPFL 8 /* HP Fiber-link */
+#define DTYPE_FLOPPY 10 /* floppy */
+
+/* d_subtype values: */
+#define DSTYPE_INDOSPART 0x8 /* is inside dos partition */
+#define DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */
+#define DSTYPE_GEOMETRY 0x10 /* drive params in label */
+
+#ifdef DKTYPENAMES
+static char *dktypenames[] = {
+ "unknown",
+ "SMD",
+ "MSCP",
+ "old DEC",
+ "SCSI",
+ "ESDI",
+ "ST506",
+ "HP-IB",
+ "HP-FL",
+ "type 9",
+ "floppy",
+ 0
+};
+#define DKMAXTYPES (sizeof(dktypenames) / sizeof(dktypenames[0]) - 1)
+#endif
+
+/*
+ * Filesystem type and version.
+ * Used to interpret other filesystem-specific
+ * per-partition information.
+ */
+#define FS_UNUSED 0 /* unused */
+#define FS_SWAP 1 /* swap */
+#define FS_V6 2 /* Sixth Edition */
+#define FS_V7 3 /* Seventh Edition */
+#define FS_SYSV 4 /* System V */
+#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
+#define FS_V8 6 /* Eighth Edition, 4K blocks */
+#define FS_BSDFFS 7 /* 4.2BSD fast file system */
+#define FS_MSDOS 8 /* MSDOS file system */
+#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */
+#define FS_OTHER 10 /* in use, but unknown/unsupported */
+#define FS_HPFS 11 /* OS/2 high-performance file system */
+#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */
+#define FS_BOOT 13 /* partition contains bootstrap */
+
+#ifdef DKTYPENAMES
+static char *fstypenames[] = {
+ "unused",
+ "swap",
+ "Version 6",
+ "Version 7",
+ "System V",
+ "4.1BSD",
+ "Eighth Edition",
+ "4.2BSD",
+ "MSDOS",
+ "4.4LFS",
+ "unknown",
+ "HPFS",
+ "ISO9660",
+ "boot",
+ 0
+};
+#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
+#endif
+
+/*
+ * flags shared by various drives:
+ */
+#define D_REMOVABLE 0x01 /* removable media */
+#define D_ECC 0x02 /* supports ECC */
+#define D_BADSECT 0x04 /* supports bad sector forw. */
+#define D_RAMDISK 0x08 /* disk emulator */
+#define D_CHAIN 0x10 /* can do back-back transfers */
+
+/*
+ * Drive data for SMD.
+ */
+#define d_smdflags d_drivedata[0]
+#define D_SSE 0x1 /* supports skip sectoring */
+#define d_mindist d_drivedata[1]
+#define d_maxdist d_drivedata[2]
+#define d_sdist d_drivedata[3]
+
+/*
+ * Drive data for ST506.
+ */
+#define d_precompcyl d_drivedata[0]
+#define d_gap3 d_drivedata[1] /* used only when formatting */
+
+/*
+ * Drive data for SCSI.
+ */
+#define d_blind d_drivedata[0]
+
+#ifndef LOCORE
+/*
+ * Structure used to perform a format
+ * or other raw operation, returning data
+ * and/or register values.
+ * Register identification and format
+ * are device- and driver-dependent.
+ */
+struct format_op {
+ char *df_buf;
+ long df_count; /* value-result */
+ daddr_t df_startblk;
+ long df_reg[8]; /* result */
+};
+
+/*
+ * Structure used internally to retrieve
+ * information about a partition on a disk.
+ */
+struct partinfo {
+ struct disklabel *disklab;
+ struct partition *part;
+};
+
+/* DOS partition table -- located in boot block */
+
+#define DOSBBSECTOR 0 /* DOS boot block relative sector number */
+#define DOSPARTOFF 446
+#define NDOSPART 4
+#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */
+#define MBR_PTYPE_FreeBSD 0xa5 /* FreeBSD partition type */
+
+struct dos_partition {
+ unsigned char dp_flag; /* bootstrap flags */
+ unsigned char dp_shd; /* starting head */
+ unsigned char dp_ssect; /* starting sector */
+ unsigned char dp_scyl; /* starting cylinder */
+ unsigned char dp_typ; /* partition type */
+ unsigned char dp_ehd; /* end head */
+ unsigned char dp_esect; /* end sector */
+ unsigned char dp_ecyl; /* end cylinder */
+ unsigned long dp_start; /* absolute starting sector number */
+ unsigned long dp_size; /* partition size in sectors */
+};
+
+extern struct dos_partition dos_partitions[NDOSPART];
+
+#define DPSECT(s) ((s) & 0x3f) /* isolate relevant bits of sector */
+#define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* and those that are cylinder */
+
+/*
+ * Disk-specific ioctls.
+ */
+ /* get and set disklabel; DIOCGPART used internally */
+#define DIOCGDINFO _IOR('d', 101, struct disklabel)/* get */
+#define DIOCSDINFO _IOW('d', 102, struct disklabel)/* set */
+#define DIOCWDINFO _IOW('d', 103, struct disklabel)/* set, update disk */
+#define DIOCGPART _IOW('d', 104, struct partinfo) /* get partition */
+
+/* do format operation, read or write */
+#define DIOCRFORMAT _IOWR('d', 105, struct format_op)
+#define DIOCWFORMAT _IOWR('d', 106, struct format_op)
+
+#define DIOCSSTEP _IOW('d', 107, int) /* set step rate */
+#define DIOCSRETRIES _IOW('d', 108, int) /* set # of retries */
+#define DIOCWLABEL _IOW('d', 109, int) /* write en/disable label */
+
+#define DIOCSBAD _IOW('d', 110, struct dkbad) /* set kernel dkbad */
+
+#endif /* LOCORE */
+
+#ifdef KERNEL
+struct dkbad;
+
+u_int dkcksum __P((struct disklabel *));
+int writedisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp));
+char * readdisklabel __P((dev_t dev, void (*strat)(), struct disklabel *lp, struct dos_partition *dp, struct dkbad *bdp));
+int setdisklabel __P((struct disklabel *olp, struct disklabel *nlp, u_long openmask));
+void disksort __P((struct buf *ap, struct buf *bp));
+void diskerr __P((struct buf *, char *, char *, int, int, struct disklabel *));
+#ifdef __i386
+char * readMBRtolabel __P(( dev_t dev , void (*strat)(), register struct disklabel *lp, struct dos_partition *dp, int *cyl));
+#endif
+#endif
+
+#if !defined(KERNEL) && !defined(LOCORE)
+
+#include "cdefs.h"
+
+__BEGIN_DECLS
+struct disklabel *getdiskbyname __P((const char *));
+__END_DECLS
+
+#endif
+
+#ifdef __i386
+/* encoding of disk minor numbers, should be elsewhere... */
+#define dkunit(dev) (minor(dev) >> 3)
+#define dkpart(dev) (minor(dev) & 07)
+#define dkminor(unit, part) (((unit) << 3) | (part))
+#endif
+
+#endif
+
+
diff --git a/sys/i386/boot/dosboot/dkbad.h b/sys/i386/boot/dosboot/dkbad.h
new file mode 100644
index 0000000..492b848
--- /dev/null
+++ b/sys/i386/boot/dosboot/dkbad.h
@@ -0,0 +1,99 @@
+/*-
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)dkbad.h 8.1 (Berkeley) 6/2/93
+ * $Id: dkbad.h,v 1.4 1994/12/11 23:20:50 bde Exp $
+ */
+
+#ifndef _SYS_DKBAD_H_
+#define _SYS_DKBAD_H_
+
+/*
+ * Definitions needed to perform bad sector revectoring ala DEC STD 144.
+ *
+ * The bad sector information is located in the first 5 even numbered
+ * sectors of the last track of the disk pack. There are five identical
+ * copies of the information, described by the dkbad structure.
+ *
+ * Replacement sectors are allocated starting with the first sector before
+ * the bad sector information and working backwards towards the beginning of
+ * the disk. A maximum of 126 bad sectors are supported. The position of
+ * the bad sector in the bad sector table determines which replacement sector
+ * it corresponds to.
+ *
+ * The bad sector information and replacement sectors are conventionally
+ * only accessible through the 'c' file system partition of the disk. If
+ * that partition is used for a file system, the user is responsible for
+ * making sure that it does not overlap the bad sector information or any
+ * replacement sectors.
+ */
+
+#define DKBAD_MAGIC 0x4321 /* normal value for bt_flag */
+#define DKBAD_MAXBAD 126 /* maximum bad sectors supported */
+#define DKBAD_NOCYL 0xffff /* cylinder to mark end of disk table */
+
+struct dkbad {
+ long bt_csn; /* cartridge serial number */
+ u_short bt_mbz; /* unused; should be 0 */
+ u_short bt_flag; /* -1 => alignment cartridge */
+ struct bt_bad {
+ u_short bt_cyl; /* cylinder number of bad sector */
+ u_short bt_trksec; /* track and sector number */
+ } bt_bad[DKBAD_MAXBAD];
+};
+
+#define ECC 0
+#define SSE 1
+#define BSE 2
+#define CONT 3
+
+#ifdef KERNEL
+include <sys/conf.h>
+
+#define DKBAD_NOSECT (-1) /* sector to mark end of core table */
+
+struct dkbad_intern {
+ daddr_t bi_maxspare; /* last spare sector */
+ u_int bi_nbad; /* actual dimension of bi_badsect[] */
+ long bi_bad[DKBAD_MAXBAD + 1]; /* actually usually less */
+};
+
+struct disklabel;
+
+struct dkbad_intern *internbad144 __P((struct dkbad *btp,
+ struct disklabel *lp));
+char *readbad144 __P((dev_t dev, d_strategy_t *strat,
+ struct disklabel *lp, struct dkbad *btp));
+daddr_t transbad144 __P((struct dkbad_intern *bip, daddr_t blkno));
+#endif
+
+#endif /* !_SYS_DKBAD_H_ */
diff --git a/sys/i386/boot/dosboot/dosboot.c b/sys/i386/boot/dosboot/dosboot.c
new file mode 100644
index 0000000..b3b0bc8
--- /dev/null
+++ b/sys/i386/boot/dosboot/dosboot.c
@@ -0,0 +1,192 @@
+/*
+ * dosboot.c Boot FreeBSD from DOS partition
+ *
+ * (C) 1994 by Christian Gusenbauer (cg@fimp01.fim.uni-linz.ac.at)
+ * 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.
+ *
+ * I ALLOW YOU USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. I DISCLAIM
+ * ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+ * USE OF THIS SOFTWARE.
+ *
+ * Parts of this file are
+ * 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.
+ */
+#include <bios.h>
+#include <stdio.h>
+#include <process.h>
+
+#include "protmod.h"
+#include "param.h"
+#include "boot.h"
+#include "bootinfo.h"
+#include "reboot.h"
+
+#include "exec.h"
+
+#define BUFSIZE 4096
+
+static struct exec head;
+static long argv[10];
+static long startaddr;
+
+int biosread(int dev, int track, int head, int sector, int cnt, unsigned char far *buffer)
+{
+ struct _diskinfo_t di;
+ int r;
+
+ di.drive = dev; /* first hard disk */
+ di.head = head; /* head # */
+ di.track = track; /* track # */
+ di.sector = sector+1; /* sector # */
+ di.nsectors = cnt; /* only 1 sector */
+ di.buffer = (void far *) buffer; /* sector buffer */
+ r= _bios_disk(_DISK_READ, &di);
+ return r&0xFF00;
+}
+
+static void dosxread(FILE *fp, unsigned long addr, long size)
+{
+ extern char buf[BUFSIZE];
+
+ int count = BUFSIZE;
+ while (size > 0l) {
+ if (BUFSIZE > size)
+ count = (int) size;
+ fread(buf, count, 1, fp);
+ pm_copy(buf, addr, count);
+ size -= count;
+ addr += count;
+ }
+}
+
+static long loadprog(FILE *fp, int howto, long *hsize)
+{
+ long int addr; /* physical address.. not directly useable */
+ long int hmaddress;
+ static int (*x_entry)() = 0;
+
+ argv[3] = 0;
+ argv[4] = 0;
+ fread(&head, sizeof(head), 1, fp);
+ fseek(fp, 4096-sizeof(head), 1);
+ if ( N_BADMAG(head)) {
+ printf("Invalid format!\n");
+ exit(0);
+ }
+
+ poff = N_TXTOFF(head);
+
+ startaddr = (long)head.a_entry;
+ addr = (startaddr & 0x00ffffffl); /* some MEG boundary */
+ printf("Booting @ 0x%lx\n", addr);
+ if(addr < 0x100000l)
+ {
+ printf("kernel linked for wrong address!\n");
+ printf("Only hope is to link the kernel for > 1MB\n");
+ exit(0);
+ }
+
+ *hsize = head.a_text+head.a_data+head.a_bss;
+ addr=hmaddress=get_high_memory(*hsize);
+ if (!hmaddress) {
+ printf("Sorry, can't allocate enough memory!\n");
+ exit(0);
+ }
+
+ printf("text=0x%lx ", head.a_text);
+ /********************************************************/
+ /* LOAD THE TEXT SEGMENT */
+ /********************************************************/
+ dosxread(fp, addr, head.a_text);
+ addr += head.a_text;
+
+ /********************************************************/
+ /* Load the Initialised data after the text */
+ /********************************************************/
+ while (addr & CLOFSET)
+ pm_copy("\0", addr++, 1);
+
+ printf("data=0x%lx ", head.a_data);
+ dosxread(fp, addr, head.a_data);
+ addr += head.a_data;
+
+ /********************************************************/
+ /* Skip over the uninitialised data */
+ /* (but clear it) */
+ /********************************************************/
+ printf("bss=0x%lx ", head.a_bss);
+ pbzero(addr, head.a_bss);
+ argv[3] = (addr += head.a_bss);
+ argv[3] += -hmaddress+0x100000l;
+
+ /********************************************************/
+ /* and note the end address of all this */
+ /********************************************************/
+
+ addr = addr-hmaddress+0x100000l;
+ argv[4] = ((addr+(long) sizeof(long)-1l))&~((long)sizeof(long)-1l);
+ printf("total=0x%lx ",argv[4]);
+
+ /*
+ * We now pass the various bootstrap parameters to the loaded
+ * image via the argument list
+ * (THIS IS A BIT OF HISTORY FROM MACH.. LEAVE FOR NOW)
+ * arg1 = boot flags
+ * arg2 = boot device
+ * arg3 = start of symbol table (0 if not loaded)
+ * arg4 = end of symbol table (0 if not loaded)
+ * arg5 = transfer address from image
+ * arg6 = transfer address for next image pointer
+ */
+ argv[1] = howto;
+ argv[2] = (MAKEBOOTDEV(maj, (slice>>4), (slice&0xf), unit, part)) ;
+ argv[5] = (head.a_entry &= 0xfffffff);
+ argv[6] = (long) &x_entry;
+ argv[0] = 8;
+
+ printf("entry point=0x%lx\n" ,((long)startaddr) & 0xffffff);
+ return hmaddress;
+}
+
+void dosboot(int howto, char *kernel)
+{
+ long hmaddress, size;
+ FILE *fp;
+
+ fp = fopen(kernel, "rb"); /* open kernel for reading */
+ if (!fp) {
+ fprintf(stderr, "Sorry, can't open %s!\n", kernel);
+ return;
+ }
+ hmaddress = loadprog(fp, howto, &size);
+ fclose(fp);
+ startprog(hmaddress, size, (startaddr & 0xffffffl), argv);
+}
+
diff --git a/sys/i386/boot/dosboot/dosboot.h b/sys/i386/boot/dosboot/dosboot.h
new file mode 100644
index 0000000..5a98501
--- /dev/null
+++ b/sys/i386/boot/dosboot/dosboot.h
@@ -0,0 +1,18 @@
+/*
+ * dosboot.h Boot FreeBSD from DOS partition
+ *
+ * (C) 1994 by Christian Gusenbauer (cg@fimp01.fim.uni-linz.ac.at)
+ * 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.
+ *
+ * I ALLOW YOU USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. I DISCLAIM
+ * ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+ * USE OF THIS SOFTWARE.
+ *
+ */
+void dosboot(int howto, char *kernel);
diff --git a/sys/i386/boot/dosboot/endian.h b/sys/i386/boot/dosboot/endian.h
new file mode 100644
index 0000000..ff7dad5
--- /dev/null
+++ b/sys/i386/boot/dosboot/endian.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1987, 1991 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)endian.h 7.8 (Berkeley) 4/3/91
+ * $Id: endian.h,v 1.5 1994/09/10 20:03:14 csgr Exp $
+ */
+
+#ifndef _MACHINE_ENDIAN_H_
+#define _MACHINE_ENDIAN_H_ 1
+
+/*
+ * Define the order of 32-bit words in 64-bit words.
+ */
+#define _QUAD_HIGHWORD 1
+#define _QUAD_LOWWORD 0
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
+
+#define BYTE_ORDER LITTLE_ENDIAN
+
+#ifndef KERNEL
+#include "cdefs.h"
+#endif
+
+#define __word_swap_long(x) \
+({ register u_long X = (x); \
+ __asm ("rorl $16, %1" \
+ : "=r" (X) \
+ : "0" (X)); \
+ X; })
+#if __GNUC__ >= 2
+#define __byte_swap_long(x) \
+({ register u_long X = (x); \
+ __asm ("xchgb %h1, %b1\n\trorl $16, %1\n\txchgb %h1, %b1" \
+ : "=q" (X) \
+ : "0" (X)); \
+ X; })
+#define __byte_swap_word(x) \
+({ register u_short X = (x); \
+ __asm ("xchgb %h1, %b1" \
+ : "=q" (X) \
+ : "0" (X)); \
+ X; })
+#else /* __GNUC__ >= 2 */
+#define __byte_swap_long(x) \
+({ register u_long X = (x); \
+ __asm ("rorw $8, %w1\n\trorl $16, %1\n\trorw $8, %w1" \
+ : "=r" (X) \
+ : "0" (X)); \
+ X; })
+#define __byte_swap_word(x) \
+({ register u_short X = (x); \
+ __asm ("rorw $8, %w1" \
+ : "=r" (X) \
+ : "0" (X)); \
+ X; })
+#endif /* __GNUC__ >= 2 */
+
+/*
+ * Macros for network/external number representation conversion.
+ */
+#if BYTE_ORDER == BIG_ENDIAN && !defined(lint)
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#define NTOHL(x) (x)
+#define NTOHS(x) (x)
+#define HTONL(x) (x)
+#define HTONS(x) (x)
+
+#else
+
+#define ntohl __byte_swap_long
+#define ntohs __byte_swap_word
+#define htonl __byte_swap_long
+#define htons __byte_swap_word
+
+#define NTOHL(x) (x) = ntohl((u_long)x)
+#define NTOHS(x) (x) = ntohs((u_short)x)
+#define HTONL(x) (x) = htonl((u_long)x)
+#define HTONS(x) (x) = htons((u_short)x)
+#endif
+#endif /* _MACHINE_ENDIAN_H_ */
diff --git a/sys/i386/boot/dosboot/exec.h b/sys/i386/boot/dosboot/exec.h
new file mode 100644
index 0000000..6f6a9e9
--- /dev/null
+++ b/sys/i386/boot/dosboot/exec.h
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 1992, 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)exec.h 8.3 (Berkeley) 1/21/94
+ * $Id: exec.h,v 1.9 1994/10/09 21:50:57 sos Exp $
+ */
+
+#ifndef _SYS_EXEC_H_
+#define _SYS_EXEC_H_
+
+/*
+ * The following structure is found at the top of the user stack of each
+ * user process. The ps program uses it to locate argv and environment
+ * strings. Programs that wish ps to display other information may modify
+ * it; normally ps_argvstr points to the text for argv[0], and ps_nargvstr
+ * is the same as the program's argc. The fields ps_envstr and ps_nenvstr
+ * are the equivalent for the environment.
+ */
+struct ps_strings {
+ char *ps_argvstr; /* first of 0 or more argument strings */
+ long ps_nargvstr; /* the number of argument strings */
+ char *ps_envstr; /* first of 0 or more environment strings */
+ long ps_nenvstr; /* the number of environment strings */
+};
+
+/*
+ * Address of ps_strings structure (in user space).
+ */
+#define SPARE_USRSPACE 256
+#define PS_STRINGS ((struct ps_strings *) \
+ (USRSTACK - sizeof(struct ps_strings) - SPARE_USRSPACE))
+
+/*
+ * Arguments to the exec system call.
+ */
+struct execve_args {
+ char *fname;
+ char **argv;
+ char **envv;
+};
+
+struct execsw {
+ int (*ex_imgact)(void * /* struct image_params * */);
+ const char *ex_name;
+};
+
+#ifdef KERNEL
+extern const struct execsw **execsw;
+
+#endif
+
+#include "mexec.h"
+
+#endif
diff --git a/sys/i386/boot/dosboot/fbsdboot.c b/sys/i386/boot/dosboot/fbsdboot.c
new file mode 100644
index 0000000..84fdb39
--- /dev/null
+++ b/sys/i386/boot/dosboot/fbsdboot.c
@@ -0,0 +1,92 @@
+/*
+ * fbsdboot.c Boot FreeBSD from DOS
+ *
+ * (C) 1994 by Christian Gusenbauer (cg@fimp01.fim.uni-linz.ac.at)
+ * 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.
+ *
+ * I ALLOW YOU USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. I DISCLAIM
+ * ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+ * USE OF THIS SOFTWARE.
+ *
+ */
+#include <dos.h>
+#include <stdio.h>
+#include <process.h>
+
+#include "reboot.h"
+#include "boot.h"
+#include "bootinfo.h"
+#include "dosboot.h"
+#include "protmod.h"
+
+#define MAV 1
+#define MIV 5
+
+#define ptr2pa(x) (((((long)(x))&0xffff0000l)>>12l)+(((long)(x))&0xffffl))
+
+static void usage(char *name)
+{
+ fprintf(stderr, "FreeBSD boot Version %d.%d\n", MAV, MIV);
+ fprintf(stderr, "(c) 1994 Christian Gusenbauer, cg@fimp01.fim.uni-linz.ac.at\n\n");
+ fprintf(stderr, "usage: %s [ options ] [ kernelname ]\n", name);
+ fprintf(stderr, "where options are:\n");
+ fprintf(stderr, "\t-r ... use compiled-in rootdev\n");
+ fprintf(stderr, "\t-s ... reboot to single user only\n");
+ fprintf(stderr, "\t-a ... ask for file name to reboot from\n");
+ fprintf(stderr, "\t-d ... give control to kernel debugger\n");
+ fprintf(stderr, "\t-c ... invoke user configuration routing\n");
+ fprintf(stderr, "\t-v ... print all potentially useful info\n");
+ fprintf(stderr, "\t-D ... boot a kernel from a DOS medium\n");
+ fprintf(stderr, "\t (default: c:\\kernel)\n");
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ char *kernel="/kernel", *ptr;
+ int i, dos=0, howto=0;
+ extern unsigned long get_diskinfo(int);
+
+ VCPIboot = 0;
+ slice = 0;
+
+ for (i = 1; i < argc; i++) { /* check arguments */
+ if (argv[i][0] != '-') { /* kernel name */
+ kernel = argv[i];
+ break;
+ }
+ ptr = &argv[i][1];
+ while (*ptr) { /* check options */
+ switch(*ptr) {
+ case 'r': howto |= RB_DFLTROOT; break;
+ case 's': howto |= RB_SINGLE; break;
+ case 'a': howto |= RB_ASKNAME; break;
+ case 'c': howto |= RB_CONFIG; break;
+ case 'd': howto |= RB_KDB; break;
+ case 'v': howto |= RB_VERBOSE; break;
+ case 'D': dos = 1; kernel = "c:\\kernel"; break;
+ case '?':
+ default: usage(argv[0]);
+ }
+ ptr++;
+ }
+ }
+
+ bootinfo.version = 1;
+ bootinfo.nfs_diskless = 0;
+ bootinfo.kernelname = (char *) ptr2pa(kernel);
+ for (i = 0; i < N_BIOS_GEOM; i++)
+ bootinfo.bios_geom[i] = get_diskinfo(0x80+i);
+
+ if (dos)
+ dosboot(howto, kernel); /* boot given kernel from DOS partition */
+ else
+ bsdboot(0x80, howto, kernel); /* boot from FreeBSD partition */
+ return 0;
+}
diff --git a/sys/i386/boot/dosboot/fbsdboot.exe.uu b/sys/i386/boot/dosboot/fbsdboot.exe.uu
new file mode 100644
index 0000000..06611d1
--- /dev/null
+++ b/sys/i386/boot/dosboot/fbsdboot.exe.uu
@@ -0,0 +1,494 @@
+begin 664 fbsdboot.exe
+M35I!`"P`DP!````,___D#P`4```>`-<!'@````$`30(``#4"```1`@``Q@``
+M`+T```"N````GP```)````"!````<@```&,```!4````10```#8````C````
+M%````"0")0"6`"4`30<E`/0&)0#J!B4`T`8E`'\&)0!U!B4`908E`!@$)0#H
+M`R4`T@,E`$D#J@#2`JH`EP*J`(\"J@!W`JH`:P*J`%$"J@`%`JH`[`&J`-L!
+MJ@"_`:H`FP&J`(H!J@!Y`:H`;P&J`%,!J@`T`:H`*@&J`!X!J@`*`:H`P@"J
+M`+@`J@",`*H`4P"J`"`$J@#L`ZH`X@.J`,X#J@"5`NP`5`+L`#$![``1!.P`
+M^P/L`-T#[`"^`^P`W`(^`:<!/@%U`3X!3P`^`<D%/@&2!3X!-04^`68$/@&U
+M`YP!E@.<`6T#G`%0`YP!+0.<`;8"G`%Z`IP!:0*<`3P"G`$@`IP!Z`&<`=<!
+MG`'-`9P!L0&<`9(!G`&(`9P!?`&<`6@!G`$?`9P!%0&<`>D`G`'4`)P!CP"<
+M`6X`G`$Y`)P!+`#7`<0`UP')`-<!T`#7`>L`UP$-`=<!+@'7`0````0L#@4$
+M5@+7`=4%UP'Z!M<![0;7`=(&UP&Q!M<!E0;7`5L'UP%`!]<!&P?7`8<'UP$]
+M"=<!#@`5!6`)UP%L"=<!C`X%!(8.!01"$`4$$PO7`3X+UP%A#-<!)`W7`:H.
+MUP&##M<!(@[7`<<-UP&M%]<!O!`%!,`0!03$$`4$R!`%!,P0!030$`4$U!`%
+M!&<9UP'C&=<!KQG7`64;UP$.&]<!.1K7`=<;UP&4']<!````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````%6+[&9H`0`%`!YH
+M0@`>:+@.FF('UP&+Y1YH7@`>:+@.FF('UP&+Y6;_=@8>:)P`'FBX#IIB!]<!
+MB^4>:,(`'FBX#IIB!]<!B^4>:-8`'FBX#IIB!]<!B^4>:/<`'FBX#IIB!]<!
+MB^4>:!L!'FBX#IIB!]<!B^4>:$4!'FBX#IIB!]<!B^4>:&X!'FBX#IIB!]<!
+MB^4>:)D!'FBX#IIB!]<!B^4>:,0!'FBX#IIB!]<!B^4>:.T!'FBX#IIB!]<!
+MB^5J`9KY`=<!R<O(%@``5U;'1O`+`HQ>\F8SP(E&[HE&]*/V>V:C:IVY`0`Y
+M3@8/CLP`BT8(BU8*!00`B]B)5OB.1O@FQ#<F@#PM#X6@`(U\`8Q&_B:`/0`/
+MA(4`B4[ZB5[VBW;T)HH%F#UV`'1<=PX\8W0^?Q@L1'0B+!UT+L1>"&8F_S<.
+MZ+?^@\0$ZT`L9'0F+`YT*/[(="KKXL=&[@$`QT;P$P*,7O+K(Y"#S@'K'9"!
+MS@`$ZQ:#SD#K$9"#SB#K"Y"#S@+K!9"!S@`(CD;^1R:`/0!UC8EV](M>]HM.
+M^H/#!$$[3@8/C%3_ZQ"+V<'C`L1V"&8FBP!FB4;P9L<&-IT!````9L<&/IT`
+M````BT;PB]"+7O*`Y@\#TA/;$](3VQ/2$]L3TA/;$]*'TX/C#P/0@],`B18Z
+MG8D>/)TS]L=&_D:=BW[^C82``%":"`#L`(/$`HD%B54"@\<$1H'_9IURY(-^
+M[@!T%6;_=O#_=O2:/`.<`8/$!C/`7E_)RV;_=O#_=O1H@`":>@.J`(/$"#/`
+M7E_)R\@$``!6BT8.B4;\BT80"T8.=0>X__]>R<N0BT;\2*,N`HM.""O2`\D3
+MT@/)$](#R1/2`\D3T@-.!H/2`#,.,`(S%C("*O8Q#C`",18R`HL.,`*+%C("
+MMI*)%C("HS8"BT8*BU8,,P8X`C,6.@(J]C$&.`(Q%CH"H3@"BQ8Z`K:2B18Z
+M`M%N_&"TAXM._+L!!([#OAX"S16(9OYABD;^*N1>R<N0R`0``%;'!E8"1P",
+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
+M%,<%_O^)?PI(B02,'XO&C-J.PHU_!ORKJT=',\"KJZNK7P?#)HM%`@O`=0DF
+MC%T")HD=ZQ0&)L1U"":,7`XFB5P,C$<2B7<0!R:,70HFB5T()HQ=!B:)703#
+M08#A_E/\BW<(BU\*,__K(XO#6Z@!=4)3BW<&BU\(.]YT-DLS_^L,D(U4_CO3
+M<^$#\'(CK:@!=/"+_D@[P7,C`_!R$XO0K:@!=-X#PH/``HOWB43^Z^2+P%N+
+M1P:)1PCYZQE;B4S^=`D#^2O!2(D%*_D#^8E_"(O&C-KXPXO1@\(G@.+PB]KW
+MV_?;]=';T>O1Z]'KM$C-(7(F.P8:#G;T.P88#G8#HQ@.CM@SVR:+10R)1P*+
+MPNC>_N@/__CK`?G#58OL'L56!K1!S2$?Z6?C```````````````!!```````
+M``````````````````````!-4R!2=6XM5&EM92!,:6)R87)Y("T@0V]P>7)I
+M9VAT("AC*2`Q.3DR+"!-:6-R;W-O9G0@0V]R<!H`1G)E94)31"!B;V]T(%9E
+M<G-I;VX@)60N)60*`"AC*2`Q.3DT($-H<FES=&EA;B!'=7-E;F)A=65R+"!C
+M9T!F:6UP,#$N9FEM+G5N:2UL:6YZ+F%C+F%T"@H`=7-A9V4Z("5S(%L@;W!T
+M:6]N<R!=(%L@:V5R;F5L;F%M92!="@!W:&5R92!O<'1I;VYS(&%R93H*``DM
+M<B`N+BX@=7-E(&-O;7!I;&5D+6EN(')O;W1D978*``DM<R`N+BX@<F5B;V]T
+M('1O('-I;F=L92!U<V5R(&]N;'D*``DM82`N+BX@87-K(&9O<B!F:6QE(&YA
+M;64@=&\@<F5B;V]T(&9R;VT*``DM9"`N+BX@9VEV92!C;VYT<F]L('1O(&ME
+M<FYE;"!D96)U9V=E<@H`"2UC("XN+B!I;G9O:V4@=7-E<B!C;VYF:6=U<F%T
+M:6]N(')O=71I;F<*``DM=B`N+BX@<')I;G0@86QL('!O=&5N=&EA;&QY('5S
+M969U;"!I;F9O"@`)+40@+BXN(&)O;W0@82!K97)N96P@9G)O;2!A($1/4R!M
+M961I=6T*``D@("`@("`@*&1E9F%U;'0Z(&,Z7&ME<FYE;"D*`"]K97)N96P`
+M8SI<:V5R;F5L````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````/__````G\\`__\```"3SP#__P```)Y``/__````DD``__\```">````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````+P``````1P``````_P<`
+M````<F(`14U-6%A86#``5D-022!S97)V:6-E<R!697)S:6]N("5D+B5D(&1E
+M=&5C=&5D(0H`0V%N)W0@<W=I=&-H('1O('!R;W1E8W1E9"!M;V1E(0H`1VEV
+M:6YG('5P(#HM*"$*`&YO="!E;F]U9V@@;65M;W)Y(0H``````$EN=F%L:60@
+M9F]R;6%T(0H`0F]O=&EN9R!`(#!X)6QX"@!K97)N96P@;&EN:V5D(&9O<B!W
+M<F]N9R!A9&1R97-S(0H`3VYL>2!H;W!E(&ES('1O(&QI;FL@=&AE(&ME<FYE
+M;"!F;W(@/B`Q34(*`%-O<G)Y+"!C86XG="!A;&QO8V%T92!E;F]U9V@@;65M
+M;W)Y(0H`=&5X=#TP>"5L>"````!D871A/3!X)6QX(`!B<W,],'@E;'@@`'1O
+M=&%L/3!X)6QX(``*"DEN<V5R="!F:6QE('-Y<W1E;2!F;&]P<'D@:6X@9')I
+M=F4@02!O<B!""@!0<F5S<R`G02<L("=")R!O<B!A;GD@;W1H97(@:V5Y(&9O
+M<B!T:&4@9&5F875L="``)6,Z(``*`&5N=')Y('!O:6YT/3!X)6QX"@!#86XG
+M="!F:6YD("5S"@!B860@9&ES:VQA8F5L`$)A9"!B861S96-T('1A8FQE"@!5
+M<VEN9R!B860Q-#0@8F%D('-E8W1O<B!A="`E;&0*`$5R<F]R.B!#.B5D($@Z
+M)60@4SHE9`H```````````!);G9A;&ED(&9O<FUA="$*`$)O;W1I;F<@0"`P
+M>"5L>`H`:V5R;F5L(&QI;FME9"!F;W(@=W)O;F<@861D<F5S<R$*`$]N;'D@
+M:&]P92!I<R!T;R!L:6YK('1H92!K97)N96P@9F]R(#X@,4U""@!3;W)R>2P@
+M8V%N)W0@86QL;V-A=&4@96YO=6=H(&UE;6]R>2$*`'1E>'0],'@E;'@@````
+M9&%T83TP>"5L>"``8G-S/3!X)6QX(`!T;W1A;#TP>"5L>"``96YT<GD@<&]I
+M;G0],'@E;'@*`')B`%-O<G)Y+"!C86XG="!O<&5N("5S(0H``````@`````%
+M``````````````````````````````!?0U]&24Q%7TE.1D\]````````````
+M`````````````````````````````!0`@8&!`0$`````````````````````
+M````````````;@X!!```````````````````_____S"_```````6`@(8#0D,
+M#`P'"!86_P(-$@+_7`!<``````````````````$```````````````(!````
+M``````````("M0\!!```M0\!!(0#``````````````($````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````!````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````A`\!!`````````````````8```8``0``$``#!@`&`A`$145%!04%!04U
+M,`!0`````"`@,%!8!P@`,#`P5U`'```@(```````"&!@8&!@8```<'!X>'AX
+M"`<(```'``@("```"``(```(*&YU;&PI!@```````````"#.`M<!S@+7`<X"
+MUP'.`M<!S@+7`<X"UP'.`M<!``````$!__\``````````````````````P``
+M````\@#R`/(`````````````````````````6@G7`3P\3DU31SX^``!2-C`P
+M,`T*+2!S=&%C:R!O=F5R9FQO=PT*``,`4C8P,#,-"BT@:6YT96=E<B!D:79I
+M9&4@8GD@,`T*``D`4C8P,#D-"BT@;F]T(&5N;W5G:"!S<&%C92!F;W(@96YV
+M:7)O;FUE;G0-"@#\``T*`/\`<G5N+71I;64@97)R;W(@``(`4C8P,#(-"BT@
+M9FQO871I;F<M<&]I;G0@<W5P<&]R="!N;W0@;&]A9&5D#0H``0!2-C`P,0T*
+?+2!N=6QL('!O:6YT97(@87-S:6=N;65N=`T*`/___V5D
+`
+end
diff --git a/sys/i386/boot/dosboot/fbsdboot.mak b/sys/i386/boot/dosboot/fbsdboot.mak
new file mode 100644
index 0000000..06f8bed
--- /dev/null
+++ b/sys/i386/boot/dosboot/fbsdboot.mak
@@ -0,0 +1,177 @@
+# Microsoft Visual C++ generated build script - Do not modify
+
+PROJ = FBSDBOOT
+DEBUG = 0
+PROGTYPE = 6
+CALLER =
+ARGS =
+DLLS =
+D_RCDEFINES = -d_DEBUG
+R_RCDEFINES = -dNDEBUG
+ORIGIN = MSVC
+ORIGIN_VER = 1.00
+PROJPATH = C:\SRC\FBSDBOOT\
+USEMFC = 0
+CC = cl
+CPP = cl
+CXX = cl
+CCREATEPCHFLAG =
+CPPCREATEPCHFLAG =
+CUSEPCHFLAG =
+CPPUSEPCHFLAG =
+FIRSTC = FBSDBOOT.C
+FIRSTCPP =
+RC = rc
+CFLAGS_D_DEXE = /nologo /Gs /G3 /Zp1 /W3 /Zi /AL /Oi /D "_DEBUG" /D "i386" /D "_DOS" /D "__i386__" /D "DO_BAD144" /Fc /Fd"FBSDBOOT.PDB"
+CFLAGS_R_DEXE = /nologo /Gs /G3 /Zp1 /W3 /AL /Ox /D "NDEBUG" /D "i386" /D "_DOS" /D "__i386__" /D "DO_BAD144"
+LFLAGS_D_DEXE = /NOLOGO /NOI /STACK:6000 /ONERROR:NOEXE /CO /MAP /LINE
+LFLAGS_R_DEXE = /NOLOGO /NOI /STACK:5120 /ONERROR:NOEXE
+LIBS_D_DEXE = oldnames llibce
+LIBS_R_DEXE = oldnames llibce
+RCFLAGS = /nologo
+RESFLAGS = /nologo
+RUNFLAGS =
+OBJS_EXT =
+LIBS_EXT =
+!if "$(DEBUG)" == "1"
+CFLAGS = $(CFLAGS_D_DEXE)
+LFLAGS = $(LFLAGS_D_DEXE)
+LIBS = $(LIBS_D_DEXE)
+MAPFILE = nul
+RCDEFINES = $(D_RCDEFINES)
+!else
+CFLAGS = $(CFLAGS_R_DEXE)
+LFLAGS = $(LFLAGS_R_DEXE)
+LIBS = $(LIBS_R_DEXE)
+MAPFILE = nul
+RCDEFINES = $(R_RCDEFINES)
+!endif
+!if [if exist MSVC.BND del MSVC.BND]
+!endif
+SBRS = FBSDBOOT.SBR \
+ PROTMOD.SBR \
+ BOOT.SBR \
+ DISK.SBR \
+ SYS.SBR \
+ DOSBOOT.SBR
+
+
+FBSDBOOT_DEP = c:\src\fbsdboot\reboot.h \
+ c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\dosboot.h
+
+
+PROTMOD_DEP = c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\protmod.h
+
+
+BOOT_DEP = c:\src\fbsdboot\protmod.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\reboot.h \
+ c:\src\fbsdboot\exec.h
+
+
+DISK_DEP = c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\disklabe.h
+
+
+SYS_DEP = c:\src\fbsdboot\protmod.h \
+ c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\dir.h \
+ c:\src\fbsdboot\dirent.h
+
+
+DOSBOOT_DEP = c:\src\fbsdboot\protmod.h \
+ c:\src\fbsdboot\param.h \
+ c:\src\fbsdboot\syslimit.h \
+ c:\src\fbsdboot\boot.h \
+ c:\src\fbsdboot\quota.h \
+ c:\src\fbsdboot\cdefs.h \
+ c:\src\fbsdboot\fs.h \
+ c:\src\fbsdboot\inode.h \
+ c:\src\fbsdboot\dinode.h \
+ c:\src\fbsdboot\reboot.h \
+ c:\src\fbsdboot\exec.h
+
+
+all: $(PROJ).EXE
+
+FBSDBOOT.OBJ: FBSDBOOT.C $(FBSDBOOT_DEP)
+ $(CC) $(CFLAGS) $(CCREATEPCHFLAG) /c FBSDBOOT.C
+
+PROTMOD.OBJ: PROTMOD.C $(PROTMOD_DEP)
+ $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c PROTMOD.C
+
+BOOT.OBJ: BOOT.C $(BOOT_DEP)
+ $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c BOOT.C
+
+DISK.OBJ: DISK.C $(DISK_DEP)
+ $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DISK.C
+
+SYS.OBJ: SYS.C $(SYS_DEP)
+ $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c SYS.C
+
+DOSBOOT.OBJ: DOSBOOT.C $(DOSBOOT_DEP)
+ $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DOSBOOT.C
+
+$(PROJ).EXE:: FBSDBOOT.OBJ PROTMOD.OBJ BOOT.OBJ DISK.OBJ SYS.OBJ DOSBOOT.OBJ $(OBJS_EXT) $(DEFFILE)
+ echo >NUL @<<$(PROJ).CRF
+FBSDBOOT.OBJ +
+PROTMOD.OBJ +
+BOOT.OBJ +
+DISK.OBJ +
+SYS.OBJ +
+DOSBOOT.OBJ +
+$(OBJS_EXT)
+$(PROJ).EXE
+$(MAPFILE)
+c:\msvc\lib\+
+c:\msvc\mfc\lib\+
+$(LIBS)
+$(DEFFILE);
+<<
+ link $(LFLAGS) @$(PROJ).CRF
+
+run: $(PROJ).EXE
+ $(PROJ) $(RUNFLAGS)
+
+
+$(PROJ).BSC: $(SBRS)
+ bscmake @<<
+/o$@ $(SBRS)
+<<
diff --git a/sys/i386/boot/dosboot/fs.h b/sys/i386/boot/dosboot/fs.h
new file mode 100644
index 0000000..68ccd98
--- /dev/null
+++ b/sys/i386/boot/dosboot/fs.h
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)fs.h 7.12 (Berkeley) 5/8/91
+ * $Id: fs.h,v 1.6 1993/12/19 22:51:09 alm Exp $
+ */
+
+#ifndef _UFS_FS_H_
+#define _UFS_FS_H_ 1
+
+#define MAXFRAG 8
+
+/*
+ * 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 ((daddr_t)(0))
+#define SBLOCK ((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
+ * addressible; 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.
+ *
+ * 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)
+
+/*
+ * 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.
+ * The limit on the amount of summary information per file system
+ * is defined by MAXCSBUFS. It is currently parameterized for a
+ * maximum of two million cylinders.
+ */
+#define MAXMNTLEN 512
+#define MAXCSBUFS 32
+
+/*
+ * 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.
+ *
+ * N.B. sizeof(struct csum) must be a power of two in order for
+ * the ``fs_cs'' macro to work (see below).
+ */
+struct csum {
+ long cs_ndir; /* number of directories */
+ long cs_nbfree; /* number of free blocks */
+ long cs_nifree; /* number of free inodes */
+ long cs_nffree; /* number of free frags */
+};
+
+/*
+ * Super block for a file system.
+ */
+#define FS_MAGIC 0x011954
+#define FSOKAY 0x7c269d38
+struct fs
+{
+ struct fs *fs_link; /* linked list of file systems */
+ struct fs *fs_rlink; /* used for incore super blocks */
+ daddr_t fs_sblkno; /* addr of super-block in filesys */
+ daddr_t fs_cblkno; /* offset of cyl-block in filesys */
+ daddr_t fs_iblkno; /* offset of inode-blocks in filesys */
+ daddr_t fs_dblkno; /* offset of first data after cg */
+ long fs_cgoffset; /* cylinder group offset in cylinder */
+ long fs_cgmask; /* used to calc mod fs_ntrak */
+ time_t fs_time; /* last time written */
+ long fs_size; /* number of blocks in fs */
+ long fs_dsize; /* number of data blocks in fs */
+ long fs_ncg; /* number of cylinder groups */
+ long fs_bsize; /* size of basic blocks in fs */
+ long fs_fsize; /* size of frag blocks in fs */
+ long fs_frag; /* number of frags in a block in fs */
+/* these are configuration parameters */
+ long fs_minfree; /* minimum percentage of free blocks */
+ long fs_rotdelay; /* num of ms for optimal next block */
+ long fs_rps; /* disk revolutions per second */
+/* these fields can be computed from the others */
+ long fs_bmask; /* ``blkoff'' calc of blk offsets */
+ long fs_fmask; /* ``fragoff'' calc of frag offsets */
+ long fs_bshift; /* ``lblkno'' calc of logical blkno */
+ long fs_fshift; /* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+ long fs_maxcontig; /* max number of contiguous blks */
+ long fs_maxbpg; /* max number of blks per cyl group */
+/* these fields can be computed from the others */
+ long fs_fragshift; /* block to frag shift */
+ long fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
+ long fs_sbsize; /* actual size of super block */
+ long fs_csmask; /* csum block offset */
+ long fs_csshift; /* csum block number */
+ long fs_nindir; /* value of NINDIR */
+ long fs_inopb; /* value of INOPB */
+ long fs_nspf; /* value of NSPF */
+/* yet another configuration parameter */
+ long fs_optim; /* optimization preference, see below */
+/* these fields are derived from the hardware */
+ long fs_npsect; /* # sectors/track including spares */
+ long fs_interleave; /* hardware sector interleave */
+ long fs_trackskew; /* sector 0 skew, per track */
+ long fs_headswitch; /* head switch time, usec */
+ long fs_trkseek; /* track-to-track seek, usec */
+/* sizes determined by number of cylinder groups and their sizes */
+ daddr_t fs_csaddr; /* blk addr of cyl grp summary area */
+ long fs_cssize; /* size of cyl grp summary area */
+ long fs_cgsize; /* cylinder group size */
+/* these fields are derived from the hardware */
+ long fs_ntrak; /* tracks per cylinder */
+ long fs_nsect; /* sectors per track */
+ long fs_spc; /* sectors per cylinder */
+/* this comes from the disk driver partitioning */
+ long fs_ncyl; /* cylinders in file system */
+/* these fields can be computed from the others */
+ long fs_cpg; /* cylinders per group */
+ long fs_ipg; /* inodes per group */
+ long 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 */
+ char fs_fmod; /* super block modified flag */
+ char fs_clean; /* file system is clean flag */
+ char fs_ronly; /* mounted read-only flag */
+ char fs_flags; /* currently unused flag */
+ char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
+/* these fields retain the current block allocation info */
+ long fs_cgrotor; /* last cg searched */
+ struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
+ long fs_cpc; /* cyl per cycle in postbl */
+ short fs_opostbl[16][8]; /* old rotation block list head */
+ long fs_sparecon[55]; /* reserved for future constants */
+ long fs_state; /* validate fs_clean field */
+ union {
+/* quad_t v;*/
+ long val[2];
+ } fs_qbmask; /* ~fs_bmask - for use with quad size */
+ union {
+/* quad_t v;*/
+ long val[2];
+ } fs_qfmask; /* ~fs_fmask - for use with quad size */
+ long fs_postblformat; /* format of positional layout tables */
+ long fs_nrpos; /* number of rotaional positions */
+ long fs_postbloff; /* (short) rotation block list head */
+ long fs_rotbloff; /* (u_char) blocks for each rotation */
+ long fs_magic; /* magic number */
+ u_char fs_space[1]; /* list of blocks for each rotation */
+/* actually longer */
+};
+/*
+ * Preference for optimization.
+ */
+#define FS_OPTTIME 0 /* minimize allocation time */
+#define FS_OPTSPACE 1 /* minimize disk fragmentation */
+
+/*
+ * 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]) \
+ : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
+#define fs_rotbl(fs) \
+ (((fs)->fs_postblformat == FS_42POSTBLFMT) \
+ ? ((fs)->fs_space) \
+ : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
+
+/*
+ * Convert cylinder group to base address of its global summary info.
+ *
+ * N.B. This macro assumes that sizeof(struct csum) is a power of two.
+ */
+#define fs_cs(fs, indx) \
+ fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
+
+/*
+ * Cylinder group block for a file system.
+ */
+#define CG_MAGIC 0x090255
+struct cg {
+ struct cg *cg_link; /* linked list of cyl groups */
+ long cg_magic; /* magic number */
+ time_t cg_time; /* time last written */
+ long cg_cgx; /* we are the cgx'th cylinder group */
+ short cg_ncyl; /* number of cyl's this cg */
+ short cg_niblk; /* number of inode blocks this cg */
+ long cg_ndblk; /* number of data blocks this cg */
+ struct csum cg_cs; /* cylinder summary information */
+ long cg_rotor; /* position of last used block */
+ long cg_frotor; /* position of last used frag */
+ long cg_irotor; /* position of last used inode */
+ long cg_frsum[MAXFRAG]; /* counts of available frags */
+ long cg_btotoff; /* (long) block totals per cylinder */
+ long cg_boff; /* (short) free block positions */
+ long cg_iusedoff; /* (char) used inode map */
+ long cg_freeoff; /* (u_char) free block map */
+ long cg_nextfreeoff; /* (u_char) next available space */
+ long cg_sparecon[16]; /* reserved for future use */
+ u_char 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) \
+ : ((long *)((char *)(cgp) + (cgp)->cg_btotoff)))
+#define cg_blks(fs, cgp, cylno) \
+ (((cgp)->cg_magic != CG_MAGIC) \
+ ? (((struct ocg *)(cgp))->cg_b[cylno]) \
+ : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
+#define cg_inosused(cgp) \
+ (((cgp)->cg_magic != CG_MAGIC) \
+ ? (((struct ocg *)(cgp))->cg_iused) \
+ : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
+#define cg_blksfree(cgp) \
+ (((cgp)->cg_magic != CG_MAGIC) \
+ ? (((struct ocg *)(cgp))->cg_free) \
+ : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
+#define cg_chkmagic(cgp) \
+ ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
+
+/*
+ * The following structure is defined
+ * for compatibility with old file systems.
+ */
+struct ocg {
+ struct ocg *cg_link; /* linked list of cyl groups */
+ struct ocg *cg_rlink; /* used for incore cyl groups */
+ time_t cg_time; /* time last written */
+ long cg_cgx; /* we are the cgx'th cylinder group */
+ short cg_ncyl; /* number of cyl's this cg */
+ short cg_niblk; /* number of inode blocks this cg */
+ long cg_ndblk; /* number of data blocks this cg */
+ struct csum cg_cs; /* cylinder summary information */
+ long cg_rotor; /* position of last used block */
+ long cg_frotor; /* position of last used frag */
+ long cg_irotor; /* position of last used inode */
+ long cg_frsum[8]; /* counts of available frags */
+ long cg_btot[32]; /* block totals per cylinder */
+ short cg_b[32][8]; /* positions of free blocks */
+ char cg_iused[256]; /* used inode map */
+ long cg_magic; /* magic number */
+ u_char 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) ((daddr_t)((fs)->fs_fpg * (c)))
+#define cgstart(fs, c) \
+ (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
+#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 cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode blk */
+#define cgdmin(fs, c) (cgstart(fs, c) + (fs)->fs_dblkno) /* 1st data */
+
+/*
+ * 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 itoo(fs, x) ((x) % INOPB(fs))
+#define itog(fs, x) ((x) / (fs)->fs_ipg)
+#define itod(fs, x) \
+ ((daddr_t)(cgimin(fs, itog(fs, x)) + \
+ (blkstofrags((fs), (((x) % (fs)->fs_ipg) / 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_bmask)
+#define fragoff(fs, loc) /* calculates (loc % fs->fs_fsize) */ \
+ ((loc) & ~(fs)->fs_fmask)
+#define lblktosize(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_bsize - 1) & (fs)->fs_bmask)
+#define fragroundup(fs, size) /* calculates roundup(size, fs->fs_fsize) */ \
+ (((size) + (fs)->fs_fsize - 1) & (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 - ((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 >= ((lbn) + 1) << (fs)->fs_bshift) \
+ ? (fs)->fs_bsize \
+ : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define dblksize(fs, dip, lbn) \
+ (((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
+ ? (fs)->fs_bsize \
+ : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
+
+/*
+ * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
+ */
+#define NSPB(fs) ((fs)->fs_nspf << (fs)->fs_fragshift)
+#define NSPF(fs) ((fs)->fs_nspf)
+
+/*
+ * INOPB is the number of inodes in a secondary storage block.
+ */
+#define INOPB(fs) ((fs)->fs_inopb)
+#define INOPF(fs) ((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * NINDIR is the number of indirects in a file system block.
+ */
+#define NINDIR(fs) ((fs)->fs_nindir)
+
+#ifdef KERNEL
+
+extern void fserr(struct fs *, int /*uid_t*/, const char *);
+extern void fragacct(struct fs *, int, long *, int);
+extern int isblock(struct fs *, u_char *, daddr_t);
+extern void clrblock(struct fs *, u_char *, daddr_t);
+extern void setblock(struct fs *, u_char *, daddr_t);
+extern ino_t dirpref(struct fs *);
+extern daddr_t mapsearch(struct fs *, struct cg *, daddr_t, int);
+
+#endif /* KERNEL */
+#endif /* _UFS_FS_H_ */
diff --git a/sys/i386/boot/dosboot/imgact.h b/sys/i386/boot/dosboot/imgact.h
new file mode 100644
index 0000000..dde841e
--- /dev/null
+++ b/sys/i386/boot/dosboot/imgact.h
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)exec.h 8.1 (Berkeley) 6/11/93
+ * $Id: imgact_aout.h,v 1.1 1994/09/24 21:09:18 davidg Exp $
+ */
+
+#ifndef _IMGACT_AOUT_H_
+#define _IMGACT_AOUT_H_
+
+#define N_GETMAGIC(ex) \
+ ( (ex).a_midmag & 0xffff )
+#define N_GETMID(ex) \
+ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \
+ ((ex).a_midmag >> 16) & 0x03ff )
+#define N_GETFLAG(ex) \
+ ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \
+ ((ex).a_midmag >> 26) & 0x3f )
+#define N_SETMAGIC(ex,mag,mid,flag) \
+ ( (ex).a_midmag = (((flag) & 0x3f) <<26) | (((mid) & 0x03ff) << 16) | \
+ ((mag) & 0xffff) )
+
+#define N_GETMAGIC_NET(ex) \
+ (ntohl((ex).a_midmag) & 0xffff)
+#define N_GETMID_NET(ex) \
+ ((ntohl((ex).a_midmag) >> 16) & 0x03ff)
+#define N_GETFLAG_NET(ex) \
+ ((ntohl((ex).a_midmag) >> 26) & 0x3f)
+#define N_SETMAGIC_NET(ex,mag,mid,flag) \
+ ( (ex).a_midmag = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \
+ (((mag)&0xffff)) ) )
+
+#define N_ALIGN(ex,x) \
+ (N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC || \
+ N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \
+ ((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define N_BADMAG(ex) \
+ (N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \
+ N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC /*&& \
+ N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \
+ N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC*/)
+
+
+/* Address of the bottom of the text segment. */
+#define N_TXTADDR(ex) \
+ ((N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC || \
+ N_GETMAGIC(ex) == ZMAGIC) ? 0 : __LDPGSZ)
+
+/* Address of the bottom of the data segment. */
+#define N_DATADDR(ex) \
+ N_ALIGN(ex, N_TXTADDR(ex) + (ex).a_text)
+
+/* Text segment offset. */
+#define N_TXTOFF(ex) \
+ (N_GETMAGIC(ex) == ZMAGIC ? __LDPGSZ : (N_GETMAGIC(ex) == QMAGIC /*|| \
+ N_GETMAGIC_NET(ex) == ZMAGIC*/) ? 0 : sizeof(struct exec))
+
+/* Data segment offset. */
+#define N_DATOFF(ex) \
+ N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text)
+
+/* Relocation table offset. */
+#define N_RELOFF(ex) \
+ N_ALIGN(ex, N_DATOFF(ex) + (ex).a_data)
+
+/* Symbol table offset. */
+#define N_SYMOFF(ex) \
+ (N_RELOFF(ex) + (ex).a_trsize + (ex).a_drsize)
+
+/* String table offset. */
+#define N_STROFF(ex) (N_SYMOFF(ex) + (ex).a_syms)
+
+/*
+ * Header prepended to each a.out file.
+ * only manipulate the a_midmag field via the
+ * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros in a.out.h
+ */
+
+struct exec {
+ unsigned long a_midmag; /* htonl(flags<<26 | mid<<16 | magic) */
+ unsigned long a_text; /* text segment size */
+ unsigned long a_data; /* initialized data size */
+ unsigned long a_bss; /* uninitialized data size */
+ unsigned long a_syms; /* symbol table size */
+ unsigned long a_entry; /* entry point */
+ unsigned long a_trsize; /* text relocation size */
+ unsigned long a_drsize; /* data relocation size */
+};
+#define a_magic a_midmag /* XXX Hack to work with current kern_execve.c */
+
+/* a_magic */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+#define QMAGIC 0314 /* "compact" demand load format */
+
+/* a_mid */
+#define MID_ZERO 0 /* unknown - implementation dependent */
+#define MID_SUN010 1 /* sun 68010/68020 binary */
+#define MID_SUN020 2 /* sun 68020-only binary */
+#define MID_I386 134 /* i386 BSD binary */
+#define MID_SPARC 138 /* sparc */
+#define MID_HP200 200 /* hp200 (68010) BSD binary */
+#define MID_HP300 300 /* hp300 (68020+68881) BSD binary */
+#define MID_HPUX 0x20C /* hp200/300 HP-UX binary */
+#define MID_HPUX800 0x20B /* hp800 HP-UX binary */
+
+/*
+ * a_flags
+ */
+#define EX_PIC 0x10 /* contains position independant code */
+#define EX_DYNAMIC 0x20 /* contains run-time link-edit info */
+#define EX_DPMASK 0x30 /* mask for the above */
+
+#endif /* !_IMGACT_AOUT_H_ */
diff --git a/sys/i386/boot/dosboot/inode.h b/sys/i386/boot/dosboot/inode.h
new file mode 100644
index 0000000..9f9310b
--- /dev/null
+++ b/sys/i386/boot/dosboot/inode.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1982, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)inode.h 7.17 (Berkeley) 5/8/91
+ * $Id: inode.h,v 1.6 1993/12/19 00:55:37 wollman Exp $
+ */
+
+#ifndef _UFS_INODE_H_
+#define _UFS_INODE_H_ 1
+
+#ifdef KERNEL
+include "../ufs/dinode.h"
+#else
+#include "dinode.h"
+#endif
+
+/*
+ * 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
+ * permannent 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 inode *i_chain[2]; /* hash chain, MUST be first */
+ struct vnode *i_vnode; /* vnode associated with this inode */
+ struct vnode *i_devvp; /* vnode for block I/O */
+ u_long i_flag; /* see below */
+ dev_t i_dev; /* device where inode resides */
+ ino_t i_number; /* the identity of the inode */
+ struct fs *i_fs; /* filesystem associated with this inode */
+ struct dquot *i_dquot[MAXQUOTAS]; /* pointer to dquot structures */
+ struct lockf *i_lockf; /* head of byte-level lock list */
+ long i_diroff; /* offset in dir, where we found last entry */
+ off_t i_endoff; /* end of useful stuff in directory */
+ long i_spare0;
+ long i_spare1;
+ struct dinode i_din; /* the on-disk dinode */
+};
+
+#define FASTLINK(ip) (DFASTLINK((ip)->i_din))
+#define i_symlink i_din.di_symlink
+#define i_mode i_din.di_mode
+#define i_nlink i_din.di_nlink
+#define i_uid i_din.di_uid
+#define i_gid i_din.di_gid
+#if BYTE_ORDER == LITTLE_ENDIAN || defined(tahoe) /* ugh! -- must be fixed */
+#define i_size i_din.di_qsize.val[0]
+#else /* BYTE_ORDER == BIG_ENDIAN */
+#define i_size i_din.di_qsize.val[1]
+#endif
+#define i_db i_din.di_db
+#define i_ib i_din.di_ib
+#define i_atime i_din.di_atime
+#define i_mtime i_din.di_mtime
+#define i_ctime i_din.di_ctime
+#define i_blocks i_din.di_blocks
+#define i_rdev i_din.di_db[0]
+#define i_flags i_din.di_flags
+#define i_gen i_din.di_gen
+#define i_forw i_chain[0]
+#define i_back i_chain[1]
+#define i_di_spare i_din.di_spare
+
+/* flags */
+#define ILOCKED 0x0001 /* inode is locked */
+#define IWANT 0x0002 /* some process waiting on lock */
+#define IRENAME 0x0004 /* inode is being renamed */
+#define IUPD 0x0010 /* file has been modified */
+#define IACC 0x0020 /* inode access time to be updated */
+#define ICHG 0x0040 /* inode has been changed */
+#define IMOD 0x0080 /* inode has been modified */
+#define ISHLOCK 0x0100 /* file has shared lock */
+#define IEXLOCK 0x0200 /* file has exclusive lock */
+#define ILWAIT 0x0400 /* someone waiting on file lock */
+
+#ifdef KERNEL
+/*
+ * Convert between inode pointers and vnode pointers
+ */
+#define VTOI(vp) ((struct inode *)(vp)->v_data)
+#define ITOV(ip) ((ip)->i_vnode)
+
+/*
+ * Convert between vnode types and inode formats
+ */
+extern enum vtype iftovt_tab[];
+extern int vttoif_tab[];
+#define IFTOVT(mode) (iftovt_tab[((mode) & IFMT) >> 12])
+#define VTTOIF(indx) (vttoif_tab[(int)(indx)])
+
+#define MAKEIMODE(indx, mode) (int)(VTTOIF(indx) | (mode))
+
+extern u_long nextgennumber; /* next generation number to assign */
+
+extern ino_t dirpref();
+
+/*
+ * Lock and unlock inodes.
+ */
+#ifdef notdef
+#define ILOCK(ip) { \
+ while ((ip)->i_flag & ILOCKED) { \
+ (ip)->i_flag |= IWANT; \
+ (void) sleep((caddr_t)(ip), PINOD); \
+ } \
+ (ip)->i_flag |= ILOCKED; \
+}
+
+#define IUNLOCK(ip) { \
+ (ip)->i_flag &= ~ILOCKED; \
+ if ((ip)->i_flag&IWANT) { \
+ (ip)->i_flag &= ~IWANT; \
+ wakeup((caddr_t)(ip)); \
+ } \
+}
+#else
+#define ILOCK(ip) ilock(ip)
+#define IUNLOCK(ip) iunlock(ip)
+#endif
+
+#define IUPDAT(ip, t1, t2, waitfor) { \
+ if (ip->i_flag&(IUPD|IACC|ICHG|IMOD)) \
+ (void) iupdat(ip, t1, t2, waitfor); \
+}
+
+#define ITIMES(ip, t1, t2) { \
+ if ((ip)->i_flag&(IUPD|IACC|ICHG)) { \
+ (ip)->i_flag |= IMOD; \
+ if ((ip)->i_flag&IACC) \
+ (ip)->i_atime = (t1)->tv_sec; \
+ if ((ip)->i_flag&IUPD) \
+ (ip)->i_mtime = (t2)->tv_sec; \
+ if ((ip)->i_flag&ICHG) \
+ (ip)->i_ctime = time.tv_sec; \
+ (ip)->i_flag &= ~(IACC|IUPD|ICHG); \
+ } \
+}
+
+/*
+ * This overlays the fid sturcture (see mount.h)
+ */
+struct ufid {
+ u_short ufid_len; /* length of structure */
+ u_short ufid_pad; /* force long alignment */
+ ino_t ufid_ino; /* file number (ino) */
+ long ufid_gen; /* generation number */
+};
+
+/*
+ * Prototypes for UFS vnode operations
+ */
+int ufs_lookup __P((struct vnode *vp, struct nameidata *ndp, struct proc *p));
+int ufs_create __P((struct nameidata *ndp, struct vattr *vap, struct proc *p));
+int ufs_mknod __P((struct nameidata *ndp, struct vattr *vap, struct ucred *cred,
+ struct proc *p));
+int ufs_open __P((struct vnode *vp, int mode, struct ucred *cred,
+ struct proc *p));
+int ufs_close __P((struct vnode *vp, int fflag, struct ucred *cred,
+ struct proc *p));
+int ufs_access __P((struct vnode *vp, int mode, struct ucred *cred,
+ struct proc *p));
+int ufs_getattr __P((struct vnode *vp, struct vattr *vap, struct ucred *cred,
+ struct proc *p));
+int ufs_setattr __P((struct vnode *vp, struct vattr *vap, struct ucred *cred,
+ struct proc *p));
+int ufs_read __P((struct vnode *vp, struct uio *uio, int ioflag,
+ struct ucred *cred));
+int ufs_write __P((struct vnode *vp, struct uio *uio, int ioflag,
+ struct ucred *cred));
+int ufs_ioctl __P((struct vnode *vp, int command, caddr_t data, int fflag,
+ struct ucred *cred, struct proc *p));
+int ufs_select __P((struct vnode *vp, int which, int fflags, struct ucred *cred,
+ struct proc *p));
+int ufs_mmap __P((struct vnode *vp, int fflags, struct ucred *cred,
+ struct proc *p));
+int ufs_fsync __P((struct vnode *vp, int fflags, struct ucred *cred,
+ int waitfor, struct proc *p));
+int ufs_seek __P((struct vnode *vp, off_t oldoff, off_t newoff,
+ struct ucred *cred));
+int ufs_remove __P((struct nameidata *ndp, struct proc *p));
+int ufs_link __P((struct vnode *vp, struct nameidata *ndp, struct proc *p));
+int ufs_rename __P((struct nameidata *fndp, struct nameidata *tdnp,
+ struct proc *p));
+int ufs_mkdir __P((struct nameidata *ndp, struct vattr *vap, struct proc *p));
+int ufs_rmdir __P((struct nameidata *ndp, struct proc *p));
+int ufs_symlink __P((struct nameidata *ndp, struct vattr *vap, char *target,
+ struct proc *p));
+int ufs_readdir __P((struct vnode *vp, struct uio *uio, struct ucred *cred,
+ int *eofflagp));
+int ufs_readlink __P((struct vnode *vp, struct uio *uio, struct ucred *cred));
+int ufs_abortop __P((struct nameidata *ndp));
+int ufs_inactive __P((struct vnode *vp, struct proc *p));
+int ufs_reclaim __P((struct vnode *vp));
+int ufs_lock __P((struct vnode *vp));
+int ufs_unlock __P((struct vnode *vp));
+int ufs_bmap __P((struct vnode *vp, daddr_t bn, struct vnode **vpp,
+ daddr_t *bnp));
+int ufs_strategy __P((struct buf *bp));
+void ufs_print __P((struct vnode *vp));
+int ufs_islocked __P((struct vnode *vp));
+int ufs_advlock __P((struct vnode *vp, caddr_t id, int op, struct flock *fl,
+ int flags));
+
+extern void blkfree(struct inode *, daddr_t, off_t);
+extern void ifree(struct inode *, ino_t, int);
+extern void iput(struct inode *);
+extern void ilock(struct inode *);
+extern void iunlock(struct inode *);
+extern void dirbad(struct inode *, off_t, char *);
+
+extern int alloc(struct inode *, daddr_t, daddr_t, int, daddr_t *);
+extern int realloccg(struct inode *, off_t, daddr_t, int, int, struct buf **);
+extern int ialloc(struct inode *, ino_t, int, struct ucred *, struct inode **);
+extern daddr_t blkpref(struct inode *, daddr_t, int, daddr_t *);
+extern u_long hashalloc(struct inode *, int, long, int,
+ u_long (*)(struct inode *, int, long, int));
+extern daddr_t fragextend(struct inode *, int, long, int, int);
+extern daddr_t alloccg(struct inode *, int, daddr_t, int);
+
+struct cg; /* I really don't want to know why */
+struct direct; /* this header is required by NFS... */
+
+extern daddr_t alloccgblk(struct fs *, struct cg *, daddr_t);
+extern ino_t ialloccg(struct inode *, int, daddr_t, int);
+extern int ufs_lookup(struct vnode *, struct nameidata *, struct proc *);
+extern int dirbadentry(struct direct *, int);
+extern int direnter(struct inode *, struct nameidata *);
+extern int dirremove(struct nameidata *);
+extern int dirrewrite(struct inode *, struct inode *, struct nameidata *);
+extern int blkatoff(struct inode *, off_t, char **, struct buf **);
+extern int dirempty(struct inode *, ino_t, struct ucred *);
+extern int checkpath(struct inode *, struct inode *, struct ucred *);
+
+extern void ufs_init(void);
+extern int iget(struct inode *, ino_t, struct inode **);
+extern int ufs_inactive(struct vnode *, struct proc *);
+extern int ufs_reclaim(struct vnode *);
+extern int iupdat(struct inode *, struct timeval *, struct timeval *,
+ int);
+extern int itrunc(struct inode *, u_long, int);
+extern int indirtrunc(struct inode *, daddr_t, daddr_t, int, long *);
+
+extern int bmap(struct inode *, daddr_t, daddr_t *);
+extern int balloc(struct inode *, daddr_t, int, struct buf **, int);
+
+#endif /* KERNEL */
+#endif /* _UFS_INODE_H_ */
diff --git a/sys/i386/boot/dosboot/mexec.h b/sys/i386/boot/dosboot/mexec.h
new file mode 100644
index 0000000..dbaf8f2
--- /dev/null
+++ b/sys/i386/boot/dosboot/mexec.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)exec.h 8.1 (Berkeley) 6/11/93
+ * $Id: exec.h,v 1.5 1994/09/24 21:36:38 davidg Exp $
+ */
+
+#ifndef _EXEC_H_
+#define _EXEC_H_
+
+#define __LDPGSZ 4096
+
+#include "imgact.h"
+
+#endif /* !_EXEC_H_ */
diff --git a/sys/i386/boot/dosboot/param.h b/sys/i386/boot/dosboot/param.h
new file mode 100644
index 0000000..67882bf
--- /dev/null
+++ b/sys/i386/boot/dosboot/param.h
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)param.h 5.8 (Berkeley) 6/28/91
+ * $Id: param.h,v 1.16 1994/09/18 22:05:22 bde Exp $
+ */
+
+#ifndef _MACHINE_PARAM_H_
+#define _MACHINE_PARAM_H_
+
+/*
+ * Machine dependent constants for Intel 386.
+ */
+
+#define MACHINE "i386"
+#define MID_MACHINE MID_I386
+
+/*
+ * Round p (pointer or byte index) up to a correctly-aligned value
+ * for all data types (int, long, ...). The result is unsigned int
+ * and must be cast to any desired pointer type.
+ */
+#define ALIGNBYTES (sizeof(long) - 1)
+#define ALIGN(p) (((unsigned long)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+
+/* XXX PGSHIFT and PG_SHIFT are two names for the same thing */
+#define PGSHIFT 12 /* LOG2(NBPG) */
+#define PAGE_SHIFT 12
+#define NBPG (1 << PAGE_SHIFT) /* bytes/page */
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#define PAGE_MASK (PAGE_SIZE-1)
+#define PGOFSET (NBPG-1) /* byte offset into page */
+#define NPTEPG (NBPG/(sizeof (pt_entry_t)))
+
+/* XXX PDRSHIFT and PD_SHIFT are two names for the same thing */
+#define PDRSHIFT 22 /* LOG2(NBPDR) */
+#define NBPDR (1 << PDRSHIFT) /* bytes/page dir */
+#define PDROFSET (NBPDR-1) /* byte offset into page dir */
+
+/*
+ * XXX This should really be KPTDPTDI << PDRSHIFT, but since KPTDPTDI is
+ * defined in pmap.h which is included after this we can't do that
+ * (YET!)
+ */
+#define BTOPKERNBASE (KERNBASE >> PGSHIFT)
+
+#define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */
+#define DEV_BSIZE (1 << DEV_BSHIFT)
+
+#define BLKDEV_IOSIZE 2048
+#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
+
+#define CLSIZELOG2 0
+#define CLSIZE (1 << CLSIZELOG2)
+
+/* NOTE: SSIZE, SINCR and UPAGES must be multiples of CLSIZE */
+#define SSIZE 1 /* initial stack size/NBPG */
+#define SINCR 1 /* increment of stack/NBPG */
+
+#define UPAGES 2 /* pages of u-area */
+
+/*
+ * Constants related to network buffer management.
+ * MCLBYTES must be no larger than CLBYTES (the software page size), and,
+ * on machines that exchange pages of input or output buffers with mbuf
+ * clusters (MAPPED_MBUFS), MCLBYTES must also be an integral multiple
+ * of the hardware page size.
+ */
+#ifndef MSIZE
+#define MSIZE 128 /* size of an mbuf */
+#endif /* MSIZE */
+
+#ifndef MCLSHIFT
+#define MCLSHIFT 12 /* convert bytes to m_buf clusters */
+#endif /* MCLSHIFT */
+#define MCLBYTES (1 << MCLSHIFT) /* size of an m_buf cluster */
+#define MCLOFSET (MCLBYTES - 1) /* offset within an m_buf cluster */
+
+#ifndef NMBCLUSTERS
+#ifdef GATEWAY
+#define NMBCLUSTERS 512 /* map size, max cluster allocation */
+#else
+#define NMBCLUSTERS 256 /* map size, max cluster allocation */
+#endif /* GATEWAY */
+#endif /* NMBCLUSTERS */
+
+/*
+ * Some macros for units conversion
+ */
+/* Core clicks (4096 bytes) to segments and vice versa */
+#define ctos(x) (x)
+#define stoc(x) (x)
+
+/* Core clicks (4096 bytes) to disk blocks */
+#define ctod(x) ((x)<<(PGSHIFT-DEV_BSHIFT))
+#define dtoc(x) ((x)>>(PGSHIFT-DEV_BSHIFT))
+#define dtob(x) ((x)<<DEV_BSHIFT)
+
+/* clicks to bytes */
+#define ctob(x) ((x)<<PGSHIFT)
+
+/* bytes to clicks */
+#define btoc(x) (((unsigned long)(x)+(NBPG-1))>>PGSHIFT)
+
+#define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \
+ ((unsigned long)(bytes) >> DEV_BSHIFT)
+#define dbtob(db) /* calculates (db * DEV_BSIZE) */ \
+ ((unsigned long)(db) << DEV_BSHIFT)
+
+/*
+ * Map a ``block device block'' to a file system block.
+ * This should be device dependent, and will be if we
+ * add an entry to cdevsw/bdevsw for that purpose.
+ * For now though just use DEV_BSIZE.
+ */
+#define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE))
+
+/*
+ * Mach derived conversion macros
+ */
+#define trunc_page(x) ((unsigned long)(x) & ~(NBPG-1))
+#define round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1))
+
+#define atop(x) ((unsigned long)(x) >> PG_SHIFT)
+#define ptoa(x) ((unsigned long)(x) << PG_SHIFT)
+
+#define i386_round_pdr(x) ((((unsigned long)(x)) + NBPDR - 1) & ~(NBPDR-1))
+#define i386_trunc_pdr(x) ((unsigned long)(x) & ~(NBPDR-1))
+#define i386_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1))
+#define i386_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1))
+#define i386_btod(x) ((unsigned long)(x) >> PDRSHIFT)
+#define i386_dtob(x) ((unsigned long)(x) << PDRSHIFT)
+#define i386_btop(x) ((unsigned long)(x) >> PGSHIFT)
+#define i386_ptob(x) ((unsigned long)(x) << PGSHIFT)
+
+#include "sysparam.h"
+
+#endif /* !_MACHINE_PARAM_H_ */
diff --git a/sys/i386/boot/dosboot/protmod.c b/sys/i386/boot/dosboot/protmod.c
new file mode 100644
index 0000000..acedc20
--- /dev/null
+++ b/sys/i386/boot/dosboot/protmod.c
@@ -0,0 +1,591 @@
+/*
+ * protmod.c Protected Mode Utilities
+ *
+ * (C) 1994 by Christian Gusenbauer (cg@fimp01.fim.uni-linz.ac.at)
+ * 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.
+ *
+ * I ALLOW YOU USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. I DISCLAIM
+ * ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+ * USE OF THIS SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <dos.h>
+#include <memory.h>
+#include <process.h>
+#include "boot.h"
+#include "bootinfo.h"
+#include "protmod.h"
+
+#define data32 _emit 0x66
+#define addr32 _emit 0x67
+
+#define SEG(a) ((unsigned int)(((long)(a))>>16l))
+#define OFF(a) ((unsigned int)((long)(a)))
+#define ptr2lin(a) ((unsigned long)(SEG(a)*0x10l+(long)OFF(a)))
+
+typedef struct {
+ unsigned short limit; /* Segment limit */
+ unsigned long addr:24; /* address */
+ unsigned long rights:8; /* access rights */
+ unsigned short reserved; /* reserved on 80286 */
+} DTENTRY;
+
+struct dtr {
+ unsigned short limit;
+ unsigned long base;
+};
+
+struct {
+ unsigned long cr3;
+ unsigned long GdtrAddress;
+ unsigned long IdtrAddress;
+ unsigned short LDTR;
+ unsigned short TR;
+ unsigned long EIP;
+ unsigned short CS;
+} VCPI;
+
+static DTENTRY gdt[] =
+{
+ { 0, 0, 0, 0 }, /* Dummy */
+ { 0, 0, 0, 0 }, /* GDT itself */
+ { 0, 0, 0, 0 }, /* FROM */
+ { 0, 0, 0, 0 }, /* TO */
+ { 0, 0, 0, 0 }, /* BIOS CS */
+ { 0, 0, 0, 0 } /* SS */
+};
+
+static DTENTRY gdt2[] =
+{
+ { 0, 0, 0, 0 }, /* Dummy */
+ { 0, 0, 0, 0 }, /* GDT itself */
+ { 0, 0, 0, 0 }, /* IDT */
+ { 0, 0, 0, 0 }, /* DS */
+ { 0, 0, 0, 0 }, /* ES */
+ { 0, 0, 0, 0 }, /* SS */
+ { 0, 0, 0, 0 }, /* CS */
+ { 0, 0, 0, 0 }, /* BIOS CS, uninitialized */
+ { 0, 0, 0, 0 } /* VCPI: TSS */
+};
+
+static DTENTRY FreeBSDGdt[] = {
+ { 0x0000, 0, 0x00, 0x0000 }, /* 0: empty */
+ { 0xffff, 0, 0x9f, 0x00cf }, /* 1: kernel code */
+ { 0xffff, 0, 0x93, 0x00cf }, /* 2: kernel data */
+ { 0xffff, 0, 0x9e, 0x0040 }, /* 3: boot code */
+ { 0xffff, 0, 0x92, 0x0040 }, /* 4: boot data */
+ { 0xffff, 0, 0x9e, 0x0000 }, /* 5: 16bit boot code */
+};
+
+static DTENTRY Ldt[] = {
+ { 0x0000, 0, 0x00, 0x0000 }, /* 0: empty */
+};
+
+static DTENTRY idt2[256] = { 0 };
+static unsigned char Tss[256];
+
+static struct dtr FreeBSDGdtr = { sizeof FreeBSDGdt - 1, 0 };
+static struct dtr Gdtr = { sizeof gdt2 - 1, 0 };
+static struct dtr Idtr = { sizeof idt2 - 1, 0 };
+
+struct bootinfo_t bootinfo;
+int VCPIboot;
+
+int pm_copy(char far *from, unsigned long to, unsigned long count)
+{
+ unsigned char status;
+ unsigned short cnt = (unsigned short) count;
+
+ if (count == 0l) return -1; /* count has to be > 0!! */
+ gdt[2].limit = cnt-1; /* so much bytes to receive */
+ gdt[2].addr = _FP_SEG(from)*0x10l+_FP_OFF(from);
+ gdt[2].rights = 0x92; /* Data Segment: r/w */
+
+ gdt[3].limit = cnt-1; /* so much bytes to read */
+ gdt[3].addr = to; /* from HiMem */
+ gdt[3].rights = 0x92; /* Data Segment: r/w */
+
+ cnt >>= 1;
+
+ _asm {
+ pusha
+ mov ah,87h ; move words
+ mov cx,cnt ; that many
+ mov bx,seg gdt ; es:si points to the GDT
+ mov es,bx
+ mov si,offset gdt
+ int 15h ; now move the memory block
+ mov status,ah ; status is the return value:
+ ; 0 .. no error,
+ ; 1 .. parity error,
+ ; 2 .. exception interrupt
+ ; 3 .. gate A20 failed
+ popa
+ }
+
+ return (int) status;
+}
+
+static int pm_enter(void)
+{
+ unsigned char status;
+ unsigned int segment;
+
+ /* setup GDT entry 1: GDT */
+ gdt2[1].limit = sizeof(gdt2)-1;
+ gdt2[1].addr = ptr2lin(gdt2);
+ gdt2[1].rights = 0x92; /* Data Segment: r/w */
+
+ /* setup GDT entry 2: IDT */
+ gdt2[2].limit = sizeof(idt2)-1;
+ gdt2[2].addr = ptr2lin(idt2);
+ gdt2[2].rights = 0x92; /* Data Segment: r/w */
+
+ /* setup GDT entry 3: DS */
+ _asm mov segment,ds
+ gdt2[3].limit = 0xffff; /* max. offset */
+ gdt2[3].addr = segment*0x10l; /* segment starts at */
+ gdt2[3].rights = 0x92; /* Data Segment: r/w */
+
+ /* setup GDT entry 4: ES */
+ _asm mov segment,es
+ gdt2[4].limit = 0xffff; /* max. offset */
+ gdt2[4].addr = segment*0x10l; /* segment starts at */
+ gdt2[4].rights = 0x92; /* Data Segment: r/w */
+
+ /* setup GDT entry 5: SS */
+ _asm mov segment,ss
+ gdt2[5].limit = 0; /* max. offset = 64 K!! */
+ gdt2[5].addr = segment*0x10l; /* segment starts at */
+ gdt2[5].rights = 0x96; /* Stack Segment: r/w, expansion direction=down */
+
+ /* setup GDT entry 7: uninitialized! */
+
+ /* setup GDT entry 6: CS */
+ _asm mov segment,cs
+ gdt2[6].limit = 0xffff; /* max. offset */
+ gdt2[6].addr = segment*0x10l; /* segment starts at */
+ gdt2[6].rights = 0x9a; /* Code Segment: execute only */
+
+ _asm {
+ pusha
+ mov ah,89h ; enter protected mode
+ mov bx,seg gdt2 ; es:si points to the GDT
+ mov es,bx
+ mov si,offset gdt2
+ mov bx,2820h ; setup Interrupt Levels
+ int 15h ; now move the memory block
+ mov status,ah ; status is the return value and 0 if no error occurred
+ popa
+ }
+
+ if (status) return (int) status;/* no protected mode; return status */
+
+ _asm {
+ mov ax,30h
+ mov word ptr ss:[bp+4],ax ; patch code selector
+ }
+ return 0;
+}
+
+static void setupVCPI(void)
+{
+ unsigned int segment;
+
+ /* setup GDT entry 1: VCPI 1 (code) */
+ gdt2[1].limit = 0; /* max. offset */
+ gdt2[1].addr = 0; /* segment starts at */
+ gdt2[1].rights = 0; /* Data Segment: r/w */
+
+ /* setup GDT entry 2: VCPI 2 */
+ gdt2[2].limit = 0; /* max. offset */
+ gdt2[2].addr = 0; /* segment starts at */
+ gdt2[2].rights = 0; /* Data Segment: r/w */
+
+ /* setup GDT entry 3: VCPI 3 */
+ gdt2[3].limit = 0; /* max. offset */
+ gdt2[3].addr = 0; /* segment starts at */
+ gdt2[3].rights = 0; /* Data Segment: r/w */
+
+ /* setup GDT entry 4: code segment (use16) */
+ _asm mov segment,cs
+ gdt2[4].limit = 0xffff; /* max. offset */
+ gdt2[4].addr = segment*0x10l; /* segment starts at */
+ gdt2[4].rights = 0x9a; /* Code Segment */
+
+ /* setup GDT entry 5: data segment (use16) */
+ _asm mov segment,ds
+ gdt2[5].limit = 0xffff; /* max. offset */
+ gdt2[5].addr = segment*0x10l; /* segment starts at */
+ gdt2[5].rights = 0x92; /* Data Segment: r/w */
+
+ /* setup GDT entry 6: stack segment */
+ _asm mov segment,ss
+ gdt2[6].limit = 0; /* max. offset */
+ gdt2[6].addr = segment*0x10l; /* segment starts at */
+ gdt2[6].rights = 0x96; /* Stack Segment: r/w */
+
+ /* setup GDT entry 7: LDT selector */
+ gdt2[7].limit = 7; /* max. offset */
+ gdt2[7].addr = ptr2lin(Ldt); /* segment starts at */
+ gdt2[7].rights = 0x82; /* Data Segment: r/w */
+
+ /* setup GDT entry 8: 286-TSS */
+ gdt2[8].limit = 43; /* max. offset */
+ gdt2[8].addr = ptr2lin(Tss); /* segment starts at */
+ gdt2[8].rights = 0x81; /* TSS */
+}
+
+long get_high_memory(long size)
+{
+ int kb = ((int) (size/1024l)+3)&0xfffc; /* we need this much KB */
+ int lo, hi, vcpiVer, vcpiStatus;
+ int (far *xms_entry)();
+ FILE *fp;
+
+ /*
+ * Let's check for VCPI services.
+ */
+
+ fp = fopen("EMMXXXX0", "rb");
+ if (fp) {
+ fclose(fp);
+ _asm {
+ pusha
+ mov ax,0de00h
+ int 67h
+ mov vcpiVer,bx
+ mov vcpiStatus,ax
+ popa
+ }
+ if (!(vcpiStatus&0xff00)) {
+ VCPIboot = 1;
+ printf("VCPI services Version %d.%d detected!\n", vcpiVer>>8, vcpiVer&0xff);
+ }
+ }
+
+ /*
+ * I don't know why, but 386max seems to use the first 64 KB of that
+ * XMS area?! So I allocate more ram than I need!
+ */
+ kb += 128;
+
+ _asm {
+ pusha
+ mov ax,4300h
+ int 2fh ; let's look if we have XMS
+ cmp al,80h
+ je wehaveit ; ok, we have it
+ popa
+ }
+ return 0x110000l; /* default load address */
+
+no: _asm popa
+ return 0l;
+
+ _asm {
+wehaveit: mov ax,4310h
+ int 2fh ; get xms entry point
+ mov word ptr [xms_entry],bx
+ mov word ptr [xms_entry+2],es
+
+ mov ah,8h
+ call [xms_entry]
+
+ cmp ax,kb
+ jl no
+
+ mov dx,kb
+ mov ah,9h
+ call [xms_entry] ; get memory
+ cmp ax,0
+ je no ; sorry, no memory
+
+ mov ah,0ch
+ call [xms_entry] ; lock memory block (dx = handle)
+ cmp ax,0
+ je no
+ mov lo,bx
+ mov hi,dx
+ popa
+ }
+ return (long)hi*0x10000l+(long)lo + 128l*1024l;
+}
+
+void startprog(long hmaddress, long hmsize, long startaddr, long argv[])
+{
+ long GDTaddr=ptr2lin(FreeBSDGdt);
+ long *stack=_MK_FP(0x9f00, 0); /* prepare stack for starting the kernel */
+ unsigned int pmseg, pmoff;
+ unsigned int segment, pcxoff, psioff;
+ long h, BOOTaddr, ourret;
+ unsigned char *page;
+ int status;
+
+ /*
+ * The MSVC 1.5 inline assembler is not able to work with
+ * 386 opcodes (ie. extended registers like eax). So we have
+ * to use a workaround (god save Micro$oft and their customers ;)
+ */
+
+ _asm {
+ mov segment,cs
+ mov ax, offset our_return
+ mov pmoff,ax
+ }
+ BOOTaddr = segment*0x10l;
+ ourret = BOOTaddr + (long) pmoff;
+
+ _asm {
+ push ds
+
+ mov ax,cs
+ mov ds,ax
+ mov bx,offset lab ; patch the far jump after
+ mov byte ptr ds:[patch],bl ; switching gdt for FreeBSD
+ mov byte ptr ds:[patch+1],bh
+
+ mov bx,offset pcx
+ mov pcxoff,bx
+ mov bx,offset psi
+ mov psioff,bx
+ mov segment,ds
+
+ pop ds
+ }
+
+ *((long *)_MK_FP(segment, pcxoff+1)) = hmsize;
+ *((long *)_MK_FP(segment, psioff+1)) = hmaddress;
+
+ h = ptr2lin(&VCPI);
+
+ _asm {
+ push ds
+ mov ax,cs
+ mov ds,ax
+
+ mov bx,word ptr ss:[h]
+ mov cx,word ptr ss:[h+2]
+
+ mov byte ptr ds:[patch2+1],bl
+ mov byte ptr ds:[patch2+2],bh
+ mov byte ptr ds:[patch2+3],cl
+ mov byte ptr ds:[patch2+4],ch
+
+ pop ds
+ }
+
+ /*
+ * Setup the stack for executing the kernel. These parameters are
+ * put on the stack in reversed order (addresses are INCREMENTED)!
+ */
+
+ *stack++ = startaddr; /* that's the startaddress */
+ *stack++ = 8l; /* new CS */
+ *stack++ = ourret; /* ourreturn */
+ *stack++ = argv[1]; /* howto */
+ *stack++ = argv[2]; /* bootdev */
+ *stack++ = 0l; /* Parameter 4 */
+ *stack++ = 0l; /* Parameter 5 */
+ *stack++ = 0l; /* Parameter 6 */
+ *stack++ = ptr2lin(&bootinfo); /* bootinfo */
+
+ /*
+ * Initialize FreeBSD GDT and GDTR
+ */
+
+ FreeBSDGdtr.base = GDTaddr;
+
+ FreeBSDGdt[3].addr = BOOTaddr;
+
+ /*
+ * Now, we have to start the kernel at the given startaddress. To do this, we must
+ * switch to protected mode using INT15 with AH=0x89. This call uses its own layout
+ * of the GDT, so we switch to our own GDT after we return from the INT15 call. But
+ * before we do this, we must copy the 64 K which overwrites the HIMEM at 0x100000.
+ */
+
+ if (!VCPIboot) {
+ if (!(status=pm_enter())) {
+ _asm {
+ cli
+ mov ax,18h
+ mov ds,ax
+ }
+ goto nowgo;
+ }
+ fprintf(stderr, "Can't switch to protected mode!\n");
+ fprintf(stderr, "Giving up :-(!\n");
+ exit(0);
+ }
+
+ /*
+ * OK. Let's use VCPI services.
+ */
+
+ Gdtr.base = ptr2lin(gdt2);
+ Idtr.base = ptr2lin(idt2);
+ setupVCPI();
+
+ page = malloc(8192); /* allocate 8 KB */
+ if (!page) {
+ fprintf(stderr, "not enough memory!\n");
+ exit(0);
+ }
+ memset(page, 0, 8192);
+
+ h = (ptr2lin(page)+4095l) & 0xfffff000l;
+ pmseg = (unsigned short) (h>>4l);
+
+ /*
+ * We *do* have VCPI services, so let's get the protected mode
+ * interface and page table 0 from the server.
+ */
+
+ _asm {
+ push ds
+ push si
+ push di
+ mov ax,seg gdt2
+ mov ds,ax
+ mov ax,offset gdt2
+ add ax,8
+ mov si,ax
+ mov ax,pmseg
+ mov es,ax
+ xor di,di
+ mov ax,0xde01
+ int 0x67
+ pop di
+ pop si
+ pop ds
+ }
+
+ /*
+ * setup values for the mode change call
+ */
+
+ *((unsigned long *) MK_FP(pmseg,0x1000)) = h+3l;
+
+ VCPI.cr3 = h+0x1000l; /* page dir is the next page */
+ VCPI.GdtrAddress = ptr2lin(&Gdtr);
+ VCPI.IdtrAddress = ptr2lin(&Idtr);
+ VCPI.LDTR = 7*8;
+ VCPI.TR = 8*8;
+
+ _asm {
+ mov ax,offset nowgoVCPI
+ mov pmoff,ax
+ }
+
+ VCPI.EIP = (long) pmoff;
+ VCPI.CS = 4*8;
+
+ _asm {
+ cli
+ data32
+patch2: mov si,0
+ _emit 0
+ _emit 0
+ mov ax,0de0ch
+ int 67h
+
+nowgoVCPI: ; we are now executing in protected mode
+ ; first, we turn paging off!
+
+ data32
+ _emit 0fh ; this is "mov eax,CR0"
+ _emit 20h ;
+ _emit 0c0h ;
+
+ data32
+ and ax,0ffffh
+ _emit 0ffh
+ _emit 7fh
+
+ data32
+ _emit 0fh ; this is "mov CR0,eax"
+ _emit 22h ; and turns paging off
+ _emit 0c0h ;
+
+ data32
+ xor ax,ax
+
+ data32
+ _emit 0fh ; this is "mov CR3,eax"
+ _emit 22h ; and clears the page cache
+ _emit 0d8h ;
+
+ mov ax,28h
+ mov ds,ax ; load new DS
+ mov es,ax
+ mov ax,6*8
+ mov ss,ax
+ }
+
+/*******************************************************************************
+ * now this is all executed in protected mode!!!
+ */
+
+ /* setup new gdt for the FreeBSD kernel */
+ _asm {
+nowgo: cli
+ lgdt FreeBSDGdtr
+
+ data32
+ _emit 0eah ; far jump to "lab" (switch cs)
+patch: _emit 0 ; these two bytes are patched with the
+ _emit 0 ; correct offset of "lab"
+ _emit 0
+ _emit 0
+ _emit 18h
+ _emit 0
+
+ ; Setup SS, DS and ES registers with correct values, initialize the
+ ; stackpointer to the correct value and execute kernel
+
+lab: mov bx,10h
+ _emit 0
+ _emit 0
+ mov ds,bx
+ mov es,bx
+ mov ss,bx
+
+ ; move kernel to its correct address
+
+pcx: _emit 0b9h ; Micro$oft knows, why "mov cx,0" does not
+ _emit 0 ; work here
+ _emit 0
+ _emit 0
+ _emit 0
+psi: _emit 0beh ; mov si,0
+ _emit 0
+ _emit 0
+ _emit 0
+ _emit 0
+ _emit 0bfh ; mov di,0
+ _emit 0
+ _emit 0
+ _emit 0x10
+ _emit 0
+
+ rep movsb
+
+ ; MSVC is unable to assemble this instruction: mov esp,09f000h
+
+ mov sp,0f000h
+ _emit 9h
+ _emit 0
+ retf ; execute kernel
+our_return: jmp our_return
+ }
+ /* not reached */
+}
diff --git a/sys/i386/boot/dosboot/protmod.h b/sys/i386/boot/dosboot/protmod.h
new file mode 100644
index 0000000..60a6c406
--- /dev/null
+++ b/sys/i386/boot/dosboot/protmod.h
@@ -0,0 +1,34 @@
+/*
+ * protmod.h Protected Mode Utilities
+ *
+ * (C) 1994 by Christian Gusenbauer (cg@fimp01.fim.uni-linz.ac.at)
+ * 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.
+ *
+ * I ALLOW YOU USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. I DISCLAIM
+ * ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+ * USE OF THIS SOFTWARE.
+ *
+ */
+extern struct bootinfo_t bootinfo;
+extern int VCPIboot;
+
+extern int pm_copy(char far *from, unsigned long to, unsigned long count);
+/* pm_copy copies "count" bytes from location "from" (valid C pointer) to the
+ * address "to" in the high-memory space.
+ */
+
+extern void startprog(long hmaddress, long size, long startaddr, long argv[]);
+/* startprog switches to protected mode, moves the kernel from hmaddress
+ * to 0x100000l and finally starts the kernel.
+ */
+
+extern long get_high_memory(long size);
+/* get_high_memory allocates size bytes from high memory (>1MB) and returns
+ * the address of this area.
+ */
diff --git a/sys/i386/boot/dosboot/quota.h b/sys/i386/boot/dosboot/quota.h
new file mode 100644
index 0000000..e1d7207
--- /dev/null
+++ b/sys/i386/boot/dosboot/quota.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1982, 1986 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)quota.h 7.9 (Berkeley) 2/22/91
+ * $Id: quota.h,v 1.3 1993/11/25 01:38:27 wollman Exp $
+ */
+
+#ifndef _QUOTA_
+#define _QUOTA_
+
+/*
+ * 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) /* 1 week */
+#define MAX_DQ_TIME (7*24*60*60) /* 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.
+ */
+enum quotatype {
+ USRQUOTA = 0, /* element used for user quotas */
+ GRPQUOTA = 1, /* element used for group quotas */
+ MAXQUOTAS = 2
+};
+
+/*
+ * 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_long dqb_bhardlimit; /* absolute limit on disk blks alloc */
+ u_long dqb_bsoftlimit; /* preferred limit on disk blks */
+ u_long dqb_curblocks; /* current block count */
+ u_long dqb_ihardlimit; /* maximum # allocated inodes + 1 */
+ u_long dqb_isoftlimit; /* preferred inode limit */
+ u_long 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
+/*
+ * 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 {
+ struct dquot *dq_forw, *dq_back;/* MUST be first entry */
+ struct dquot *dq_freef, **dq_freeb; /* free list */
+ short dq_flags; /* flags, see below */
+ short dq_cnt; /* count of active references */
+ short dq_spare; /* unused spare padding */
+ short dq_type; /* quota type of this dquot */
+ u_long 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 ((struct dquot *) 0)
+
+/*
+ * 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.
+ */
+#ifndef DIAGNOSTIC
+#define DQREF(dq) (dq)->dq_cnt++
+#else
+#define DQREF(dq) dqref(dq)
+#endif /* DIAGNOSTIC */
+
+struct inode; struct ucred; struct mount; struct vnode;
+
+int getinoquota(struct inode *);
+int chkdq(struct inode *, long, struct ucred *, int);
+int chkdqchg(struct inode *, long, struct ucred *, enum quotatype);
+int chkiq(struct inode *, long, struct ucred *, int);
+int chkiqchg(struct inode *, long, struct ucred *, enum quotatype);
+#ifdef DIAGNOSTIC
+void chkdquot(struct inode *);
+#endif
+int quotaon(struct proc *, struct mount *, enum quotatype, caddr_t);
+int quotaoff(struct proc *, struct mount *, enum quotatype);
+int getquota(struct mount *, u_long, enum quotatype, caddr_t);
+int setquota(struct mount *, u_long, enum quotatype, caddr_t);
+int setuse(struct mount *, u_long, enum quotatype, caddr_t);
+int qsync(struct mount *);
+void dqinit(void);
+int dqget(struct vnode *, u_long, struct ufsmount *, enum quotatype, struct dquot **);
+void dqref(struct dquot *);
+void dqrele(struct vnode *, struct dquot *);
+int dqsync(struct vnode *, struct dquot *);
+void dqflush(struct vnode *);
+
+#else
+
+#include "cdefs.h"
+
+__BEGIN_DECLS
+int quotactl __P((const char *, int, int, void *));
+__END_DECLS
+
+#endif /* KERNEL */
+#endif /* _QUOTA_ */
diff --git a/sys/i386/boot/dosboot/readme b/sys/i386/boot/dosboot/readme
new file mode 100644
index 0000000..f4e273f
--- /dev/null
+++ b/sys/i386/boot/dosboot/readme
@@ -0,0 +1,41 @@
+Hi Everybody!
+
+This is version 1.5 of "fbsdboot", a program that allows you to boot a kernel
+from a MS-DOS partition or a FreeBSD partition. This program runs using DOS.
+It works with various memory managers (like EMM386, 386MAX) under certain
+circumstances.
+
+First, a FreeBSD kernel is always loaded to memory starting at 0x100000. To
+assure that loading the kernel *does not* overwrite memory used by memory
+managers, high memory for the kernel is allocated and after loading the kernel
+it's moved to 0x100000.
+
+Second, there are many ways to switch to protected mode which is necessary to
+start the kernel. Each BIOS gives you the possibility to use INT15H (AH=89H)
+to do that. But some memory-managers like 386max does not allow you to use
+this method.
+
+An other way to do the switch is to use DPMI services, but they do not
+guarantee, that the protected mode application is executed with privilege
+level 0. Therefore this method is *not* used.
+
+VCPI services offer another way to switch to protected mode, and VCPI servers
+are built into "emm386.exe", "386max" and "qemm". That's why, this method is
+implemented in fbsdboot.exe.
+
+Fbsdboot.exe tries to switch to protected mode using VCPI services. If they're
+not available INT15H is used to do the switch. If that fails, it's not possible
+for this version of fbsdboot.exe to boot a kernel :-(.
+
+You can get commandline options of fbsdboot if you start it with "-?" as option!
+
+I don't know, if fbsdboot works with QEMM, as I don't have the possibility to
+test it.
+
+Enjoy and have fun!
+
+Christian.
+cg@fimp01.fim.uni-linz.ac.at
+
+
+PS: Many thanks to Bruce Evans for his assistance!
diff --git a/sys/i386/boot/dosboot/reboot.h b/sys/i386/boot/dosboot/reboot.h
new file mode 100644
index 0000000..76766aa
--- /dev/null
+++ b/sys/i386/boot/dosboot/reboot.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)reboot.h 8.1 (Berkeley) 6/2/93
+ * $Id: reboot.h,v 1.7 1994/11/26 09:08:40 phk Exp $
+ */
+
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+/*
+ * Arguments to reboot system call.
+ * These are passed to boot program in r11,
+ * and on to init.
+ */
+#define RB_AUTOBOOT 0 /* flags for system auto-booting itself */
+
+#define RB_ASKNAME 0x01 /* ask for file name to reboot from */
+#define RB_SINGLE 0x02 /* reboot to single user only */
+#define RB_NOSYNC 0x04 /* dont sync before reboot */
+#define RB_HALT 0x08 /* don't reboot, just halt */
+#define RB_INITNAME 0x10 /* name given for /etc/init (unused) */
+#define RB_DFLTROOT 0x20 /* use compiled-in rootdev */
+#define RB_KDB 0x40 /* give control to kernel debugger */
+#define RB_RDONLY 0x80 /* mount root fs read-only */
+#define RB_DUMP 0x100 /* dump kernel memory before reboot */
+#define RB_MINIROOT 0x200 /* mini-root present in memory at boot time */
+#define RB_CONFIG 0x400 /* invoke user configuration routing */
+#define RB_VERBOSE 0x800 /* print all potentially useful info */
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility. Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ * (4) (4) (4) (4) (8) (8)
+ * --------------------------------
+ * |MA | AD| CT| UN| PART | TYPE |
+ * --------------------------------
+ */
+#define B_ADAPTORSHIFT 24
+#define B_ADAPTORMASK 0x0f
+#define B_ADAPTOR(val) (((val) >> B_ADAPTORSHIFT) & B_ADAPTORMASK)
+#define B_CONTROLLERSHIFT 20
+#define B_CONTROLLERMASK 0xf
+#define B_CONTROLLER(val) (((val)>>B_CONTROLLERSHIFT) & B_CONTROLLERMASK)
+#define B_UNITSHIFT 16
+#define B_UNITMASK 0xf
+#define B_UNIT(val) (((val) >> B_UNITSHIFT) & B_UNITMASK)
+#define B_PARTITIONSHIFT 8
+#define B_PARTITIONMASK 0xff
+#define B_PARTITION(val) (((val) >> B_PARTITIONSHIFT) & B_PARTITIONMASK)
+#define B_TYPESHIFT 0
+#define B_TYPEMASK 0xff
+#define B_TYPE(val) (((val) >> B_TYPESHIFT) & B_TYPEMASK)
+
+#define B_MAGICMASK ((u_long)0xf0000000)
+#define B_DEVMAGIC ((u_long)0xa0000000)
+
+#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \
+ (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \
+ ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \
+ ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC)
+
+#endif
diff --git a/sys/i386/boot/dosboot/sys.c b/sys/i386/boot/dosboot/sys.c
new file mode 100644
index 0000000..172545c
--- /dev/null
+++ b/sys/i386/boot/dosboot/sys.c
@@ -0,0 +1,173 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:36:34 rpd
+ * $Id: sys.c,v 1.3 1993/10/16 19:11:39 rgrimes Exp $
+ */
+#include <stdio.h>
+#include <string.h>
+#include <memory.h>
+
+#define bcopy(a,b,c) memcpy(b,a,c)
+
+#include "protmod.h"
+#include "boot.h"
+#include "dir.h"
+
+#define BUFSIZE 4096
+#undef MAXBSIZE
+#define MAXBSIZE 8192
+
+void ufs_read(char *buffer, long count);
+static long block_map(long file_block);
+
+char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
+char mapbuf[MAXBSIZE];
+long mapblock = 0;
+
+void xread(unsigned long addr, long size)
+{
+ long count = BUFSIZE;
+ while (size > 0l) {
+ if (BUFSIZE > size)
+ count = size;
+ ufs_read(buf, count);
+ pm_copy(buf, addr, count);
+ size -= count;
+ addr += count;
+ }
+}
+
+void ufs_read(char *buffer, long count)
+{
+ long logno, off, size;
+ long cnt2, bnum2;
+
+ while (count) {
+ off = blkoff(fs, poff);
+ logno = lblkno(fs, poff);
+ cnt2 = size = blksize(fs, &inode, logno);
+ bnum2 = fsbtodb(fs, block_map(logno)) + boff;
+ cnt = cnt2;
+ bnum = bnum2;
+ if ( (!off) && (size <= count))
+ {
+ iodest = buffer;
+ devread();
+ }
+ else
+ {
+ iodest = iobuf;
+ size -= off;
+ if (size > count)
+ size = count;
+ devread();
+ bcopy(iodest+off,buffer,size);
+ }
+ buffer += size;
+ count -= size;
+ poff += size;
+ }
+}
+
+static int find(char *path)
+{
+ char *rest, ch;
+ long block, off, loc, ino = ROOTINO;
+ struct direct *dp;
+loop: iodest = iobuf;
+ cnt = fs->fs_bsize;
+ bnum = fsbtodb(fs,itod(fs,ino)) + boff;
+ devread();
+ bcopy(&((struct dinode *)iodest)[ino % fs->fs_inopb],
+ &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)
+ return 0;
+ if (!(off = blkoff(fs, loc))) {
+ block = lblkno(fs, loc);
+ cnt = blksize(fs, &inode, block);
+ bnum = fsbtodb(fs, block_map(block)) + boff;
+ iodest = iobuf;
+ devread();
+ }
+ dp = (struct direct *)(iodest + off);
+ loc += dp->d_reclen;
+ } while (!dp->d_ino || strcmp(path, dp->d_name));
+ ino = dp->d_ino;
+ *(path = rest) = ch;
+ goto loop;
+}
+
+static long block_map(long file_block)
+{
+ if (file_block < NDADDR)
+ return(inode.i_db[file_block]);
+ if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) {
+ iodest = mapbuf;
+ cnt = fs->fs_bsize;
+ devread();
+ mapblock = bnum;
+ }
+ return (((long *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
+}
+
+int openrd(char *name)
+{
+ char *cp = name;
+
+ dosdev = 0x80; /* only 1st HD supported yet */
+ inode.i_dev = dosdev;
+ /***********************************************\
+ * Now we know the disk unit and part, *
+ * Load disk info, (open the device) *
+ \***********************************************/
+ if (devopen()) return 1;
+
+ /***********************************************\
+ * Load Filesystem info (mount the device) *
+ \***********************************************/
+ iodest = (char *)(fs = (struct fs *)fsbuf);
+ cnt = SBSIZE;
+ bnum = SBLOCK + boff;
+ devread();
+ /***********************************************\
+ * Find the actual FILE on the mounted device *
+ \***********************************************/
+ if (!find(cp)) return 1;
+ poff = 0;
+ name = cp;
+ return 0;
+}
diff --git a/sys/i386/boot/dosboot/syslimit.h b/sys/i386/boot/dosboot/syslimit.h
new file mode 100644
index 0000000..007dbc6
--- /dev/null
+++ b/sys/i386/boot/dosboot/syslimit.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)syslimits.h 7.4 (Berkeley) 2/4/91
+ * $Id: syslimits.h,v 1.4 1994/01/20 22:57:32 davidg Exp $
+ */
+
+#ifndef _SYS_SYSLIMITS_H_
+#define _SYS_SYSLIMITS_H_ 1
+
+#define ARG_MAX 32768 /* max bytes for an exec function */
+#define CHILD_MAX 40 /* max simultaneous processes */
+#define LINK_MAX 32767 /* max file link count */
+#define MAX_CANON 255 /* max bytes in terminal canonical input line */
+#define MAX_INPUT 255 /* max bytes in terminal input */
+#define NAME_MAX 255 /* max number of bytes in a file name */
+#define NGROUPS_MAX 16 /* max number of supplemental group id's */
+#define OPEN_MAX 64 /* max open files per process */
+#define PATH_MAX 1024 /* max number of bytes in pathname */
+#define PIPE_BUF 512 /* max number of bytes for atomic pipe writes */
+
+#define BC_BASE_MAX 99 /* max ibase/obase values allowed by bc(1) */
+#define BC_DIM_MAX 2048 /* max array elements allowed by bc(1) */
+#define BC_SCALE_MAX 99 /* max scale value allowed by bc(1) */
+#define BC_STRING_MAX 1000 /* max const string length allowed by bc(1) */
+#define EQUIV_CLASS_MAX 2 /* max weights for order keyword; see locale */
+#define EXPR_NEST_MAX 32 /* max expressions nested in expr(1) */
+#define LINE_MAX 2048 /* max length in bytes of an input line */
+#define RE_DUP_MAX 255 /* max repeated RE's using interval notation */
+#endif /* _SYS_SYSLIMITS_H_ */
diff --git a/sys/i386/boot/dosboot/sysparam.h b/sys/i386/boot/dosboot/sysparam.h
new file mode 100644
index 0000000..6331d69
--- /dev/null
+++ b/sys/i386/boot/dosboot/sysparam.h
@@ -0,0 +1,225 @@
+/*-
+ * Copyright (c) 1982, 1986, 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)param.h 8.2 (Berkeley) 1/21/94
+ * $Id: param.h,v 1.5 1994/09/01 05:12:51 davidg Exp $
+ */
+
+#ifndef _SYS_PARAM_H_
+#define _SYS_PARAM_H_
+
+#define BSD 199306 /* System version (year & month). */
+#define BSD4_3 1
+#define BSD4_4 1
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef LOCORE
+#include "types.h"
+#endif
+
+/*
+ * Machine-independent constants (some used in following include files).
+ * Redefined constants are from POSIX 1003.1 limits file.
+ *
+ * MAXCOMLEN should be >= sizeof(ac_comm) (see <acct.h>)
+ * MAXLOGNAME should be >= UT_NAMESIZE (see <utmp.h>)
+ */
+#include "syslimits.h"
+
+#define MAXCOMLEN 16 /* max command name remembered */
+#define MAXINTERP 32 /* max interpreter file name length */
+#define MAXLOGNAME 12 /* max login name length */
+#define MAXUPRC CHILD_MAX /* max simultaneous processes */
+#define NCARGS ARG_MAX /* max bytes for an exec function */
+#define NGROUPS NGROUPS_MAX /* max number groups */
+#define NOFILE OPEN_MAX /* max open files per process */
+#define NOGROUP 65535 /* marker for empty group set member */
+#define MAXHOSTNAMELEN 256 /* max hostname size */
+
+/* More types and definitions used throughout the kernel. */
+#ifdef KERNEL
+/*
+include <sys/cdefs.h>
+include <sys/errno.h>
+include <sys/time.h>
+include <sys/resource.h>
+include <sys/ucred.h>
+include <sys/uio.h>
+include <sys/rtprio.h>
+*/
+#endif
+
+/* Signals. */
+/*#include <sys/signal.h>*/
+
+/* Machine type dependent parameters. */
+#include "param.h"
+#include "limits.h"
+
+/*
+ * Priorities. Note that with 32 run queues, differences less than 4 are
+ * insignificant.
+ */
+#define PSWP 0
+#define PVM 4
+#define PINOD 8
+#define PRIBIO 16
+#define PVFS 20
+#define PZERO 22 /* No longer magic, shouldn't be here. XXX */
+#define PSOCK 24
+#define PWAIT 32
+#define PLOCK 36
+#define PPAUSE 40
+#define PUSER 50
+#define MAXPRI 127 /* Priorities range from 0 through MAXPRI. */
+
+#define PRIMASK 0x0ff
+#define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */
+
+#define NZERO 0 /* default "nice" */
+
+#define NBPW sizeof(long) /* number of bytes per word (integer) */
+
+#define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */
+#define NODEV (dev_t)(-1) /* non-existent device */
+
+/*
+ * Clustering of hardware pages on machines with ridiculously small
+ * page sizes is done here. The paging subsystem deals with units of
+ * CLSIZE pte's describing NBPG (from machine/machparam.h) pages each.
+ */
+#define CLBYTES (CLSIZE*NBPG)
+#define CLOFSET (CLSIZE*NBPG-1) /* for clusters, like PGOFSET */
+#define claligned(x) ((((long)(x))&CLOFSET)==0)
+#define CLOFF CLOFSET
+#define CLSHIFT (PGSHIFT+CLSIZELOG2)
+
+#if CLSIZE==1
+#define clbase(i) (i)
+#define clrnd(i) (i)
+#else
+/* Give the base virtual address (first of CLSIZE). */
+#define clbase(i) ((i) &~ (CLSIZE-1))
+/* Round a number of clicks up to a whole cluster. */
+#define clrnd(i) (((i) + (CLSIZE-1)) &~ (CLSIZE-1))
+#endif
+
+#define CBLOCK 128 /* Clist block size, must be a power of 2. */
+#define CBQSIZE (CBLOCK/NBBY) /* Quote bytes/cblock - can do better. */
+ /* Data chars/clist. */
+#define CBSIZE (CBLOCK - sizeof(struct cblock *) - CBQSIZE)
+#define CROUND (CBLOCK - 1) /* Clist rounding. */
+
+/*
+ * File system parameters and macros.
+ *
+ * The file system is made out of blocks of at most MAXBSIZE units, with
+ * smaller units (fragments) only in the last direct block. MAXBSIZE
+ * primarily determines the size of buffers in the buffer pool. It may be
+ * made larger without any effect on existing file systems; however making
+ * it smaller make make some file systems unmountable.
+ */
+#define MAXBSIZE MAXPHYS
+#define MAXFRAG 8
+
+/*
+ * MAXPATHLEN defines the longest permissable path length after expanding
+ * symbolic links. It is used to allocate a temporary buffer from the buffer
+ * pool in which to do the name expansion, hence should be a power of two,
+ * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the
+ * maximum number of symbolic links that may be expanded in a path name.
+ * It should be set high enough to allow all legitimate uses, but halt
+ * infinite loops reasonably quickly.
+ */
+#define MAXPATHLEN PATH_MAX
+#define MAXSYMLINKS 8
+
+/* Bit map related macros. */
+#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
+
+/* Macros for counting and rounding. */
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
+#define powerof2(x) ((((x)-1)&(x))==0)
+
+/* Macros for min/max. */
+#ifndef KERNEL
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+/*
+ * Constants for setting the parameters of the kernel memory allocator.
+ *
+ * 2 ** MINBUCKET is the smallest unit of memory that will be
+ * allocated. It must be at least large enough to hold a pointer.
+ *
+ * Units of memory less or equal to MAXALLOCSAVE will permanently
+ * allocate physical memory; requests for these size pieces of
+ * memory are quite fast. Allocations greater than MAXALLOCSAVE must
+ * always allocate and free physical memory; requests for these
+ * size allocations should be done infrequently as they will be slow.
+ *
+ * Constraints: CLBYTES <= MAXALLOCSAVE <= 2 ** (MINBUCKET + 14), and
+ * MAXALLOCSIZE must be a power of two.
+ */
+#define MINBUCKET 4 /* 4 => min allocation of 16 bytes */
+#define MAXALLOCSAVE (2 * CLBYTES)
+
+/*
+ * Scale factor for scaled integers used to count %cpu time and load avgs.
+ *
+ * The number of CPU `tick's that map to a unique `%age' can be expressed
+ * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that
+ * can be calculated (assuming 32 bits) can be closely approximated using
+ * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15).
+ *
+ * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age',
+ * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024.
+ */
+#define FSHIFT 11 /* bits to right of fixed binary point */
+#define FSCALE (1<<FSHIFT)
+
+#endif
diff --git a/sys/i386/boot/dosboot/types.h b/sys/i386/boot/dosboot/types.h
new file mode 100644
index 0000000..77d8373
--- /dev/null
+++ b/sys/i386/boot/dosboot/types.h
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 1982, 1986, 1991, 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)types.h 8.4 (Berkeley) 1/21/94
+ * $Id: types.h,v 1.4 1994/09/25 15:56:25 davidg Exp $
+ */
+
+#ifndef _SYS_TYPES_H_
+#define _SYS_TYPES_H_
+
+#include "cdefs.h"
+
+/* Machine type dependent parameters. */
+#include "endian.h"
+
+#ifndef _POSIX_SOURCE
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short ushort; /* Sys V compatibility */
+typedef unsigned int uint; /* Sys V compatibility */
+#endif
+
+struct __help__ {
+ long a,b;
+};
+
+typedef struct __help__ u_quad_t; /* quads */
+typedef struct __help__ quad_t;
+typedef quad_t * qaddr_t;
+
+typedef char * caddr_t; /* core address */
+typedef long daddr_t; /* disk address */
+typedef unsigned short dev_t; /* device number (cg: was u_long) */
+typedef unsigned long fixpt_t; /* fixed point number */
+typedef unsigned short gid_t; /* group id */
+typedef unsigned long ino_t; /* inode number */
+typedef unsigned short mode_t; /* permissions */
+typedef unsigned short nlink_t; /* link count */
+typedef long off_t; /* file offset (cg: was quad) */
+typedef long pid_t; /* process id */
+typedef long segsz_t; /* segment size */
+typedef long swblk_t; /* swap offset */
+typedef unsigned short uid_t; /* user id */
+
+/*
+ * This belongs in unistd.h, but is placed here to ensure that programs
+ * casting the second parameter of lseek to off_t will get the correct
+ * version of lseek.
+ */
+#ifndef KERNEL
+__BEGIN_DECLS
+off_t lseek __P((int, off_t, int));
+__END_DECLS
+#endif
+
+#ifndef _POSIX_SOURCE
+/*
+ * minor() gives a cookie instead of an index since we don't want to
+ * change the meanings of bits 0-15 or waste time and space shifting
+ * bits 16-31 for devices that don't use them.
+ */
+#define major(x) ((int)(((u_int)(x) >> 8)&0xff)) /* major number */
+#define minor(x) ((int)((x)&0xffff00ff)) /* minor number */
+#define makedev(x,y) ((dev_t)(((x)<<8) | (y))) /* create dev_t */
+#endif
+
+#include "ansi.h"
+/*#include <machine/types.h>*/
+
+#ifdef _BSD_CLOCK_T_
+typedef _BSD_CLOCK_T_ clock_t;
+#undef _BSD_CLOCK_T_
+#endif
+
+#ifdef _BSD_SIZE_T_
+typedef _BSD_SIZE_T_ size_t;
+#undef _BSD_SIZE_T_
+#endif
+
+#ifdef _BSD_SSIZE_T_
+typedef _BSD_SSIZE_T_ ssize_t;
+#undef _BSD_SSIZE_T_
+#endif
+
+#ifdef _BSD_TIME_T_
+typedef _BSD_TIME_T_ time_t;
+#undef _BSD_TIME_T_
+#endif
+
+#ifndef _POSIX_SOURCE
+#define NBBY 8 /* number of bits in a byte */
+
+/*
+ * Select uses bit masks of file descriptors in longs. These macros
+ * manipulate such bit fields (the filesystem macros use chars).
+ * FD_SETSIZE may be defined by the user, but the default here should
+ * be enough for most uses.
+ */
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 256
+#endif
+
+typedef long fd_mask;
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif
+
+typedef struct fd_set {
+ fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+} fd_set;
+
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_COPY(f, t) bcopy(f, t, sizeof(*(f)))
+#define FD_ZERO(p) bzero(p, sizeof(*(p)))
+
+#if defined(__STDC__) && defined(KERNEL)
+/*
+ * Forward structure declarations for function prototypes. We include the
+ * common structures that cross subsystem boundaries here; others are mostly
+ * used in the same place that the structure is defined.
+ */
+struct proc;
+struct pgrp;
+struct ucred;
+struct rusage;
+struct file;
+struct buf;
+struct tty;
+struct uio;
+#endif
+
+typedef long time_t;
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !_SYS_TYPES_H_ */
OpenPOWER on IntegriCloud