* query BIOS geometry information, possibly using the int 13 extensions.
* pass them on to the kernel * print a message if the 2nd stage bootloader returns (i.e. fails) instead of just hanging.
This commit is contained in:
parent
fcfc497f58
commit
f8e221511b
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.17 1999/02/13 02:54:46 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.18 1999/03/08 00:09:24 fvdl Exp $
|
||||
|
||||
S= ${.CURDIR}/../../../../
|
||||
|
||||
|
@ -20,7 +20,7 @@ CPPFLAGS+= -DCOMPAT_OLDBOOT -DCOMPAT_386BSD_MBRPART
|
|||
# and maybe
|
||||
#CPPFLAGS+= -DDIRECT_SERIAL -DCOMCONS_KEYPRESS -DCONSPEED=57600
|
||||
|
||||
#CPPFLAGS+= -DPASS_BIOSGEOM
|
||||
CPPFLAGS+= -DPASS_BIOSGEOM
|
||||
#uncomment if there are problems with memory detection
|
||||
#CPPFLAGS+= -DCONSERVATIVE_MEMDETECT
|
||||
#increase MAXFLENTRIES if "installboot" complains about
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bios_disk.S,v 1.4 1998/10/30 12:16:59 ws Exp $ */
|
||||
/* $NetBSD: bios_disk.S,v 1.5 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
|
@ -114,8 +114,7 @@ ENTRY(biosread)
|
|||
|
||||
/*
|
||||
#
|
||||
# get_diskinfo(): return a word that represents the
|
||||
# max number of sectors and heads and drives for this device
|
||||
# get_diskinfo(): takes a pointer to a biosdisk_ll struct, and fills it in.
|
||||
#
|
||||
*/
|
||||
|
||||
|
@ -129,7 +128,9 @@ ENTRY(get_diskinfo)
|
|||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 8(%ebp), %dl # diskinfo(drive #)
|
||||
movl 8(%ebp), %esi # diskinfo(drive #)
|
||||
movb (%esi), %dl
|
||||
pushl %esi
|
||||
|
||||
call _C_LABEL(prot_to_real) # enter real mode
|
||||
|
||||
|
@ -156,12 +157,20 @@ ok:
|
|||
data32
|
||||
call _C_LABEL(real_to_prot) # back to protected mode
|
||||
|
||||
xorl %eax, %eax
|
||||
popl %esi
|
||||
|
||||
/*form a longword representing all this gunk*/
|
||||
movb %dh, %ah # max head
|
||||
andb $0x3f, %cl # mask of cylinder gunk
|
||||
movb %cl, %al # max sector (and # sectors)
|
||||
movzbl %dh, %eax
|
||||
movl %eax, 8(%esi) # heads
|
||||
movb %cl, %al
|
||||
andb $0x3f, %al
|
||||
movzbl %al, %ebx
|
||||
movl %ebx, 4(%esi) # sectors per track
|
||||
xorl %eax, %eax
|
||||
movb %ch, %al
|
||||
andl $0x0c0, %ecx
|
||||
shll $2, %ecx
|
||||
orl %ecx, %eax
|
||||
movl %eax, 12(%esi) # cylinders
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
|
@ -217,7 +226,7 @@ ENTRY(int13_extension)
|
|||
/*
|
||||
# BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
|
||||
# Call with %ah = 0x42
|
||||
# %ds:%di = parameter block
|
||||
# %ds:%si = parameter block
|
||||
# %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
|
||||
# Return:
|
||||
# %al = 0x0 on success; err code on failure
|
||||
|
@ -253,3 +262,36 @@ ENTRY(biosextread)
|
|||
popl %ebx
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
ENTRY(int13_getextinfo)
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
pushl %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
movb 8(%ebp), %dl # device
|
||||
movl 12(%ebp), %esi # parameter block
|
||||
movl $0x01a, (%esi) # length (v 1.x)
|
||||
|
||||
call _C_LABEL(prot_to_real) # enter real mode
|
||||
|
||||
movb $0x48, %ah # subfunction
|
||||
int $0x13
|
||||
setc %bl
|
||||
|
||||
data32
|
||||
call _C_LABEL(real_to_prot) # back to protected mode
|
||||
|
||||
xorl %eax, %eax
|
||||
movb %bl, %al # return value in %ax
|
||||
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %edx
|
||||
pop %ecx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
ret
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: biosdisk.c,v 1.10 1999/01/27 20:54:57 thorpej Exp $ */
|
||||
/* $NetBSD: biosdisk.c,v 1.11 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 1998
|
||||
|
@ -169,7 +169,7 @@ biosdiskopen(struct open_file *f, ...)
|
|||
}
|
||||
va_start(ap, f);
|
||||
d->ll.dev = va_arg(ap, int);
|
||||
if (set_geometry(&d->ll)) {
|
||||
if (set_geometry(&d->ll, NULL)) {
|
||||
#ifdef DISK_DEBUG
|
||||
printf("no geometry information\n");
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: biosdisk_ll.c,v 1.5 1998/10/15 15:28:22 ws Exp $ */
|
||||
/* $NetBSD: biosdisk_ll.c,v 1.6 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -47,7 +47,8 @@
|
|||
|
||||
extern long ourseg;
|
||||
|
||||
extern int get_diskinfo __P((int));
|
||||
extern void get_diskinfo __P((struct biosdisk_ll *));
|
||||
extern void int13_getextinfo __P((int, struct biosdisk_ext13info *));
|
||||
extern int int13_extension __P((int));
|
||||
extern int biosread __P((int, int, int, int, int, char *));
|
||||
extern int biosextread __P((int, void *));
|
||||
|
@ -55,30 +56,33 @@ static int do_read __P((struct biosdisk_ll *, int, int, char *));
|
|||
|
||||
#define SPT(di) ((di)&0xff)
|
||||
#define HEADS(di) ((((di)>>8)&0xff)+1)
|
||||
#define CYL(di)
|
||||
|
||||
#ifndef BIOSDISK_RETRIES
|
||||
#define BIOSDISK_RETRIES 5
|
||||
#endif
|
||||
|
||||
int
|
||||
set_geometry(d)
|
||||
set_geometry(d, ed)
|
||||
struct biosdisk_ll *d;
|
||||
struct biosdisk_ext13info *ed;
|
||||
{
|
||||
int diskinfo;
|
||||
d->sec = d->head = 0;
|
||||
|
||||
diskinfo = get_diskinfo(d->dev);
|
||||
get_diskinfo(d);
|
||||
|
||||
d->flags = 0;
|
||||
if ((d->dev&0x80) && int13_extension(d->dev))
|
||||
if ((d->dev&0x80) && int13_extension(d->dev)) {
|
||||
d->flags |= BIOSDISK_EXT13;
|
||||
|
||||
d->spc = (d->spt = SPT(diskinfo)) * HEADS(diskinfo);
|
||||
if (ed != NULL)
|
||||
int13_getextinfo(d->dev, ed);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_diskinfo assumes floppy if BIOS call fails. Check at least
|
||||
* "valid" geometry.
|
||||
*/
|
||||
return (!d->spc || !d->spt);
|
||||
return (!d->sec || !d->head || !d->cyl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -97,7 +101,7 @@ do_read(d, dblk, num, buf)
|
|||
int dblk, num;
|
||||
char *buf;
|
||||
{
|
||||
int cyl, head, sec, nsec;
|
||||
int cyl, head, sec, nsec, spc;
|
||||
struct {
|
||||
int8_t size;
|
||||
int8_t resvd;
|
||||
|
@ -120,11 +124,11 @@ do_read(d, dblk, num, buf)
|
|||
|
||||
return ext.cnt;
|
||||
} else {
|
||||
|
||||
cyl = dblk / d->spc;
|
||||
head = (dblk % d->spc) / d->spt;
|
||||
sec = dblk % d->spt;
|
||||
nsec = d->spt - sec;
|
||||
spc = (d->head + 1) * d->sec;
|
||||
cyl = dblk / spc;
|
||||
head = (dblk % spc) / d->sec;
|
||||
sec = dblk % d->sec;
|
||||
nsec = d->sec - sec;
|
||||
|
||||
if (nsec > num)
|
||||
nsec = num;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: biosdisk_ll.h,v 1.3 1998/10/15 15:28:22 ws Exp $ */
|
||||
/* $NetBSD: biosdisk_ll.h,v 1.4 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -40,14 +40,41 @@
|
|||
* parts from bios_disk.S
|
||||
*/
|
||||
|
||||
/*
|
||||
* Beware that bios_disk.S relies on the offsets of the structure
|
||||
* members.
|
||||
*/
|
||||
struct biosdisk_ll {
|
||||
int dev; /* BIOS device number */
|
||||
int spt, spc; /* geometry */
|
||||
int sec, head, cyl; /* geometry */
|
||||
int flags; /* see below */
|
||||
};
|
||||
#define BIOSDISK_EXT13 1 /* BIOS supports int13 extension */
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Version 1.x drive parameters from int13 extensions. Should be supported
|
||||
* by every BIOS that supports the extensions.
|
||||
*/
|
||||
|
||||
struct biosdisk_ext13info {
|
||||
u_int16_t size; /* size of buffer, set on call */
|
||||
u_int16_t flags; /* flags, see below */
|
||||
u_int32_t cyl; /* # of physical cylinders */
|
||||
u_int32_t head; /* # of physical heads */
|
||||
u_int32_t sec; /* # of physical sectors per track */
|
||||
u_int64_t totsec; /* total number of sectors */
|
||||
u_int16_t sbytes; /* # of bytes per sector */
|
||||
} __attribute__((packed));
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ < 7
|
||||
#pragma pack(4)
|
||||
#endif
|
||||
|
||||
#define BIOSDISK_SECSIZE 512
|
||||
|
||||
int set_geometry __P((struct biosdisk_ll *));
|
||||
int set_geometry __P((struct biosdisk_ll *, struct biosdisk_ext13info *));
|
||||
int readsects __P((struct biosdisk_ll *, int, int, char *, int));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bootinfo.h,v 1.2 1997/09/20 12:10:06 drochner Exp $ */
|
||||
/* $NetBSD: bootinfo.h,v 1.3 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997
|
||||
|
@ -39,6 +39,8 @@ struct bootinfo {
|
|||
physaddr_t entry[1];
|
||||
};
|
||||
|
||||
#define BI_NHD 16
|
||||
|
||||
extern struct bootinfo *bootinfo;
|
||||
|
||||
#define BI_ALLOC(max) (bootinfo = alloc(sizeof(struct bootinfo) \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bootinfo_biosgeom.c,v 1.3 1999/01/28 20:22:31 christos Exp $ */
|
||||
/* $NetBSD: bootinfo_biosgeom.c,v 1.4 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997
|
||||
|
@ -44,37 +44,61 @@
|
|||
|
||||
void bi_getbiosgeom()
|
||||
{
|
||||
unsigned char nhd;
|
||||
struct btinfo_biosgeom *bibg;
|
||||
int i;
|
||||
int i, j, nhd, nvalid;
|
||||
unsigned int cksum;
|
||||
|
||||
pvbcopy((void *)(0x400 + 0x75), &nhd, 1); /* from BIOS data area */
|
||||
if(nhd == 0 || nhd > 4 /* ??? */ )
|
||||
return;
|
||||
pvbcopy((void *)(0x400 + 0x75), &nhd, 1);
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("nhd %d\n", nhd);
|
||||
#endif
|
||||
|
||||
bibg = alloc(sizeof(struct btinfo_biosgeom)
|
||||
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry));
|
||||
if(!bibg) return;
|
||||
if (!bibg)
|
||||
return;
|
||||
|
||||
bibg->num = nhd;
|
||||
|
||||
for(i = 0; i < nhd; i++) {
|
||||
for (i = nvalid = 0; i < BI_NHD && nvalid < nhd; i++) {
|
||||
struct biosdisk_ll d;
|
||||
struct biosdisk_ext13info ed;
|
||||
char buf[BIOSDISK_SECSIZE];
|
||||
|
||||
d.dev = 0x80 + i;
|
||||
set_geometry(&d);
|
||||
bibg->disk[i].spc = d.spc;
|
||||
bibg->disk[i].spt = d.spt;
|
||||
|
||||
bzero(bibg->disk[i].dosparts,
|
||||
sizeof(bibg->disk[i].dosparts));
|
||||
if(readsects(&d, 0, 1, buf, 0))
|
||||
if (set_geometry(&d, &ed))
|
||||
continue;
|
||||
bzero(&bibg->disk[nvalid], sizeof(bibg->disk[nvalid]));
|
||||
|
||||
bibg->disk[nvalid].sec = d.sec;
|
||||
bibg->disk[nvalid].head = d.head + 1;
|
||||
bibg->disk[nvalid].cyl = d.cyl + 1;
|
||||
bibg->disk[nvalid].dev = d.dev;
|
||||
|
||||
if (readsects(&d, 0, 1, buf, 0)) {
|
||||
bibg->disk[nvalid].flags |= BI_GEOM_INVALID;
|
||||
nvalid++;
|
||||
continue;
|
||||
bcopy(&buf[MBR_PARTOFF], bibg->disk[i].dosparts,
|
||||
sizeof(bibg->disk[i].dosparts));
|
||||
}
|
||||
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("#%d: %x: C %d H %d S %d\n", nvalid,
|
||||
d.dev, d.cyl, d.head, d.sec);
|
||||
#endif
|
||||
|
||||
if (d.flags & BIOSDISK_EXT13) {
|
||||
bibg->disk[nvalid].totsec = ed.totsec;
|
||||
bibg->disk[nvalid].flags |= BI_GEOM_EXTINT13;
|
||||
}
|
||||
for (j = 0, cksum = 0; j < BIOSDISK_SECSIZE; j++)
|
||||
cksum += buf[j];
|
||||
bibg->disk[nvalid].cksum = cksum;
|
||||
bcopy(&buf[MBR_PARTOFF], bibg->disk[nvalid].dosparts,
|
||||
sizeof(bibg->disk[nvalid].dosparts));
|
||||
nvalid++;
|
||||
}
|
||||
|
||||
bibg->num = nvalid;
|
||||
|
||||
BI_ADD(bibg, BTINFO_BIOSGEOM, sizeof(struct btinfo_biosgeom)
|
||||
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry));
|
||||
+ nvalid * sizeof(struct bi_biosgeom_entry));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bootsectmain.c,v 1.1.1.1 1997/03/14 02:40:34 perry Exp $ */
|
||||
/* $NetBSD: bootsectmain.c,v 1.2 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -62,7 +62,8 @@ int biosdev;
|
|||
* load sectors from bootdev
|
||||
*/
|
||||
d.dev = biosdev;
|
||||
set_geometry(&d);
|
||||
set_geometry(&d, NULL);
|
||||
|
||||
|
||||
buf = (char*)(PRIM_LOADSZ * BIOSDISK_SECSIZE);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: start_bootsect.S,v 1.9 1999/01/29 18:45:12 christos Exp $ */
|
||||
/* $NetBSD: start_bootsect.S,v 1.10 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* BIOS bootsector startup
|
||||
|
@ -146,6 +146,7 @@ hd: /**** load sector 0 (DOSBBSECTOR) into the BOOTSEG ****/
|
|||
data32
|
||||
jb read_error
|
||||
|
||||
|
||||
/***# find the first NetBSD partition *****/
|
||||
data32
|
||||
movl $PARTSTART, %ebx
|
||||
|
@ -234,6 +235,7 @@ found:
|
|||
* 4: segment:offset of buffer
|
||||
* 8: block number (8 bytes)
|
||||
*/
|
||||
|
||||
pushl %ss
|
||||
popl %ds
|
||||
data32
|
||||
|
@ -257,6 +259,7 @@ found:
|
|||
popl %ds /* but reestablish %ds */
|
||||
data32
|
||||
jb read_error
|
||||
|
||||
data32
|
||||
jmp to_boot2
|
||||
|
||||
|
@ -288,6 +291,7 @@ load:
|
|||
jb read_error
|
||||
|
||||
to_boot2:
|
||||
|
||||
# ljmp to the second stage boot loader (boot2).
|
||||
# After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
|
||||
# as an internal buffer "intbuf".
|
||||
|
@ -352,6 +356,7 @@ done:
|
|||
|
||||
eread: .asciz "Read error\r\n"
|
||||
enoboot: .asciz "No bootable partition\r\n"
|
||||
efail: .asciz "Boot failed, system halted\r\n"
|
||||
|
||||
/* throw in a partition in case we are block0 as well */
|
||||
/* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
|
||||
|
@ -462,6 +467,11 @@ _C_LABEL(boot2):
|
|||
pushl %edx
|
||||
call _C_LABEL(bootsectmain)
|
||||
ENTRY(exit)
|
||||
call _C_LABEL(prot_to_real)
|
||||
data32
|
||||
movl $efail, %esi
|
||||
data32
|
||||
call message
|
||||
cli
|
||||
hlt
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: exec.c,v 1.8 1999/01/29 18:49:08 christos Exp $ */
|
||||
/* $NetBSD: exec.c,v 1.9 1999/03/08 00:09:25 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
|
@ -112,6 +112,10 @@ exec_netbsd(file, loadaddr, boothowto)
|
|||
|
||||
BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
|
||||
|
||||
#ifdef PASS_BIOSGEOM
|
||||
bi_getbiosgeom();
|
||||
#endif
|
||||
|
||||
extmem = getextmem();
|
||||
|
||||
#ifdef XMS
|
||||
|
@ -194,9 +198,6 @@ exec_netbsd(file, loadaddr, boothowto)
|
|||
boot_argv[4] = extmem;
|
||||
boot_argv[5] = getbasemem();
|
||||
|
||||
#ifdef PASS_BIOSGEOM
|
||||
bi_getbiosgeom();
|
||||
#endif
|
||||
close(fd);
|
||||
|
||||
#ifdef XMS
|
||||
|
|
Loading…
Reference in New Issue