Friday, April 7, 2017

WCE7 detailed boot procedure

Here is a detailed description of how, theoretically, Windows CE boots on a device..

BUILD-TIME:

1. ROMIMAGE fixes up binaries in the OS image
An EXE or a DLL can be fixed up, which means that they are modified to adjust the variables and functions addresses depending on the binary location in virtual memory. At build time, the compiler doesn't know where the binaries will be located, so all of the pre-built addresses are wrong and need to be updated at load time. This is exactly what ROMIMAGE does when inserting the binaries in the final image that reflects the device's memory. To achieve this, ROMIMAGE relies on config.bib.
Note: All EXE and DLL files have a reserved section to be fixed up.
Note 2: All EXE and DLL files have an entry point that can be read in binary.

The image will contain 2 major binaries that will be required to boot:

Binary Description
NK.exe Contains all the functionality that is platform and architecture specific (typically, the OAL)
kernel.dll Contains architecture-neutral functionalities 

2. ROMIMAGE places tge TOC in the image file and fills pTOC variable with the location address
TOC stands for "Table Of Content". When all binaries have been placed in the image by ROMIMAGE, the start address of every binary is listed into a TOC structure. The TOC is then placed in the image as well.
The TOC will be needed at runtime and is accessible in the OAL with a pointer named pTOC. The value of this pointer is -1 at build time because the location of the TOC is unkown at this moment. The value is updated by ROMIMAGE once the TOC has been placed in the image.

Using the TOC, the program can find all other pieces of the operating system image.

BOOT TIME:

3. Bootloader puts the image at the right place in memory
4. Bootloader looks for the TOC in the image
Bootloader does not have access to pTOC variable (it is not part of NK.exe). Instead, it will use a trick done by ROMIMAGE.
When the TOC is placed in the image, it is prepended with a marker : "CECE" (or 0x44424442). The bootloader will find this marker and read the TOC.
5. Bootloader looks for NK.exe in TOC
6. Bootloader jumps to the entry point of NK.exe
7. NK.exe calculates the physical address of OEMAddressTable
At this moment of boot, the memory can only be addressed physically.
OEMAddressTable is a symbol in NK.exe, which means that it has a virtual memory fixed by ROMIMAGE. NK.exe knows its own physical location in memory and its future location in virtual memory.
OEMAddressTable physical address = (Physical address of NK.exe) + ( (OEMAddressTable virtual address) - (Virtual base address of NK.exe) )
8. NK.exe sets up the virtual memory mapping for the MMU
Virtual memory is now enabled and NK.exe moves to virtual memory.
However, RAM has not been initialized yet which means that all read/write variables can have any content whatsoever.
9. NK.exe copies the "copy entries" to RAM (R/W portions or RAM)
The function that does this is KernelReloacte().
The TOC describes also the RAM and where the read/write portions of each module are to be located. Pieces of OS image that need to be copied to RAM are called "copy entries".
Note: Obviously, pTOC is not located in RAM otherwise none of this would work. It is in ROM (const variable).
10. NK.exe sets up the Kernel Data Page and its initial content
Windows CE reserves a few regions of virtual address range for its own private use inside the OS kernel. There are several 4k pages of virtual memory from 0xFFFE0000 upwards. At least one page is reserved to Kernel Data Page.
NK.exe sets up the location and inserts:
  • A copy of TOC
  • The address of OEMAddressTable
  • The address of the function OEMInitGlobals()
11. NK.exe jumps to kernel.dll entry point with the address of the kernel data page as parameter
12. kernel.dll calls OEMInitGlobals() with the address of NKGlobals as parameter and gets the dadress of OEMGlobals as a return value

Variable Description
NKGlobals Static table of functions (ex: SetLastError(), NKwvsprintfW() ) and data in kernel.dll
OEMGlobals Static table of functions pointers and data : PFN_InitDebugSerial(), PFN_Ioctl(),... The functions pointers points to legacy OEM_xxx() functions (like OEMInitDebugSerial())

