systemd / systemd

The systemd System and Service Manager
https://systemd.io
GNU General Public License v2.0
13.27k stars 3.8k forks source link

repart: Support booting via CD-ROM #28798

Open DaanDeMeyer opened 1 year ago

DaanDeMeyer commented 1 year ago

Component

systemd-repart

Is your feature request related to a problem? Please describe

No response

Describe the solution you'd like

We should make sure repart generated images can boot from CD-ROM. This is generally done via ISO9660 with El Torito boot records. If I understand correctly, we don't even need to use the ISO filesystem itself, all we need is a boot record volume descriptor pointing to a boot catalog with a single entry pointing to the EFI partition. ISO9660 starts at 16 sectors into the image, which means this extra data shouldn't conflict with the partition table.

Aside from that, we just need to make sure the CD-ROM is properly treated as a block device (which I think we already do) and things "should just work".

Describe alternatives you've considered

No response

The systemd version you checked that didn't have the feature you are asking for

No response

bluca commented 1 year ago

lol I realized I don't even have a cdrom drive anywhere to test this :-D

poettering commented 1 year ago

fuck me. i thought uefi booting from cdrom was exactly the same as from a regular block device. i thought eltorrito and that crap was a pre-uefi thing. apparently i am wrong. gah.

yeah, we probably should support this, and maybe just make the default. though not sure how well that will work given that cds have a sector size of 2k iirc

https://wiki.osdev.org/El-Torito

AdrianVovk commented 1 year ago

Read a bit of the UEFI spec. By the sounds of it, we don't really need to do anything special. i.e. UEFI firmware should be able to read a GPT partition table off of the boot medium and boot it. In fact, my understanding is that UEFI will completely ignore the El Torito boot record if the disk has a GPT partition table

DaanDeMeyer commented 1 year ago

Yes I realized this as well, there's no point to this except for on BIOS I guess.

AdrianVovk commented 1 year ago

Gave it a quick test w/ QEMU. Passing in -cdrom path/to/ddi.img doesn't successfully boot the VM. The firmware in the VM tells me that it Failed to load Boot0001 "UEFI QEMU DVD-ROM [...]" from [...]: Not Found

GNOME Boxes straight-up crashes if I rename the DDI to ddi.iso and try to boot it. I suspect this has something to do w/ libosinfo trying to ID the iso

DaanDeMeyer commented 1 year ago

Huh that's weird I got it booting with mkosi without issues

AdrianVovk commented 1 year ago

This is before #28806? What are you passing into qemu's command line?

DaanDeMeyer commented 1 year ago

Ah, it's probably because of the sector size. Your image needs to be sector size 2048 to work as a CD-ROM. The images built by repart from latest git main can trivially be changed to a different sector size using --copy-from + --sector-size.

poettering commented 1 year ago

so, i guess we need to think about images that work on all three relevant sector sizes: old style 512bytes, 2K for cdrom and 4K for new style hdds...

GPT puts the header at sector 1 (not 0), so in theory that allows you to build an image that comes with three separate full tables, one for each sector size. but i am sure firmware might be confused if it gets to pick its preferred sector size...

DaanDeMeyer commented 1 year ago

GPT puts the header at sector 1 (not 0), so in theory that allows you to build an image that comes with three separate full tables, one for each sector size. but i am sure firmware might be confused if it gets to pick its preferred sector size...

That only works if you don't have too many partitions right? The partition entries start at LBA2, so for sector size 512, that means you have 1024-2048 for partition entries. One entry is 128 bytes so you have space for 8 partitions. For 2048, LBA2 is 4096 so if you want to support 4096 you're out of luck, no room for any partitions.

With the latest changes, it's trivial to change between sector sizes using repart. That might be the best we're going to get. Unless we start overriding the partition entries LBA in the GPT header, but AFAIK libfdisk doesn't allow that because it's recommended to use LBA 2 for compatibility.

poettering commented 1 year ago

That only works if you don't have too many partitions right? The partition entries start at LBA2, so for sector size 512, that means you have 1024-2048 for partition entries. One entry is 128 bytes so you have space for 8 partitions. For 2048, LBA2 is 4096 so if you want to support 4096 you're out of luck, no room for any partitions.

nah, you can place the actual table wherever you want and make it any size you want. the only thing with a fixed location is the main header really, everything else is specified in it, including the secondary header, and can be allocated to any place you like...

but tbh I am pretty sure plenty of sw will be very confused with such multi-sector-size partitin tables, i wouldn't even try.

My suspicion is that if you do use eltorito + gpt for uefi it gives you a way to build images that work with both 2k and 512 sector sizes. If you use gpt only then you are stuck with a single sector size. or in other words: if you avoid eltorito and just stick a regular gpt table on a cdrom, it menas the image only works on cdrom, but not otherwise. if you do the eltorito dance otoh you could do both: support both 2k and 512b in a single image.

DaanDeMeyer commented 1 year ago

My suspicion is that if you do use eltorito + gpt for uefi it gives you a way to build images that work with both 2k and 512 sector sizes. If you use gpt only then you are stuck with a single sector size. or in other words: if you avoid eltorito and just stick a regular gpt table on a cdrom, it menas the image only works on cdrom, but not otherwise. if you do the eltorito dance otoh you could do both: support both 2k and 512b in a single image.

The cd-rom will still have sector size 2k so we would have to attach it to a loop device with sector size 512 to be able to support that scheme. But theoretically it could work that way yes.

poettering commented 1 year ago

so, apparently there are people who are doing this:

  1. stick a 4k gpt table on the disk for new-style hdds
  2. stick iso9660+eltorito on the disk for booting as iso (i.e. the 2k case)
  3. stick a 512 byte mbr/msdos table on the disk for old-style hdds (i.e. partition type 0xEF allows ESP on mbr/msdos table after all)

in all cases you'd use UEFI but different logic to find the ESP: on a 4K disk it would be the obvious way, on a 2K cdrom it would be the native eltorito and on a 512 legacy disk it would be by finding the ESP as mbr/msdos table entry.

in all three cases you'd end up with a being able tun an uefi app. once you then reach linux you should be able to set the logical sector size of the block device via BLKBSZSET to 4K on the backing device to force that things are read via the 4K GPT table in all scenarios.

poettering commented 1 year ago

(maybe we should have a udev builtin helper that can be run on a block device, that then probes for a GPT partition table and automatically fires BLKBSZSET if the GPT data and the current block size don#t match up)

poettering commented 1 year ago

(didn't check if BLKBSZSET actually works, but looking through the kernel code it should really just work)

adrelanos commented 10 months ago

feature requests:

Please consider involving shim so images can be booted with the usually in the EFI firmware pre-installed Microsoft Secure Boot key. Otherwise Linux distributions that want to be compatible with booting on EFI without the user needing to enroll their own Secure Boot keys won't be able to use mkosi as bootable (ISO) installer creation tool.


I have recently managed to create a bootable hybrid live Debian ISO that is compatible with:

It's using shim, grub2, dracut. (No isolinux.)

I suppose that way it might have best compatibility among most different motherboards.

The code is here: https://github.com/Kicksecure/grml-debootstraptest

That was the most difficult sysadmin task I've ever completed. I could only do that by copying over, modifying some FLOSS scripts by Debian's live-build.

If I should extract the commands that are actually required for the black magic of bootable ISO creation or other questions, happy to help.

However, if you come up with a more clever implementation that doesn't even need ISO9660, that's great too but then I unfortunately I cannot help with this as this is getting too difficult for me.

lol I realized I don't even have a cdrom drive anywhere to test this :-D

Can be tested in a QEMU or in a virtualizer such as VirtualBox.