[Etherboot-developers] gPXE/Bootix incompatibility
Brought to you by:
marty_connor,
stefanhajnoczi
|
From: Alex Z. <ale...@eu...> - 2010-03-24 12:02:53
|
Hi all,
We've found that gPXE clients cannot boot successfully from a Bootix server.
The problem appears to be to do with the cached filenames that gPXE saves and
returns to the NBP when in response to a PXENV_GET_CACHED_INFO call. There are
3 such filenames:
* from the last DHCP discovery (CACHED_INFO_DHCPDISCOVER)
* from the last DHCP ACK (CACHED_INFO_DHCPACK)
* from the last PXE request (CACHED_INFO_BINL)
Now, when the Bootix NBP calls PXENV_GET_CACHED_INFO it doesn't provide a
buffer. As a result gPXE returns a pointer to cached_info[CACHED_INFO_BINL]
rather than copying this struct into a caller provided buffer.
When the Bootix NBP calls PXENV_TFTP_READ_FILE gPXE updates the filenames in
cached_info[CACHED_INFO_DHCPACK] and cached_info[CACHED_INFO_BINL]. According
to the comments it does this because some Intel PXE implementation did this and
even though this is a bug NTLDR depends on it.
The problem is that the Bootix NBP has a pointer to
cached_info[CACHED_INFO_BINL] and is using it to store the name of the next file
to get!
Perhaps the Bootix NBP shouldn't be doing this... but we've found that if we
make PXENV_TFTP_READ_FILE only update the filename in
cached_info[CACHED_INFO_DHCPACK] and leave the filename in
cached_info[CACHED_INFO_BINL] then the boot succeeds. (See patch below.)
If anybody is still reading, do you know whether this is an okay way to fix the
problem, ... or will it break NTLDR?
Regards,
Alex
--- pxe_preboot.c.orig 2010-03-24 10:27:50.000000000 +0000
+++ pxe_preboot.c 2010-03-24 10:28:13.000000000 +0000
@@ -111,22 +111,22 @@
* This is a bug-for-bug compatibility hack needed in order to work
* with Microsoft Remote Installation Services (RIS). The filename
* used in a call to PXENV_RESTART_TFTP or PXENV_TFTP_READ_FILE must
* be returned as the DHCP filename in subsequent calls to
* PXENV_GET_CACHED_INFO.
*/
void pxe_set_cached_filename ( const unsigned char *filename ) {
memcpy ( cached_info[CACHED_INFO_DHCPACK].dhcphdr.file, filename,
sizeof ( cached_info[CACHED_INFO_DHCPACK].dhcphdr.file ) );
- memcpy ( cached_info[CACHED_INFO_BINL].dhcphdr.file, filename,
- sizeof ( cached_info[CACHED_INFO_BINL].dhcphdr.file ) );
+// memcpy ( cached_info[CACHED_INFO_BINL].dhcphdr.file, filename,
+// sizeof ( cached_info[CACHED_INFO_BINL].dhcphdr.file ) );
}
/**
* UNLOAD BASE CODE STACK
*
* @v None -
* @ret ...
*
*/
|