Once the call to OEMInitGlobals() completes, the kernel.dll has everuthing it needs to architecture-generic and platform-specific processing. It knows how memory is laid out virtually and where are all modules in the image.
NK.exe has also access to a set of kernel functions that it can call.
13. kernel.dll runs architecture-specific setup (ARMSetup() or X86Setup())
During this step, Interlocked API will be copied to Kernel Data Page. This is a critical part of the system that manages the coordination between threads.
14. kernel.dll runs architecture-neutral setup
Initialization of kernel debug output, selection of kernel processor type, check of the presence of KITL.dll.
Note: KITL is the system debugger.
Note 2: KITL can be loaded as a dll or directly included in the OAL. If the dll exists, it is loaded here.
15. kernel.dll runs platform-specific setup (OEMInit())
Platform specific initialization. KITL is started (if included in the image).
16. kernel.dll runs its first thread (SystemStartupFunc())
17. SystemStartupFunc() initializes the system
System loader, paging pool, system logging, system debugger, message queue, watchdog.
Creates a thread for Power Management.
Creates a thread for File System.
18. SystemStartupFunc() creates another thead which calls RunAppAtStartup()
This new thread creates first user processes.

WCE7 : Types of drivers

The Windows CE device drivers model takes into consideration 3 types of drivers:

Type of driver Description
Native drivers Built-in device drivers. They implement a feature-specific interface (Device Drivers Interface, DDI). They are loaded by GWES. Typical built-in drivers are:
- Display driver
- Touchscreen driver
- Keyboard driver
- Mouse driver
- LEDs drivers
Stream drivers Installable drivers. They implement a standard IO interface used for all types of IO devices (Init, DeInit, Open, Close, Read, Write...). They are configured in the registry and mounted by a device manager. They are very easy to add. Typical stream drivers are:
- Serial drivers
- Bus drivers
- Block drivers (for storage devices)
- Specific stream drivers
Hybrid drivers Stream drivers that implement an additional specific interface to their dedicated feature. Mounted by device manager but used by other processes through their specific interfaces. Example of hybrid drivers:
- Audio drivers
- PCMCIA controller drivers
- USB drivers

Types of architecture

Type of architecture Description
Layered Split into 2 layers : Model Device Driver (MDD) and Platform dependent device (PDD). The MDD implements the functional behaviors of the device that are independent of the device that is managed by the driver. Usually, this layer does not need to be modified.
The PDD implements treatments that are specific to the device being managed.
Windows CE device driver model defines the interface of PDD allowing the development of a PDD without caring about what MDD does. The interface of PDD is standardized but specific for each type of driver (Device Driver Service provider Interface, DDSI)
Monolithic Merge of MDD and PDD into one layer. Poor reusability. This type of drivers are mainly used for simple driver, without functional layer.


WCE7 : Customize your BSP

We suppose here that all the components required for your OSDesign are already in the catalog of your source platform. This is basically the case when you clone an existing BSP.
To customize your BSP, you will have to check the features you want to include in your OS image. Additionally, you can add registry settings, files or even add a new device driver if required (this is not explained here). This page gives an overview of a BSP customization for the BeagleBone Black platform.

 

Select your features


BSP features

Open Catalog Items View and unfold Third Party->BSP-><your BSP name>.
You have here all platform-specific components that you can reuse on your target platform.
Here is a picture of a possible selection for the BBB:


Core OS

Open Catalog Items View and unfold CoreOS->Windows Embedded Compact.
The core OS features are platform-independent which means that they can be used on any target platform. Some of these options are related to the BSP features (via SYSGEN_xxx variables) and that's why some checkboxes are already checked (with a green square usually).
Below is an overview of the checked features for the BBB. We excluded IE7 support, media players, audio decoders, battery support... :


Add files to your BSP

