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://git.ipxe.org/ipxe.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:
    #!ipxe
    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>::::iqn.example.com:win7
    
    LABEL WINDOWS_PE
            menu label ^Windows Preinstallation Exnvironment
            kernel windows.pe/pxeboot.0
  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:
    Windows\System32\iscsicli.exe
    Windows\System32\iscsicpl.exe
    Windows\System32\iscsicpl.dll
    Windows\System32\iscsidsc.dll
    Windows\System32\iscsied.dll
    Windows\System32\iscsiexe.dll
    Windows\System32\iscsilog.dll
    Windows\System32\iscsium.dll
    Windows\System32\iscsiwmi.dll
    Windows\System32\Drivers\msiscsi.sys
    Windows\System32\en-us\iscsicli.exe.mui
    Windows\System32\en-us\iscsicpl.dll.mui
    Windows\System32\en-us\iscsicpl.exe.mui
    Windows\System32\en-us\iscsidsc.dll.mui
    Windows\System32\en-us\iscsiexe.dll.mui
    Windows\System32\en-us\iscsilog.dll.mui

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]
    "Godzilla"=hex(7):4d,00,53,00,69,00,53,00,43,00,53,00,49,00,00,00,00,00
     
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI]
     
    [HKEY_LOCAL_MACHINE\PE_Soft\Microsoft\Windows NT\CurrentVersion\iSCSI\Discovery]
    "AllowiSNSFirewallException"=dword:00000001
     
    [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]
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\LEGACY_MSISCSI]
    "NextInstance"=dword:00000001
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\LEGACY_MSISCSI\0000]
    "Service"="MSiSCSI"
    "Legacy"=dword:00000001
    "ConfigFlags"=dword:00000000
    "Class"="LegacyDriver"
    "ClassGUID"="{8ECC055D-047F-11D1-A537-0000F8753ED1}"
    "DeviceDesc"="@%SystemRoot%\\system32\\iscsidsc.dll,-5000"
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT]
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT\0000]
    "ClassGUID"="{4d36e97b-e325-11ce-bfc1-08002be10318}"
    "Class"="SCSIAdapter"
    "HardwareID"=hex(7):52,00,4f,00,4f,00,54,00,5c,00,69,00,53,00,43,00,53,00,49,\
      00,50,00,72,00,74,00,00,00,00,00
    "ConfigFlags"=dword:00000000
    "Driver"="{4d36e97b-e325-11ce-bfc1-08002be10318}\\0000"
    "Mfg"="@iscsi.inf,%msft%;Microsoft"
    "Service"="iScsiPrt"
    "DeviceDesc"="@iscsi.inf,%iscsiprt%;Microsoft iSCSI Initiator"
    "Capabilities"=dword:00000000
     
    [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]
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT\0000\LogConf]
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Enum\Root\ISCSIPRT\0000\Control]
    "ActiveService"="iScsiPrt"
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\iScsiPrt]
    "DisplayName"="iScsiPort Driver"
    "ImagePath"=hex(2):73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,44,00,\
      52,00,49,00,56,00,45,00,52,00,53,00,5c,00,6d,00,73,00,69,00,73,00,63,00,73,\
      00,69,00,2e,00,73,00,79,00,73,00,00,00
    "ErrorControl"=dword:00000001
    "Start"=dword:00000000
    "Type"=dword:00000001
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\iScsiPrt\Parameters]
    "BusType"=dword:00000009
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\iScsiPrt\Enum]
    "0"="Root\\ISCSIPRT\\0000"
    "Count"=dword:00000001
    "NextInstance"=dword:00000001
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\MSiSCSI]
    "DisplayName"="@%SystemRoot%\\system32\\iscsidsc.dll,-5000"
    "Group"="iSCSI"
    "ImagePath"=hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,00,6f,00,\
      74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
      00,76,00,63,00,68,00,6f,00,73,00,74,00,2e,00,65,00,78,00,65,00,20,00,2d,00,\
      6b,00,20,00,6e,00,65,00,74,00,73,00,76,00,63,00,73,00,00,00
    "Description"="@%SystemRoot%\\system32\\iscsidsc.dll,-5001"
    "ObjectName"="LocalSystem"
    "ErrorControl"=dword:00000001
    "Start"=dword:00000002
    "Type"=dword:00000020
    "ServiceSidType"=dword:00000001
    "RequiredPrivileges"=hex(7):53,00,65,00,41,00,75,00,64,00,69,00,74,00,50,00,72,\
      00,69,00,76,00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,43,00,68,00,\
      61,00,6e,00,67,00,65,00,4e,00,6f,00,74,00,69,00,66,00,79,00,50,00,72,00,69,\
      00,76,00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,43,00,72,00,65,00,\
      61,00,74,00,65,00,47,00,6c,00,6f,00,62,00,61,00,6c,00,50,00,72,00,69,00,76,\
      00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,43,00,72,00,65,00,61,00,\
      74,00,65,00,50,00,65,00,72,00,6d,00,61,00,6e,00,65,00,6e,00,74,00,50,00,72,\
      00,69,00,76,00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,49,00,6d,00,\
      70,00,65,00,72,00,73,00,6f,00,6e,00,61,00,74,00,65,00,50,00,72,00,69,00,76,\
      00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,54,00,63,00,62,00,50,00,\
      72,00,69,00,76,00,69,00,6c,00,65,00,67,00,65,00,00,00,00,00
    "FailureActionsOnNonCrashFailures"=dword:00000001
    "FailureActions"=hex:50,46,00,00,01,00,00,00,01,00,00,00,03,00,00,00,14,00,00,\
      00,01,00,00,00,c0,d4,01,00,01,00,00,00,e0,93,04,00,00,00,00,00,00,00,00,00
    "RebootMessage"="See Note 3 below"
    "FailureCommand"="customScript.cmd"
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\MSiSCSI\Parameters]
    "ServiceDll"=hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,00,6f,\
      00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\
      69,00,73,00,63,00,73,00,69,00,65,00,78,00,65,00,2e,00,64,00,6c,00,6c,00,00,\
      00
    "ServiceDllUnloadOnStop"=dword:00000001
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\MSiSCSI\Enum]
    "0"="Root\\LEGACY_MSISCSI\\0000"
    "Count"=dword:00000001
    "NextInstance"=dword:00000001
    
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Services\MSiSCSI]
    "ImagePath"=hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,00,6f,00,\
      74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
      00,76,00,63,00,68,00,6f,00,73,00,74,00,2e,00,65,00,78,00,65,00,20,00,2d,00,\
      6b,00,20,00,47,00,6f,00,64,00,7a,00,69,00,6c,00,6c,00,61,00,00,00
     
    Windows Registry Editor Version 5.00
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}]
    "LegacyAdapterDetection"=dword:00000000
    "Class"="SCSIAdapter"
    "ClassDesc"="@%SystemRoot%\\System32\\SysClass.Dll,-3005"
    @="@%SystemRoot%\\System32\\SysClass.Dll,-3005"
    "IconPath"=hex(7):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
      74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
      00,65,00,74,00,75,00,70,00,61,00,70,00,69,00,2e,00,64,00,6c,00,6c,00,2c,00,\
      2d,00,31,00,30,00,00,00,00,00
    "Installer32"="SysClass.Dll,ScsiClassInstaller"
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0000]
    "InfPath"="iscsi.inf"
    "InfSection"="iScsiPort_Install_Control"
    "ProviderName"="Microsoft"
    "DriverDateData"=hex:00,80,8c,a3,c5,94,c6,01
    "DriverDate"="6-21-2006"
    "DriverVersion"="6.0.6000.16386"
    "MatchingDeviceId"="root\\iscsiprt"
    "DriverDesc"="Microsoft iSCSI Initiator"
    "EnumPropPages32"="iscsipp.dll,iSCSIPropPageProvider"
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0000\Parameters]
    "TCPConnectTime"=dword:0000000f
    "TCPDisconnectTime"=dword:0000000f
    "WMIRequestTimeout"=dword:0000001e
    "DelayBetweenReconnect"=dword:00000005
    "MaxPendingRequests"=dword:000000ff
    "EnableNOPOut"=dword:00000000
    "MaxTransferLength"=dword:00040000
    "MaxBurstLength"=dword:00040000
    "FirstBurstLength"=dword:00010000
    "MaxRecvDataSegmentLength"=dword:00010000
    "MaxConnectionRetries"=dword:ffffffff
    "MaxRequestHoldTime"=dword:0000003c
    "LinkDownTime"=dword:0000000f
    "IPSecConfigTimeout"=dword:0000003c
    "InitialR2T"=dword:00000000
    "ImmediateData"=dword:00000001
    "ErrorRecoveryLevel"=dword:00000002
    "PortalRetryCount"=dword:00000005
    "NetworkReadyRetryCount"=dword:0000000a
    "SrbTimeoutDelta"=dword:0000000f
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0000\PersistentTargets]
    @=""
     
    [HKEY_LOCAL_MACHINE\PE_Sys\ControlSet001\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\Properties]
    "DeviceType"=dword:00000004
    "DeviceCharacteristics"=dword:00000100
    "Security"=hex:01,00,04,90,00,00,00,00,00,00,00,00,00,00,00,00,14,00,00,00,02,\
      00,34,00,02,00,00,00,00,00,14,00,ff,01,1f,10,01,01,00,00,00,00,00,05,12,00,\
      00,00,00,00,18,00,ff,01,1f,10,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,\
      00
  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.

