> 2025年2月18日 16:32,Michael Tokarev <[email protected]> 写道:
> 
> 03.02.2025 17:51, Miao Wang wrote:
>> Source: qemu
>> Version: 1:9.2.0+ds-5
>> Severity: normal
>> X-Debbugs-CC: [email protected]
>> Control: affects -1 + ipxe-qemu
>> Dear qemu maintainers,
>> I will soon maintain ipxe along with Harry Chen, planing importing new
>> ipxe version snapshots and enabling more architectures. I noticed that
>> qemu-system-* is depending the ROMs provided by ipxe. So I believe it will
>> be necessary for coordination between the two packages.
> 
> Thank you for this effort.  And please excuse me for long delay, - I had
> very little time lately which I can spare.
> 
>> Currently the package ipxe-qemu provides a series of ROM files for the
>> emulated NICs. Without manually specifying romfile=, qemu-system-* for
>> whichever architecture will try to load the corresponding ROM file.
>> Without the ROM file, qemu will refuse to start, unless an empty romfile=
>> is manually specified. In such condition, of course the PXE functionality
>> will not work.
>> Previously, each ROM file provided by ipxe-qemu is combined with two ROMs,
>> one is for x86 legacy booting and the other is for x86-64 UEFI booting.
> 
> IIRC, there are two separate ROM files, - pxe-foo.rom and efi-foo.rom,
> which are not combined.

Actually, in the current ipxe-qemu package, efi-foo.rom is actually
combined from bin-i386-pcbios/foo.rom and src/bin-x86_64-efi/foo.efirom,
and pxe-foo.rom is solely bin-i386-pcbios/foo.rom. Also, qemu itself is
unaware of whether it is booted using legacy BIOS or UEFI, so whether
to use efi-foo.rom or pxe-foo.rom is hard-coded in the device emulation
code. A simple search in the qemu code base shows:

$ grep -R 'romfile = "' hw/
hw/net/pcnet-pci.c:    k->romfile = "efi-pcnet.rom",
hw/net/e1000e.c:    c->romfile = "efi-e1000e.rom";
hw/net/ne2000-pci.c:    k->romfile = "efi-ne2k_pci.rom",
hw/net/e1000.c:    k->romfile = "efi-e1000.rom";
hw/net/rtl8139.c:    k->romfile = "efi-rtl8139.rom";
hw/net/eepro100.c:    k->romfile = "pxe-eepro100.rom";
hw/net/vmxnet3.c:    c->romfile = "efi-vmxnet3.rom";
hw/display/vmware_vga.c:    k->romfile = "vgabios-vmware.bin";
hw/display/vga-pci.c:    k->romfile = "vgabios-stdvga.bin";
hw/display/virtio-vga.c:    pcidev_k->romfile = "vgabios-virtio.bin";
hw/display/ati.c:    k->romfile = "vgabios-ati.bin";
hw/display/qxl.c:    k->romfile = "vgabios-qxl.bin";
hw/virtio/virtio-net-pci.c:    k->romfile = "efi-virtio.rom";

> 
>> The former provides the networking driver for the emulated NIC and full
>> PXE stack, while the later only provides the driver on the lower layer,
>> letting the firmware provide the upper PXE stack. When booting a virtual
>> machine of other architectures, say an arm64 virtual machine, the ROMs
>> will also be picked up by qemu-system-aarch64 by default, but not
>> providing any functionalities, since they do not contain code for that
>> architecture.
>> The first problem is that currently the package qemu-system-x86 depends
>> on ipxe-qemu, but other qemu-system-* packages recommend it. According to
>> the same behavior that qemu for no matter which architecture requires a
>> ROM file by default, should the relationship between all the qemu-system-*
>> packages be made the same?
> 
> This is a historic disparity, so to say.  In both cases it's possible to
> get away from rom dependency by specifying romfile=, but in non-x86 case
> these roms actually does nothing due to the wrong architecture.
> 
> I don't see this depends/recommends disparity as a problem.
> 
>> The second problem is that Debian is additionally providing edk2
>> firmwares for arm64, riscv64 and loong64, enabling UEFI booting for
>> qemu-system for these architectures. I've tested that if drivers for these
>> architectures are also compiled in iPXE and combined into the ROM files,
>> the emulated NIC can be recognized in the UEFI firmware settings interface
>> (in Device Manager -> Network Device List). We now may have two options
>> for enabling drivers for these architectures:
> 
> I never thought about providing network booting for other architectures,
> and didn't even know it is possible.  Yes, this is definitely interesting.