If you want to add some files to your BSP, they need to be placed in C:\WINCE700\platorm\<your bsp>\Files.
All files located in this directory will be copied to the build release directory during build process.
To manage the files you want to copy to your output directory, you need to edit OSDesign.bib (you can also do this from C:\WINCE700\platorm\<your bsp>\Files\PLATFORM.BIB but it would applied to all OSDesigns).
For instance, if you want to add CoreCon files, you should append the following lines under FILES section:
eDbgTL.dll            $(_FLATRELEASEDIR)\eDbgTL.dll                    NK    S
TcpConnectionA.dll    $(_FLATRELEASEDIR)\TcpConnectionA.dll            NK    S

Reminder: All of these files need to be located in C:\WINCE700\platorm\<your bsp>\Files.
Setting Description
NK NK memory block specified in config.bib file (output NK.bin image)
S System file (will be located as system file in \Windows directory)
H Hidden file
K Kernel file
(for example, use SHK for a hidden system file located in kernel space).

 

What if I put these lines under MODULE section ?

The files put in MODULES will be processed by romimage so that the executable can be executed in eXecute In Place (XIP) from the ROM image. If you are not interested in that, put files in FILES section.

KITL and serial Debug

As explained here
When launching an OS image from the target device’s local storage, built with the above debugging helper components enabled, the OS image may not be able to function as intended and may not be able to complete the boot process, such as:
  • When an OS image is generated with KITL component enabled, it attempts to establish connection with an unavailable KITL connection, which causes the OS not able to complete the boot process.
  • When an OS image is generated with the serial debug component enabled, the serial debug component capture one of the available serial port, making the port unavailable to the device’s application.
So go through the following steps before building the image:
  • Open your project properties and disable KITL. Clik OK to apply

Additional registry settings


FTPD settings

Add these lines to your OSDesign.reg file to allow unauthenticated connections with anonymous credentials.
Set the default directory to root dir to give an access to all files remotely.
[HKEY_LOCAL_MACHINE\COMM\FTPD]
    "IsEnabled"=dword:1
    "UseAuthentication"=dword:0
    "UserList"="@*;" 
    "AllowAnonymous"=dword:1
    "AllowAnonymousUpload"=dword:1
    "AllowAnonymousVroots"=dword:1
    "DefaultDir"="\\" 

.NET CF runtime error bypass

The following error can happen at the execution of a .NET application after boot
.NET CF Initialization Error, The application failed to load required components. If the .NET Compact Framework is installed on a storage card... Support info:
-2147438590 (8000B002)
However, if we deploy an application from a PC to the remote device and start an app again it will work. This strange beahavior is due to a registry setting that is updated when we deploy an application.
To avoid this issue, edit OSDesign.reg and add the following lines
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NetCompactFramework\Managed Debugger]
    "AttachEnabled"=dword:0
And add the following files to your OSDesign (in C:\WINCE700\platform\<your BSP>\FILES):
%COMMONPROGRAMFILES%\Microsoft shared\CoreCon\1.0\Target\wce400\armv4i\eDbgTL.dll
%COMMONPROGRAMFILES%\Microsoft shared\CoreCon\1.0\Target\wce400\armv4i\TcpConnectionA.dll

WCE7 : How to write a device driver


Quick introduction

An application interacts with a device driver thanks to file system functions (CreateFile, ReadFile, WriteFile,...).
To identify the driver to be opened, the application needs to specify a file name to CreateFile:

* [Usual format] "XXXy:" : with X a capital letter and y a number in [1;9] (0 is authorize to indicate the 10th index)
* [Device mount point] "\\<device_mount_point>\\XXXy:"
* [Bus mount point] "\\<bus_mount_point>\\XXXy:"
The three capital letters form a prefix that will identify the driver. The number indicates the index of the driver if several can be instanciated.
This prefix is also used by Windows to load the device driver methods. In fact, the prefix shall precede the device driver methods in driver dll:
* XXX_CreateFile
* XXX_ReadFile
* ...

All device drivers are listed in registry below HKLM\Drivers\BuiltIn with at least the following subkeys:

Key Description
Prefix Explained above (e.g. "XXX")
Dll Driver dll method to be loaded

