Initial /boot stuff (from Mickey)
authorweingart <weingart@openbsd.org>
Mon, 31 Mar 1997 03:11:58 +0000 (03:11 +0000)
committerweingart <weingart@openbsd.org>
Mon, 31 Mar 1997 03:11:58 +0000 (03:11 +0000)
44 files changed:
sys/arch/i386/stand/Makefile [new file with mode: 0644]
sys/arch/i386/stand/Makefile.inc [new file with mode: 0644]
sys/arch/i386/stand/README [new file with mode: 0644]
sys/arch/i386/stand/biosboot/Makefile [new file with mode: 0644]
sys/arch/i386/stand/biosboot/biosboot.8 [new file with mode: 0644]
sys/arch/i386/stand/biosboot/biosboot.S [new file with mode: 0644]
sys/arch/i386/stand/boot/Makefile [new file with mode: 0644]
sys/arch/i386/stand/boot/boot.8 [new file with mode: 0644]
sys/arch/i386/stand/boot/boot.c [new file with mode: 0644]
sys/arch/i386/stand/boot/cmd.c [new file with mode: 0644]
sys/arch/i386/stand/boot/cmd.h [new file with mode: 0644]
sys/arch/i386/stand/boot/conf.c [new file with mode: 0644]
sys/arch/i386/stand/boot/crt0.c [new file with mode: 0644]
sys/arch/i386/stand/boot/srt0.S [new file with mode: 0644]
sys/arch/i386/stand/boot/version.c [new file with mode: 0644]
sys/arch/i386/stand/installboot/Makefile [new file with mode: 0644]
sys/arch/i386/stand/installboot/installboot.8 [new file with mode: 0644]
sys/arch/i386/stand/installboot/installboot.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/Makefile [new file with mode: 0644]
sys/arch/i386/stand/libsa/asm.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/bioscom.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/biosdev.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/biosdev.h [new file with mode: 0644]
sys/arch/i386/stand/libsa/biosdisk.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/bioskbd.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/biostime.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/dev_i386.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/exec_i386.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/gateA20.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/libsa.h [new file with mode: 0644]
sys/arch/i386/stand/libsa/memprobe.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/memsize.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/probe_keyboard.c [new file with mode: 0644]
sys/arch/i386/stand/libsa/real_prot.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/srt0.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/startprog.S [new file with mode: 0644]
sys/arch/i386/stand/libsa/unixsys.S [new file with mode: 0644]
sys/arch/i386/stand/libz/Makefile [new file with mode: 0644]
sys/arch/i386/stand/mbr/Makefile [new file with mode: 0644]
sys/arch/i386/stand/mbr/mbr.8 [new file with mode: 0644]
sys/arch/i386/stand/mbr/mbr.S [new file with mode: 0644]
sys/stand/boot/boot.c [new file with mode: 0644]
sys/stand/boot/cmd.c [new file with mode: 0644]
sys/stand/boot/cmd.h [new file with mode: 0644]

