2004-06-01 15:11:45

by Patrick J. LoPresti

[permalink] [raw]
Subject: Re: 2.6.x partition breakage and dual booting

Sean Estabrooks <[email protected]> writes:

> Just don't alter partition table entries of non Linux partitions?

I have not been very clear, so let me try once more.

Yes, using the existing partition table geometry will work if you
install Windows before you install Linux. But it will fail if you do
things the other way around.

I am suggesting an approach which will work either way; namely,
determine the Windows-compatible geometry and use it.

The Windows-compatible geometry is the one reported by the "legacy
INT13 BIOS interface"; i.e., INT13/AH=08h.

Because this legacy BIOS interface can only be invoked from real mode,
Linux 2.2.x and 2.4.x tried to infer the legacy geometry by parsing
CMOS tables. This did not always work, both because the tables are
poorly specified and buggy and vendor-specific, and because it
requires mapping between BIOS disk numbers and Linux devices, which is
tricky. So the old code was gutted for 2.6.x, and now the kernel
simply reports the geometry as reported by the disk controller.
(Linux itself does not care about the geometry, because it does
everything in "linear" mode.)

This means partitions created under Linux are incompatible with
Windows, unless you get lucky and your BIOS uses (or can be configured
to use) the geometry reported by the controller.

Now, starting with 2.6.5 Linux actually invokes INT13/AH=08h during
real-mode startup and stashes the values away. They are available via
Dell's EDD module. So, to find the Windows-compatible geometry, you
simply:

modprobe edd
cat /sys/firmware/edd/int13_dev80/{legacy_heads,legacy_sectors}

(And add 1 to the "heads" value because the legacy BIOS interface is
freaky.)