At system boot, Device Manager will iterate over these entries and load them. For every loaded driver, an entry will be created in HKLM\Drivers\Active.
The order of load can be specified if the driver entry specifies a key Order followed by a number that indicates when it shall be loaded (with 1 the first to be loaded)
Other optional subkeys can be used for a driver, but they won't be described here.
In the following chapters, we will create the necessary files to add a driver to our BSP. In the scope of this tutorial, we will create a driver for the DS1307 RTC chip.

 

Add a new catalog entry

The first step is to add a catalog entry to our BSP. To do so, either open the *.pbcxml file with Visual Studio and use the graphical interface or edit the *.pbcxml file and add the following lines:
<Bsp>
    ...
    <BspItemId>FT5X06_TOUCH:LNI Swissgass:FT5X06_LniBSP</BspItemId>
    <BspItemId>RTC_DS1307:LNI Swissgass:RTC_DS1307_LniBSP</BspItemId>
    <BspItemId>DVI_Type:LNI Swissgas:DVI_Type_LniBSP</BspItemId>
    ...
</Bsp>
<Item Id="RTC_DS1307:LNI Swissgass:RTC_DS1307_LniBSP">
    <Title>RTC driver</Title>
    <Description>Real Time Clock</Description>
    <Comment>Only valid for DS1307 chip</Comment>
    <Type>BspSpecific</Type>
    <Variable>BSP_RTC_DS1307</Variable>
    <Module>rtc_ds1307.dll</Module>
    <Location ConditionLocation="">Drivers\RTC</Location>
</Item>
These lines add a new driver to the catalog under Driver\RTC. If checked, this driver defines the variable BSP_RTC_DS1307.

 

Hands on code : create the driver component

Create a directory for our driver under <MyBSP>\SRC\Drivers : here we create a folder named RTC. The following steps are to be done in this directory.
The most obvious file to add to our componen is makefile. This file is always the same for all drivers so copy/paste an existing one or create it and add the following lines:
!if 0
Copyright (c) Microsoft Corporation.  All rights reserved.
!endif
!if 0
Use of this source code is subject to the terms of the Microsoft end-user
license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
If you did not accept the terms of the EULA, you are not authorized to use
this source code. For a copy of the EULA, please see the LICENSE.RTF on your
install media.
!endif
#
# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
# file to this component.  This file merely indirects to the real make file
# that is shared by all the components of Windows CE.
#
!INCLUDE $(_MAKEENVROOT)\makefile.def
Our driver needs to be declared in registry. Create an rtc_ds1307.reg file and the following lines:
IF BSP_RTC_DS1307
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\RTC_DS1307]
    "Prefix"="RTC" 
    "Dll"="rtc_ds1307.dll" 
    "Index"=dword:1
    "order"=dword:101                ; Should be loaded after I2C
ENDIF BSP_RTC_DS1307
The file structure of a WEC7 BSP requires a file named sources in every folder that contains files to take into consideration during build. Create one with the following lines:
!if 0
;================================================================================
; RTC Driver DS1307
;================================================================================
!endif

!IF "$(BSP_RTC_DS1307)" == "" 
SKIPBUILD=1
!ENDIF

TARGETNAME=rtc_ds1307
TARGETTYPE=DYNLINK

