[syslinux] tftp file size limit: pxelinux.0 vs. syslinux.efi
John Z. Bohach
jzb at z2zcorp.com
Mon Nov 28 15:16:23 PST 2016
On 11/28/2016 09:33 AM, Ady Ady via Syslinux wrote:
>> I am pxebooting a large linux kernel (with embedded initramfs) that is around
>> 250 MB in size.
>> When booting a board in legacy BIOS mode, the pxelinux.0 executable is
>> transferred to the board and takes over, from where loading and booting this
>> large kernel works as expected. Actually, better than expected, as no tftp
>> file size limit is incurred.
>> If I change the BIOS settings to UEFI mode, then syslinux.efi is transferred
>> and takes over executing my menu, etc. just like pxelinux.0 did. But then if
>> try to boot the same large linux kernel, board hangs during file transfer.
>> I've run a network analyzer on the tftp transfer, and can see that the
>> transfer stops after 65535 blocks have been transferred, which is the usual
>> limit for tftp. I understand that this is a tftp limit.
>> However, this same limit is not encountered by pxelinux.0 and the entirety of
>> the large file makes it through just fine, and then proceeds to boot just fine.
>> Can someone please confirm if there is a known or intentional difference in
>> pxelinux.0 vs. syslinux.efi as far as tftp file size limits?
> Questions that might be relevant:
> Which version of Syslinux? Pre-built official binaries from kernel.org?
> Or from some package? Or your own build?
> Have you tried using the pre-built (no 'make') official binaries
> included in 6.04-pre1?
> Have you tried booting the same kernel by means of another UEFI-capable
> Have you tried using http instead of tftp?
> Generic reminders (which might not be relevant in this particular
> _ All files shall be provided by the same exact version/build;
> including the bootloader file, the core module (ldlinux.*) and the c32
> modules from the relevant platform (bios / efi32 / efi64). Mixing files
> from different builds / versions will result in unexpected behavior.
> _ Double check that the c32 modules being used are really pertinent to
> the relevant platform (e.g. not using menu.c32 for BIOS in order to try
> to boot EFI64).
Thanks for the response. I've analyzed my network sniffer capture some more,
and compared it with the working case for the BIOS.
The relevant issue is that for BIOS boots, the tftp transfer is much faster
than the same file during UEFI execution. The major discrepancy is that
buring BIOS boot, the ACK packet for the tftp data packet is sent about 30
microseconds after the data packet arrives. Same file during the UEFI boot,
the ACK-packet's trail the data packet by about 4 milliseconds!
That's roughly a 100x slow-down. What happens on the BIOS side is that after
the 65535'th data packet, the counter restarts and file transfer continues.
It takes about 17 seconds to download the entire ~250 MB. Works pretty well.
However, in the case of the UEFI environment, after ~155 seconds, only ~93 MB
has been transferred, and what I observe in the traffic is that the tftp
client in syslinux.efi is ACK-ing the last packet received over and over
without ACK-ing the next packet, even though the server has sent several
additional packets (which are now waiting to be ACK-ed). I've glanced at the
code in tftp.c and this appears related to the variable "timeout" though I
haven't dug deep enough to be able to confirm exactly the progression of the
timeout through the TimeoutTable, but it appears that the pointer has hit the
"null" at the end of the table and we're giving up on the transfer.
So my thought is that the UEFI environment, or the code executing therein, is
_much_ slower than during standard BIOS boot, and we are in fact hitting a
built-in timeout in the tftp client portion of syslinux.efi likely due to some
slowness in UEFI environment. If you have any suggestions on where to modify
the code, I can increase the timeout values to try to confirm if this is in
fact what is happening.
I am using syslinux-6.03 that I built myself on a fairly recent motherboard.
More information about the Syslinux