Page MenuHomeFreeBSD

Add support for legacy 512-byte block size MBRs on 4K block size disks
Needs ReviewPublic

Authored by hselasky on Feb 19 2019, 10:18 AM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Nov 26, 2:55 AM
Unknown Object (File)
Sat, Nov 16, 9:55 PM
Unknown Object (File)
Tue, Nov 12, 4:44 AM
Unknown Object (File)
Nov 5 2024, 9:50 AM
Unknown Object (File)
Oct 31 2024, 8:13 AM
Unknown Object (File)
Oct 28 2024, 8:09 AM
Unknown Object (File)
Oct 2 2024, 9:09 PM
Unknown Object (File)
Sep 30 2024, 9:28 AM
Subscribers

Details

Reviewers
imp
phk
cem
Summary

When using MBRs for booting on a 4K block size disk, the BIOS should emulate 512 byte block size for the disk.
In order for the operating system to understand such MBRs a new SYSCTL has been added, kern.geom.part.mbr.enforce_512bbs, which basically translate the MBR partition offsets and sizes accordingly. This option works for both reading and writing MBRs.

This option allows FreeBSD to boot on an intel based MAC with 4K block size SSDs.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

hselasky edited the summary of this revision. (Show Details)
cem added inline comments.
sys/geom/geom_io.c
958–959

It seems a bit dubious to transparently RMW all GEOM IOs? Granted, nothing previously enforced length % cp->provider->sectorsize == 0.

sys/geom/part/g_part_bsd.c
51

s/512/DEV_BSIZE/ ?

Won't this universally be 512 (disklabel is only ~270 bytes)? You could instead _Static_assert(sizeof(disklabel) <= DEV_BSIZE).

64–67

It seems like this should be a property of a GEOM_PART_BSD rather than a global sysctl.

404

I would suggest doing a native sector read here and just referencing the desired portion instead.

sys/geom/part/g_part_mbr.c
63–66

Same suggestion as for GEOM_PART_BSD (property of the geom instance, not a global sysctl).

398

Set but not used variable?

640

I'd move the read-modify-write of the non-native 512 byte sub-sector out to here (or a RMW-specific subroutine).

I'm not sure I understand the point of this. No matter what the GEOM is doing, the BIOS INT call interface doesn't support 4KB sectors...?

I'm not sure I understand the point of this. No matter what the GEOM is doing, the BIOS INT call interface doesn't support 4KB sectors...?

The point is that GEOM will use 4KB based LBA addresses as a basis when setting up the MBR and BSD tables, while the loaders and boot code think those addresses and lengths are 512 byte based. This causes the wrong disk locations to be used and so the loader eventually crashes failing the get into kernel mode.

Yes, BIOS INT call will treat the 4KB device like if it was 512 byte based and hide the fact we are using multiples of 4KB disk access. This was observed by at least Apple's BIOS.

Yes, BIOS INT call will treat the 4KB device like if it was 512 byte based and hide the fact we are using multiples of 4KB disk access. This was observed by at least Apple's BIOS.

That might be something unique to Apple's CSM then. I've used the CSM which is part of the AMI UEFI implementation (branded "Aptio"), and it has never performed firmware-level 512b emulation -- AF-4Kn drives were unbootable, period.

hselasky added inline comments.
sys/geom/part/g_part_bsd.c
64–67

@phk : Can you help with this?

404

It becomes quite more code. I'd rather have this factored out.

sys/geom/part/g_part_mbr.c
640

I was thinking these routines were not that frequently used, that it doesn't matter?

Yes, BIOS INT call will treat the 4KB device like if it was 512 byte based and hide the fact we are using multiples of 4KB disk access. This was observed by at least Apple's BIOS.

That might be something unique to Apple's CSM then. I've used the CSM which is part of the AMI UEFI implementation (branded "Aptio"), and it has never performed firmware-level 512b emulation -- AF-4Kn drives were unbootable, period.

I did not manage to boot in UEFI mode on Apple. Only the regular BIOS mode works for me.

cem requested changes to this revision.Feb 20 2019, 11:33 PM
cem added inline comments.
sys/geom/part/g_part_bsd.c
64–67

For an example of how this might be done, check out g_part_ctlreq. That might set some flag on the partition via modify. It is plumbed through individual g_parts via the G_PART_MODIFY op. Something like that.

You could always inject it via ioctl (g_part_ioctl), but that is usually uglier.

404

It seems like it would add 2-3 lines, no?

sys/geom/part/g_part_mbr.c
640

They're used by ~64 different GEOM modules, none of which had potential RMW semantics before this change. I think this in particular is a blocking issue. (Also easy to overcome.)

This revision now requires changes to proceed.Feb 20 2019, 11:33 PM
sys/geom/part/g_part_bsd.c
64–67

How can I have system read support for such partitions then? It is not only about writing those partitions, but also about reading them during boot.

sys/geom/part/g_part_bsd.c
64–67

The property can either be explicitly encoded as a flag or other on-disk record, or be inferred at probe by the condition table->sectorsize == 512 && pp->sectorsize != table->sectorsize.

(The ugly style of this geom makes it difficult to determine the on-disk structure, but if you don't find a better place, there seems to be plenty of room for flags in e.g., gpt_entries, which gets 16 bits on disk but has a hardcoded maximal value of 20 decimal.)

I think there may be some benefit to inferring the property rather than requiring the explicit flag; e.g., 512 disk images splatted directly onto 4Kn disks.

Rebase patch on top of 13-stable, in case someone wants it.