Ugly Stool Rotating Header Image

April, 2011:

How to Create a WinPE ISO

Download the Windows Automated Installation Kit, or WAIK (pronounced “wake”) from Microsoft.  WAIK’s are versioned by the OS they are based on.  For example, there is WAIK for Vista/Server 2008, and another for WAIK for Windows 7/Server 2008 R2.  (WAIK for Windows 7/Server 2008 R2 SP1 was recently released.)

After installing WAIK execute the following instructions to build a WinPE x86 (32-bit) ISO image.  (You need to run as an administrator to execute some of these commands.)  WinPE is a stripped down Windows 7 OS and only supports the architecture it is built against.  For example, the amd64 (64-bit) does not support running 32-bit binaries even though the full OS does.  If the application you want to run is strictly 64-bit use amd64, likewise if it is a 32-bit application use x86.  (ia64 support is available too.).

cd "\Program Files\Windows AIK\Tools\PETools"
pesetenv.cmd
copype.cmd x86 c:\windowspe-x86
cd "\Program Files\Windows AIK\Tools\Servicing"
dism /Mount-Wim /WimFile:c:\windowspe-x86\winpe.wim /Index:1 /MountDir:c:\windowspe-x86\mount
copy ..\x86\imagex.exe c:\windowspe-x86\mount\Windows\System32\
dism /Add-Package /PackagePath:..\PETools\x86\WinPE_FPs\winpe-scripting.cab /image:c:\windowspe-x86\mount
dism /Add-Package /PackagePath:..\PETools\x86\WinPE_FPs\winpe-wmi.cab /image:c:\windowspe-x86\mount
dism /Unmount-Wim /Commit /MountDir:c:\windowspe-x86\mount
copy c:\windowspe-x86\winpe.wim c:\windowspe-x86\ISO\sources\boot.wim
..\x86\oscdimg.exe -n -bc:\windowspe-x86\etfsboot.com c:\windowspe-x86\ISO c:\windowspe-x86\windowspe-x86.iso

This is a basic WinPE with two packages added via the dism command.  The winpe-scripting.cab package installs code to run WSH scripts – think VBscript and JScript.  The winpe-wmi.cab package supports the execution of the WMI commands.  WMI is useful for interrogating the system’s resource from the command line.  Documentation for other WinPE packages is available at MSDN.

Step 6 copies the imagex.exe executable into the WinPE because it is not installed by default.  ImageX is used to copy disk/OS images from an existing machine, and for applying disk/OS images.  (Not sure why the default image does not include ImageX as it is the OS deployment tool.)

Device drivers can be installed into a WinPE image using the dism command.  For example, if the drivers have been unzip’ed into c:\drivers, the following command would install all drivers found into the WinPE mount point.  (The WinPE image must still be mounted, step 5, for this command to work.)  WAIK for Windows 7 includes the drivers for Hyper-V, such as the synthetic NIC.

dism /Add-Driver /Driver:c:\drivers /Recurse /ForceUnsigned /image:c:\windowspe-x86\mount

Installing other programs into WinPE is as simple as copying the binaries into the mounted WinPE image.  The program must be compiled for the target architecture (32 vs. 64).  The deployment process can be scripted using VBscript or JScript, but I think ruby is more expressive.  Download the ruby-1.9.1p378 binary for windows, and extract the contents into the mount point.  Rebuild the CD using oscdimg, and viola!

image

If you want to start a program when WinPE boot, simply start it from the startnet.cmd file located in \Windows\System32.

I would also recommend adding the UnxUtils because they are small and you get useful command line utilities (find and grep) in a limited WinPE environment.

It is interesting that WAIK includes an ISO creation tool – oscdimg.exe.  Unfortunately, the license is rather strict.

C:\Program Files\Windows AIK\Tools\Servicing>..\x86\oscdimg.exe ISO -help

OSCDIMG 2.55 CD-ROM and DVD-ROM Premastering Utility

Copyright (C) Microsoft, 1993-2007. All rights reserved.

Licensed only for producing Microsoft authorized content.

Syslinux

This is a post of me meandering through the Syslinux source code, there isn’t a real point.

Syslinux is most closely associated with Linux, but it actually supports the booting of other OS’s.  It can boot over the network (PXE), CD-ROM, and various file systems.

I am working on a project that utilizes Syslinux; the project must read and write Syslinux boot configuration files.  I need to understand the available options, and what they mean.  The best place to start is with the Syslinux documentation, and the relevant code.  (The real impetus for this project is to learn Scala.)

