summaryrefslogtreecommitdiffstats
path: root/sys/i386/boot
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/boot')
-rw-r--r--sys/i386/boot/Makefile106
-rw-r--r--sys/i386/boot/README.386BSD151
-rw-r--r--sys/i386/boot/README.MACH210
-rw-r--r--sys/i386/boot/asm.S260
-rw-r--r--sys/i386/boot/asm.h144
-rw-r--r--sys/i386/boot/asm.s270
-rw-r--r--sys/i386/boot/bios.S329
-rw-r--r--sys/i386/boot/bios.s326
-rw-r--r--sys/i386/boot/biosboot/Makefile106
-rw-r--r--sys/i386/boot/biosboot/README.386BSD151
-rw-r--r--sys/i386/boot/biosboot/README.MACH210
-rw-r--r--sys/i386/boot/biosboot/asm.S260
-rw-r--r--sys/i386/boot/biosboot/asm.h144
-rw-r--r--sys/i386/boot/biosboot/bios.S329
-rw-r--r--sys/i386/boot/biosboot/boot.c308
-rw-r--r--sys/i386/boot/biosboot/boot.h40
-rw-r--r--sys/i386/boot/biosboot/boot2.S177
-rw-r--r--sys/i386/boot/biosboot/disk.c281
-rw-r--r--sys/i386/boot/biosboot/io.c214
-rw-r--r--sys/i386/boot/biosboot/start.S292
-rw-r--r--sys/i386/boot/biosboot/sys.c232
-rw-r--r--sys/i386/boot/biosboot/table.c125
-rw-r--r--sys/i386/boot/boot.c308
-rw-r--r--sys/i386/boot/boot.h40
-rw-r--r--sys/i386/boot/boot.sed3
-rw-r--r--sys/i386/boot/boot2.S177
-rw-r--r--sys/i386/boot/boot2.s73
-rw-r--r--sys/i386/boot/disk.c281
-rw-r--r--sys/i386/boot/io.c214
-rw-r--r--sys/i386/boot/rmaouthdr6
-rw-r--r--sys/i386/boot/start.S292
-rw-r--r--sys/i386/boot/start.s323
-rw-r--r--sys/i386/boot/sys.c232
-rw-r--r--sys/i386/boot/table.c125
34 files changed, 6739 insertions, 0 deletions
diff --git a/sys/i386/boot/Makefile b/sys/i386/boot/Makefile
new file mode 100644
index 0000000..568c747
--- /dev/null
+++ b/sys/i386/boot/Makefile
@@ -0,0 +1,106 @@
+#
+# 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:33:46 rpd
+# $Id: Makefile,v 1.9 1994/06/16 03:53:24 adam Exp $
+#
+
+wd0:
+ dd if=boot of=biosboot count=1
+ dd if=boot of=bootbios skip=1
+ disklabel -r -w wd0 nec5655 newboot biosboot bootbios
+ rm biosboot bootbios
+
+NOPROG= noprog
+NOMAN= noman
+
+# tunable loopcount parameter, waiting for keypress
+BOOTWAIT?= 2400
+
+CFLAGS = -O2 -DDO_BAD144 -DBOOTWAIT=${BOOTWAIT} -I${.CURDIR}
+LIBS= -lc
+INC= -I${.CURDIR}/../..
+
+# start.o should be first
+OBJS = start.o table.o boot2.o boot.o asm.o bios.o io.o disk.o sys.o
+
+.SUFFIXES: .S .c .o
+
+.c.o:
+ $(CC) $(CFLAGS) $(INC) -c $<
+
+.S.o:
+ $(CC) $(CFLAGS) -c $<
+
+boot: $(OBJS)
+ $(LD) -Bstatic -N -T 0 -o boot $(OBJS) $(LIBS)
+ cp boot boot.sym
+ @strip boot
+ @sh ${.CURDIR}/rmaouthdr boot boot.tmp
+ @mv -f boot.tmp boot
+ @ls -l boot
+
+biosboot: boot
+ dd if=boot of=biosboot count=1
+
+bootbios: boot
+ dd if=boot of=bootbios skip=1
+
+${DESTDIR}/usr/mdec/bootsd: bootbios
+ cp bootbios ${DESTDIR}/usr/mdec/bootsd
+
+${DESTDIR}/usr/mdec/sdboot: biosboot
+ cp biosboot ${DESTDIR}/usr/mdec/sdboot
+
+${DESTDIR}/usr/mdec/bootwd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootwd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootwd
+
+${DESTDIR}/usr/mdec/wdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/wdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/wdboot
+
+${DESTDIR}/usr/mdec/bootfd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootfd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootfd
+
+${DESTDIR}/usr/mdec/fdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/fdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/fdboot
+
+sd: ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/sdboot
+wd: ${DESTDIR}/usr/mdec/bootwd ${DESTDIR}/usr/mdec/wdboot
+fd: ${DESTDIR}/usr/mdec/bootfd ${DESTDIR}/usr/mdec/fdboot
+
+all: biosboot bootbios
+
+fd0:
+ dd if=boot of=biosboot count=1
+ dd if=boot of=bootbios skip=1
+ disklabel -r -w fd0 floppy bootflpy biosboot bootbios
+ rm biosboot bootbios
+
+install: wd sd fd
+
+clean:
+ /bin/rm -f *.o *.d boot bootbios biosboot boot.sym
+
+.include <bsd.prog.mk>
diff --git a/sys/i386/boot/README.386BSD b/sys/i386/boot/README.386BSD
new file mode 100644
index 0000000..cc5cb8f
--- /dev/null
+++ b/sys/i386/boot/README.386BSD
@@ -0,0 +1,151 @@
+This Boot code is different from the original boot code that came with
+386BSD in that it uses the BIOS to load the kernel and to provide all i/o
+services. The advantage ofthis is that the same boot code exactly, can run
+on any device that is supported by the BIOS. (That's most of them)
+This is important for the 'generic scsi' project because it means we can
+write drivers for new scsi adapters without having to develop an new
+set of boot blocks for each.
+
+At this point you should read the first part of README.MACH... come back here
+when you have done that:
+
+In normal operation, when co-existing with other operating systems, the
+following operations occur:
+
+1/ the BIOS loads the first block of the disk (called the Master Boot Record
+or MBR) and if it has the correct magic numbers, jumps into it:
+
+2/ The MBR code, looks at the Partition table that is embedded within it,
+to detirmine which is the partition to boot from. If you are using the os-bs
+bootblocks (highly recommended) then it will give you a menu to choose from.
+
+3/ The MBR will load the first record of the selected partition and
+if it has (the same) magic numbers, jumps into it. In 386bsd this is the
+first stage boot, (or boot1) it is represented in /usr/mdec by
+wdboot, asboot and sdboot. If the disk has been set up without DOS partitioning
+then this block will be at block zero, and will have been loaded directly by
+the BIOS.
+
+4/ Boot1 will look at block0 (which might be itself if there are no DOS
+partitions) and will find the 386bsd partition, and using the information
+regarding the start position of that partition, will load the next 13 sectors
+or so, to around 90000 (640k - 64k). and will jump into it at the appropriate
+entry point. Since boot1 and boot2 were compiled together as one file
+and then split later, boot1 knows the exact position within boot2 of the
+entry point.
+
+Boot 1 also contains a compiled in DOS partition table
+(in case it is at block 0), which contains a 386bsd partition starting
+at 0. This ensures that the same code can work whether or not
+boot1 is at block 0.
+
+5/ Boot2 asks the user for a boot device, partition and filename, and then
+loads the MBR of the selected device. This may or may not be the device
+which was originally used to boot the first MBR. The partition table
+of the new MBR is searched for a 386bsd partition, and if one is found,
+that is then in turn searched for the disklabel. This could all be on the
+second disk at this point, if the user selected it.
+
+6/On finding the disklabel, boot2 can find the correct unix partition
+within the 386bsd partition, and using cutdown filesystem code,
+look for the file to boot (e.g. 386bsd).
+
+7/ Boot2 loads this file starting at the location specified by the a.out header,
+(see later) and leaps into it at the location specified in he header.
+
+if the file does not exist or cannot be loaded, boot2 goes back to step 5.
+
+386bsd is now running and will hopefully start vm etc. and get to multi-user
+mode.
+
+##########################################################################
+During all these steps, all i/o is performed using the BIOS. This has a number
+of side effects:
+
+1/ Since BIOS disk calls are specified in terms of cylinder,head and sector,
+and the BIOS read the disk information from either the CMOS or from some other
+location which is un-available to us, we must use the cyl,head,sec information
+that is given in the MBR, rather than the start address in the MBR, because
+we cannot guarentee that we can corectly calculate C,H,S from the start address.
+
+Therefore, the C,H,S information in the MBR must be as correct for this boot
+to work as it would be for DOS to boot. For example, adaptec BIOS routines
+assume a layout of 64 heads and 32 sectors giving 1MB per ficticious cylinder.
+You must use these figures to calculate the correct values. Luckily, the DOS
+fdisk program will do all this for you if you tell it to give you a DOS
+partition, and you can change it to a 386BSD partition later. If you use
+no DOS partitioning, then the compiled in table in Boot1 will do just fine.
+
+If you want to do it by hand remember that BIOS counts sectors starting at 1.
+(cylinders and heads start at 0 (??))
+
+2/ you cannot overwrite the bottom 4k of ram until you have finished ALL
+bios calls, as BIOS uses this area as scratch memory.
+
+3/ Since BIOS runs in REAL mode, and Boot2 runs in protected mode,
+Boot 2 switches back to real mode just before each BIOS call and then
+back to protected mode on each return. Touch this at your peril.!
+
+#########################################################################
+In answering the prompt from Boot2:
+you can,
+1/ leave it alone.. it will boot the indicated file from the first
+partition of the first drive seen by the BIOS (C:)
+
+2/ enter only "-s" to boot the default to single user mode
+
+3/ enter only a filename (optionally with -s) to boot that kernel,
+
+4/ enter a whole line of the form shown in the prompt. This allows you to
+boot some other partition, possibly on the second drive, as root.
+
+
+##########################################################################
+In the case you have two drives the same type (both scsi or bith IDE/ESDI),
+wd(0,a)xxx
+ will boot xxx from drive 0, a partition.
+wd(1,a)xxx
+ will boot xxx from drive 1, a partition.
+
+similarly for sd.
+
+if you have one wd drive and one scsi drive, then you MUST
+use device 'hd'
+
+otherwise the following will happen:
+
+with wd0 and sd0, you specify sd1 or wd1 to indicate the 2nd drive.
+it boots the kernel correctly, then tells the kernel to use sd1 as root.
+you however may not have an sd1, and problems arise.
+
+hd is special in that the kernel is always told to use unit 0,
+The correct TYPE of device will be specified too, so the kernel
+will be told either sd0 or wd0.
+
+Whether sd or wd is specified to the kernel is read from the disklabel,
+so ensure that all SCSI disks have type SCSI in their disklabel or the
+boot code will assume they are ESDI or IDE. (Remember, because it is
+working through the BIOS it has ho idea what kind of disk it is.
+
+##########################################################################
+Installing:
+The makefile supplied has a target install which will create the
+files wdboot,bootwd ,sdboot and bootsd in /usr/mdec.
+BEWARE these will overwrite the existing wdboot and bootwd. (so back
+them up)
+
+there are also targets wd and sd which wil only do one of them
+
+The commented out targets wd0 and sd0 are examples of how to
+load the new bootblocks, however,make sure you change the
+device type and label to suit your drive if you uncomment them.
+(see 'man disklabel')
+
+If you already have made partitions using the old bootblocks
+these should install painlessly.
+
+Before you do this ensure you have a booting floppy with correct
+disktab and bootblock files on it so that if it doesn't work, you can
+re-disklabel from the floppy.
+
+$Id$
diff --git a/sys/i386/boot/README.MACH b/sys/i386/boot/README.MACH
new file mode 100644
index 0000000..cb62329
--- /dev/null
+++ b/sys/i386/boot/README.MACH
@@ -0,0 +1,210 @@
+/*
+ * 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:33:55 rpd
+ * $Id$
+ */
+
+********NOTE: This is not all relevant to the 386BSD version**********
+
+ AT386 Protected Mode Bootstrap Loader
+ =====================================
+
+1. Overview of Startup
+ -------------------
+
+ After the system is rebooted, the BIOS bootstrap routine reads Sector
+ 1, Track 0 into memory at location 0000:7C00H. If location 0000:7DFEH
+ (last two bytes of that sector) contains the value AA55H, the BIOS
+ bootstrap routine will transfer control to 0000:7C00H. Otherwise, the
+ boot code in that sector is bad and the boot routine stops.
+
+ For DOS compatibility reason, one extra stage of boot is required if
+ the boot device is a hard disk. The first sector of the hard disk will
+ contain the MOS-DOS boot code and a boot record partition table.
+ When this sector is loaded into 0000:7C00H, it will relocate itself
+ to somewhere else and then load the first sector of the active
+ partition into 0000:7C00H. Both UNIX and DOS use the command "fdisk"
+[ 386bsd does not have an 'fdisk' (yet) ]
+ to install this first sector into the hard disk and to manipulate
+ the hard disk partitions.
+
+
+
+2. The First Stage Bootstrap Loader
+ --------------------------------
+
+ After startup, the first stage boot is loaded at 0000:7C00H. This
+ first stage boot will load itself and the second stage boot into
+ memory at location 0000:1000H. For floppy disks, the first cylinder
+ is reserved as the boot cylinder, and the boot code (first and second)
+ will be loaded from there. Currently, only double sided, high density
+ (15 sectors per track) floppies are supported. For hard disks, the
+ first 29 sectors of the active partition is reserved for boot code
+ which will be loaded by the first stage boot. All the disk types
+ recognized by BIOS are supported by this bootstrap loader.
+[for 386bsd we load the second stage booter to 9000:0]
+
+
+
+3. The Second Stage Bootstrap Loader
+ --------------------------------
+
+ After the boot code is loaded, the control is passed to the second
+ stage bootstrap loader "boot2()". In order to be able to load the
+ big kernel image (bigger than 512K or 640K, depends on the memory
+ configuration), the second stage boot loader will run on the protected
+ mode. This bootstarp loader does not have any stand alone device
+ drivers, all the I/O's are through the BIOS calls. Since the first
+ stage boot code will no longer be used at this moment, the memory
+ location of the first stage boot code (0000:1000H to 0000:1200H) will
+ be used as an internal buffer for BIOS calls. Immediately after this
+ internal buffer is the GDT table for the second stage boot loader.
+ Since this boot loader needs to switch back and forth between protected
+ and real mode in order to use BIOS calls, the limit of the boot code
+ and boot data segments must not be greater than 64K.
+
+ The boot loader loads the kernel image at memory location above 1 MB
+ to skip the memory hole between 521K/640K and 1MB. After the kernel
+ is loaded, the boot loader stores the information in the stack and
+ then passes control to kernel. Currently, the three information passed
+ fromm the boot loader to the kernel are type of the boot device, size
+ of the base memory and size of the extended memory.
+
+[ 386bsd receives: howto, bootdev]
+
+[ 386bsd is loaded where-ever the "MByte" bits of the load address specify,
+so if you link it for FE100000 it will load to 1MB, but if you link
+it for FE000000 it will load ad 0MB]
+
+[for machines with only 512KB normal ram the kernel will need to be linked
+for 1MB and the bootblocks modified to run below 512KB. (8000:0)]
+
+
+4. The UNIX Startup
+ ----------------
+
+ Since the boot loader loads the kernel image at memory location above
+ 1MB, the kernel has to start as protected mode. In addition, the
+ link editor description file (vuifile) has to indicate that
+ the text and data segments start above 1MB. Also, the boot loader
+ passes the infomation to the kernel through the stack.
+
+[MOST of what is mentionned below is NOT relevant to 386bsd]
+
+5. Disk Layout and Bad Block Handling
+ ---------------------------------
+
+ The System V/386 Release 3.2 (AT) disk layout will be used as the disk
+ layout for the MACH System on the AT platform.
+
+ This disk layout is as follows:
+
+ * Reserve the first sector of cylinder 0 for the DOS boot record which
+ contains the master boot code (446 bytes) and the partition table.
+ (Refer to DOS Technical Reference Manual page 9-6 to 9-10).
+
+ * Reserve the first 29 sectors of the UNIX partition for the first
+ and the second stage bootstrap.
+
+ * Reserve the 30th sector of the UNIX partition for the pdinfo and
+ the vtoc tables.
+
+ * Reserve the 31st to the 34th sectors of the UNIX partition for the
+ bad track and the bad block mapping tables.
+
+ * Reserve up to 253 consecutive tracks when required, beginning with
+ the 35th sector of the UNIX partition, for alternate tracks.
+
+ * Reserve up to 253 consecutive blocks, beginning with the first
+ sector after the alternate tracks area, for alternate blocks.
+
+ SEC
+ 1
+ ----------------------------------------------------
+ | X | | CYL 0, TRK 0
+ ---------------- .......... --------------------
+ | .......... |
+ ---------------- .......... --------------------
+ | .......... |
+ ===============================================================
+ ^ | BOOTSTRAP | CYL N, TRK M
+ | ----------------------------------------------------
+ | | |30 |31 |32 |33 |34 |
+ ---------------------------------------------------- ---
+ U | .......... | ^
+ N ---------------- .......... --------------------- |
+ I | .......... | Alternate Tracks
+ X ---------------- .......... --------------------- |
+ | .......... | V
+ P ---------------------------------------------------- ---
+ A | .......... | ^
+ R ---------------- .......... --------------------- |
+ T | .......... | Alternate Blocks
+ I ---------------- .......... -------------------- |
+ T | .......... | V
+ I ---------------------------------------------------- ---
+ O | Unix root partition starts from here |
+ N ---------------- -----------------
+ | |
+ ----------------------------------------------------
+ | |
+ ----------------------------------------------------
+ | |
+ | ---------------------------------------------------
+ | | |
+ | ----------------------------------------------------
+ V | |
+ ===============================================================
+ | ........ |
+ --------------- ........ --------------
+ | ........ |
+ ----------------------------------------------------
+
+
+ The bad block handling mechanism is as follows:
+
+ * Use the alternate track in the alternate tracks area if the
+ track containing the target sector is bad.
+
+ * Use the alternate block in the alternate blocks area if the
+ target sector is bad.
+
+
+
+
+6. How to make:
+ -----------
+
+ Since the kernel image is loaded above 1 MB, the kernel must start
+ as protected mode. This means that this bootstrap loader will work
+ only when the corresponding changes on the kernel startup code are done.
+
+ The make command to generate this bootstrap loader is:
+
+ make -f boot.mk fdboot (floppy boot loader)
+ make -f boot.mk hdboot (wini boot loader)
+[to make 386bsd bootblocks "make sd wd" (warning: they will be installed
+in /dev/mdec.. take backups)]
diff --git a/sys/i386/boot/asm.S b/sys/i386/boot/asm.S
new file mode 100644
index 0000000..b291428
--- /dev/null
+++ b/sys/i386/boot/asm.S
@@ -0,0 +1,260 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
+ * $Id$
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "asm.s"
+
+#include "asm.h"
+
+
+CR0_PE_ON = 0x1
+CR0_PE_OFF = 0xfffffffe
+
+.globl _ouraddr
+ .text
+
+/*
+#
+# real_to_prot()
+# transfer from real mode to protected mode.
+*/
+
+ENTRY(real_to_prot)
+ # guarantee that interrupt is disabled when in prot mode
+ cli
+
+ # load the gdtr
+ addr32
+ data32
+ lgdt EXT(Gdtr)
+
+ # set the PE bit of CR0
+ mov %cr0, %eax
+
+ data32
+ or $CR0_PE_ON, %eax
+ mov %eax, %cr0
+
+ # make intrasegment jump to flush the processor pipeline and
+ # reload CS register
+ data32
+ ljmp $0x18, $xprot
+
+xprot:
+ # we are in USE32 mode now
+ # set up the protected mode segment registers : DS, SS, ES
+ mov $0x20, %eax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ # load idtr so we can debug
+ lidt EXT(Idtr_prot)
+
+ ret
+
+/*
+#
+# prot_to_real()
+# transfer from protected mode to real mode
+#
+*/
+
+ENTRY(prot_to_real)
+
+ # set up a dummy stack frame for the second seg change.
+ movl _ouraddr, %eax
+ sarl $4, %eax
+ pushw %ax
+ movw $xreal, %ax # gas botches pushw $xreal - extra bytes 0, 0
+ pushw %ax # decode to add %al, (%eax) (%al usually 0)
+
+ # Change to use16 mode.
+ ljmp $0x28, $x16
+
+x16:
+ # clear the PE bit of CR0
+ mov %cr0, %eax
+ data32
+ and $CR0_PE_OFF, %eax
+ mov %eax, %cr0
+
+ # make intersegment jmp to flush the processor pipeline
+ # using the fake stack frame set up earlier
+ # and reload CS register
+ lret
+
+xreal:
+ # we are in real mode now
+ # set up the real mode segment registers : DS, SS, ES
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ # load idtr so we can debug
+ addr32
+ data32
+ lidt EXT(Idtr_real)
+
+ data32
+ ret
+
+/*
+#
+# startprog(phyaddr)
+# start the program on protected mode where phyaddr is the entry point
+#
+*/
+
+ENTRY(startprog)
+ push %ebp
+ mov %esp, %ebp
+
+ # get things we need into registers
+ movl 0x8(%ebp), %ecx # entry offset
+ movl 0x0c(%ebp), %eax # &argv
+
+ # make a new stack at 0:0xa0000 (big segs)
+ mov $0x10, %ebx
+ movw %bx, %ss
+ movl $0xa0000, %ebx
+ movl %ebx, %esp
+
+ # push some number of args onto the stack
+ pushl $0 # nominally a cyl offset in the boot.
+ pushl 0x8(%eax) # argv[2] = bootdev
+ pushl 0x4(%eax) # argv[1] = howto
+ pushl $0 # dummy 'return' address
+
+ # push on our entry address
+ mov $0x08, %ebx # segment
+ pushl %ebx
+ pushl %ecx
+
+ # convert over the other data segs
+ mov $0x10, %ebx
+ movw %bx, %ds
+ movw %bx, %es
+
+ # convert the PC (and code seg)
+ lret
+/*
+#
+# pbzero( dst, cnt)
+# where src is a virtual address and dst is a physical address
+*/
+
+ENTRY(pbzero)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %edi # destination
+ mov 0xc(%ebp), %ecx # count
+ mov $0x0, %eax # value
+
+ rep
+ stosb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+/*
+#
+# pcpy(src, dst, cnt)
+# where src is a virtual address and dst is a physical address
+#
+*/
+
+ENTRY(pcpy)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %esi # source
+ mov 0xc(%ebp), %edi # destination
+ mov 0x10(%ebp), %ecx # count
+
+ rep
+ movsb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+
diff --git a/sys/i386/boot/asm.h b/sys/i386/boot/asm.h
new file mode 100644
index 0000000..43242bd
--- /dev/null
+++ b/sys/i386/boot/asm.h
@@ -0,0 +1,144 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.7 92/02/29 15:33:41 rpd
+ * $Id$
+ */
+
+#define S_ARG0 4(%esp)
+#define S_ARG1 8(%esp)
+#define S_ARG2 12(%esp)
+#define S_ARG3 16(%esp)
+
+#define FRAME pushl %ebp; movl %esp, %ebp
+#define EMARF leave
+
+#define B_ARG0 8(%ebp)
+#define B_ARG1 12(%ebp)
+#define B_ARG2 16(%ebp)
+#define B_ARG3 20(%ebp)
+
+#ifdef wheeze
+
+#define ALIGN 4
+#define EXT(x) x
+#define LEXT(x) x:
+#define LCL(x) ./**/x
+
+#define LB(x,n) ./**/x
+#define LBb(x,n) ./**/x
+#define LBf(x,n) ./**/x
+
+#define SVC lcall $7,$0
+
+#define String .string
+#define Value .value
+#define Times(a,b) [a\*b]
+#define Divide(a,b) [a\\b]
+
+#define INB inb (%dx)
+#define OUTB outb (%dx)
+#define INL inl (%dx)
+#define OUTL outl (%dx)
+
+#else wheeze
+#define ALIGN
+#define LCL(x) x
+
+#define LB(x,n) n
+#ifdef __STDC__
+#define EXT(x) _ ## x
+#define LEXT(x) _ ## x ## :
+
+#define LBb(x,n) n ## b
+#define LBf(x,n) n ## f
+#else __STDC__
+#define EXT(x) _/**/x
+#define LEXT(x) _/**/x/**/:
+#define LBb(x,n) n/**/b
+#define LBf(x,n) n/**/f
+#endif __STDC__
+#define SVC .byte 0x9a; .long 0; .word 0x7
+
+#define String .ascii
+#define Value .word
+#define Times(a,b) (a*b)
+#define Divide(a,b) (a/b)
+
+#define INB inb %dx, %al
+#define OUTB outb %al, %dx
+#define INL inl %dx, %eax
+#define OUTL outl %eax, %dx
+
+#endif wheeze
+
+#define addr32 .byte 0x67
+#define data32 .byte 0x66
+
+#ifdef GPROF
+#ifdef __STDC__
+
+#define MCOUNT .data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ASENTRY(x) .globl x; .align ALIGN; x ## : ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+
+#else __STDC__
+
+#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x: ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+
+#endif __STDC__
+#else GPROF
+#ifdef __STDC__
+
+#define MCOUNT
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x ## :
+
+#else __STDC__
+
+#define MCOUNT
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x:
+
+#endif __STDC__
+#endif GPROF
+
+#define Entry(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define DATA(x) .globl EXT(x); .align ALIGN; LEXT(x)
diff --git a/sys/i386/boot/asm.s b/sys/i386/boot/asm.s
new file mode 100644
index 0000000..8802b13
--- /dev/null
+++ b/sys/i386/boot/asm.s
@@ -0,0 +1,270 @@
+/*
+ * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
+ *
+ * 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.
+ */
+
+/*
+ * HISTORY
+ * $Log: asm.s,v $
+ * Revision 2.2 92/04/04 11:34:13 rpd
+ * Fix Intel Copyright as per B. Davies authorization.
+ * [92/04/03 rvb]
+ * From 2.5 boot: pruned inb(), outb(), and pzero().
+ * [92/03/30 rvb]
+ *
+ * Revision 2.2 91/04/02 14:35:10 mbj
+ * Added _sp() => where is the stack at. [kupfer]
+ * Add Intel copyright
+ * [90/02/09 rvb]
+ *
+ */
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "asm.s"
+
+#include "asm.h"
+
+
+CR0_PE_ON = 0x1
+CR0_PE_OFF = 0xfffffffe
+
+.globl _ouraddr
+ .text
+
+/*
+#
+# real_to_prot()
+# transfer from real mode to protected mode.
+*/
+
+ENTRY(real_to_prot)
+ # guarantee that interrupt is disabled when in prot mode
+ cli
+
+ # load the gdtr
+ addr16
+ data32
+ lgdt EXT(Gdtr)
+
+ # set the PE bit of CR0
+ mov %cr0, %eax
+
+ data32
+ or $CR0_PE_ON, %eax
+ mov %eax, %cr0
+
+ # make intrasegment jump to flush the processor pipeline and
+ # reload CS register
+ data32
+ ljmp $0x18, $xprot
+
+xprot:
+ # we are in USE32 mode now
+ # set up the protective mode segment registers : DS, SS, ES
+ mov $0x20, %eax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ ret
+
+/*
+#
+# prot_to_real()
+# transfer from protected mode to real mode
+#
+*/
+
+ENTRY(prot_to_real)
+
+ # set up a dummy stack frame for the second seg change.
+ movl _ouraddr, %eax
+ sarl $4, %eax
+ pushw %ax
+ pushw $xreal
+
+ # Change to use16 mode.
+ ljmp $0x28, $x16
+
+x16:
+ # clear the PE bit of CR0
+ mov %cr0, %eax
+ data32
+ and $CR0_PE_OFF, %eax
+ mov %eax, %cr0
+
+
+ # make intersegment jmp to flush the processor pipeline
+ # using the fake stack frame set up earlier
+ # and reload CS register
+ lret
+
+
+xreal:
+ # we are in real mode now
+ # set up the real mode segment registers : DS, SS, ES
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ data32
+ ret
+
+/*
+#
+# startprog(phyaddr)
+# start the program on protected mode where phyaddr is the entry point
+#
+*/
+
+ENTRY(startprog)
+ push %ebp
+ mov %esp, %ebp
+
+
+
+ # get things we need into registers
+ movl 0x8(%ebp), %ecx # entry offset
+ movl 0x0c(%ebp), %eax # &argv
+
+ # make a new stack at 0:0xa0000 (big segs)
+ mov $0x10, %ebx
+ movw %bx, %ss
+ movl $0xa0000,%ebx
+ movl %ebx,%esp
+
+
+ # push some number of args onto the stack
+ pushl $0 # nominally a cyl offset in the boot.
+ pushl 0x8(%eax) # argv[2] = bootdev
+ pushl 0x4(%eax) # argv[1] = howto
+ pushl $0 # dummy 'return' address
+
+ # push on our entry address
+ mov $0x08, %ebx # segment
+ pushl %ebx
+ pushl %ecx
+
+ # convert over the other data segs
+ mov $0x10, %ebx
+ movw %bx, %ds
+ movw %bx, %es
+
+ # convert the PC (and code seg)
+ lret
+/*
+#
+# pbzero( dst, cnt)
+# where src is a virtual address and dst is a physical address
+*/
+
+ENTRY(pbzero)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %edi # destination
+ mov 0xc(%ebp), %ecx # count
+ mov $0x0,%eax # value
+
+ rep
+ stosb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+/*
+#
+# pcpy(src, dst, cnt)
+# where src is a virtual address and dst is a physical address
+#
+*/
+
+ENTRY(pcpy)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %esi # source
+ mov 0xc(%ebp), %edi # destination
+ mov 0x10(%ebp), %ecx # count
+
+ rep
+ movsb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+
diff --git a/sys/i386/boot/bios.S b/sys/i386/boot/bios.S
new file mode 100644
index 0000000..687ca18
--- /dev/null
+++ b/sys/i386/boot/bios.S
@@ -0,0 +1,329 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
+ * $Id$
+ */
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "bios.s"
+
+#include "asm.h"
+ .text
+
+/*
+# biosread(dev, cyl, head, sec, nsec, offset)
+# Read "nsec" sectors from disk to offset "offset" in boot segment
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+ENTRY(biosread)
+ push %ebp
+ mov %esp, %ebp
+
+ push %ebx
+ push %ecx
+ push %edx
+ push %es
+
+ movb 0x10(%ebp), %dh
+ movw 0x0c(%ebp), %cx
+ xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
+ rorb $2, %cl
+ movb 0x14(%ebp), %al
+ orb %al, %cl
+ incb %cl # sector; sec starts from 1, not 0
+ movb 0x8(%ebp), %dl # device
+ movl 0x1c(%ebp), %ebx # offset
+ # prot_to_real will set %es to BOOTSEG
+
+ call EXT(prot_to_real) # enter real mode
+ movb $0x2, %ah # subfunction
+ addr32
+ movb 0x18(%ebp), %al # number of sectors
+
+ sti
+ int $0x13
+ cli
+
+ mov %eax, %ebx # save return value (actually movw %ax, %bx)
+
+ data32
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+ movb %bh, %al # return value in %ax
+
+ pop %es
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %ebp
+
+ ret
+
+
+/*
+# putc(ch)
+# BIOS call "INT 10H Function 0Eh" to write character to console
+# Call with %ah = 0x0e
+# %al = character
+# %bh = page
+# %bl = foreground color ( graphics modes)
+*/
+
+
+ENTRY(putc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+ push %ecx
+
+ movb 0x8(%ebp), %cl
+
+ call EXT(prot_to_real)
+
+ data32
+ mov $0x1, %ebx # %bh=0, %bl=1 (blue)
+ movb $0xe, %ah
+ movb %cl, %al
+ sti
+ int $0x10 # display a byte
+ cli
+
+ data32
+ call EXT(real_to_prot)
+
+ pop %ecx
+ pop %ebx
+ pop %ebp
+ ret
+
+
+/*
+# getc()
+# BIOS call "INT 16H Function 00H" to read character from keyboard
+# Call with %ah = 0x0
+# Return: %ah = keyboard scan code
+# %al = ASCII character
+*/
+
+ENTRY(getc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx # save %ebx
+
+ call EXT(prot_to_real)
+
+ movb $0x0, %ah
+ sti
+ int $0x16
+ cli
+
+ movb %al, %bl # real_to_prot uses %eax
+
+ data32
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+/*
+# ischar()
+# if there is a character pending, return it; otherwise return 0
+# BIOS call "INT 16H Function 01H" to check whether a character is pending
+# Call with %ah = 0x1
+# Return:
+# If key waiting to be input:
+# %ah = keyboard scan code
+# %al = ASCII character
+# Zero flag = clear
+# else
+# Zero flag = set
+*/
+ENTRY(ischar)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ xor %ebx, %ebx
+ movb $0x1, %ah
+ sti
+ int $0x16
+ cli
+ data32
+ jz nochar
+ movb %al, %bl
+
+nochar:
+ data32
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+
+/*
+#
+# get_diskinfo(): return a word that represents the
+# max number of sectors and heads and drives for this device
+#
+*/
+
+ENTRY(get_diskinfo)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %ebx
+ push %ecx
+ push %edx
+
+ movb 0x8(%ebp), %dl # diskinfo(drive #)
+ call EXT(prot_to_real) # enter real mode
+
+ movb $0x8, %ah # ask for disk info
+
+ sti
+ int $0x13
+ cli
+
+ jnc ok
+ /*
+ * Urk. Call failed. It is not supported for floppies by old BIOS's.
+ * Guess it's a 15-sector floppy. Initialize all the registers for
+ * documentation, although we only need head and sector counts.
+ */
+ subb %ah, %ah # %ax = 0
+ movb %al, %al
+ movb %ah, %bh # %bh = 0
+ movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
+ movb $79, %ch # max track
+ movb $15, %cl # max sector
+ movb $1, %dh # max head
+ movb $1, %dl # # floppy drives installed
+ # es:di = parameter table
+ # carry = 0
+ok:
+
+ data32
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+
+ /*form a longword representing all this gunk*/
+ movb %dh, %ah # max head
+ andb $0x3f, %cl # mask of cylinder gunk
+ movb %cl, %al # max sector (and # sectors)
+
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %es
+ pop %ebp
+ ret
+
+/*
+#
+# memsize(i) : return the memory size in KB. i == 0 for conventional memory,
+# i == 1 for extended memory
+# BIOS call "INT 12H" to get conventional memory size
+# BIOS call "INT 15H, AH=88H" to get extended memory size
+# Both have the return value in AX.
+#
+*/
+
+ENTRY(memsize)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ mov 8(%ebp), %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ cmpb $0x1, %bl
+ data32
+ je xext
+
+ sti
+ int $0x12
+ cli
+ data32
+ jmp xdone
+
+xext: movb $0x88, %ah
+ sti
+ int $0x15
+ cli
+
+xdone:
+ mov %eax, %ebx
+
+ data32
+ call EXT(real_to_prot)
+
+ mov %ebx, %eax
+ pop %ebx
+ pop %ebp
+ ret
diff --git a/sys/i386/boot/bios.s b/sys/i386/boot/bios.s
new file mode 100644
index 0000000..d1673a5
--- /dev/null
+++ b/sys/i386/boot/bios.s
@@ -0,0 +1,326 @@
+/*
+ * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
+ *
+ * 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.
+ */
+
+/*
+ * HISTORY
+ * $Log: bios.s,v $
+ * Revision 2.2 92/04/04 11:34:26 rpd
+ * Fix Intel Copyright as per B. Davies authorization.
+ * [92/04/03 rvb]
+ * From 2.5 version
+ * [92/03/30 mg32]
+ *
+ * Revision 2.2 91/04/02 14:35:21 mbj
+ * Add Intel copyright
+ * [90/02/09 rvb]
+ *
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "bios.s"
+
+#include "asm.h"
+ .text
+
+/*
+# biosread(dev, cyl, head, sec)
+# Read one sector from disk into the internal buffer "intbuf" which
+# is the first 512 bytes of the boot loader.
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+ENTRY(biosread)
+ push %ebp
+ mov %esp, %ebp
+
+ push %ebx
+ push %ecx
+ push %edx
+ push %es
+
+ movb 0x10(%ebp), %dh
+ movw 0x0c(%ebp), %cx
+ xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
+ rorb $2, %cl
+ movb 0x14(%ebp), %al
+ orb %al, %cl
+ incb %cl # sector; sec starts from 1, not 0
+ movb 0x8(%ebp), %dl # device
+ xor %ebx, %ebx # offset -- 0
+ # prot_to_real will set %es to BOOTSEG
+
+ call EXT(prot_to_real) # enter real mode
+ movb $0x2, %ah # subfunction
+ movb $0x1, %al # number of sectors -- one
+
+ sti
+ int $0x13
+ cli
+
+ mov %eax, %ebx # save return value
+
+ data16
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+ movb %bh, %al # return value in %ax
+
+ pop %es
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %ebp
+
+ ret
+
+
+/*
+# putc(ch)
+# BIOS call "INT 10H Function 0Eh" to write character to console
+# Call with %ah = 0x0e
+# %al = character
+# %bh = page
+# %bl = foreground color ( graphics modes)
+*/
+
+
+ENTRY(putc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+ push %ecx
+
+ movb 0x8(%ebp), %cl
+
+ call EXT(prot_to_real)
+
+ data16
+ mov $0x1, %ebx # %bh=0, %bl=1 (blue)
+ movb $0xe, %ah
+ movb %cl, %al
+ sti
+ int $0x10 # display a byte
+ cli
+
+ data16
+ call EXT(real_to_prot)
+
+ pop %ecx
+ pop %ebx
+ pop %ebp
+ ret
+
+
+/*
+# getc()
+# BIOS call "INT 16H Function 00H" to read character from keyboard
+# Call with %ah = 0x0
+# Return: %ah = keyboard scan code
+# %al = ASCII character
+*/
+
+ENTRY(getc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx # save %ebx
+
+ call EXT(prot_to_real)
+
+ movb $0x0, %ah
+ sti
+ int $0x16
+ cli
+
+ movb %al, %bl # real_to_prot uses %eax
+
+ data16
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+/*
+# ischar()
+# if there is a character pending, return it; otherwise return 0
+# BIOS call "INT 16H Function 01H" to check whether a character is pending
+# Call with %ah = 0x1
+# Return:
+# If key waiting to be input:
+# %ah = keyboard scan code
+# %al = ASCII character
+# Zero flag = clear
+# else
+# Zero flag = set
+*/
+ENTRY(ischar)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ xor %ebx, %ebx
+ movb $0x1, %ah
+ sti
+ int $0x16
+ cli
+ data16
+ jz nochar
+ movb %al, %bl
+
+nochar:
+ data16
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+
+/*
+#
+# get_diskinfo(): return a word that represents the
+# max number of sectors and heads and drives for this device
+#
+*/
+
+ENTRY(get_diskinfo)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %ebx
+ push %ecx
+ push %edx
+
+ movb 0x8(%ebp), %dl # diskinfo(drive #)
+ call EXT(prot_to_real) # enter real mode
+
+ movb $0x8, %ah # ask for disk info
+
+ sti
+ int $0x13
+ cli
+
+ data16
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+
+ /*form a longword representing all this gunk*/
+ movb %dh, %ah # # heads
+ andb $0x3f, %cl # mask of cylinder gunk
+ movb %cl, %al # # sectors
+
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %es
+ pop %ebp
+ ret
+
+/*
+#
+# memsize(i) : return the memory size in KB. i == 0 for conventional memory,
+# i == 1 for extended memory
+# BIOS call "INT 12H" to get conventional memory size
+# BIOS call "INT 15H, AH=88H" to get extended memory size
+# Both have the return value in AX.
+#
+*/
+
+ENTRY(memsize)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ mov 8(%ebp), %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ cmpb $0x1, %bl
+ data16
+ je xext
+
+ sti
+ int $0x12
+ cli
+ data16
+ jmp xdone
+
+xext: movb $0x88, %ah
+ sti
+ int $0x15
+ cli
+
+xdone:
+ mov %eax, %ebx
+
+ data16
+ call EXT(real_to_prot)
+
+ mov %ebx, %eax
+ pop %ebx
+ pop %ebp
+ ret
diff --git a/sys/i386/boot/biosboot/Makefile b/sys/i386/boot/biosboot/Makefile
new file mode 100644
index 0000000..568c747
--- /dev/null
+++ b/sys/i386/boot/biosboot/Makefile
@@ -0,0 +1,106 @@
+#
+# 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:33:46 rpd
+# $Id: Makefile,v 1.9 1994/06/16 03:53:24 adam Exp $
+#
+
+wd0:
+ dd if=boot of=biosboot count=1
+ dd if=boot of=bootbios skip=1
+ disklabel -r -w wd0 nec5655 newboot biosboot bootbios
+ rm biosboot bootbios
+
+NOPROG= noprog
+NOMAN= noman
+
+# tunable loopcount parameter, waiting for keypress
+BOOTWAIT?= 2400
+
+CFLAGS = -O2 -DDO_BAD144 -DBOOTWAIT=${BOOTWAIT} -I${.CURDIR}
+LIBS= -lc
+INC= -I${.CURDIR}/../..
+
+# start.o should be first
+OBJS = start.o table.o boot2.o boot.o asm.o bios.o io.o disk.o sys.o
+
+.SUFFIXES: .S .c .o
+
+.c.o:
+ $(CC) $(CFLAGS) $(INC) -c $<
+
+.S.o:
+ $(CC) $(CFLAGS) -c $<
+
+boot: $(OBJS)
+ $(LD) -Bstatic -N -T 0 -o boot $(OBJS) $(LIBS)
+ cp boot boot.sym
+ @strip boot
+ @sh ${.CURDIR}/rmaouthdr boot boot.tmp
+ @mv -f boot.tmp boot
+ @ls -l boot
+
+biosboot: boot
+ dd if=boot of=biosboot count=1
+
+bootbios: boot
+ dd if=boot of=bootbios skip=1
+
+${DESTDIR}/usr/mdec/bootsd: bootbios
+ cp bootbios ${DESTDIR}/usr/mdec/bootsd
+
+${DESTDIR}/usr/mdec/sdboot: biosboot
+ cp biosboot ${DESTDIR}/usr/mdec/sdboot
+
+${DESTDIR}/usr/mdec/bootwd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootwd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootwd
+
+${DESTDIR}/usr/mdec/wdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/wdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/wdboot
+
+${DESTDIR}/usr/mdec/bootfd: ${DESTDIR}/usr/mdec/bootsd
+ rm -f ${DESTDIR}/usr/mdec/bootfd
+ ln ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/bootfd
+
+${DESTDIR}/usr/mdec/fdboot: ${DESTDIR}/usr/mdec/sdboot
+ rm -f ${DESTDIR}/usr/mdec/fdboot
+ ln ${DESTDIR}/usr/mdec/sdboot ${DESTDIR}/usr/mdec/fdboot
+
+sd: ${DESTDIR}/usr/mdec/bootsd ${DESTDIR}/usr/mdec/sdboot
+wd: ${DESTDIR}/usr/mdec/bootwd ${DESTDIR}/usr/mdec/wdboot
+fd: ${DESTDIR}/usr/mdec/bootfd ${DESTDIR}/usr/mdec/fdboot
+
+all: biosboot bootbios
+
+fd0:
+ dd if=boot of=biosboot count=1
+ dd if=boot of=bootbios skip=1
+ disklabel -r -w fd0 floppy bootflpy biosboot bootbios
+ rm biosboot bootbios
+
+install: wd sd fd
+
+clean:
+ /bin/rm -f *.o *.d boot bootbios biosboot boot.sym
+
+.include <bsd.prog.mk>
diff --git a/sys/i386/boot/biosboot/README.386BSD b/sys/i386/boot/biosboot/README.386BSD
new file mode 100644
index 0000000..cc5cb8f
--- /dev/null
+++ b/sys/i386/boot/biosboot/README.386BSD
@@ -0,0 +1,151 @@
+This Boot code is different from the original boot code that came with
+386BSD in that it uses the BIOS to load the kernel and to provide all i/o
+services. The advantage ofthis is that the same boot code exactly, can run
+on any device that is supported by the BIOS. (That's most of them)
+This is important for the 'generic scsi' project because it means we can
+write drivers for new scsi adapters without having to develop an new
+set of boot blocks for each.
+
+At this point you should read the first part of README.MACH... come back here
+when you have done that:
+
+In normal operation, when co-existing with other operating systems, the
+following operations occur:
+
+1/ the BIOS loads the first block of the disk (called the Master Boot Record
+or MBR) and if it has the correct magic numbers, jumps into it:
+
+2/ The MBR code, looks at the Partition table that is embedded within it,
+to detirmine which is the partition to boot from. If you are using the os-bs
+bootblocks (highly recommended) then it will give you a menu to choose from.
+
+3/ The MBR will load the first record of the selected partition and
+if it has (the same) magic numbers, jumps into it. In 386bsd this is the
+first stage boot, (or boot1) it is represented in /usr/mdec by
+wdboot, asboot and sdboot. If the disk has been set up without DOS partitioning
+then this block will be at block zero, and will have been loaded directly by
+the BIOS.
+
+4/ Boot1 will look at block0 (which might be itself if there are no DOS
+partitions) and will find the 386bsd partition, and using the information
+regarding the start position of that partition, will load the next 13 sectors
+or so, to around 90000 (640k - 64k). and will jump into it at the appropriate
+entry point. Since boot1 and boot2 were compiled together as one file
+and then split later, boot1 knows the exact position within boot2 of the
+entry point.
+
+Boot 1 also contains a compiled in DOS partition table
+(in case it is at block 0), which contains a 386bsd partition starting
+at 0. This ensures that the same code can work whether or not
+boot1 is at block 0.
+
+5/ Boot2 asks the user for a boot device, partition and filename, and then
+loads the MBR of the selected device. This may or may not be the device
+which was originally used to boot the first MBR. The partition table
+of the new MBR is searched for a 386bsd partition, and if one is found,
+that is then in turn searched for the disklabel. This could all be on the
+second disk at this point, if the user selected it.
+
+6/On finding the disklabel, boot2 can find the correct unix partition
+within the 386bsd partition, and using cutdown filesystem code,
+look for the file to boot (e.g. 386bsd).
+
+7/ Boot2 loads this file starting at the location specified by the a.out header,
+(see later) and leaps into it at the location specified in he header.
+
+if the file does not exist or cannot be loaded, boot2 goes back to step 5.
+
+386bsd is now running and will hopefully start vm etc. and get to multi-user
+mode.
+
+##########################################################################
+During all these steps, all i/o is performed using the BIOS. This has a number
+of side effects:
+
+1/ Since BIOS disk calls are specified in terms of cylinder,head and sector,
+and the BIOS read the disk information from either the CMOS or from some other
+location which is un-available to us, we must use the cyl,head,sec information
+that is given in the MBR, rather than the start address in the MBR, because
+we cannot guarentee that we can corectly calculate C,H,S from the start address.
+
+Therefore, the C,H,S information in the MBR must be as correct for this boot
+to work as it would be for DOS to boot. For example, adaptec BIOS routines
+assume a layout of 64 heads and 32 sectors giving 1MB per ficticious cylinder.
+You must use these figures to calculate the correct values. Luckily, the DOS
+fdisk program will do all this for you if you tell it to give you a DOS
+partition, and you can change it to a 386BSD partition later. If you use
+no DOS partitioning, then the compiled in table in Boot1 will do just fine.
+
+If you want to do it by hand remember that BIOS counts sectors starting at 1.
+(cylinders and heads start at 0 (??))
+
+2/ you cannot overwrite the bottom 4k of ram until you have finished ALL
+bios calls, as BIOS uses this area as scratch memory.
+
+3/ Since BIOS runs in REAL mode, and Boot2 runs in protected mode,
+Boot 2 switches back to real mode just before each BIOS call and then
+back to protected mode on each return. Touch this at your peril.!
+
+#########################################################################
+In answering the prompt from Boot2:
+you can,
+1/ leave it alone.. it will boot the indicated file from the first
+partition of the first drive seen by the BIOS (C:)
+
+2/ enter only "-s" to boot the default to single user mode
+
+3/ enter only a filename (optionally with -s) to boot that kernel,
+
+4/ enter a whole line of the form shown in the prompt. This allows you to
+boot some other partition, possibly on the second drive, as root.
+
+
+##########################################################################
+In the case you have two drives the same type (both scsi or bith IDE/ESDI),
+wd(0,a)xxx
+ will boot xxx from drive 0, a partition.
+wd(1,a)xxx
+ will boot xxx from drive 1, a partition.
+
+similarly for sd.
+
+if you have one wd drive and one scsi drive, then you MUST
+use device 'hd'
+
+otherwise the following will happen:
+
+with wd0 and sd0, you specify sd1 or wd1 to indicate the 2nd drive.
+it boots the kernel correctly, then tells the kernel to use sd1 as root.
+you however may not have an sd1, and problems arise.
+
+hd is special in that the kernel is always told to use unit 0,
+The correct TYPE of device will be specified too, so the kernel
+will be told either sd0 or wd0.
+
+Whether sd or wd is specified to the kernel is read from the disklabel,
+so ensure that all SCSI disks have type SCSI in their disklabel or the
+boot code will assume they are ESDI or IDE. (Remember, because it is
+working through the BIOS it has ho idea what kind of disk it is.
+
+##########################################################################
+Installing:
+The makefile supplied has a target install which will create the
+files wdboot,bootwd ,sdboot and bootsd in /usr/mdec.
+BEWARE these will overwrite the existing wdboot and bootwd. (so back
+them up)
+
+there are also targets wd and sd which wil only do one of them
+
+The commented out targets wd0 and sd0 are examples of how to
+load the new bootblocks, however,make sure you change the
+device type and label to suit your drive if you uncomment them.
+(see 'man disklabel')
+
+If you already have made partitions using the old bootblocks
+these should install painlessly.
+
+Before you do this ensure you have a booting floppy with correct
+disktab and bootblock files on it so that if it doesn't work, you can
+re-disklabel from the floppy.
+
+$Id$
diff --git a/sys/i386/boot/biosboot/README.MACH b/sys/i386/boot/biosboot/README.MACH
new file mode 100644
index 0000000..cb62329
--- /dev/null
+++ b/sys/i386/boot/biosboot/README.MACH
@@ -0,0 +1,210 @@
+/*
+ * 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:33:55 rpd
+ * $Id$
+ */
+
+********NOTE: This is not all relevant to the 386BSD version**********
+
+ AT386 Protected Mode Bootstrap Loader
+ =====================================
+
+1. Overview of Startup
+ -------------------
+
+ After the system is rebooted, the BIOS bootstrap routine reads Sector
+ 1, Track 0 into memory at location 0000:7C00H. If location 0000:7DFEH
+ (last two bytes of that sector) contains the value AA55H, the BIOS
+ bootstrap routine will transfer control to 0000:7C00H. Otherwise, the
+ boot code in that sector is bad and the boot routine stops.
+
+ For DOS compatibility reason, one extra stage of boot is required if
+ the boot device is a hard disk. The first sector of the hard disk will
+ contain the MOS-DOS boot code and a boot record partition table.
+ When this sector is loaded into 0000:7C00H, it will relocate itself
+ to somewhere else and then load the first sector of the active
+ partition into 0000:7C00H. Both UNIX and DOS use the command "fdisk"
+[ 386bsd does not have an 'fdisk' (yet) ]
+ to install this first sector into the hard disk and to manipulate
+ the hard disk partitions.
+
+
+
+2. The First Stage Bootstrap Loader
+ --------------------------------
+
+ After startup, the first stage boot is loaded at 0000:7C00H. This
+ first stage boot will load itself and the second stage boot into
+ memory at location 0000:1000H. For floppy disks, the first cylinder
+ is reserved as the boot cylinder, and the boot code (first and second)
+ will be loaded from there. Currently, only double sided, high density
+ (15 sectors per track) floppies are supported. For hard disks, the
+ first 29 sectors of the active partition is reserved for boot code
+ which will be loaded by the first stage boot. All the disk types
+ recognized by BIOS are supported by this bootstrap loader.
+[for 386bsd we load the second stage booter to 9000:0]
+
+
+
+3. The Second Stage Bootstrap Loader
+ --------------------------------
+
+ After the boot code is loaded, the control is passed to the second
+ stage bootstrap loader "boot2()". In order to be able to load the
+ big kernel image (bigger than 512K or 640K, depends on the memory
+ configuration), the second stage boot loader will run on the protected
+ mode. This bootstarp loader does not have any stand alone device
+ drivers, all the I/O's are through the BIOS calls. Since the first
+ stage boot code will no longer be used at this moment, the memory
+ location of the first stage boot code (0000:1000H to 0000:1200H) will
+ be used as an internal buffer for BIOS calls. Immediately after this
+ internal buffer is the GDT table for the second stage boot loader.
+ Since this boot loader needs to switch back and forth between protected
+ and real mode in order to use BIOS calls, the limit of the boot code
+ and boot data segments must not be greater than 64K.
+
+ The boot loader loads the kernel image at memory location above 1 MB
+ to skip the memory hole between 521K/640K and 1MB. After the kernel
+ is loaded, the boot loader stores the information in the stack and
+ then passes control to kernel. Currently, the three information passed
+ fromm the boot loader to the kernel are type of the boot device, size
+ of the base memory and size of the extended memory.
+
+[ 386bsd receives: howto, bootdev]
+
+[ 386bsd is loaded where-ever the "MByte" bits of the load address specify,
+so if you link it for FE100000 it will load to 1MB, but if you link
+it for FE000000 it will load ad 0MB]
+
+[for machines with only 512KB normal ram the kernel will need to be linked
+for 1MB and the bootblocks modified to run below 512KB. (8000:0)]
+
+
+4. The UNIX Startup
+ ----------------
+
+ Since the boot loader loads the kernel image at memory location above
+ 1MB, the kernel has to start as protected mode. In addition, the
+ link editor description file (vuifile) has to indicate that
+ the text and data segments start above 1MB. Also, the boot loader
+ passes the infomation to the kernel through the stack.
+
+[MOST of what is mentionned below is NOT relevant to 386bsd]
+
+5. Disk Layout and Bad Block Handling
+ ---------------------------------
+
+ The System V/386 Release 3.2 (AT) disk layout will be used as the disk
+ layout for the MACH System on the AT platform.
+
+ This disk layout is as follows:
+
+ * Reserve the first sector of cylinder 0 for the DOS boot record which
+ contains the master boot code (446 bytes) and the partition table.
+ (Refer to DOS Technical Reference Manual page 9-6 to 9-10).
+
+ * Reserve the first 29 sectors of the UNIX partition for the first
+ and the second stage bootstrap.
+
+ * Reserve the 30th sector of the UNIX partition for the pdinfo and
+ the vtoc tables.
+
+ * Reserve the 31st to the 34th sectors of the UNIX partition for the
+ bad track and the bad block mapping tables.
+
+ * Reserve up to 253 consecutive tracks when required, beginning with
+ the 35th sector of the UNIX partition, for alternate tracks.
+
+ * Reserve up to 253 consecutive blocks, beginning with the first
+ sector after the alternate tracks area, for alternate blocks.
+
+ SEC
+ 1
+ ----------------------------------------------------
+ | X | | CYL 0, TRK 0
+ ---------------- .......... --------------------
+ | .......... |
+ ---------------- .......... --------------------
+ | .......... |
+ ===============================================================
+ ^ | BOOTSTRAP | CYL N, TRK M
+ | ----------------------------------------------------
+ | | |30 |31 |32 |33 |34 |
+ ---------------------------------------------------- ---
+ U | .......... | ^
+ N ---------------- .......... --------------------- |
+ I | .......... | Alternate Tracks
+ X ---------------- .......... --------------------- |
+ | .......... | V
+ P ---------------------------------------------------- ---
+ A | .......... | ^
+ R ---------------- .......... --------------------- |
+ T | .......... | Alternate Blocks
+ I ---------------- .......... -------------------- |
+ T | .......... | V
+ I ---------------------------------------------------- ---
+ O | Unix root partition starts from here |
+ N ---------------- -----------------
+ | |
+ ----------------------------------------------------
+ | |
+ ----------------------------------------------------
+ | |
+ | ---------------------------------------------------
+ | | |
+ | ----------------------------------------------------
+ V | |
+ ===============================================================
+ | ........ |
+ --------------- ........ --------------
+ | ........ |
+ ----------------------------------------------------
+
+
+ The bad block handling mechanism is as follows:
+
+ * Use the alternate track in the alternate tracks area if the
+ track containing the target sector is bad.
+
+ * Use the alternate block in the alternate blocks area if the
+ target sector is bad.
+
+
+
+
+6. How to make:
+ -----------
+
+ Since the kernel image is loaded above 1 MB, the kernel must start
+ as protected mode. This means that this bootstrap loader will work
+ only when the corresponding changes on the kernel startup code are done.
+
+ The make command to generate this bootstrap loader is:
+
+ make -f boot.mk fdboot (floppy boot loader)
+ make -f boot.mk hdboot (wini boot loader)
+[to make 386bsd bootblocks "make sd wd" (warning: they will be installed
+in /dev/mdec.. take backups)]
diff --git a/sys/i386/boot/biosboot/asm.S b/sys/i386/boot/biosboot/asm.S
new file mode 100644
index 0000000..b291428
--- /dev/null
+++ b/sys/i386/boot/biosboot/asm.S
@@ -0,0 +1,260 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:34:13 rpd
+ * $Id$
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "asm.s"
+
+#include "asm.h"
+
+
+CR0_PE_ON = 0x1
+CR0_PE_OFF = 0xfffffffe
+
+.globl _ouraddr
+ .text
+
+/*
+#
+# real_to_prot()
+# transfer from real mode to protected mode.
+*/
+
+ENTRY(real_to_prot)
+ # guarantee that interrupt is disabled when in prot mode
+ cli
+
+ # load the gdtr
+ addr32
+ data32
+ lgdt EXT(Gdtr)
+
+ # set the PE bit of CR0
+ mov %cr0, %eax
+
+ data32
+ or $CR0_PE_ON, %eax
+ mov %eax, %cr0
+
+ # make intrasegment jump to flush the processor pipeline and
+ # reload CS register
+ data32
+ ljmp $0x18, $xprot
+
+xprot:
+ # we are in USE32 mode now
+ # set up the protected mode segment registers : DS, SS, ES
+ mov $0x20, %eax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ # load idtr so we can debug
+ lidt EXT(Idtr_prot)
+
+ ret
+
+/*
+#
+# prot_to_real()
+# transfer from protected mode to real mode
+#
+*/
+
+ENTRY(prot_to_real)
+
+ # set up a dummy stack frame for the second seg change.
+ movl _ouraddr, %eax
+ sarl $4, %eax
+ pushw %ax
+ movw $xreal, %ax # gas botches pushw $xreal - extra bytes 0, 0
+ pushw %ax # decode to add %al, (%eax) (%al usually 0)
+
+ # Change to use16 mode.
+ ljmp $0x28, $x16
+
+x16:
+ # clear the PE bit of CR0
+ mov %cr0, %eax
+ data32
+ and $CR0_PE_OFF, %eax
+ mov %eax, %cr0
+
+ # make intersegment jmp to flush the processor pipeline
+ # using the fake stack frame set up earlier
+ # and reload CS register
+ lret
+
+xreal:
+ # we are in real mode now
+ # set up the real mode segment registers : DS, SS, ES
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ # load idtr so we can debug
+ addr32
+ data32
+ lidt EXT(Idtr_real)
+
+ data32
+ ret
+
+/*
+#
+# startprog(phyaddr)
+# start the program on protected mode where phyaddr is the entry point
+#
+*/
+
+ENTRY(startprog)
+ push %ebp
+ mov %esp, %ebp
+
+ # get things we need into registers
+ movl 0x8(%ebp), %ecx # entry offset
+ movl 0x0c(%ebp), %eax # &argv
+
+ # make a new stack at 0:0xa0000 (big segs)
+ mov $0x10, %ebx
+ movw %bx, %ss
+ movl $0xa0000, %ebx
+ movl %ebx, %esp
+
+ # push some number of args onto the stack
+ pushl $0 # nominally a cyl offset in the boot.
+ pushl 0x8(%eax) # argv[2] = bootdev
+ pushl 0x4(%eax) # argv[1] = howto
+ pushl $0 # dummy 'return' address
+
+ # push on our entry address
+ mov $0x08, %ebx # segment
+ pushl %ebx
+ pushl %ecx
+
+ # convert over the other data segs
+ mov $0x10, %ebx
+ movw %bx, %ds
+ movw %bx, %es
+
+ # convert the PC (and code seg)
+ lret
+/*
+#
+# pbzero( dst, cnt)
+# where src is a virtual address and dst is a physical address
+*/
+
+ENTRY(pbzero)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %edi # destination
+ mov 0xc(%ebp), %ecx # count
+ mov $0x0, %eax # value
+
+ rep
+ stosb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+/*
+#
+# pcpy(src, dst, cnt)
+# where src is a virtual address and dst is a physical address
+#
+*/
+
+ENTRY(pcpy)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %esi
+ push %edi
+ push %ecx
+
+ cld
+
+ # set %es to point at the flat segment
+ mov $0x10, %eax
+ movw %ax, %es
+
+ mov 0x8(%ebp), %esi # source
+ mov 0xc(%ebp), %edi # destination
+ mov 0x10(%ebp), %ecx # count
+
+ rep
+ movsb
+
+ pop %ecx
+ pop %edi
+ pop %esi
+ pop %es
+ pop %ebp
+
+ ret
+
diff --git a/sys/i386/boot/biosboot/asm.h b/sys/i386/boot/biosboot/asm.h
new file mode 100644
index 0000000..43242bd
--- /dev/null
+++ b/sys/i386/boot/biosboot/asm.h
@@ -0,0 +1,144 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.7 92/02/29 15:33:41 rpd
+ * $Id$
+ */
+
+#define S_ARG0 4(%esp)
+#define S_ARG1 8(%esp)
+#define S_ARG2 12(%esp)
+#define S_ARG3 16(%esp)
+
+#define FRAME pushl %ebp; movl %esp, %ebp
+#define EMARF leave
+
+#define B_ARG0 8(%ebp)
+#define B_ARG1 12(%ebp)
+#define B_ARG2 16(%ebp)
+#define B_ARG3 20(%ebp)
+
+#ifdef wheeze
+
+#define ALIGN 4
+#define EXT(x) x
+#define LEXT(x) x:
+#define LCL(x) ./**/x
+
+#define LB(x,n) ./**/x
+#define LBb(x,n) ./**/x
+#define LBf(x,n) ./**/x
+
+#define SVC lcall $7,$0
+
+#define String .string
+#define Value .value
+#define Times(a,b) [a\*b]
+#define Divide(a,b) [a\\b]
+
+#define INB inb (%dx)
+#define OUTB outb (%dx)
+#define INL inl (%dx)
+#define OUTL outl (%dx)
+
+#else wheeze
+#define ALIGN
+#define LCL(x) x
+
+#define LB(x,n) n
+#ifdef __STDC__
+#define EXT(x) _ ## x
+#define LEXT(x) _ ## x ## :
+
+#define LBb(x,n) n ## b
+#define LBf(x,n) n ## f
+#else __STDC__
+#define EXT(x) _/**/x
+#define LEXT(x) _/**/x/**/:
+#define LBb(x,n) n/**/b
+#define LBf(x,n) n/**/f
+#endif __STDC__
+#define SVC .byte 0x9a; .long 0; .word 0x7
+
+#define String .ascii
+#define Value .word
+#define Times(a,b) (a*b)
+#define Divide(a,b) (a/b)
+
+#define INB inb %dx, %al
+#define OUTB outb %al, %dx
+#define INL inl %dx, %eax
+#define OUTL outl %eax, %dx
+
+#endif wheeze
+
+#define addr32 .byte 0x67
+#define data32 .byte 0x66
+
+#ifdef GPROF
+#ifdef __STDC__
+
+#define MCOUNT .data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ASENTRY(x) .globl x; .align ALIGN; x ## : ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+
+#else __STDC__
+
+#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x: ; \
+ pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp;
+
+#endif __STDC__
+#else GPROF
+#ifdef __STDC__
+
+#define MCOUNT
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x ## :
+
+#else __STDC__
+
+#define MCOUNT
+#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \
+ .align ALIGN; LEXT(x) LEXT(y)
+#define ASENTRY(x) .globl x; .align ALIGN; x:
+
+#endif __STDC__
+#endif GPROF
+
+#define Entry(x) .globl EXT(x); .align ALIGN; LEXT(x)
+#define DATA(x) .globl EXT(x); .align ALIGN; LEXT(x)
diff --git a/sys/i386/boot/biosboot/bios.S b/sys/i386/boot/biosboot/bios.S
new file mode 100644
index 0000000..687ca18
--- /dev/null
+++ b/sys/i386/boot/biosboot/bios.S
@@ -0,0 +1,329 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
+ * $Id$
+ */
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+ .file "bios.s"
+
+#include "asm.h"
+ .text
+
+/*
+# biosread(dev, cyl, head, sec, nsec, offset)
+# Read "nsec" sectors from disk to offset "offset" in boot segment
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+ENTRY(biosread)
+ push %ebp
+ mov %esp, %ebp
+
+ push %ebx
+ push %ecx
+ push %edx
+ push %es
+
+ movb 0x10(%ebp), %dh
+ movw 0x0c(%ebp), %cx
+ xchgb %ch, %cl # cylinder; the highest 2 bits of cyl is in %cl
+ rorb $2, %cl
+ movb 0x14(%ebp), %al
+ orb %al, %cl
+ incb %cl # sector; sec starts from 1, not 0
+ movb 0x8(%ebp), %dl # device
+ movl 0x1c(%ebp), %ebx # offset
+ # prot_to_real will set %es to BOOTSEG
+
+ call EXT(prot_to_real) # enter real mode
+ movb $0x2, %ah # subfunction
+ addr32
+ movb 0x18(%ebp), %al # number of sectors
+
+ sti
+ int $0x13
+ cli
+
+ mov %eax, %ebx # save return value (actually movw %ax, %bx)
+
+ data32
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+ movb %bh, %al # return value in %ax
+
+ pop %es
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %ebp
+
+ ret
+
+
+/*
+# putc(ch)
+# BIOS call "INT 10H Function 0Eh" to write character to console
+# Call with %ah = 0x0e
+# %al = character
+# %bh = page
+# %bl = foreground color ( graphics modes)
+*/
+
+
+ENTRY(putc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+ push %ecx
+
+ movb 0x8(%ebp), %cl
+
+ call EXT(prot_to_real)
+
+ data32
+ mov $0x1, %ebx # %bh=0, %bl=1 (blue)
+ movb $0xe, %ah
+ movb %cl, %al
+ sti
+ int $0x10 # display a byte
+ cli
+
+ data32
+ call EXT(real_to_prot)
+
+ pop %ecx
+ pop %ebx
+ pop %ebp
+ ret
+
+
+/*
+# getc()
+# BIOS call "INT 16H Function 00H" to read character from keyboard
+# Call with %ah = 0x0
+# Return: %ah = keyboard scan code
+# %al = ASCII character
+*/
+
+ENTRY(getc)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx # save %ebx
+
+ call EXT(prot_to_real)
+
+ movb $0x0, %ah
+ sti
+ int $0x16
+ cli
+
+ movb %al, %bl # real_to_prot uses %eax
+
+ data32
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+/*
+# ischar()
+# if there is a character pending, return it; otherwise return 0
+# BIOS call "INT 16H Function 01H" to check whether a character is pending
+# Call with %ah = 0x1
+# Return:
+# If key waiting to be input:
+# %ah = keyboard scan code
+# %al = ASCII character
+# Zero flag = clear
+# else
+# Zero flag = set
+*/
+ENTRY(ischar)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ xor %ebx, %ebx
+ movb $0x1, %ah
+ sti
+ int $0x16
+ cli
+ data32
+ jz nochar
+ movb %al, %bl
+
+nochar:
+ data32
+ call EXT(real_to_prot)
+
+ xor %eax, %eax
+ movb %bl, %al
+
+ pop %ebx
+ pop %ebp
+ ret
+
+/*
+#
+# get_diskinfo(): return a word that represents the
+# max number of sectors and heads and drives for this device
+#
+*/
+
+ENTRY(get_diskinfo)
+ push %ebp
+ mov %esp, %ebp
+ push %es
+ push %ebx
+ push %ecx
+ push %edx
+
+ movb 0x8(%ebp), %dl # diskinfo(drive #)
+ call EXT(prot_to_real) # enter real mode
+
+ movb $0x8, %ah # ask for disk info
+
+ sti
+ int $0x13
+ cli
+
+ jnc ok
+ /*
+ * Urk. Call failed. It is not supported for floppies by old BIOS's.
+ * Guess it's a 15-sector floppy. Initialize all the registers for
+ * documentation, although we only need head and sector counts.
+ */
+ subb %ah, %ah # %ax = 0
+ movb %al, %al
+ movb %ah, %bh # %bh = 0
+ movb $2, %bl # %bl bits 0-3 = drive type, 2 = 1.2M
+ movb $79, %ch # max track
+ movb $15, %cl # max sector
+ movb $1, %dh # max head
+ movb $1, %dl # # floppy drives installed
+ # es:di = parameter table
+ # carry = 0
+ok:
+
+ data32
+ call EXT(real_to_prot) # back to protected mode
+
+ xor %eax, %eax
+
+ /*form a longword representing all this gunk*/
+ movb %dh, %ah # max head
+ andb $0x3f, %cl # mask of cylinder gunk
+ movb %cl, %al # max sector (and # sectors)
+
+ pop %edx
+ pop %ecx
+ pop %ebx
+ pop %es
+ pop %ebp
+ ret
+
+/*
+#
+# memsize(i) : return the memory size in KB. i == 0 for conventional memory,
+# i == 1 for extended memory
+# BIOS call "INT 12H" to get conventional memory size
+# BIOS call "INT 15H, AH=88H" to get extended memory size
+# Both have the return value in AX.
+#
+*/
+
+ENTRY(memsize)
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+
+ mov 8(%ebp), %ebx
+
+ call EXT(prot_to_real) # enter real mode
+
+ cmpb $0x1, %bl
+ data32
+ je xext
+
+ sti
+ int $0x12
+ cli
+ data32
+ jmp xdone
+
+xext: movb $0x88, %ah
+ sti
+ int $0x15
+ cli
+
+xdone:
+ mov %eax, %ebx
+
+ data32
+ call EXT(real_to_prot)
+
+ mov %ebx, %eax
+ pop %ebx
+ pop %ebp
+ ret
diff --git a/sys/i386/boot/biosboot/boot.c b/sys/i386/boot/biosboot/boot.c
new file mode 100644
index 0000000..e186bdc
--- /dev/null
+++ b/sys/i386/boot/biosboot/boot.c
@@ -0,0 +1,308 @@
+/*
+ * 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.13 1994/06/14 07:31:42 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 <sys/param.h>
+#include "boot.h"
+#include <a.out.h>
+#include <sys/reboot.h>
+
+struct exec head;
+int argv[10], esym;
+char *name;
+char *names[] = {
+ "/386bsd", "/o386bsd", "/386bsd.old"
+};
+#define NUMNAMES (sizeof(names)/sizeof(char *))
+
+extern int end;
+boot(drive)
+int drive;
+{
+ int loadflags, currname = 0;
+ char *t;
+
+ printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory [%s]\n",
+ ouraddr,
+ argv[7] = memsize(0),
+ argv[8] = memsize(1),
+ "$Revision: 1.14 $");
+ printf("use hd(1,a)/386bsd to boot sd0 when wd0 is also installed\n");
+ gateA20();
+loadstart:
+ /***************************************************************\
+ * 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 */
+ name = names[currname++];
+
+ loadflags = 0;
+ if (currname == NUMNAMES)
+ currname = 0;
+ getbootdev(&loadflags);
+ if (openrd()) {
+ printf("Can't find %s\n", name);
+ goto loadstart;
+ }
+/* if (inode.i_mode&IEXEC)
+ loadflags |= RB_KDB;
+*/
+ loadprog(loadflags);
+ goto loadstart;
+}
+
+loadprog(howto)
+ int howto;
+{
+ long int startaddr;
+ long int addr; /* physical address.. not directly useable */
+ long int addr0;
+ int i;
+ static int (*x_entry)() = 0;
+ unsigned char tmpbuf[4096]; /* we need to load the first 4k here */
+
+ argv[3] = 0;
+ argv[4] = 0;
+ read(&head, sizeof(head));
+ if ( N_BADMAG(head)) {
+ printf("Invalid format!\n");
+ return;
+ }
+
+ poff = N_TXTOFF(head);
+ /*if(poff==0)
+ poff = 32;*/
+
+ startaddr = (int)head.a_entry;
+ addr = (startaddr & 0x00ffffff); /* some MEG boundary */
+ addr0 = addr;
+ printf("Booting %s(%d,%c)%s @ 0x%x\n"
+ , devs[maj]
+ , unit
+ , 'a'+part
+ , name
+ , addr);
+ if(addr < ouraddr)
+ {
+ if((addr + head.a_text + head.a_data) > ouraddr)
+ {
+ printf("kernel overlaps loader\n");
+ return;
+ }
+ if((addr + head.a_text + head.a_data + head.a_bss) > 0xa0000)
+ {
+ printf("bss exceeds 640k limit\n");
+ return;
+ }
+ }
+ printf("text=0x%x ", head.a_text);
+ /********************************************************/
+ /* LOAD THE TEXT SEGMENT */
+ /* don't clobber the first 4k yet (BIOS NEEDS IT) */
+ /********************************************************/
+ read(tmpbuf,4096);
+ addr += 4096;
+ xread(addr, head.a_text - 4096);
+ addr += head.a_text - 4096;
+
+ /********************************************************/
+ /* Load the Initialised data after the text */
+ /********************************************************/
+ while (addr & CLOFSET)
+ *(char *)addr++ = 0;
+
+ printf("data=0x%x ", head.a_data);
+ xread(addr, head.a_data);
+ addr += head.a_data;
+
+ /********************************************************/
+ /* Skip over the uninitialised data */
+ /* (but clear it) */
+ /********************************************************/
+ printf("bss=0x%x ", head.a_bss);
+ if( (addr < ouraddr) && ((addr + head.a_bss) > ouraddr))
+ {
+ pbzero(addr,ouraddr - (int)addr);
+ }
+ else
+ {
+ pbzero(addr,head.a_bss);
+ }
+ argv[3] = (addr += head.a_bss);
+
+#ifdef LOADSYMS /* not yet, haven't worked this out yet */
+ if (addr > 0x100000)
+ {
+ /********************************************************/
+ /*copy in the symbol header */
+ /********************************************************/
+ pcpy(&head.a_syms, addr, sizeof(head.a_syms));
+ addr += sizeof(head.a_syms);
+
+ /********************************************************/
+ /* READ in the symbol table */
+ /********************************************************/
+ printf("symbols=[+0x%x", head.a_syms);
+ xread(addr, head.a_syms);
+ addr += head.a_syms;
+
+ /********************************************************/
+ /* Followed by the next integer (another header) */
+ /* more debug symbols? */
+ /********************************************************/
+ read(&i, sizeof(int));
+ pcpy(&i, addr, sizeof(int));
+ i -= sizeof(int);
+ addr += sizeof(int);
+
+
+ /********************************************************/
+ /* and that many bytes of (debug symbols?) */
+ /********************************************************/
+ printf("+0x%x] ", i);
+ xread(addr, i);
+ addr += i;
+ }
+#endif LOADSYMS
+ /********************************************************/
+ /* and note the end address of all this */
+ /********************************************************/
+
+ argv[4] = ((addr+sizeof(int)-1))&~(sizeof(int)-1);
+ printf("total=0x%x ",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 = getchar();
+ 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, 0, 0, unit, part)) ;
+ argv[5] = (head.a_entry &= 0xfffffff);
+ argv[6] = (int) &x_entry;
+ argv[0] = 8;
+ /****************************************************************/
+ /* copy that first page and overwrite any BIOS variables */
+ /****************************************************************/
+ printf("entry point=0x%x\n" ,((int)startaddr) & 0xffffff);
+ /* Under no circumstances overwrite precious BIOS variables! */
+ pcpy(tmpbuf, addr0, 0x400);
+ pcpy(tmpbuf + 0x500, addr0 + 0x500, 4096 - 0x500);
+ startprog(((int)startaddr & 0xffffff),argv);
+}
+
+char namebuf[100];
+getbootdev(howto)
+ int *howto;
+{
+ char c, *ptr = namebuf;
+ printf("Boot: [[[%s(%d,%c)]%s][-s][-a][-d]] :- "
+ , devs[maj]
+ , unit
+ , 'a'+part
+ , name);
+ if (gets(namebuf)) {
+ while (c=*ptr) {
+ while (c==' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c=='-')
+ while ((c = *++ptr) && c!=' ')
+ switch (c) {
+ case 'r':
+ *howto |= RB_DFLTROOT; continue;
+ case 'a':
+ *howto |= RB_ASKNAME; continue;
+ case 's':
+ *howto |= RB_SINGLE; continue;
+ case 'd':
+ *howto |= RB_KDB; continue;
+ case 'b':
+ *howto |= RB_HALT; continue;
+ }
+ else {
+ name = ptr;
+ while ((c = *++ptr) && c!=' ');
+ if (c)
+ *ptr++ = 0;
+ }
+ }
+ } else
+ printf("\n");
+}
+
diff --git a/sys/i386/boot/biosboot/boot.h b/sys/i386/boot/biosboot/boot.h
new file mode 100644
index 0000000..f77f882
--- /dev/null
+++ b/sys/i386/boot/biosboot/boot.h
@@ -0,0 +1,40 @@
+/*
+ * 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$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <ufs/quota.h>
+#include <ufs/fs.h>
+#include <ufs/inode.h>
+
+extern char *devs[], *name, *iodest;
+extern struct fs *fs;
+extern struct inode inode;
+extern int dosdev, unit, part, maj, boff, poff, bnum, cnt;
+extern long int ouraddr;
diff --git a/sys/i386/boot/biosboot/boot2.S b/sys/i386/boot/biosboot/boot2.S
new file mode 100644
index 0000000..f78ce10
--- /dev/null
+++ b/sys/i386/boot/biosboot/boot2.S
@@ -0,0 +1,177 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
+ * $Id: boot2.S,v 1.3 1993/11/13 04:43:25 rgrimes Exp $
+ */
+
+#include "asm.h"
+
+/* Conventional GDT indexes. */
+#define BOOT_CS_INDEX 3
+#define BOOT_CS16_INDEX 5
+#define BOOT_DS_INDEX 4
+#define DB_CS_INDEX 14
+#define DB_CS16_INDEX 15
+#define DB_DS_INDEX 16
+#define GDT_INDEX 17
+
+/* Vector numbers. */
+#define BREAKPOINT_VECTOR 3
+#define DEBUG_VECTOR 1
+
+/*
+ * boot2() -- second stage boot
+ */
+
+.globl EXT(ouraddr)
+
+ENTRY(boot2)
+ data32
+ subl %eax, %eax
+ mov %cs, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ data32
+ shll $4, %eax
+ addr32
+ data32
+ movl %eax, EXT(ouraddr)
+
+ /* fix up GDT entries for bootstrap */
+#define FIXUP(gdt_index) \
+ addr32; \
+ movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \
+ addr32; \
+ movb %bl, EXT(Gdt)+(8*gdt_index)+4
+
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(BOOT_CS_INDEX)
+ FIXUP(BOOT_CS16_INDEX)
+ FIXUP(BOOT_DS_INDEX)
+
+ /* fix up GDT entry for GDT, and GDT and IDT pointers */
+ data32
+ movl %eax, %ecx
+ data32
+ addl $ EXT(Gdt), %eax
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(GDT_INDEX)
+ addr32
+ data32
+ movl %eax, EXT(Gdtr)+2
+ data32
+ addl $ EXT(Idt), %ecx
+ addr32
+ data32
+ movl %ecx, EXT(Idtr_prot)+2
+
+ /* %es = vector table segment for a while */
+ push %es
+ data32
+ subl %eax, %eax
+ mov %ax, %es
+
+ /* fix up GDT entries for bdb */
+ data32
+ movl $4*DEBUG_VECTOR, %esi
+ addr32
+ movl %es: 2(%esi), %eax /* actually movw to %ax */
+ data32
+ shll $4, %eax
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(DB_CS_INDEX)
+ FIXUP(DB_CS16_INDEX)
+ FIXUP(DB_DS_INDEX)
+
+ /* Fetch entry points of bdb's protected mode trap handlers. These
+ * are stored at 2 before the corresponding entry points for real mode.
+ */
+ data32
+ subl %ebx, %ebx
+ addr32
+ movl %es: (%esi), %ebx /* actually movw to %bx */
+ data32
+ subl %ecx, %ecx
+ addr32
+ movl %es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx
+ /* actually movw to %cx */
+
+ /* %es = bdb segment for a while */
+ data32
+ shrl $4, %eax
+ mov %ax, %es
+
+ /* fix up IDT entries for bdb */
+ data32
+ subl $2, %ebx /* calculate EA to check it */
+ jb 1f /* give up if it would trap */
+ addr32
+ movl %es: (%ebx), %eax /* actually movw to %ax */
+ addr32
+ movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
+1:
+ data32
+ subl $2, %ecx
+ jb 1f
+ addr32
+ movl %es: (%ecx), %eax /* actually movw to %ax */
+ addr32
+ movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
+1:
+
+ /* finished with groping in real mode segments */
+ pop %es
+
+ /* change to protected mode */
+ data32
+ call EXT(real_to_prot)
+
+ /* clear the bss */
+ movl $ EXT(edata), %edi /* no EXT(_edata) - krufty ld */
+ movl $ EXT(end), %ecx /* or EXT(_end) */
+ subl %edi, %ecx
+ subb %al, %al
+ rep
+ stosb
+
+ movzbl %dl, %edx /* discard head (%dh) and random high bits */
+ pushl %edx
+ call EXT(boot)
+oops:
+ hlt
+ jmp oops
+
+ .data
+ .align 2
+#if 0 /* XXX this would give losing "_ouraddr :". Better declared in C */
+EXT(ouraddr):
+#else
+_ouraddr:
+#endif
+ .long 0
diff --git a/sys/i386/boot/biosboot/disk.c b/sys/i386/boot/biosboot/disk.c
new file mode 100644
index 0000000..a63ca5a
--- /dev/null
+++ b/sys/i386/boot/biosboot/disk.c
@@ -0,0 +1,281 @@
+/*
+ * 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 $
+ */
+
+/*
+ * 93/10/08 bde
+ * If there is no 386BSD partition, initialize the label sector with
+ * LABELSECTOR instead of with garbage.
+ *
+ * 93/08/22 bde
+ * Fixed reading of bad sector table. It is at the end of the 'c'
+ * partition, which is not always at the end of the disk.
+ */
+
+#include "boot.h"
+#ifdef DO_BAD144
+#include <sys/dkbad.h>
+#endif DO_BAD144
+#include <sys/disklabel.h>
+
+#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)
+
+char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0};
+
+#ifdef DO_BAD144
+struct dkbad dkb;
+int do_bad144;
+int bsize;
+#endif DO_BAD144
+
+int spt, spc;
+
+char *iodest;
+struct fs *fs;
+struct inode inode;
+int dosdev, unit, part, maj, boff, poff, bnum, cnt;
+
+/*#define EMBEDDED_DISKLABEL 1*/
+extern struct disklabel disklabel;
+/*struct disklabel disklabel;*/
+
+devopen()
+{
+ struct dos_partition *dptr;
+ struct disklabel *dl;
+ int dosdev = inode.i_dev;
+ int i, sector, di;
+
+ di = get_diskinfo(dosdev);
+ spc = (spt = SPT(di)) * 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 *)0)+DOSPARTOFF);
+ sector = LABELSECTOR;
+ for (i = 0; i < NDOSPART; i++, dptr++)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start + LABELSECTOR;
+ break;
+ }
+ Bread(dosdev, sector++);
+ dl=((struct disklabel *)0);
+ 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;
+ int dkbbnum;
+ struct dkbad *dkbptr;
+
+ /* find the first readable bad sector table */
+ /* some of this code is copied from ufs/ufs_disksubr.c */
+ /* including the bugs :-( */
+ /* read a bad sector table */
+
+#define BAD144_PART 2 /* XXX scattered magic numbers */
+#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ dkbbnum = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ dkbbnum = dl->d_secperunit;
+ dkbbnum -= dl->d_nsectors;
+
+ if (dl->d_secsize > DEV_BSIZE)
+ dkbbnum *= dl->d_secsize / DEV_BSIZE;
+ else
+ dkbbnum /= DEV_BSIZE / dl->d_secsize;
+ i = 0;
+ do_bad144 = 0;
+ do {
+ /* XXX: what if the "DOS sector" < 512 bytes ??? */
+ Bread(dosdev, dkbbnum + i);
+ dkbptr = (struct dkbad *) 0;
+/* 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 && i < dl->d_nsectors);
+ if (!do_bad144)
+ printf("Bad bad sector table\n");
+ else
+ printf("Using bad sector table at %d\n", dkbbnum+i);
+ }
+#endif DO_BAD144
+ }
+ return 0;
+}
+
+devread()
+{
+ int offset, sector = bnum;
+ int dosdev = inode.i_dev;
+ for (offset = 0; offset < cnt; offset += BPS)
+ {
+ Bread(dosdev, badsect(dosdev, sector++));
+ bcopy(0, iodest+offset, BPS);
+ }
+}
+
+#define I_ADDR ((void *) 0) /* XXX where all reads go */
+
+/* Read ahead buffer large enough for one track on a 1440K floppy. For
+ * reading from floppies, the bootstrap has to be loaded on a 64K boundary
+ * to ensure that this buffer doesn't cross a 64K DMA boundary.
+ */
+#define RA_SECTORS 18
+static char ra_buf[RA_SECTORS * BPS];
+static int ra_dev;
+static int ra_end;
+static int ra_first;
+
+Bread(dosdev,sector)
+ int dosdev,sector;
+{
+ if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
+ {
+ int cyl, head, sec, nsec;
+
+ cyl = sector/spc;
+ head = (sector % spc) / spt;
+ sec = sector % spt;
+ nsec = spt - sec;
+ if (nsec > RA_SECTORS)
+ nsec = RA_SECTORS;
+ twiddle();
+ if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
+ {
+ nsec = 1;
+ twiddle();
+ while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
+ printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
+ twiddle();
+ }
+ }
+ ra_dev = dosdev;
+ ra_first = sector;
+ ra_end = sector + nsec;
+ }
+ bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);
+}
+
+badsect(dosdev, sector)
+ int dosdev, sector;
+{
+ int i;
+#ifdef DO_BAD144
+ if (do_bad144) {
+ u_short cyl;
+ u_short head;
+ u_short sec;
+ int newsec;
+ struct disklabel *dl = &disklabel;
+
+ /* XXX */
+ /* from wd.c */
+ /* bt_cyl = cylinder number in sorted order */
+ /* bt_trksec is actually (head << 8) + sec */
+
+ /* only remap sectors in the partition */
+ if (sector < boff || sector >= boff + bsize) {
+ goto no_remap;
+ }
+
+ cyl = sector / dl->d_secpercyl;
+ head = (sector % dl->d_secpercyl) / dl->d_nsectors;
+ sec = 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 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ newsec = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ newsec = dl->d_secperunit;
+ newsec -= dl->d_nsectors + i + 1;
+ return newsec;
+ }
+#endif DO_BAD144
+ no_remap:
+ return sector;
+}
diff --git a/sys/i386/boot/biosboot/io.c b/sys/i386/boot/biosboot/io.c
new file mode 100644
index 0000000..ee441f0
--- /dev/null
+++ b/sys/i386/boot/biosboot/io.c
@@ -0,0 +1,214 @@
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
+ * $Id: io.c,v 1.5 1994/06/15 19:09:14 jkh Exp $
+ */
+
+#include <i386/include/pio.h>
+
+#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
+#define K_STATUS 0x64 /* keyboard status */
+#define K_CMD 0x64 /* keybd ctlr command (write-only) */
+
+#define K_OBUF_FUL 0x01 /* output buffer full */
+#define K_IBUF_FUL 0x02 /* input buffer full */
+
+#define KC_CMD_WIN 0xd0 /* read output port */
+#define KC_CMD_WOUT 0xd1 /* write output port */
+#define KB_A20 0xdf /* enable A20,
+ enable output buffer full interrupt
+ enable data line
+ enable clock line */
+
+/*
+ * Gate A20 for high memory
+ */
+unsigned char x_20 = KB_A20;
+gateA20()
+{
+#ifdef IBM_L40
+ outb(0x92, 0x2);
+#else IBM_L40
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_OBUF_FUL)
+ (void)inb(K_RDWR);
+
+ outb(K_CMD, KC_CMD_WOUT);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ outb(K_RDWR, x_20);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+#endif IBM_L40
+}
+
+/* printf - only handles %d as decimal, %c as char, %s as string */
+
+printf(format,data)
+ char *format;
+ int data;
+{
+ int *dataptr = &data;
+ char c;
+
+ reset_twiddle();
+ while (c = *format++)
+ if (c != '%')
+ putchar(c);
+ else
+ switch (c = *format++) {
+ case 'd': {
+ int num = *dataptr++;
+ char buf[10], *ptr = buf;
+ if (num<0) {
+ num = -num;
+ putchar('-');
+ }
+ do
+ *ptr++ = '0'+num%10;
+ while (num /= 10);
+ do
+ putchar(*--ptr);
+ while (ptr != buf);
+ break;
+ }
+ case 'x': {
+ int num = *dataptr++, dig;
+ char buf[8], *ptr = buf;
+ do
+ *ptr++ = (dig=(num&0xf)) > 9?
+ 'a' + dig - 10 :
+ '0' + dig;
+ while (num >>= 4);
+ do
+ putchar(*--ptr);
+ while (ptr != buf);
+ break;
+ }
+ case 'c': putchar((*dataptr++)&0xff); break;
+ case 's': {
+ char *ptr = (char *)*dataptr++;
+ while (c = *ptr++)
+ putchar(c);
+ break;
+ }
+ }
+}
+
+putchar(c)
+{
+ if (c == '\n')
+ putc('\r');
+ putc(c);
+}
+
+getchar()
+{
+ int c;
+
+ if ((c=getc()) == '\r')
+ c = '\n';
+ if (c == '\b') {
+ putchar('\b');
+ putchar(' ');
+ }
+ putchar(c);
+ return(c);
+}
+
+#if BOOTWAIT
+spinwait(i)
+int i;
+{
+ while (--i >= 0)
+ (void)inb(0x84);
+}
+#endif
+
+gets(buf)
+char *buf;
+{
+ int i;
+ char *ptr=buf;
+
+#if BOOTWAIT
+ for (i = BOOTWAIT; i>0; spinwait(10000),i--)
+#endif
+ if (ischar())
+ for (;;)
+ switch(*ptr = getchar() & 0xff) {
+ case '\n':
+ case '\r':
+ *ptr = '\0';
+ return 1;
+ case '\b':
+ if (ptr > buf) ptr--;
+ continue;
+ default:
+ ptr++;
+ }
+ return 0;
+}
+
+strcmp(s1, s2)
+char *s1, *s2;
+{
+ while (*s1 == *s2) {
+ if (!*s1++)
+ return 0;
+ s2++;
+ }
+ return 1;
+}
+
+bcopy(from, to, len)
+char *from, *to;
+int len;
+{
+ while (len-- > 0)
+ *to++ = *from++;
+}
+
+static int tw_on;
+static int tw_pos;
+static char tw_chars[] = "|/-\\";
+
+reset_twiddle()
+{
+ if (tw_on)
+ putchar('\b');
+ tw_on = 0;
+ tw_pos = 0;
+}
+
+twiddle()
+{
+ if (tw_on)
+ putchar('\b');
+ else
+ tw_on = 1;
+ putchar(tw_chars[tw_pos++]);
+ tw_pos %= (sizeof(tw_chars) - 1);
+}
diff --git a/sys/i386/boot/biosboot/start.S b/sys/i386/boot/biosboot/start.S
new file mode 100644
index 0000000..aa65212
--- /dev/null
+++ b/sys/i386/boot/biosboot/start.S
@@ -0,0 +1,292 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
+ * $Id: start.S,v 1.2 1993/10/16 19:11:38 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 "asm.h"
+
+ .file "start.s"
+
+BOOTSEG = 0x9000 # boot will be loaded here (below 640K)
+BOOTSTACK = 0xe000 # boot stack
+SIGNATURE = 0xaa55
+LOADSZ = 15 # size of unix boot
+PARTSTART = 0x1be # starting address of partition table
+NUMPART = 4 # number of partitions in partition table
+PARTSZ = 16 # each partition table entry is 16 bytes
+BSDPART = 0xA5 # value of boot_ind, means bootable partition
+BOOTABLE = 0x80 # value of boot_ind, means bootable partition
+
+ .text
+
+ENTRY(boot1)
+ # start (aka boot1) is loaded at 0x0:0x7c00 but we want 0x7c0:0
+ # ljmp to the next instruction to adjust %cs
+ data32
+ ljmp $0x7c0, $start
+
+start:
+ # set up %ds
+ mov %cs, %ax
+ mov %ax, %ds
+
+ # set up %ss and %esp
+ data32
+ mov $BOOTSEG, %eax
+ mov %ax, %ss
+ data32
+ mov $BOOTSTACK, %esp
+
+ /*** set up %es, (where we will load boot2 to) ***/
+ mov %ax, %es
+
+#ifdef DEBUG
+ data32
+ mov $one, %esi
+ data32
+ call message
+#endif
+
+ # bootstrap passes us drive number in %dl
+ cmpb $0x80, %dl
+ data32
+ jae hd
+
+fd:
+ mov $0x0, %dl
+# reset the disk system
+#ifdef DEBUG
+ data32
+ mov $two, %esi
+ data32
+ call message
+#endif
+ movb $0x0, %ah
+ int $0x13
+ data32
+ mov $0x0001, %ecx # cyl 0, sector 1
+ movb $0, %dh # head
+#ifdef DEBUG
+ data32
+ mov $three, %esi
+ data32
+ call message
+#endif
+ data32
+ jmp load
+
+hd: /**** load sector 0 into the BOOTSEG ****/
+#ifdef DEBUG
+ data32
+ mov $four, %esi
+ data32
+ call message
+#endif
+ data32
+ mov $0x0201, %eax
+ xor %ebx, %ebx # %bx = 0
+ data32
+ mov $0x0001, %ecx
+#ifdef DEBUG
+ data32
+ mov $five, %esi
+ data32
+ call message
+#endif
+ data32
+ andl $0xff, %edx
+ /*mov $0x0080, %edx*/
+ int $0x13
+ data32
+ jb read_error
+
+ /***# find the first 386BSD partition *****/
+ data32
+ mov $PARTSTART, %ebx
+ data32
+ mov $NUMPART, %ecx
+again:
+ addr32
+ movb %es:4(%ebx), %al
+ cmpb $BSDPART, %al
+ data32
+ je found
+ data32
+ add $PARTSZ, %ebx
+ data32
+ loop again
+ data32
+ mov $enoboot, %esi
+ data32
+ jmp err_stop
+
+
+/*
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+found:
+ addr32
+ movb %es:1(%ebx), %dh /* head */
+ addr32
+ movl %es:2(%ebx), %ecx /*sect, cyl (+ 2 bytes junk in top word) */
+
+load:
+ movb $0x2, %ah /* function 2 */
+ movb $LOADSZ, %al /* number of blocks */
+ xor %ebx, %ebx /* %bx = 0, put it at 0 in the BOOTSEG */
+ int $0x13
+ data32
+ jb read_error
+
+ # ljmp to the second stage boot loader (boot2).
+ # After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
+ # as an internal buffer "intbuf".
+
+#ifdef DEBUG
+ data32
+ mov $six, %esi
+ data32
+ call message
+#endif
+ data32
+ ljmp $BOOTSEG, $ EXT(boot2)
+
+#
+# read_error
+#
+
+read_error:
+ data32
+ mov $eread, %esi
+err_stop:
+ data32
+ call message
+ data32
+ jmp stop
+
+#
+# message: write the error message in %ds:%esi to console
+#
+
+message:
+/*
+ # Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+ # %ah = 0xe %al = character
+ # %bh = page %bl = foreground color (graphics modes)
+*/
+
+ data32
+ push %eax
+ data32
+ push %ebx
+ data32
+ mov $0x0001, %ebx
+ cld
+
+nextb:
+ lodsb # load a byte into %al
+ cmpb $0x0, %al
+ data32
+ je done
+ movb $0xe, %ah
+ int $0x10 # display a byte
+ data32
+ jmp nextb
+done:
+ data32
+ pop %ebx
+ data32
+ pop %eax
+ data32
+ ret
+
+stop: hlt
+ data32
+ jmp stop # halt doesnt actually halt forever
+
+/* error messages */
+
+#ifdef DEBUG
+one: String "1\r\n\0"
+two: String "2\r\n\0"
+three: String "3\r\n\0"
+four: String "4\r\n\0"
+five: String "5\r\n\0"
+six: String "6\r\n\0"
+seven: String "7\r\n\0"
+#endif DEBUG
+eread: String "Read error\r\n\0"
+enoboot: String "No bootable partition\r\n\0"
+endofcode:
+/* throw in a partition in case we are block0 as well */
+/* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
+ . = EXT(boot1) + PARTSTART
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte BOOTABLE,0,1,0,BSDPART,255,255,255
+ .long 0,50000
+/* the last 2 bytes in the sector 0 contain the signature */
+ . = EXT(boot1) + 0x1fe
+ .value SIGNATURE
+ENTRY(disklabel)
+ . = EXT(boot1) + 0x400
diff --git a/sys/i386/boot/biosboot/sys.c b/sys/i386/boot/biosboot/sys.c
new file mode 100644
index 0000000..4ffe171
--- /dev/null
+++ b/sys/i386/boot/biosboot/sys.c
@@ -0,0 +1,232 @@
+/*
+ * 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$
+ */
+
+#include "boot.h"
+#include <sys/dir.h>
+#include <sys/reboot.h>
+
+/* #define BUFSIZE 4096 */
+#define BUFSIZE MAXBSIZE
+
+char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
+
+int xread(addr, size)
+ char * addr;
+ int size;
+{
+ int count = BUFSIZE;
+ while (size > 0) {
+ if (BUFSIZE > size)
+ count = size;
+ read(buf, count);
+ pcpy(buf, addr, count);
+ size -= count;
+ addr += count;
+ }
+}
+
+read(buffer, count)
+ int count;
+ char *buffer;
+{
+ int logno, off, size;
+ int 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;
+ }
+}
+
+find(path)
+ char *path;
+{
+ char *rest, ch;
+ int 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;
+}
+
+char mapbuf[MAXBSIZE];
+int mapblock = 0;
+
+block_map(file_block)
+ int 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 (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
+}
+
+openrd()
+{
+ char **devp, *cp = name;
+ /*******************************************************\
+ * If bracket given look for preceding device name *
+ \*******************************************************/
+ while (*cp && *cp!='(')
+ cp++;
+ if (!*cp)
+ {
+ cp = name;
+ }
+ else
+ {
+ if (cp++ != name)
+ {
+ for (devp = devs; *devp; devp++)
+ if (name[0] == (*devp)[0] &&
+ name[1] == (*devp)[1])
+ break;
+ if (!*devp)
+ {
+ printf("Unknown device\n");
+ return 1;
+ }
+ maj = devp-devs;
+ }
+ /*******************************************************\
+ * Look inside brackets for unit number, and partition *
+ \*******************************************************/
+ if (*cp >= '0' && *cp <= '9')
+ if ((unit = *cp++ - '0') > 1)
+ {
+ printf("Bad unit\n");
+ return 1;
+ }
+ if (!*cp || (*cp == ',' && !*++cp))
+ return 1;
+ if (*cp >= 'a' && *cp <= 'p')
+ part = *cp++ - 'a';
+ while (*cp && *cp++!=')') ;
+ if (!*cp)
+ return 1;
+ }
+ switch(maj)
+ {
+ case 1:
+ dosdev = unit | 0x80;
+ unit = 0;
+ break;
+ case 0:
+ case 4:
+ dosdev = unit | 0x80;
+ break;
+ case 2:
+ dosdev = unit;
+ break;
+ case 3:
+ printf("Wangtek unsupported\n");
+ return 1;
+ break;
+ }
+ 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/biosboot/table.c b/sys/i386/boot/biosboot/table.c
new file mode 100644
index 0000000..c53173d
--- /dev/null
+++ b/sys/i386/boot/biosboot/table.c
@@ -0,0 +1,125 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:36:43 rpd
+ * $Id$
+ */
+
+/*
+ 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.
+*/
+
+/* Segment Descriptor
+ *
+ * 31 24 19 16 7 0
+ * ------------------------------------------------------------
+ * | | |B| |A| | | |1|0|E|W|A| |
+ * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 |
+ * | | |D| |L| 19..16| | |1|1|C|R|A| |
+ * ------------------------------------------------------------
+ * | | |
+ * | BASE 15..0 | LIMIT 15..0 |
+ * | | |
+ * ------------------------------------------------------------
+ */
+
+struct seg_desc {
+ unsigned short limit_15_0;
+ unsigned short base_15_0;
+ unsigned char base_23_16;
+ unsigned char p_dpl_type;
+ unsigned char g_b_a_limit;
+ unsigned char base_31_24;
+ };
+
+#define RUN 0 /* not really 0, but filled in at boot time */
+
+struct seg_desc Gdt[] = {
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0x0 : null */
+ {0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0}, /* 0x08 : kernel code */
+ /* 0x9E? */
+ {0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */
+ /* 0x92? */
+ {0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */
+ {0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* 0x20 : boot data */
+ {0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */
+ /* More for bdb. */
+ {}, /* BIOS_CS_INDEX = 6 : null */
+ {}, /* BIOS_TMP_INDEX = 7 : null */
+ {}, /* TSS_INDEX = 8 : null */
+ {0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* DS_286_INDEX = 9 */
+ {0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* ES_286_INDEX = 10 */
+ {}, /* Unused = 11 : null */
+ {0x7FFF, 0x8000, 0xB, 0xB2, 0x40, 0x0}, /* COLOR_INDEX = 12 */
+ {0x7FFF, 0x0, 0xB, 0xB2, 0x40, 0x0}, /* MONO_INDEX = 13 */
+ {0xFFFF, RUN, RUN, 0x9A, 0x40, 0x0}, /* DB_CS_INDEX = 14 */
+ {0xFFFF, RUN, RUN, 0x9A, 0x0, 0x0}, /* DB_CS16_INDEX = 15 */
+ {0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* DB_DS_INDEX = 16 */
+ {8*18-1, RUN, RUN, 0x92, 0x40, 0x0}, /* GDT_INDEX = 17 */
+};
+
+struct idt_desc {
+ unsigned short entry_15_0;
+ unsigned short selector;
+ unsigned char padding;
+ unsigned char p_dpl_type;
+ unsigned short entry_31_16;
+};
+
+struct idt_desc Idt[] = {
+ {}, /* Null (int 0) */
+ {RUN, 0x70, 0, 0x8E, 0}, /* DEBUG_VECTOR = 1 */
+ {}, /* Null (int 2) */
+ {RUN, 0x70, 0, 0xEE, 0}, /* BREAKPOINT_VECTOR = 3 */
+};
+
+struct pseudo_desc {
+ unsigned short limit;
+ unsigned short base_low;
+ unsigned short base_high;
+ };
+
+struct pseudo_desc Gdtr = { sizeof Gdt - 1, RUN, RUN };
+struct pseudo_desc Idtr_prot = { sizeof Idt - 1, RUN, RUN };
+struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0, 0x0 };
diff --git a/sys/i386/boot/boot.c b/sys/i386/boot/boot.c
new file mode 100644
index 0000000..e186bdc
--- /dev/null
+++ b/sys/i386/boot/boot.c
@@ -0,0 +1,308 @@
+/*
+ * 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.13 1994/06/14 07:31:42 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 <sys/param.h>
+#include "boot.h"
+#include <a.out.h>
+#include <sys/reboot.h>
+
+struct exec head;
+int argv[10], esym;
+char *name;
+char *names[] = {
+ "/386bsd", "/o386bsd", "/386bsd.old"
+};
+#define NUMNAMES (sizeof(names)/sizeof(char *))
+
+extern int end;
+boot(drive)
+int drive;
+{
+ int loadflags, currname = 0;
+ char *t;
+
+ printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory [%s]\n",
+ ouraddr,
+ argv[7] = memsize(0),
+ argv[8] = memsize(1),
+ "$Revision: 1.14 $");
+ printf("use hd(1,a)/386bsd to boot sd0 when wd0 is also installed\n");
+ gateA20();
+loadstart:
+ /***************************************************************\
+ * 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 */
+ name = names[currname++];
+
+ loadflags = 0;
+ if (currname == NUMNAMES)
+ currname = 0;
+ getbootdev(&loadflags);
+ if (openrd()) {
+ printf("Can't find %s\n", name);
+ goto loadstart;
+ }
+/* if (inode.i_mode&IEXEC)
+ loadflags |= RB_KDB;
+*/
+ loadprog(loadflags);
+ goto loadstart;
+}
+
+loadprog(howto)
+ int howto;
+{
+ long int startaddr;
+ long int addr; /* physical address.. not directly useable */
+ long int addr0;
+ int i;
+ static int (*x_entry)() = 0;
+ unsigned char tmpbuf[4096]; /* we need to load the first 4k here */
+
+ argv[3] = 0;
+ argv[4] = 0;
+ read(&head, sizeof(head));
+ if ( N_BADMAG(head)) {
+ printf("Invalid format!\n");
+ return;
+ }
+
+ poff = N_TXTOFF(head);
+ /*if(poff==0)
+ poff = 32;*/
+
+ startaddr = (int)head.a_entry;
+ addr = (startaddr & 0x00ffffff); /* some MEG boundary */
+ addr0 = addr;
+ printf("Booting %s(%d,%c)%s @ 0x%x\n"
+ , devs[maj]
+ , unit
+ , 'a'+part
+ , name
+ , addr);
+ if(addr < ouraddr)
+ {
+ if((addr + head.a_text + head.a_data) > ouraddr)
+ {
+ printf("kernel overlaps loader\n");
+ return;
+ }
+ if((addr + head.a_text + head.a_data + head.a_bss) > 0xa0000)
+ {
+ printf("bss exceeds 640k limit\n");
+ return;
+ }
+ }
+ printf("text=0x%x ", head.a_text);
+ /********************************************************/
+ /* LOAD THE TEXT SEGMENT */
+ /* don't clobber the first 4k yet (BIOS NEEDS IT) */
+ /********************************************************/
+ read(tmpbuf,4096);
+ addr += 4096;
+ xread(addr, head.a_text - 4096);
+ addr += head.a_text - 4096;
+
+ /********************************************************/
+ /* Load the Initialised data after the text */
+ /********************************************************/
+ while (addr & CLOFSET)
+ *(char *)addr++ = 0;
+
+ printf("data=0x%x ", head.a_data);
+ xread(addr, head.a_data);
+ addr += head.a_data;
+
+ /********************************************************/
+ /* Skip over the uninitialised data */
+ /* (but clear it) */
+ /********************************************************/
+ printf("bss=0x%x ", head.a_bss);
+ if( (addr < ouraddr) && ((addr + head.a_bss) > ouraddr))
+ {
+ pbzero(addr,ouraddr - (int)addr);
+ }
+ else
+ {
+ pbzero(addr,head.a_bss);
+ }
+ argv[3] = (addr += head.a_bss);
+
+#ifdef LOADSYMS /* not yet, haven't worked this out yet */
+ if (addr > 0x100000)
+ {
+ /********************************************************/
+ /*copy in the symbol header */
+ /********************************************************/
+ pcpy(&head.a_syms, addr, sizeof(head.a_syms));
+ addr += sizeof(head.a_syms);
+
+ /********************************************************/
+ /* READ in the symbol table */
+ /********************************************************/
+ printf("symbols=[+0x%x", head.a_syms);
+ xread(addr, head.a_syms);
+ addr += head.a_syms;
+
+ /********************************************************/
+ /* Followed by the next integer (another header) */
+ /* more debug symbols? */
+ /********************************************************/
+ read(&i, sizeof(int));
+ pcpy(&i, addr, sizeof(int));
+ i -= sizeof(int);
+ addr += sizeof(int);
+
+
+ /********************************************************/
+ /* and that many bytes of (debug symbols?) */
+ /********************************************************/
+ printf("+0x%x] ", i);
+ xread(addr, i);
+ addr += i;
+ }
+#endif LOADSYMS
+ /********************************************************/
+ /* and note the end address of all this */
+ /********************************************************/
+
+ argv[4] = ((addr+sizeof(int)-1))&~(sizeof(int)-1);
+ printf("total=0x%x ",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 = getchar();
+ 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, 0, 0, unit, part)) ;
+ argv[5] = (head.a_entry &= 0xfffffff);
+ argv[6] = (int) &x_entry;
+ argv[0] = 8;
+ /****************************************************************/
+ /* copy that first page and overwrite any BIOS variables */
+ /****************************************************************/
+ printf("entry point=0x%x\n" ,((int)startaddr) & 0xffffff);
+ /* Under no circumstances overwrite precious BIOS variables! */
+ pcpy(tmpbuf, addr0, 0x400);
+ pcpy(tmpbuf + 0x500, addr0 + 0x500, 4096 - 0x500);
+ startprog(((int)startaddr & 0xffffff),argv);
+}
+
+char namebuf[100];
+getbootdev(howto)
+ int *howto;
+{
+ char c, *ptr = namebuf;
+ printf("Boot: [[[%s(%d,%c)]%s][-s][-a][-d]] :- "
+ , devs[maj]
+ , unit
+ , 'a'+part
+ , name);
+ if (gets(namebuf)) {
+ while (c=*ptr) {
+ while (c==' ')
+ c = *++ptr;
+ if (!c)
+ return;
+ if (c=='-')
+ while ((c = *++ptr) && c!=' ')
+ switch (c) {
+ case 'r':
+ *howto |= RB_DFLTROOT; continue;
+ case 'a':
+ *howto |= RB_ASKNAME; continue;
+ case 's':
+ *howto |= RB_SINGLE; continue;
+ case 'd':
+ *howto |= RB_KDB; continue;
+ case 'b':
+ *howto |= RB_HALT; continue;
+ }
+ else {
+ name = ptr;
+ while ((c = *++ptr) && c!=' ');
+ if (c)
+ *ptr++ = 0;
+ }
+ }
+ } else
+ printf("\n");
+}
+
diff --git a/sys/i386/boot/boot.h b/sys/i386/boot/boot.h
new file mode 100644
index 0000000..f77f882
--- /dev/null
+++ b/sys/i386/boot/boot.h
@@ -0,0 +1,40 @@
+/*
+ * 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$
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <ufs/quota.h>
+#include <ufs/fs.h>
+#include <ufs/inode.h>
+
+extern char *devs[], *name, *iodest;
+extern struct fs *fs;
+extern struct inode inode;
+extern int dosdev, unit, part, maj, boff, poff, bnum, cnt;
+extern long int ouraddr;
diff --git a/sys/i386/boot/boot.sed b/sys/i386/boot/boot.sed
new file mode 100644
index 0000000..c6b38ea
--- /dev/null
+++ b/sys/i386/boot/boot.sed
@@ -0,0 +1,3 @@
+/^[ ]*.data/c\
+ .text
+/^[ ]*.ident/d
diff --git a/sys/i386/boot/boot2.S b/sys/i386/boot/boot2.S
new file mode 100644
index 0000000..f78ce10
--- /dev/null
+++ b/sys/i386/boot/boot2.S
@@ -0,0 +1,177 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:26 rpd
+ * $Id: boot2.S,v 1.3 1993/11/13 04:43:25 rgrimes Exp $
+ */
+
+#include "asm.h"
+
+/* Conventional GDT indexes. */
+#define BOOT_CS_INDEX 3
+#define BOOT_CS16_INDEX 5
+#define BOOT_DS_INDEX 4
+#define DB_CS_INDEX 14
+#define DB_CS16_INDEX 15
+#define DB_DS_INDEX 16
+#define GDT_INDEX 17
+
+/* Vector numbers. */
+#define BREAKPOINT_VECTOR 3
+#define DEBUG_VECTOR 1
+
+/*
+ * boot2() -- second stage boot
+ */
+
+.globl EXT(ouraddr)
+
+ENTRY(boot2)
+ data32
+ subl %eax, %eax
+ mov %cs, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ data32
+ shll $4, %eax
+ addr32
+ data32
+ movl %eax, EXT(ouraddr)
+
+ /* fix up GDT entries for bootstrap */
+#define FIXUP(gdt_index) \
+ addr32; \
+ movl %eax, EXT(Gdt)+(8*gdt_index)+2; /* actually movw %ax */ \
+ addr32; \
+ movb %bl, EXT(Gdt)+(8*gdt_index)+4
+
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(BOOT_CS_INDEX)
+ FIXUP(BOOT_CS16_INDEX)
+ FIXUP(BOOT_DS_INDEX)
+
+ /* fix up GDT entry for GDT, and GDT and IDT pointers */
+ data32
+ movl %eax, %ecx
+ data32
+ addl $ EXT(Gdt), %eax
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(GDT_INDEX)
+ addr32
+ data32
+ movl %eax, EXT(Gdtr)+2
+ data32
+ addl $ EXT(Idt), %ecx
+ addr32
+ data32
+ movl %ecx, EXT(Idtr_prot)+2
+
+ /* %es = vector table segment for a while */
+ push %es
+ data32
+ subl %eax, %eax
+ mov %ax, %es
+
+ /* fix up GDT entries for bdb */
+ data32
+ movl $4*DEBUG_VECTOR, %esi
+ addr32
+ movl %es: 2(%esi), %eax /* actually movw to %ax */
+ data32
+ shll $4, %eax
+ data32
+ shld $16, %eax, %ebx
+ FIXUP(DB_CS_INDEX)
+ FIXUP(DB_CS16_INDEX)
+ FIXUP(DB_DS_INDEX)
+
+ /* Fetch entry points of bdb's protected mode trap handlers. These
+ * are stored at 2 before the corresponding entry points for real mode.
+ */
+ data32
+ subl %ebx, %ebx
+ addr32
+ movl %es: (%esi), %ebx /* actually movw to %bx */
+ data32
+ subl %ecx, %ecx
+ addr32
+ movl %es: 4*(BREAKPOINT_VECTOR-DEBUG_VECTOR)(%esi), %ecx
+ /* actually movw to %cx */
+
+ /* %es = bdb segment for a while */
+ data32
+ shrl $4, %eax
+ mov %ax, %es
+
+ /* fix up IDT entries for bdb */
+ data32
+ subl $2, %ebx /* calculate EA to check it */
+ jb 1f /* give up if it would trap */
+ addr32
+ movl %es: (%ebx), %eax /* actually movw to %ax */
+ addr32
+ movl %eax, EXT(Idt)+8*DEBUG_VECTOR /* actually movw %ax */
+1:
+ data32
+ subl $2, %ecx
+ jb 1f
+ addr32
+ movl %es: (%ecx), %eax /* actually movw to %ax */
+ addr32
+ movl %eax, EXT(Idt)+8*BREAKPOINT_VECTOR /* actually movw %ax */
+1:
+
+ /* finished with groping in real mode segments */
+ pop %es
+
+ /* change to protected mode */
+ data32
+ call EXT(real_to_prot)
+
+ /* clear the bss */
+ movl $ EXT(edata), %edi /* no EXT(_edata) - krufty ld */
+ movl $ EXT(end), %ecx /* or EXT(_end) */
+ subl %edi, %ecx
+ subb %al, %al
+ rep
+ stosb
+
+ movzbl %dl, %edx /* discard head (%dh) and random high bits */
+ pushl %edx
+ call EXT(boot)
+oops:
+ hlt
+ jmp oops
+
+ .data
+ .align 2
+#if 0 /* XXX this would give losing "_ouraddr :". Better declared in C */
+EXT(ouraddr):
+#else
+_ouraddr:
+#endif
+ .long 0
diff --git a/sys/i386/boot/boot2.s b/sys/i386/boot/boot2.s
new file mode 100644
index 0000000..d319edf
--- /dev/null
+++ b/sys/i386/boot/boot2.s
@@ -0,0 +1,73 @@
+/*
+ * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
+ *
+ * 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.
+ */
+
+/*
+ * HISTORY
+ * $Log: boot2.s,v $
+ * Revision 2.2 92/04/04 11:35:26 rpd
+ * From 2.5
+ * [92/03/30 rvb]
+ *
+ * Revision 2.2 91/04/02 14:39:21 mbj
+ * Put into rcs tree
+ * [90/02/09 rvb]
+ *
+ */
+
+#include "asm.h"
+#define LOADMSG 1
+/*
+ * boot2() -- second stage boot
+ */
+
+.globl _ouraddr
+
+ENTRY(boot2)
+ movl %cs, %ax
+ movl %ax, %ds
+ movl %ax, %es
+ data32
+ sall $4, %eax
+ data32
+ movl %eax, _ouraddr
+ /* save the drive type and ID */
+ data32
+ pushl %edx
+ /* change to protected mode */
+ data32
+ call _real_to_prot
+
+ call _boot
+ ret
+
+ .data
+ .align 2
+_ouraddr:
+ .long 0
+
+
diff --git a/sys/i386/boot/disk.c b/sys/i386/boot/disk.c
new file mode 100644
index 0000000..a63ca5a
--- /dev/null
+++ b/sys/i386/boot/disk.c
@@ -0,0 +1,281 @@
+/*
+ * 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 $
+ */
+
+/*
+ * 93/10/08 bde
+ * If there is no 386BSD partition, initialize the label sector with
+ * LABELSECTOR instead of with garbage.
+ *
+ * 93/08/22 bde
+ * Fixed reading of bad sector table. It is at the end of the 'c'
+ * partition, which is not always at the end of the disk.
+ */
+
+#include "boot.h"
+#ifdef DO_BAD144
+#include <sys/dkbad.h>
+#endif DO_BAD144
+#include <sys/disklabel.h>
+
+#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)
+
+char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0};
+
+#ifdef DO_BAD144
+struct dkbad dkb;
+int do_bad144;
+int bsize;
+#endif DO_BAD144
+
+int spt, spc;
+
+char *iodest;
+struct fs *fs;
+struct inode inode;
+int dosdev, unit, part, maj, boff, poff, bnum, cnt;
+
+/*#define EMBEDDED_DISKLABEL 1*/
+extern struct disklabel disklabel;
+/*struct disklabel disklabel;*/
+
+devopen()
+{
+ struct dos_partition *dptr;
+ struct disklabel *dl;
+ int dosdev = inode.i_dev;
+ int i, sector, di;
+
+ di = get_diskinfo(dosdev);
+ spc = (spt = SPT(di)) * 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 *)0)+DOSPARTOFF);
+ sector = LABELSECTOR;
+ for (i = 0; i < NDOSPART; i++, dptr++)
+ if (dptr->dp_typ == DOSPTYP_386BSD) {
+ sector = dptr->dp_start + LABELSECTOR;
+ break;
+ }
+ Bread(dosdev, sector++);
+ dl=((struct disklabel *)0);
+ 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;
+ int dkbbnum;
+ struct dkbad *dkbptr;
+
+ /* find the first readable bad sector table */
+ /* some of this code is copied from ufs/ufs_disksubr.c */
+ /* including the bugs :-( */
+ /* read a bad sector table */
+
+#define BAD144_PART 2 /* XXX scattered magic numbers */
+#define BSD_PART 0 /* XXX should be 2 but bad144.c uses 0 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ dkbbnum = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ dkbbnum = dl->d_secperunit;
+ dkbbnum -= dl->d_nsectors;
+
+ if (dl->d_secsize > DEV_BSIZE)
+ dkbbnum *= dl->d_secsize / DEV_BSIZE;
+ else
+ dkbbnum /= DEV_BSIZE / dl->d_secsize;
+ i = 0;
+ do_bad144 = 0;
+ do {
+ /* XXX: what if the "DOS sector" < 512 bytes ??? */
+ Bread(dosdev, dkbbnum + i);
+ dkbptr = (struct dkbad *) 0;
+/* 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 && i < dl->d_nsectors);
+ if (!do_bad144)
+ printf("Bad bad sector table\n");
+ else
+ printf("Using bad sector table at %d\n", dkbbnum+i);
+ }
+#endif DO_BAD144
+ }
+ return 0;
+}
+
+devread()
+{
+ int offset, sector = bnum;
+ int dosdev = inode.i_dev;
+ for (offset = 0; offset < cnt; offset += BPS)
+ {
+ Bread(dosdev, badsect(dosdev, sector++));
+ bcopy(0, iodest+offset, BPS);
+ }
+}
+
+#define I_ADDR ((void *) 0) /* XXX where all reads go */
+
+/* Read ahead buffer large enough for one track on a 1440K floppy. For
+ * reading from floppies, the bootstrap has to be loaded on a 64K boundary
+ * to ensure that this buffer doesn't cross a 64K DMA boundary.
+ */
+#define RA_SECTORS 18
+static char ra_buf[RA_SECTORS * BPS];
+static int ra_dev;
+static int ra_end;
+static int ra_first;
+
+Bread(dosdev,sector)
+ int dosdev,sector;
+{
+ if (dosdev != ra_dev || sector < ra_first || sector >= ra_end)
+ {
+ int cyl, head, sec, nsec;
+
+ cyl = sector/spc;
+ head = (sector % spc) / spt;
+ sec = sector % spt;
+ nsec = spt - sec;
+ if (nsec > RA_SECTORS)
+ nsec = RA_SECTORS;
+ twiddle();
+ if (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0)
+ {
+ nsec = 1;
+ twiddle();
+ while (biosread(dosdev, cyl, head, sec, nsec, ra_buf) != 0) {
+ printf("Error: C:%d H:%d S:%d\n", cyl, head, sec);
+ twiddle();
+ }
+ }
+ ra_dev = dosdev;
+ ra_first = sector;
+ ra_end = sector + nsec;
+ }
+ bcopy(ra_buf + (sector - ra_first) * BPS, I_ADDR, BPS);
+}
+
+badsect(dosdev, sector)
+ int dosdev, sector;
+{
+ int i;
+#ifdef DO_BAD144
+ if (do_bad144) {
+ u_short cyl;
+ u_short head;
+ u_short sec;
+ int newsec;
+ struct disklabel *dl = &disklabel;
+
+ /* XXX */
+ /* from wd.c */
+ /* bt_cyl = cylinder number in sorted order */
+ /* bt_trksec is actually (head << 8) + sec */
+
+ /* only remap sectors in the partition */
+ if (sector < boff || sector >= boff + bsize) {
+ goto no_remap;
+ }
+
+ cyl = sector / dl->d_secpercyl;
+ head = (sector % dl->d_secpercyl) / dl->d_nsectors;
+ sec = 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 */
+ if (dl->d_partitions[BSD_PART].p_offset != 0)
+ newsec = dl->d_partitions[BAD144_PART].p_offset
+ + dl->d_partitions[BAD144_PART].p_size;
+ else
+ newsec = dl->d_secperunit;
+ newsec -= dl->d_nsectors + i + 1;
+ return newsec;
+ }
+#endif DO_BAD144
+ no_remap:
+ return sector;
+}
diff --git a/sys/i386/boot/io.c b/sys/i386/boot/io.c
new file mode 100644
index 0000000..ee441f0
--- /dev/null
+++ b/sys/i386/boot/io.c
@@ -0,0 +1,214 @@
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:35:57 rpd
+ * $Id: io.c,v 1.5 1994/06/15 19:09:14 jkh Exp $
+ */
+
+#include <i386/include/pio.h>
+
+#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
+#define K_STATUS 0x64 /* keyboard status */
+#define K_CMD 0x64 /* keybd ctlr command (write-only) */
+
+#define K_OBUF_FUL 0x01 /* output buffer full */
+#define K_IBUF_FUL 0x02 /* input buffer full */
+
+#define KC_CMD_WIN 0xd0 /* read output port */
+#define KC_CMD_WOUT 0xd1 /* write output port */
+#define KB_A20 0xdf /* enable A20,
+ enable output buffer full interrupt
+ enable data line
+ enable clock line */
+
+/*
+ * Gate A20 for high memory
+ */
+unsigned char x_20 = KB_A20;
+gateA20()
+{
+#ifdef IBM_L40
+ outb(0x92, 0x2);
+#else IBM_L40
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ while (inb(K_STATUS) & K_OBUF_FUL)
+ (void)inb(K_RDWR);
+
+ outb(K_CMD, KC_CMD_WOUT);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+ outb(K_RDWR, x_20);
+ while (inb(K_STATUS) & K_IBUF_FUL);
+#endif IBM_L40
+}
+
+/* printf - only handles %d as decimal, %c as char, %s as string */
+
+printf(format,data)
+ char *format;
+ int data;
+{
+ int *dataptr = &data;
+ char c;
+
+ reset_twiddle();
+ while (c = *format++)
+ if (c != '%')
+ putchar(c);
+ else
+ switch (c = *format++) {
+ case 'd': {
+ int num = *dataptr++;
+ char buf[10], *ptr = buf;
+ if (num<0) {
+ num = -num;
+ putchar('-');
+ }
+ do
+ *ptr++ = '0'+num%10;
+ while (num /= 10);
+ do
+ putchar(*--ptr);
+ while (ptr != buf);
+ break;
+ }
+ case 'x': {
+ int num = *dataptr++, dig;
+ char buf[8], *ptr = buf;
+ do
+ *ptr++ = (dig=(num&0xf)) > 9?
+ 'a' + dig - 10 :
+ '0' + dig;
+ while (num >>= 4);
+ do
+ putchar(*--ptr);
+ while (ptr != buf);
+ break;
+ }
+ case 'c': putchar((*dataptr++)&0xff); break;
+ case 's': {
+ char *ptr = (char *)*dataptr++;
+ while (c = *ptr++)
+ putchar(c);
+ break;
+ }
+ }
+}
+
+putchar(c)
+{
+ if (c == '\n')
+ putc('\r');
+ putc(c);
+}
+
+getchar()
+{
+ int c;
+
+ if ((c=getc()) == '\r')
+ c = '\n';
+ if (c == '\b') {
+ putchar('\b');
+ putchar(' ');
+ }
+ putchar(c);
+ return(c);
+}
+
+#if BOOTWAIT
+spinwait(i)
+int i;
+{
+ while (--i >= 0)
+ (void)inb(0x84);
+}
+#endif
+
+gets(buf)
+char *buf;
+{
+ int i;
+ char *ptr=buf;
+
+#if BOOTWAIT
+ for (i = BOOTWAIT; i>0; spinwait(10000),i--)
+#endif
+ if (ischar())
+ for (;;)
+ switch(*ptr = getchar() & 0xff) {
+ case '\n':
+ case '\r':
+ *ptr = '\0';
+ return 1;
+ case '\b':
+ if (ptr > buf) ptr--;
+ continue;
+ default:
+ ptr++;
+ }
+ return 0;
+}
+
+strcmp(s1, s2)
+char *s1, *s2;
+{
+ while (*s1 == *s2) {
+ if (!*s1++)
+ return 0;
+ s2++;
+ }
+ return 1;
+}
+
+bcopy(from, to, len)
+char *from, *to;
+int len;
+{
+ while (len-- > 0)
+ *to++ = *from++;
+}
+
+static int tw_on;
+static int tw_pos;
+static char tw_chars[] = "|/-\\";
+
+reset_twiddle()
+{
+ if (tw_on)
+ putchar('\b');
+ tw_on = 0;
+ tw_pos = 0;
+}
+
+twiddle()
+{
+ if (tw_on)
+ putchar('\b');
+ else
+ tw_on = 1;
+ putchar(tw_chars[tw_pos++]);
+ tw_pos %= (sizeof(tw_chars) - 1);
+}
diff --git a/sys/i386/boot/rmaouthdr b/sys/i386/boot/rmaouthdr
new file mode 100644
index 0000000..4bb9c84
--- /dev/null
+++ b/sys/i386/boot/rmaouthdr
@@ -0,0 +1,6 @@
+#!/bin/csh -f
+#
+# from: Mach, Revision 2.2 92/04/04 11:36:01 rpd
+# $Id$
+#
+dd if=$1 of=$2 ibs=32 skip=1 obs=1024b
diff --git a/sys/i386/boot/start.S b/sys/i386/boot/start.S
new file mode 100644
index 0000000..aa65212
--- /dev/null
+++ b/sys/i386/boot/start.S
@@ -0,0 +1,292 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:36:29 rpd
+ * $Id: start.S,v 1.2 1993/10/16 19:11:38 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 "asm.h"
+
+ .file "start.s"
+
+BOOTSEG = 0x9000 # boot will be loaded here (below 640K)
+BOOTSTACK = 0xe000 # boot stack
+SIGNATURE = 0xaa55
+LOADSZ = 15 # size of unix boot
+PARTSTART = 0x1be # starting address of partition table
+NUMPART = 4 # number of partitions in partition table
+PARTSZ = 16 # each partition table entry is 16 bytes
+BSDPART = 0xA5 # value of boot_ind, means bootable partition
+BOOTABLE = 0x80 # value of boot_ind, means bootable partition
+
+ .text
+
+ENTRY(boot1)
+ # start (aka boot1) is loaded at 0x0:0x7c00 but we want 0x7c0:0
+ # ljmp to the next instruction to adjust %cs
+ data32
+ ljmp $0x7c0, $start
+
+start:
+ # set up %ds
+ mov %cs, %ax
+ mov %ax, %ds
+
+ # set up %ss and %esp
+ data32
+ mov $BOOTSEG, %eax
+ mov %ax, %ss
+ data32
+ mov $BOOTSTACK, %esp
+
+ /*** set up %es, (where we will load boot2 to) ***/
+ mov %ax, %es
+
+#ifdef DEBUG
+ data32
+ mov $one, %esi
+ data32
+ call message
+#endif
+
+ # bootstrap passes us drive number in %dl
+ cmpb $0x80, %dl
+ data32
+ jae hd
+
+fd:
+ mov $0x0, %dl
+# reset the disk system
+#ifdef DEBUG
+ data32
+ mov $two, %esi
+ data32
+ call message
+#endif
+ movb $0x0, %ah
+ int $0x13
+ data32
+ mov $0x0001, %ecx # cyl 0, sector 1
+ movb $0, %dh # head
+#ifdef DEBUG
+ data32
+ mov $three, %esi
+ data32
+ call message
+#endif
+ data32
+ jmp load
+
+hd: /**** load sector 0 into the BOOTSEG ****/
+#ifdef DEBUG
+ data32
+ mov $four, %esi
+ data32
+ call message
+#endif
+ data32
+ mov $0x0201, %eax
+ xor %ebx, %ebx # %bx = 0
+ data32
+ mov $0x0001, %ecx
+#ifdef DEBUG
+ data32
+ mov $five, %esi
+ data32
+ call message
+#endif
+ data32
+ andl $0xff, %edx
+ /*mov $0x0080, %edx*/
+ int $0x13
+ data32
+ jb read_error
+
+ /***# find the first 386BSD partition *****/
+ data32
+ mov $PARTSTART, %ebx
+ data32
+ mov $NUMPART, %ecx
+again:
+ addr32
+ movb %es:4(%ebx), %al
+ cmpb $BSDPART, %al
+ data32
+ je found
+ data32
+ add $PARTSZ, %ebx
+ data32
+ loop again
+ data32
+ mov $enoboot, %esi
+ data32
+ jmp err_stop
+
+
+/*
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+found:
+ addr32
+ movb %es:1(%ebx), %dh /* head */
+ addr32
+ movl %es:2(%ebx), %ecx /*sect, cyl (+ 2 bytes junk in top word) */
+
+load:
+ movb $0x2, %ah /* function 2 */
+ movb $LOADSZ, %al /* number of blocks */
+ xor %ebx, %ebx /* %bx = 0, put it at 0 in the BOOTSEG */
+ int $0x13
+ data32
+ jb read_error
+
+ # ljmp to the second stage boot loader (boot2).
+ # After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
+ # as an internal buffer "intbuf".
+
+#ifdef DEBUG
+ data32
+ mov $six, %esi
+ data32
+ call message
+#endif
+ data32
+ ljmp $BOOTSEG, $ EXT(boot2)
+
+#
+# read_error
+#
+
+read_error:
+ data32
+ mov $eread, %esi
+err_stop:
+ data32
+ call message
+ data32
+ jmp stop
+
+#
+# message: write the error message in %ds:%esi to console
+#
+
+message:
+/*
+ # Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+ # %ah = 0xe %al = character
+ # %bh = page %bl = foreground color (graphics modes)
+*/
+
+ data32
+ push %eax
+ data32
+ push %ebx
+ data32
+ mov $0x0001, %ebx
+ cld
+
+nextb:
+ lodsb # load a byte into %al
+ cmpb $0x0, %al
+ data32
+ je done
+ movb $0xe, %ah
+ int $0x10 # display a byte
+ data32
+ jmp nextb
+done:
+ data32
+ pop %ebx
+ data32
+ pop %eax
+ data32
+ ret
+
+stop: hlt
+ data32
+ jmp stop # halt doesnt actually halt forever
+
+/* error messages */
+
+#ifdef DEBUG
+one: String "1\r\n\0"
+two: String "2\r\n\0"
+three: String "3\r\n\0"
+four: String "4\r\n\0"
+five: String "5\r\n\0"
+six: String "6\r\n\0"
+seven: String "7\r\n\0"
+#endif DEBUG
+eread: String "Read error\r\n\0"
+enoboot: String "No bootable partition\r\n\0"
+endofcode:
+/* throw in a partition in case we are block0 as well */
+/* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
+ . = EXT(boot1) + PARTSTART
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte BOOTABLE,0,1,0,BSDPART,255,255,255
+ .long 0,50000
+/* the last 2 bytes in the sector 0 contain the signature */
+ . = EXT(boot1) + 0x1fe
+ .value SIGNATURE
+ENTRY(disklabel)
+ . = EXT(boot1) + 0x400
diff --git a/sys/i386/boot/start.s b/sys/i386/boot/start.s
new file mode 100644
index 0000000..f6f4bf0
--- /dev/null
+++ b/sys/i386/boot/start.s
@@ -0,0 +1,323 @@
+/*
+ * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
+ *
+ * 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.
+ */
+
+/*
+ * HISTORY
+ * $Log: start.s,v $
+ * Revision 2.2 92/04/04 11:36:29 rpd
+ * Fix Intel Copyright as per B. Davies authorization.
+ * [92/04/03 rvb]
+ * Need to zero dh on hd path; at least for an adaptec card.
+ * [92/01/14 rvb]
+ *
+ * From 2.5 boot:
+ * Flush digit printing.
+ * Fuse floppy and hd boot by using Int 21 to tell
+ * boot type (slightly dubious since Int 21 is DOS
+ * not BIOS)
+ * [92/03/30 mg32]
+ *
+ * Revision 2.2 91/04/02 14:42:04 mbj
+ * Fix the BIG boot bug. We had missed a necessary data
+ * before a xor that was clearing a register used later
+ * as an index register.
+ * [91/03/01 rvb]
+ * Remember floppy type for swapgeneric
+ * Add Intel copyright
+ * [90/02/09 rvb]
+ *
+ */
+
+
+/*
+ Copyright 1988, 1989, 1990, 1991, 1992
+ by Intel Corporation, Santa Clara, California.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and
+its documentation for any purpose and without fee is hereby
+granted, provided that the above copyright notice appears in all
+copies and that both the copyright notice and this permission notice
+appear in supporting documentation, and that the name of Intel
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
+NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+#include "asm.h"
+
+ .file "start.s"
+
+BOOTSEG = 0x9000 # boot will be loaded at 640k-64k
+BOOTSTACK = 0xe000 # boot stack
+SIGNATURE = 0xaa55
+LOADSZ = 14 # size of unix boot
+PARTSTART = 0x1be # starting address of partition table
+NUMPART = 4 # number of partitions in partition table
+PARTSZ = 16 # each partition table entry is 16 bytes
+BSDPART = 0xA5 # value of boot_ind, means bootable partition
+BOOTABLE = 0x80 # value of boot_ind, means bootable partition
+
+ .text
+
+ENTRY(boot1)
+
+ # boot1 is loaded at 0x0:0x7c00
+ # ljmp to the next instruction to set up %cs
+ data32
+ ljmp $0x7c0, $start
+
+start:
+ # set up %ds
+ mov %cs, %ax
+ mov %ax, %ds
+
+
+ # set up %ss and %esp
+ data32
+ mov $BOOTSEG, %eax
+ mov %ax, %ss
+ data32
+ mov $BOOTSTACK, %esp
+
+ /*** set up %es, (where we will load boot2 to) ***/
+ mov %ax, %es
+
+#ifdef DEBUG
+ data32
+ mov $one, %esi
+ data32
+ call message
+#endif
+ # get the boot drive id
+ movb $0x33, %ah
+ movb $0x05, %al
+ int $0x21
+
+ cmpb $0x80, %dl
+ data32
+ jge hd
+
+fd:
+# reset the disk system
+#ifdef DEBUG
+ data32
+ mov $two, %esi
+ data32
+ call message
+#endif
+ movb $0x0, %ah
+ int $0x13
+ data32
+ mov $0x0001, %ecx # cyl 0, sector 1
+ data32
+#ifdef DEBUG
+ data32
+ mov $three, %esi
+ data32
+ call message
+#endif
+ jmp load
+
+hd: /**** load sector 0 into the BOOTSEG ****/
+#ifdef DEBUG
+ data32
+ mov $four, %esi
+ data32
+ call message
+#endif
+ data32
+ mov $0x0201, %eax
+ xor %ebx, %ebx # %bx = 0
+ data32
+ mov $0x0001, %ecx
+#ifdef DEBUG
+ data32
+ mov $five, %esi
+ data32
+ call message
+#endif
+ data32
+ andl $0xff, %edx
+ /*mov $0x0080, %edx*/
+ int $0x13
+ data32
+ jb read_error
+
+ /***# find the bootable partition *****/
+ data32
+ mov $PARTSTART, %ebx
+ data32
+ mov $NUMPART, %ecx
+again:
+ addr16
+ movb %es:4(%ebx), %al
+ cmpb $BSDPART, %al
+ data32
+ je found
+ data32
+ add $PARTSZ, %ebx
+ data32
+ loop again
+ data32
+ mov $enoboot, %esi
+ data32
+ jmp err_stop
+
+
+/*
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+# Call with %ah = 0x2
+# %al = number of sectors
+# %ch = cylinder
+# %cl = sector
+# %dh = head
+# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+# %es:%bx = segment:offset of buffer
+# Return:
+# %al = 0x0 on success; err code on failure
+*/
+
+found:
+ addr16
+ movb %es:1(%ebx), %dh /* head */
+ addr16
+ xor %ecx, %ecx
+ addr16
+ movw %es:2(%ebx), %ecx /*sect,cyl (+ 2 bytes junk in top word )*/
+
+load:
+ movb $0x2, %ah /* function 2 */
+ movb $LOADSZ, %al /* number of blocks */
+ xor %ebx, %ebx /* %bx = 0, put it at 0 in the BOOTSEG */
+ int $0x13
+ data32
+ jb read_error
+
+ # ljmp to the second stage boot loader (boot2).
+ # After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
+ # as an internal buffer "intbuf".
+
+#ifdef DEBUG
+ data32
+ mov $six, %esi
+ data32
+ call message
+#endif
+ data32
+ ljmp $BOOTSEG, $EXT(boot2)
+
+#
+# read_error
+#
+
+read_error:
+
+ data32
+ mov $eread, %esi
+err_stop:
+ data32
+ call message
+ data32
+ jmp stop
+
+#
+# message: write the error message in %ds:%esi to console
+#
+
+message:
+ # Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+ # %ah = 0xe %al = character
+ # %bh = page %bl = foreground color (graphics modes)
+
+ data32
+ push %eax
+ data32
+ push %ebx
+ data32
+ mov $0x0001, %ebx
+ cld
+
+nextb:
+ lodsb # load a byte into %al
+ cmpb $0x0, %al
+ data32
+ je done
+ movb $0xe, %ah
+ int $0x10 # display a byte
+ data32
+ jmp nextb
+done:
+ data32
+ pop %ebx
+ data32
+ pop %eax
+ data32
+ ret
+
+stop: hlt
+ data32
+ jmp stop # halt doesnt actually halt forever
+
+/* error messages */
+
+#ifdef DEBUG
+one: String "1\r\n\0"
+two: String "2\r\n\0"
+three: String "3\r\n\0"
+four: String "4\r\n\0"
+five: String "5\r\n\0"
+six: String "6\r\n\0"
+seven: String "7\r\n\0"
+#endif DEBUG
+eread: String "Read error\r\n\0"
+enoboot: String "No bootable partition\r\n\0"
+endofcode:
+/* throw in a partition in case we are block0 as well */
+/* flag,head,sec,cyl,typ,ehead,esect,ecyl,start,len */
+ . = EXT(boot1) + PARTSTART
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte 0x0,0,0,0,0,0,0,0
+ .long 0,0
+ .byte BOOTABLE,0,1,0,BSDPART,255,255,255
+ .long 0,50000
+/* the last 2 bytes in the sector 0 contain the signature */
+ . = EXT(boot1) + 0x1fe
+ .value SIGNATURE
+ENTRY(disklabel)
+ . = EXT(boot1) + 0x400
diff --git a/sys/i386/boot/sys.c b/sys/i386/boot/sys.c
new file mode 100644
index 0000000..4ffe171
--- /dev/null
+++ b/sys/i386/boot/sys.c
@@ -0,0 +1,232 @@
+/*
+ * 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$
+ */
+
+#include "boot.h"
+#include <sys/dir.h>
+#include <sys/reboot.h>
+
+/* #define BUFSIZE 4096 */
+#define BUFSIZE MAXBSIZE
+
+char buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE];
+
+int xread(addr, size)
+ char * addr;
+ int size;
+{
+ int count = BUFSIZE;
+ while (size > 0) {
+ if (BUFSIZE > size)
+ count = size;
+ read(buf, count);
+ pcpy(buf, addr, count);
+ size -= count;
+ addr += count;
+ }
+}
+
+read(buffer, count)
+ int count;
+ char *buffer;
+{
+ int logno, off, size;
+ int 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;
+ }
+}
+
+find(path)
+ char *path;
+{
+ char *rest, ch;
+ int 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;
+}
+
+char mapbuf[MAXBSIZE];
+int mapblock = 0;
+
+block_map(file_block)
+ int 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 (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]);
+}
+
+openrd()
+{
+ char **devp, *cp = name;
+ /*******************************************************\
+ * If bracket given look for preceding device name *
+ \*******************************************************/
+ while (*cp && *cp!='(')
+ cp++;
+ if (!*cp)
+ {
+ cp = name;
+ }
+ else
+ {
+ if (cp++ != name)
+ {
+ for (devp = devs; *devp; devp++)
+ if (name[0] == (*devp)[0] &&
+ name[1] == (*devp)[1])
+ break;
+ if (!*devp)
+ {
+ printf("Unknown device\n");
+ return 1;
+ }
+ maj = devp-devs;
+ }
+ /*******************************************************\
+ * Look inside brackets for unit number, and partition *
+ \*******************************************************/
+ if (*cp >= '0' && *cp <= '9')
+ if ((unit = *cp++ - '0') > 1)
+ {
+ printf("Bad unit\n");
+ return 1;
+ }
+ if (!*cp || (*cp == ',' && !*++cp))
+ return 1;
+ if (*cp >= 'a' && *cp <= 'p')
+ part = *cp++ - 'a';
+ while (*cp && *cp++!=')') ;
+ if (!*cp)
+ return 1;
+ }
+ switch(maj)
+ {
+ case 1:
+ dosdev = unit | 0x80;
+ unit = 0;
+ break;
+ case 0:
+ case 4:
+ dosdev = unit | 0x80;
+ break;
+ case 2:
+ dosdev = unit;
+ break;
+ case 3:
+ printf("Wangtek unsupported\n");
+ return 1;
+ break;
+ }
+ 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/table.c b/sys/i386/boot/table.c
new file mode 100644
index 0000000..c53173d
--- /dev/null
+++ b/sys/i386/boot/table.c
@@ -0,0 +1,125 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ * from: Mach, Revision 2.2 92/04/04 11:36:43 rpd
+ * $Id$
+ */
+
+/*
+ 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.
+*/
+
+/* Segment Descriptor
+ *
+ * 31 24 19 16 7 0
+ * ------------------------------------------------------------
+ * | | |B| |A| | | |1|0|E|W|A| |
+ * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 |
+ * | | |D| |L| 19..16| | |1|1|C|R|A| |
+ * ------------------------------------------------------------
+ * | | |
+ * | BASE 15..0 | LIMIT 15..0 |
+ * | | |
+ * ------------------------------------------------------------
+ */
+
+struct seg_desc {
+ unsigned short limit_15_0;
+ unsigned short base_15_0;
+ unsigned char base_23_16;
+ unsigned char p_dpl_type;
+ unsigned char g_b_a_limit;
+ unsigned char base_31_24;
+ };
+
+#define RUN 0 /* not really 0, but filled in at boot time */
+
+struct seg_desc Gdt[] = {
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0x0 : null */
+ {0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0}, /* 0x08 : kernel code */
+ /* 0x9E? */
+ {0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */
+ /* 0x92? */
+ {0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */
+ {0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* 0x20 : boot data */
+ {0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */
+ /* More for bdb. */
+ {}, /* BIOS_CS_INDEX = 6 : null */
+ {}, /* BIOS_TMP_INDEX = 7 : null */
+ {}, /* TSS_INDEX = 8 : null */
+ {0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* DS_286_INDEX = 9 */
+ {0xFFFF, 0x0, 0x0, 0xB2, 0x40, 0x0}, /* ES_286_INDEX = 10 */
+ {}, /* Unused = 11 : null */
+ {0x7FFF, 0x8000, 0xB, 0xB2, 0x40, 0x0}, /* COLOR_INDEX = 12 */
+ {0x7FFF, 0x0, 0xB, 0xB2, 0x40, 0x0}, /* MONO_INDEX = 13 */
+ {0xFFFF, RUN, RUN, 0x9A, 0x40, 0x0}, /* DB_CS_INDEX = 14 */
+ {0xFFFF, RUN, RUN, 0x9A, 0x0, 0x0}, /* DB_CS16_INDEX = 15 */
+ {0xFFFF, RUN, RUN, 0x92, 0x40, 0x0}, /* DB_DS_INDEX = 16 */
+ {8*18-1, RUN, RUN, 0x92, 0x40, 0x0}, /* GDT_INDEX = 17 */
+};
+
+struct idt_desc {
+ unsigned short entry_15_0;
+ unsigned short selector;
+ unsigned char padding;
+ unsigned char p_dpl_type;
+ unsigned short entry_31_16;
+};
+
+struct idt_desc Idt[] = {
+ {}, /* Null (int 0) */
+ {RUN, 0x70, 0, 0x8E, 0}, /* DEBUG_VECTOR = 1 */
+ {}, /* Null (int 2) */
+ {RUN, 0x70, 0, 0xEE, 0}, /* BREAKPOINT_VECTOR = 3 */
+};
+
+struct pseudo_desc {
+ unsigned short limit;
+ unsigned short base_low;
+ unsigned short base_high;
+ };
+
+struct pseudo_desc Gdtr = { sizeof Gdt - 1, RUN, RUN };
+struct pseudo_desc Idtr_prot = { sizeof Idt - 1, RUN, RUN };
+struct pseudo_desc Idtr_real = { 0x400 - 1, 0x0, 0x0 };
OpenPOWER on IntegriCloud