You can have a try with the ipxe-qemu in experimental, which provides
ROMs supporting other architectures. A demonstration is:

qemu-system-aarch64 \
  -cpu max -machine virt \
  -bios /usr/share/qemu-efi-aarch64/QEMU_EFI.fd \
  -smp cpus=1,cores=1,sockets=1 -m 1G \
  -chardev stdio,mux=on,id=char0 -nographic \
  -monitor chardev:char0 -serial chardev:char0 \
  -netdev user,id=net0,tftp=/tmp/test,bootfile=__nonexistent__ \
  -device e1000,netdev=net0,id=net0

You can see the firmware is trying to boot from PXE. When specifying
an empty romfile= to -device e1000, the firmware will not recognize
the NIC and will directly boot into the UEFI Shell.

For riscv64 and loong64, although not tested, I believe PXE will also
work if the PXE stack is enabled in the edk2 build.

> 
> I did try to eliminate dependency on the rom files for non-x86, but not
> very hard, - because it needs to be done in migration-compatible way and
> it becomes twisty.
> 
>> Opt1: Combine the drivers for all the architectures into one ROM like
>> before.
> 
> This is definitely not an option, because this breaks migration.  The
> size bucket is here for a reason, the size must stay within the current
> constraints.
> 
>> Pros:
>> - changes are only needed in ipxe and no changes are needed for qemu;
>> - it is actually tested and indeed works;
>> Cons:
>> - the size of the ROM files will grow beyond the current 512k pow2
>>   bucket, affecting live migration. (See #881263)
> 
> Current bucket is 256k.  If ipxe source package is unable to keep the
> roms within this size for trixie, I'll have to resort to building them
> from qemu source instead, which I want to avoid.  This is principal.
> (Currently I remove roms/ipxe/ dir from qemu source when doing the +ds
> repack, - I'll have to stop doing this.  But this opens a possibililty
> to also compress the efi roms using compression utility from edk2, so
> there's at least a possible good side here).

It seems that the generated ipxe images has already been compressed.

> When/why we went past the 256k limit for the efi roms?

According to my knowledge, the size limit was not passed because ipxe
is not updated in the Debian repo since buster, util Sven Geuer tried
to import changes made on the Ubuntu side into unstable, when the limit
is raised to 512K, the same to Ubuntu. Note that the ROMs in stable
now contains only code for legacy boot and x86-64 UEFI boot. I propose
that if we would like to choose to combine the images for other
architectures, we can raise the limit to 1M.

> 
>> Opt2: Using separate ROM files for each architecture. The name of the
>> files remain unchanged but the ROMs for each architecture is put into
>> separate directories, and maybe into separate packages, and qemu-system-*
>> is configured to search different directories for different architectures.
> 
> This is the way to go, given the size constraints we have.
> 
> But while this can be done in debian by specifying different subdirs for
> the rom files, I think it needs to be coordinated with qemu upstream, so
> everyone can benefit from this.  We can try it as a proof-of-concept, to
> demonstrate that it works.

Yes, it would be nice if we can use different subduers for this. I propose
that in the rules file of qemu, we can prepend a target-arch-specific path
to FIRMWAREPATH, e.g. /usr/share/qemu-aarch64, where we can put all the
ROMS for arm64, including NIC ROMs and firmwares. And in the end (maybe
in the next stable release, forky), we can finally remove the common
/usr/share/qemu directory.

Cheers,

Miao Wang

Reply via email to