posts - 20 , comments - 57 , trackbacks - 0

Monday, August 3, 2015

x86 bootloader for WCE8

This blog will reveal how to build the Windows CE bootloader for x86 that shipped with Windows CE 6. This bootloader also works for Windows CE 7 and 8 (CE2013)

Locate the x86 bootloader code in WINCE600\PLATFORM\CEPC\SRC\BOOTLOADER and copy it "as is" to WINCE600\PLATFORM\<YourBsp>\SRC\BOOTLOADER. Making any changes now to <YourBsp> prevents that the CEPC sources are "polluted" with your changes. You can also copy the BOOTLOADER sources to a Windows CE 7 or 8 platform directory. The bootloader will work fine too for these versions.

The normal build step is to open a Release Directory in a Build Window and "Build -c".
If you do so on the BOOTLOADER directory, you will get a number of build errors. How to fix this?

First we need to understand what we can expect. The bootloader consists of 2 parts: BSECT and BLDR:

  • BSECT (BootSECTor) is a 512 bytes binary image that is always located in sector 0 of a bootable disk. The BIOS locates it by checking that the last two bytes are FF AA and boot jumps to it. The code inside BSECT can do 2 things; either jump to the real OS bootloader or jump again to a new BSECT. The latter happens e.g. on a FAT file system. Each physical disk in FAT can contain up to 4 partitions or volumes. One of them can be marked as active partition, meaning it contains again a BSECT sector. This 2nd BSECT now will jump to the OS bootloader.
  • BLDR is the actual Windows CE bootloader, here referred to as biosloader as it uses BIOS functionality for disk, video, COM, keyboard, ... access. Other bootloaders could implement own driver code to access hardware to be independent of a BIOS.
We will build both BSECT and BLDR. Contrary to a normal Windows CE build, not a sources file is build, but instead (DOS) batch files are used.
  • The batch file itself uses an old DOS tool DEBUG.EXE to extract (cut and paste) bytes from an EXE or COM executable. Too old to explain every bit of it here, but you could use any other tool that can cut bytes from an offset + length of a file and paste them to another file. It mainly is used to strip off the PE header of an EXE file. You should know that this tool only runs on desktop Windows 32bit in compatibility mode. And DEBUG.EXE can only been run from a path that does not contain more than 64 characters... (old DOS tool I said). As I run my Windows CE builds from inside a Virtual Machine that runs Windows 7 32bit, this is not a problem.
  • The batch file also uses an oldish assembler compiler. The package that comes with this blog contains this old Windows 3.1/95 Windows assembler... You could also use the open source MASM32 assembler that is compatible with the Microsoft Assembler.

Now, let us examine what is located in the BOOTLOADER directory? We are only interested in the BIOSLOADER subdirectory. This directory contains on its turn the following directories:

  1. BOOTSECTOR: contains the sources to build the BSECT image.
  2. DISKIMAGES: contains ready to use images. We are not using these, we build our own.
  3. INIPARSER: builds a library used to parse commandline options and some utility functions.
  4. LOADER: contains the sources to build the BLDR bios loader
  5. UTILITIES: sources of some utility programs needed or useful to prepare your bootable disk to boot a Windows CE OS.

We build for FAT32 filesystem, the most commonly used filesystem supported by all Windows (and Linux) versions.

    2. Run from Release build window 'build2.bat'. The batch file is an edited version of the original 'build.bat', mainly referring to other paths (assembler and linker).
    3. This builds a FAT32 compatible partition bootloader.
    4. The result is BSECT.IMG, a binary image of 512 bytes.
  2. BLDR:
    2. Run from Release build window 'build -c'. It is important to build the Release version to fit in 64k memory.
    4. Run from Release build window 'build -c'. It is important to build the Release version to fit in 64k memory.
    6. Run from Release build window 'makebldr2.bat'. The batch file is an edited version of the original 'build.bat', it refers to boot2.bib, which on its turn is an edited version (increase of RAMSIZE to fit in memory).
      BLDR 00001000 00006000 RAMIMAGE ; Size should be evenly divisible by 512b.
    7. The result is BLDR, a binary image of 24k bytes that runs in 64k memory space. 'makebldr2.bat' uses the 'build' tool that can only work in 32bit Windows and cannot be run from a full path with more than 64 characters. If so, copy the contents of FIXED\FAT32 folder to a folder with less characters before executing 'makebldr2.bat'

