Comboot API

From Syslinux Wiki
Jump to: navigation, search

Syslinux is extensible via COMBOOT modules, which can be written in C or in assembly. [-4.xx] Syslinux (prior to version 5.00) supports both 16- and 32bit COMBOOT modules; 16bit COMBOOT modules implement a subset of the MS-DOS ".COM" API, and can thus be written to be runnable under DOS if desired.

[5.00+] Since version 5.00, support for 16bit COMBOOT modules has been dropped, and c32 modules switched from the COM32 object format to ELF.

Assembly API reference

The assembly-level API reference can be found here.

C API reference

The Syslinux distribution contains a significant subset of the standard C library, as well as a number of Syslinux-specific C functions. At this point, the main documentation for these are in the C header files ("com32/include/") included with the Syslinux distribution.

Shuffle API

A very important part of the Syslinux C API is contained in the functions syslinux_shuffle_boot_rm() and syslinux_shuffle_boot_pm() (real and 32bit flat protected mode), defined in "syslinux/bootrm.h" and "syslinux/bootpm.h", respectively. These functions allow arbitrary memory blocks to be mapped into desired locations, and set up entry conditions. This API can be used to support loading new binary formats.

Sample modules using this API include "elf.c32" and "sdi.c32".

Linux loading API

The Syslinux C API also includes a higher-level API for loading Linux, and compose a custom initial RAM filesystem (initramfs) at boot time. This API is defined in "syslinux/linux.h".

A sample module using this API is "linux.c32".

Patching COM Module linux.c32 with the dhcp_info patch

The linux.c32 module is an optional add-on module for Syslinux bootloaders, which extends their functionality.

It is used in place of a kernel in the configuration file, and the APPEND option lists the actual kernel, initrd, and any kernel options.

linux.c32 accepts an option, "-dhcpinfo". This copies the DHCP packet received by PXE BIOS before configuring itself and downloading the PXELINUX bootloader into the initrd ramdisk loaded into memory just after the kernel.

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. Don't Panic! It's simple C code, elegant though it appears, it's not that hard to figure out.

April 10th of 2007, 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 structure (keyname=value) 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.

Example of how to get started with COM32 API

  • First download the Syslinux source; it comes with the COM examples in the tarball.
  • Then download Ferenc's patch from the Syslinux mail list [1] 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.)
Install 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.
Example of what to do
  1. Extract the tarball to your working directory. tar -zxvf syslinux-3.50.tar.gz
  2. 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
    
  3. 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.
  4. Ferenc forgot to include usage examples with the inital patch, but posted instructions in follow up messages:
    kernel linux.c32
    append vmlinuz initrd=initrd.img root=/dev/mapper/$HOST$-root
    
    or:
    kernel linux.c32
    append -dhcpinfo vmlinuz initrd=initrd.img root=/dev/mapper/$HOST$-root
    
    or even:
    kernel linux.c32
    append -dhcpinfo vmlinuz initrd=$SNAME$.img
    
    I tested his directions and they work just fine.
Details
  • It is important to note that the patch does not rename the linux.c32 binary and what pops out of the oven will still be called linux.c32 unless you change it in the appropriate Makefile. I think Ferenc was just trying to be clear that this isn't the garden variety linux.c32 in his instructions.
  • 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 is 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 it is more useful when you can refer it to with a macro string you can insert anywhere in the kernel string.
  • See, the problem is that 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.
Closing

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!

- Oh by the way... I'm not Peter. My name is John, I'm just a contributor.