TARGETLIBS= \
    $(_PLATLIB)\$(_CPUDEPPATH)\ceddk.lib \
    $(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib

SOURCES= \
    rtc_ds1307.c \
Our driver will obviously need to export the stream interface driver methods. This is done with a *.def file as follows:
LIBRARY     RTC_DS1307

EXPORTS RTC_Init
    RTC_Deinit
    RTC_Open
    RTC_Close
    RTC_Read
    RTC_Write
    RTC_IOControl
And now, we can add some code :
//
//  File: rtc_ds1307.c
//
//  This file implements device driver for RTC DS1307. 
//
#include "omap.h" 
#include "ceddkex.h" 
#include "sdk_padcfg.h" 
#include "bsp_padcfg.h" 
#include "bsp.h" 

#include <nkintr.h>
#include <winuserm.h>
#include <pmpolicy.h>

// ==== Debug Zones ================================================================================
// simple handling: debug zones are forced with TRUE or FALSE and need a recompile to be activated
// for sophisticated handling: use macro DEBUGZONE(), DBGPARAM dpCurSettings etc.
// (see MSDN e.g. Win CE 5.0, Debug Zones)
#ifndef SHIP_BUILD

#undef ZONE_ERROR
#undef ZONE_WARN
#undef ZONE_FUNCTION
#undef ZONE_INFO
#undef ZONE_TIPSTATE

#define ZONE_ERROR          DEBUGZONE(0)
#define ZONE_WARN           DEBUGZONE(1)
#define ZONE_FUNCTION       DEBUGZONE(2)
#define ZONE_INFO           DEBUGZONE(3)
#define ZONE_TIPSTATE       DEBUGZONE(4)

static DBGPARAM dpCurSettings = {
    L"RTC_DS1307", {
        L"Errors",      L"Warnings",    L"Function",    L"Info",
            L"IST",         L"Undefined",   L"Undefined",   L"Undefined",
            L"Undefined",   L"Undefined",   L"Undefined",   L"Undefined",
            L"Undefined",   L"Undefined",   L"Undefined",   L"Undefined" 
    },
    // Bitfield controlling the zones.  1 means the zone is enabled, 0 disabled
    // We'll enable the Error, Warning, and Info zones by default here
    1 | 1 << 1 | 1 << 2 | 1 << 3
};

#endif

//------------------------------------------------------------------------------
DWORD RTC_Init(LPCTSTR szContext, LPCVOID pBusContext)
//  Called by device manager to initialize device.
{
    int i;
    DWORD rc = (DWORD)NULL;

    UNREFERENCED_PARAMETER(pBusContext);

    DEBUGMSG(ZONE_FUNCTION, (L"+RTC_Init(%s, 0x%08x)\r\n", szContext, pBusContext));
    RETAILMSG(1, (L"+RTC_Init\r\n"));

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (L"-RTC_Init(rc = %d\r\n", rc));

    return rc;
}

//------------------------------------------------------------------------------
BOOL RTC_Deinit(DWORD context)
{
    BOOL rc = FALSE;

    DEBUGMSG(ZONE_FUNCTION, (L"+RTC_Deinit(0x%08x)\r\n", context));

    rc = TRUE;

cleanUp:
    DEBUGMSG(ZONE_FUNCTION, (L"-RTC_Deinit(rc = %d)\r\n", rc));
    return rc;
}

//------------------------------------------------------------------------------
DWORD RTC_Open(DWORD context, DWORD accessCode, DWORD shareMode)
{
    UNREFERENCED_PARAMETER(context);
    UNREFERENCED_PARAMETER(accessCode);
    UNREFERENCED_PARAMETER(shareMode);
    return context;
}

//------------------------------------------------------------------------------
BOOL RTC_Close(DWORD context)
{
    UNREFERENCED_PARAMETER(context);
    return TRUE;
}

//------------------------------------------------------------------------------
DWORD RTC_Read(DWORD context, LPVOID pBuffer, DWORD Count)
{
    UNREFERENCED_PARAMETER(context);
    UNREFERENCED_PARAMETER(pBuffer);
    UNREFERENCED_PARAMETER(Count);
    return 0;
}

//------------------------------------------------------------------------------
DWORD RTC_Write(DWORD context, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
    UNREFERENCED_PARAMETER(context);
    UNREFERENCED_PARAMETER(pSourceBytes);
    UNREFERENCED_PARAMETER(NumberOfBytes);
    return 0;
}

//------------------------------------------------------------------------------
BOOL RTC_IOControl(
    DWORD context, DWORD code, BYTE *pInBuffer, DWORD inSize, BYTE *pOutBuffer,
    DWORD outSize, DWORD *pOutSize
) {
    UNREFERENCED_PARAMETER(context);
    UNREFERENCED_PARAMETER(code);
    UNREFERENCED_PARAMETER(pInBuffer);
    UNREFERENCED_PARAMETER(inSize);
    UNREFERENCED_PARAMETER(pOutBuffer);
    UNREFERENCED_PARAMETER(outSize);
    UNREFERENCED_PARAMETER(pOutSize);
    DEBUGMSG(ZONE_INIT, (L"RTC_IOControl"));
    return FALSE;
}

//------------------------------------------------------------------------------
BOOL __stdcall DllMain(HANDLE hDLL, DWORD reason, VOID *pReserved)
{
    UNREFERENCED_PARAMETER(pReserved);
    switch (reason) {
    case DLL_PROCESS_ATTACH:
        DEBUGREGISTER(hDLL);
        DisableThreadLibraryCalls((HMODULE)hDLL);
        break;
    }
    return TRUE;
}
and a header (optional):
#ifndef __RTC_DS1307_H
#define __RTC_DS1307_H

// Stream interface entry points

// Initialization of controlled hardware, setup of ISR and IST(if any),
// setup of memory access (if any) 
DWORD RTC_Init(LPCTSTR szContext, LPCVOID pBusContext);
// Cleans up what Init did
BOOL RTC_Deinit(DWORD context);
// Implicitely called by CreateFile
// Opens the context for client usage
DWORD RTC_Open(DWORD context, DWORD accessCode, DWORD shareMode);
// Closes the context opened in Open
BOOL RTC_Close(DWORD context);
// Use if required : read data out of driver
DWORD RTC_Read(DWORD context, LPVOID pBuffer, DWORD Count);
// Use if required : write data to driver
DWORD RTC_Write(DWORD context, LPCVOID pSourceBytes, DWORD NumberOfBytes);
// Driver specific functionality
BOOL RTC_IOControl(
    DWORD context, DWORD code, BYTE *pInBuffer, DWORD inSize, BYTE *pOutBuffer,
    DWORD outSize, DWORD *pOutSize
);

#endif // __RTC_DS1307_H

Add driver to project build

The driver component is ready, we need to include it to the project. As said earlier, the file structure of a BSP requires sources files to include files to build but also dirs files to list the directories that will be visited during build. Open <MyBSP>\SRC\Drivers\dirs and add an entry for our new driver.
DIRS=\
        ...
    FT5X06\
    RTC_DS1307\
    WAVEDEV2\
        ...
For rom image creation, we need now to tell the project that it should put the driver's dll into the image.
Open platform.bib and add the following lines:
...
IF BSP_RTC_DS1307
rtc_ds1307.dll    $(_FLATRELEASEDIR)\rtc_ds1307.dll            NK  SHK
ENDIF
...
Finally, add the following lines to platform.reg to integrate the component's registry settings:
...
;===============================================================================
; RTC DS1307 driver
#include "$(PLAT_DRIVERS_DIR)\RTC_DS1307\rtc_ds1307.reg" 
...
You're good to start the development of the driver.

WCE7 : Develop a touchscreen driver

The Compact 7 touch driver architecture includes a touch driver and a touch proxy driver (WinCE 6 legacy interface).


Component Description
Touch driver Stream interface driver implemented as a layered driver. MDD exports standard stream interface functions (Init, PreDeInit, PreClose, Close, PowerDown, PowerUp, Read and IOContol). Since this is a stream interface driver, it is loaded by Device Manager.
Touch proxy driver Provides the WinCE 6 touch API. GWES loads this driver instead of touch driver.
Touch calibration DLL Not compiled in the driver. Separate DLL provided by Compact 7
The picture above, shows:
  • The initialization mechanism with blue arrows
  • The touch event management with red arrows

Where to start ?

Most of the components introduced in the first part are already included in Compact 7:
  • Touch driver proxy : _WINCEROOT\Public\Common\Oak\Drivers\touch
  • Touch driver MDD : _WINCEROOT\public\common\oak\drivers\touch\tchstreammdd
  • Calibration DLL : _WINCEROOT\public\common\oak\drivers\touch\tchcaldll