As usual, there are bugs in the shipped source code.

  1. BLDR cannot locate NK.BIN if its first cluster is located above cluster# 65535. When you create a clean formatted disk and copy NK.BIN to the FAT32 filesystem, NK.BIN's first cluster is typically below 65535. The source code only takes the lowest 16bit cluster value into account. However if you delete, move, copy the file often, it might be located above 65535 on larger sized disks with > 64k clusters. If so, BLDR cannot locate NK.BIN anymore, failing to boot.
  2. To fix it, change the following in WINCE600\PLATFORM\<YourBsp>\SRC\BOOTLOADER\BIOSLOADER\LOADER\FIXED\FAT32\fat32.h

    // // FAT directory entry structure. // #pragma pack(1) #if 0 // Original typedef struct { UCHAR FileName[8]; UCHAR FileExt[3]; UCHAR FATTr; UCHAR FOO[10]; USHORT LModTime; USHORT LModDate; USHORT FirstClust; ULONG FileSize; } DIRENTRY, *PDIRENTRY; #else // New, more correct typedef struct { UCHAR FileName[8]; UCHAR FileExt[3]; UCHAR FATTr; ULONG CreateTime; USHORT CreateDate; USHORT LAccessDate; USHORT FirstClustH; // high 16bit USHORT LModTime; USHORT LModDate; USHORT FirstClustL; // low 16bit ULONG FileSize; } DIRENTRY, *PDIRENTRY; #endif #pragma pack()


    if (!bFound || pDirEntry == NULL) { WARNMSG(MSG_FILE_NOT_FOUND, ("File '%s' not found\n", pFileName)); return(0); } else { ULONG FirstClust = (pDirEntry->FirstClustH << 16) + pDirEntry->FirstClustL; // Create 32bit cluster to locate file in larger sized disks with > 64K clusters INFOMSG(MSG_FILE_FOUND, ("Found file '%s' (start=0x%x size=0x%x)\n", pFileName, FirstClust, pDirEntry->FileSize)); }

  3. While starting BLDR, it enumerates the BIOS to list the available video modes. These video modes are listed in a BIOS table, usually the first table entries are consequentially filled with valid video modes. However some BIOS do not list valid video modes in the first entries, instead they are listed further down the table. BLDR did not handle this situation correctly.

    To fix it, change the following in WINCE600\PLATFORM\<YourBsp>\SRC\BOOTLOADER\BIOSLOADER\LOADER\FIXED\MAIN\video.c

    // Iterate over available video modes for (i = 0; pVideoModeList[i] != 0xFFFF; i++) { if ((ulVbeStatus = BIOS_VBEModeInfo(&vesaModeInfo, pVideoModeList[i])) != 0x004F) { WARNMSG(MSG_CANNOT_GET_MODE_INFO, ("Cannot get mode info (status=0x%x)\n", ulVbeStatus)); //break; // Some BIOS return an error code on this 'pVideoModeList[i]' instance, but continue on the next one. Don't break, but continue search... } ... }


From WCE7 onwards, CEPC platform ships with WCELDR, an alternative bootloader for x86 platforms. It has many advantages over BLDR, but cannot work with single partition/volume disk images. This is usually not a problem, it depends mainly on how you format your CE boot disk image.


CeSys.exe is a tool to prepare your fresh formatted (FAT32) disk image to be bootable from the first partition/volume. It also copies BSECT to the first sector (MasterBootRecord, MBR). Although the sources suggest it is a DOS tool, you can easily compile it as a modern desktop Windows program. You can find it in WINCE600\PLATFORM\<YourBsp>\SRC\BOOTLOADER\BIOSLOADER\UTILITIES\CESYS\DOS.

Create a bootable BLDR disk

  1. Build BSECT.IMG and BLDR
  2. Format your disk (from desktop Windows) to FAT32 filesystem. Set volume label to empty (blank).
  3. Build CeSys.exe
  4. Run 'CeSys.exe z: bsect.img bldr -f -a' to make your disk CE bootable.
  5. Run 'BinCompress.exe /C YourSplashImage.bmp splash.bmx' from a WCE Release Directory in a Build Window
  6. Copy NK.BIN, boot.ini and splash.bmx to the root of your disk.
  7. Insert disk in your CE device and boot.

Useful references:

Posted On Monday, August 3, 2015 8:48 PM | Comments (0) | Filed Under [ Windows Embedded Compact Embedded Microsoft BootLoader ]

Powered by: