Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: LBA vs CHS?



>> [...] it appears that the BIOS call it's using, int 0x13 function 2,
>> is ignoring the cylinder number.
> I don't know about it ignoring the cylinder number, but int 13h
> function 02h is limited to approximately 8GB (1024 cyl * 256 heads *
> 63 sectors * 512 bytes), so I'd expect the boot code to use int 13h
> function 42h for larger disks. I see a biosdisk_extread routine in
> [bios-disk.s] so the code exists in 5.2.

It does.  My debugging code produces different output for
biosdisk_extread and biosdisk_read, though, which is why I said it's
using function 2:

diff --git a/sys/arch/i386/stand/lib/biosdisk_ll.c b/sys/arch/i386/stand/lib/biosdisk_ll.c
index 6d26d86..55d2e6e 100644
--- a/sys/arch/i386/stand/lib/biosdisk_ll.c
+++ b/sys/arch/i386/stand/lib/biosdisk_ll.c
@@ -177,10 +177,30 @@ static int      ra_first;
 	  ((dblk) + (num)) >= (d)->chs_sectors))
 #endif
 
+extern void savec(char);
+extern void hex(unsigned long long int, int);
+extern void hexdump(const void *, int);
+extern void putstr(const char *);
+
 static int
 do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
 {
-
+ static int g_head = 0;
+ static int g_sec = 0;
+
+if ((d->head != g_head) || (d->sec != g_sec))
+ { g_head = d->head;
+   g_sec = d->sec;
+   savec('G');
+   savec('=');
+   savec('H');
+   hex(g_head,-1);
+   savec('S');
+   hex(g_sec,-1);
+   savec('.');
+ }
+savec('[');
+hex(dblk,-1);
 	if (NEED_INT13EXT(d, dblk, num)) {
 		struct {
 			int8_t size;
@@ -190,7 +210,6 @@ do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
 			int16_t seg;
 			int64_t sec;
 		} ext;
-
 		if (!(d->flags & BIOSDISK_INT13EXT))
 			return -1;
 		ext.size = sizeof(ext);
@@ -201,11 +220,24 @@ do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
 		ext.seg = vtophys(buf) >> 4;
 		ext.sec = dblk;
 
+savec('x');
+hex(ext.size,-1);
+savec('.');
+hex(ext.cnt,-1);
+savec('.');
+hex(ext.off,-1);
+savec('.');
+hex(ext.seg,-1);
+savec('.');
+hex(ext.sec,-1);
 		if (biosdisk_extread(d->dev, &ext)) {
 			(void)biosdisk_reset(d->dev);
 			return -1;
 		}
 
+savec('=');
+hex(ext.cnt,-1);
+savec(']');
 		return ext.cnt;
 	} else {
 		int cyl, head, sec, nsec, spc, dblk32;
@@ -220,11 +252,24 @@ do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
 		if (nsec > num)
 			nsec = num;
 
+savec('n');
+hex(cyl,-1);
+savec('.');
+hex(head,-1);
+savec('.');
+hex(sec,-1);
+savec('.');
+hex(nsec,-1);
+savec('>');
+hex((unsigned int)buf,-1);
 		if (biosdisk_read(d->dev, cyl, head, sec, nsec, buf)) {
 			(void)biosdisk_reset(d->dev);
 			return -1;
 		}
 
+savec('=');
+hex(nsec,-1);
+savec(']');
 		return nsec;
 	}
 }

(the savec name is a historical artifact).

> Although I'd also expect function 2 to work for reading below the
> 1024 cylinder limit (such as your example of cyl 1 head 4 sec 19).

I would too.  That's (part of) why I'm so puzzled by this.

There are two real puzzles for me.  One is why the geometry as seen by
bootxx_ffsv1 (256 heads) is so different from the geometry as seen by
the kernel (16 heads); the other is why the cylinder number is getting
ignored when reading.

> I ran NetBSD on a Soekris net4501, but with an 8GB CF card. I never
> had any problems with it booting, but I don't know if it ever had to
> load anything from other than cyl 0.  However, it seems likely that
> it would have... one cylinder is only about 8MB, right?

About, yes: 256*63 sectors of 512 bytes each, which is 8064K.

The BIOS version could also be relevant; after all, both of those
puzzles are directly related to BIOS calls.  I've got

comBIOS ver. 1.33  20080103  Copyright (C) 2000-2007 Soekris Engineering.

Your use of the past tense leads me to suspect you no longer have your
net4501, though, or at least no longer have it live, so it wouldn't
surprise me if you don't have your BIOS version readily available.

I'll see if Soekris still exists enough to offer any thoughts on this.

> It seems unlikely that the kernel would have always been on the first
> 8MB of the card.

True, especially since 8M isn't big enough to hold more than one kernel
(at least for the 5.2 I'm using; my 1.4T i386 machine's kernels are
under 3.5M, but even then it'd hold at most two kernels).  This is why
I don't just use a tiny boot-and-kernel partition with root elsewhere
(I do that often enough on other machines, but I've never run into a
case where I'd want the boot partition to be this tiny).

It would in theory be possible to have a boot partition that holds
bootxx_ffsv1 and /boot and nothing else, entirely below the 8064K
point, with /boot containing its own wdc/wd driver that knows how to
use LBA.  But that would be a relatively radical departure from how
/boot works at present (in 5.2; I haven't checked -current).

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse%rodents-montreal.org@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Home | Main Index | Thread Index | Old Index