* 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:
fvdl 1999-03-08 00:09:24 +00:00
parent fcfc497f58
commit f8e221511b
10 changed files with 170 additions and 59 deletions

View File

@ -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}/../../../../ S= ${.CURDIR}/../../../../
@ -20,7 +20,7 @@ CPPFLAGS+= -DCOMPAT_OLDBOOT -DCOMPAT_386BSD_MBRPART
# and maybe # and maybe
#CPPFLAGS+= -DDIRECT_SERIAL -DCOMCONS_KEYPRESS -DCONSPEED=57600 #CPPFLAGS+= -DDIRECT_SERIAL -DCOMCONS_KEYPRESS -DCONSPEED=57600
#CPPFLAGS+= -DPASS_BIOSGEOM CPPFLAGS+= -DPASS_BIOSGEOM
#uncomment if there are problems with memory detection #uncomment if there are problems with memory detection
#CPPFLAGS+= -DCONSERVATIVE_MEMDETECT #CPPFLAGS+= -DCONSERVATIVE_MEMDETECT
#increase MAXFLENTRIES if "installboot" complains about #increase MAXFLENTRIES if "installboot" complains about

View File

@ -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 * 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 # get_diskinfo(): takes a pointer to a biosdisk_ll struct, and fills it in.
# max number of sectors and heads and drives for this device
# #
*/ */
@ -129,7 +128,9 @@ ENTRY(get_diskinfo)
push %esi push %esi
push %edi 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 call _C_LABEL(prot_to_real) # enter real mode
@ -156,12 +157,20 @@ ok:
data32 data32
call _C_LABEL(real_to_prot) # back to protected mode call _C_LABEL(real_to_prot) # back to protected mode
xorl %eax, %eax popl %esi
/*form a longword representing all this gunk*/ movzbl %dh, %eax
movb %dh, %ah # max head movl %eax, 8(%esi) # heads
andb $0x3f, %cl # mask of cylinder gunk movb %cl, %al
movb %cl, %al # max sector (and # sectors) 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 %edi
pop %esi pop %esi
@ -217,7 +226,7 @@ ENTRY(int13_extension)
/* /*
# BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory # BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
# Call with %ah = 0x42 # Call with %ah = 0x42
# %ds:%di = parameter block # %ds:%si = parameter block
# %dl = drive (0x80 for hard disk, 0x0 for floppy disk) # %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
# Return: # Return:
# %al = 0x0 on success; err code on failure # %al = 0x0 on success; err code on failure
@ -253,3 +262,36 @@ ENTRY(biosextread)
popl %ebx popl %ebx
popl %ebp popl %ebp
ret 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

View File

@ -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 * Copyright (c) 1996, 1998
@ -169,7 +169,7 @@ biosdiskopen(struct open_file *f, ...)
} }
va_start(ap, f); va_start(ap, f);
d->ll.dev = va_arg(ap, int); d->ll.dev = va_arg(ap, int);
if (set_geometry(&d->ll)) { if (set_geometry(&d->ll, NULL)) {
#ifdef DISK_DEBUG #ifdef DISK_DEBUG
printf("no geometry information\n"); printf("no geometry information\n");
#endif #endif

View File

@ -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 * Copyright (c) 1996
@ -47,7 +47,8 @@
extern long ourseg; 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 int13_extension __P((int));
extern int biosread __P((int, int, int, int, int, char *)); extern int biosread __P((int, int, int, int, int, char *));
extern int biosextread __P((int, void *)); 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 SPT(di) ((di)&0xff)
#define HEADS(di) ((((di)>>8)&0xff)+1) #define HEADS(di) ((((di)>>8)&0xff)+1)
#define CYL(di)
#ifndef BIOSDISK_RETRIES #ifndef BIOSDISK_RETRIES
#define BIOSDISK_RETRIES 5 #define BIOSDISK_RETRIES 5
#endif #endif
int int
set_geometry(d) set_geometry(d, ed)
struct biosdisk_ll *d; 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; d->flags = 0;
if ((d->dev&0x80) && int13_extension(d->dev)) if ((d->dev&0x80) && int13_extension(d->dev)) {
d->flags |= BIOSDISK_EXT13; d->flags |= BIOSDISK_EXT13;
if (ed != NULL)
d->spc = (d->spt = SPT(diskinfo)) * HEADS(diskinfo); int13_getextinfo(d->dev, ed);
}
/* /*
* get_diskinfo assumes floppy if BIOS call fails. Check at least * get_diskinfo assumes floppy if BIOS call fails. Check at least
* "valid" geometry. * "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; int dblk, num;
char *buf; char *buf;
{ {
int cyl, head, sec, nsec; int cyl, head, sec, nsec, spc;
struct { struct {
int8_t size; int8_t size;
int8_t resvd; int8_t resvd;
@ -120,11 +124,11 @@ do_read(d, dblk, num, buf)
return ext.cnt; return ext.cnt;
} else { } else {
spc = (d->head + 1) * d->sec;
cyl = dblk / d->spc; cyl = dblk / spc;
head = (dblk % d->spc) / d->spt; head = (dblk % spc) / d->sec;
sec = dblk % d->spt; sec = dblk % d->sec;
nsec = d->spt - sec; nsec = d->sec - sec;
if (nsec > num) if (nsec > num)
nsec = num; nsec = num;

View File

@ -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 * Copyright (c) 1996
@ -40,14 +40,41 @@
* parts from bios_disk.S * parts from bios_disk.S
*/ */
/*
* Beware that bios_disk.S relies on the offsets of the structure
* members.
*/
struct biosdisk_ll { struct biosdisk_ll {
int dev; /* BIOS device number */ int dev; /* BIOS device number */
int spt, spc; /* geometry */ int sec, head, cyl; /* geometry */
int flags; /* see below */ int flags; /* see below */
}; };
#define BIOSDISK_EXT13 1 /* BIOS supports int13 extension */ #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 #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)); int readsects __P((struct biosdisk_ll *, int, int, char *, int));

View File

@ -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 * Copyright (c) 1997
@ -39,6 +39,8 @@ struct bootinfo {
physaddr_t entry[1]; physaddr_t entry[1];
}; };
#define BI_NHD 16
extern struct bootinfo *bootinfo; extern struct bootinfo *bootinfo;
#define BI_ALLOC(max) (bootinfo = alloc(sizeof(struct bootinfo) \ #define BI_ALLOC(max) (bootinfo = alloc(sizeof(struct bootinfo) \

View File

@ -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 * Copyright (c) 1997
@ -44,37 +44,61 @@
void bi_getbiosgeom() void bi_getbiosgeom()
{ {
unsigned char nhd;
struct btinfo_biosgeom *bibg; struct btinfo_biosgeom *bibg;
int i; int i, j, nhd, nvalid;
unsigned int cksum;
pvbcopy((void *)(0x400 + 0x75), &nhd, 1); /* from BIOS data area */ pvbcopy((void *)(0x400 + 0x75), &nhd, 1);
if(nhd == 0 || nhd > 4 /* ??? */ ) #ifdef GEOM_DEBUG
return; printf("nhd %d\n", nhd);
#endif
bibg = alloc(sizeof(struct btinfo_biosgeom) bibg = alloc(sizeof(struct btinfo_biosgeom)
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry)); + (nhd - 1) * sizeof(struct bi_biosgeom_entry));
if(!bibg) return; if (!bibg)
return;
bibg->num = nhd; for (i = nvalid = 0; i < BI_NHD && nvalid < nhd; i++) {
for(i = 0; i < nhd; i++) {
struct biosdisk_ll d; struct biosdisk_ll d;
struct biosdisk_ext13info ed;
char buf[BIOSDISK_SECSIZE]; char buf[BIOSDISK_SECSIZE];
d.dev = 0x80 + i; d.dev = 0x80 + i;
set_geometry(&d);
bibg->disk[i].spc = d.spc;
bibg->disk[i].spt = d.spt;
bzero(bibg->disk[i].dosparts, if (set_geometry(&d, &ed))
sizeof(bibg->disk[i].dosparts)); continue;
if(readsects(&d, 0, 1, buf, 0)) 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; 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) BI_ADD(bibg, BTINFO_BIOSGEOM, sizeof(struct btinfo_biosgeom)
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry)); + nvalid * sizeof(struct bi_biosgeom_entry));
} }

View File

@ -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 * Copyright (c) 1996
@ -62,7 +62,8 @@ int biosdev;
* load sectors from bootdev * load sectors from bootdev
*/ */
d.dev = biosdev; d.dev = biosdev;
set_geometry(&d); set_geometry(&d, NULL);
buf = (char*)(PRIM_LOADSZ * BIOSDISK_SECSIZE); buf = (char*)(PRIM_LOADSZ * BIOSDISK_SECSIZE);

View File

@ -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 * BIOS bootsector startup
@ -146,6 +146,7 @@ hd: /**** load sector 0 (DOSBBSECTOR) into the BOOTSEG ****/
data32 data32
jb read_error jb read_error
/***# find the first NetBSD partition *****/ /***# find the first NetBSD partition *****/
data32 data32
movl $PARTSTART, %ebx movl $PARTSTART, %ebx
@ -234,6 +235,7 @@ found:
* 4: segment:offset of buffer * 4: segment:offset of buffer
* 8: block number (8 bytes) * 8: block number (8 bytes)
*/ */
pushl %ss pushl %ss
popl %ds popl %ds
data32 data32
@ -257,6 +259,7 @@ found:
popl %ds /* but reestablish %ds */ popl %ds /* but reestablish %ds */
data32 data32
jb read_error jb read_error
data32 data32
jmp to_boot2 jmp to_boot2
@ -288,6 +291,7 @@ load:
jb read_error jb read_error
to_boot2: to_boot2:
# ljmp to the second stage boot loader (boot2). # ljmp to the second stage boot loader (boot2).
# After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used # After ljmp, %cs is BOOTSEG and boot1 (512 bytes) will be used
# as an internal buffer "intbuf". # as an internal buffer "intbuf".
@ -352,6 +356,7 @@ done:
eread: .asciz "Read error\r\n" eread: .asciz "Read error\r\n"
enoboot: .asciz "No bootable partition\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 */ /* throw in a partition in case we are block0 as well */
/* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */ /* flag, head, sec, cyl, typ, ehead, esect, ecyl, start, len */
@ -462,6 +467,11 @@ _C_LABEL(boot2):
pushl %edx pushl %edx
call _C_LABEL(bootsectmain) call _C_LABEL(bootsectmain)
ENTRY(exit) ENTRY(exit)
call _C_LABEL(prot_to_real)
data32
movl $efail, %esi
data32
call message
cli cli
hlt hlt

View File

@ -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 * 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)); BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
#ifdef PASS_BIOSGEOM
bi_getbiosgeom();
#endif
extmem = getextmem(); extmem = getextmem();
#ifdef XMS #ifdef XMS
@ -194,9 +198,6 @@ exec_netbsd(file, loadaddr, boothowto)
boot_argv[4] = extmem; boot_argv[4] = extmem;
boot_argv[5] = getbasemem(); boot_argv[5] = getbasemem();
#ifdef PASS_BIOSGEOM
bi_getbiosgeom();
#endif
close(fd); close(fd);
#ifdef XMS #ifdef XMS