Page MenuHomeFreeBSD

biosboot: Detect memory disks from PXE
Needs ReviewPublic

Authored by imp on May 30 2024, 1:35 AM.
Tags
None
Referenced Files
F120235494: D45404.id139204.diff
Mon, Jun 16, 7:39 AM
Unknown Object (File)
Fri, Jun 13, 8:53 PM
Unknown Object (File)
May 17 2025, 10:57 PM
Unknown Object (File)
May 7 2025, 8:06 PM
Unknown Object (File)
Apr 30 2025, 1:33 PM
Unknown Object (File)
Apr 29 2025, 5:13 PM
Unknown Object (File)
Apr 17 2025, 2:45 AM
Unknown Object (File)
Apr 16 2025, 10:00 AM

Details

Summary

Walk through the disk driver entries chained off of INT13.

MEMDISK is part of the Syslinux project; it loads disk images into
memory, sets an int 13h hook and then does a BIOS boot from the image;
this can be used as part of a PXE boot environment to load installer
disks, however the disks are not accessible from inside the FreeBSD
kernel because it doesn't access disks through BIOS APIs.

This patch detects the disk images in the loader, and passes their
address and length as a driver hint. When the md driver sees the hint,
it maps the image, and presents it to the system.

Test Plan

I'm most confident about the boot loader changes (though the arbitrary limit likely needs some help)
I need review and ideally testing of the md.
Also, I'm not at all sure that we reserve the area, so maybe kernel allocations overwrite the ram disk? How do I prevent that?

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 57960
Build 54848: arc lint + arc unit

Event Timeline

imp requested review of this revision.May 30 2024, 1:35 AM

Thanks for picking this up!

I'm most confident about the boot loader changes (though the arbitrary limit likely needs some help)

I don't remember where that 32 came from; I think I just wanted to have a limit, so the loop would be be bounded, even if data was

Also, I'm not at all sure that we reserve the area, so maybe kernel allocations overwrite the ram disk? How do I prevent that?

memdisk adjusts the e820 memory map, so the memory it uses for the disk image will not be available memory for the kernel, but it seems like a good idea to somehow ensure that.

stand/i386/libi386/biosmemdisk.c
63

I have been testing this patch, but it remains stuck in the loader: it prints everything, but I cannot hit any key, the timer is not running.

I have been testing this patch, but it remains stuck in the loader: it prints everything, but I cannot hit any key, the timer is not running.

So we're hitting an infinite loop before interact()... That's going to be fun to debug... Is this with or without ram disks configured for iPXE?

this is with ramdisk configured via ipxe

After more testing:

INT 13 08: Failure, assuming this is the only drive^M
Drive probing gives drive shift limit: 0x81^M
old: int13 = f000e3fe  int15 = f000f859  int1e = f000607c^M
new: int13 = 9b80000a  int15 = 9b8003ba  int1e = f000607c^M
Loading boot sector... booting...^M

I can see the kernel booting but it fails at mounting the root with error 19
in the mountfrom prompt I get:

 mountroot> random: unblocking device.
? 

List of GEOM managed disk devices:
      iso9660/iPXE cd0

mountroot>

Indeed, there is the question of whether the mapped memory could be used by the VM. russor_ruka.org implies it should not as it is removed from the BIOS SMAP.

I'm not aware of a common facility to exclude physical memory regions early, or one to do that after vm_page_startup() starts (and bases its actions upon phys_avail[] and vm_phys_early_segs[]). There are two ways finally leading to filling phys_avail[]: amd64 & i386 use physmap[] (see add_physmap_entry()/bios_add_smap_entries()), whereas arm64 (and riscv IIRC) use the facilities in subr_physmem.c (there is a physmem_exclude_region() function). If limited to amd64, this would have to go into machdep.c. I'm not sure if it's possible to query hints that early.

stand/i386/libi386/biosmemdisk.c
59–61

(minor)

  • Switch C++ comments to C ones, as some other "VERY important" (see style(9)) single-line comments below use original C syntax?
  • Cosmetic: Would write 0x4C as 0x13 * 4.
89–96

(minor) This assignment feels out of place. Move it close to the checksum computation?

Indeed, there is the question of whether the mapped memory could be used by the VM. russor_ruka.org implies it should not as it is removed from the BIOS SMAP.

I'm not aware of a common facility to exclude physical memory regions early, or one to do that after vm_page_startup() starts (and bases its actions upon phys_avail[] and vm_phys_early_segs[]). There are two ways finally leading to filling phys_avail[]: amd64 & i386 use physmap[] (see add_physmap_entry()/bios_add_smap_entries()), whereas arm64 (and riscv IIRC) use the facilities in subr_physmem.c (there is a physmem_exclude_region() function). If limited to amd64, this would have to go into machdep.c. I'm not sure if it's possible to query hints that early.

This is only possible on x86 BIOS systems, so only i386 and amd64 systems only. I have this on my radar to test / fix / audit since it's a boot-loader thing and things passed from the boot loader are special. There's other methods for passing ram disks from other setups (like initrd for linux boot / UEFI booting). I have these changes queued and in my list to commit.

I'm unsure about it being removed from BIOS SMAP. On the one hand, we'd have to remove it from the avail map if it is in the SMAP. On the other, it just works as if this were treated as a "device with memory" by the OS. So I'm thinking yes, it can be used by the VM, just like we can use other memory mapped items. It's on my list of things to check into more deeply before committing.

stand/i386/libi386/biosmemdisk.c
66

I was planning on making this a #define and define it to more like 2 or 4. Though it doesn't hurt to iterate a few times.

75

I was considering making this 'bootverbose'