diff options
Diffstat (limited to 'sys/i386/boot')
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 }; |