I was reading the parsing source code that I found in com32/menu/readconfig.c, but I could not find the code that configured the serial console.  The documentation has this to say about serial port configuration.

For the SERIAL directive to be guaranteed to work properly, it
should be the first directive in the configuration file.

Despite this statement, I could not find any code to parse the serial directive, so I started to ack.  I found the method __syslinux_get_serial_console_info(void), which seemed like a good start.  The prototype had an attribute that did not make sense to me – __constructor__.

void __constructor __syslinux_get_serial_console_info(void)
{
    static com32sys_t reg;
    memset(&reg, 0, sizeof reg);
    reg.eax.w[0] = 0x000b;
    __intcall(0x22, &reg, &reg);
    __syslinux_serial_console_info.iobase = reg.edx.w[0];
    __syslinux_serial_console_info.divisor = reg.ecx.w[0];
    __syslinux_serial_console_info.flowctl = reg.ebx.w[0];
}

I asked the oracle, and found out that this is a GCC-ism, that guarantees the function is invoked before main().  But, wait, there is even more coolness going on.  What about com32sys_ and intcall!

I went back to the oracle, and asked about interrupt 0x22.  I found out that it is typically reserved for DOS methods, so I assumed that Syslinux was hooking the interrupt to provide system calls.

After some more acking I found out the intcall function’s methods are the following. 

  1. interrupt handler to invoke
  2. register values to pass to the invoked system call; call executed is determined by the value in EAX.
  3. register results of the invoked system call

The actual system calls are setup in comboot.inc.  The assembly code calls into C code to do the heavy lifting.  Comboot is an API to extend Syslinux, and there are several projects that take advantage of it.

Back to the code…

Scala, SBT, and IntelliJ

I started a personal project to learn Scala, and I had zero idea where to start – how do I build Hello World and then continue to scale it.  I know how to do it with make/gcc, ant/Eclipse, and VisualStudio.  From reading various Scala projects on github and code.google.com it was clear that people where using some combination of sbt, maven, and IntelliJ.

I know nothing about Maven, but at first blush it is intimidating – I am sure it is my lack of knowledge.  I punted on maven.  sbt appears (stress on appears) simple, and it is written in and developers configure it by writing Scala.

The IntelliJ pick is more of an experiment to see how it compares to Eclipse.  I know not everyone thinks you should change editors.

There may be better ways to combine sbt and IntelliJ, but this one is fairly easy.  I assume sbt is already installed.

Step 1 – SBT

Create a directory to hold your project, and then create an empty project by invoking sbt.

$ mkdir test
$ cd test
$ sbt
Project does not exist, create new project? (y/N/s) y
Name: example
Organizatoin: org.example
Version [1.0]:
Scala version [2.8.1]:
sbt version [0.7.5]:
...
> exit

Note: SBT uses Scala version 2.7.7, but builds your project with Scala 2.8.1.

Step 2 – Build

Create a .scala file to control the building of your project, and to specify your project’s dependencies.

$ mkdir project\build
$ notepad project\build\project.scala

This file includes example dependencies for Squeryl.

import sbt._
class Project(info: ProjectInfo) extends DefaultProject(info)
      with IdeaProject {
  val mysql = "mysql" % "mysql-connector-java" % "5.1.15"
  val squeryl = "org.squeryl" % "squeryl_2.8.1" % "0.9.4-RC6"
  override def libraryDependencies = Set(
    mysql,
    squeryl
  ) ++ super.libraryDependencies
}

Step 3 – Plugin

Add the IntelliJ plugin to SBT.

$ mkdir project\plugins
$ notepad project\plugins\plugins.scala

Create the plugins.scala file, and add the appropriate reference.

import sbt._
class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
    val sbtIdeaRepo  = "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"
    val sbtIdea = "com.github.mpeltonen" % "sbt-idea-plugin" % "0.4.0"
}

Step 4 – Build

Create a Hello World application to build, and put it in src/main/scala/.

object Program {
    def main(args: Array[String]): Unit = {
        println("Hello World")
    }
}

Launch sbt, and fetch the dependencies. Execute the idea command to create an IntelliJ project.

$ sbt update
$ sbt idea
$ sbt run

Once the files have been created simply open the project using IntelliJ.  sbt can be executed from within IntelliJ using the idea-sbt-plugin

Page optimized by WP Minify WordPress Plugin