diff options
author | Tom Cosgrove <tom@cvs.openbsd.org> | 2004-08-21 18:53:39 +0000 |
---|---|---|
committer | Tom Cosgrove <tom@cvs.openbsd.org> | 2004-08-21 18:53:39 +0000 |
commit | 344335c7bf85ce6d4b5a9b8c702ecfb01900e29f (patch) | |
tree | 78093d955bae8192e4df7fe744fed12dfa723087 | |
parent | 1d0cf3361556a13c670d6364b82fd141715302b6 (diff) |
Enter cdboot, a CD-specific second-stage bootrap. Based on the i386
cdboot that Toby and I put together at the hackathon.
"go for it" deraadt@
-rw-r--r-- | sys/arch/amd64/include/biosvar.h | 3 | ||||
-rw-r--r-- | sys/arch/amd64/stand/cdboot/Makefile | 66 | ||||
-rw-r--r-- | sys/arch/amd64/stand/cdboot/cdboot.8 | 96 | ||||
-rw-r--r-- | sys/arch/amd64/stand/cdboot/conf.c | 91 | ||||
-rw-r--r-- | sys/arch/amd64/stand/cdboot/srt0.S | 243 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/biosdev.c | 57 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/dev_i386.c | 20 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/diskprobe.c | 102 | ||||
-rw-r--r-- | sys/arch/amd64/stand/libsa/libsa.h | 3 |
9 files changed, 649 insertions, 32 deletions
diff --git a/sys/arch/amd64/include/biosvar.h b/sys/arch/amd64/include/biosvar.h index b9261e27297..f0ccb202090 100644 --- a/sys/arch/amd64/include/biosvar.h +++ b/sys/arch/amd64/include/biosvar.h @@ -1,5 +1,5 @@ /* XXX - DSR */ -/* $OpenBSD: biosvar.h,v 1.3 2004/02/27 21:55:25 deraadt Exp $ */ +/* $OpenBSD: biosvar.h,v 1.4 2004/08/21 18:53:38 tom Exp $ */ /* * Copyright (c) 1997-1999 Michael Shalayeff @@ -164,6 +164,7 @@ typedef struct _bios_diskinfo { #define BDI_INVALID 0x00000001 /* I/O error during checksumming */ #define BDI_GOODLABEL 0x00000002 /* Had SCSI or ST506/ESDI disklabel */ #define BDI_BADLABEL 0x00000004 /* Had another disklabel */ +#define BDI_EL_TORITO 0x00000008 /* 2,048-byte sectors */ #define BDI_PICKED 0x80000000 /* kernel-only: cksum matched */ } bios_diskinfo_t; diff --git a/sys/arch/amd64/stand/cdboot/Makefile b/sys/arch/amd64/stand/cdboot/Makefile new file mode 100644 index 00000000000..ec48e91e56f --- /dev/null +++ b/sys/arch/amd64/stand/cdboot/Makefile @@ -0,0 +1,66 @@ +# $OpenBSD: Makefile,v 1.1 2004/08/21 18:53:38 tom Exp $ + +.include "${.CURDIR}/../Makefile.inc" + +MAN= cdboot.8 + +.if ${MACHINE} == "amd64" +S =${.CURDIR}/../../../.. +SADIR= ${.CURDIR}/.. + +PROG= cdboot +SRCS= srt0.S conf.c +LD?= ld +SIZE?= size +LDFLAGS+=-melf_i386 -nostdlib -Bstatic -Ttext $(LINKADDR) -N -x -noinhibit-exec +LDFLAGS+=-L/usr/libdata +INSTALL_STRIP= + +.PATH: ${SADIR}/libsa +# i386 stuff (so, it will possibly load in the same 64k) +SRCS+= machdep.c dev_i386.c exec_i386.c cmd_i386.c +SRCS+= gidt.S alloca.S biosdev.c bioscons.c gateA20.c \ + memprobe.c diskprobe.c time.c biosprobe.c + +.PATH: ${S}/stand/boot +SRCS+= boot.c cmd.c vars.c bootarg.c + +.PATH: ${S}/lib/libsa +.PATH: ${S}/lib/libkern # for strl* +# stand routines +# not required: getfile.c gets.c globals.c strlcat.c +SRCS+= alloc.c exit.c strcmp.c strlen.c \ + strncmp.c memcmp.c memcpy.c memset.c printf.c snprintf.c \ + strerror.c strncpy.c strtol.c ctime.c strlcpy.c +# io routines +# not required: ioctl.c write.c +SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c fstat.c lseek.c \ + open.c read.c stat.c cread.c readdir.c cons.c loadfile.c +# boot filesystems +SRCS+= ufs.c cd9660.c + +.PATH: ${S}/lib/libz +SRCS+= adler32.c crc32.c inflate.c inftrees.c + +#LDADD= ${LIBSA} ${LIBZ} +#DPADD= ${LIBSA} ${LIBZ} + +${PROG}: $(OBJS) $(DPADD) + $(LD) $(LDFLAGS) -o ${PROG} $(OBJS) $(LDADD) + @if [ -x ${.OBJDIR}/${PROG} ]; then \ + objcopy -O binary ${PROG} ${.OBJDIR}/.tmp;\ + mv -f ${.OBJDIR}/.tmp ${.OBJDIR}/${PROG}; \ + ls -l ${.OBJDIR}/${PROG}; \ + fi + +.else +NOPROG= +.endif + +.include <bsd.prog.mk> + +CPPFLAGS+=-DBOOTMAGIC=$(BOOTMAGIC) ${DEBUGFLAGS} +CPPFLAGS+=-DSLOW -DSMALL -DNOBYFOUR -DNO_GZIP -DDYNAMIC_CRC_TABLE +CPPFLAGS+=-DLINKADDR=${LINKADDR} -I${S}/stand/boot +CFLAGS+=-m32 ${SACFLAGS} -D__INTERNAL_LIBSA_CREAD +AFLAGS+=-m32 diff --git a/sys/arch/amd64/stand/cdboot/cdboot.8 b/sys/arch/amd64/stand/cdboot/cdboot.8 new file mode 100644 index 00000000000..8109ebdbebb --- /dev/null +++ b/sys/arch/amd64/stand/cdboot/cdboot.8 @@ -0,0 +1,96 @@ +.\" $OpenBSD: cdboot.8,v 1.1 2004/08/21 18:53:38 tom Exp $ +.\" Copyright (c) 2004 Tom Cosgrove +.\" Copyright (c) 2003 Matthias Drochner +.\" Copyright (c) 1999 Doug White +.\" 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.Dd August 21, 2004 +.Dt CDBOOT 8 amd64 +.Os +.Sh NAME +.Nm cdboot +.Nd +amd64-specific second-stage CD-specific bootstrap +.Sh DESCRIPTION +.Nm +is a modified version of the amd64 second-stage bootstrap program, +.Xr boot 8 , +configured to be run by the +.Ox +El Torito CD-ROM boot sector +.Pa cdbr . +.Nm +will look for an +.Pa /etc/boot.conf +configuration +file on the CD-ROM. +If it finds one, it processes the commands within it. +.Pp +.Nm +then sits in a loop, +processing commands given by the user. +It accepts all the commands accepted by +.Xr boot 8 . +.Pp +If no commands are given for a short time, +.Nm +will then attempt to load an +.Ox +kernel +.Pa /bsd +from the CD. +It may be told to boot an alternative kernel, +either by commands in the +.Pa boot.conf +file, +or by commands typed by the user at the +.Ic boot> +prompt. +.Sh FILES +.Bl -tag -width /usr/mdec/cdbootxx -compact +.It Pa /usr/mdec/cdboot +CD-specific second-stage bootstrap +.It Pa /etc/boot.conf +.Nm +configuration file (read from CD) +.El +.Sh EXAMPLES +Boot the install kernel: +.Pp +.Dl boot> bsd.rd +.Sh SEE ALSO +.Xr boot 8 , +.Xr boot_amd64 8 +.Rs +.%T "El Torito" Bootable CD-ROM Format Specification +.%N Version 1.0 +.%D January 25, 1995 +.%A Curtis E. Stevens, Phoenix Technologies +.%A Stan Merkin, IBM +.Re +.Sh HISTORY +The +.Nm +program first appeared in +.Ox 3.6 . diff --git a/sys/arch/amd64/stand/cdboot/conf.c b/sys/arch/amd64/stand/cdboot/conf.c new file mode 100644 index 00000000000..29c69442bc8 --- /dev/null +++ b/sys/arch/amd64/stand/cdboot/conf.c @@ -0,0 +1,91 @@ +/* $OpenBSD: conf.c,v 1.1 2004/08/21 18:53:38 tom Exp $ */ + +/* + * Copyright (c) 2004 Tom Cosgrove + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <netinet/in.h> +#include <libsa.h> +#include <lib/libsa/ufs.h> +#include <lib/libsa/cd9660.h> +#ifdef notdef +#include <lib/libsa/fat.h> +#include <lib/libsa/nfs.h> +#include <lib/libsa/tftp.h> +#include <lib/libsa/netif.h> +#endif +#include <lib/libsa/unixdev.h> +#include <biosdev.h> +#include <dev/cons.h> + +const char version[] = "1.00"; +int debug = 1; + + +void (*sa_cleanup)(void) = NULL; + + +void (*amd64_probe1[])(void) = { + gateA20on, cninit, memprobe +}; +void (*amd64_probe2[])(void) = { + diskprobe, cdprobe +}; + +struct i386_boot_probes probe_list[] = { + { "probing", amd64_probe1, NENTS(amd64_probe1) }, + { "disk", amd64_probe2, NENTS(amd64_probe2) } +}; +int nibprobes = NENTS(probe_list); + +struct fs_ops file_system[] = { + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, + cd9660_stat, cd9660_readdir }, + { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, + ufs_stat, ufs_readdir }, +#ifdef notdef + { tftp_open, tftp_close, tftp_read, tftp_write, tftp_seek, + tftp_stat, tftp_readdir }, + { nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, + nfs_stat, nfs_readdir }, + { fat_open, fat_close, fat_read, fat_write, fat_seek, + fat_stat, fat_readdir }, +#endif +}; +int nfsys = NENTS(file_system); + +struct devsw devsw[] = { + { "BIOS", biosstrategy, biosopen, biosclose, biosioctl }, +}; +int ndevs = NENTS(devsw); + +struct consdev constab[] = { + { pc_probe, pc_init, pc_getc, pc_putc }, + { com_probe, com_init, com_getc, com_putc }, + { NULL } +}; +struct consdev *cn_tab = constab; diff --git a/sys/arch/amd64/stand/cdboot/srt0.S b/sys/arch/amd64/stand/cdboot/srt0.S new file mode 100644 index 00000000000..14366333637 --- /dev/null +++ b/sys/arch/amd64/stand/cdboot/srt0.S @@ -0,0 +1,243 @@ +/* $OpenBSD: srt0.S,v 1.1 2004/08/21 18:53:38 tom 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. + * + * 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 <machine/asm.h> +#include <assym.h> + +#define BOOTSTACK 0xfffc + + .globl _C_LABEL(end) + .globl _C_LABEL(edata) + .globl _C_LABEL(boot) + .globl _C_LABEL(_rtt) + .globl _C_LABEL(bios_bootdev) + .globl _ASM_LABEL(pmm_init) + .globl Gdtr + + .text + .code16 + .globl _start +_start: +#ifdef DEBUG + movl $0xb80a0, %ebx + addr32 movl $0x07420742, (%ebx) +#endif + +/* Clobbers %ax, maybe more */ +#define putc(c) movb $c, %al; call Lchr + + /* + * We operate as a no emulation boot image, as defined by the + * El Torito Bootable CD-ROM Format Specification v1.0. We use + * a load segment of 0x07C0 (physical load address of 0x7C00). + * Like the standard /boot, we are linked to run at 0x40120 + * (load address 0x40000), so we relocate to there. + * + * From 0x7C00 to 0x40000 is 0x38400 (230400) bytes, so don't + * have to worry about an overlapping copy until cdboot is + * over 225 KB. + * + * Note that there are other reasons to be worried if + * sizeof(/boot) > 64 KB. So currently we copy a maximum of 64 KB. + * + * Our cdbr CD-ROM boot sector passes us the drive number to use + * in %dl. + */ +#define CDBOOTADDR 0x7c00 /* Address where BIOS loads up */ + xorw %ax, %ax + movw %ax, %ss /* CPU disables interrupts till... */ + movl $CDBOOTADDR-4, %esp /* after this instruction */ + + movw $(CDBOOTADDR >> 4), %ax + movw %ax, %ds + xorw %si, %si /* Where we're coming from */ + + movw $(LINKADDR >> 4), %ax + movw %ax, %es /* Set %es = 0x4000 */ + xorw %di, %di /* Where we're going to */ + + movl $_C_LABEL(end), %ecx + subl $_C_LABEL(_start), %ecx /* How big are we? */ + + cld + rep; movsb /* Copy into place */ + + jmpl $(LINKADDR >> 4), $(relocated-_start) /* Now relocate */ + +relocated: + /* + * In 16-bit mode, we have segment registers == 0x4012, and + * offsets work from here, with offset(_start) == 0. + * + * In 32-bit mode, we have a flat memory model, where + * offset(_start) == 0x40120. This is how we're linked. + * + * Now transition to protected mode. + * + * First, initialise the global descriptor table. + */ + cli + push %cs + pop %ds + addr32 data32 lgdt (Gdtr - LINKADDR) + + movl %cr0, %eax + orl $CR0_PE, %eax + data32 movl %eax, %cr0 + data32 ljmp $8, $1f /* Seg sel 0x08 is flat 32-bit code */ +1: + .code32 + movl $0x10, %eax /* Seg sel 0x10 is flat 32-bit data */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + movl $BOOTSTACK, %esp +#ifdef DEBUG + movl $0xb8000, %ebx + movl $0x07420742, (%ebx) +#endif + + movzbl %dl, %eax + orl $0x100, %eax /* Indicate that it's a cd device */ + pushl %eax /* boot() takes this as a parameter */ + + /* Set up an interrupt descriptor table for protected mode. */ + call _ASM_LABEL(pmm_init) +#ifdef DEBUG + movl $0xb80a4, %ebx + movl $0x07520752, (%ebx) +#endif + + /* Zero .bss */ + xorl %eax, %eax + movl $_C_LABEL(end), %ecx + subl $_C_LABEL(edata), %ecx + movl $_C_LABEL(edata), %edi + cld + rep; stosb + + /* Set our program name ("CDBOOT", not "BOOT"). */ + movl $cd_progname, %eax + movl %eax, progname + + /* Put the boot device number into the globals that need it */ + popl %eax /* Get this back from the stack */ + pushl %eax /* boot() takes this as a parameter */ + movl %eax, _C_LABEL(bios_bootdev) + movl %eax, _C_LABEL(bios_cddev) + + /* + * Now call "main()". + * + * We run in flat 32-bit protected mode, with no address mapping. + */ +#ifdef DEBUG + movl $0xb8004, %ebx + movl $0x07410741, (%ebx) +#endif + call _C_LABEL(boot) + + /* boot() should not return. If it does, reset computer. */ + jmp _C_LABEL(_rtt) + +ENTRY(debugchar) + pushl %ebx + movl 8(%esp), %ebx + addl %ebx, %ebx + addl $0xb8000, %ebx + + xorl %eax, %eax + movb 12(%esp), %al + + andl $0xfffffffe, %ebx + movb %al, (%ebx) + popl %ebx + ret + + .code16 + +/* + * Display ASCIZ string at %si. Trashes %si. + */ +Lstr: + pushw %ax + cld +1: + lodsb /* %al = *%si++ */ + testb %al, %al + jz 1f + call Lchr + jmp 1b +1: popw %ax + ret + +/* + * Write out value in %ax in hex + */ +hex_word: + pushw %ax + mov %ah, %al + call hex_byte + popw %ax + /* fall thru */ +/* + * Write out value in %al in hex + */ +hex_byte: + pushw %ax + shrb $4, %al + call hex_nibble + popw %ax + /* fall thru */ + +/* Write out nibble in %al */ +hex_nibble: + and $0x0F, %al + add $'0', %al + cmpb $'9', %al + jbe Lchr + addb $'A'-'9'-1, %al + /* fall thru to Lchr */ +/* + * Lchr: write the character in %al to console + */ +Lchr: + pushw %bx + movb $0x0e, %ah + xorw %bx, %bx + incw %bx /* movw $0x01, %bx */ + int $0x10 + popw %bx + ret + +cd_progname: + .asciz "CDBOOT" + + .end diff --git a/sys/arch/amd64/stand/libsa/biosdev.c b/sys/arch/amd64/stand/libsa/biosdev.c index f0c86450879..3265a5ff2f5 100644 --- a/sys/arch/amd64/stand/libsa/biosdev.c +++ b/sys/arch/amd64/stand/libsa/biosdev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: biosdev.c,v 1.1 2004/02/03 12:09:47 mickey Exp $ */ +/* $OpenBSD: biosdev.c,v 1.2 2004/08/21 18:53:38 tom Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -14,8 +14,8 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * 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 @@ -34,6 +34,7 @@ #include <machine/tss.h> #include <machine/biosvar.h> #include <lib/libsa/saerrno.h> +#include <isofs/cd9660/iso.h> #include "disk.h" #include "libsa.h" #include "biosdev.h" @@ -46,6 +47,7 @@ static int EDD_rw (int, int, u_int64_t, u_int32_t, void *); extern int debug; int bios_bootdev; +int bios_cddev = -1; /* Set by srt0 if coming from CD */ #if 0 struct biosdisk { @@ -238,22 +240,40 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) int dev = bd->bios_number; int j, error; void *bb; + int bbsize = nsect * DEV_BSIZE; - /* use a bounce buffer to not cross 64k DMA boundary */ - if ((((u_int32_t)buf) & ~0xffff) != - (((u_int32_t)buf + nsect * DEV_BSIZE) & ~0xffff)) { + if (bd->flags & BDI_EL_TORITO) { /* It's a CD device */ + dev &= 0xff; /* Mask out this flag bit */ + + /* + * sys/lib/libsa/cd9600.c converts 2,048-byte CD sectors + * to DEV_BSIZE blocks before calling the device strategy + * routine. However, the El Torito spec says that the + * BIOS will work in 2,048-byte sectors. So shift back. + */ + off >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT); + nsect >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT); + } + + /* + * Use a bounce buffer to not cross 64k DMA boundary, and to + * not access 1 MB or above. + */ + if (((((u_int32_t)buf) & ~0xffff) != + (((u_int32_t)buf + bbsize) & ~0xffff)) || + (((u_int32_t)buf) >= 0x100000)) { /* * XXX we believe that all the io is buffered * by fs routines, so no big reads anyway */ - bb = alloca(nsect * DEV_BSIZE); + bb = alloca(bbsize); if (rw != F_READ) - bcopy (buf, bb, nsect * DEV_BSIZE); + bcopy(buf, bb, bbsize); } else bb = buf; /* Try to do operation up to 5 times */ - for (error = 1, j = 5; j-- && error;) { + for (error = 1, j = 5; j-- && error; ) { /* CHS or LBA access? */ if (bd->bios_edd != -1) { error = EDD_rw(rw, dev, off, nsect, bb); @@ -264,9 +284,11 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) /* Handle track boundaries */ for (error = i = 0; error == 0 && i < nsect; - i += n, off += n, p += n * DEV_BSIZE) { + i += n, off += n, p += n * DEV_BSIZE) { + + btochs(off, cyl, head, sect, bd->bios_heads, + bd->bios_sectors); - btochs(off, cyl, head, sect, bd->bios_heads, bd->bios_sectors); if ((sect + (nsect - i)) >= bd->bios_sectors) n = bd->bios_sectors - sect; else @@ -289,7 +311,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) #ifdef BIOS_DEBUG if (debug) printf("\nBIOS error 0x%x (%s)\n", - error, biosdisk_err(error)); + error, biosdisk_err(error)); #endif biosdreset(dev); break; @@ -297,7 +319,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) } if (bb != buf && rw == F_READ) - bcopy (bb, buf, nsect * DEV_BSIZE); + bcopy(bb, buf, bbsize); #ifdef BIOS_DEBUG if (debug) { @@ -307,7 +329,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf) } #endif - return (error); + return error; } /* @@ -396,7 +418,7 @@ biosopen(struct open_file *f, ...) cp++; } - for (maj = 0; maj < nbdevs && + for (maj = 0; maj < nbdevs && strncmp(*file, bdevs[maj], cp - *file); maj++); if (maj >= nbdevs) { printf("Unknown device: "); @@ -436,6 +458,9 @@ biosopen(struct open_file *f, ...) break; case 2: /* fd */ break; + case 6: /* cd */ + biosdev = bios_bootdev & 0xff; + break; default: return ENXIO; } @@ -485,7 +510,7 @@ biosopen(struct open_file *f, ...) return 0; } -const u_char bidos_errs[] = +const u_char bidos_errs[] = /* ignored "\x00" "successful completion\0" */ "\x01" "invalid function/parameter\0" "\x02" "address mark not found\0" diff --git a/sys/arch/amd64/stand/libsa/dev_i386.c b/sys/arch/amd64/stand/libsa/dev_i386.c index c2bd950ebaa..3a5264a7a42 100644 --- a/sys/arch/amd64/stand/libsa/dev_i386.c +++ b/sys/arch/amd64/stand/libsa/dev_i386.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev_i386.c,v 1.1 2004/02/03 12:09:47 mickey Exp $ */ +/* $OpenBSD: dev_i386.c,v 1.2 2004/08/21 18:53:38 tom Exp $ */ /* * Copyright (c) 1996-1999 Michael Shalayeff @@ -97,12 +97,18 @@ devboot(dev_t bootdev, char *p) *p++ = '/'; *p++ = 'r'; #endif - if (bootdev & 0x80) - *p++ = 'h'; - else - *p++ = 'f'; - *p++ = 'd'; - *p++ = '0' + (bootdev & 0x7f); + if (bootdev & 0x100) { + *p++ = 'c'; + *p++ = 'd'; + *p++ = '0'; + } else { + if (bootdev & 0x80) + *p++ = 'h'; + else + *p++ = 'f'; + *p++ = 'd'; + *p++ = '0' + (bootdev & 0x7f); + } *p++ = 'a'; *p = '\0'; } diff --git a/sys/arch/amd64/stand/libsa/diskprobe.c b/sys/arch/amd64/stand/libsa/diskprobe.c index 501fa402c9f..ddb8990b963 100644 --- a/sys/arch/amd64/stand/libsa/diskprobe.c +++ b/sys/arch/amd64/stand/libsa/diskprobe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diskprobe.c,v 1.2 2004/03/21 21:37:41 tom Exp $ */ +/* $OpenBSD: diskprobe.c,v 1.3 2004/08/21 18:53:38 tom Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -13,8 +13,8 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * 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 @@ -53,6 +53,8 @@ struct disklist_lh disklist; struct diskinfo *bootdev_dip; extern int debug; +extern int bios_bootdev; +extern int bios_cddev; /* Probe for all BIOS floppies */ static void @@ -201,6 +203,84 @@ diskprobe(void) } +void +cdprobe(void) +{ + struct diskinfo *dip; + int cddev = bios_cddev & 0xff; + + /* Another BIOS boot device... */ + + if (bios_cddev == -1) /* Not been set, so don't use */ + return; + + dip = alloc(sizeof(struct diskinfo)); + bzero(dip, sizeof(*dip)); + +#if 0 + if (bios_getdiskinfo(cddev, &dip->bios_info)) { + printf(" <!cd0>"); /* XXX */ + free(dip, 0); + return; + } +#endif + + printf(" cd0"); + + dip->bios_info.bios_number = cddev; + dip->bios_info.bios_edd = 1; /* Use the LBA calls */ + dip->bios_info.flags |= BDI_GOODLABEL | BDI_EL_TORITO; + dip->bios_info.checksum = 0; /* just in case */ + dip->bios_info.bsd_dev = + MAKEBOOTDEV(0, 0, 0, 0xff, RAW_PART); + + /* Create an imaginary disk label */ + dip->disklabel.d_secsize = 2048; + dip->disklabel.d_ntracks = 1; + dip->disklabel.d_nsectors = 100; + dip->disklabel.d_ncylinders = 1; + dip->disklabel.d_secpercyl = dip->disklabel.d_ntracks * + dip->disklabel.d_nsectors; + if (dip->disklabel.d_secpercyl == 0) { + dip->disklabel.d_secpercyl = 100; + /* as long as it's not 0, since readdisklabel divides by it */ + } + + strncpy(dip->disklabel.d_typename, "ATAPI CD-ROM", + sizeof(dip->disklabel.d_typename)); + dip->disklabel.d_type = DTYPE_ATAPI; + + strncpy(dip->disklabel.d_packname, "fictitious", + sizeof(dip->disklabel.d_packname)); + dip->disklabel.d_secperunit = 100; + dip->disklabel.d_rpm = 300; + dip->disklabel.d_interleave = 1; + dip->disklabel.d_flags = D_REMOVABLE; + + dip->disklabel.d_bbsize = 2048; + dip->disklabel.d_sbsize = 2048; + + dip->disklabel.d_magic = DISKMAGIC; + dip->disklabel.d_magic2 = DISKMAGIC; + dip->disklabel.d_checksum = dkcksum(&dip->disklabel); + + /* 'a' partition covering the "whole" disk */ + dip->disklabel.d_partitions[0].p_offset = 0; + dip->disklabel.d_partitions[0].p_size = 100; + dip->disklabel.d_partitions[0].p_fstype = FS_UNUSED; + + /* The raw partition is special */ + dip->disklabel.d_partitions[RAW_PART].p_offset = 0; + dip->disklabel.d_partitions[RAW_PART].p_size = 100; + dip->disklabel.d_partitions[RAW_PART].p_fstype = FS_UNUSED; + + dip->disklabel.d_npartitions = RAW_PART + 1; + + /* Add to queue of disks */ + TAILQ_INSERT_TAIL(&disklist, dip, list); +} + + /* Find info on given BIOS disk */ struct diskinfo * dklookup(int dev) @@ -220,13 +300,22 @@ dump_diskinfo(void) struct diskinfo *dip; printf("Disk\tBIOS#\tType\tCyls\tHeads\tSecs\tFlags\tChecksum\n"); - for(dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)){ + for (dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)) { bios_diskinfo_t *bdi = &dip->bios_info; int d = bdi->bios_number; + int u = d & 0x7f; + char c; + + if (bdi->flags & BDI_EL_TORITO) { + c = 'c'; + u = 0; + } else { + c = (d & 0x80) ? 'h' : 'f'; + } printf("%cd%d\t0x%x\t%s\t%d\t%d\t%d\t0x%x\t0x%x\n", - (d & 0x80)?'h':'f', d & 0x7F, d, - (bdi->flags & BDI_BADLABEL)?"*none*":"label", + c, u, d, + (bdi->flags & BDI_BADLABEL)?"*none*":"label", bdi->bios_cylinders, bdi->bios_heads, bdi->bios_sectors, bdi->flags, bdi->checksum); } @@ -288,4 +377,3 @@ disksum(int blk) return (reprobe); } - diff --git a/sys/arch/amd64/stand/libsa/libsa.h b/sys/arch/amd64/stand/libsa/libsa.h index b61adea1107..200997e06be 100644 --- a/sys/arch/amd64/stand/libsa/libsa.h +++ b/sys/arch/amd64/stand/libsa/libsa.h @@ -1,4 +1,4 @@ -/* $OpenBSD: libsa.h,v 1.2 2004/03/21 21:37:41 tom Exp $ */ +/* $OpenBSD: libsa.h,v 1.3 2004/08/21 18:53:38 tom Exp $ */ /* * Copyright (c) 1996-1999 Michael Shalayeff @@ -46,6 +46,7 @@ void smpprobe(void); void pciprobe(void); void memprobe(void); void diskprobe(void); +void cdprobe(void); void apmprobe(void); void apmfixmem(void); void dump_biosmem(bios_memmap_t *); |