Patching COM Module linux.c32 with the dhcp_info patch
The linux.c32 module is an optional add-on module for the PXELINUX bootloader.
It provides enhanced functionality to PXELINUX.
Basically you use it as if it were a kernel and tell the pxelinux.cfg file for your booting device to load it instead of your actual kernel.
Then using the APPEND option to list the kernel, the initrd, and any kernel options.
Normally the linux.c32 accepts an option -dhcpinfo that instructs it to copy the dhcp packet PXE Bios received before configuring itself and downloading the PXELINUX bootloader into the initrd ramdisk loaded into memory just after the kernel.
Speaking strictly of the Syslinux-3.50 source version:
The linux.c32 "module" is located in [ syslinux-3.50/com32/modules/linux.c ].
It's really an amazing read and has examples of how to use the COM32 API.
It's simple C code, elegant though it appears, its not that hard to figure out.
April 10th of this year Ferenc Wagner responded to another user with a patch for linux.c32 which basically created a structure for the dhcp_packet based on the dhcp.h from a DHCP server.
Then assigned tags to the parts of the structure, and rendered the data in the parts into strings.
Once this tagged keyname=value structure was created, the patch enabled linux.c32 to recognize and replace macro $keyname$ tags in the APPEND option line with the string-ified dhcp_packet data.
So basically here is an example of how to get started with COM32 API.
First download the SYSLINUX/PXELINUX source, from [kernel.org|http://www.kernel.org/pub/linux/utils/boot/syslinux/Old/] it comes with the COM examples in the tarball.
Then download Ferenc's patch from the SYSLINUX mail list [Patch|http://syslinux.zytor.com/archives/2007-April/008308.html] and save to a text file.
The patch is known to work with syslinux-3.50 but may have some problem with later versions, such is the fragility of patches.. sometimes they must be re-worked.
On my system, I installed RHEL5-Client on a i386 platform from a RHEL5-Client DVD.
The base install asks if you'd like developer packages and I selected those, the syslinux-3.50 source code will build on a linux system with the nasm assembly compiler, but by default that package is not installed on RHEL5-Client. It is however included on the DVD in the "Workstation" directory.
After setting up RHEL5-Client, you just need to login and mount the DVD change to the /dvd/Workstation directory and issue # rpm -i nasm-* and you should be all set.
Some parts of the syslinux source are in assembler and some are in C code, by installing the developer suite of packages when I installed RHEL5-Client I also got a C compiler and a lot of other developer tools.
So here's an example of what to do:
Extract the tarball to your working directory.
tar -zxvf syslinux-3.50.tar.gz
Then Copy Ferenc's text file patch you saved from the mail list to the syslinux-3.50 source directory, and apply the patch:
- cd /root/syslinux-3.50
- patch -p1 < patch-linux32.txt
patching file com32/modules/dhcp.h patching file com32/modules/linux.c
Then just type "# make" and everything should build, except the win32/syslinux.exe, but that won't stop it from completing it just emits a warning.
If you really do want to build win32/syslinux.exe or just don't like that creepy feeling you get when something compiles and emits warning messages.
Just download the mingw compiler rpm's from [kernel.org mingw|http://www.kernel.org/pub/linux/utils/boot/syslinux/mingw/] or here
- mkdir mingw
- cd /root/mingw
- wget http://mirzam.it.vu.nl/mingw/packages/fc6/mingw-binutils-2.17.50-10hl.i386.rpm
- wget http://mirzam.it.vu.nl/mingw/packages/fc5/mingw-gcc-core-3.4.5-13hl.i386.rpm
- wget http://mirzam.it.vu.nl/mingw/packages/fc6/mingw-runtime-3.9-20hl.i386.rpm
- wget http://mirzam.it.vu.nl/mingw/packages/fc6/mingw-w32api-3.8-20hl.i386.rpm
- rpm -i *.rpm
The next time you type "# make" it'll compile everything and complete without warning.
Ferenc forgot to include examples with the inital patch, but posted instructions in a follow up message here [How To use dhcp.c32| http://syslinux.zytor.com/archives/2007-April/008309.html]
I tested his directions and they work just fine.
Now if you read the patch or the source code for linux.c32 after you apply the patch [use a syntax highlighting editor if possible, Notepad++ on Windows in nice, vim on Linux has syntax highlighting].. anyway.. if you read the source.. you will notice Ferenc created string renderers for most types of dhcp_info packet information and a catch all for unknown types.
There's another option you might also find interesting called CHADDR which is the Client Hardware Address. pxelinux.0 normally affords you access to this through the IPAPPEND 2 option but its more useful when you can refer it to with a macro string you can insert anywhere in the kernel string.
See the problem is at different times the kernel may be front-ending different initrd disk images for different purposes. And the kernel option name for the follow up application may change. Boy can it change!
IPAPPEND delivers the chaddr in a fixed keyname=value form, linux.c32 let's you move it around and even change its form (by changing the string renderer).
And it's just good exercise to understand the code, build confidence in hacking a COM32 module and see the results.
Well its getting a bit late in my part of the world so I'll leave it here for the evening (08/14/07 1:31 AM CDT).
I've a lot to learn about Wiki formatting and this probably looks terrible. If anyone feels like it please! go ahead and reformat this page. Or correct my grammar, or correct the content.
Next time I'd like to go over the linux.c32 code in a tiny bit of detail and point out how to write a new renderer and assign some more dhcp_info packet values to keynames you can use as macros in the APPEND line.
Till then have a great day!