Hello, I'm trying to find out how to pxe boot with syslinux.efi on QEMU with OVMF. After getting through the initial hurdle caused by the iPXE based option ROM included with QEMU having a problem as described in these threads: http://www.syslinux.org/archives/2014-November/022804.html http://sourceforge.net/p/edk2/mailman/message/33236100/ I'm now getting further to almost being able to boot but still not quite. To eliminate further variables I'm now using the suggested virtio-net-pci with romfile= option to disable any iPXE code and only use code included in OVMF and syslinux. Where I'm stuck now is that syslinux.efi fails when trying to download a file from http. This fails with the efi version but works with the same PXE/HTTP server and QEMU client not using OVMF and instead of syslinux.efi using lpxelinux.0. Looking at packet captures show that the connection is closed by the server after establishment with syslinux.efi. This is the http connection with BIOS and lpxelinux.0: TCP 49153 > http [SYN] Seq=0 Win=64000 Len=0 MSS=1460 TCP http > 49153 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 TCP 49153 > http [ACK] Seq=1 Ack=1 Win=64000 Len=0 HTTP GET /boot HTTP/1.0 with http transfer commencing normally after this, while with OVMF and syslinux.efi I get the following: TCP 1654 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=1039 TSecr=0 TCP http > 1654 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=64 TSval=1151334911 TSecr=1039 TCP 1654 > http [ACK] Seq=1 Ack=1 Win=2097152 Len=0 TSval=1039 TSecr=0 TCP http > 1654 [RST] Seq=1 Win=0 Len=0 HTTP GET /boot HTTP/1.0 with data packets sent by the http server getting RST replies after this presumably due to socket closed in reply to the RST packet from the server. I see different options and values used in the EFI case but I don't know where these are coming from and if they are causing the problem. Does anyone have an understanding what happens or any hints what to look for? If I try tftp instead it can transfer some files but is very slow (slower than it should be as it is faster with the BIOS version) and still cannot successfully boot with the transfer ending unexpectedly before finishing. (I saw similar reports on the mailing lists with HP and Dell hardware but I'm not sure they are related.) Any help is greatly appreciated. Regards, BALATON Zoltan
On 04/07/15 19:22, BALATON Zoltan wrote:> Hello, > > I'm trying to find out how to pxe boot with syslinux.efi on QEMU with > OVMF. After getting through the initial hurdle caused by the iPXE based > option ROM included with QEMU having a problem as described in these > threads: > > http://www.syslinux.org/archives/2014-November/022804.html > http://sourceforge.net/p/edk2/mailman/message/33236100/ > > I'm now getting further to almost being able to boot but still not quite. > > To eliminate further variables I'm now using the suggested > virtio-net-pci with romfile= option to disable any iPXE code and only > use code included in OVMF and syslinux. > > Where I'm stuck now is that syslinux.efi fails when trying to download a > file from http. This fails with the efi version but works with the same > PXE/HTTP server and QEMU client not using OVMF and instead of > syslinux.efi using lpxelinux.0. Looking at packet captures show that the > connection is closed by the server after establishment with syslinux.efi. > > This is the http connection with BIOS and lpxelinux.0: > > TCP 49153 > http [SYN] Seq=0 Win=64000 Len=0 MSS=1460 > TCP http > 49153 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 > TCP 49153 > http [ACK] Seq=1 Ack=1 Win=64000 Len=0 > HTTP GET /boot HTTP/1.0 > > with http transfer commencing normally after this, while with OVMF and > syslinux.efi I get the following: > > TCP 1654 > http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=64 TSval=1039 > TSecr=0 > TCP http > 1654 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=64 > TSval=1151334911 TSecr=1039 > TCP 1654 > http [ACK] Seq=1 Ack=1 Win=2097152 Len=0 TSval=1039 TSecr=0 > TCP http > 1654 [RST] Seq=1 Win=0 Len=0 > HTTP GET /boot HTTP/1.0 > > with data packets sent by the http server getting RST replies after this > presumably due to socket closed in reply to the RST packet from the > server. I see different options and values used in the EFI case but I > don't know where these are coming from and if they are causing the > problem. Does anyone have an understanding what happens or any hints > what to look for? > > If I try tftp instead it can transfer some files but is very slow > (slower than it should be as it is faster with the BIOS version) and > still cannot successfully boot with the transfer ending unexpectedly > before finishing. (I saw similar reports on the mailing lists with HP > and Dell hardware but I'm not sure they are related.) > > Any help is greatly appreciated.As far as I can see (... well, guess), lpxelinux.0 uses the TCP implementation under core/lwip/, which doesn't support TCP timestamps. Whereas syslinux.efi apparently uses the embedded gpxe/ tree, and that one uses TCP timestamps. See tcp_xmit() in gpxe/src/net/tcp.c: if ( ( flags & TCP_SYN ) || tcp->timestamps ) { tsopt = iob_push ( iobuf, sizeof ( *tsopt ) ); memset ( tsopt->nop, TCP_OPTION_NOP, sizeof ( tsopt->nop ) ); tsopt->tsopt.kind = TCP_OPTION_TS; tsopt->tsopt.length = sizeof ( tsopt->tsopt ); tsopt->tsopt.tsval = ntohl ( currticks() ); tsopt->tsopt.tsecr = ntohl ( tcp->ts_recent ); } (When opening the connection, the TCP_SYN flag is set (from tcp_open() I guess?).) So, the two builds use different TCP stacks on the client side. (Obviously I have no clue, but this is what I could gather in five minutes.) Laszlo
On Tue, 7 Apr 2015, Laszlo Ersek wrote:> As far as I can see (... well, guess), lpxelinux.0 uses the TCP > implementation under core/lwip/, which doesn't support TCP timestamps. > > Whereas syslinux.efi apparently uses the embedded gpxe/ tree, and that > one uses TCP timestamps. See tcp_xmit() in gpxe/src/net/tcp.c: > > if ( ( flags & TCP_SYN ) || tcp->timestamps ) { > tsopt = iob_push ( iobuf, sizeof ( *tsopt ) ); > memset ( tsopt->nop, TCP_OPTION_NOP, sizeof ( tsopt->nop ) ); > tsopt->tsopt.kind = TCP_OPTION_TS; > tsopt->tsopt.length = sizeof ( tsopt->tsopt ); > tsopt->tsopt.tsval = ntohl ( currticks() ); > tsopt->tsopt.tsecr = ntohl ( tcp->ts_recent ); > } > > (When opening the connection, the TCP_SYN flag is set (from tcp_open() I > guess?).) > > So, the two builds use different TCP stacks on the client side.OK, so I've changed the test with BIOS to use gpxelinux.0 instead (hoping that will match the syslinux.efi case better, did not check details in the source yet) and that does not work either but in a different way. The packet capture shows that gpxelinux.0 does not even try to open a the TCP connection to the http server. It flashes briefly: Loading filename... Failed: No such file or directory then returns to the menu. The file is there and lpxelinux.0 finds and loads it. A DNS query is sent for the server name in the http URL and gets a reply but the request is not made after that. (Also tried with IP address with the same results: no DNS query in this case but no http connection is tried either.) I've also noticed that for the syslinux.efi case I had a typo in the config for the server name but that does not seem to do a DNS query and just uses the server IP address (which happened to be correct for my case). But syslinux.efi breaks on getting an RST from the server. A few things seem to be broken here. Any ideas where to start debugging? The main difference in packets shown in my previous message, apart from additional features due to different TCP/IP stack is the big Window size returned with the client's ACK. I'm not too familiar with low level TCP. Could this make the server drop the connection? Regards, BALATON Zoltan
On Tue, 7 Apr 2015, Laszlo Ersek wrote:> Whereas syslinux.efi apparently uses the embedded gpxe/ tree, and that > one uses TCP timestamps. See tcp_xmit() in gpxe/src/net/tcp.c:Actually syslinux.efi seems to be using the implementation calling into UEFI via these functions: http://git.kernel.org/cgit/boot/syslinux/syslinux.git/tree/efi/tcp.c I've tried to add debug messages to these functions and got the following: core_tcp_connect: connecting core_tcp_connect: connected core_tcp_connect: at out: closing CompletionToken core_tcp_write: Sending 227 bytes tcp transmit failed, Access Denied Meanwhile on the OVMF side I could get these debug logs: Tcb (3F296898) state TCP_CLOSED --> TCP_SYN_SENT TcpToSendData: set RTT measure sequence 464107706 for TCB 3F296898 Tcb (3F296898) state TCP_SYN_SENT --> TCP_ESTABLISHED TcpComputeRtt: new RTT for TCB 3F296898 computed SRTT: 0 RTTVAR: 0 RTO: 5 TcpInput: connection established for TCB 3F296898 in SYN_SENT TcpInput: connection reset for TCB 3F296898 Tcb (3F296898) state TCP_ESTABLISHED --> TCP_CLOSED Tcb (3F296898) state TCP_CLOSED --> TCP_CLOSED So now it seems the problem may be in OVMF somewhere but how to find it? EDK2 code is hard to follow and I'm not sure what should I look for. Any hints? Regards, BALATON Zoltan