There is just one catch. This assumes BIOS device 80h (the boot
device) is the disk you care about. If not, you need to figure out
which BIOS device corresponds to the disk you do care about. This is
the hard part, but it is not THAT hard, because the /sys/firmware/edd
interface exposes lots of information which will help you deduce this
correspondence. It exports the extended (controller) geometry, the
disk size, and the MBR signature (see
http://seclists.org/lists/linux-kernel/2004/Jan/5257.html). For a
sufficiently modern (EDD 3.0) BIOS, it will even include the exact
information (PCI device etc.) identifying the disk.

This is not surprising, because the EDD module was specifically
designed with this mapping goal in mind; one of Dell's interests is
automatically finding the boot disk on systems with lots of drives.

So, if we write a decent library routine to map between BIOS device
numbers and Linux devices, then we will be finished, and everything
will work fine no matter which OS the user installs first.

- Pat


2004-06-01 23:56:27

by Andries E. Brouwer

[permalink] [raw]
Subject: Re: 2.6.x partition breakage and dual booting

On Tue, Jun 01, 2004 at 11:10:27AM -0400, Patrick J. LoPresti wrote:

> Now, starting with 2.6.5 Linux actually invokes INT13/AH=08h during
> real-mode startup and stashes the values away. They are available via
> Dell's EDD module. So, to find the Windows-compatible geometry, you
> simply:
>
> modprobe edd
> cat /sys/firmware/edd/int13_dev80/{legacy_heads,legacy_sectors}
>
> (And add 1 to the "heads" value because the legacy BIOS interface is
> freaky.)

Now that we are discussing this stuff anyway:
The names chosen are really bad, they are an invitation for
confusion and bugs.

We have "sectors" and it gives a count of sectors, like 0x7280b80
(yecch - why in hex??).
But "legacy_sectors" is not a number of sectors, but a number of
sectors per track, just like "default_sectors_per_track".

We have "default_heads" and it is a number of heads, like 0xff
(yecch - why in hex??).
But "legacy_heads" is not a number of heads, it is the largest
head number, that is, one less than the number of heads.

Please, now that this is still unused, fix your names and/or
your code. Names could be legacy_max_head (etc.) if you want
to keep the values, or otherwise add 1 to the values.

Note that sectors are counted from 1 here, so by some coincidence
legacy_max_sectors_per_track is the same as legacy_sectors_per_track.

Also - people will try to match the 0x7280b80 for int13_dev83 with
the 120064896 sectors that dmesg or hdparm -g reports for /dev/hdf.
Life would be easier with values given in decimal, as they are
everywhere else.

Andries


> There is just one catch. This assumes BIOS device 80h (the boot
> device) is the disk you care about. If not, you need to figure out
> which BIOS device corresponds to the disk you do care about. This is
> the hard part, but it is not THAT hard, because the /sys/firmware/edd
> interface exposes lots of information which will help you deduce this
> correspondence.

It is basically impossible, but it is easy to give heuristics
that very often work. Very good that that now is a job left
to user space.

2004-06-02 13:02:29

by Patrick J. LoPresti

[permalink] [raw]
Subject: Re: 2.6.x partition breakage and dual booting

Andries Brouwer <[email protected]> writes:

> We have "sectors" and it gives a count of sectors, like 0x7280b80
> (yecch - why in hex??).
> But "legacy_sectors" is not a number of sectors, but a number of
> sectors per track, just like "default_sectors_per_track".
>
> We have "default_heads" and it is a number of heads, like 0xff
> (yecch - why in hex??).
> But "legacy_heads" is not a number of heads, it is the largest
> head number, that is, one less than the number of heads.
>
> Please, now that this is still unused, fix your names and/or
> your code. Names could be legacy_max_head (etc.) if you want
> to keep the values, or otherwise add 1 to the values.

Well, the EDD module belongs to Matt Domsch. I only contributed the
"legacy_*" code and names.

If it is OK with Matt, I agree we should rename legacy_heads to
legacy_max_head and legacy_sectors to legacy_sectors_per_track. I
doubt anybody other than myself is using these yet anyway.

> Also - people will try to match the 0x7280b80 for int13_dev83 with
> the 120064896 sectors that dmesg or hdparm -g reports for /dev/hdf.
> Life would be easier with values given in decimal, as they are
> everywhere else.

I used hex for legacy_* because that is what all the other fields
already used. It was not my decision, and I have no opinion either
way. Convince Matt.

- Pat

2004-06-02 15:02:29

by Matt Domsch

[permalink] [raw]
Subject: Re: 2.6.x partition breakage and dual booting

On Wed, Jun 02, 2004 at 09:02:23AM -0400, Patrick J. LoPresti wrote:
> Andries Brouwer <[email protected]> writes:
> > Please, now that this is still unused, fix your names and/or
> > your code. Names could be legacy_max_head (etc.) if you want
> > to keep the values, or otherwise add 1 to the values.
>
> Well, the EDD module belongs to Matt Domsch. I only contributed the
> "legacy_*" code and names.
>
> If it is OK with Matt, I agree we should rename legacy_heads to
> legacy_max_head and legacy_sectors to legacy_sectors_per_track. I
> doubt anybody other than myself is using these yet anyway.

Yes, please submit a patch now to Andrew, cc: me and linux-kernel at
least. I've confirmed that our internal tools are not using these
fields yet.

> > Also - people will try to match the 0x7280b80 for int13_dev83 with
> > the 120064896 sectors that dmesg or hdparm -g reports for /dev/hdf.
> > Life would be easier with values given in decimal, as they are
> > everywhere else.
>
> I used hex for legacy_* because that is what all the other fields
> already used. It was not my decision, and I have no opinion either
> way. Convince Matt.

Whatever, scanf works with either representation. Patrick, if you're
changing the above, feel free to submit a second patch to switch these
all to %u instead.

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer
Dell Linux Solutions linux.dell.com & http://www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


Attachments:
(No filename) (1.46 kB)
(No filename) (189.00 B)
Download all attachments

2004-06-02 23:04:29

by Andries E. Brouwer

[permalink] [raw]
Subject: Re: [PATCH] Better names for EDD legacy_* fields

On Wed, Jun 02, 2004 at 05:22:50PM -0400, Patrick J. LoPresti wrote:

> > > > Please, now that this is still unused, fix your names and/or
> > > > your code. Names could be legacy_max_head (etc.)
>
> Trivial (search & replace) patch against 2.6.6 is attached. This
> renames legacy_heads to legacy_max_head legacy_sectors to
> legacy_sectors_per_track.

Ach - I should have been more explicit instead of saying (etc.).
Also legacy_cylinders is really legacy_max_cylinder
(one less than the number of cylinders).

Andries