summaryrefslogtreecommitdiff
path: root/sys/arch/i386/boot
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1996-05-13 09:13:08 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1996-05-13 09:13:08 +0000
commit6b3352d4addbff179912915ad004947505e67434 (patch)
tree9049519131c954d92980af70226c4d4fb4c1d7f3 /sys/arch/i386/boot
parenteff39dd1d9285f27518a1a78cb60580abb10f63d (diff)
From NetBSD PR#1133:
add '?' to list available files at boot.
Diffstat (limited to 'sys/arch/i386/boot')
-rw-r--r--sys/arch/i386/boot/asm.S16
-rw-r--r--sys/arch/i386/boot/bios.S131
-rw-r--r--sys/arch/i386/boot/boot.c42
-rw-r--r--sys/arch/i386/boot/disk.c29
-rw-r--r--sys/arch/i386/boot/io.c40
-rw-r--r--sys/arch/i386/boot/start.S7
-rw-r--r--sys/arch/i386/boot/sys.c31
-rw-r--r--sys/arch/i386/boot/version.c7
8 files changed, 279 insertions, 24 deletions
diff --git a/sys/arch/i386/boot/asm.S b/sys/arch/i386/boot/asm.S
index 18261ffad28..5d9f708eef5 100644
--- a/sys/arch/i386/boot/asm.S
+++ b/sys/arch/i386/boot/asm.S
@@ -103,10 +103,13 @@ xprot:
*/
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)
+ # 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.
ljmp $0x28, $x16
@@ -121,7 +124,10 @@ x16:
# make intersegment jmp to flush the processor pipeline
# using the fake stack frame set up earlier
# and reload CS register
- lret
+ # Here we have an 16 bits intersegment jump.
+ .byte 0xea
+ .word xreal
+ .word 0
xreal:
# we are in real mode now
diff --git a/sys/arch/i386/boot/bios.S b/sys/arch/i386/boot/bios.S
index ea00644b7fa..b6f79b5e5eb 100644
--- a/sys/arch/i386/boot/bios.S
+++ b/sys/arch/i386/boot/bios.S
@@ -71,6 +71,8 @@ ENTRY(biosread)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
movb 16(%ebp), %dh
movw 12(%ebp), %cx
@@ -97,11 +99,120 @@ ENTRY(biosread)
xorl %eax, %eax
movb %bl, %al # return value in %ax
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
+#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
/*
#ifndef SERIAL
# BIOS call "INT 10H Function 0Eh" to write character to console
@@ -120,6 +231,8 @@ ENTRY(putc)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
movb 8(%ebp), %cl
@@ -141,6 +254,8 @@ ENTRY(putc)
data32
call _C_LABEL(real_to_prot)
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
@@ -164,6 +279,8 @@ ENTRY(getc)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
call _C_LABEL(prot_to_real)
@@ -184,6 +301,8 @@ ENTRY(getc)
xorl %eax, %eax
movb %bl, %al
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
@@ -212,6 +331,8 @@ ENTRY(ischar)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
call _C_LABEL(prot_to_real)
@@ -234,6 +355,8 @@ ENTRY(ischar)
xorl %eax, %eax
movb %bl, %al
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
@@ -249,6 +372,8 @@ ENTRY(get_diskinfo)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
movb 8(%ebp), %dl # diskinfo(drive #)
@@ -284,6 +409,8 @@ ok:
andb $0x3f, %cl # mask of cylinder gunk
movb %cl, %al # max sector (and # sectors)
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
@@ -302,6 +429,8 @@ ENTRY(memsize)
pushl %ebp
movl %esp, %ebp
pushl %ebx
+ pushl %esi
+ pushl %edi
movl 8(%ebp), %ebx
@@ -326,6 +455,8 @@ xdone:
call _C_LABEL(real_to_prot)
movl %ebx, %eax
+ popl %edi
+ popl %esi
popl %ebx
popl %ebp
ret
diff --git a/sys/arch/i386/boot/boot.c b/sys/arch/i386/boot/boot.c
index 0e55dbdf62d..86c7adbb448 100644
--- a/sys/arch/i386/boot/boot.c
+++ b/sys/arch/i386/boot/boot.c
@@ -73,7 +73,7 @@ char *names[] = {
static void getbootdev __P((int *howto));
static void loadprog __P((int howto));
-extern char *version;
+extern char version[];
extern int end;
void
@@ -85,6 +85,7 @@ boot(drive)
printf("\n"
">> OpenBSD BOOT: %d/%d k [%s]\n"
+ "use ? for file list, or carriage return for defaults\n"
"use hd(1,a)/bsd to boot sd0 when wd0 is also installed\n",
argv[7] = memsize(0),
argv[8] = memsize(1),
@@ -95,21 +96,36 @@ loadstart:
* As a default set it to the first partition of the first *
* floppy or hard drive *
\***************************************************************/
- part = 0;
- unit = drive&0x7f;
- maj = (drive&0x80 ? 0 : 2); /* a good first bet */
+#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++];
loadflags = 0;
- if (currname == NUMNAMES)
- currname = 0;
getbootdev(&loadflags);
- if (openrd()) {
+ switch(openrd()) {
+ case 0:
+ loadprog(loadflags);
+ break;
+ case -1:
+ currname--;
+ break;
+ default:
printf("Can't find %s\n", name);
- goto loadstart;
+ break;
}
- loadprog(loadflags);
+ if (currname == NUMNAMES)
+ currname = 0;
goto loadstart;
}
@@ -128,8 +144,6 @@ loadprog(howto)
return;
}
- poff = N_TXTOFF(head);
-
startaddr = (int)head.a_entry;
addr = (startaddr & 0x00f00000); /* some MEG boundary */
printf("Booting %s(%d,%c)%s @ 0x%x\n",
@@ -149,7 +163,8 @@ loadprog(howto)
/* LOAD THE TEXT SEGMENT */
/********************************************************/
printf("%d", head.a_text);
- xread(addr, head.a_text);
+ pcpy(&head, addr, sizeof(head));
+ xread(addr+sizeof(head), head.a_text - sizeof(head));
#ifdef CHECKSUM
if (cflag)
printf("(%x)", cksum(addr, head.a_text));
@@ -223,6 +238,9 @@ loadprog(howto)
}
putchar(']');
+#ifdef DOSREAD
+ doclose();
+#endif
/********************************************************/
/* and that many bytes of (debug symbols?) */
diff --git a/sys/arch/i386/boot/disk.c b/sys/arch/i386/boot/disk.c
index 0f37b2471d1..4bf990cca7c 100644
--- a/sys/arch/i386/boot/disk.c
+++ b/sys/arch/i386/boot/disk.c
@@ -41,7 +41,11 @@
#define SPT(di) ((di)&0xff)
#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
struct dkbad dkb;
@@ -148,11 +152,28 @@ static char ra_buf[RA_SECTORS * BPS];
static int ra_dev;
static int ra_end;
static int ra_first;
+static int ra_sectors;
+static int ra_skip;
Bread(sector, addr)
int sector;
void *addr;
{
+ extern int ourseg;
+ int dmalimit = ((((ourseg<<4)+(int)ra_buf)+65536) & ~65535)
+ - ((ourseg<<4)+ (int)ra_buf);
+ if (dmalimit<RA_SECTORS*BPS) {
+ if (dmalimit*2<RA_SECTORS*BPS) {
+ ra_sectors = (RA_SECTORS*BPS-dmalimit)/BPS;
+ ra_skip = RA_SECTORS - ra_sectors;
+ } else {
+ ra_sectors = dmalimit/BPS;
+ ra_skip = 0;
+ }
+ } else {
+ ra_sectors = RA_SECTORS;
+ ra_skip=0;
+ }
if (dosdev != ra_dev || sector < ra_first || sector >= ra_end) {
int cyl, head, sec, nsec;
@@ -161,10 +182,10 @@ Bread(sector, addr)
head = (sector % spc) / spt;
sec = sector % spt;
nsec = spt - sec;
- if (nsec > RA_SECTORS)
- nsec = RA_SECTORS;
+ if (nsec > ra_sectors)
+ nsec = ra_sectors;
twiddle();
- while (biosread(dosdev, cyl, head, sec, nsec, ra_buf)) {
+ 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;
twiddle();
@@ -173,7 +194,7 @@ Bread(sector, addr)
ra_first = sector;
ra_end = sector + nsec;
}
- bcopy(ra_buf + (sector - ra_first) * BPS, addr, BPS);
+ bcopy(ra_buf + (sector - ra_first+ra_skip) * BPS, addr, BPS);
}
badsect(sector)
diff --git a/sys/arch/i386/boot/io.c b/sys/arch/i386/boot/io.c
index 30324242c19..aed0e47dda4 100644
--- a/sys/arch/i386/boot/io.c
+++ b/sys/arch/i386/boot/io.c
@@ -148,9 +148,42 @@ gets(buf)
char *buf;
{
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 (;;) {
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');
*ptr = '\0';
@@ -158,6 +191,13 @@ gets(buf)
} else if (c == '\b' || c == '\177') {
if (ptr > buf) {
putchar('\b');
+#ifdef DOSREAD
+ if (hadarg) {
+ putchar('\n');
+ *ptr=0;
+ return 1;
+ }
+#endif
putchar(' ');
putchar('\b');
ptr--;
diff --git a/sys/arch/i386/boot/start.S b/sys/arch/i386/boot/start.S
index c70205ed786..288c75326ad 100644
--- a/sys/arch/i386/boot/start.S
+++ b/sys/arch/i386/boot/start.S
@@ -70,6 +70,7 @@ BOOTABLE = 0x80 # value of boot_ind, means bootable partition
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
data32
@@ -182,8 +183,13 @@ again:
movl $enoboot, %esi
data32
jmp err_stop
+#else /* !DOSREAD */
+ movb $0xff, %dl
+ jmp _C_LABEL(boot2)
+#endif /* DOSREAD */
+#ifndef DOSREAD
/*
# BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
# Call with %ah = 0x2
@@ -264,6 +270,7 @@ message:
data32
pushl %edx
+#endif
nextb:
cld
lodsb # load a byte into %al
diff --git a/sys/arch/i386/boot/sys.c b/sys/arch/i386/boot/sys.c
index f8009aaf4b9..17796ece6d6 100644
--- a/sys/arch/i386/boot/sys.c
+++ b/sys/arch/i386/boot/sys.c
@@ -60,6 +60,11 @@ _read(buffer, count, copy)
int logno, off, size;
int cnt2;
+#ifdef DOSREAD
+ extern short doshandle;
+ if (doshandle>=0)
+ return __dosread(buffer,count,copy);
+#endif
while (count) {
off = blkoff(fs, poff);
logno = lblkno(fs, poff);
@@ -85,6 +90,10 @@ find(path)
int block, off, loc, ino = ROOTINO, parent;
struct dirent *dp;
int nlinks = 0;
+ int list_only = 0;
+
+ if (strcmp(path, "?") == 0)
+ list_only = 1;
loop:
iodest = iobuf;
@@ -127,7 +136,11 @@ loop:
loc = 0;
do {
if (loc >= inode.i_size)
- return 0;
+ if (list_only) {
+ putchar('\n');
+ return -1;
+ } else
+ return 0;
if (!(off = blkoff(fs, loc))) {
int cnt2;
block = lblkno(fs, loc);
@@ -143,6 +156,11 @@ loop:
return 0;
}
loc += dp->d_reclen;
+ if (dp->d_fileno && list_only &&
+ dp->d_type == DT_REG && dp->d_name[0] != '.') {
+ printf("%s", dp->d_name);
+ putchar(' ');
+ }
} while (!dp->d_fileno || strcmp(path, dp->d_name));
ino = dp->d_fileno;
*(path = rest) = ch;
@@ -212,6 +230,11 @@ openrd()
printf("Wangtek unsupported\n");
return 1;
}
+#ifdef DOSREAD
+ else if (maj == 5) {
+ return dosopenrd(cp);
+ }
+#endif
inode.i_dev = dosdev;
/***********************************************\
* Now we know the disk unit and part, *
@@ -240,8 +263,12 @@ openrd()
/***********************************************\
* Find the actual FILE on the mounted device *
\***********************************************/
- if (!find(cp))
+ switch(find(cp)) {
+ case -1:
+ return -1;
+ case 0:
return 1;
+ }
poff = 0;
name = cp;
diff --git a/sys/arch/i386/boot/version.c b/sys/arch/i386/boot/version.c
index 3d40a95b061..d15e839c8f5 100644
--- a/sys/arch/i386/boot/version.c
+++ b/sys/arch/i386/boot/version.c
@@ -1,8 +1,13 @@
+/* $OpenBSD: version.c,v 1.3 1996/05/13 09:13:07 mickey Exp $ */
/* $NetBSD: version.c,v 1.28 1995/12/23 17:21:23 perry Exp $ */
/*
* NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.
*
+ * 1.28 -> 1.29
+ * adding program for booting from DOS file.
+ * implement 'list files' (Luke Mewburn <lukem@telstra.com.au>)
+ *
* 1.27 -> 1.28
* fix gets to use real timeout instead of loop and do
* a little cleanup, and add some prototypes. A lot more
@@ -54,4 +59,4 @@
* look in boot.c revision logs
*/
-char *version = "1.28";
+char version[] = "1.29";