The only part that needs to be developed is the touch driver PDD which is the platform-dependent module (MDD is the platform independent module).
The interface of PDD is defined by the DDSI (Device Driver Stream Interface) and includes the following methods:

Function Description
TchPdd_Init Returns the pointers to the DDSI interface and initialize hardware
TchPdd_DeInit Clean up (hardware deinit, memory release...)
TchPdd_PowerUp Called by MDD (implicitely by power manager) at power-up
TchPdd_PowerUp Called by MDD (implicitely by power manager) at power-down
TchPdd_Ioctl Specific-features offered to the MDD

Enable touch screen mechanism

To enable the Compact 7's internal touchscreen, the following variables need to be defined in the OS Design from catalog item view.

Variable Description
SYSGEN_TOUCH If defined, the touch cursor will be set

WCE7 : How to debug the BSP

Debugging is a key part in driver development. It helps to step into the code at runtime and analyze the memory stacks.

 

How to enable debugging ?

Debugging is handled by KITL (Kernel Independent Transport Layer) in Windows Embedded Compact. KITL makes the connection between host and target device and transports debugging information.
To enable it, here are the main steps:
  • Select the DEBUG configuration in your BSP project
  • Open project properties from Solution Explorer. From the left pane, expand Configuration Properties node and select Build Options.
  • Enable KITL and Enable Profiling.
  • Ensure that ship build is not checked.
  • Disable "CPGMAC Ethernet" driver from catalog (incompatible with Kitl)
  • Save and rebuild the image.
Once built, copy the new NK.bin and EBOOTSD.nb0 to the target's SD card (or wherever you boot from) and boot.
At startup, hit space to enter EBOOT menu when asked to (from the serial debug line UART0):
BOOTLOADER: b# total sectors:1DD77C1
BOOTLOADER: b# sec/fat:      3B9F
BOOTLOADER: b# hidden sec:   1
BOOTLOADER: FileIoInit() initializing data structures.
BOOTLOADER: FileIoReadNextSectors EOF
BOOTLOADER: FileIoReadNextSectors EOF
BLReadBootCfg returns error
WARN: Boot config wasn't found, using defaults
INFO:LCD display configured
INFO:LCD resolution 800x480
INFO:Boot setting: 0x18
INFO:Boot setting: Using SDCard
INFO:PRM_RSTST: 0x00000020
7255c288 d6a2 -> 88 c2 55 72 a2 d6
7255c288 d8a2 -> 88 c2 55 72 a2 d8
Hit space to enter configuration menu [468] 5...
Hit space to enter configuration menu [1468] 4...
Hit space to enter configuration menu [2468] 3...

--------------------------------------------------------------------------------
 Main Menu
--------------------------------------------------------------------------------
 [1] Show Current Settings
 [2] Select Boot Device
 [3] Select KITL (Debug) Device
 [4] Network Settings
 [5] SDCard Settings
 [6] Set Device ID
 [7] Save Settings
 [9] Enable/Disable OAL Retail Messages
 [a] Select Display Resolution
 [b] Select OPP Mode
 [c] Enable clean registry boot
 [0] Exit and Continue

 Selection:
Select menu number 2 and then select "Internal EMAC". Finally select 0 to exit and continue:
--------------------------------------------------------------------------------
 Main Menu
--------------------------------------------------------------------------------
 [1] Show Current Settings
 [2] Select Boot Device
 [3] Select KITL (Debug) Device
 [4] Network Settings
 [5] SDCard Settings
 [6] Set Device ID
 [7] Save Settings
 [9] Enable/Disable OAL Retail Messages
 [a] Select Display Resolution
 [b] Select OPP Mode
 [c] Enable clean registry boot
 [0] Exit and Continue

 Selection: 2

--------------------------------------------------------------------------------
 Select Boot Device