diff --git a/sys/arch/i386/stand/Makefile b/sys/arch/i386/stand/Makefile
new file mode 100644 (file)
index 0000000..dbd19e9
--- /dev/null
@@ -0,0 +1,5 @@
+#      $OpenBSD: Makefile,v 1.6 1997/03/31 03:11:58 weingart Exp $
+
+SUBDIR=        libsa libz biosboot installboot boot mbr
+
+.include <bsd.subdir.mk>
diff --git a/sys/arch/i386/stand/Makefile.inc b/sys/arch/i386/stand/Makefile.inc
new file mode 100644 (file)
index 0000000..3c7d5a7
--- /dev/null
@@ -0,0 +1,14 @@
+
+CPPFLAGS+=-D_STANDALONE -DSAVE_MEMORY
+CPPFLAGS+=-DDEBUG
+# -DALLOC_TRACE
+# -D_TEST
+# -DUNIX_DEBUG
+# -DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG
+# -DNFS_DEBUG -DRPC_DEBUG -DRARP_DEBUG
+REL=0x1000
+
+NO_NET=no_net
+SA_ZLIB=sa_zlib
+BINDIR=        /usr/mdec
+
diff --git a/sys/arch/i386/stand/README b/sys/arch/i386/stand/README
new file mode 100644 (file)
index 0000000..5a92aa7
--- /dev/null
@@ -0,0 +1,62 @@
+$OpenBSD: README,v 1.1 1997/03/31 03:11:59 weingart Exp $
+
+
+Ok, just a couple quick pointers to people hacking on this stuff.  These
+are things that I have found out, and hopefully will make things easier
+for the next dude.
+
+First of all, don't trust gas to get the opcodes right.  Look at the
+listing (-Wa,a), and check them.  In particular, check for EIP relative
+and absolute addressing.  Some of this stuff is pretty hairy in that way.
+
+Debugging this stuff is hell.  Remember that stores directly to video
+memory will go a long way towards tracking how far things are getting,
+especially when you don't have the BIOS handy.  (movl %0x07410741, 0xb8000)
+
+
+The basics of the /boot system is the following:
+
+biosboot: 512 bytes of the first sector on the disk/partition.  This loads
+/boot (or whatever you did with installboot) into ram.
+
+boot: relocates itself, and starts protected mode.  There is some magic here
+in terms of the placement and size of the various segments, as this piece of
+code has to switch between real and protected mode many times to load the
+next piece of the puzzle, /bsd.gz.
+
+bsd: The kernel itself, can be gzipped if ya want.
+
+
+The basic steps at creating a boot floppy for yourself, and checking things
+out are the following:
+
+1.) Compile a kernel you wish to use.
+2.) Compile the new stand stuff.
+3.) Mount floppy.
+4.) Copy boot and kernel to floppy.  (Kernel could be gzipped if needed)
+5.) Run installboot on floppy.
+6.) Unmount floppy.
+7.) Test...
+
+A quick pasto for ya:
+> natasha# mount /dev/fd0a /mnt
+> natasha# cp boot/obj/boot /mnt
+> natasha# gzip -9c bsd > /mnt/bsd.gz
+> natasha# installboot -v /mnt/boot biosboot /dev/rfd0a
+> boot: /mnt/boot
+> proto: biosboot/obj/biosboot
+> device: /dev/rfd0a
+> 
+> biosboot/obj/biosboot: entry point 0
+> proto bootblock size 512
+> room for 32 filesystem blocks at 0x138
+> Will load 9 blocks of size 4096 each.
+>  0:  4 @(2 1 15) (104-107)
+>  1: 18 @(3 0 1) (108-125)
+>  2: 18 @(3 1 1) (126-143)
+>  3: 18 @(4 0 1) (144-161)
+>  4: 14 @(4 1 1) (162-175)
+> /mnt/boot: 5 entries total
+> natasha# umount /mnt
+> natasha# 
+
diff --git a/sys/arch/i386/stand/biosboot/Makefile b/sys/arch/i386/stand/biosboot/Makefile
new file mode 100644 (file)
index 0000000..4d0ffbc
--- /dev/null
@@ -0,0 +1,21 @@
+#      $OpenBSD: Makefile,v 1.2 1997/03/31 03:12:00 weingart Exp $
+
+PROG=  biosboot
+SRCS=  biosboot.S
+AFLAGS+=-DREL=$(REL) #-Wa,-a
+LDFLAGS=-Wl,-T0,-N,-x -nostdlib
+STRIP=
+MAN=   biosboot.8
+LINKS= ${BINDIR}/biosboot ${BINDIR}/fdboot \
+       ${BINDIR}/biosboot ${BINDIR}/wdboot \
+       ${BINDIR}/biosboot ${BINDIR}/sdboot \
+
+# XXX - Toby
+# These should not output anything, once /boot is loaded, let
+# it figure out who to talk to (probe the keyboard).  That way
+# we will not need two different types of bootblocks...
+#
+# Uncomment this to make the boot block talk to a serial port.
+# CPPFLAGS+=-DSERIAL=0
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/stand/biosboot/biosboot.8 b/sys/arch/i386/stand/biosboot/biosboot.8
new file mode 100644 (file)
index 0000000..270a099
--- /dev/null
@@ -0,0 +1,130 @@
+.\"    $OpenBSD: biosboot.8,v 1.2 1997/03/31 03:12:00 weingart Exp $
+.\"    $NetBSD: boot_i386.8,v 1.3 1995/04/23 10:33:35 cgd Exp $
+.\"
+.\" Copyright (c) 1991, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software written and contributed
+.\" to Berkeley by William Jolitz.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)boot_i386.8        8.2 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.Dt BOOT 8 i386
+.Os
+.Sh NAME
+.Nm boot
+.Nd
+system bootstrapping procedures
+.Sh DESCRIPTION
+.Sy Power fail and crash recovery.
+Normally, the system will reboot itself at power-up or after crashes.
+An automatic consistency check of the file systems will be performed,
+and unless this fails, the system will resume multi-user operations.
+.Pp
+.Sy Cold starts.
+The 386
+.Tn "PC AT"
+clones attempt to boot the floppy disk drive A (otherwise known as drive
+0) first, and failing that, attempt to boot the hard disk C (otherwise
+known as hard disk controller 1, drive 0).
+The automatic boot will attempt to load
+.Pa bsd
+from partition A of either the floppy or the hard disk.
+This boot may be aborted by typing any character on the keyboard repeatedly
+(four or five times at least) during the operating system load phase, after
+which the bootstrap will prompt for the file that you wish to load instead.
+.Pp
+One exception to this is the
+.Ql d
+key, which will not abort the load but instead silently force the
+.Dv DEBUG
+boot flags.
+The boot flags for an autoboot are 0, and 3 for the successive boot after
+an aborted autoboot sequence.
+No other provison is made for setting boot flags (yet).
+A specific device or bootstrap file may be used; for example,
+.Pp
+The file specifications used for the boostrap
+when loaded with the
+.Dq askme
+flag
+(e.g. an aborted autoboot)
+are of the form:
+.Pp
+.Dl device unit partition:
+.Pp
+where
+.Ar device
+is the type of the device, assumed to be on the ISA bus, to be searched,
+.Ar unit
+is the unit number of the disk or tape,
+and
+.Ar partition
+is the disk partition or tape file number.
+Normal line editing characters can be used when typing the file specification.
+The following list of supported devices may vary from installation to
+installation:
+.Bd -unfilled -offset indent
+wd     ST506, IDE, ESDI, RLL disks on a WD100[2367] or lookalike
+       controller
+fd     5 1/4" or 3 1/2" High density floppies
+.Ed
+.Pp
+For example,
+to boot from a file system which starts at cylinder 0
+of unit 0 of an IDE disk, type
+.Dq Li wd(0,a)/bsd
+to the boot prompt;
+.Dq Li fd(0,a)/bsd
+would specify a 3 1/2" floppy drive 0 .
+.Pp
+In an emergency, the bootstrap methods described in the paper
+.%T "Installing and Operating 4.3 BSD-Reno UNIX on the AT/386"
+can be used
+to boot from a distribution tape.
+.Sh FILES
+.Bl -tag -width /bsdxx -compact
+.It Pa /boot
+system bootstrap
+.It Pa /bsd
+system code
+.El
+.Sh SEE ALSO
+.Xr boot 8 ,
+.Xr halt 8 ,
+.Xr reboot 8 ,
+.Xr shutdown 8
+.Sh BUGS
+The disklabel format used by this version of
+.Bx
+is quite
+different from that of other architectures.
diff --git a/sys/arch/i386/stand/biosboot/biosboot.S b/sys/arch/i386/stand/biosboot/biosboot.S
new file mode 100644 (file)
index 0000000..ef0e00f
--- /dev/null
@@ -0,0 +1,312 @@
+/*     $OpenBSD: biosboot.S,v 1.2 1997/03/31 03:12:01 weingart Exp $   */
+
+       .file   "bootbios.S"
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+#define _LOCORE
+#include <machine/segments.h>
+#undef _LOCORE
+
+#define addr32  .byte 0x67
+#define data32  .byte 0x66
+
+#ifdef DEBUG
+#define        BLKCNT  32
+#else
+#define        BLKCNT  48
+#endif
+
+#define BIOSSEG                0x07c0  /* boot loaded here */
+#define BOOTSEG                0x1000  /* /boot placement */
+#define BOOTSTACK      0xfffc  /* /boot stack */
+#define ZMAGIC         0x0b01  /* ZMAGIC */
+
+#ifdef DEBUG
+#define DBGMSG(msg)            \
+       movb    $msg, %al;      \
+       data32;                 \
+       call    chr
+#define CHAR_M 'M'     /* magic check */
+#define CHAR_P 'P'     /* switch to protected mode */
+#else /* !DEBUG */
+#define DBGMSG(msg)
+#endif /* !DEBUG */
+
+       .text
+
+       .globl  start
+start:
+       /* adjust %cs */
+       data32
+       ljmp $BIOSSEG, $2f
+1:     .asciz  "loading /boot"
+
+2:     /* set up stack (%ss:%esp) */
+       cli                     /* disable interrupts w/o stack */
+       data32
+       movl    $BOOTSEG, %ax
+       movl    %ax, %ss
+       data32
+       movl    $BOOTSTACK, %esp
+       sti                     /* we have stack, do ints */
+
+       /* set up %es, (where we will load /boot to) */
+       movl    %ax, %es
+
+       /* set up %ds */
+       pushl   %cs
+       popl    %ds
+
+#ifdef SERIAL
+       # Initialize the serial port to 9600 baud, 8N1.
+       pushl   %dx
+       movl    $0x00e3, %ax
+       data32
+       movl    SERIAL, %edx
+       int     $0x14
+       popl    %dx
+#endif
+
+       data32
+       movl    $1b, %esi
+       data32
+       call    message
+
+       data32
+       xorl    %ebx, %ebx              /* put it at %es:0 */
+       addr32
+       movb    _block_count, %cl       /* how many to read */
+       movzbl  %cl, %ecx
+       data32
+       movl    $_block_table, %esi
+
+1:
+       pushl   %ecx
+       cld
+       lodsl   /* word */      /* cylinder/sector */
+       movl    %ax, %cx
+       lodsb                   /* head */
+       movb    %al, %dh
+       lodsb                   /* # of sectors to load */
+       movb    $0x2, %ah
+       pushl   %ax
+       int     $0x13
+       jnc     3f
+
+       /* read error */
+               data32
+       movl    $2f, %esi
+       jmp     halt
+2:     .asciz  "\r\nRead error\r\n"
+
+3:     /* read next block */
+       movb    $'.', %al
+       data32
+       call    chr             /* show progress indicator */
+
+       popl    %ax
+       data32
+       movzbl  %al, %eax
+       shll    $9, %ax         /* 512 bytes sectors */
+       addl    %ax, %bx
+       popl    %ecx
+       loop    1b
+
+       data32
+       movl    $2f, %esi       /* new line */
+       data32
+       call    message
+
+#if 0
+       DBGMSG(CHAR_M)
+#endif
+
+       xorl    %esi, %esi
+       cld
+       /* check /boot magic */
+       es;lodsl;es;lodsl       /* no need for high word */
+       # cmpw  $ZMAGIC, %ax
+       .byte   0x3d
+       .word   ZMAGIC
+       je      3f
+
+       data32
+       movl    $1f, %esi
+halt:
+       data32
+       call    message
+       cli
+       hlt
+1:     .ascii  "Bad magic"
+2:     .asciz  "\r\n"
+3:
+#if notdef
+       data32;es;lodsl /* text size */
+       data32;es;lodsl /* data size */
+       data32;es;lodsl /* bss  size */
+       data32;es;lodsl /* syms size */
+#endif
+#if 0
+       data32;addr32
+       addl    16(%esi), %edi  /* entry */
+       data32
+       subl    $REL, %edi
+#endif
+
+#if 0
+       DBGMSG(CHAR_P)
+#endif
+
+       /* change to protected mode */
+       /* guarantee that interrupts are disabled when in prot mode */
+       cli
+
+       /* load the gdtr */
+       addr32
+       data32
+       lgdt    Gdtr
+
+       /* set the PE bit of CR0 */
+       movl    %cr0, %eax
+       data32
+       orl     $CR0_PE, %eax
+       movl    %eax, %cr0 
+
+       /*
+        * make intrasegment jump to flush the processor pipeline and
+        * reload CS register
+        */
+       data32
+       ljmp    $8, $1f+(BIOSSEG << 4)
+
+1:     /*
+        * 32bit mode
+        * set up %ds, %ss, %es
+        */
+       movl    $0x10, %eax
+       movl    %ax, %ds
+       movl    %ax, %ss
+       movl    %ax, %es
+       movl    %ax, %fs
+       movl    %ax, %gs
+       movl    $BOOTSTACK, %esp
+
+#if 0
+#ifdef DEBUG
+       movl    $0xb8000, %ebx
+       movl    $0x074f0747, (%ebx)
+#endif
+#endif
+
+       movzbl  %dl, %eax       /* drive number is in the lowest byte */
+       pushl   %eax
+
+#if 0
+#ifdef DEBUG
+       movl    $0x10000, %ebx
+       movl    (%ebx), %ecx
+       /* cmpw $ZMAGIC, %ax */
+       .byte   0x3d
+       .word   ZMAGIC
+je     1f
+       movl    $0xb8004, %ebx
+       movl    $0x07500748, (%ebx)
+       jne     2f
+1:
+       movl    $0xb8004, %ebx
+       movl    $0x074f0747, (%ebx)
+2:
+#endif
+#endif
+
+       /* jmp  /boot */
+       ljmp    $0x8, $(REL << 4) + 0x20
+       /* not reached */
+
+#
+#      chr: write the character in %al to console
+#
+chr:
+       data32
+       pushl   %eax
+
+#ifndef SERIAL
+       data32
+       pushl   %ebx
+       movb    $0x0e, %ah
+       xorl    %bx, %bx
+       incl    %bx             /* movw $0x01, %bx */
+       int     $0x10
+       data32
+       popl    %ebx
+#else
+       data32
+       pushl   %edx
+       movb    $0x01, %ah
+       xorl    %dx, %dx
+       movb    SERIAL, %dl
+       int     $0x14
+       data32
+       popl    %edx
+#endif
+       data32
+       popl    %eax
+       data32
+       ret
+
+/*
+ * Display string
+ */
+message:
+       data32
+       pushl   %eax
+       cld
+1:
+       lodsb                   # load a byte into %al
+       testb   %al, %al
+       jz      1f
+       data32
+       call    chr
+       jmp     1b
+1:
+       data32
+       popl    %eax
+       data32
+       ret
+
+       .align  2
+Gdtr:  .word   3 * 8 - 1
+       .long   (BIOSSEG << 4) + 2f
+       .align  3
+2:             /* 0x00 : null */
+       .long   0, 0
+               /* 0x08 : flat code */
+       .word   0xFFFF                  # lolimit
+       .word   0                       # lobase
+       .byte   0                       # midbase
+       .byte   SDT_MEMERAC | 0 | 0x80  # RWXAC, dpl = 0, present
+       .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
+       .byte   0                       # hibase
+               /* 0x10 : flat data */
+       .word   0xFFFF                  # lolimit
+       .word   0                       # lobase
+       .byte   0                       # midbase
+       .byte   SDT_MEMRWA | 0 | 0x80   # RWA, dpl = 0, present
+       .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
+       .byte   0                       # hibase
+
+       .globl  _block_table
+_block_table:
+       .word   0       /* cyllinder/sector */
+       .byte   0       /* head */
+       .byte   0       /* nsect */
+       . = _block_table + BLKCNT*4
+       .globl  _block_count
+_block_count:
+       .byte   BLKCNT  /* entries in _block_table */
+
+       . = 0x200 - 4
+       /* a little signature */
+       .ascii  "boot"
+
diff --git a/sys/arch/i386/stand/boot/Makefile b/sys/arch/i386/stand/boot/Makefile
new file mode 100644 (file)
index 0000000..3b3532f
--- /dev/null
@@ -0,0 +1,19 @@
+#      $OpenBSD: Makefile,v 1.2 1997/03/31 03:12:02 weingart Exp $
+
+PROG=  boot
+SRCS=  srt0.S boot.c cmd.c conf.c version.c
+CFLAGS=-I${.CURDIR}/../../../../lib/libsa -I${.CURDIR}/../libsa
+AFLAGS+=-DREL=$(REL) #-Wa,-a
+CFLAGS+=-Wall -O
+LDFLAGS=-Wl,-T$(REL),-x,-z -e start_boot
+LDFLAGS+=-static -nostdlib
+MAN=   boot.8
+
+LDADD= -L../libsa -lsa -L../libz -lz
+DPADD= ../libsa/libsa.a ../libz/libz.a
+
+.include <bsd.prog.mk>
+
+.ifdef NO_NET
+CPPFLAGS+=-DNO_NET
+.endif
diff --git a/sys/arch/i386/stand/boot/boot.8 b/sys/arch/i386/stand/boot/boot.8
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sys/arch/i386/stand/boot/boot.c b/sys/arch/i386/stand/boot/boot.c
new file mode 100644 (file)
index 0000000..5770f60
--- /dev/null
@@ -0,0 +1,130 @@
+/*     $OpenBSD: boot.c,v 1.2 1997/03/31 03:12:03 weingart Exp $       */
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <a.out.h>
+#include <sys/disklabel.h>
+#include <libsa.h>
+#include "cmd.h"
+
+/*
+ * Boot program, loaded by boot block from remaing 7.5K of boot area.
+ * Sifts through disklabel and attempts to load an program image of
+ * a standalone program off the disk. If keyboard is hit during load,
+ * or if an error is encounter, try alternate files.
+ */
+
+char *kernels[] = {
+       "bsd", "bsd.gz",
+       "obsd", "obsd.gz",
+       "bsd.old", "bsd.old.gz",
+       NULL
+};
+
+int    retry = 0;
+extern char version[];
+extern dev_t bootdev;
+extern int boothowto;
+int    cnvmem, extmem, probemem;
+
+void   boot ();
+struct cmd_state cmd;
+
+/*
+ * Boot program... loads /boot out of filesystem indicated by arguements.
+ * We assume an autoboot unless we detect a misconfiguration.
+ */
+void
+boot()
+{
+       register char *bootfile = kernels[0];
+       register int i;
+
+
+       /* Get memory size */
+       cnvmem = memsize(0);
+       extmem = memsize(1);
+       gateA20(1);
+       probemem = memprobe();
+
+
+       /* XXX init cmd here to cut on .data !!! */
+       strncpy(cmd.bootdev,
+#ifdef _TEST
+               "/dev/rfd0a",
+#else
+               "fd(0,a)",
+#endif
+               sizeof(cmd.bootdev));
+       cmd.image[0] = '\0';
+       cmd.cwd[0] = '/';
+       cmd.cwd[1] = '\0';
+       cmd.addr = (void *)0x100000;
+       cmd.timeout = 50000;
+
+       printf("\n>> OpenBSD BOOT: %d/%d (%d) k [%s]\n",
+               cnvmem, extmem, probemem, version);
+
+       for (i = 0;;) {
+
+               strncpy(cmd.image, bootfile, sizeof(cmd.image));
+
+               do {
+                       printf("boot> ");
+               } while(!getcmd(&cmd) && !execmd(&cmd));
+
+               sprintf(cmd.path, "%s%s%s", cmd.bootdev, cmd.cwd, bootfile);
+               printf("\nbooting %s: ", cmd.path);
+               exec (cmd.path, cmd.addr, boothowto);
+
+               if(kernels[++i] == NULL)
+                       bootfile = kernels[i=0];
+               else
+                       bootfile = kernels[i];
+
+               cmd.timeout += 20;
+
+               printf(" failed(%d)\nwill try %s\n", errno, bootfile);
+       }
+}
+
+#ifdef _TEST
+int
+main()
+{
+       boot();
+       return 0;
+}
+#endif
diff --git a/sys/arch/i386/stand/boot/cmd.c b/sys/arch/i386/stand/boot/cmd.c
new file mode 100644 (file)
index 0000000..f6d2aa3
--- /dev/null
@@ -0,0 +1,325 @@
+/*     $OpenBSD: cmd.c,v 1.1 1997/03/31 03:12:03 weingart Exp $        */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <string.h>
+#include <libsa.h>
+#include "cmd.h"
+
+static struct cmd_table {
+       char *cmd_name;
+       int cmd_id;
+} cmd_table[] = {
+       {"addr",   CMD_ADDR},
+       {"boot",   CMD_BOOT},
+       {"cd",     CMD_CD},
+       {"device", CMD_DEVICE},
+       {"help",   CMD_HELP},
+       {"image",  CMD_IMAGE},
+       {"ls",     CMD_LS},
+       {"nope",   CMD_NOPE},
+       {"reboot", CMD_REBOOT},
+       {"set",    CMD_SET},
+       {NULL, 0},
+};
+
+extern char version[];
+void ls __P((char *, register struct stat *));
+char skipblnk __P((void));
+
+char cmd_buf[133];
+
+int
+getcmd(cmd)
+       register struct cmd_state *cmd;
+{
+       register struct cmd_table *ct = cmd_table;
+       register char *p = cmd_buf; /* input */
+       register char ch;
+       int len;
+
+       cmd->rc = 0;
+       cmd->argc = 1;
+
+       for (len = cmd->timeout; len-- && !ischar(); );
+
+       if (len < 0) {
+               cmd->cmd = CMD_BOOT;
+               cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
+               cmd->argv[1] = NULL;
+               return 0;
+       }
+
+       ch = skipblnk();
+
+       for (len = 0; ch != '\n' &&
+                    ch != ' ' && ch != '\t'; len++, ch = getchar())
+               *p++ = ch;
+       *p = '\0';
+
+       if (len == 0 && ch == '\n') {
+               cmd->cmd = CMD_NOPE;
+               return 0;
+       }
+
+       while (ct->cmd_name != NULL &&
+              strncmp(cmd_buf, ct->cmd_name, len))
+               ct++;
+
+       if (ct->cmd_name == NULL) {
+               cmd->cmd = CMD_ERROR;
+               cmd->argv[0] = ct->cmd_name;
+               return 0;
+       }
+
+       cmd->cmd = ct->cmd_id;
+       cmd->argv[0] = ct->cmd_name;
+       if (ct->cmd_name != NULL) {
+               while (ch != '\n') {
+
+                       ch = skipblnk();
+
+                       if (ch != '\n') {
+                               cmd->argv[cmd->argc] = p;
+                               *p++ = ch;
+                               for (len = 0; (ch = getchar()) != '\n' &&
+                                            ch != ' ' && ch != '\t'; len++)
+                                       *p++ = ch;
+                               *p++ = '\0';
+                               if (len != 0)
+                                       cmd->argc++;
+                       }
+               }
+               cmd->argv[cmd->argc] = NULL;
+       }
+
+       return cmd->rc;
+}
+
+char
+skipblnk()
+{
+       register char ch;
+
+       /* skip blanks */
+       while ((ch = getchar()) != '\n' &&
+              (ch == ' ' || ch == '\t'));
+
+       return ch;
+}
+
+int
+execmd(cmd)
+       register struct cmd_state *cmd;
+{
+       struct stat sb;
+       int fd;
+       register char *p, *q;
+       register struct cmd_table *ct;
+
+       cmd->rc = 0;
+
+       switch (cmd->cmd) {
+
+       case CMD_HELP:
+               printf("commands: ");
+               for (ct = cmd_table; ct->cmd_name != NULL; ct++)
+                       printf(" %s", ct->cmd_name);
+               putchar('\n');
+               break;
+
+       case CMD_DEVICE:
+               if (cmd->argc != 2)
+                       printf("device: device name required\n");
+               else {
+                       strncpy(cmd->bootdev, cmd->argv[1],
+                               sizeof(cmd->bootdev));
+               }
+               break;
+
+       case CMD_IMAGE:
+               if (cmd->argc != 2)
+                       printf("image: pathname required\n");
+               else {
+                       strncpy(cmd->image, cmd->argv[1],
+                               sizeof(cmd->image));
+               }
+               break;
+
+       case CMD_ADDR:
+               if (cmd->argc != 2)
+                       printf("addr: address required\n");
+               else {
+                       register u_long a;
+
+                       p = cmd->argv[1];
+                       if (p[0] == '0' && p[1] == 'x')
+                               p += 2;
+                       for (a = 0; *p != '\0'; p++) {
+                               a <<= 4;
+                               a |= (isdigit(*p)? *p - '0':
+                                     10 + tolower(*p) - 'a') & 0xf;
+                       }
+
+                       cmd->addr = (void *)a;
+               }
+               break;
+
+       case CMD_LS:
+               {
+                       q = cmd->argv[1] == NULL? "." : cmd->argv[1];
+                       sprintf(cmd->path, "%s%s%s",
+                               cmd->bootdev, cmd->cwd, q);
+
+                       if (stat(cmd->path, &sb) < 0) {
+                               printf("stat(%s): %d\n", cmd->path, errno);
+                               break;
+                       }
+
+                       if ((sb.st_mode & S_IFMT) != S_IFDIR)
+                               ls(q, &sb);
+                       else {
+                               if ((fd = opendir(cmd->path)) < 0) {
+                                       printf ("opendir(%s): %d\n",
+                                               cmd->path, errno);
+                                       break;
+                               }
+
+                               p = cmd->path + strlen(cmd->path);
+                               *p++ = '/';
+                               *p = '\0';
+
+                               while(readdir(fd, p) >= 0 && *p != '\0') {
+
+                                       if (stat(cmd->path, &sb) < 0) {
+                                               printf("stat(%s): %d\n",
+                                                      cmd->path, errno);
+                                               break;
+                                       }
+                                       ls(p, &sb);
+                               }
+
+                               closedir (fd);
+                       }
+               }
+               break;
+
+       case CMD_CD:
+               if (cmd->argc == 1) {
+                       cmd->cwd[0] = '/';
+                       cmd->cwd[1] = '\0';
+                       break;
+               }
+
+               if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
+                       break;
+
+               if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
+                   && cmd->argv[1][2] == '\0') {
+                       /* strrchr(cmd->cwd, '/'); */
+                       for (p = cmd->cwd; *++p;);
+                       for (p--; *--p != '/';);
+                       p[1] = '\0';
+                       break;
+               }
+
+               sprintf(cmd->path, "%s%s%s",
+                       cmd->bootdev, cmd->cwd, cmd->argv[1]);
+               if (stat(cmd->path, &sb) < 0) {
+                       printf("stat(%s): %d\n", cmd->argv[1], errno);
+                       break;
+               }
+
+               if (!S_ISDIR(sb.st_mode)) {
+                       printf("boot: %s: not a dir\n", cmd->argv[1]);
+                       break;
+               }
+
+               /* change dir */
+               for (p = cmd->cwd; *p; p++);
+               for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
+               if (p[-2] != '/') {
+                       p[-1] = '/';
+                       p[0] = '\0';
+               }
+               break;
+
+       case CMD_SET:
+               printf("OpenBSD boot version %s\n"
+                      "device:\t%s\n"
+                      "cwd:\t%s\n"
+                      "image:\t%s\n"
+                      "load at:\t%p\n"
+                      "timeout:\t%d\n",
+                      version, cmd->bootdev, cmd->cwd, cmd->image,
+                      cmd->addr, cmd->timeout);
+               break;
+
+       case CMD_REBOOT:
+               exit(1);
+               break;
+
+       case CMD_BOOT:
+               return 1;
+               break;
+
+       case CMD_ERROR:
+       default:
+               printf ("%s: invalid command\n", cmd->argv[0]);
+       case CMD_NOPE:
+               break;
+       }
+
+       return cmd->rc;
+}
+
+#define lsrwx(mode,s) \
+       putchar ((mode) & S_IROTH? 'r' : '-'); \
+       putchar ((mode) & S_IWOTH? 'w' : '-'); \
+       putchar ((mode) & S_IXOTH? *(s): (s)[1]);
+
+void
+ls(name, sb)
+       char *name;
+       register struct stat *sb;
+{
+       putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]);
+       lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-"));
+       lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISUID? "sS" : "x-"));
+       lsrwx(sb->st_mode     , (sb->st_mode & S_ISTXT? "tT" : "x-"));
+
+       printf (" %s\tuid=%u\tgid=%u\t%lu\n", name, sb->st_uid, sb->st_gid,
+               (u_long)sb->st_size);
+}
+
diff --git a/sys/arch/i386/stand/boot/cmd.h b/sys/arch/i386/stand/boot/cmd.h
new file mode 100644 (file)
index 0000000..35f3d58
--- /dev/null
@@ -0,0 +1,53 @@
+/*     $OpenBSD: cmd.h,v 1.1 1997/03/31 03:12:03 weingart Exp $        */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct cmd_state {
+       char bootdev[16]; /* device */
+       char image[32]; /* image */
+       char cwd[MAXPATHLEN - 32 - 32];
+       void *addr; /* load here */
+       int timeout;
+       char path[MAXPATHLEN]; /* buffer for pathname compose */
+
+       enum { CMD_ADDR, CMD_BOOT, CMD_CD, CMD_DEVICE, CMD_HELP,
+              CMD_IMAGE, CMD_LS, CMD_NOPE, CMD_REBOOT, CMD_SET,
+              CMD_ERROR /* last !!! */ };
+       int cmd;
+       int argc;
+       char *argv[8];  /* XXX i hope this is enough */
+       int rc;
+};
+
+int getcmd __P((register struct cmd_state *));
+int execmd __P((register struct cmd_state *));
diff --git a/sys/arch/i386/stand/boot/conf.c b/sys/arch/i386/stand/boot/conf.c
new file mode 100644 (file)
index 0000000..70a07c6
--- /dev/null
@@ -0,0 +1,92 @@
+/*     $OpenBSD: conf.c,v 1.2 1997/03/31 03:12:04 weingart Exp $       */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <libsa.h>
+#include <ufs.h>
+#include <nfs.h>
+#include <cd9660.h>
+#include <netif.h>
+#include "biosdev.h"
+#include "unixdev.h"
+
+int    debug = 1;
+
+struct fs_ops file_system[] = {
+       { ufs_open,    ufs_close,    ufs_read,    ufs_write,    ufs_seek,
+         ufs_stat,    ufs_readdir    },
+#ifdef notdef
+       { fat_open,    fat_close,    fat_read,    fat_write,    fat_seek,
+         fat_stat,    fat_readdir    },
+       { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek,
+         cd9660_stat, cd9660_readdir },
+#endif
+#ifndef NO_NET
+       { nfs_open,    nfs_close,    nfs_read,    nfs_write,    nfs_seek,
+         nfs_stat,    nfs_readdir    },
+#endif
+#ifdef _TEST
+       { null_open,   null_close,   null_read,   null_write,   null_seek,
+         null_stat,   null_readdir   }
+#endif
+};
+int nfsys = NENTS(file_system);
+
+struct devsw   devsw[] = {
+#ifdef _TEST
+       { "UNIX", unixstrategy, unixopen, unixclose, unixioctl },
+#else
+       { "BIOS", biosstrategy, biosopen, biosclose, biosioctl },
+#endif
+};
+int    ndevs = NENTS(devsw);
+
+#ifndef NO_NET
+struct netif_driver    *netif_drivers[] = {
+       NULL
+};
+int n_netif_drivers = NENTS(netif_drivers);
+#endif
+
+struct consw   consw[] = {
+#ifdef _TEST
+       { "unix",unix_probe,unix_putc,unix_getc,unix_ischar},
+#else
+       { "kbd", kbd_probe, kbd_putc, kbd_getc, kbd_ischar },
+       { "com", com_probe, com_putc, com_getc, com_ischar },
+#endif
+};
+int    ncons = NENTS(consw);
+
diff --git a/sys/arch/i386/stand/boot/crt0.c b/sys/arch/i386/stand/boot/crt0.c
new file mode 100644 (file)
index 0000000..14802ae
--- /dev/null
@@ -0,0 +1,115 @@
+/*     $OpenBSD: crt0.c,v 1.1 1997/03/31 03:12:04 weingart Exp $       */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <termios.h>
+#include "libsa.h"
+#include "unixdev.h"
+
+extern void start __P((void)) asm("start");
+extern int  main __P((int, char **, char **));
+static void domap __P((void));
+static void seterm __P((void));
+
+void
+start()
+{
+       domap();
+       seterm();
+       uexit(main(0, NULL, NULL));
+}
+
+#define ummap(a,l,p,f,fd,o) (caddr_t)syscall((quad_t)SYS_mmap,a,l,p,f,fd,0,o)
+
+static void
+domap()
+{
+       extern char end[];
+       register caddr_t p = (caddr_t)(((u_long)end + PGOFSET) & ~PGOFSET);
+       register size_t sz = 0x10000 - (u_long)p - NBPG;
+
+#ifdef DEBUG
+       /* we are low on memory w/ the DEBUG defined ); */
+       sz = 40 * NBPG;
+#endif
+
+       /* map heap */
+       if ( (p = ummap(p, sz, PROT_READ|PROT_WRITE,
+                  MAP_FIXED|MAP_ANON, -1, 0)) == (caddr_t)-1) {
+               printf("mmap failed: %d\n", errno);
+               uexit(1);
+       }
+#ifdef DEBUG
+       else
+               printf("mmap==%p\n", p);
+#endif
+
+       /* map kernel */
+       if ( (p = ummap(0x100000, 0xf00000, PROT_READ|PROT_WRITE,
+                  MAP_FIXED|MAP_ANON, -1, 0)) == (caddr_t)-1) {
+               printf("mmap failed: %d\n", errno);
+               uexit(1);
+       }
+#ifdef DEBUG
+       else
+               printf("mmap==%p\n", p);
+#endif
+
+}
+
+void
+seterm()
+{
+       struct termios tc;
+
+       if (uioctl(0, TIOCGETA, (char *)&tc) < 0) {
+               printf("cannot get tty\n");
+               uexit(1);
+       }
+
+        tc.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+        tc.c_oflag &= ~OPOST;
+        tc.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+        tc.c_cflag &= ~(CSIZE|PARENB);
+        tc.c_cflag |= CS8;
+
+       if (uioctl(0, TIOCSETA, (char *)&tc) < 0) {
+               printf("cannot set tty\n");
+               uexit(1);
+       }
+}
diff --git a/sys/arch/i386/stand/boot/srt0.S b/sys/arch/i386/stand/boot/srt0.S
new file mode 100644 (file)
index 0000000..923a47a
--- /dev/null
@@ -0,0 +1,258 @@
+/*     $OpenBSD: srt0.S,v 1.1 1997/03/31 03:12:05 weingart Exp $       */
+/*     $NetBSD: srt0.c,v 1.3 1994/10/27 04:21:59 cgd Exp $     */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)srt0.c      5.3 (Berkeley) 4/28/91
+ */
+
+/*
+ * Startup code for standalone system
+ * Non-relocating version -- for programs which are loaded by boot
+ * Relocating version for boot
+ * Small relocating version for "micro" boot
+ */
+
+#include <machine/psl.h>
+#define _LOCORE
+#include <machine/segments.h>
+#undef _LOCORE
+
+       .globl  _end
+       .globl  _edata
+       .globl  _boot
+       .globl  __rtt
+
+       .data
+       .globl  _Gdtr
+       .align  2
+_Gdtr: .word   4 * 8 - 1
+       .long   2f
+       .align  3
+2:             /* 0x00 : null */
+       .long   0, 0
+               /* 0x08 : flat code */
+       .word   0xFFFF                  # lolimit
+       .word   0                       # lobase
+       .byte   0                       # midbase
+       .byte   SDT_MEMERAC | 0 | 0x80  # RWXAC, dpl = 0, present
+       .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
+       .byte   0                       # hibase
+               /* 0x10 : flat data */
+       .word   0xFFFF                  # lolimit
+       .word   0                       # lobase
+       .byte   0                       # midbase
+       .byte   SDT_MEMRWA | 0 | 0x80   # RWA, dpl = 0, present
+       .byte   0xf | 0 | 0x40 | 0x80   # hilimit, xx, 32bit, 4k granularity
+       .byte   0                       # hibase
+               /* 0x18 : 16 bit code */
+       .word   0xFFFF                  # lolimit
+       .word   0                       # lobase
+       .byte   0                       # midbase
+       .byte   SDT_MEMERC | 0 | 0x80   # RWXAC, dpl = 0, present
+       .byte   0x0 | 0 | 0 | 0         # hilimit, xx, 16bit, byte granularity
+       .byte   0                       # hibase
+
+       .globl  _codeseg
+       .globl  _bootdev
+       .globl  _boothowto
+       .globl  _cyloffset
+_codeseg:      .long   0
+_bootdev:      .long   0
+_boothowto:    .long   0
+_cyloffset:    .long   0
+_esym:         .long   0
+
+       .text
+text_start:
+
+#define        NOP     inb $0x84,%al ; inb $0x84,%al
+
+       .globl  start_boot
+
+start_boot:
+       pushl   %ebp
+       movl    %esp, %ebp
+
+#ifdef REL
+       /* relocate code+data */
+       call    1f
+1:     popl    %esi
+       subl    $1b, %esi
+       addl    $text_start, %esi       /* %esi = %eip - (1b - text_start) */
+       subl    $0x20, %esi                     /* XXX - Fudge factor for header */
+       movl    $REL, %edi
+       movl    $_edata, %ecx
+       subl    $text_start, %ecx
+       shrl    $2, %ecx
+       incl    %ecx
+       cld
+       rep
+       movsl
+#endif /* REL */
+
+       lgdt    _Gdtr
+
+       /* The following should *not* be moved before the lgdt.
+        * Trust me, bad things will happen!
+        * Start executing from relocated code
+        */
+       movl    $0x10, %eax
+       movl    %eax, %ds
+       movl    %eax, %es
+       movl    %eax, %fs
+       movl    %eax, %gs
+       movl    %eax, %ss
+       ljmp    $0x8,$docs
+docs:
+       nop
+
+       /* XXX - I don't know if the following is right */
+       movl    8(%ebp), %eax
+       movl    %eax, _boothowto
+       movl    12(%ebp),%eax
+       movl    %eax, _bootdev
+       movl    16(%ebp),%eax
+       movl    %eax, _cyloffset
+       movl    20(%ebp),%eax
+       movl    %eax, _esym
+
+       /* save old stack state */
+       movl    %esp,savearea
+       movl    %ebp,savearea+4
+
+       /* setup stack pointer */
+#ifdef REL
+       movl    $0xfffc, %esp
+#else  
+       movl    $_end, %eax
+       addl    $10000, %eax
+       movl    %eax, %esp
+#endif
+
+       /* clear memory as needed */
+       movl    %esp,%esi
+       movl    $_end, %eax
+       subl    $_edata,%eax
+       pushl   %eax
+       pushl   $0
+       pushl   $_edata
+       call    _memset
+       #call   _kbdreset       /* resets keyboard and gatea20 brain damage */
+       movl    %esi,%esp
+
+       pushl   __rtt
+       ljmp    $0x8, $_boot    /* Jmp to boot code */
+
+       .data
+
+savearea:      .long   0,0     # sp & bp to return to
+
+       .text
+
+__rtt:
+       movl    $-7,%eax
+#ifdef REL
+       movw    $0x1234,%ax
+       movw    %ax,0x472       # warm boot
+       movl    $0,%esp         # segment violation
+       ret
+#else
+       movl    savearea,%esp
+       movl    savearea+4,%ebp
+       ret
+#endif
+
+       .globl  _inb
+_inb:  movl    4(%esp),%edx
+       subl    %eax,%eax       # clr eax
+       NOP
+       inb     %dx,%al
+       ret
+
+       .globl  _outb
+_outb: movl    4(%esp),%edx
+       NOP
+       movl    8(%esp),%eax
+       outb    %al,%dx
+       ret
+
+       .globl ___udivsi3
+___udivsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       divl 8(%esp)
+       ret
+
+       .globl ___divsi3
+___divsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       cltd
+       idivl 8(%esp)
+       ret
+
+       .globl  _insw
+_insw:
+       pushl   %edi
+       movw    8(%esp),%dx
+       movl    12(%esp),%edi
+       movl    16(%esp),%ecx
+       NOP
+       cld
+       nop
+       .byte 0x66,0xf2,0x6d    # rep insw
+       nop
+       movl    %edi,%eax
+       popl    %edi
+       ret
+
+       # outsw(port,addr,cnt)
+       .globl  _outsw
+_outsw:
+       pushl   %esi
+       movw    8(%esp),%dx
+       movl    12(%esp),%esi
+       movl    16(%esp),%ecx
+       NOP
+       cld
+       nop
+       .byte 0x66,0xf2,0x6f    # rep outsw
+       nop
+       movl    %esi,%eax
+       popl    %esi
+       ret
+
diff --git a/sys/arch/i386/stand/boot/version.c b/sys/arch/i386/stand/boot/version.c
new file mode 100644 (file)
index 0000000..78ecc80
--- /dev/null
@@ -0,0 +1,2 @@
+
+char   version[] = "1.0";
diff --git a/sys/arch/i386/stand/installboot/Makefile b/sys/arch/i386/stand/installboot/Makefile
new file mode 100644 (file)
index 0000000..ec82f45
--- /dev/null
@@ -0,0 +1,10 @@
+#      $OpenBSD: Makefile,v 1.2 1997/03/31 03:12:06 weingart Exp $
+
+PROG=  installboot
+CFLAGS+=-DDEBUG -g -Wall
+MAN=   installboot.8
+
+# Need this to work in the miniroot
+LDSTATIC=      -static
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/stand/installboot/installboot.8 b/sys/arch/i386/stand/installboot/installboot.8
new file mode 100644 (file)
index 0000000..b52eb65
--- /dev/null
@@ -0,0 +1,58 @@
+.\"    $OpenBSD: installboot.8,v 1.2 1997/03/31 03:12:06 weingart Exp $
+.\"
+.Dd 31 May 1995
+.Dt INSTALLBOOT 8
+.Os 
+.Sh NAME
+.Nm installboot
+.Nd install a bootstrap on a UFS disk
+.Sh SYNOPSIS
+.Nm installboot
+.Fl n | Fl v
+.Ar ufsboot
+.Ar bootxx
+.Ar rawdev
+.Sh DESCRIPTION
+.Nm installboot
+is used to install a "first-stage" boot program into the boot area
+of a UFS disk partition, and initialize the table of block numbers the
+.Ar bootxx
+program uses to load the second-stage boot program.
+.Pp
+The options are as follows:
+.Bl -tag -width flag
+.It Fl n
+Do not actually write anything on the disk.
+.It Fl v
+Be verbose, printing out the block numbers that
+.Ar bootxx
+will use to load
+.Ar ufsboot .
+.El
+.Pp
+The arguments are:
+.Bl -tag -width ufsboot
+.It Ar ufsboot
+the name of the second-stage boot program in the file system
+where the first-stage boot program is to be installed.
+.It Ar bootxx
+the name of the prototype file for the first stage boot program.
+.It Ar rawdev
+the name of the raw device in which the first-stage boot program
+is to be installed.  This should correspond to the block device
+on which the file system containing
+.Ar ufsboot
+is mounted.
+.El
+.Sh BUGS
+.Nm installboot
+requires simultaneous access to the mounted file system and
+the raw device, but that is not allowed with the kernel
+.Nm securelevel
+variable set to a value greater than zero (the default), so
+.Nm installboot
+only works in single-user mode (or insecure mode - see 
+.Xr init 8 ).
+.Sh "SEE ALSO"
+.Xr disklabel 8 ,
+.Xr init 8
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c
new file mode 100644 (file)
index 0000000..8b6d25a
--- /dev/null
@@ -0,0 +1,436 @@
+/*     $OpenBSD: installboot.c,v 1.2 1997/03/31 03:12:07 weingart Exp $        */
+/*     $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
+
+/*
+ * Copyright (c) 1994 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
+#include <ufs/ffs/fs.h>
+#include <err.h>
+#include <a.out.h>
+#include <fcntl.h>
+#include <nlist.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int    verbose, nowrite;
+char   *boot, *proto, *dev;
+struct nlist nl[] = {
+#define X_BLOCK_COUNT  0
+       {{"_block_count"}},
+#define X_BLOCK_TABLE  1
+       {{"_block_table"}},
+       {{NULL}}
+};
+
+u_int8_t *block_count_p;       /* block count var. in prototype image */
+u_int8_t *block_table_p;       /* block number array in prototype image */
+int    maxblocknum;    /* size of this array */
+
+
+char           *loadprotoblocks __P((char *, long *));
+int            loadblocknums __P((char *, int));
+static void    devread __P((int, void *, daddr_t, size_t, char *));
+static void    usage __P((void));
+static int     record_block
+       __P((u_int8_t *, daddr_t, u_int, struct disklabel *));
+
+static void
+usage()
+{
+       fprintf(stderr,
+               "usage: installboot [-n] [-v] <boot> <proto> <device>\n");
+       exit(1);
+}
+
+int
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       int     c;
+       int     devfd;
+       char    *protostore;
+       long    protosize;
+
+       while ((c = getopt(argc, argv, "vn")) != EOF) {
+               switch (c) {
+               case 'n':
+                       /* Do not actually write the bootblock to disk */
+                       nowrite = 1;
+                       break;
+               case 'v':
+                       /* Chat */
+                       verbose = 1;
+                       break;
+               default:
+                       usage();
+               }
+       }
+
+       if (argc - optind < 3) {
+               usage();
+       }
+
+       boot = argv[optind];
+       proto = argv[optind + 1];
+       dev = argv[optind + 2];
+
+       if (verbose) {
+               printf("boot: %s\n", boot);
+               printf("proto: %s\n", proto);
+               printf("device: %s\n", dev);
+       }
+
+       /* Load proto blocks into core */
+       if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
+               exit(1);
+
+       /* XXX - Paranoia: Make sure size is aligned! */
+       if (protosize & (DEV_BSIZE - 1))
+               err(1, "proto bootblock bad size=%ld", protosize);
+
+       /* Open and check raw disk device */
+       if ((devfd = open(dev, O_RDONLY, 0)) < 0)
+               err(1, "open: %s", dev);
+
+       /* Extract and load block numbers */
+       if (loadblocknums(boot, devfd) != 0)
+               exit(1);
+
+       (void)close(devfd);
+
+       if (nowrite)
+               return 0;
+
+       /* Write patched proto bootblocks into the superblock */
+       if (protosize > SBSIZE - DEV_BSIZE)
+               errx(1, "proto bootblocks too big");
+
+       if ((devfd = open(dev, O_RDWR, 0)) < 0)
+               err(1, "open: %s", dev);
+
+       /* Sync filesystems (to clean in-memory superblock?) */
+       sync();
+
+       if (write(devfd, protostore, protosize) != protosize)
+               err(1, "write bootstrap");
+       (void)close(devfd);
+       return 0;
+}
+
+char *
+loadprotoblocks(fname, size)
+       char *fname;
+       long *size;
+{
+       int     fd;
+       size_t  tdsize;         /* text+data size */
+       char    *bp;
+       struct  nlist *nlp;
+       struct  exec eh;
+
+       fd = -1;
+       bp = NULL;
+
+       /* Locate block number array in proto file */
+       if (nlist(fname, nl) != 0) {
+               warnx("nlist: %s: symbols not found", fname);
+               return NULL;
+       }
+       /* Validate symbol types (global data). */
+       for (nlp = nl; nlp->n_un.n_name; nlp++) {
+               if (nlp->n_type != (N_TEXT | N_EXT)) {
+                       warnx("nlist: %s: wrong type", nlp->n_un.n_name);
+                       return NULL;
+               }
+       }
+
+       if ((fd = open(fname, O_RDONLY)) < 0) {
+               warn("open: %s", fname);
+               return NULL;
+       }
+       if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {
+               warn("read: %s", fname);
+               goto bad;
+       }
+       if (N_GETMAGIC(eh) != OMAGIC) {
+               warn("bad magic: 0x%lx", eh.a_midmag);
+               goto bad;
+       }
+       /*
+        * We have to include the exec header in the beginning of
+        * the buffer, and leave extra space at the end in case
+        * the actual write to disk wants to skip the header.
+        */
+       tdsize = eh.a_text + eh.a_data;
+
+       /*
+        * Allocate extra space here because the caller may copy
+        * the boot block starting at the end of the exec header.
+        * This prevents reading beyond the end of the buffer.
+        */
+       if ((bp = calloc(tdsize, 1)) == NULL) {
+               warnx("malloc: %s: no memory", fname);
+               goto bad;
+       }
+       /* Read the rest of the file. */
+       if (read(fd, bp, tdsize) != tdsize) {
+               warn("read: %s", fname);
+               goto bad;
+       }
+
+       *size = tdsize; /* not aligned to DEV_BSIZE */
+
+       /* Calculate the symbols' locations within the proto file */
+       block_count_p = (u_int8_t *) (bp + nl[X_BLOCK_COUNT].n_value);
+       block_table_p = (u_int8_t *) (bp + nl[X_BLOCK_TABLE].n_value);
+       maxblocknum = *block_count_p;
+
+       if (verbose) {
+               printf("%s: entry point %#lx\n", fname, eh.a_entry);
+               printf("proto bootblock size %ld\n", *size);
+               printf("room for %d filesystem blocks at %#lx\n",
+                       maxblocknum, nl[X_BLOCK_TABLE].n_value);
+       }
+
+       close(fd);
+       return bp;
+
+ bad:
+       if (bp)
+               free(bp);
+       if (fd >= 0)
+               close(fd);
+       return NULL;
+}
+
+static void
+devread(fd, buf, blk, size, msg)
+       int     fd;
+       void    *buf;
+       daddr_t blk;
+       size_t  size;
+       char    *msg;
+{
+       if (lseek(fd, dbtob(blk), SEEK_SET) != dbtob(blk))
+               err(1, "%s: devread: lseek", msg);
+
+       if (read(fd, buf, size) != size)
+               err(1, "%s: devread: read", msg);
+}
+
+static char sblock[SBSIZE];
+
+int
+loadblocknums(boot, devfd)
+char   *boot;
+int    devfd;
+{
+       int             i, fd;
+       struct stat     statbuf;
+       struct statfs   statfsbuf;
+       struct disklabel dl;
+       struct fs       *fs;
+       char            *buf;
+       daddr_t         blk, *ap;
+       struct dinode   *ip;
+       int             ndb;
+       u_int8_t        *bt;
+       struct exec     eh;
+
+       /*
+        * Open 2nd-level boot program and record the block numbers
+        * it occupies on the filesystem represented by `devfd'.
+        */
+
+       /* Make sure the (probably new) boot file is on disk. */
+       sync(); sleep(1);
+
+       if (ioctl(devfd, DIOCGDINFO, &dl) != 0)
+               err(1, "disklabel: %s", dev);
+
+       /* check disklabel */
+       if (dl.d_magic != DISKMAGIC)
+               err(1, "bad disklabel magic=%0x8x", dl.d_magic);
+
+       if ((fd = open(boot, O_RDONLY)) < 0)
+               err(1, "open: %s", boot);
+
+       if (fstatfs(fd, &statfsbuf) != 0)
+               err(1, "statfs: %s", boot);
+
+       if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&
+           strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN) ) {
+               errx(1, "%s: must be on an FFS filesystem", boot);
+       }
+
+       if (read(fd, &eh, sizeof(eh)) != sizeof(eh)) {
+               errx(1, "read: %s", boot);
+       }
+
+       if (N_GETMAGIC(eh) != ZMAGIC) {
+               errx(1, "%s: bad magic: 0x%lx", boot, eh.a_midmag);
+       }
+
+       if (fsync(fd) != 0)
+               err(1, "fsync: %s", boot);
+
+       if (fstat(fd, &statbuf) != 0)
+               err(1, "fstat: %s", boot);
+
+       close(fd);
+
+       /* Read superblock */
+       devread(devfd, sblock, SBLOCK, SBSIZE, "superblock");
+       fs = (struct fs *)sblock;
+
+       /* Sanity-check super-block. */
+       if (fs->fs_magic != FS_MAGIC)
+               errx(1, "Bad magic number in superblock");
+       if (fs->fs_inopb <= 0)
+               err(1, "Bad inopb=%d in superblock", fs->fs_inopb);
+
+       /* Read inode */
+       if ((buf = malloc(fs->fs_bsize)) == NULL)
+               errx(1, "No memory for filesystem block");
+
+       blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));
+       devread(devfd, buf, blk, fs->fs_bsize, "inode");
+       ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);
+
+       /*
+        * Have the inode.  Figure out how many blocks we need.
+        */
+       ndb = howmany(ip->di_size, fs->fs_bsize);
+       if (ndb > maxblocknum)
+               errx(1, "Too many blocks");
+       if (verbose)
+               printf("Will load %d blocks of size %d each.\n",
+                          ndb, fs->fs_bsize);
+
+       /*
+        * Get the block numbers; we don't handle fragments
+        */
+       ap = ip->di_db;
+       bt = block_table_p;
+       for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--)
+               bt += record_block(bt, fsbtodb(fs, *ap),
+                                           fs->fs_bsize / 512, &dl);
+       if (ndb != 0) {
+
+               /*
+                * Just one level of indirections; there isn't much room
+                * for more in the 1st-level bootblocks anyway.
+                */
+               blk = fsbtodb(fs, ip->di_ib[0]);
+               devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
+               ap = (daddr_t *)buf;
+               for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--)
+                       bt += record_block(bt, fsbtodb(fs, *ap),
+                                          fs->fs_bsize / 512, &dl);
+       }
+
+       /* write out remaining piece */
+       bt += record_block(bt, 0, 0, &dl);
+       /* and again */
+       bt += record_block(bt, 0, 0, &dl);
+       *block_count_p = (bt - block_table_p) / 4;
+
+       if (verbose)
+               printf("%s: %d entries total\n", boot, *block_count_p);
+
+       return 0;
+}
+
+static int
+record_block(bt, blk, bs, dl)
+       u_int8_t *bt;
+       daddr_t blk;
+       u_int bs;
+       struct disklabel *dl;
+{
+       static u_int ss = 0, l = 0, i = 0; /* start and len of group */
+       int ret = 0;
+
+       if (ss == 0) { /* very beginning */
+               ss = blk;
+               l = bs;
+               return 0;
+       } else if (l == 0)
+               return 0;
+
+       /* record on track boundary or non-contig blocks or last call */
+       if ((ss + l) != blk ||
+           (ss % dl->d_nsectors + l) >= dl->d_nsectors) {
+               register u_int c = ss / dl->d_secpercyl,
+                       s = ss % dl->d_nsectors + 1;
+
+               /* nsectors */
+               if ((ss % dl->d_nsectors + l) >= dl->d_nsectors)
+                       bt[3] = dl->d_nsectors - s + 1;
+               else
+                       bt[3] = l; /* non-contig or last block piece */
+
+               bt[2] = (ss % dl->d_secpercyl) / dl->d_nsectors; /* head */
+               *(u_int16_t *)bt = (s & 0x3f) | /* sect, cyl */
+                       ((c & 0xff) << 8) | ((c & 0x300) >> 2);
+
+               if (verbose)
+                       printf("%2d: %2d @(%d %d %d) (%d-%d)\n",
+                              i, bt[3], c, bt[2], s, ss, ss + bt[3] - 1);
+
+               if ((ss % dl->d_nsectors + l) >= dl->d_nsectors) {
+                       ss += bt[3];
+                       l -= bt[3];
+                       l += bs;
+               } else {
+                       ss = blk;
+                       l = bs;
+               }
+
+               i++;
+               ret = 4;
+       } else {
+               l += bs;
+       }
+
+       return ret;
+}
diff --git a/sys/arch/i386/stand/libsa/Makefile b/sys/arch/i386/stand/libsa/Makefile
new file mode 100644 (file)
index 0000000..42b2fee
--- /dev/null
@@ -0,0 +1,51 @@
+#      $OpenBSD: Makefile,v 1.2 1997/03/31 03:12:08 weingart Exp $
+
+
+LIB= sa
+
+CFLAGS+=-Wall
+#CFLAGS+=-DBIOS_DEBUG
+CFLAGS+=-DEXEC_DEBUG
+CFLAGS+=-DNO_IDTR
+CFLAGS+=-DHEAP_START="0x10000"
+CFLAGS+=-DHEAP_LIMIT="0xa0000"
+CFLAGS+=-D__INTERNAL_LIBSA_CREAD
+CFLAGS+=${DEBUGFLAGS} -I${.CURDIR} -I${.CURDIR}/..
+CFLAGS+=-I${.CURDIR}/../../../..  -I${.CURDIR}/../../../../lib/libsa
+#AS+=  -Wa,-a
+
+S=${.CURDIR}/../../../..
+DIR_SA=$S/lib/libsa
+DIR_KERN=$S/lib/libkern
+
+# stand routines
+SRCS=   alloc.c exit.c exec.c getfile.c gets.c globals.c strcmp.c \
+        strncmp.c memcmp.c memcpy.c memset.c printf.c strerror.c strncpy.c
+
+# io routines
+SRCS+=  close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c ioctl.c lseek.c \
+        open.c read.c stat.c write.c cread.c readdir.c cons.c
+
+# network routines
+SRCS+=  arp.c ether.c in_cksum.c net.c netif.c rpc.c
+
+# network info services
+SRCS+=  bootp.c bootparam.c rarp.c
+
+# boot filesystems
+SRCS+=  ufs.c nfs.c
+
+# i386 stuff
+SRCS+= asm.S bioscom.S biosdev.c biosdisk.S bioskbd.S biostime.S startprog.S \
+       dev_i386.c exec_i386.c gateA20.c memprobe.c memsize.S probe_keyboard.c \
+       real_prot.S srt0.S unixsys.S
+
+NOPROFILE=noprofile
+NOPIC=nopic
+
+.PATH:  ${DIR_SA} ${DIR_KERN}
+
+all: ${SALIB}
+
+.include <bsd.lib.mk>
+
diff --git a/sys/arch/i386/stand/libsa/asm.S b/sys/arch/i386/stand/libsa/asm.S
new file mode 100644 (file)
index 0000000..23de810
--- /dev/null
@@ -0,0 +1,108 @@
+/*     $OpenBSD: asm.S,v 1.1 1997/03/31 03:12:08 weingart Exp $        */
+/*     $NetBSD: srt0.c,v 1.3 1994/10/27 04:21:59 cgd Exp $     */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)srt0.c      5.3 (Berkeley) 4/28/91
+ */
+
+/*
+ * Startup code for standalone system
+ * Non-relocating version -- for programs which are loaded by boot
+ * Relocating version for boot
+ * Small relocating version for "micro" boot
+ */
+
+       .globl  _inb
+_inb:  movl    4(%esp),%edx
+       subl    %eax,%eax       # clr eax
+       NOP
+       inb     %dx,%al
+       ret
+
+       .globl  _outb
+_outb: movl    4(%esp),%edx
+       NOP
+       movl    8(%esp),%eax
+       outb    %al,%dx
+       ret
+
+       .globl ___udivsi3
+___udivsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       divl 8(%esp)
+       ret
+
+       .globl ___divsi3
+___divsi3:
+       movl 4(%esp),%eax
+       xorl %edx,%edx
+       cltd
+       idivl 8(%esp)
+       ret
+
+       .globl  _insw
+_insw:
+       pushl   %edi
+       movw    8(%esp),%dx
+       movl    12(%esp),%edi
+       movl    16(%esp),%ecx
+       NOP
+       cld
+       nop
+       .byte 0x66,0xf2,0x6d    # rep insw
+       nop
+       movl    %edi,%eax
+       popl    %edi
+       ret
+
+       # outsw(port,addr,cnt)
+       .globl  _outsw
+_outsw:
+       pushl   %esi
+       movw    8(%esp),%dx
+       movl    12(%esp),%esi
+       movl    16(%esp),%ecx
+       NOP
+       cld
+       nop
+       .byte 0x66,0xf2,0x6f    # rep outsw
+       nop
+       movl    %esi,%eax
+       popl    %esi
+       ret
+
diff --git a/sys/arch/i386/stand/libsa/bioscom.S b/sys/arch/i386/stand/libsa/bioscom.S
new file mode 100644 (file)
index 0000000..f840200
--- /dev/null
@@ -0,0 +1,208 @@
+/*     $OpenBSD: bioscom.S,v 1.2 1997/03/31 03:12:09 weingart Exp $    */
+
+/*
+ * 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: bioscom.S,v 1.2 1997/03/31 03:12:09 weingart 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.
+*/
+
+/*
+ * Serial bootblock interface routines
+ * Copyright (c) 1994, J"org Wunsch
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ */ 
+
+       .file   "serial.s"
+
+#include <machine/asm.h>
+
+port:
+       .long   0x3f8
+
+       .text
+
+/*
+ * The serial port interface routines implement a simple polled i/o
+ * interface to a standard serial port.  Due to the space restrictions
+ * for the boot blocks, no BIOS support is used (since BIOS requires
+ * expensive real/protected mode switches), instead the rudimentary
+ * BIOS support is duplicated here.
+ *
+ * The base address for the i/o port is stored in 'port' variable upon
+ * probing for device.  Console parameters are currently
+ * hard-coded to 9600 Bd, 8 bit.  This can be changed in the
+ * init_serial() function.
+ */
+
+/*
+ * int com_probe();
+ *     probe com[0-3] ports and store first found in 'port' variable
+ */
+ENTRY(com_probe)
+       push    %ebp
+       mov     %esp, %ebp
+
+       /*
+        * void init_serial(void)
+        *      initialize the serial console port to 9600 Bd, 8 bpc
+        */
+       movl    $port, %edx     # line control reg
+       addb    5, %dl
+       movl    $0x80, %eax
+       outb    %al, %dx        # enable DLAB
+
+       subb    $3, %dl         # divisor latch, low byte
+       movb    $12, %al        # divisor 12: 9600 Bd
+       outb    %al, %dx
+       incl    %edx            # divisor latch, high byte
+       movb    %ah, %al
+       outb    %al, %dx
+
+       addb    $2, %dl         # line control reg
+       movb    $0x13, %al
+       outb    %al, %dx        # 8 bit, no parity, 1 stop bit
+
+       incl    %edx            # modem control reg
+       movb    $3, %al
+       outb    %al, %dx        # enable DTR/RTS
+
+       /* now finally, flush the input buffer */
+       incl    %edx            # line status reg
+1:
+       inb     %dx, %al
+       testb   $0x01, %al
+       jz      2f              # no more characters buffered
+       subb    $5, %dl         # rx buffer reg
+       inb     %dx, %al        # throw away
+       addb    $5, %dl
+       jmp     1b
+2:
+       xorl    %eax, %eax      # is present (:
+       incl    %eax
+       popl    %ebp
+       ret
+
+/*
+ * void com_putc(ch) char ch;
+ *     send ch to serial port
+ *
+ */
+
+ENTRY(com_putc)
+       pushl   %ebp
+       movl    %esp, %ebp
+
+       movl    $port, %edx     # line status reg
+       add     5, %edx
+1:     inb     %dx, %al
+       test    $0x20, %al
+       jz      1b              # TX buffer not empty
+
+       movb    8(%ebp), %al
+
+       sub     $5, %edx        # TX output reg
+       outb    %al, %dx        # send this one
+
+       popl    %ebp
+       ret
+
+/*
+ * int com_getc(void)
+ *     read a character from serial port
+ */
+
+ENTRY(com_getc)
+       push    %ebp
+       movl    %esp, %ebp
+
+       movl    $port, %edx     # line status reg
+       addl    5, %edx
+1:
+       inb     %dx, %al
+       testb   $0x01, %al
+       jz      1b              # no RX char available
+
+       xorl    %eax, %eax
+       subl    $5, %edx        # RX buffer reg
+       inb     %dx, %al        # fetch (first) character
+
+       andb    $0x7F, %eax     # remove any parity bits we get
+       cmpb    $0x7F, %eax     # make DEL...
+       jne     2f
+       movb    $0x08, %eax     # look like BS
+2:
+       popl    %ebp
+       ret
+
+/*
+ * int com_ischar(void)
+ *       if there is a character pending, return true; otherwise return 0
+ */
+ENTRY(com_ischar)
+       push    %ebp
+       mov     %esp, %ebp
+
+       xorl    %eax, %eax
+       movl    $port, %edx     # line status reg
+       addl    5, %edx
+       inb     %dx, %al
+       andb    $0x01, %al              # RX char available?
+
+       pop     %ebp
+       ret
+
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
new file mode 100644 (file)
index 0000000..6049c63
--- /dev/null
@@ -0,0 +1,197 @@
+/*     $OpenBSD: biosdev.c,v 1.2 1997/03/31 03:12:09 weingart Exp $    */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <libsa.h>
+#include "biosdev.h"
+
+dev_t  maj, unit, part;
+
+int
+biosstrategy(void *devdata, int rw,
+       daddr_t blk, size_t size, void *buf, size_t *rsize)
+{
+       int     error = 0;
+       u_int   dinfo;
+       register size_t i, nsect;
+       void *local_buf, *lb;                   /* 1MB real mode stuff */
+
+       /* We need a buffer below 1MB 
+        *
+        * Note: not really needed for the gzip stuff,
+        * as it already allocates buffers below 1MB,
+        * but just to make sure (in case using oread()
+        */
+       lb = local_buf = alloc(size);
+
+#ifdef BIOS_DEBUG
+       printf("biosstrategy: %s %d bytes @ %d -> %p\n",
+               (rw==F_READ?"reading":"writing"), size, blk, buf);
+#endif
+
+       dinfo = biosdinfo(bootdev);
+       nsect = (size + DEV_BSIZE-1) / DEV_BSIZE;
+       for (i = 0; error == 0 && i < nsect; ) {
+               register int    cyl, hd, sect, n;
+
+               btochs(blk, cyl, hd, sect, 
+                       BIOSNHEADS(dinfo), BIOSNSECTS(dinfo));
+               if ((sect + (nsect - i)) >= BIOSNSECTS(dinfo))
+                       n = BIOSNSECTS(dinfo) - sect;
+               else
+                       n = nsect - i;
+#ifdef BIOS_DEBUG
+               printf("biosread: dev=%x, cyl=%d, hd=%d, sc=%d, n=%d, buf=%lx",
+                       bootdev, cyl, hd, sect, n, (u_long)local_buf);
+#endif
+               if (rw == F_READ)
+                       error = biosread (bootdev, cyl, hd, sect, n, local_buf);
+               else
+                       error = bioswrite(bootdev, cyl, hd, sect, n, local_buf);
+#ifdef BIOS_DEBUG
+               printf(", ret=%x\n", error);
+#endif
+               local_buf += n * DEV_BSIZE;
+               i += n;
+               blk += n;
+       }
+
+       /* Copy to final location */
+       memcpy(buf, lb, size);
+       free(lb, size);
+
+       /* Amount we read */
+       *rsize = i * DEV_BSIZE;
+
+       return error;
+}
+
+int
+biosopen(struct open_file *f, ...)
+{
+       va_list ap;
+       register char   *cp, *fname, **file;
+       static const char *devs[] = {"wd", "hd", "fd", "wt", "sd", NULL};
+
+       va_start(ap, f);
+       cp = fname = *(file = va_arg(ap, char **));
+       va_end(ap);
+
+       /* search for device specification */
+       while (*cp != 0 && *cp != '(')
+               cp++;
+       if (*cp != 0) {
+               if (*cp++ == '(') {
+                       char **devp = (char **)devs;
+
+                       for (; *devp != NULL && 
+                               (fname[0] != (*devp)[0] ||
+                                fname[1] != (*devp)[1]); devp++)
+                               ;
+                       if (*devp == NULL) {
+                               printf("Unknown device");
+                               errno = ENXIO;
+                               return -1;
+                       }
+                       maj = devp - (char **)devs;
+               }
+               /* check syntax */
+               if (cp[1] != ',' || cp[3] != ')') {
+                       printf("Syntax error\n");
+                       errno = EINVAL;
+                       return -1;
+               }
+
+               /* get unit */
+               if ('0' <= *cp && *cp <= '9')
+                       unit = *cp++ - '0';
+               else {
+                       printf("Bad unit number\n");
+                       errno = ENXIO;
+                       return -1;
+               }
+               cp++;   /* skip ',' */
+               /* get partition */
+               if ('a' <= *cp && *cp <= 'p')
+                       part = *cp++ - 'a';
+               else {
+                       printf("Bad partition id\n");
+                       errno = ENXIO;
+                       return -1;
+               }
+               cp++;   /* skip ')' */
+               if (*cp != 0)
+                       *file = cp;
+
+               switch (maj) {
+               case 0:
+               case 4:
+                       bootdev = unit | 0x80;
+                       break;
+               case 1:
+                       bootdev = unit | 0x80;
+                       unit = 0;
+                       break;
+               case 2:
+                       bootdev = unit;
+                       break;
+               case 3:
+#ifdef DEBUG
+                       printf("Wangtek is unsupported\n");
+#endif
+                       errno = ENXIO;
+                       return -1;
+               default:
+                       break;
+               }
+
+       }
+
+       return 0;
+}
+
+int
+biosclose(struct open_file *f)
+{
+
+       return 0;
+}
+
+int
+biosioctl(struct open_file *f, u_long cmd, void *data)
+{
+
+       return 0;
+}
+
diff --git a/sys/arch/i386/stand/libsa/biosdev.h b/sys/arch/i386/stand/libsa/biosdev.h
new file mode 100644 (file)
index 0000000..da61902
--- /dev/null
@@ -0,0 +1,64 @@
+/*     $OpenBSD: biosdev.h,v 1.2 1997/03/31 03:12:10 weingart Exp $    */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+
+#define        BIOSNHEADS(d)   (((d)>>8)+1)
+#define        BIOSNSECTS(d)   ((d)&0xff)      /* sectors are 1-based */
+
+/* biosdev.c */
+extern const char *biosdevs[];
+int biosstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
+int biosopen __P((struct open_file *, ...));
+int biosclose __P((struct open_file *));
+int biosioctl __P((struct open_file *, u_long, void *));
+
+/* biosdisk.S */
+u_int  biosdinfo __P((int dev));
+int     biosread  __P((int dev, int cyl, int hd, int sect, int nsect, void *));
+int     bioswrite __P((int dev, int cyl, int hd, int sect, int nsect, void *));
+
+/* bioskbd.S */
+int    kbd_probe __P((void));
+void   kbd_putc __P((int c));
+int    kbd_getc __P((void));
+int    kbd_ischar __P((void));
+
+/* bioscom.S */
+int    com_probe __P((void));
+void   com_putc __P((int c));
+int    com_getc __P((void));
+int    com_ischar __P((void));
+
+/* biostime.S */
+void   usleep __P((u_long));
diff --git a/sys/arch/i386/stand/libsa/biosdisk.S b/sys/arch/i386/stand/libsa/biosdisk.S
new file mode 100644 (file)
index 0000000..f036d0f
--- /dev/null
@@ -0,0 +1,187 @@
+/*     $OpenBSD: biosdisk.S,v 1.2 1997/03/31 03:12:11 weingart Exp $   */
+
+/*
+ * 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.
+ */
+
+/*
+  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 <machine/asm.h>
+#define        addr32  .byte 0x67
+#define        data32  .byte 0x66
+
+/*
+# 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)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+       push    %es
+
+       movb    8(%ebp), %dl    # device
+       movw    12(%ebp), %cx
+       xchgb   %ch, %cl        # cylinder; the highest 2 bits of cyl is in %cl
+       rorb    $2, %cl
+       movb    16(%ebp), %dh   # head
+       movb    20(%ebp), %al
+       orb     %al, %cl
+       incb    %cl             # sector; sec starts from 1, not 0
+       movb    $0x2, %ah       # subfunction
+       movb    24(%ebp), %al   # number of sectors
+       movl    %eax, %esi      # save this against mode switch
+       movl    28(%ebp), %ebx  # offset
+
+
+       # prot_to_real will set %es to BOOTSEG
+       # Which means %cs == %es.
+       # XXX - This hoses things severly.  Better
+       # recoup %es to point to the base of the given
+       # buffer, and let %bx be the index into it,
+       # that way we can read a max of 64K give or
+       # take 15 bytes anyways.
+
+       # Save %es in %edi
+       movl    %ebx, %eax
+       shrl    $4, %eax
+       movl    %eax, %edi
+       andl    $0xF, %ebx
+
+       call    _C_LABEL(prot_to_real)  # enter real mode
+
+       # Restore %es
+       movl    %di, %es
+
+       # Restore %ax
+       movl    %si, %ax
+
+       int     $0x13
+       setc    %bl
+
+       data32
+       call    _C_LABEL(real_to_prot) # back to protected mode
+
+       movzbl  %bl, %eax       # return value in %ax
+
+       pop             %es
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+ENTRY(bioswrite)
+
+       movl    $1, %eax
+       ret
+
+/*
+#
+# biosdinfo():  return a word that represents the
+#      max number of sectors and  heads and drives for this device
+#
+*/
+
+ENTRY(biosdinfo)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+
+       movb    8(%ebp), %dl            # diskinfo(drive #)
+
+       call    _C_LABEL(prot_to_real)  # enter real mode
+
+       movb    $0x08, %ah              # ask for disk info
+       int     $0x13
+       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.
+        */
+       xorl    %bx, %bx                # %bh = 0
+       incw %bx; incw %bx              # %bl bits 0-3 = drive type, 2 = 1.2M
+       movb    $79, %ch                # max track
+       movb    $15, %cl                # max sector
+       xorl    %dx, %dx
+       incw    %dx                     # floppy drives installed
+       movb    %dl, %dh                # max head
+       # es:di = parameter table
+       # carry = 0
+
+ok:
+       data32
+       call    _C_LABEL(real_to_prot)  # back to protected mode
+
+       xorl    %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)
+
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+
diff --git a/sys/arch/i386/stand/libsa/bioskbd.S b/sys/arch/i386/stand/libsa/bioskbd.S
new file mode 100644 (file)
index 0000000..ff414bf
--- /dev/null
@@ -0,0 +1,170 @@
+/*     $OpenBSD: bioskbd.S,v 1.2 1997/03/31 03:12:11 weingart Exp $    */
+
+/*
+ * 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.
+ */
+
+/*
+  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 <machine/asm.h>
+#define        addr32  .byte 0x67
+#define        data32  .byte 0x66
+
+/* 
+ * int kbd_probe();
+ *     probe if keyboard present
+ *
+ */
+ENTRY(kbd_probe)
+       
+       movl    1, %eax         /* present (: */
+       ret
+
+/*
+# BIOS call "INT 10H Function 0Eh" to write character to console
+#      Call with       %ah = 0x0e
+#                      %al = character
+#                      %bh = page
+#                      %bl = foreground color
+*/
+ENTRY(kbd_putc)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+
+       movb    8(%ebp), %cl
+
+       call    _C_LABEL(prot_to_real)
+
+       movb    %cl, %al
+
+       movb    $0x0e, %ah
+       xorl    %ebx, %ebx
+       incl    %ebx
+       int     $0x10           # display a byte
+
+       data32
+       call    _C_LABEL(real_to_prot)
+
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+# BIOS call "INT 16H Function 00H" to read character from the keyboard
+#      Call with       %ah = 0x00
+#      Return:         %ah = keyboard scan code
+#                      %al = ASCII character
+*/
+ENTRY(kbd_getc)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+
+       call    _C_LABEL(prot_to_real)
+
+       xorl    %eax, %eax
+       int     $0x16
+
+       movb    %al, %bl        # real_to_prot uses %eax
+
+       data32
+       call    _C_LABEL(real_to_prot)
+
+       movzbl  %bl, %eax
+
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
+
+
+/*
+# BIOS call "INT 16H Function 01H" to check whether a character is pending
+#      Call with       %ah = 0x01
+#      Return: 
+#              If key waiting to be input:
+#                      %ah = keyboard scan code
+#                      %al = ASCII character
+#                      ZF  = clear
+#              else
+#                      ZF  = set
+*/
+ENTRY(kbd_ischar)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+       pushl   %esi
+       pushl   %edi
+
+       call    _C_LABEL(prot_to_real)
+
+       movb    $0x01, %ah
+       int     $0x16
+       setnz   %ah
+
+       movb    %ah, %bl        # real_to_prot uses %eax
+
+       data32
+       call    _C_LABEL(real_to_prot)
+
+       movzbl  %bl, %eax
+
+       popl    %edi
+       popl    %esi
+       popl    %ebx
+       popl    %ebp
+       ret
diff --git a/sys/arch/i386/stand/libsa/biostime.S b/sys/arch/i386/stand/libsa/biostime.S
new file mode 100644 (file)
index 0000000..fbcc8c7
--- /dev/null
@@ -0,0 +1,100 @@
+/*     $OpenBSD: biostime.S,v 1.2 1997/03/31 03:12:12 weingart Exp $   */
+
+/*
+ * 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.
+ */
+
+/*
+  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 <machine/asm.h>
+#define addr32 .byte 0x67
+#define data32 .byte 0x66
+
+/*
+# BIOS call "INT 15H Function 86H" to sleep for a set number of microseconds
+#      Call with       %ah = 0x86
+#                      %cx = time interval (high)
+#                      %dx = time interval (low)
+#      Return: 
+#              If error
+#                      CF  = set
+#              else
+#                      CF  = clear
+*/
+ENTRY(usleep)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %ebx
+
+       movw    8(%ebp), %dx
+       movw    10(%ebp), %cx
+
+       call    _C_LABEL(prot_to_real)
+
+       movb    $0x86, %ah
+       int     $0x15
+       setnc   %ah
+
+       movb    %ah, %bl        # real_to_prot uses %eax
+
+       data32
+       call    _C_LABEL(real_to_prot)
+
+       movzbl  %bl, %eax
+
+       popl    %ebx
+       popl    %ebp
+       ret
+
+/*
+#
+#
+*/
+ENTRY(getsecs)
+       ret
+
diff --git a/sys/arch/i386/stand/libsa/dev_i386.c b/sys/arch/i386/stand/libsa/dev_i386.c
new file mode 100644 (file)
index 0000000..c573295
--- /dev/null
@@ -0,0 +1,82 @@
+/*     $OpenBSD: dev_i386.c,v 1.2 1997/03/31 03:12:12 weingart Exp $   */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <libsa.h>
+#include "biosdev.h"
+
+/* pass dev_t to the open routines */
+int
+devopen(struct open_file *f, const char *fname, char **file)
+{
+       struct devsw *dp = devsw;
+       register int i, rc = 0;
+
+       *file = (char *)fname;
+
+       for (i = 0; i < ndevs ; dp++, i++)
+               if ((rc = (*dp->dv_open)(f, file))== 0) {
+                       f->f_dev = dp;
+                       return 0;
+               }
+
+       if ((f->f_flags & F_NODEV) == 0)
+               f->f_dev = dp;
+
+       return rc;
+}
+
+void
+putchar(c)
+       int     c;
+{
+       putc(c);
+       if (c == '\n')
+               putc('\r');
+}
+
+int
+getchar()
+{
+       int c = getc();
+
+       if (c == '\b' || c == '\177')
+               return(c);
+
+       if (c == '\r')
+               c = '\n';
+
+       putchar(c);
+
+       return(c);
+}
diff --git a/sys/arch/i386/stand/libsa/exec_i386.c b/sys/arch/i386/stand/libsa/exec_i386.c
new file mode 100644 (file)
index 0000000..3a43749
--- /dev/null
@@ -0,0 +1,51 @@
+
+/* $OpenBSD: exec_i386.c,v 1.1 1997/03/31 03:12:13 weingart Exp $ */
+
+#include <sys/param.h>
+#include <sys/exec.h>
+#include <sys/reboot.h>
+#include <libsa.h>
+
+
+void
+machdep_start(startaddr, howto, loadaddr, ssym, esym)
+       char *startaddr, *loadaddr, *ssym, *esym;
+       int howto;
+{
+       static int argv[9];
+       static int (*x_entry)() = 0;
+
+       x_entry = (void *)startaddr;
+       (int)startaddr &= 0xffffff;
+
+       /*
+        *  We now pass the various bootstrap parameters to the loaded
+        *  image via the argument list
+        *
+        *  arg0 = 8 (magic)
+        *  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
+        *  arg7 = conventional memory size (640)
+        *  arg8 = extended memory size (8196)
+        */
+       argv[0] = 8;
+       argv[1] = howto;
+       argv[2] = 0;            /* Boot device */
+       argv[3] = 0;            /* Cyl offset */
+       argv[4] = (int)esym;
+       argv[5] = (int)startaddr;
+       argv[6] = (int)&x_entry;
+       argv[7] = 0;
+       argv[8] = 0;
+
+       /****************************************************************/
+       /* copy that first page and overwrite any BIOS variables        */
+       /****************************************************************/
+       printf("entry point at 0x%x\n", (int)startaddr);
+       startprog(startaddr, argv);
+}
+
diff --git a/sys/arch/i386/stand/libsa/gateA20.c b/sys/arch/i386/stand/libsa/gateA20.c
new file mode 100644 (file)
index 0000000..7c3ac5a
--- /dev/null
@@ -0,0 +1,76 @@
+/*     $OpenBSD: gateA20.c,v 1.2 1997/03/31 03:12:13 weingart Exp $    */
+
+/*
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <machine/pio.h>
+#include <stand.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
+ */
+void
+gateA20(on)
+       int on;
+{
+#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);
+
+       if (on)
+               outb(K_RDWR, KB_A20);
+       else
+               outb(K_RDWR, 0xcd);
+       while (inb(K_STATUS) & K_IBUF_FUL);
+
+       while (inb(K_STATUS) & K_OBUF_FUL)
+               (void)inb(K_RDWR);
+#endif IBM_L40
+}
diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h
new file mode 100644 (file)
index 0000000..b5eb8dd
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: libsa.h,v 1.2 1997/03/31 03:12:14 weingart Exp $      */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <stand.h>
+
+void startprog __P((char *addr, int argv[]));
+void gateA20 __P((int on));
+int memsize __P((int which));
+int memprobe __P((void));
+
+extern dev_t   bootdev, maj, unit, part;
+extern u_long  cyloffset;
+extern u_long  ourseg, esym;
+extern int     boothowto;
diff --git a/sys/arch/i386/stand/libsa/memprobe.c b/sys/arch/i386/stand/libsa/memprobe.c
new file mode 100644 (file)
index 0000000..1a67eaf
--- /dev/null
@@ -0,0 +1,50 @@
+/* $OpenBSD: memprobe.c,v 1.1 1997/03/31 03:12:14 weingart Exp $ */
+
+#include <sys/param.h>
+#include <libsa.h>
+
+
+/* addrprobe(kloc): Probe memory at address kloc * 1024.
+ *
+ * This is a hack, but it seems to work ok.  Maybe this is
+ * the *real* way that you are supposed to do probing???
+ */
+static int addrprobe(int kloc){
+       volatile int *loc, i;
+       static int pat[] = {
+               0x00000000, 0xFFFFFFFF,
+               0x01010101, 0x10101010,
+               0x55555555, 0xCCCCCCCC
+       };
+
+       /* Get location */
+       loc = (int *)(kloc * 1024);
+
+       /* Probe address */
+       for(i = 0; i < sizeof(pat)/sizeof(pat[0]); i++){
+               *loc = pat[i];
+               if(*loc != pat[i]) return(1);
+       }
+
+       return(0);
+}
+
+
+/* memprobe():  return probed memory size in KB for extended memory
+ *
+ * There is no need to do this in assembly language.  This are
+ * much easier to debug in C anyways.
+ */
+int memprobe(void){
+       int ram;
+
+       for(ram = 1024; ram < 512*1024; ram += 4){
+
+               printf("Probing memory: %d KB\r", ram-1024);
+               if(addrprobe(ram)) break;
+       }
+
+       printf("\n");
+       return(ram-1024);
+}
+
diff --git a/sys/arch/i386/stand/libsa/memsize.S b/sys/arch/i386/stand/libsa/memsize.S
new file mode 100644 (file)
index 0000000..2887d10
--- /dev/null
@@ -0,0 +1,98 @@
+/*     $OpenBSD: memsize.S,v 1.2 1997/03/31 03:12:15 weingart Exp $    */
+
+/*
+ * 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.
+ */
+
+/*
+  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 <machine/asm.h>
+#define        addr32  .byte 0x67
+#define        data32  .byte 0x66
+
+/*
+#
+# 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)
+       pushl   %ebp
+       movl    %esp, %ebp
+       pushl   %esi
+       pushl   %edi
+
+       movl    8(%ebp), %edx
+
+       call    _C_LABEL(prot_to_real)  # enter real mode
+
+       testb   %dl, %dl
+       jnz     1f
+       
+       int     $0x12
+       jmp     2f
+
+1:
+       movb    $0x88, %ah
+       int     $0x15
+
+2:
+       movl    %eax, %edx
+
+       data32
+       call    _C_LABEL(real_to_prot)
+
+       movl    %edx, %eax
+       popl    %edi
+       popl    %esi
+       popl    %ebp
+       ret
diff --git a/sys/arch/i386/stand/libsa/probe_keyboard.c b/sys/arch/i386/stand/libsa/probe_keyboard.c
new file mode 100644 (file)
index 0000000..e680c24
--- /dev/null
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 1992-1995 Søren Schmidt
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This is a modified version of the keyboard reset code used in syscons.
+ * If the keyboard reset fails, we assume that the keyboard has been
+ * unplugged and we use a serial port (COM1) as the console instead.
+ * Returns 1 on failure (no keyboard), 0 on success (keyboard attached).
+ *
+ * This grody hack brought to you by Bill Paul (wpaul@ctr.columbia.edu)
+ *
+ *     $Id: probe_keyboard.c,v 1.2 1997/03/31 03:12:15 weingart Exp $
+ */
+
+#ifdef PROBE_KEYBOARD
+
+#include <machine/console.h>
+#include <machine/cpufunc.h>
+#include "boot.h"
+
+int
+probe_keyboard(void)
+{
+       int i, retries = 5;
+       unsigned char val;
+
+       /* flush any noise in the buffer */
+       while (inb(KB_STAT) & KB_BUF_FULL) {
+               delay1ms();
+               (void) inb(KB_DATA);
+       }
+
+       /* Try to reset keyboard hardware */
+  again:
+       while (--retries) {
+#ifdef DEBUG
+               printf("%d ", retries);
+#endif
+               while ((inb(KB_STAT) & KB_READY) == KB_READY) delay1ms();
+               outb(KB_DATA, KB_RESET);
+               for (i=0; i<1000; i++) {
+                       delay1ms();
+                       val = inb(KB_DATA);
+                       if (val == KB_ACK || val == KB_ECHO)
+                               goto gotack;
+                       if (val == KB_RESEND)
+                               break;
+               }
+       }
+gotres:
+#ifdef DEBUG
+       printf("gotres\n");
+#endif
+       if (!retries) {
+#ifdef DEBUG
+               printf("gave up\n");
+#endif
+               return(1);
+       }
+gotack:
+       delay1ms();
+       while ((inb(KB_STAT) & KB_BUF_FULL) == 0) delay1ms();
+       delay1ms();
+#ifdef DEBUG
+       printf("ACK ");
+#endif
+       val = inb(KB_DATA);
+       if (val == KB_ACK)
+               goto gotack;
+       if (val == KB_RESEND)
+               goto again;
+       if (val != KB_RESET_DONE) {
+#ifdef DEBUG
+               printf("stray val %d\n", val);
+#endif
+               return(0);
+       }
+#ifdef DEBUG
+       printf("ok\n");
+#endif
+       return(0);
+}
+
+#endif /* PROBE_KEYBOARD */
diff --git a/sys/arch/i386/stand/libsa/real_prot.S b/sys/arch/i386/stand/libsa/real_prot.S
new file mode 100644 (file)
index 0000000..765c318
--- /dev/null
@@ -0,0 +1,172 @@
+/*     $OpenBSD: real_prot.S,v 1.2 1997/03/31 03:12:16 weingart Exp $  */
+
+/*
+ * 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: real_prot.S,v 1.2 1997/03/31 03:12:16 weingart 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.
+*/
+       .file "real_prot.S"
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+
+#define addr32  .byte 0x67
+#define data32  .byte 0x66
+
+       .data
+
+       .globl  _codeseg
+       .globl  _Gdtr
+#ifndef NO_IDTR
+       .globl  _Idtr_prot
+       .globl  _Idtr_real
+#endif
+
+       .text
+
+/*
+ *
+ * real_to_prot()
+ *     transfer from real mode to protected mode.
+ */
+
+.align 4,0x90
+ENTRY(real_to_prot)
+       /* guarantee that interrupt is disabled when in prot mode */
+       cli
+
+       /* load the gdtr */
+       addr32
+       data32
+       lgdt    _C_LABEL(Gdtr)
+
+       /* set the PE bit of CR0 */
+       movl    %cr0, %eax
+       data32
+       orl     $CR0_PE, %eax
+       movl    %eax, %cr0 
+
+       /*
+        * make intrasegment jump to flush the processor pipeline and
+        * reload CS register
+        */
+       data32
+       ljmp    $0x08, $1f
+
+1:     /*
+        * we are in USE32 mode now
+        * set up the protected mode segment registers : DS, SS, ES
+        */
+       movl    $0x10, %eax
+       movl    %ax, %ds
+       movl    %ax, %ss
+       movl    %ax, %es
+
+#ifndef NO_IDTR
+       /* load idtr so we can debug */
+       lidt    _Idtr_prot
+#endif
+       ret
+
+/*
+ *
+ * prot_to_real()
+ *     transfer from protected mode to real mode
+ * 
+ */
+
+.align 4,0x90
+ENTRY(prot_to_real)
+
+       /*
+        * This is self-modifying code, but we need a writable
+        * code segment, and an intersegment return does not give us that.
+        */
+       movw    _codeseg, %ax
+       pushw   %ax
+       movw    $2f, %ax
+       pushw   %ax
+
+       /* Change to use16 mode. */
+       ljmp    $0x18, $1f
+
+1:     /* clear the PE bit of CR0 */
+       movl    %cr0, %eax
+       data32
+       andl    $~CR0_PE, %eax
+       movl    %eax, %cr0
+
+       /*
+        * make intersegment jmp to flush the processor pipeline
+        * using the fake stack frame set up earlier
+        * and reload CS register
+        */
+#if 0
+       hlt
+#endif
+       lret
+2:     /*
+        * we are in real mode now
+        * set up the real mode segment registers : DS, SS, ES
+        */
+       movl    %cs, %ax
+       movl    %ax, %ds
+       movl    %ax, %ss
+       movl    %ax, %es
+#ifndef        NO_IDTR
+       /* load idtr so we can debug */
+       addr32
+       data32
+       lidt    _Idtr_real
+#endif
+       sti
+       data32
+       ret
+
diff --git a/sys/arch/i386/stand/libsa/srt0.S b/sys/arch/i386/stand/libsa/srt0.S
new file mode 100644 (file)
index 0000000..e0c94c9
--- /dev/null
@@ -0,0 +1,139 @@
+/*     $OpenBSD: srt0.S,v 1.2 1997/03/31 03:12:16 weingart Exp $       */
+/*     $NetBSD: srt0.c,v 1.3 1994/10/27 04:21:59 cgd Exp $     */
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)srt0.c      5.3 (Berkeley) 4/28/91
+ */
+
+/*
+ * Startup code for standalone system
+ * Non-relocating version -- for programs which are loaded by boot
+ * Relocating version for boot
+ * Small relocating version for "micro" boot
+ */
+
+#include <machine/psl.h>
+
+       .globl  _end
+       .globl  _edata
+       .globl  _boot
+       .globl  __rtt
+       .globl  _bootdev
+       .globl  _boothowto
+       .globl  _cyloffset
+
+       .data
+       .globl  _Gdtr
+_Gdtr:
+       .long   0
+       .word   0
+_bootdev:      .long   0
+_boothowto:    .long   0
+_cyloffset:    .long   0
+_esym:         .long   0
+
+       .text
+
+#define        NOP     inb $0x84,%al ; inb $0x84,%al
+
+       .globl  start_boot
+
+start_boot:
+       pushl   %ebp
+       movl    %esp, %ebp
+
+       /* First, reset the PSL. */
+       pushl   $PSL_MBO
+       popfl
+
+       movl    8(%ebp), %eax
+       movl    %eax, _boothowto
+       movl    12(%ebp),%eax
+       movl    %eax, _bootdev
+       movl    16(%ebp),%eax
+       movl    %eax, _cyloffset
+       movl    20(%ebp),%eax
+       movl    %eax, _esym
+
+       /* save old stack state */
+       movl    %esp,savearea
+       movl    %ebp,savearea+4
+
+#if 0
+       /* setup stack pointer */
+       movl    _end, %eax
+       addl    $10000, %eax
+       movl    %eax, %esp
+
+       /* clear memory as needed */
+       movl    %esp,%esi
+       movl    $_edata,%edx
+
+       movl    %esp,%eax
+       subl    %edx,%eax
+       pushl   %edx
+       pushl   0
+       pushl   %esp
+       call    _memset
+
+       #call   _kbdreset       /* resets keyboard and gatea20 brain damage */
+       movl    %esi,%esp
+#endif
+       call    _boot
+       jmp     __rtt
+
+       .data
+
+savearea:      .long   0,0     # sp & bp to return to
+
+       .text
+
+__rtt:
+       movl    $-7,%eax
+#ifdef REL
+#ifndef SMALL
+       call    _reset_cpu
+#endif
+       movw    $0x1234,%ax
+       movw    %ax,0x472       # warm boot
+       movl    $0,%esp         # segment violation
+       ret
+#else
+       movl    savearea,%esp
+       movl    savearea+4,%ebp
+       ret
+#endif
diff --git a/sys/arch/i386/stand/libsa/startprog.S b/sys/arch/i386/stand/libsa/startprog.S
new file mode 100644 (file)
index 0000000..e1f4e26
--- /dev/null
@@ -0,0 +1,45 @@
+/*     $OpenBSD: startprog.S,v 1.1 1997/03/31 03:12:17 weingart Exp $  */
+
+#include <machine/asm.h>
+
+
+/*
+ * startprog(phyaddr, argv)
+ *     start the program on protected mode where phyaddr is the entry point
+ */
+ENTRY(startprog)
+       pushl   %ebp
+       movl    %esp, %ebp
+
+       # get things we need into registers
+       movl    8(%ebp), %ecx           # entry offset 
+       movl    12(%ebp), %eax          # &argv
+
+       # make a new stack at 0:0x90000 (big segs)
+       movl    $0x10, %ebx
+       movw    %bx, %ss
+       movl    $0x90000, %ebx
+       movl    %ebx, %esp
+
+       # push some number of args onto the stack
+       pushl   28(%eax)                # argv[7] = cnvmem
+       pushl   32(%eax)                # argv[8] = extmem
+       pushl   16(%eax)                # argv[4] = esym
+       pushl   12(%eax)                # argv[3] = cyl offset
+       pushl   8(%eax)                 # argv[2] = bootdev
+       pushl   4(%eax)                 # argv[1] = howto
+       pushl   $0                      # dummy 'return' address
+
+       # push on our entry address
+       movl    $0x8, %ebx              # segment
+       pushw   %bx
+       pushl   %ecx
+
+       # convert over the other data segs
+       movl    $0x10, %ebx
+       movl    %bx, %ds
+       movl    %bx, %es
+
+       # convert the PC (and code seg)
+       lret
+
diff --git a/sys/arch/i386/stand/libsa/unixsys.S b/sys/arch/i386/stand/libsa/unixsys.S
new file mode 100644 (file)
index 0000000..346d625
--- /dev/null
@@ -0,0 +1,39 @@
+
+
+#include <machine/asm.h>
+#include <sys/syscall.h>
+
+
+#define RSYSCALL(x) \
+       ENTRY(u/**/x); \
+               movl     $(SYS_/**/x), %eax; \
+               jmp      1f
+
+       .globl  _errno
+
+RSYSCALL(open)
+RSYSCALL(read)
+RSYSCALL(write)
+RSYSCALL(ioctl)
+RSYSCALL(close)
+RSYSCALL(exit)
+
+1:
+       int     $0x80
+2:     jnc     3f
+       movl    %eax, _errno
+       movl    $-1, %eax
+       movl    $-1, %edx
+3:     ret
+
+ENTRY(__syscall)
+       movl    $(SYS___syscall), %eax
+       jmp     1b
+
+ENTRY(syscall)
+       popl    %ecx    /* rta */
+       popl    %eax    /* syscall number */
+       pushl   %ecx
+       int     $0x80
+       pushl   %ecx
+       jmp     2b
diff --git a/sys/arch/i386/stand/libz/Makefile b/sys/arch/i386/stand/libz/Makefile
new file mode 100644 (file)
index 0000000..067a8a7
--- /dev/null
@@ -0,0 +1,17 @@
+#      $OpenBSD: Makefile,v 1.1 1997/03/31 03:12:18 weingart Exp $
+
+.include "../Makefile.inc"
+
+CFLAGS+=-Wall
+
+S      = ${.CURDIR}/../../../..
+ZDST=${.OBJDIR}
+.include "${S}/lib/libz/Makefile.inc"
+
+all: ${ZLIB}
+
+.include <bsd.obj.mk>
+.include <bsd.dep.mk>
+.include <bsd.subdir.mk>
+.include <bsd.sys.mk>
+
diff --git a/sys/arch/i386/stand/mbr/Makefile b/sys/arch/i386/stand/mbr/Makefile
new file mode 100644 (file)
index 0000000..a7a97ef
--- /dev/null
@@ -0,0 +1,22 @@
+#      $OpenBSD: Makefile,v 1.1 1997/03/31 03:12:19 weingart Exp $
+#
+
+PROG=  mbr
+SRCS=  mbr.S
+AFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../.. #-Wa,-a
+LDFLAGS=-s -Wl,-T0,-N,-x -nostdlib
+MAN+=  mbr.8
+STRIP=
+
+# Uncomment this to make mbr talk to a serial port.
+#CPPFLAGS+=-DSERIAL=0
+
+all:
+       # XXX access(2) says X_OK to root even w/o the x bit set !!!
+       @if [ -x ${.OBJDIR}/${PROG} ]; then \
+               dd if=${.OBJDIR}/${PROG} of=${.OBJDIR}/.tmp ibs=32 skip=1; \
+               mv -f ${.OBJDIR}/.tmp ${.OBJDIR}/${PROG}; \
+               ls -l ${.OBJDIR}/${PROG}; \
+       fi
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/i386/stand/mbr/mbr.8 b/sys/arch/i386/stand/mbr/mbr.8
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sys/arch/i386/stand/mbr/mbr.S b/sys/arch/i386/stand/mbr/mbr.S
new file mode 100644 (file)
index 0000000..2b48f58
--- /dev/null
@@ -0,0 +1,309 @@
+/*     $OpenBSD: mbr.S,v 1.1 1997/03/31 03:12:19 weingart Exp $        */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ */
+
+/* Copyright (c) 1996 VaX#n8 (vax@linkdead.paranoia.com)
+ * last edited 9 July 1996
+ * many thanks to Erich Boleyn (erich@uruk.org) for putting up with
+ * all my questions, and for his work on GRUB
+ * You may use this code or fragments thereof in a manner consistent
+ * with the other copyrights as long as you retain my pseudonym and
+ * this copyright notice in the file.
+ */
+
+/*     $OpenBSD: mbr.S,v 1.1 1997/03/31 03:12:19 weingart Exp $        */
+
+/*
+ * Copyright (c) 1996 Michael Shalayeff
+ */
+
+/* Copyright (c) 1996 VaX#n8 (vax@linkdead.paranoia.com)
+ * last edited 9 July 1996
+ * many thanks to Erich Boleyn (erich@uruk.org) for putting up with
+ * all my questions, and for his work on GRUB
+ * You may use this code or fragments thereof in a manner consistent
+ * with the other copyrights as long as you retain my pseudonym and
+ * this copyright notice in the file.
+ */
+
+       .file   "start.S"
+
+#include <machine/asm.h>
+#include <machine/specialreg.h>
+
+#define data32 .byte 0x66
+#define addr32 .byte 0x67
+
+#define BOOTBIOS       0x7c0   /* segment where we are loaded */
+#define BOOTRELOC      0x7a0   /* segment where to relocate */
+#define SIGNATURE      0xaa55  /* MBR signature */
+#define NUMPART                4       /* number of partitions in partition table */
+#define PARTSZ         16      /* each partition table entry is 16 bytes */
+#define BSDPART                0xA6    /* OpenBSD partition */
+#define OLDBSDPART     0xA5    /* {386,Net,Free}BSD partition */
+#define BOOTABLE       0x80    /* bootable partition */
+
+#ifdef DEBUG
+#define CHAR_S         'S'     /* started */
+#define CHAR_L         'L'     /* looking up bootable partition */
+#define CHAR_P         'P'     /* partition table corrupted */
+#define CHAR_O         'O'     /* force OpenBSD load */
+#define CHAR_B         'B'     /* loading boot */
+#define CHAR_G         'G'     /* jumping to boot */
+
+#define DBGMSG(msg)            \
+       movb    $msg, %al;      \
+       data32;                 \
+       call    chr
+#else /* !DEBUG */
+#define DBGMSG(msg)
+#endif /* !DEBUG */
+
+       .text
+
+       .globl  start
+start:
+       movl    %cs, %ax
+       # set up stack(%ss:%esp)
+       cli                     /* disable interrupts w/o stack */
+       movl    %ax, %ss
+       data32
+       movl    $0xfffc, %esp
+       sti                     /* we have stack, do ints */
+       /* setup %ds */
+       movl    %ax, %ds
+
+       /* relocate the code to leave the space for boot stage */
+       data32
+       movl    $BOOTRELOC, %eax
+       movl    %ax, %es
+       xorl    %si, %si
+       xorl    %di, %di
+       xorl    %cx, %cx
+       incb    %ch     /* movl $0x100, %ecx */
+       cld
+       rep
+       movsw
+
+       # jump to the relocated code
+       data32
+       ljmp $BOOTRELOC, $1f
+1:
+       DBGMSG(CHAR_S)
+
+       /* setup %es, %ds */
+       pushl   %ds
+       popl    %es     /* next boot is at the same place as we were loaded */
+       pushl   %cs
+       popl    %ds     /* and %ds is at the %cs */
+
+#ifdef SERIAL
+       # Initialize the serial port to 9600 baud, 8N1.
+       xorl    %ax, %ax
+               movb    $0xe3, %ax
+       data32
+       movl    $SERIAL, %dx
+       int     $0x14
+#endif
+
+       /* bootstrap passes us drive number in %dl */
+       testb   $0x80, %dl
+       jnz     1f
+
+       /* mbr on floppy ??? */
+       data32
+       movl    $fdmbr, %esi
+       data32
+       call    message
+
+1:     xorl    %bx, %bx
+       # cmpw  $SIGNATURE, (%bx)
+       .byte   0x81, 0xbf
+       .word   signature
+       .word   SIGNATURE
+       je      1f
+       DBGMSG(CHAR_P)
+
+       /* find the first active partition */
+1:     DBGMSG(CHAR_L)
+       data32
+       movl    $pt, %esi
+       data32
+       movl    $NUMPART, %cx
+1:
+       # movb  (%si), %al
+       .byte   0x8a, 0x44, 0x00
+       cmpb    $BOOTABLE, %al
+       je      2f
+       data32
+       addl    $PARTSZ, %esi
+       loop    1b
+       jmp     1f      /* no bootable -- find $BSDPART */
+
+2:     # test if bootable is ours
+       # movb  4(%si), %al     # partition type
+       .byte   0x8a, 0x44, 0x04
+       cmpb    $BSDPART, %al
+       je      found
+
+       /* else: ask! */
+       data32
+       movl    $prompt, %esi
+       data32
+       call    message
+
+       # BIOS call: read char from kbd
+       #       return: %ah == scancode, %al == ascii
+       xorl    %ax, %ax
+       int     $0x16
+
+       /* load active, if not */
+       cmpb    'n', %al
+       je      found
+       cmpb    'N', %al
+       je      found
+
+1:
+       /* else: find OpenBSD partition */
+       DBGMSG(CHAR_O)
+       data32
+       movl    $pt, %esi
+       data32
+       movl    $NUMPART, %ecx
+1:
+       # movb  (%si), %al
+       .byte   0x8a, 0x44, 0x00
+       cmpb    $BSDPART, %al
+       je      found
+       data32
+       addl    $PARTSZ, %esi
+       loop    1b
+       data32
+       movl    $enoboot, %esi
+err_stop:
+       data32
+       call    message
+       cli
+       hlt
+
+found:
+       DBGMSG(CHAR_B)
+       # movb  1(%si), %dh     # head
+       .byte   0x8a, 0x74, 0x01
+       # movw  2(%si), %cx     # sect, cyl
+       .byte   0x8b, 0x4c, 0x02
+       # movb  4(%si), %al     # partition type
+       .byte   0x8a, 0x44, 0x04
+
+/*
+# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+#       Call with       %ah = 0x2
+#                       %al = number of sectors
+#                       %ch = cylinder
+#                       %cl = sector
+#                       %dh = head
+#                       %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+#                       %es:%bx = segment:offset of buffer
+#       Return:
+#                       %al = 0x0 on success; err code on failure
+*/
+       data32
+       movl    $0x200 | 1, %eax        /* number of blocks */
+       xorl    %bx, %bx                /* put it at %es:0 */
+       int     $0x13
+       data32
+       movl    $eread, %si
+       jc      err_stop
+
+       DBGMSG(CHAR_G)
+
+       # jump to the new code (%ds:%si is at he right point)
+       data32
+       ljmp    $0, $BOOTBIOS << 4
+       /* not reached */
+
+#
+#      message: write the error message in %ds:%si to console
+#
+chr:
+/*
+#ifndef SERIAL
+# BIOS call "INT 10H Function 0Eh" to write character to console
+#      Call with       %ah = 0x0e
+#                      %al = character
+#                      %bh = page
+#                      %bl = foreground color
+#else
+# BIOS call "INT 14H Function 01h" to write character to console
+#      Call with       %ah = 0x01
+#                      %al = character
+#                      %dx = port number
+#endif
+*/
+       pushl   %eax
+
+#ifndef SERIAL
+       pushl   %ebx
+       movb    $0x0e, %ah
+       xorl    %bx, %bx
+       incl    %bx             /* movw $0x01, %bx */
+       int     $0x10
+       popl    %ebx
+#else
+       pushl   %edx
+       movb    $0x01, %ah
+       data32
+       movl    SERIAL, %dx
+       int     $0x14
+       popl    %edx
+#endif
+       popl    %ax
+       data32
+       ret
+
+/*
+ * Display string
+ */
+message:
+       pushl   %ax
+       cld
+1:
+       lodsb                   # load a byte into %al
+       testb   %al, %al
+       jz      1f
+       data32
+       call    chr
+       jmp     1b
+1:
+       popl    %ax
+       ret
+
+/* error messages */
+
+fdmbr: .asciz          "MBR on fd?\r\n"
+eread: .asciz          "Read error\r\n"
+enoboot: .asciz                "No partition to boot\r\n"
+prompt:        .asciz          "OpenBSD? "
+
+endofcode:
+       nop
+
+/* throw in a partition table */
+/* flag, head, sec, cyl, type, ehead, esect, ecyl, start, len */
+       . = 0x1be       # starting address of partition table
+pt:
+       .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 */
+       . = 0x1fe
+signature:
+       .short  SIGNATURE
+       . = 0x200
diff --git a/sys/stand/boot/boot.c b/sys/stand/boot/boot.c
new file mode 100644 (file)
index 0000000..5770f60
--- /dev/null
@@ -0,0 +1,130 @@
+/*     $OpenBSD: boot.c,v 1.2 1997/03/31 03:12:03 weingart Exp $       */
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/stat.h>
+#include <a.out.h>
+#include <sys/disklabel.h>
+#include <libsa.h>
+#include "cmd.h"
+
+/*
+ * Boot program, loaded by boot block from remaing 7.5K of boot area.
+ * Sifts through disklabel and attempts to load an program image of
+ * a standalone program off the disk. If keyboard is hit during load,
+ * or if an error is encounter, try alternate files.
+ */
+
+char *kernels[] = {
+       "bsd", "bsd.gz",
+       "obsd", "obsd.gz",
+       "bsd.old", "bsd.old.gz",
+       NULL
+};
+
+int    retry = 0;
+extern char version[];
+extern dev_t bootdev;
+extern int boothowto;
+int    cnvmem, extmem, probemem;
+
+void   boot ();
+struct cmd_state cmd;
+
+/*
+ * Boot program... loads /boot out of filesystem indicated by arguements.
+ * We assume an autoboot unless we detect a misconfiguration.
+ */
+void
+boot()
+{
+       register char *bootfile = kernels[0];
+       register int i;
+
+
+       /* Get memory size */
+       cnvmem = memsize(0);
+       extmem = memsize(1);
+       gateA20(1);
+       probemem = memprobe();
+
+
+       /* XXX init cmd here to cut on .data !!! */
+       strncpy(cmd.bootdev,
+#ifdef _TEST
+               "/dev/rfd0a",
+#else
+               "fd(0,a)",
+#endif
+               sizeof(cmd.bootdev));
+       cmd.image[0] = '\0';
+       cmd.cwd[0] = '/';
+       cmd.cwd[1] = '\0';
+       cmd.addr = (void *)0x100000;
+       cmd.timeout = 50000;
+
+       printf("\n>> OpenBSD BOOT: %d/%d (%d) k [%s]\n",
+               cnvmem, extmem, probemem, version);
+
+       for (i = 0;;) {
+
+               strncpy(cmd.image, bootfile, sizeof(cmd.image));
+
+               do {
+                       printf("boot> ");
+               } while(!getcmd(&cmd) && !execmd(&cmd));
+
+               sprintf(cmd.path, "%s%s%s", cmd.bootdev, cmd.cwd, bootfile);
+               printf("\nbooting %s: ", cmd.path);
+               exec (cmd.path, cmd.addr, boothowto);
+
+               if(kernels[++i] == NULL)
+                       bootfile = kernels[i=0];
+               else
+                       bootfile = kernels[i];
+
+               cmd.timeout += 20;
+
+               printf(" failed(%d)\nwill try %s\n", errno, bootfile);
+       }
+}
+
+#ifdef _TEST
+int
+main()
+{
+       boot();
+       return 0;
+}
+#endif
diff --git a/sys/stand/boot/cmd.c b/sys/stand/boot/cmd.c
new file mode 100644 (file)
index 0000000..f6d2aa3
--- /dev/null
@@ -0,0 +1,325 @@
+/*     $OpenBSD: cmd.c,v 1.1 1997/03/31 03:12:03 weingart Exp $        */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <string.h>
+#include <libsa.h>
+#include "cmd.h"
+
+static struct cmd_table {
+       char *cmd_name;
+       int cmd_id;
+} cmd_table[] = {
+       {"addr",   CMD_ADDR},
+       {"boot",   CMD_BOOT},
+       {"cd",     CMD_CD},
+       {"device", CMD_DEVICE},
+       {"help",   CMD_HELP},
+       {"image",  CMD_IMAGE},
+       {"ls",     CMD_LS},
+       {"nope",   CMD_NOPE},
+       {"reboot", CMD_REBOOT},
+       {"set",    CMD_SET},
+       {NULL, 0},
+};
+
+extern char version[];
+void ls __P((char *, register struct stat *));
+char skipblnk __P((void));
+
+char cmd_buf[133];
+
+int
+getcmd(cmd)
+       register struct cmd_state *cmd;
+{
+       register struct cmd_table *ct = cmd_table;
+       register char *p = cmd_buf; /* input */
+       register char ch;
+       int len;
+
+       cmd->rc = 0;
+       cmd->argc = 1;
+
+       for (len = cmd->timeout; len-- && !ischar(); );
+
+       if (len < 0) {
+               cmd->cmd = CMD_BOOT;
+               cmd->argv[0] = cmd_table[CMD_BOOT].cmd_name;
+               cmd->argv[1] = NULL;
+               return 0;
+       }
+
+       ch = skipblnk();
+
+       for (len = 0; ch != '\n' &&
+                    ch != ' ' && ch != '\t'; len++, ch = getchar())
+               *p++ = ch;
+       *p = '\0';
+
+       if (len == 0 && ch == '\n') {
+               cmd->cmd = CMD_NOPE;
+               return 0;
+       }
+
+       while (ct->cmd_name != NULL &&
+              strncmp(cmd_buf, ct->cmd_name, len))
+               ct++;
+
+       if (ct->cmd_name == NULL) {
+               cmd->cmd = CMD_ERROR;
+               cmd->argv[0] = ct->cmd_name;
+               return 0;
+       }
+
+       cmd->cmd = ct->cmd_id;
+       cmd->argv[0] = ct->cmd_name;
+       if (ct->cmd_name != NULL) {
+               while (ch != '\n') {
+
+                       ch = skipblnk();
+
+                       if (ch != '\n') {
+                               cmd->argv[cmd->argc] = p;
+                               *p++ = ch;
+                               for (len = 0; (ch = getchar()) != '\n' &&
+                                            ch != ' ' && ch != '\t'; len++)
+                                       *p++ = ch;
+                               *p++ = '\0';
+                               if (len != 0)
+                                       cmd->argc++;
+                       }
+               }
+               cmd->argv[cmd->argc] = NULL;
+       }
+
+       return cmd->rc;
+}
+
+char
+skipblnk()
+{
+       register char ch;
+
+       /* skip blanks */
+       while ((ch = getchar()) != '\n' &&
+              (ch == ' ' || ch == '\t'));
+
+       return ch;
+}
+
+int
+execmd(cmd)
+       register struct cmd_state *cmd;
+{
+       struct stat sb;
+       int fd;
+       register char *p, *q;
+       register struct cmd_table *ct;
+
+       cmd->rc = 0;
+
+       switch (cmd->cmd) {
+
+       case CMD_HELP:
+               printf("commands: ");
+               for (ct = cmd_table; ct->cmd_name != NULL; ct++)
+                       printf(" %s", ct->cmd_name);
+               putchar('\n');
+               break;
+
+       case CMD_DEVICE:
+               if (cmd->argc != 2)
+                       printf("device: device name required\n");
+               else {
+                       strncpy(cmd->bootdev, cmd->argv[1],
+                               sizeof(cmd->bootdev));
+               }
+               break;
+
+       case CMD_IMAGE:
+               if (cmd->argc != 2)
+                       printf("image: pathname required\n");
+               else {
+                       strncpy(cmd->image, cmd->argv[1],
+                               sizeof(cmd->image));
+               }
+               break;
+
+       case CMD_ADDR:
+               if (cmd->argc != 2)
+                       printf("addr: address required\n");
+               else {
+                       register u_long a;
+
+                       p = cmd->argv[1];
+                       if (p[0] == '0' && p[1] == 'x')
+                               p += 2;
+                       for (a = 0; *p != '\0'; p++) {
+                               a <<= 4;
+                               a |= (isdigit(*p)? *p - '0':
+                                     10 + tolower(*p) - 'a') & 0xf;
+                       }
+
+                       cmd->addr = (void *)a;
+               }
+               break;
+
+       case CMD_LS:
+               {
+                       q = cmd->argv[1] == NULL? "." : cmd->argv[1];
+                       sprintf(cmd->path, "%s%s%s",
+                               cmd->bootdev, cmd->cwd, q);
+
+                       if (stat(cmd->path, &sb) < 0) {
+                               printf("stat(%s): %d\n", cmd->path, errno);
+                               break;
+                       }
+
+                       if ((sb.st_mode & S_IFMT) != S_IFDIR)
+                               ls(q, &sb);
+                       else {
+                               if ((fd = opendir(cmd->path)) < 0) {
+                                       printf ("opendir(%s): %d\n",
+                                               cmd->path, errno);
+                                       break;
+                               }
+
+                               p = cmd->path + strlen(cmd->path);
+                               *p++ = '/';
+                               *p = '\0';
+
+                               while(readdir(fd, p) >= 0 && *p != '\0') {
+
+                                       if (stat(cmd->path, &sb) < 0) {
+                                               printf("stat(%s): %d\n",
+                                                      cmd->path, errno);
+                                               break;
+                                       }
+                                       ls(p, &sb);
+                               }
+
+                               closedir (fd);
+                       }
+               }
+               break;
+
+       case CMD_CD:
+               if (cmd->argc == 1) {
+                       cmd->cwd[0] = '/';
+                       cmd->cwd[1] = '\0';
+                       break;
+               }
+
+               if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '\0')
+                       break;
+
+               if (cmd->argv[1][0] == '.' && cmd->argv[1][1] == '.'
+                   && cmd->argv[1][2] == '\0') {
+                       /* strrchr(cmd->cwd, '/'); */
+                       for (p = cmd->cwd; *++p;);
+                       for (p--; *--p != '/';);
+                       p[1] = '\0';
+                       break;
+               }
+
+               sprintf(cmd->path, "%s%s%s",
+                       cmd->bootdev, cmd->cwd, cmd->argv[1]);
+               if (stat(cmd->path, &sb) < 0) {
+                       printf("stat(%s): %d\n", cmd->argv[1], errno);
+                       break;
+               }
+
+               if (!S_ISDIR(sb.st_mode)) {
+                       printf("boot: %s: not a dir\n", cmd->argv[1]);
+                       break;
+               }
+
+               /* change dir */
+               for (p = cmd->cwd; *p; p++);
+               for (q = cmd->argv[1]; (*p++ = *q++) != '\0';);
+               if (p[-2] != '/') {
+                       p[-1] = '/';
+                       p[0] = '\0';
+               }
+               break;
+
+       case CMD_SET:
+               printf("OpenBSD boot version %s\n"
+                      "device:\t%s\n"
+                      "cwd:\t%s\n"
+                      "image:\t%s\n"
+                      "load at:\t%p\n"
+                      "timeout:\t%d\n",
+                      version, cmd->bootdev, cmd->cwd, cmd->image,
+                      cmd->addr, cmd->timeout);
+               break;
+
+       case CMD_REBOOT:
+               exit(1);
+               break;
+
+       case CMD_BOOT:
+               return 1;
+               break;
+
+       case CMD_ERROR:
+       default:
+               printf ("%s: invalid command\n", cmd->argv[0]);
+       case CMD_NOPE:
+               break;
+       }
+
+       return cmd->rc;
+}
+
+#define lsrwx(mode,s) \
+       putchar ((mode) & S_IROTH? 'r' : '-'); \
+       putchar ((mode) & S_IWOTH? 'w' : '-'); \
+       putchar ((mode) & S_IXOTH? *(s): (s)[1]);
+
+void
+ls(name, sb)
+       char *name;
+       register struct stat *sb;
+{
+       putchar("-fc-d-b---l-s-w-"[(sb->st_mode & S_IFMT) >> 12]);
+       lsrwx(sb->st_mode >> 6, (sb->st_mode & S_ISUID? "sS" : "x-"));
+       lsrwx(sb->st_mode >> 3, (sb->st_mode & S_ISUID? "sS" : "x-"));
+       lsrwx(sb->st_mode     , (sb->st_mode & S_ISTXT? "tT" : "x-"));
+
+       printf (" %s\tuid=%u\tgid=%u\t%lu\n", name, sb->st_uid, sb->st_gid,
+               (u_long)sb->st_size);
+}
+
diff --git a/sys/stand/boot/cmd.h b/sys/stand/boot/cmd.h
new file mode 100644 (file)
index 0000000..35f3d58
--- /dev/null
@@ -0,0 +1,53 @@
+/*     $OpenBSD: cmd.h,v 1.1 1997/03/31 03:12:03 weingart Exp $        */
+
+/*
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+struct cmd_state {
+       char bootdev[16]; /* device */
+       char image[32]; /* image */
+       char cwd[MAXPATHLEN - 32 - 32];
+       void *addr; /* load here */
+       int timeout;
+       char path[MAXPATHLEN]; /* buffer for pathname compose */
+
+       enum { CMD_ADDR, CMD_BOOT, CMD_CD, CMD_DEVICE, CMD_HELP,
+              CMD_IMAGE, CMD_LS, CMD_NOPE, CMD_REBOOT, CMD_SET,
+              CMD_ERROR /* last !!! */ };
+       int cmd;
+       int argc;
+       char *argv[8];  /* XXX i hope this is enough */
+       int rc;
+};
+
+int getcmd __P((register struct cmd_state *));
+int execmd __P((register struct cmd_state *));