From df1f5d3aedcb94a9e017ed4f3dd038e588f8d6e2 Mon Sep 17 00:00:00 2001 From: weingart Date: Mon, 31 Mar 1997 03:11:58 +0000 Subject: [PATCH] Initial /boot stuff (from Mickey) --- sys/arch/i386/stand/Makefile | 5 + sys/arch/i386/stand/Makefile.inc | 14 + sys/arch/i386/stand/README | 62 +++ sys/arch/i386/stand/biosboot/Makefile | 21 + sys/arch/i386/stand/biosboot/biosboot.8 | 130 ++++++ sys/arch/i386/stand/biosboot/biosboot.S | 312 +++++++++++++ sys/arch/i386/stand/boot/Makefile | 19 + sys/arch/i386/stand/boot/boot.8 | 0 sys/arch/i386/stand/boot/boot.c | 130 ++++++ sys/arch/i386/stand/boot/cmd.c | 325 +++++++++++++ sys/arch/i386/stand/boot/cmd.h | 53 +++ sys/arch/i386/stand/boot/conf.c | 92 ++++ sys/arch/i386/stand/boot/crt0.c | 115 +++++ sys/arch/i386/stand/boot/srt0.S | 258 +++++++++++ sys/arch/i386/stand/boot/version.c | 2 + sys/arch/i386/stand/installboot/Makefile | 10 + sys/arch/i386/stand/installboot/installboot.8 | 58 +++ sys/arch/i386/stand/installboot/installboot.c | 436 ++++++++++++++++++ sys/arch/i386/stand/libsa/Makefile | 51 ++ sys/arch/i386/stand/libsa/asm.S | 108 +++++ sys/arch/i386/stand/libsa/bioscom.S | 208 +++++++++ sys/arch/i386/stand/libsa/biosdev.c | 197 ++++++++ sys/arch/i386/stand/libsa/biosdev.h | 64 +++ sys/arch/i386/stand/libsa/biosdisk.S | 187 ++++++++ sys/arch/i386/stand/libsa/bioskbd.S | 170 +++++++ sys/arch/i386/stand/libsa/biostime.S | 100 ++++ sys/arch/i386/stand/libsa/dev_i386.c | 82 ++++ sys/arch/i386/stand/libsa/exec_i386.c | 51 ++ sys/arch/i386/stand/libsa/gateA20.c | 76 +++ sys/arch/i386/stand/libsa/libsa.h | 45 ++ sys/arch/i386/stand/libsa/memprobe.c | 50 ++ sys/arch/i386/stand/libsa/memsize.S | 98 ++++ sys/arch/i386/stand/libsa/probe_keyboard.c | 117 +++++ sys/arch/i386/stand/libsa/real_prot.S | 172 +++++++ sys/arch/i386/stand/libsa/srt0.S | 139 ++++++ sys/arch/i386/stand/libsa/startprog.S | 45 ++ sys/arch/i386/stand/libsa/unixsys.S | 39 ++ sys/arch/i386/stand/libz/Makefile | 17 + sys/arch/i386/stand/mbr/Makefile | 22 + sys/arch/i386/stand/mbr/mbr.8 | 0 sys/arch/i386/stand/mbr/mbr.S | 309 +++++++++++++ sys/stand/boot/boot.c | 130 ++++++ sys/stand/boot/cmd.c | 325 +++++++++++++ sys/stand/boot/cmd.h | 53 +++ 44 files changed, 4897 insertions(+) create mode 100644 sys/arch/i386/stand/Makefile create mode 100644 sys/arch/i386/stand/Makefile.inc create mode 100644 sys/arch/i386/stand/README create mode 100644 sys/arch/i386/stand/biosboot/Makefile create mode 100644 sys/arch/i386/stand/biosboot/biosboot.8 create mode 100644 sys/arch/i386/stand/biosboot/biosboot.S create mode 100644 sys/arch/i386/stand/boot/Makefile create mode 100644 sys/arch/i386/stand/boot/boot.8 create mode 100644 sys/arch/i386/stand/boot/boot.c create mode 100644 sys/arch/i386/stand/boot/cmd.c create mode 100644 sys/arch/i386/stand/boot/cmd.h create mode 100644 sys/arch/i386/stand/boot/conf.c create mode 100644 sys/arch/i386/stand/boot/crt0.c create mode 100644 sys/arch/i386/stand/boot/srt0.S create mode 100644 sys/arch/i386/stand/boot/version.c create mode 100644 sys/arch/i386/stand/installboot/Makefile create mode 100644 sys/arch/i386/stand/installboot/installboot.8 create mode 100644 sys/arch/i386/stand/installboot/installboot.c create mode 100644 sys/arch/i386/stand/libsa/Makefile create mode 100644 sys/arch/i386/stand/libsa/asm.S create mode 100644 sys/arch/i386/stand/libsa/bioscom.S create mode 100644 sys/arch/i386/stand/libsa/biosdev.c create mode 100644 sys/arch/i386/stand/libsa/biosdev.h create mode 100644 sys/arch/i386/stand/libsa/biosdisk.S create mode 100644 sys/arch/i386/stand/libsa/bioskbd.S create mode 100644 sys/arch/i386/stand/libsa/biostime.S create mode 100644 sys/arch/i386/stand/libsa/dev_i386.c create mode 100644 sys/arch/i386/stand/libsa/exec_i386.c create mode 100644 sys/arch/i386/stand/libsa/gateA20.c create mode 100644 sys/arch/i386/stand/libsa/libsa.h create mode 100644 sys/arch/i386/stand/libsa/memprobe.c create mode 100644 sys/arch/i386/stand/libsa/memsize.S create mode 100644 sys/arch/i386/stand/libsa/probe_keyboard.c create mode 100644 sys/arch/i386/stand/libsa/real_prot.S create mode 100644 sys/arch/i386/stand/libsa/srt0.S create mode 100644 sys/arch/i386/stand/libsa/startprog.S create mode 100644 sys/arch/i386/stand/libsa/unixsys.S create mode 100644 sys/arch/i386/stand/libz/Makefile create mode 100644 sys/arch/i386/stand/mbr/Makefile create mode 100644 sys/arch/i386/stand/mbr/mbr.8 create mode 100644 sys/arch/i386/stand/mbr/mbr.S create mode 100644 sys/stand/boot/boot.c create mode 100644 sys/stand/boot/cmd.c create mode 100644 sys/stand/boot/cmd.h diff --git a/sys/arch/i386/stand/Makefile b/sys/arch/i386/stand/Makefile new file mode 100644 index 00000000000..dbd19e9e3be --- /dev/null +++ b/sys/arch/i386/stand/Makefile @@ -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 diff --git a/sys/arch/i386/stand/Makefile.inc b/sys/arch/i386/stand/Makefile.inc new file mode 100644 index 00000000000..3c7d5a7c867 --- /dev/null +++ b/sys/arch/i386/stand/Makefile.inc @@ -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 index 00000000000..5a92aa772ac --- /dev/null +++ b/sys/arch/i386/stand/README @@ -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 index 00000000000..4d0ffbc8575 --- /dev/null +++ b/sys/arch/i386/stand/biosboot/Makefile @@ -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 diff --git a/sys/arch/i386/stand/biosboot/biosboot.8 b/sys/arch/i386/stand/biosboot/biosboot.8 new file mode 100644 index 00000000000..270a099a72d --- /dev/null +++ b/sys/arch/i386/stand/biosboot/biosboot.8 @@ -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 index 00000000000..ef0e00f311a --- /dev/null +++ b/sys/arch/i386/stand/biosboot/biosboot.S @@ -0,0 +1,312 @@ +/* $OpenBSD: biosboot.S,v 1.2 1997/03/31 03:12:01 weingart Exp $ */ + + .file "bootbios.S" + +#include +#include +#define _LOCORE +#include +#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 index 00000000000..3b3532fc083 --- /dev/null +++ b/sys/arch/i386/stand/boot/Makefile @@ -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 + +.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 index 00000000000..e69de29bb2d diff --git a/sys/arch/i386/stand/boot/boot.c b/sys/arch/i386/stand/boot/boot.c new file mode 100644 index 00000000000..5770f608d53 --- /dev/null +++ b/sys/arch/i386/stand/boot/boot.c @@ -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 +#include +#include +#include +#include +#include +#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 index 00000000000..f6d2aa39a9f --- /dev/null +++ b/sys/arch/i386/stand/boot/cmd.c @@ -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 +#include +#include +#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 index 00000000000..35f3d58348a --- /dev/null +++ b/sys/arch/i386/stand/boot/cmd.h @@ -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 index 00000000000..70a07c6494b --- /dev/null +++ b/sys/arch/i386/stand/boot/conf.c @@ -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 +#include +#include +#include +#include +#include +#include +#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 index 00000000000..14802aeb187 --- /dev/null +++ b/sys/arch/i386/stand/boot/crt0.c @@ -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 +#include +#include +#include +#include +#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 index 00000000000..923a47aeecf --- /dev/null +++ b/sys/arch/i386/stand/boot/srt0.S @@ -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 +#define _LOCORE +#include +#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 index 00000000000..78ecc804998 --- /dev/null +++ b/sys/arch/i386/stand/boot/version.c @@ -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 index 00000000000..ec82f45956c --- /dev/null +++ b/sys/arch/i386/stand/installboot/Makefile @@ -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 diff --git a/sys/arch/i386/stand/installboot/installboot.8 b/sys/arch/i386/stand/installboot/installboot.8 new file mode 100644 index 00000000000..b52eb6587a4 --- /dev/null +++ b/sys/arch/i386/stand/installboot/installboot.8 @@ -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 index 00000000000..8b6d25a8d8e --- /dev/null +++ b/sys/arch/i386/stand/installboot/installboot.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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] \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 index 00000000000..42b2feed81e --- /dev/null +++ b/sys/arch/i386/stand/libsa/Makefile @@ -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 + diff --git a/sys/arch/i386/stand/libsa/asm.S b/sys/arch/i386/stand/libsa/asm.S new file mode 100644 index 00000000000..23de81028bc --- /dev/null +++ b/sys/arch/i386/stand/libsa/asm.S @@ -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 index 00000000000..f8402007401 --- /dev/null +++ b/sys/arch/i386/stand/libsa/bioscom.S @@ -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 + +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 index 00000000000..6049c632923 --- /dev/null +++ b/sys/arch/i386/stand/libsa/biosdev.c @@ -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 +#include +#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 index 00000000000..da619027b82 --- /dev/null +++ b/sys/arch/i386/stand/libsa/biosdev.h @@ -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 index 00000000000..f036d0f95c0 --- /dev/null +++ b/sys/arch/i386/stand/libsa/biosdisk.S @@ -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 +#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 index 00000000000..ff414bf30f2 --- /dev/null +++ b/sys/arch/i386/stand/libsa/bioskbd.S @@ -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 +#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 index 00000000000..fbcc8c73fc9 --- /dev/null +++ b/sys/arch/i386/stand/libsa/biostime.S @@ -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 +#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 index 00000000000..c573295390f --- /dev/null +++ b/sys/arch/i386/stand/libsa/dev_i386.c @@ -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 +#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 index 00000000000..3a437498264 --- /dev/null +++ b/sys/arch/i386/stand/libsa/exec_i386.c @@ -0,0 +1,51 @@ + +/* $OpenBSD: exec_i386.c,v 1.1 1997/03/31 03:12:13 weingart Exp $ */ + +#include +#include +#include +#include + + +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 index 00000000000..7c3ac5a5fda --- /dev/null +++ b/sys/arch/i386/stand/libsa/gateA20.c @@ -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 +#include +#include + +#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 index 00000000000..b5eb8ddea58 --- /dev/null +++ b/sys/arch/i386/stand/libsa/libsa.h @@ -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 + +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 index 00000000000..1a67eafb84d --- /dev/null +++ b/sys/arch/i386/stand/libsa/memprobe.c @@ -0,0 +1,50 @@ +/* $OpenBSD: memprobe.c,v 1.1 1997/03/31 03:12:14 weingart Exp $ */ + +#include +#include + + +/* 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 index 00000000000..2887d10449b --- /dev/null +++ b/sys/arch/i386/stand/libsa/memsize.S @@ -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 +#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 index 00000000000..e680c248e91 --- /dev/null +++ b/sys/arch/i386/stand/libsa/probe_keyboard.c @@ -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 +#include +#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 index 00000000000..765c318cc76 --- /dev/null +++ b/sys/arch/i386/stand/libsa/real_prot.S @@ -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 +#include + +#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 index 00000000000..e0c94c975eb --- /dev/null +++ b/sys/arch/i386/stand/libsa/srt0.S @@ -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 + + .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 index 00000000000..e1f4e267a43 --- /dev/null +++ b/sys/arch/i386/stand/libsa/startprog.S @@ -0,0 +1,45 @@ +/* $OpenBSD: startprog.S,v 1.1 1997/03/31 03:12:17 weingart Exp $ */ + +#include + + +/* + * 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 index 00000000000..346d625a122 --- /dev/null +++ b/sys/arch/i386/stand/libsa/unixsys.S @@ -0,0 +1,39 @@ + + +#include +#include + + +#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 index 00000000000..067a8a773e3 --- /dev/null +++ b/sys/arch/i386/stand/libz/Makefile @@ -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 +.include +.include +.include + diff --git a/sys/arch/i386/stand/mbr/Makefile b/sys/arch/i386/stand/mbr/Makefile new file mode 100644 index 00000000000..a7a97efbccd --- /dev/null +++ b/sys/arch/i386/stand/mbr/Makefile @@ -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 diff --git a/sys/arch/i386/stand/mbr/mbr.8 b/sys/arch/i386/stand/mbr/mbr.8 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sys/arch/i386/stand/mbr/mbr.S b/sys/arch/i386/stand/mbr/mbr.S new file mode 100644 index 00000000000..2b48f580e96 --- /dev/null +++ b/sys/arch/i386/stand/mbr/mbr.S @@ -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 +#include + +#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 index 00000000000..5770f608d53 --- /dev/null +++ b/sys/stand/boot/boot.c @@ -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 +#include +#include +#include +#include +#include +#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 index 00000000000..f6d2aa39a9f --- /dev/null +++ b/sys/stand/boot/cmd.c @@ -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 +#include +#include +#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 index 00000000000..35f3d58348a --- /dev/null +++ b/sys/stand/boot/cmd.h @@ -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 *)); -- 2.20.1