Windows CE .NET Componentization and Build System
Microsoft® Windows® CE
Microsoft Windows CE .NET
Summary: Microsoft Windows CE has been designed from the ground up to be a componentized operating system. This paper outlines the componentization model used by Windows CE .NET and discusses how to add additional components and features to Windows CE. (10 printed pages)
Both Microsoft Windows CE and Windows XP Embedded are modular operating systems. The tools that are included with each product give developers the ability to pick the features needed for their specific embedded device, but why is modularity or componentization important for embedded systems?
There are a number of answers to this question, but footprint, security, and reliability are at the top of the list of reasons why a developer would build an embedded system using a modular operating system.
Footprint — Developers may have a limit to the size of boot media or random access memory (RAM) within their embedded system. Building an embedded system using only the required technologies gives developers the ability to tune the overall footprint of read-only memory (ROM) or RAM for a specific device.
Security — Embedded systems are becoming increasingly smart and connected, either to a company intranet, or directly to the Internet. Because only the required components of an operating system are included, developers can to minimize "code exposure" to attack. In addition, developers might need to configure services within a device to minimize the risk of attack, and removing unwanted services will remove this need. The exclusion of components such as WCELOAD can enforce a "closed box" device, which stops users from downloading and installing additional applications onto a device. For more information about Windows CE, see Security Features in Windows CE .NET.
Reliability — If a component does not exist within an operating system image, it cannot run, and if the component cannot run it cannot cause faults within the device—therefore, tuning a device for size and functionality can increase the overall reliability of a device. For more information about Reliability and building fault-tolerant systems, see Implementing Fault Tolerant Systems with Windows CE .NET.
Windows CE was designed from the ground up to be a modular operating system, giving developers the ability to tune an operating system image to the specific needs of an embedded system. This includes headless devices such as set-top boxes, industrial control systems, and devices with a user interface such as Smart Displays, Voice over IP (VoIP) phones, and Windows Powered Pocket PC devices.
Each new release of Windows CE typically adds support for additional processors, hardware reference boards, and operating system technologies. Windows CE 2.0 was released in 1998 and included approximately 50 modules. Compare this to the current version, Windows CE .NET 4.2 which contains more than 350 modules.
Windows CE is modular at more than one level. An operating system image is made up of a number of executable files and DLLs, Coredll.dll, and GWES.exe. For example, GWES, the most componentized module within Windows CE, is made up of a number of subcomponents, including menu, clipboard, caret, and user interface controls, each individually selectable at build time.
The way developers configure and build the operating system has evolved over time. Developers that used Windows CE 2.0 could only use the command line to configure and build an operating system image. Developers using Windows CE .NET 4.2 now have a choice of the command line or fully integrated Integrated Development Environment (IDE). The IDE hides the underlying build system from a developer and makes the configuration of an operating system extremely simple.
Extensibility is important to both Windows CE and Windows XP Embedded development tools because it gives developers the ability to add support for additional hardware reference boards. For additional drivers or applications, new or third-party generated Board Support Packages can be added to Platform Builder (the Windows CE configure/build/deploy/debug tool) through the addition of CE Component (.cec) files. In fact, all of the components that are visible through the Platform Builder Catalog are hosted through .cec files.
The Windows CE and Windows XP Embedded build systems are not related. Windows XP Embedded includes pre-built Windows XP service pack 1 binaries. The build system copies the appropriate binaries to the correct output folder, which includes building the folder structure needed to support the Windows XP Embedded operating system: \Windows, \Windows\System32, \Program Files, and so on.
Windows CE builds hardware dependent files, operating system components, and additional user applications from source files. This may require the use of assemblers, compilers, and linkers to produce the final operating system image. The Windows CE build system is related to the Microsoft Windows NT® Device Driver Development Kit (DDK) build system, in that the build system relies heavily on "environment variables" to control the inclusion or exclusion of components from the final operating system image.
There are four main stages to the build process:
- Build Public projects (C:\Wince420\Public).
- Build Platform (C:\Wince420\Platform).
- Create the build Release (build output) Directory.
- Create the operating system image (nk.bin).
Step 1: Build Public Projects
The folder C:\Wince420\Public contains user created projects and operating system projects. Windows CE contains multiple "public" projects, for example, Microsoft Internet Explorer, Microsoft DirectX®, and the Shell.
It is obvious which "public" projects will be built for an example project called MyPlatform, which is based on the Internet Appliance platform template and includes Internet Explorer, the Microsoft .NET Compact Framework, and the HTTPD Web server. An environment variable (viewable from a build window) called _DEPTREES contains the list of public projects, including the "MyPlatform" project. To see this, open Platform Builder, create a platform based on Internet Appliance, open the Build Release Window, and then use the set _deptrees command, which will return the following information.
C:\WINCE420\PUBLIC\MyPlatform\RelDir\EMULAT~2>set _deptrees _DEPTREES=winceos dcom netcf ie script servers rdp shellsdk shell wceshellfe wceappsfe viewers directx datasync SQLCE speech MYPLATFORM
You can see that a number of Windows CE project folders will be built based on the above _deptrees environment variable, which includes NETCF, SERVERS, RDP, SHELL, and MYPLATFORM. The order in which the projects is build is determined by the _deptrees environment variable.
Step 2: Build the Platform
The Windows CE build system needs a way to determine which files from the platform and public folders need to be built. This is handled by DIRS and SOURCES files.
The folder C:\Wince420\Platform contains board support packages (BSPs), or hardware specific files. Note that a number of platform-independent device drivers are included with Windows CE .NET, and are located in C:\Wince420\Public\Common\Oak\Drivers.
The BSP emulator is located in C:\Wince420\Platform\Emulator. The following is a listing of files for this folder.
Directory of C:\WINCE420\PLATFORM\EMULATOR 03/25/2003 11:00 AM <DIR> . 03/25/2003 11:00 AM <DIR> .. 03/25/2003 11:00 AM <DIR> CESYSGEN 03/21/2003 01:00 AM 476 dirs 03/25/2003 11:00 AM <DIR> DRIVERS 03/21/2003 01:00 AM 884 emulator.bat 03/25/2003 11:00 AM <DIR> FILES 03/25/2003 11:00 AM <DIR> GWE 03/25/2003 11:00 AM <DIR> INC 03/25/2003 11:00 AM <DIR> KERNEL 03/21/2003 01:00 AM 452 sources.cmn 3 File(s) 1,812 bytes
The text file called dirs contains a list of the subfolders for this BSP that need to be built. The following code shows the contents of this file.
DIRS= \ gwe \ kernel \ drivers
In this case, three subfolders need to be built: GWE, Kernel, and Drivers, in that order. Note that the order of folders listed in the dirs file specifies the order in which the drivers are built. This is useful to allow common driver libraries to be built before the drivers that need them.
Directory of C:\WINCE420\PLATFORM\EMULATOR\DRIVERS 03/25/2003 11:00 AM <DIR> . 03/25/2003 11:00 AM <DIR> .. 03/21/2003 01:00 AM 1,012 dirs 03/25/2003 11:00 AM <DIR> DISPLAY 03/25/2003 11:00 AM <DIR> DMA 03/25/2003 11:00 AM <DIR> EMULSERV 03/25/2003 11:00 AM <DIR> KBDMOUSE 03/25/2003 11:00 AM <DIR> NET 03/25/2003 11:00 AM <DIR> VCEFSD 03/25/2003 11:00 AM <DIR> WAVEDEV 1 File(s) 1,012 bytes
This case also shows a dirs file, which contains a list of each of the driver's subfolders that need to be built. To add an additional driver, create the appropriate subfolder and driver code, and edit the dirs file to include the new folder.
At some point you will also need a makefile, which describes the type of project (.exe, .dll, or library), the entry point to the project, any required libraries, and source files. In the emulator\drivers\wavedev folder, there is not a dirs file in this. In effect this is the end of this folder tree, but there is a sources file, which contains the make information for this driver.
Examining the contents of the sources file shows us the executable type, which in this case is a DYNLINK or DLL (which is typical for Windows CE device drivers), you can also see the required Library files needed to build the driver, the entry point for the driver DllEntry, and the source files needed to build the driver.
TARGETNAME=wavedev RELEASETYPE=PLATFORM TARGETTYPE=DYNLINK TARGETLIBS=$(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib SOURCELIBS= \ $(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\wavemdd.lib \ $(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\ceddk.lib \ DEFFILE=$(_COMMONOAKROOT)\inc\wavedev.def DLLENTRY=DllEntry INCLUDES=..\..\inc; $(_PUBLICROOT)\common\oak\csp\i486\inc SOURCES=wavepdd.c
Within the Windows CE build system, a folder must contain either a SOURCES file or a DIRS file. Directories listed within a DIRS file are typically subfolders of the folder containing the DIRS file. Note that folders that do not contain a SOURCES or DIRS file are ignored by the build system.
How does the build system determine which drivers are to be included in the final operating system image? This is controlled by environment variables, for the emulator project the following hardware related environment variables are used:
BSP_EMULDRIVEMAP=1 BSP_NO1394=1 BSP_NOCOMCARD=1 BSP_NOFIR=1 BSP_NOIDE=1 BSP_NONLED=1 BSP_NOPCIBUS=1 BSP_NOPCMCIA=1 BSP_NORNDIS=1 BSP_NOSIR=1 BSP_NOTOUCH=1 BSP_NOUSB=1 BSP_NOUSBSER=1
Due to the fact that this is an emulator image that runs on your desktop computer, there is no need for hardware such as PCMCIA, or 1394. The BSP_ environment variables exclude these features from the final image. Drivers such as Keyboard are included in the image because BSP_NOKEYBD is not set.
How the build system determines which BSP will be built is also controlled through environment variables. The following environment variable _TARGETPLATROOT shows that, in this case, the current platform is the emulator.
Step 3: Create the Release Directory
The build release folder, which is often called the _FLATRELEASEDIR (another environment variable,) is created for the appropriate build type. For this example emulator platform, there are two potential release folders: Debug, and Release. In the case of building a debug image, the folder C:\Wince420\Public\MyPlatform\RelDir\EMULATOR_X86Debug will be created and all temporary files will be copied to this folder.
Step 4: Create the Operating System Image (nk.bin)
The final step in building the operating system image is called makeimg, this is where the individual components are pulled together to form the final operating system image, into a file called NK.BIN. This file contains the OAL, Drivers, Win32 components, shell, applications, and so forth.
The operating system is made up of a number of components. Some components, such as the Graphical Windowing and Event Subsystem (GWES) are made up of a number of optional subcomponents. The build system needs a way to determine which modules and components are to be included in the operating system, which is achieved through environment variables, and through a file called CESYSGEN.bat. Take the sample MyPlatform, which is based on the Internet Appliance platform configuration. The cesysgen.bat file is in C:\Wince420\Public\MyPlatform\Wince420\Emulator\Oak\Misc.
Each component is included in the final operating system by having the appropriate environment or "sysgen" variable set. By using Platform Builder, you can examine the sysgen variable for any component in the catalog. The following graphic shows the sysgen variable for the .NET Compact Framework—SYSGEN_DOTNET.
Figure 1. The .NET Compact Framework Environment Variable
With the component added from the catalog to a workspace, or by directly setting the SYSGEN_DOTNET environment variable in a build window, you can then proceed with the build process. At some point the build system will need to determine exactly what needs to be built or copied for prebuild components, and how to get the required files into the correct build output folder.
In the following excerpt from the CESYSGEN.bat file for the "MyPlatform" project, you can see that the SYSGEN_DOTNET sysgen variable is selected. If this is already set, an additional environment variable SYSGEN_DOTNET_SUPPORT is enabled, which sets additional environment variables needed to support the .NET Compact Framework.
REM Add .Net Compact Framework to the platform if "%SYSGEN_DOTNET%"=="1" set SYSGEN_DOTNET_SUPPORT=1 REM Add .Net Compact Framework dependency support to the platform if not "%SYSGEN_DOTNET_SUPPORT%"=="1" goto NoDotNetSupp set SYSGEN_CPP_SEH=1 set SYSGEN_CRYPTO=1 set SYSGEN_WININET=1 set __SYSGEN_IMGDECMP=1 :NoDotNetSupp
How does the setting of the environment variable translate into a component being added to the operating system? This is also handled by environment variables, the .NET Compact Framework is made up of a number of optional modules, which include the Visual Studio .NET Smart Device Authentication Utility (SDAuthUtilDevice.exe), and support for SQL Server CE 2.0. Developers have the choice of including or excluding these components from the operating system.
In the case of the .NET Compact Framework, you set an environment variable called NETCF_MODULES. The .NET Compact Framework makefile will use this environment variable to determine what to build (if a build is required), and which files to copy to the final build output folder. Notice that NETCF_MODULES will be set to dotnet if the .NET Compact Framework is to be included in the operating system.
REM ======================================================= REM .NET Compact Framework modules REM ======================================================= if "%SYSGEN_DOTNET%"=="1" set NETCF_MODULES=%NETCF_MODULES% dotnet if "%SYSGEN_SQLCE20_DP%"=="1" set NETCF_MODULES=%NETCF_MODULES% sqlce20_dp if "%SYSGEN_SQL2000_DP%"=="1" set NETCF_MODULES=%NETCF_MODULES% sql2000_dp REM ======================================================= REM Visual Studio Add-in REM ======================================================= if "%SYSGEN_VS_SD_AUTH%"=="1" set NETCF_MODULES=%NETCF_MODULES% vs_sd_auth REM ======================================================= REM Microsoft SQLCE REM ======================================================= if "%SYSGEN_SQLCE20%"=="1" set SQLCE_MODULES=%SQLCE_MODULES% sqlce20
You already know that there are a number of public projects that can be built as part of the build process (set through the _deptrees environment variable); one of these is the NETCF project. This project contains the makefile needed to build the .NET Compact Framework into an operating system image. The makefile for the NETCF project is in C:\WINCE420\PUBLIC\NETCF\CESYSGEN. The following example shows the contents of the makefile. Note that some of the makefile has been removed to make this easier to read.
dotnet: @echo Copying .NET Compact Framework Components to $(_FLATRELEASEDIR) -@xcopy /I /D /Q $(DOTNET_ROOT)\$(MAPPEDDIRNET)\*.exe $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT) -@xcopy /I /D /Q $(DOTNET_ROOT)\$(MAPPEDDIRNET)\*.dll $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT) -@xcopy /I /D /Q $(DOTNET_ROOT)\$(MAPPEDDIRNET)\*.nlp $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT) -@xcopy /I /D /Q $(DOTNET_ROOT)\$(MAPPEDDIRNET)\*.rel $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT) -@xcopy /I /D /Q $(DOTNET_ROOT)\managed\*.dll $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT) vs_sd_auth: @echo Copying Visual Studio .NET 2003 Windows CE Utilities to $(_FLATRELEASEDIR) -@xcopy /I /D /Q $(VS_ROOT)\$(MAPPEDDIRNET)\SDAuthUtilDevice.* $(_FLATRELEASEDIR) > nul $(SG_XCOPYREDIRECT)
The .NET Compact Framework ships as pre-built binaries, so in this case the makefile copies the appropriate files to the build release folder, which is also set through an environment variable called _FLATRELEASEDIR.
At this point, you have a basic understanding of how the build system pulls modules and components into an operating system image—the entire process is managed through environment variables. This is satisfactory if you are building an operating system from the command line—you only need to set the appropriate environment variables and then build the operating system image—but how does this work from the integrated development environment?
Windows CE developers have two choices when building an operating system image: building from the command line or using the Windows CE Platform Builder Integrated Development Environment (IDE).
Some developers prefer to build their operating system from the command line, which gives fine control over which parts of the operating system are to be built and can improve build times by building the components that have changed and then making the final operating system image.
Other developers prefer to use the Windows CE Platform Builder IDE to configure and build the operating system image. The IDE wraps up the underlying command line build. Selecting components from the catalog sets the underlying environment variable, which is then used by the build system to include the appropriate modules and components.
Platform Builder, the Windows CE development tool, includes a catalog of components where each component is wrapped by one or more CE Catalog (.cec) files. The catalog is completely extensible and allows developers to easily develop additional .cec files that can act as "macro" components for other commonly used components. For example, the .NET Compact Framework OS Dependencies component is a macro component. It has no functionality of its own; instead, it can pull in four required operating system components), a single device driver for a specific Board Support Package, or an entire Board Support Package. Platform Builder includes a graphical .cec editor, which enables you to create new components such as "macro" components from the ground up or to customize existing components.
Figure 2. The CEC editor
Catalog components are grouped into related technologies such as multimedia, file systems and data store, applications and services development, BSPs, and drivers. This makes it easy for a developer to locate a specific feature, and then in turn to add this feature to the current workspace.
Figure 3. The Platform Builder Catalog
The catalog provides information that is not readily available from the command line. A developer might know that to the HTTPD Web Server, SYSGEN_HTTPD will need to be set. The developer might not know which processor(s) are supported, the approximate size of this component when added to a platform, or what additional operating system dependencies are required in order to work with this component.
For example, the .NET Compact Framework shows a number of features exposed from the Platform Builder IDE. A developer can right-click a component in the catalog and then click Properties to open the dialog box in Figure 4, which shows the following details:
- The Name of the component as it appears in the catalog
- The Vendor and date the component was created
- The Component Version number
- The approximate component size (the size may vary based on the underlying processor type)
Figure 4. The .NET Compact Framework Component
The Feature Properties dialog box contains three tabs. The first tab shows the size and name of the platform. The second tab shows the environment variable(s) that will be set by including this component into a platform. In the case of the .NET Compact Framework, this is SYSGEN_DOTNET, exactly the same environment variable which would be used from a command line build.
Figure 5. The .NET Compact Framework Environment Variable
The third tab lists the supported CPUs for this feature (most hardware dependent drivers would list only the CPU supported by the feature), and the platform configuration types supported by this feature. There are two core platform types, headless (HLBASE), and display based (IABASE). You can see that the .NET Compact Framework is only supported on IABASE based devices, which have a user interface.
Figure 6. Supported Configurations
Another interesting feature of the Platform Builder IDE is component dependency information. Each of the features exposed out of the catalog contain dependency information, which is exposed in two ways:
- Depends On Components in this list are required for the selected component to run. As shown below, the .NET Compact Framework component requires C++ Exception Handling, Crypto API, Windows Internet Services, and the operating system (OS) Dependencies for the .NET Compact Framework.
- Dependency Of Components in this list require the selected component. As also shown below, the .NET Compact Framework is a dependency of Microsoft SQL Server™ 2000 .NET Data Provider, and SQL Server CE 2.0 .NET Data Provider.
Figure 7. Component Dependencies
Since the launch of Windows CE 2.0 in 1998, the number of supported processors, hardware reference platforms, and technologies have steadily increased. The tools used to configure, build, download and deploy Windows CE operating systems have also dramatically improved, which provides extensibility for BSPs, third-party drivers and components (through .cec files) and provides full customization of a platform through the use of Platform Wizards, the Platform Builder Catalog, and through component dependency information. Windows CE .NET 4.2 provides all of the tools and operating system features needed to rapidly build and deploy "smart" embedded systems.
For more information about Windows CE .NET, see the Windows Embedded Web site.
For online documentation and context-sensitive Help included with Windows CE .NET, see the Windows CE .NET product documentation.