diff -rc2 boot.old/asm.S boot/asm.S *** boot.old/asm.S Mon Mar 20 08:36:49 1995 --- boot/asm.S Sat Apr 29 17:37:23 1995 *************** *** 104,111 **** ENTRY(prot_to_real) # set up a dummy stack frame for the second seg change. ! movl _ourseg, %eax ! pushw %ax ! movl $xreal, %eax # gas botches pushw $xreal - extra bytes 0, 0 ! pushw %ax # decode to add %al, (%eax) (%al usually 0) # Change to use16 mode. --- 104,114 ---- ENTRY(prot_to_real) # set up a dummy stack frame for the second seg change. ! # Adjust the intersegment jump instruction following ! # the clearing of protected mode bit. ! # This is self-modifying code, but we need a writable ! # code segment, and an intersegment return does not give us that. ! ! movl _ourseg, %eax ! movw %ax, xreal-2 # Change to use16 mode. *************** *** 118,126 **** 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 ! lret xreal: --- 121,128 ---- andl $~CR0_PE, %eax movl %eax, %cr0 ! # Here we have an 16 bits intersegment jump. ! .byte 0xea ! .word xreal ! .word 0 xreal: diff -rc2 boot.old/bios.S boot/bios.S *** boot.old/bios.S Mon Mar 20 08:36:49 1995 --- boot/bios.S Sat Apr 29 17:37:23 1995 *************** *** 56,59 **** --- 56,192 ---- #define data32 .byte 0x66 + #ifdef DOSREAD + /* + # MSDOS call "INT 0x21 Function 0x3d" to open a file. + # Call with %ah = 0x3d + # %al = 0x0 (access and sharing modes) + # %ds:%dx = ASCIZ filename + # %cl = attribute mask of files to look for + */ + ENTRY(dosexit) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 0x8(%ebp), %ebx # exit code + + call _C_LABEL(prot_to_real) # enter real mode + + movb %bl, %al # exit code + movb $0x4c , %ah # Exit + int $0x21 + + cli + hlt + + ENTRY(dosopen) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 0x8(%ebp), %edx # File name. + movb $0x0 , %cl # Attribute mask. + + call _C_LABEL(prot_to_real) # enter real mode + + movb $0x3d, %ah # Open existing file. + movb $0x0 , %al # Compatibility mode + + int $0x21 + + jnc ok1 + addr32 + movl %eax, _C_LABEL(doserrno) + data32 + movl $-1, %eax + ok1: + pushl %eax + data32 + call _C_LABEL(real_to_prot) # back to protected mode + + xorl %eax, %eax + popw %ax # return value in %eax + + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + + ENTRY(dosread) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 0x8(%ebp), %ebx # File handle + movl 0xc(%ebp), %edx # Buffer. + movl 0x10(%ebp) , %ecx # Bytes to read + + call _C_LABEL(prot_to_real) # enter real mode + + movb $0x3f, %ah # Read from file or device + movb $0x0 , %al # Compatibility mode + + int $0x21 + jnc ok2 + addr32 + movl %eax, _C_LABEL(doserrno) + data32 + movl $-1, %eax + ok2: + pushl %eax + data32 + call _C_LABEL(real_to_prot) # back to protected mode + + xorl %eax, %eax + popw %ax # return value in %eax + + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + + ENTRY(dosclose) + pushl %ebp + movl %esp, %ebp + pushl %ebx + pushl %esi + pushl %edi + + movl 0x8(%ebp), %ebx # File handle + + call _C_LABEL(prot_to_real) # enter real mode + + movb $0x3e, %ah # Close file. + movb $0x0 , %al # Compatibility mode + + int $0x21 + jnc ok3 + addr32 + movl %eax, _C_LABEL(doserrno) + data32 + movl $-1, %eax + ok3: + pushl %eax + data32 + call _C_LABEL(real_to_prot) # back to protected mode + + xorl %eax, %eax + popw %ax # return value in %eax + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + + #endif + /* # BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory *************** *** 72,75 **** --- 205,210 ---- movl %esp, %ebp pushl %ebx + pushl %esi + pushl %edi movb 16(%ebp), %dh *************** *** 98,101 **** --- 233,238 ---- movb %bl, %al # return value in %ax + popl %edi + popl %esi popl %ebx popl %ebp *************** *** 121,125 **** movl %esp, %ebp pushl %ebx ! pushl %ecx movb 8(%ebp), %cl --- 258,263 ---- movl %esp, %ebp pushl %ebx ! pushl %esi ! pushl %edi movb 8(%ebp), %cl *************** *** 143,147 **** call _C_LABEL(real_to_prot) ! popl %ecx popl %ebx popl %ebp --- 281,286 ---- call _C_LABEL(real_to_prot) ! popl %edi ! popl %esi popl %ebx popl %ebp *************** *** 167,170 **** --- 306,311 ---- movl %esp, %ebp pushl %ebx + pushl %esi + pushl %edi call _C_LABEL(prot_to_real) *************** *** 187,190 **** --- 328,333 ---- movb %bl, %al + popl %edi + popl %esi popl %ebx popl %ebp *************** *** 215,218 **** --- 358,363 ---- movl %esp, %ebp pushl %ebx + pushl %esi + pushl %edi call _C_LABEL(prot_to_real) *************** *** 237,240 **** --- 382,387 ---- movb %bl, %al + popl %edi + popl %esi popl %ebx popl %ebp *************** *** 252,255 **** --- 399,404 ---- movl %esp, %ebp pushl %ebx + pushl %esi + pushl %edi movb 8(%ebp), %dl # diskinfo(drive #) *************** *** 287,290 **** --- 436,441 ---- movb %cl, %al # max sector (and # sectors) + popl %edi + popl %esi popl %ebx popl %ebp *************** *** 305,308 **** --- 456,461 ---- movl %esp, %ebp pushl %ebx + pushl %esi + pushl %edi movl 8(%ebp), %ebx *************** *** 329,332 **** --- 482,487 ---- movl %ebx, %eax + popl %edi + popl %esi popl %ebx popl %ebp diff -rc2 boot.old/boot.c boot/boot.c *** boot.old/boot.c Mon Mar 20 08:36:50 1995 --- boot/boot.c Sat Apr 29 17:37:23 1995 *************** *** 89,95 **** * floppy or hard drive * \***************************************************************/ ! part = 0; ! unit = drive&0x7f; ! maj = (drive&0x80 ? 0 : 2); /* a good first bet */ name = names[currname++]; --- 89,104 ---- * floppy or hard drive * \***************************************************************/ ! #ifdef DOSREAD ! if (drive== 0xff) { ! maj = 5; ! part = 0; ! unit = 0; ! } else ! #endif ! { ! part = 0; ! unit = drive&0x7f; ! maj = (drive&0x80 ? 0 : 2); /* a good first bet */ ! } name = names[currname++]; *************** *** 121,126 **** } - poff = N_TXTOFF(head); - startaddr = (int)head.a_entry; addr = (startaddr & 0x00f00000); /* some MEG boundary */ --- 130,133 ---- *************** *** 142,146 **** /********************************************************/ printf("%d", head.a_text); ! xread(addr, head.a_text); #ifdef CHECKSUM if (cflag) --- 149,154 ---- /********************************************************/ printf("%d", head.a_text); ! pcpy(&head, addr, sizeof(head)); ! xread(addr+sizeof(head), head.a_text - sizeof(head)); #ifdef CHECKSUM if (cflag) *************** *** 216,219 **** --- 224,230 ---- putchar(']'); + #ifdef DOSREAD + doclose(); + #endif /********************************************************/ *************** *** 254,258 **** startaddr &= 0xffffff; argv[1] = howto; ! argv[2] = (MAKEBOOTDEV(maj, 0, 0, unit, part)); argv[5] = startaddr; argv[6] = (int) &x_entry; --- 265,274 ---- startaddr &= 0xffffff; argv[1] = howto; ! #ifdef DOSREAD ! if (maj==5) ! argv[2] = 0; ! else ! #endif ! argv[2] = (MAKEBOOTDEV(maj, 0, 0, unit, part)); argv[5] = startaddr; argv[6] = (int) &x_entry; diff -rc2 boot.old/disk.c boot/disk.c *** boot.old/disk.c Mon Mar 20 08:36:51 1995 --- boot/disk.c Sat Apr 29 17:37:23 1995 *************** *** 42,46 **** --- 42,50 ---- #define HEADS(di) ((((di)>>8)&0xff)+1) + #ifdef DOSREAD + char *devs[] = {"wd", "hd", "fd", "wt", "sd", "dos", 0}; + #else char *devs[] = {"wd", "hd", "fd", "wt", "sd", 0}; + #endif #ifdef DO_BAD144 *************** *** 149,152 **** --- 153,158 ---- static int ra_end; static int ra_first; + static int ra_sectors; + static int ra_skip; Bread(sector, addr) *************** *** 154,157 **** --- 160,178 ---- void *addr; { + extern int ourseg; + int dmalimit = ((((ourseg<<4)+(int)ra_buf)+65536) & ~65535) + - ((ourseg<<4)+ (int)ra_buf); + if (dmalimit= ra_end) { *************** *** 162,169 **** sec = sector % spt; nsec = spt - sec; ! if (nsec > RA_SECTORS) ! nsec = RA_SECTORS; twiddle(); ! while (biosread(dosdev, cyl, head, sec, nsec, ra_buf)) { printf("Error: C:%d H:%d S:%d\n", cyl, head, sec); nsec = 1; --- 183,190 ---- sec = sector % spt; nsec = spt - sec; ! if (nsec > ra_sectors) ! nsec = ra_sectors; twiddle(); ! while (biosread(dosdev, cyl, head, sec, nsec, ra_buf+ra_skip*BPS)) { printf("Error: C:%d H:%d S:%d\n", cyl, head, sec); nsec = 1; *************** *** 174,178 **** ra_end = sector + nsec; } ! bcopy(ra_buf + (sector - ra_first) * BPS, addr, BPS); } --- 195,199 ---- ra_end = sector + nsec; } ! bcopy(ra_buf + (sector - ra_first+ra_skip) * BPS, addr, BPS); } diff -rc2 boot.old/io.c boot/io.c *** boot.old/io.c Mon Mar 20 08:36:51 1995 --- boot/io.c Sat Apr 29 17:37:23 1995 *************** *** 138,146 **** int i; char *ptr = buf; for (i = 240000; i > 0; i--) ! if (ischar()) for (;;) { register int c = getc(); if (c == '\n' || c == '\r') { putchar('\n'); --- 138,179 ---- int i; char *ptr = buf; + static char hadchar=0; + #ifdef DOSREAD + /* + * Simulate keyboard input of the command line arguments. + */ + static int first=1; + int hadarg=0; + + if (first) { + char *arg = (char *) 0x80; + int argcnt = *arg++; + while (argcnt && *arg==' ') { + arg++; + argcnt--; + } + while (argcnt--) { + if (*arg>='A' && *arg<='Z') + *arg += 'a' - 'A'; + putchar(*arg); + *ptr++ = *arg++; + hadarg=1; + } + first=0; + } + #endif for (i = 240000; i > 0; i--) ! if (ischar() || hadchar) for (;;) { register int c = getc(); + hadchar=1; + #ifdef DOSREAD + if (c == 3 || c== 27 ) { + printf("Exiting\n"); + dosexit(0); + printf("Exiting failed\n"); + } + #endif if (c == '\n' || c == '\r') { putchar('\n'); *************** *** 159,162 **** --- 192,202 ---- } } + #ifdef DOSREAD + if (hadarg) { + putchar('\n'); + *ptr=0; + return 1; + } + #endif return 0; } diff -rc2 boot.old/start.S boot/start.S *** boot.old/start.S Mon Mar 20 08:36:52 1995 --- boot/start.S Sat Apr 29 17:37:23 1995 *************** *** 71,74 **** --- 71,75 ---- ENTRY(boot1) start: + #ifndef DOSREAD # start (aka boot1) is loaded at 0x0:0x7c00 but we want 0x7c0:0 # ljmp to the next instruction to adjust %cs *************** *** 225,229 **** --- 226,235 ---- data32 ljmp $BOOTSEG, $_C_LABEL(boot2) + #else /* !DOSREAD */ + movb $0xff, %dl + jmp _C_LABEL(boot2) + #endif /* DOSREAD */ + #ifndef DOSREAD # # read_error *************** *** 296,299 **** --- 302,306 ---- ret + #endif /* Conventional GDT indexes. */ diff -rc2 boot.old/sys.c boot/sys.c *** boot.old/sys.c Mon Mar 20 08:36:52 1995 --- boot/sys.c Sat Apr 29 17:37:23 1995 *************** *** 61,64 **** --- 61,69 ---- int cnt2; + #ifdef DOSREAD + extern short doshandle; + if (doshandle>=0) + return __dosread(buffer,count,copy); + #endif while (count) { off = blkoff(fs, poff); *************** *** 213,216 **** --- 218,226 ---- return 1; } + #ifdef DOSREAD + else if (maj == 5) { + return dosopenrd(cp); + } + #endif inode.i_dev = dosdev; /***********************************************\ diff -rc2 boot.old/table.c boot/table.c *** boot.old/table.c Mon Mar 20 08:36:53 1995 --- boot/table.c Sat Apr 29 17:37:23 1995 *************** *** 83,88 **** {0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */ /* 0x92? */ ! {0xFFFF, RUN, RUN, 0x9E, 0xCF, 0x0}, /* 0x18 : boot code */ ! {0xFFFF, RUN, RUN, 0x92, 0xCF, 0x0}, /* 0x20 : boot data */ {0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */ }; --- 83,88 ---- {0xFFFF, 0x0, 0x0, 0x93, 0xCF, 0x0}, /* 0x10 : kernel data */ /* 0x92? */ ! {0xFFFF, RUN, RUN, 0x9E, 0x40, 0x0}, /* 0x18 : boot code */ ! {0xFFFF, RUN, RUN, 0x92, 0x0, 0x0}, /* 0x20 : boot data */ {0xFFFF, RUN, RUN, 0x9E, 0x0, 0x0}, /* 0x28 : boot code, 16 bits */ }; diff -rc2 boot.old/version.c boot/version.c *** boot.old/version.c Mon Mar 20 08:36:53 1995 --- boot/version.c Sat Apr 29 18:07:52 1995 *************** *** 4,7 **** --- 4,10 ---- * NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. * + * 1.27 -> 1.27.1 + * adding program for booting from DOS file + * * 1.26 -> 1.27 * size reduction and code cleanup. (mycroft) *************** *** 50,52 **** */ ! char *version = "1.27"; --- 53,55 ---- */ ! char *version = "1.27.1"; *** /dev/null Sat Apr 29 03:31:39 1995 --- boot/dossys.c Sat Apr 29 17:37:24 1995 *************** *** 0 **** --- 1,168 ---- + #ifdef DOSREAD + + #include "boot.h" + short doserrno; + short doshandle = -1; + void bcopy(), pcpy(); + + void _read(); + + char iobuf[MAXBSIZE]; + + char *doserrors[] ={ + /* 00 */ "no error", + /* 01 */ "function number invalid", + /* 02 */ "file not found", + /* 03 */ "path not found", + /* 04 */ "too many open files (no handles available)", + /* 05 */ "access denied", + /* 06 */ "invalid handle", + /* 07 */ "memory control block destroyed", + /* 08 */ "insufficient memory", + /* 09 */ "memory block address invalid", + /* 0A */ "environment invalid (usually >32K in length)", + /* 0B */ "format invalid", + /* 0C */ "access code invalid", + /* 0D */ "data invalid", + /* 0E */ "reserved", + /* 0F */ "invalid drive", + /* 10 */ "attempted to remove current directory", + /* 11 */ "not same device", + /* 12 */ "no more files", + /* 13 */ "disk write-protected", + /* 14 */ "unknown unit", + /* 15 */ "drive not ready", + /* 16 */ "unknown command", + /* 17 */ "data error (CRC)", + /* 18 */ "bad request structure length", + /* 19 */ "seek error", + /* 1A */ "unknown media type (non-DOS disk)", + /* 1B */ "sector not found", + /* 1C */ "printer out of paper", + /* 1D */ "write fault", + /* 1E */ "read fault", + /* 1F */ "general failure", + /* 20 */ "sharing violation", + /* 21 */ "lock violation", + /* 22 */ "disk change invalid (ES:DI -> media ID structure)(see #0839)", + /* 23 */ "FCB unavailable", + /* 24 */ "sharing buffer overflow", + /* 25 */ "(DOS 4+) code page mismatch", + /* 26 */ "(DOS 4+) cannot complete file operation (out of input)", + /* 27 */ "(DOS 4+) insufficient disk space", + /* 28 */ "Reserved error (0x28)", + /* 29 */ "Reserved error (0x29)", + /* 2A */ "Reserved error (0x2A)", + /* 2B */ "Reserved error (0x2B)", + /* 2C */ "Reserved error (0x2C)", + /* 2D */ "Reserved error (0x2D)", + /* 2E */ "Reserved error (0x2E)", + /* 2F */ "Reserved error (0x2F)", + /* 30 */ "Reserved error (0x30)", + /* 31 */ "Reserved error (0x31)", + /* 32 */ "network request not supported", + /* 33 */ "remote computer not listening", + /* 34 */ "duplicate name on network", + /* 35 */ "network name not found", + /* 36 */ "network busy", + /* 37 */ "network device no longer exists", + /* 38 */ "network BIOS command limit exceeded", + /* 39 */ "network adapter hardware error", + /* 3A */ "incorrect response from network", + /* 3B */ "unexpected network error", + /* 3C */ "incompatible remote adapter", + /* 3D */ "print queue full", + /* 3E */ "queue not full", + /* 3F */ "not enough space to print file", + /* 40 */ "network name was deleted", + /* 41 */ "network: Access denied", + /* 42 */ "network device type incorrect", + /* 43 */ "network name not found", + /* 44 */ "network name limit exceeded", + /* 45 */ "network BIOS session limit exceeded", + /* 46 */ "temporarily paused", + /* 47 */ "network request not accepted", + /* 48 */ "network print/disk redirection paused", + /* 49 */ "network software not installed", + /* 4A */ "unexpected adapter close", + /* 4B */ "(LANtastic) password expired", + /* 4C */ "(LANtastic) login attempt invalid at this time", + /* 4D */ "(LANtastic v3+) disk limit exceeded on network node", + /* 4E */ "(LANtastic v3+) not logged in to network node", + /* 4F */ "reserved", + /* 50 */ "file exists", + /* 51 */ "reserved", + /* 52 */ "cannot make directory", + /* 53 */ "fail on INT 24h", + /* 54 */ "(DOS 3.3+) too many redirections", + /* 55 */ "(DOS 3.3+) duplicate redirection", + /* 56 */ "(DOS 3.3+) invalid password", + /* 57 */ "(DOS 3.3+) invalid parameter", + /* 58 */ "(DOS 3.3+) network write fault", + /* 59 */ "(DOS 4+) function not supported on network", + /* 5A */ "(DOS 4+) required system component not installed", + /* 64 */ "(MSCDEX) unknown error", + /* 65 */ "(MSCDEX) not ready", + /* 66 */ "(MSCDEX) EMS memory no longer valid", + /* 67 */ "(MSCDEX) not High Sierra or ISO-9660 format", + /* 68 */ "(MSCDEX) door open", + }; + + + void __dosread(buffer, count, copy) + char *buffer; + int count; + void (*copy)(); + { + int size; + int cnt2; + + while (count) { + size=count; + + if (size>MAXBSIZE) + size=MAXBSIZE; + + size=dosread(doshandle,iobuf,size); + twiddle(); + copy(iobuf , buffer, size); + buffer += size; + count -= size; + } + } + + char *printdoserror(char *header) + { + static char buf[32]; + int max=sizeof(doserrors)/sizeof(doserrors[0]); + if (doserrno=0) + printf("%s: %s\n",header,doserrors[doserrno]); + else + printf("%s: Unknown error %d\n",header,doserrno); + } + + doclose() + { + if (doshandle>=0) { + if (dosclose(doshandle)<0) { + printdoserror("Dosclose"); + doshandle = -1; + return -1; + } + } + return 0; + } + + dosopenrd(char *cp) + { + if (doshandle<0) { + doshandle=dosopen(cp); + if (doshandle<0) { + printdoserror("dosopen"); + return -1; + } + } + return 0; + } + + #endif *** /dev/null Sat Apr 29 03:31:39 1995 --- boot.dos/Makefile Sat Apr 29 17:57:32 1995 *************** *** 0 **** --- 1,74 ---- + # $NetBSD: Makefile,v 1.18 1995/03/23 19:46:45 jtc Exp $ + # + # Ported to boot 386BSD by Julian Elischer (julian@tfs.com) + # September 1992 + # + # 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. + # + + S= ${.CURDIR}/../../.. + + ### find out what to use for libkern + .include "$S/lib/libkern/Makefile.inc" + .ifndef PROF + LIBKERN= ${KERNLIB} + .else + LIBKERN= ${KERNLIB_PROF} + .endif + + machine-links: + -rm -f machine && \ + ln -s ${.CURDIR}/../include machine + -rm -f ${MACHINE_ARCH} && \ + ln -s ${.CURDIR}/../include ${MACHINE_ARCH} + + all: machine-links boot.com + + NOPROG= noprog + NOMAN= noman + + CFLAGS= -O6 -DKERNEL -D_KERNEL -DI386_CPU -DI486_CPU -DI586_CPU + CFLAGS+=-DDO_BAD144 -I. -I${.CURDIR} -I$S -I${.CURDIR}/../.. + + # Uncomment this to make the boot block talk to a serial port. + #CPPFLAGS+=-DSERIAL + # Uncomment this to make boot blocks read DOS files + CPPFLAGS+= -DDOSREAD + + # start.o should be first + OBJS= start.o table.o boot.o asm.o bios.o dossys.o io.o disk.o sys.o version.o + VPATH= ${.CURDIR}/../boot + + boot.com: ${OBJS} ${LIBKERN} + ${LD} -Bstatic -e start -N -T 0x100 -o dosboot ${OBJS} ${LIBKERN} + cp dosboot dosboot.sym + @strip dosboot + @sh ${.CURDIR}/../boot/rmaouthdr dosboot dosboot.tmp + @mv -f dosboot.tmp boot.com + @ls -l boot.com + + install: boot.com + cp boot.com ${DESTDIR}/usr/mdec/boot.com + + + CLEANFILES+=boot.com dosboot dosboot.sym machine ${MACHINE_ARCH} + + .include *** Makefile.old Mon Mar 20 08:36:46 1995 --- Makefile Sat Apr 29 18:06:13 1995 *************** *** 7,11 **** NOMAN= noman ! SUBDIR= boot TI386= ../i386/tags --- 7,11 ---- NOMAN= noman ! SUBDIR= boot boot.dos TI386= ../i386/tags