Friday, December 02, 2011

iPXE: Boot iPXE Linux kernel via PXELinux

iPXE Linux kernel (ipxe.lkrn) may chain loaded by PXELinux:

default boot

label boot
        kernel ipxe.lkrn

Both iPXE firmware (undionly.kpxe) or iPXE kernel image (ipxe.lkrn) has same functions.  All usage of iPXE commands / scripts remain the same for both firmware and kernel.

Problem with Dell Vostro notebook

All the time I use PC with iPXE firmware (undionly.kpxe) with WinPE and SanBoot without problem.  If I boot Dell Vostro notebook with the same booting steps as PC, the WinPE or SanBoot doesn’t work at all.  The reason remain unknown.  Here are my booting steps:

Scenario A

  1. Switch on machine
  2. DHCP –> undionly.kpxe (undionly.0)
  3. Chain to load WinPE image
  4. Show blank screen after WinPE image

Scenario B

  1. Switch on machine
  2. DHCP –> undionly.kpxe (undionly.0)
  3. sanboot iSCSI target
  4. Machine hang while booting

Both scenario A and B works fine on PC but doesn’t work on Dell Vostro notebook.

I suspect the problem is related to:

  1. iPXE firmware
  2. Notebook network card’s firmware doesn’t work well with iPXE firmware.

Dell Vostro notebook work with iPXE kernel

While trying to find solution solving the mystery problem with Dell Vostro notebook, I found that iPXE kernel works.  I may load WinPE image or SanBoot a Windows ISCSI target with iPXE kernel chain loaded by PXELinux.

  1. Prepare ipxe.lkrn
    -bash-4.1$ git clone git://
    -bash-4.1$ cd ipxe
    bash-4.1$ make src/bin/ipxe.lkrn
  2. Copy src/bin/ipxe.lkrn to TFTP boot directory.
    # cp src/bin/ipxe.lkrn /var/lib/tftpboot
  3. Update dhcp configuration file: /etc/dhcp/dhcpd.conf to prevent infinite iPXE boot when ipxe.lkrn boot:
            if exists user-class and option user-class = "iPXE" {
                    filename "http://<ip-address>/boot.ipxe";
            } else {
                    filename "pxelinux.0";
  4. Load ipxe.lkrn after PXELinux boot:
    # cat pxelinux.cfg/default
    default boot
    label boot
            kernel ipxe.lkrn
  5. iPXE kernel will query DHCP server again, DHCP will send boot.ipxe script file via HTTP to the machine:
    set 209:string pxelinux.cfg/boot
    set 210:string http://<ip-address>/
    chain ${210:string}pxelinux.0
  6. boot.ipxe will chain load pxelinux.0 with new configuration file: pxelinux.cfg/boot:
    # cat pxelinux.cfg/boot
    default menu.c32
    prompt 0
    LABEL boot_local
            menu label ^Boot Local System
            menu default
            localboot 0
            timeout 50
    LABEL boot_san
            menu label Boot ^Storage Area Network
            com32 syslinux/gpxecmd.c32
            append sanboot iscsi:<iscsi-host>
            menu label ^Windows Preinstallation Exnvironment
  7. Both SanBoot and Window PE image works with Dell Vostro notebook now.

WAIK: Add Microsoft iSCSI service to WinPE

Microsoft iSCSI service allow user to connect to iSCSI target on SAN device.  The default WINPE image doesn’t support iSCSI service.  This topic shows how to add iSCSI service to WinPE image.  Once added, you may connect to iSCSI target after boot into WinPE environment.

Add iSCSI service files to WinPE image

  1. Start WAIK deployment Tools command prompt in privilege mode
  2. Mount an WinPE image file in RW mode:
    imagex /mountrw winpe.wim 1 mount
  3. Copy the following files into mounted winpe’s “<mount>\windows\system32” folder:

Update WinPE registry hive

  1. Start RegEdit.exe in privilege mode
  2. Select “HKEY_LOCAL_MACHINE”, and click File | Load Hive… to load hive file: <mount>\windows\system32\config\SYSTEM.  Use PE_Sys as hive key name.
  3. Select “HKEY_LOCAL_MACHINE”, and click File | Load Hive… to load hive file: <mount>\windows\system32\config\SOFTWARE. Use PE_Soft as hive key name.
  4. The HKEY_LOCAL_MACHINE should have 2 hive loaded as follow:
    Windows 7 x64 WAIK-2011-12-02-11-57-28
  5. Create a iscsi.reg file with the following content:
    Windows Registry Editor Version 5.00
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\Svchost]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery\Authentication Cache]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery\Send Targets]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery\Static Targets]
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery\Tunnel Address]
    "DeviceDesc"="@iscsi.inf,%iscsiprt%;Microsoft iSCSI Initiator"
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT\0000\Device Parameters]
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT\0000\Device Parameters\StorPort]
    "DisplayName"="iScsiPort Driver"
    "RebootMessage"="See Note 3 below"
    Windows Registry Editor Version 5.00
    "DriverDesc"="Microsoft iSCSI Initiator"
  6. Import iscsi.reg into registry.  It should update both PE_Sys and PE_Soft hive.
  7. Unload both PE_Sys and PE_Soft hive by using File | Unload Hive… in registry editor.
  8. Unmount and commit the WinPE mount:
    imagex /unmount /commit mount
  9. The WinPE image file is now ready with iSCSI service.

Start iSCSI service in WinPE environment

  1. Boot the WinPE image either by using ISO or PXE
  2. To start iSCSI service:
    X:\windows\system32>net start msiscsi
    The Microsoft iSCSI Initiator Service service is starting.
    The Microsoft iSCSI Initiator Service service was started successfully.
  3. type iscsicpl to start iSCSI GUI windows:

    Windows 7-2011-12-02-12-12-55
  4. The iSCSI initiator is now active to connect to iSCSI target.


  1. WinPE v3.0 and Microsoft iSCSI Initiator. URL:

PXELinux: Load menu other than default

When loading PXELinux via DHCP as specified in dhcp.conf:

filename "pxelinux.0";

Once PXELinux was loaded, it will look for configuration in the following order:

  1. Client PC’s GUID
  2. Client PC’s MAC Address
  3. Client PC”s IP address
  4. pxelinux.cfg/default

These searching order may reveal from /var/log/messages:

Nov 28 08:58:09 dolphin in.tftpd[24603]: RRQ from filename gpxelinux.0
Nov 28 08:58:09 dolphin in.tftpd[24604]: RRQ from filename pxelinux.cfg/0338a9f6-d2b1-11df-9ec1
Nov 28 08:58:09 dolphin in.tftpd[24605]: RRQ from filename pxelinux.cfg/01-70-71-bc-a8-4f-43
Nov 28 08:58:09 dolphin in.tftpd[24606]: RRQ from filename pxelinux.cfg/C0A800B5
Nov 28 08:58:09 dolphin in.tftpd[24607]: RRQ from filename pxelinux.cfg/C0A800B
Nov 28 08:58:09 dolphin in.tftpd[24608]: RRQ from filename pxelinux.cfg/C0A800
Nov 28 08:58:09 dolphin in.tftpd[24609]: RRQ from filename pxelinux.cfg/C0A80
Nov 28 08:58:09 dolphin in.tftpd[24610]: RRQ from filename pxelinux.cfg/C0A8
Nov 28 08:58:09 dolphin in.tftpd[24611]: RRQ from filename pxelinux.cfg/C0A
Nov 28 08:58:09 dolphin in.tftpd[24612]: RRQ from filename pxelinux.cfg/C0
Nov 28 08:58:09 dolphin in.tftpd[24613]: RRQ from filename pxelinux.cfg/C
Nov 28 08:58:09 dolphin in.tftpd[24614]: RRQ from filename pxelinux.cfg/default

In most situation, create a default configuration file works well.  There are some situations where we want to force the pxelinux to load menu configuration file other than default.

Here is a DHCP configuration that force pxelinux to load menu pxelinux.cfg/boot:

  1. option space pxelinux;
  2. option pxelinux.magic code 208 = string;
  3. option pxelinux.configfile code 209 = text;
  4. option pxelinux.pathprefix code 210 = text;
  5. option pxelinux.reboottime code 211 = unsigned integer 32;
  7. site-option-space "pxelinux";
  8. if exists dhcp-parameter-request-list {
  9.   # Always send the PXELINUX options
  10.   option dhcp-parameter-request-list = concat(option-dhcp-parameter-request-list, "208,209,210,211");
  11. }
  13. option pxelinux.configfile      "pxelinux.cfg/boot";
  14. filename "pxelinux.0";

The DHCP option 209 is the option to specify PXELinux config file.  Line 10 specify option additional parameters that will pass to dhcp client.

PXELinux: Boot ISO image from network

PXELinux’s memdisk module may boot ISO image from network.  However, not all ISO file support network booting.  It is worth to try if you need the boot ISO image via PXELinux.

The following example shows two configuration to boot WinPE and SeaTools ISO.  The PXE supports iPXE/gPXE to allow HTTP loading of ISO file.  You may use native TFTP protocol for file loading too.

label WinPE ISO
        kernel syslinux/memdisk
        append iso
        initrd http://<ip-address>/winpe7_x64.iso

label SeaTools
        menu label SeaTools for DOS v2.23
        kernel syslinux/memdisk
        append iso
        initrd http://<ip-address>/SeaToolsDOS223ALL.ISO

Monday, November 28, 2011

iPXE: iSCSI for Microsoft Windows

Prepare environment to install and boot from iSCSI target

  1. Syslinux 3.86 is the last known working version that may work with gpxe/ipxe.  Prepare a TFTP boot folder as following:
    # tree
    ├── pxelinux.cfg
    │   └── default
    ├── syslinux -> syslinux.386
    ├── syslinux.386
    │   ├── advdump.c32
    │   ├── c32echo.c32
    │   ├── cat.c32
    │   ├── chain.c32
    │   ├── cmd.c32
    │   ├──
    │   ├── complex.c32
    │   ├── config.c32
    │   ├──
    │   ├── cpuid.c32
    │   ├── cpuidtest.c32
    │   ├── disk.c32
    │   ├── display.c32
    │   ├── dmitest.c32
    │   ├── elf.c32
    │   ├── entrydump.c32
    │   ├── ethersel.c32
    │   ├── fancyhello.c32
    │   ├── fd.c32
    │   ├── filetest.c32
    │   ├── gfxboot.c32
    │   ├──
    │   ├── gpxecmd.c32
    │   ├── gpxelinux.0
    │   ├── hdt.c32
    │   ├── hello2.c32
    │   ├── hello.c32
    │   ├── ifcpu64.c32
    │   ├── ifcpu.c32
    │   ├──
    │   ├── kbdmap.c32
    │   ├── keytest.c32
    │   ├── linux.c32
    │   ├── localboot.c32
    │   ├── mboot.c32
    │   ├──
    │   ├──
    │   ├── meminfo.c32
    │   ├── menu.c32
    │   ├── pcitest.c32
    │   ├── pmload.c32
    │   ├──
    │   ├──
    │   ├── pxelinux.0
    │   ├── reboot.c32
    │   ├── resolv.c32
    │   ├── rosh.c32
    │   ├── sanboot.c32
    │   ├── sdi.c32
    │   ├── serialinfo.c32
    │   ├── simple.c32
    │   ├── sysdump.c32
    │   ├──
    │   ├── test2.c32
    │   ├── test.c32
    │   ├── vesainfo.c32
    │   ├── vesamenu.c32
    │   └── vpdtest.c32
    ├── undionly.0 -> undionly.kpxe
    ├── undionly.kpxe
        ├── BCD
        ├── bootmgr.exe
        ├── boot.sdi
        ├── fonts
        │   ├── chs_boot.ttf
        │   ├── cht_boot.ttf
        │   ├── jpn_boot.ttf
        │   ├── kor_boot.ttf
        │   └── wgl4_boot.ttf
        ├── pxeboot.0 -> pxeboot.n12
        ├── pxeboot.n12
        ├── vista_x64.wim
        ├── vista_x86.wim
        ├── win7_x64.wim
        └── win7_x86.wim
  2. Update /etc/dhcp/dhcpd.conf to use gpxelinux.0
    filename "gpxelinux.0";
  3. Restart dhcpd service
    # service dhcpd restart
    Shutting down dhcpd:                                       [  OK  ]
    Starting dhcpd:                                            [  OK  ]
  4. Update pxelinux.cfg/default:
    LABEL boot_san
            menu label Boot ^Storage Area Network
            menu indent 5
            com32 syslinux/gpxecmd.c32
            append chain t
    label undionly
            menu label Boot iPXE UNDI
            menu indent 5
            kernel undionly.0
  5. Create a sanboot.gpxe script file:
    # cat sanboot.gpxe
    chain t http://${username}:${password}${username}/menu.cfg
  6. A sample menu.cfg file:
    UI syslinux/vesamenu.c32
    LABEL Windows 7 x64
            com32 cmd.c32
            append sanboot
    LABEL Windows 8 x64
            com32 cmd.c32
            append sanboot

Install Windows 7 on iSCSI target

  1. Boot machine into iPXE kernel (Boot iPXE UNDI or undionly.0)
  2. Press Ctrl-B to start iPXE command line
  3. Obtain an IP address from dhcp
    iPXE> dhcp net0
  4. Preserve SAN device
    iPXE> set keep-san 1
  5. Supply chap information if necessary:
    iPXE> login
  6. Initialize iSCSI target:
    iPXE> sanboot
    Registered SAN device 0x80
    Booting from SAN device 0x80
    Boot from SAN device 0x80 failed: Operation canceled (
    Preserving SAN device 0x80

  7. Chain boot to Windows PE:

    iPXE> chain t
  8. Or chain boot to Windows PE ISO:
  9. iPXE> kernel syslinux/memdisk iso
    iPXE> initrd http://<ip-address>/winpe7_x64.iso
    iPXE> boot
    1. Once boot into Windows PE, you may use the iSCSI target just like your local storage.  You may install a Windows OS into the iSCSI target directly.

    Boot from iSCSI target using iPXE

    1. Boot machine into iPXE kernel
    2. Press Ctrl-B to start iPXE command line
    3. Obtain an IP address from DHCP

      iPXE> dhcp net0
    4. Supply chap information if necessary:

      iPXE> login
    5. Boot from iSCSI target:

      iPXE> sanboot

    Boot from iSCSI using PXE using HTTP

    1. Boot from PXE
    2. Use the pxe menu configuration to boot iSCSI target introduced in section “Prepare environment to install and boot from iSCSI target”


    1. User-specific boot menus. URL:
    2. Installing Windows Server 2008 to an iSCSI target. URL: