As a followup to my earlier post, I also did some tests with iPXE‘s bin/undionly.kpxe and bin/undionly.kkpxe targets.
In some of my test scenarios, I let ipxe.pxe chain-load pxelinux.0 and observed that it performed way worse than both ipxe.pxe and pxelinux.0 when they were loaded “directly” by the NIC emulation’s PXE code. This made me curious. Could it be that the VirtualBox PXE ROM is optimized in such a way that its UNDI interface is efficient enough to be used by pxelinux.0 in a very good and ipxe.pxe in a still good way, whereas iPXE possibly exports its capabilities via UNDI in an inferior way?
I already posted results with KVM in my earlier post that prove this to be not true, since KVM comes with iPXE as PXE ROM and chain-loading my custom iPXE instance showed no performance trouble at all. However, before I came to that conclusion I actually also did some tests with the bin/undionly.kpxe and bin/undionly.kkpxe build targets.
For those that don’t know, usually iPXE normally unloads both the PXE base code and the UNDI driver. If you don’t know what this means, the PXE specification won’t actually really be of much use, either ;) In short words, since that code resides in certain memory regions where every KB used to count, it is freed as soon as it is no longer needed. That’s what happens for iPXE’s .rom, .iso, .pxe etc. targets.
That’s what the .kpxe and .kkpxe targets are used for. The .kpxe targets still unloads the PXE base code but keeps the UNDI driver of the previously active PXE ROM, so it can use it for network access. This is useful eg. when iPXE itself does not have a driver for brand-new hardware. The .kkpxe target keeps the PXE base code loaded, too, which is required for some combinations of BIOS versions and PXE ROMs, where the BIOS is broken in that it can’t deal with the PXE base code unloaded when iPXE returns control via INT 18h, as laid out in the BIOS Boot Specification (BBS). iPXE will instead return via the PXE ROM. Naturally, since we want to use the previously active PXE ROM’s network driver via UNDI, it does not make sense to build iPXE with any network drivers included. Therefore, the only targets that make sense are undionly.kpxe and undionly.kkpxe.
So here are some numbers again:
- Intel PRO/1000MT Desktop (82540EM) with Intel PXE –> undionly.kpxe –> Kernel+Initrd via HTTP = 130 secs
- Intel PRO/1000MT Desktop (82540EM) with Intel PXE –> undionly.kpxe –> Kernel+Initrd via TFTP = 135 secs
- Intel PRO/1000MT Desktop (82540EM) with Intel PXE –> undionly.kpxe –> Wimboot/Windows PE via HTTP = 607 secs
- Intel PRO/1000MT Desktop (82540EM) with Intel PXE –> undionly.kpxe –> Wimboot/Windows PE via TFTP = 621 secs
One clearly sees a massive increase in boot times, rendering especially the Windows installation useless. This penalty comes from the fact that UNDI can not rely on any OS infrastructure beneath it: it has to work at BIOS level, I guess interrupt-driven and in real mode, alas not nearly using any next-to-modern technologies. Actually I got like 100% CPU load during those transfers, seeing that in my virtualization environment the CPU has to emulate the NIC. And it won’t matter how fast or modern your CPU is since UNDI’s design restrictions are the culprit here. Of course, on real hardware CPU utilization wouldn’t matter much. undionly.kkpxe results were exactly the same, by the way.
Conclusion: undionly.kpxe and undionly.kkxpe are no choice when using VirtualBox.