--------------------------------------------------------------------------------
 [1] Internal EMAC
 [2] NK from SDCard FILE
 [3] NK from eMMC FILE
 [0] Exit and Continue

 Selection (actual NK from SDCard FILE ): 1
 Boot device set to Internal EMAC

--------------------------------------------------------------------------------
 Main Menu
--------------------------------------------------------------------------------
 [1] Show Current Settings
 [2] Select Boot Device
 [3] Select KITL (Debug) Device
 [4] Network Settings
 [5] SDCard Settings
 [6] Set Device ID
 [7] Save Settings
 [9] Enable/Disable OAL Retail Messages
 [a] Select Display Resolution
 [b] Select OPP Mode
 [c] Enable clean registry boot
 [0] Exit and Continue

 Selection: 0

You should see the boot process going on and end with several BOOTME message broadcasts:
+Cpsw3gInit(0x4a100000, 0x00000001, 0x8feffedc) v0.3
g_cpsw3g_reg_base = 0xb0500000
Phy_init: Auto negotitation completed
Cpsw3gInit, wait link up on mac port:1.
link up on port 1, speed 100, full duplex
-Cpsw3gInit
INFO: Boot device uses MAC 88:c2:55:72:a2:d6
INFO: *** Device Name LNI33X-41686 ***
InitDHCP():: Calling ProcessDHCP()
ProcessDHCP()::DHCP_INIT
Got Response from DHCP server, IP address: 192.168.200.138

ProcessDHCP()::DHCP IP Address Resolved as 192.168.200.138, netmask: 255.255.255.0
Lease time: 3600 seconds
Got Response from DHCP server, IP address: 192.168.200.138
No ARP response in 2 seconds, assuming ownership of 192.168.200.138
+EbootSendBootmeAndWaitForTftp
Sent BOOTME to 255.255.255.255
!CheckUDP: Not UDP (proto = 0x6)
Sent BOOTME to 255.255.255.255
Sent BOOTME to 255.255.255.255
The target is now looking for a host to start debugging. From Visual Studio, use the "Attach device" button to detect remote targets:

A open shall show up and detect the remote device automatically.
[First time only] Double click on the target device in the popup window.

Visual Studio should now start to download the compiled binary on the target device. Once done, the debugging will start.

WCE7 : Stamp license key


From Visual Studio

After you building a Release version of NK.Bin, the license key can be "stamped" using Platform Builder :

Here are the steps:
  1. Make sure that you have selected a Release configuration of your OS design to build a run-time image from. (WINCESHIP option shall be set to 1 in project properties. It defines the compile time flag -DSHIP_BUILD)
  2. From the Build menu, verify that Make Run-Time Image After Build and Copy Files to Release Directory After Build are selected.
  3. From the Build menu, select Build and Sysgen to build your run-time image.
  4. From the Tools menu, select Platform Builder for CE 7.0, and then select License Run-Time Image to stamp your .bin file with the license key.
  5. In the License Run-Time Image dialog box, in the Run-time key field, enter the run-time key.
  6. Browse to the location of the run-time image file that you want to license, and then click License.

Automatic

Not tested
Create a text file license.txt with the following content :
<license key> 00000000 00000000 00000000 00000000 00000000
here is an example:
OKJB4-098HN-HFR8F-HBVC8-JF789 00000000 00000000 00000000 00000000 00000000
The trailing 5 DWORDs are OEM-specific.
Run the following command in the release directory:
stampbin -1 -i NK.bin license.txt
Verification:
viewbin -t nk.bin >binaryInfo.txt
Look for ROMHDR and check that PID [0-4] contains the license key:
ROMHDR Extensions -----------------------------
    PID[0] = 0x11111111
    PID[1] = 0x22222222
    PID[2] = 0x33333333
    PID[3] = 0x44444444
    PID[4] = 0x00000000
    PID[5] = 0x00000000
    PID[6] = 0x00000000
    PID[7] = 0x00000000
    PID[8] = 0x00000000
    PID[9] = 0x00000000

 
biz.