Reference

  1. WinPE v3.0 and Microsoft iSCSI Initiator. URL: http://www.gregorystrike.com/2010/01/08/winpe-v3-0-and-microsoft-iscsi-initiator/

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 192.168.0.181 filename gpxelinux.0
Nov 28 08:58:09 dolphin in.tftpd[24604]: RRQ from 192.168.0.181 filename pxelinux.cfg/0338a9f6-d2b1-11df-9ec1
-0013d4d9c9e8
Nov 28 08:58:09 dolphin in.tftpd[24605]: RRQ from 192.168.0.181 filename pxelinux.cfg/01-70-71-bc-a8-4f-43
Nov 28 08:58:09 dolphin in.tftpd[24606]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A800B5
Nov 28 08:58:09 dolphin in.tftpd[24607]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A800B
Nov 28 08:58:09 dolphin in.tftpd[24608]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A800
Nov 28 08:58:09 dolphin in.tftpd[24609]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A80
Nov 28 08:58:09 dolphin in.tftpd[24610]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A8
Nov 28 08:58:09 dolphin in.tftpd[24611]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0A
Nov 28 08:58:09 dolphin in.tftpd[24612]: RRQ from 192.168.0.181 filename pxelinux.cfg/C0
Nov 28 08:58:09 dolphin in.tftpd[24613]: RRQ from 192.168.0.181 filename pxelinux.cfg/C
Nov 28 08:58:09 dolphin in.tftpd[24614]: RRQ from 192.168.0.181 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;
  6.  
  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. }
  12.  
  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