Return to BSD News archive
Path: sserve!manuel!munnari.oz.au!uunet!portal!lll-winken!sun-barr!ames!agate!tfs.com!tfs.com!julian From: julian@tfs.com (Julian Elischer) Newsgroups: comp.unix.bsd Subject: new boot blocks: beta release part 1 of 2 Message-ID: <1992Sep23.223243.18085@tfs.com> Date: 23 Sep 92 22:32:43 GMT Organization: TRW Financial Systems Lines: 1364 These boot blocks use the BIOS to do all functions. The allow the user to select the device, partition and filename of the kernel to boot. Since the alpha release, bad block handling has been added so that a kernel lying on remapped blocks can be loaded. Also some major bugs have been removed Thanks to readers. # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # i386/boot # i386/boot/asm.h # i386/boot/table.c # i386/boot/sys.c # i386/boot/start.s # i386/boot/rmaouthdr # i386/boot/io.c # i386/boot/disk.c # i386/include/pio.h # echo c - i386/boot mkdir i386/boot > /dev/null 2>&1 echo x - i386/boot/asm.h sed 's/^X//' >i386/boot/asm.h << 'END-of-i386/boot/asm.h' X/* X * Ported to Boot 386BSD by Julian Elsicher (julian@tfs.com) Sept. 1992 X * X * Mach Operating System X * Copyright (c) 1991,1990,1989 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X/* X * HISTORY X * $Log: asm.h,v $ X * Revision 2.7 92/02/29 15:33:41 rpd X * Added ENTRY2. X * [92/02/28 rpd] X * X * Revision 2.6 92/02/19 15:07:52 elf X * Changed #if __STDC__ to #ifdef __STDC__ X * [92/01/16 jvh] X * X * Revision 2.5 91/05/14 16:02:45 mrt X * Correcting copyright X * X * Revision 2.4 91/02/05 17:10:42 mrt X * Changed to new Mach copyright X * [91/02/01 17:30:29 mrt] X * X * Revision 2.3 90/12/20 16:35:27 jeffreyh X * changes for __STDC__ X * [90/12/06 jeffreyh] X * X * Revision 2.2 90/05/03 15:24:12 dbg X * First checkin. X * X * X * Typo on ENTRY if gprof X * [90/03/29 rvb] X * X * fix SVC for "ifdef wheeze" [kupfer] X * Fix the GPROF definitions. X * ENTRY(x) gets profiled iffdef GPROF. X * Entry(x) (and DATA(x)) is NEVER profiled. X * MCOUNT can be used by asm that intends to build a frame, X * after the frame is built. X * [90/02/26 rvb] X * X * Add #define addr16 .byte 0x67 X * [90/02/09 rvb] X * Added LBi, SVC and ENTRY X * [89/11/10 09:51:33 rvb] X * X * New a.out and coff compatible .s files. X * [89/10/16 rvb] X */ X X X#define S_ARG0 4(%esp) X#define S_ARG1 8(%esp) X#define S_ARG2 12(%esp) X#define S_ARG3 16(%esp) X X#define FRAME pushl %ebp; movl %esp, %ebp X#define EMARF leave X X#define B_ARG0 8(%ebp) X#define B_ARG1 12(%ebp) X#define B_ARG2 16(%ebp) X#define B_ARG3 20(%ebp) X X#ifdef wheeze X X#define ALIGN 4 X#define EXT(x) x X#define LEXT(x) x: X#define LCL(x) ./**/x X X#define LB(x,n) ./**/x X#define LBb(x,n) ./**/x X#define LBf(x,n) ./**/x X X#define SVC lcall $7,$0 X X#define String .string X#define Value .value X#define Times(a,b) [a\*b] X#define Divide(a,b) [a\\b] X X#define INB inb (%dx) X#define OUTB outb (%dx) X#define INL inl (%dx) X#define OUTL outl (%dx) X X#else wheeze X#define ALIGN X#define LCL(x) x X X#define LB(x,n) n X#ifdef __STDC__ X#define EXT(x) _ ## x X#define LEXT(x) _ ## x ## : X X#define LBb(x,n) n ## b X#define LBf(x,n) n ## f X#else __STDC__ X#define EXT(x) _/**/x X#define LEXT(x) _/**/x/**/: X#define LBb(x,n) n/**/b X#define LBf(x,n) n/**/f X#endif __STDC__ X#define SVC .byte 0x9a; .long 0; .word 0x7 X X#define String .ascii X#define Value .word X#define Times(a,b) (a*b) X#define Divide(a,b) (a/b) X X#define INB inb %dx, %al X#define OUTB outb %al, %dx X#define INL inl %dx, %eax X#define OUTL outl %eax, %dx X X#endif wheeze X X#define data32 .byte 0x66 X#define data16 .byte 0x66 X#define addr16 .byte 0x67 X X X X#ifdef GPROF X#ifdef __STDC__ X X#define MCOUNT .data; LB(x, 9); .long 0; .text; lea LBb(x, 9),%edx; call mcount X#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \ X pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; X#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ X .align ALIGN; LEXT(x) LEXT(y) ; \ X pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; X#define ASENTRY(x) .globl x; .align ALIGN; x ## : ; \ X pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; X X#else __STDC__ X X#define MCOUNT .data; LB(x, 9): .long 0; .text; lea LBb(x, 9),%edx; call mcount X#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) ; \ X pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; X#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ X .align ALIGN; LEXT(x) LEXT(y) X#define ASENTRY(x) .globl x; .align ALIGN; x: ; \ X pushl %ebp; movl %esp, %ebp; MCOUNT; popl %ebp; X X#endif __STDC__ X#else GPROF X#ifdef __STDC__ X X#define MCOUNT X#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) X#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ X .align ALIGN; LEXT(x) LEXT(y) X#define ASENTRY(x) .globl x; .align ALIGN; x ## : X X#else __STDC__ X X#define MCOUNT X#define ENTRY(x) .globl EXT(x); .align ALIGN; LEXT(x) X#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ X .align ALIGN; LEXT(x) LEXT(y) X#define ASENTRY(x) .globl x; .align ALIGN; x: X X#endif __STDC__ X#endif GPROF X X#define Entry(x) .globl EXT(x); .align ALIGN; LEXT(x) X#define DATA(x) .globl EXT(x); .align ALIGN; LEXT(x) END-of-i386/boot/asm.h echo x - i386/boot/table.c sed 's/^X//' >i386/boot/table.c << 'END-of-i386/boot/table.c' X/* X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X * X * Mach Operating System X * Copyright (c) 1992, 1991 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X X/* X * HISTORY X * $Log: table.c,v $ X * Revision 2.2 92/04/04 11:36:43 rpd X * Fix Intel Copyright as per B. Davies authorization. X * [92/04/03 rvb] X * Taken from 2.5 bootstrap. X * [92/03/30 rvb] X * X * Revision 2.2 91/04/02 14:42:22 mbj X * Add Intel copyright X * [90/02/09 rvb] X * X */ X X/* X Copyright 1988, 1989, 1990, 1991, 1992 X by Intel Corporation, Santa Clara, California. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and Xits documentation for any purpose and without fee is hereby Xgranted, provided that the above copyright notice appears in all Xcopies and that both the copyright notice and this permission notice Xappear in supporting documentation, and that the name of Intel Xnot be used in advertising or publicity pertaining to distribution Xof the software without specific, written prior permission. X XINTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, XIN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM XLOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, XNEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION XWITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X*/ X X#define NGDTENT 6 X#define GDTLIMIT 48 /* NGDTENT * 8 */ X X/* Segment Descriptor X * X * 31 24 19 16 7 0 X * ------------------------------------------------------------ X * | | |B| |A| | | |1|0|E|W|A| | X * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL| TYPE | BASE 23:16 | X * | | |D| |L| 19..16| | |1|1|C|R|A| | X * ------------------------------------------------------------ X * | | | X * | BASE 15..0 | LIMIT 15..0 | X * | | | X * ------------------------------------------------------------ X */ X Xstruct seg_desc { X unsigned short limit_15_0; X unsigned short base_15_0; X unsigned char base_23_16; X unsigned char bit_15_8; X unsigned char bit_23_16; X unsigned char base_31_24; X }; X X Xstruct seg_desc Gdt[NGDTENT] = { X {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* 0x0 : null */ X {0xFFFF, 0x0, 0x0, 0x9F, 0xCF, 0x0}, /* 0x08 : kernel code */ X {0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */ X {0xFFFF, 0x0000, 0x9, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */ X {0xFFFF, 0x0000, 0x9, 0x92, 0x40, 0x0}, /* 0x20 : boot data */ X {0xFFFF, 0x0000, 0x9, 0x9E, 0x0, 0x0} /* 0x28 : boot code, 16 bits */ X }; X X Xstruct pseudo_desc { X unsigned short limit; X unsigned short base_low; X unsigned short base_high; X }; X Xstruct pseudo_desc Gdtr = { GDTLIMIT, 0x0400, 9 }; Xstruct pseudo_desc Gdtr2 = { GDTLIMIT, 0xfe00, 9 }; X /* boot is loaded at 0x90000, Gdt is at boot+1024 */ END-of-i386/boot/table.c echo x - i386/boot/sys.c sed 's/^X//' >i386/boot/sys.c << 'END-of-i386/boot/sys.c' X/* X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X * X * Mach Operating System X * Copyright (c) 1992, 1991 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X X/* X * HISTORY X * $Log: sys.c,v $ X * Revision 2.2 92/04/04 11:36:34 rpd X * Fabricated from 3.0 bootstrap and scratch. X * [92/03/30 mg32] X * X */ X X#include "boot.h" X#include <sys/dir.h> X#include <sys/reboot.h> X X/* #define BUFSIZE 4096 */ X#define BUFSIZE MAXBSIZE X Xchar buf[BUFSIZE], fsbuf[SBSIZE], iobuf[MAXBSIZE]; X Xint xread(addr, size) X char * addr; X int size; X{ X int count = BUFSIZE; X while (size > 0) { X if (BUFSIZE > size) X count = size; X read(buf, count); X pcpy(buf, addr, count); X size -= count; X addr += count; X } X} X Xread(buffer, count) X int count; X char *buffer; X{ X int logno, off, size; X int cnt2, bnum2; X X while (count) { X off = blkoff(fs, poff); X logno = lblkno(fs, poff); X cnt2 = size = blksize(fs, &inode, logno); X bnum2 = fsbtodb(fs, block_map(logno)) + boff; X cnt = cnt2; X bnum = bnum2; X if ( (!off) && (size <= count)) X { X iodest = buffer; X devread(); X } X else X { X iodest = iobuf; X size -= off; X if (size > count) X size = count; X devread(); X bcopy(iodest+off,buffer,size); X } X buffer += size; X count -= size; X poff += size; X } X} X Xfind(path) X char *path; X{ X char *rest, ch; X int block, off, loc, ino = ROOTINO; X struct direct *dp; Xloop: iodest = iobuf; X cnt = fs->fs_bsize; X bnum = fsbtodb(fs,itod(fs,ino)) + boff; X devread(); X bcopy(&((struct dinode *)iodest)[ino % fs->fs_inopb], X &inode.i_din, X sizeof (struct dinode)); X if (!*path) X return 1; X while (*path == '/') X path++; X if (!inode.i_size || ((inode.i_mode&IFMT) != IFDIR)) X return 0; X for (rest = path; (ch = *rest) && ch != '/'; rest++) ; X *rest = 0; X loc = 0; X do { X if (loc >= inode.i_size) X return 0; X if (!(off = blkoff(fs, loc))) { X block = lblkno(fs, loc); X cnt = blksize(fs, &inode, block); X bnum = fsbtodb(fs, block_map(block)) + boff; X iodest = iobuf; X devread(); X } X dp = (struct direct *)(iodest + off); X loc += dp->d_reclen; X } while (!dp->d_ino || strcmp(path, dp->d_name)); X ino = dp->d_ino; X *(path = rest) = ch; X goto loop; X} X Xchar mapbuf[MAXBSIZE]; Xint mapblock = 0; X Xblock_map(file_block) X int file_block; X{ X if (file_block < NDADDR) X return(inode.i_db[file_block]); X if ((bnum=fsbtodb(fs, inode.i_ib[0])+boff) != mapblock) { X iodest = mapbuf; X cnt = fs->fs_bsize; X devread(); X mapblock = bnum; X } X return (((int *)mapbuf)[(file_block - NDADDR) % NINDIR(fs)]); X} X Xopenrd() X{ X char **devp, *cp = name; X /*******************************************************\ X * If bracket given look for preceding device name * X \*******************************************************/ X while (*cp && *cp!='(') X cp++; X if (!*cp) X { X cp = name; X } X else X { X if (cp++ != name) X { X for (devp = devs; *devp; devp++) X if (name[0] == (*devp)[0] && X name[1] == (*devp)[1]) X break; X if (!*devp) X { X printf("Unknown device\n"); X return 1; X } X maj = devp-devs; X } X /*******************************************************\ X * Look inside brackets for unit number, and partition * X \*******************************************************/ X if (*cp >= '0' && *cp <= '9') X if ((unit = *cp++ - '0') > 1) X { X printf("Bad unit\n"); X return 1; X } X if (!*cp || (*cp == ',' && !*++cp)) X return 1; X if (*cp >= 'a' && *cp <= 'p') X part = *cp++ - 'a'; X while (*cp && *cp++!=')') ; X if (!*cp) X return 1; X } X switch(maj) X { X case 1: X dosdev = unit | 0x80; X unit = 0; X break; X case 0: X case 4: X dosdev = unit | 0x80; X break; X case 2: X dosdev = unit; X break; X case 3: X printf("Wangtek unsupported\n"); X return 1; X break; X } X inode.i_dev = dosdev; X /***********************************************\ X * Now we know the disk unit and part, * X * Load disk info, (open the device) * X \***********************************************/ X if (devopen()) X return 1; X X /***********************************************\ X * Load Filesystem info (mount the device) * X \***********************************************/ X iodest = (char *)(fs = (struct fs *)fsbuf); X cnt = SBSIZE; X bnum = SBLOCK + boff; X devread(); X /***********************************************\ X * Find the actual FILE on the mounted device * X \***********************************************/ X if (!find(cp)) X { X return 1; X } X poff = 0; X name = cp; X return 0; X} END-of-i386/boot/sys.c echo x - i386/boot/start.s sed 's/^X//' >i386/boot/start.s << 'END-of-i386/boot/start.s' X/* X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X * X * Mach Operating System X * Copyright (c) 1992, 1991 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X X/* X * HISTORY X * $Log: start.s,v $ X * Revision 2.2 92/04/04 11:36:29 rpd X * Fix Intel Copyright as per B. Davies authorization. X * [92/04/03 rvb] X * Need to zero dh on hd path; at least for an adaptec card. X * [92/01/14 rvb] X * X * From 2.5 boot: X * Flush digit printing. X * Fuse floppy and hd boot by using Int 21 to tell X * boot type (slightly dubious since Int 21 is DOS X * not BIOS) X * [92/03/30 mg32] X * X * Revision 2.2 91/04/02 14:42:04 mbj X * Fix the BIG boot bug. We had missed a necessary data X * before a xor that was clearing a register used later X * as an index register. X * [91/03/01 rvb] X * Remember floppy type for swapgeneric X * Add Intel copyright X * [90/02/09 rvb] X * X */ X X X/* X Copyright 1988, 1989, 1990, 1991, 1992 X by Intel Corporation, Santa Clara, California. X X All Rights Reserved X XPermission to use, copy, modify, and distribute this software and Xits documentation for any purpose and without fee is hereby Xgranted, provided that the above copyright notice appears in all Xcopies and that both the copyright notice and this permission notice Xappear in supporting documentation, and that the name of Intel Xnot be used in advertising or publicity pertaining to distribution Xof the software without specific, written prior permission. X XINTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE XINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, XIN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR XCONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM XLOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, XNEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION XWITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X*/ X#include "asm.h" X X .file "start.s" X XBOOTSEG = 0x9000 # boot will be loaded at 640k-64k XBOOTSTACK = 0xfe00 # boot stack XSIGNATURE = 0xaa55 XLOADSZ = 14 # size of unix boot XPARTSTART = 0x1be # starting address of partition table XNUMPART = 4 # number of partitions in partition table XPARTSZ = 16 # each partition table entry is 16 bytes XBSDPART = 0xA5 # value of boot_ind, means bootable partition XBOOTABLE = 0x80 # value of boot_ind, means bootable partition X X .text X XENTRY(boot1) X X # boot1 is loaded at 0x0:0x7c00 X # ljmp to the next instruction to set up %cs X data32 X ljmp $0x7c0, $start X Xstart: X # set up %ds X mov %cs, %ax X mov %ax, %ds X X X # set up %ss and %esp X data32 X mov $BOOTSEG, %eax X mov %ax, %ss X data32 X mov $BOOTSTACK, %esp X X /*** set up %es, (where we will load boot2 to) ***/ X mov %ax, %es X X # get the boot drive id X movb $0x33, %ah X movb $0x05, %al X int $0x21 X X cmpb $0x80, %dl X data32 X je hd X Xfd: X# reset the disk system X movb $0x0, %ah X int $0x13 X data32 X mov $0x0001, %ecx # cyl 0, sector 1 X data32 X jmp load X Xhd: /**** load sector 0 into the BOOTSEG ****/ X data32 X mov $0x0201, %eax X xor %ebx, %ebx # %bx = 0 X data32 X mov $0x0001, %ecx X data32 X mov $0x0080, %edx X int $0x13 X data32 X jb read_error X X /***# find the bootable partition *****/ X data32 X mov $PARTSTART, %ebx X data32 X mov $NUMPART, %ecx Xagain: X addr16 X movb %es:4(%ebx), %al X cmpb $BSDPART, %al X data32 X je found X data32 X add $PARTSZ, %ebx X data32 X loop again X data32 X mov $enoboot, %esi X data32 X jmp err_stop X X X# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory X# Call with %ah = 0x2 X# %al = number of sectors X# %ch = cylinder X# %cl = sector X# %dh = head X# %dl = drive (0x80 for hard disk, 0x0 for floppy disk) X# %es:%bx = segment:offset of buffer X# Return: X# %al = 0x0 on success; err code on failure X Xfound: X addr16 X movb %es:1(%ebx), %dh /* head */ X addr16 X movl %es:2(%ebx), %ecx /*sect,cyl (+ 2 bytes junk in top word )*/ X Xload: X movb $0x2, %ah /* function 2 */ X movb $LOADSZ, %al /* number of blocks */ X xor %ebx, %ebx /* %bx = 0, put it at 0 in the BOOTSEG */ X int $0x13 X data32 X jb read_error X X # ljmp to the second stage boot loader (boot2). X # After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used X # as an internal buffer "intbuf". X X data32 X ljmp $BOOTSEG, $EXT(boot2) X X# X# read_error X# X Xread_error: X X data32 X mov $eread, %esi Xerr_stop: X data32 X call message X data32 X jmp stop X X# X# message: write the error message in %ds:%esi to console X# X Xmessage: X # Use BIOS "int 10H Function 0Eh" to write character in teletype mode X # %ah = 0xe %al = character X # %bh = page %bl = foreground color (graphics modes) X X data32 X push %eax X data32 X push %ebx X data32 X mov $0x0001, %ebx X cld X Xnextb: X lodsb # load a byte into %al X cmpb $0x0, %al X data32 X je done X movb $0xe, %ah X int $0x10 # display a byte X data32 X jmp nextb Xdone: X data32 X pop %ebx X data32 X pop %eax X data32 X ret X Xstop: hlt X data32 X jmp stop # halt doesnt actually halt forever X# X/* error messages */ X Xeread: String "Read error\r\n\0" Xenoboot: String "No bootable partition\r\n\0" Xendofcode: X/* throw in a partition in case we are block0 as well */ X/* flag,head,sec,cyl,typ,ehead,esect,ecyl,start,len */ X . = EXT(boot1) + PARTSTART X .byte 0x0,0,0,0,0,0,0,0 X .long 0,0 X .byte 0x0,0,0,0,0,0,0,0 X .long 0,0 X .byte 0x0,0,0,0,0,0,0,0 X .long 0,0 X .byte BOOTABLE,0,1,0,BSDPART,255,255,255 X .long 0,50000 X/* the last 2 bytes in the sector 0 contain the signature */ X . = EXT(boot1) + 0x1fe X .value SIGNATURE XENTRY(disklabel) X . = EXT(boot1) + 0x400 END-of-i386/boot/start.s echo x - i386/boot/rmaouthdr sed 's/^X//' >i386/boot/rmaouthdr << 'END-of-i386/boot/rmaouthdr' X#!/bin/csh -f X# Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X# X# X# HISTORY X# $Log: rmaouthdr,v $ X# Revision 2.2 92/04/04 11:36:01 rpd X# From 2.5 boot X# [92/03/30 mg32] X# X# Xdd if=$1 of=$2 ibs=32 skip=1 obs=1024b END-of-i386/boot/rmaouthdr chmod a+x i386/boot/rmaouthdr echo x - i386/boot/io.c sed 's/^X//' >i386/boot/io.c << 'END-of-i386/boot/io.c' X/* X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X * X * Mach Operating System X * Copyright (c) 1992, 1991 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X X/* X * HISTORY X * $Log: io.c,v $ X * Revision 2.2 92/04/04 11:35:57 rpd X * Fixed for IBM L40's A20 initialization. X * [92/03/30 rvb] X * X * Created. X * [92/03/30 mg32] X * X */ X X#include <i386/include/pio.h> X X#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ X#define K_STATUS 0x64 /* keyboard status */ X#define K_CMD 0x64 /* keybd ctlr command (write-only) */ X X#define K_OBUF_FUL 0x01 /* output buffer full */ X#define K_IBUF_FUL 0x02 /* input buffer full */ X X#define KC_CMD_WIN 0xd0 /* read output port */ X#define KC_CMD_WOUT 0xd1 /* write output port */ X#define KB_A20 0x9f /* enable A20, X enable output buffer full interrupt X enable data line X disable clock line */ X X/* X * Gate A20 for high memory X */ Xunsigned char x_20 = KB_A20; XgateA20() X{ X#ifdef IBM_L40 X outb(0x92, 0x2); X#else IBM_L40 X while (inb(K_STATUS) & K_IBUF_FUL); X while (inb(K_STATUS) & K_OBUF_FUL) X (void)inb(K_RDWR); X X outb(K_CMD, KC_CMD_WOUT); X while (inb(K_STATUS) & K_IBUF_FUL); X outb(K_RDWR, x_20); X while (inb(K_STATUS) & K_IBUF_FUL); X#endif IBM_L40 X} X X/* printf - only handles %d as decimal, %c as char, %s as string */ X Xprintf(format,data) X char *format; X int data; X{ X int *dataptr = &data; X char c; X while (c = *format++) X if (c != '%') X putchar(c); X else X switch (c = *format++) { X case 'd': { X int num = *dataptr++; X char buf[10], *ptr = buf; X if (num<0) { X num = -num; X putchar('-'); X } X do X *ptr++ = '0'+num%10; X while (num /= 10); X do X putchar(*--ptr); X while (ptr != buf); X break; X } X case 'x': { X int num = *dataptr++, dig; X char buf[8], *ptr = buf; X do X *ptr++ = (dig=(num&0xf)) > 9? X 'a' + dig - 10 : X '0' + dig; X while (num >>= 4); X do X putchar(*--ptr); X while (ptr != buf); X break; X } X case 'c': putchar((*dataptr++)&0xff); break; X case 's': { X char *ptr = (char *)*dataptr++; X while (c = *ptr++) X putchar(c); X break; X } X } X} X Xputchar(c) X{ X if (c == '\n') X putc('\r'); X putc(c); X} X Xgetchar() X{ X int c; X X if ((c=getc()) == '\r') X c = '\n'; X if (c == '\b') { X putchar('\b'); X putchar(' '); X } X putchar(c); X return(c); X} X Xgets(buf) Xchar *buf; X{ X int i; X char *ptr=buf; X X for (i = 240000; i>0; i--) X if (ischar()) X for (;;) X switch(*ptr = getchar() & 0xff) { X case '\n': X case '\r': X *ptr = '\0'; X return 1; X case '\b': X if (ptr > buf) ptr--; X continue; X default: X ptr++; X } X return 0; X} X Xstrcmp(s1, s2) Xchar *s1, *s2; X{ X while (*s1 == *s2) { X if (!*s1++) X return 0; X s2++; X } X return 1; X} X Xbcopy(from, to, len) Xchar *from, *to; Xint len; X{ X while (len-- > 0) X *to++ = *from++; X} END-of-i386/boot/io.c echo x - i386/boot/disk.c sed 's/^X//' >i386/boot/disk.c << 'END-of-i386/boot/disk.c' X/* X * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 X * X * Mach Operating System X * Copyright (c) 1992, 1991 Carnegie Mellon University X * All Rights Reserved. X * X * Permission to use, copy, modify and distribute this software and its X * documentation is hereby granted, provided that both the copyright X * notice and this permission notice appear in all copies of the X * software, derivative works or modified versions, and any portions X * thereof, and that both notices appear in supporting documentation. X * X * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" X * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR X * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. X * X * Carnegie Mellon requests users of this software to return to X * X * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU X * School of Computer Science X * Carnegie Mellon University X * Pittsburgh PA 15213-3890 X * X * any improvements or extensions that they make and grant Carnegie Mellon X * the rights to redistribute these changes. X */ X X/* X * HISTORY X * $Log: disk.c,v $ X * Revision 2.2 92/04/04 11:35:49 rpd X * Fabricated from 3.0 bootstrap and 2.5 boot disk.c: X * with support for scsi X * [92/03/30 mg32] X * X */ X X/* X * 9/20/92 X * Peng-Toh Sim. sim@cory.berkeley.edu X * Added bad144 support under 386bsd for wd's X * So, bad block remapping is done when loading the kernel. X */ X X#include "boot.h" X#ifdef DO_BAD144 X#include <sys/dkbad.h> X#endif DO_BAD144 X#include <sys/disklabel.h> X X#define BIOS_DEV_FLOPPY 0x0 X#define BIOS_DEV_WIN 0x80 X X#define BPS 512 X#define SPT(di) ((di)&0xff) X#define HEADS(di) ((((di)>>8)&0xff)+1) X Xchar *devs[] = {"wd", "hd", "fd", "wt", "sd", 0}; X X#ifdef DO_BAD144 Xstruct dkbad dkb; Xint do_bad144; Xint bsize; X#endif DO_BAD144 X Xint spt, spc; X Xchar *iodest; Xstruct fs *fs; Xstruct inode inode; Xint dosdev, unit, part, maj, boff, poff, bnum, cnt; X X/*#define EMBEDDED_DISKLABEL 1*/ Xextern struct disklabel disklabel; X/*struct disklabel disklabel;*/ X Xdevopen() X{ X struct dos_partition *dptr; X struct disklabel *dl; X int dosdev = inode.i_dev; X int i, sector, di; X X di = get_diskinfo(dosdev); X spc = (spt = SPT(di)) * HEADS(di); X if (dosdev == 2) X { X boff = 0; X part = (spt == 15 ? 3 : 1); X } X else X { X#ifdef EMBEDDED_DISKLABEL X dl = &disklabel; X#else EMBEDDED_DISKLABEL X Bread(dosdev, 0); X dptr = (struct dos_partition *)(((char *)0)+DOSPARTOFF); X for (i = 0; i < NDOSPART; i++, dptr++) X if (dptr->dp_typ == DOSPTYP_386BSD) X break; X sector = dptr->dp_start + LABELSECTOR; X Bread(dosdev, sector++); X dl=((struct disklabel *)0); X disklabel = *dl; /* structure copy (maybe useful later)*/ X#endif EMBEDDED_DISKLABEL X if (dl->d_magic != DISKMAGIC) { X printf("bad disklabel"); X return 1; X } X if( (maj == 4) || (maj == 0) || (maj == 1)) X { X if (dl->d_type == DTYPE_SCSI) X { X maj = 4; /* use scsi as boot dev */ X } X else X { X maj = 0; /* must be ESDI/IDE */ X } X } X boff = dl->d_partitions[part].p_offset; X#ifdef DO_BAD144 X bsize = dl->d_partitions[part].p_size; X do_bad144 = 0; X if (dl->d_flags & D_BADSECT) { X /* this disk uses bad144 */ X int i; X int dkbbnum; X struct dkbad *dkbptr; X X /* find the first readable bad144 sector */ X /* some of this code is copied from ufs/disk_subr.c */ X /* read a bad sector table */ X dkbbnum = dl->d_secperunit - dl->d_nsectors; X if (dl->d_secsize > DEV_BSIZE) X dkbbnum *= dl->d_secsize / DEV_BSIZE; X else X dkbbnum /= DEV_BSIZE / dl->d_secsize; X i = 0; X do_bad144 = 0; X do { X /* XXX: what if the "DOS sector" < 512 bytes ??? */ X Bread(dosdev, dkbbnum + i); X dkbptr = (struct dkbad *) 0; X/* XXX why is this not in <sys/dkbad.h> ??? */ X#define DKBAD_MAGIC 0x4321 X if (dkbptr->bt_mbz == 0 && X dkbptr->bt_flag == DKBAD_MAGIC) { X dkb = *dkbptr; /* structure copy */ X do_bad144 = 1; X break; X } X i += 2; X } while (i < 10 && i < dl->d_nsectors); X if (!do_bad144) X printf("Bad badsect table\n"); X else X printf("Using bad144 bad sector at %d\n", dkbbnum+i); X } X#endif DO_BAD144 X } X return 0; X} X Xdevread() X{ X int offset, sector = bnum; X int dosdev = inode.i_dev; X for (offset = 0; offset < cnt; offset += BPS) X { X Bread(dosdev, badsect(dosdev, sector++)); X bcopy(0, iodest+offset, BPS); X } X} X XBread(dosdev,sector) X int dosdev,sector; X{ X int cyl = sector/spc, head = (sector%spc)/spt, secnum = sector%spt; X while (biosread(dosdev, cyl,head,secnum)) X { X printf("Error: C:%d H:%d S:%d\n",cyl,head,secnum); X } X} X Xbadsect(dosdev, sector) X int dosdev, sector; X{ X int i; X#ifdef DO_BAD144 X if (do_bad144) { X u_short cyl; X u_short head; X u_short sec; X int newsec; X struct disklabel *dl = &disklabel; X X /* XXX */ X /* from wd.c */ X /* bt_cyl = cylinder number in sorted order */ X /* bt_trksec is actually (head << 8) + sec */ X X /* only remap sectors in the partition */ X if (sector < boff || sector >= boff + bsize) { X goto no_remap; X } X X cyl = sector / dl->d_secpercyl; X head = (sector % dl->d_secpercyl) / dl->d_nsectors; X sec = sector % dl->d_nsectors; X sec = (head<<8) + sec; X X /* now, look in the table for a possible bad sector */ X for (i=0; i<126; i++) { X if (dkb.bt_bad[i].bt_cyl == cyl) { X /* found same cylinder */ X if (dkb.bt_bad[i].bt_trksec == sec) { X /* FOUND! */ X break; X } X } else if (dkb.bt_bad[i].bt_cyl > cyl) { X i = 126; X break; X } X } X if (i == 126) { X /* didn't find bad sector */ X goto no_remap; X } X /* otherwise find replacement sector */ X newsec = dl->d_secperunit - dl->d_nsectors - i -1; X return newsec; X } X#endif DO_BAD144 X no_remap: X return sector; X} END-of-i386/boot/disk.c echo x - i386/include/pio.h sed 's/^X//' >i386/include/pio.h << 'END-of-i386/include/pio.h' X/* X * Mach Operating System X * Copyright (c) 1990 Carnegie-Mellon University X * All rights reserved. The CMU software License Agreement specifies X * the terms and conditions for use and redistribution. X */ X/* X * HISTORY X * $Log: pio.h,v $ X * Revision 1.1 1992/05/27 00:48:30 balsup X * machkern/cor merge X * X * Revision 1.1 1991/10/10 20:11:39 balsup X * Initial revision X * X * Revision 2.2 91/04/02 11:52:29 mbj X * [90/08/14 mg32] X * X * Now we know how types are factor in. X * Cleaned up a bunch: eliminated ({ for output and flushed unused X * output variables. X * [90/08/14 rvb] X * X * This is how its done in gcc: X * Created. X * [90/03/26 rvb] X * X */ X X X#define inl(y) \ X({ unsigned long _tmp__; \ X asm volatile("inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \ X _tmp__; }) X X#define inw(y) \ X({ unsigned short _tmp__; \ X asm volatile(".byte 0x66; inl %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \ X _tmp__; }) X X#define inb(y) \ X({ unsigned char _tmp__; \ X asm volatile("inb %1, %0" : "=a" (_tmp__) : "d" ((unsigned short)(y))); \ X _tmp__; }) X X X#define outl(x, y) \ X{ asm volatile("outl %0, %1" : : "a" (y) , "d" ((unsigned short)(x))); } X X X#define outw(x, y) \ X{asm volatile(".byte 0x66; outl %0, %1" : : "a" ((unsigned short)(y)) , "d" ((unsigned short)(x))); } X X X#define outb(x, y) \ X{ asm volatile("outb %0, %1" : : "a" ((unsigned char)(y)) , "d" ((unsigned short)(x))); } END-of-i386/include/pio.h exit