Summary

Learn about the initial, low-level startup sequence and the hardware platform functions that are performed when the boot loader and OEM abstraction layer (OAL) are developed and the kernel is run. The startup sequence is an integral part of developing the OAL
for a board support package (BSP), and the development process must be implemented correctly for initializing the CPU as well as on-chip and off-chip peripherals.

The process described in this article is the minimum set of functions that need to be implemented. It might be necessary for user-defined functions to be implemented where appropriate, depending on the specific device and peripheral set you are developing.
Although the startup sequence for the different hardware platform CPU architectures that Windows CE supports is very similar, for the sake of simplicity, this article discusses the ARM kernel startup sequence.

Contents

IntroductionOverview of the BSP Development ProcessOverview of the Boot Loader and Kernel Startup SequenceBoot Loader Startup SequenceKernel Startup Sequence

frame=true#ce50anchor6" target="_self" style="line-height:1.5em!important; color:rgb(99,88,56); text-decoration:none">

Conclusion

Introduction

Creating a BSP is the initial development activity required for building a Windows CE-based device. You can develop a BSP on your own or start from a BSP provided by Microsoft or a third party. Leveraging an existing BSP can greatly reduce the amount of development
work required.

Regardless of the starting point you choose, the development process and startup sequence for the boot loader and the kernel are almost the same. This article describes this startup sequence and the functions you must implement to develop a boot loader and
kernel that will boot Windows CE on a device. It also provides information about the recommended functionality that should be implemented in each function that is called by the boot loader and kernel. Because several of the functions calls do very similar
actions, the kernel startup work can leverage the work done to develop the boot loader.

Overview of the BSP Development Process

Like many development tasks, the process for developing a BSP involves high-level and low-level tasks. For example, at the highest level, you must select the hardware platform, and at the lowest level, you must develop a boot loader and the OEM abstraction
layer (OAL) for the kernel. The following illustration shows the high-level steps needed to develop the low-level software for a BSP.

You begin by selecting or developing the hardware platform that the BSP will target. This includes developing a board with a CPU that can run the Windows CE operating system (OS), selecting the peripheral devices that will interface with the device, and including
the interfaces required to support BSP development and debugging. For example, you might not need to include support for serial connections on a device for consumers, but a serial connection is typically important for low-level software development. You should
consider populating your device with a debug header that can interface to a debug board for development, but can be depopulated before the device is used for production.

After you have identified and created the hardware platform, you must develop a BSP that will run Windows CE on the device. Often, you can modify a BSP from Microsoft or a third party, which will greatly reduce your BSP development work. The process of starting
with a BSP from Microsoft is called BSP cloning. You can find information about this process in the Windows CE Help documentation. If a BSP is not available, you will have to develop one entirely on your own. Because developing a BSP entirely on your own is
a significant amount of work, Microsoft recommends that you start with a BSP from Microsoft or a third party.

At this point, you move to the low-level development tasks by developing a boot loader that can reside in persistent memory on the device. The boot loader's primary function is to initialize enough of the hardware and CPU to allow the hardware to communicate
with the development environment for downloading a Windows CE-based run-time image. You can extend the boot loaders functionality to be used for any other purpose that your device requires. Later sections of this paper discuss the low-level startup functions
that you must implement in the boot loader.

After a boot loader has been developed, you download it and write it into persistent memory on the device using the tools specified by the silicon vendor. You then start development work on the OAL portion of the BSP. Part of the OAL work consists of implementing
the bootstrapping kernel functions required to start the Windows CE kernel. Developing the OAL is a step-by-step process of implementing the startup functions and implementing the code that will initialize the hardware on the device in preparation for running
the Windows CE kernel. You can leverage or share many of the startup functions that are implemented in the boot loader during OAL development. Once you have developed, downloaded, and debugged the OAL, a minimal Windows CE kernel will be running on the hardware
platform.

Next, you add support for the peripherals that you have chosen for the device. To do this, you have to iteratively add and debug the drivers for these peripherals one at a time. If you have multiple developers working on drivers, the drivers can be developed
in a series and added to the BSP one at a time. Depending on what peripherals you have chosen, or if you are using a System-On-Chip (SOC), you can add drivers from Microsoft or from a third party. You can leverage these drivers as the starting point for each
driver that you develop.

Once the device drivers have been developed, you should have a BSP with an OAL and the drivers for each peripheral that you intend to support on the hardware platform. Next, you will plan and implement power management.

Power management is an important part of the driver and BSP development process. Once you have planned your power management system, which includes deciding to what extent your device will rely on battery power, you will use the Power Manager to help you implement
those power management capabilities. Although power management is not the focus of this article, you can find documentation that explicitly covers power management in Windows CE Help and the MSDN Library. There you will find details about how to make each
peripheral driver power-management-aware, as well as how drivers interact with the Power Manager and OAL.

As you develop the OAL, bring up device drivers, and implement power management, you must test each component. The Windows CE Test Kit (CETK) provides a wide variety of tests to help you with this process. For information about the CETK, see Windows CE Help
and the MSDN Library.

The final steps in the BSP development process are to create a software development kit (SDK) and package the BSP into an .msi install file so that it can be installed by others. An SDK is a set of headers, libraries, connectivity files, run-time files, OS
design extensions, and Help documentation that developers use to write applications for a specific OS design. The contents of an SDK allow developers to create and debug an application on the run-time image built from your OS design. Windows CE provides an
SDK Wizard to create an SDK from your BSP and an Export Wizard to package your BSP into an .msi install file.

For detailed information on all aspects of the BSP development process, see Windows CE documentation.

Overview of the Boot Loader and Kernel Startup Sequence

For the most part, the boot loader and kernel share the same Startup functions, as well as some of the code that is called out in the subsequent functions. Consequently, you can leverage or share much of the
code initially implemented in the boot loader startup sequence during the kernel startup sequence.

The following table shows the startup functions used by the boot loader and the kernel for an ARM-based startup sequence. The startup sequence for the kernel calls into functions that are part of the shared-source license agreement that installs code into the
private tree. Because of this, you should sequence the functions as they are shown below. Within each function you might need to customize the order in which components are initialized, depending on your CPU, memory, and peripheral set.

Boot Loader Startup Sequence       Kernel Startup Sequence      
Startup()       Startup()      
  EbootMain()       KernelStart()    
    BootloaderMain()       ARMInit()  
    OEMDebugInit()         OEMInitDebugSerial()
    OEMPlatformInit()         OEMInit()
    OEMPreDownload()       KernelInit()  
      Download       HeapInit()
    OEMLaunch()         InitMemoryPool()
              ProcInit()
              SchedInit()
          FirstSchedule()    
            SystemStartupFunc()  
            IOCTL_HAL_POSTINIT  

Function calls in bold text denote functions that OEMs need to implement.

Documentation is provided in Platform Builder and on MSDN that covers the step-by-step process, with a checklist, for bringing up a boot loader and OAL.

Boot Loader Startup Sequence

The following table shows the boot loader startup sequence.

Boot Loader Startup Sequence      
Startup()      
  EbootMain()    
    BootloaderMain()  
    OEMDebugInit()  
    OEMPlatformInit()  
    OEMPreDownload()  
      Download occurs
    OEMLaunch()  

Functions in bold text denote functions that OEMs need to implement.

Startup() -> Startup.s

The boot loader Startup function is the first code that is run on the device after a hardware reset or run-time reset, and when the system wakes up. This function performs the following tasks:

  • Sets the device to supervisor mode
  • Performs the necessary initialization for the following hardware:
    • CPU
    • Memory controller
    • System clocks
    • Serial
    • Caches
    • Translation look-aside buffers (TLBs)

In the case of a wakeup event, the Startup function reads the saved address for the wakeup event, and then jumps to that location. If it is not a wakeup event, the boot loader is copied to memory and run.

The Startup code is typically located in the Startup.s file located in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader or %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Bootloader\Eboot directory. The Startup code is typically in assembly language because it is the first code that runs on the device and needs to do low-level hardware initialization
and communication with the CPU.

Because each CPU and hardware platform requires different initialization, you must modify the Startup.s file, depending on the CPU you are using. The silicon vendor provides the CPU initialization information. The Startup code
can be shared with the OAL and can be reused later during that part of the development process.

EbootMain() -> Main.c

Depending on the CPU you are using for BSP development, EbootMain is typically the entry point for the C code to be run. EbootMain is typically located in the
Main.c file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader directory or in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader\Eboot
directory. Although Main.c can perform any initializations on the device, it should end with a call to the BLCOMMON library entry point, BootloaderMain.

BootloaderMain() -> Blcommon.c

The BLCOMMON library entry point is the BootloaderMain function. BootloaderMain is the primary call in the BLCOMMON library that implements a common and consistent
framework for a boot loader. The BLCOMMON library source file is located in the Blcommon.c file in the %_WINCEROOT%\Public\Common\Oak\Drivers\Ethdbg directory.

The BLCOMMON library provides the following functionality:

  • Relocates the boot loader to RAM for faster execution
  • Decodes the .bin file contents
  • Verifies checksums
  • Keeps track of load progress

The BLCOMMON library calls well-defined OEM functions throughout the process to handle hardware platform or solution-specific customizations.

OEMDebugInit() -> Main.c

OEMDebugInit is the first function called from the BootloaderMain function when the boot loader is started. This call is typically used to initialize serial UART
debugging output. The OEM often chooses to call the OEMInitDebugSerial function to initialize a serial UART for debugging messages.

After OEMDebugInit completes, the Windows CE banner appears indicating that this interface is available. The OEM function interface can use OEMWriteDebugString, OEMWriteDebugByte,
andOEMReadDebugByte after OEMDebugInit completes.

The OAL and the boot loader can share this implementation.

OEMDebugInit is located in the Main.c file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader OR %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Bootloader\Eboot directory.

OEMPlatformInit() -> Main.c

OEMPlatformInit is the next function called from BLCOMMON after the OEMDebugInit function completes and the Windows CE banner is displayed.

OEMPlatformInit is an OEM hardware platform initialization function for the clock, PCI interface, or NIC interface. OEMPlatformInit is also where the interruption
in the boot up process takes place to display the boot loader menu. The NIC interface for downloading the image is assumed for the following download functions.

OEMPlatformInit is located in the Main.c file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader or %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Bootloader\Eboot directory.

OEMPreDownload() -> Main.c

OEMPreDownload is also called from BLCOMMON before actually downloading a run-time image. This function retrieves the IP address for the device and connects to the development workstation. You can customize OEMPreDownload to
prompt the user for feedback to obtain a static IP address or skip the download and jump to an image that might already exist on the device. The preferred method is to use the settings provided in Platform Builder.

Return values for OEMPreDownload are typically obtained through a call toEbootInitEtherTransport, which retrieves this information from Platform Builder. You can
select downloading or booting from a resident run-time image by options passed from Platform Builder to the boot loader through EbootInitEtherTransport. You can also set up OEMPreDownload to
read hardware switch settings to determine the code that should be returned.

The following tables shows the possible return codes for the OEMPreDownload function.

Return code Description
BL_DOWNLOAD (0) The Ethernet transport should be initialized by calling EbootInitEtherTransport.
BL_JUMP (1) The download function in the BLCOMMON framework is bypassed.
BL_ERROR (-1) Error condition.

If a signed run-time image has been downloaded, the signature is checked and verified before callingOEMLaunch.

OEMPreDownload is located in the Main.c file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader or %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Bootloader\Eboot directory.

OEMLaunch() -> Main.c

OEMLaunch is the last boot loader function called out of BLCOMMON and is responsible for jumping to and launching the run-time image.

OEMLaunch can use the EbootWaitForHostConnect function, which is defined in Eboot.lib, to wait for returned arguments when you have chosen passive KITL or not
to connect to the target device at boot time. Other flags are set to define the transport mechanism as a serial, USB, or Ethernet connection.

OEMLaunch jumps to the first instruction specified by the dwLaunchAddr parameter, which is the location of the run-time image Startup function. Startup calls
the KernelStart function, as defined below. The launch address is obtained from the .bin file and is stored in the length field of the last block.

At this point, the boot loader is done executing code and the Startup function in the OAL is called.

OEMLaunch is located in the Main.c file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Bootloader or %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Bootloader\Eboot directory.

Kernel Startup Sequence

The following table shows the startup functions used by the kernel for an ARM-based startup sequence. The startup sequence for the kernel requires calls into functions that are part of the shared-source license agreement that installs code into the private
tree. Because of this you should sequence the functions as they are shown below. Within each function you might need to customize the order in which components are initialized depending on your CPU, memory and peripheral set.

Kernel Startup Sequence      
Startup()      
  KernelStart()    
    ARMInit()  
      OEMInitDebugSerial()
      OEMInit()
    KernelInit()  
      HeapInit()
      InitMemoryPool()
      ProcInit()
      SchedInit()
  FirstSchedule()    
    SystemStartupFunc()  
    IOCTL_HAL_POSTINIT  

Functions in bold text denote functions that OEMs need to implement.

ARM Kernel Startup Overview

Startup() -> Startup.s

The kernel Startup function is the first code that runs after the boot loader jumps to the run-time image that is now on the device, or when the development boot loader is removed and a production boot loader
is flashed to the device and kernel Startup is called from the production boot loader.

Although in this example kernel Startup is a different source file than the boot loader Startupfunction, they have similar code and can be shared. Startup is
responsible for detecting a hardware or run-time reset or detecting when the system wakes up. The kernel Startup function performs the necessary hardware initialization, including initializing the CPU, memory
controller, system clocks, serial port, and caches, and detecting when the system wakes up.

Kernel Startup code is typically located in the Startup.s file in the %_WINCEROOT%\Platform\<Hardware Platform Name>\Src\Kernel\OAL directory. This directory can
also share the boot loader Startup.s code. The Startup code is typically in assembly language because this is the first code that runs on the device and needs to perform low-level hardware initialization.

Because each CPU and hardware platform requires different initialization, you must modify the file containing the kernel Startup function depending on the CPU you are using. The silicon vendor provides this CPU
initialization information.

Kernel Startup is responsible for computing the physical address for the OEMAddressTable and loading it into memory for use by the KernelStart function.
The Startup function sets up any hardware platform or CPU-specific configurations that are required for the kernel to access ROM and DRAM, and then jumps to KernelStartup.
The Startup routine should initialize any processor-specific cache or memory management unit (MMU), but not enable them

KernelStart() -> Armtrap.s (Private)

The KernelStart function is the main entry point for the kernel. The KernelStart function initializes the first-level page table based upon the contents of the MemoryMap array
and enables the MMU and caches. Kernel symbolic addresses are not valid and must be translated through theMemoryMap array to find the correct physical address until the MMU is enabled. KernelStart also
initializes the stacks for each mode of operation, and initializes global data for the kernel.

The KernelStart function is located in the Armtrap.s file in the %_WINCEROOT%\Private\Winceos\Coreos\Nk\Kernel\ARM directory.

ARMInit() -> Mdarm.s (Private)

The ArmInit function, which is the main ARM initialization function, is responsible for calling the OEM-supplied initialization functions. ARMInit makes the following
function calls:

  • Calls OEMInitDebugSerial to initialize the debug serial port through OEMInitDebugSerial
  • Uses OEMWriteDebugString to display the Windows CE banner
  • Calls OEMInit to perform hardware platform initialization

The ARMInit function is located in the Mdarm.c file in the %_WINCEROOT%\Private\Winceos\Coreos\Nk\Kernel\ARM directory.

OEMInitDebugSerial() -> Mdarm.s (Private)

The OEMInitDebugSerial function initializes the debug serial port on the device. The debugging functions are: OEMDebugInit, OEMWriteDebugString, OEMWriteDebugByte,
and OEMReadDebugByte.

The code for OEMInitDebugSerial is very similar to the OEMDebugInit function called from the boot loader. Therefore, most of the OEMDebugInit code
can be reused or shared.

OEMInit() -> Init.c

The kernel calls OEMInit after it has performed minimal initialization in ARMInit. When OEMInitis called, interrupts
are disabled and the kernel is unable to handle exceptions. OEMInitinitializes the following hardware:

  • Cache
  • Interrupts
  • Clock
  • All other board-level hardware peripherals needed to support the hardware platform

Note   If a KITL connection is being used, then the KITL connection can also be initialized during OEMInit through a call to the OALKitlStart function.

The OEMInit function contains much of the functionality present in the OEMPlatformInit function in the boot loader.

The OEMInit function is a kernel call from ARMInit and can be found in the Init.c file in the %_WINCEROOT%\Platform\<Hardware
Platform Name>\Src\Kernel\OAL directory.

KernelInit() -> Kwin32.c (Private)

The KernelInit function is where the kernel is initialized. KernelInit calls functions to initialize the following kernel components:

  • Heap
  • Memory pool
  • Kernel process
  • Scheduler

When KernelInit returns, the kernel is ready to schedule the first thread throughSystemStatupFunc.

The KernelInit function can be found in the Kwin32.c file in the %_WINCEROOT%\Private\Winceos\Coreos\Nk\Kernel directory.

HeapInit() -> Heap.c (Private)

The HeapInit function initializes the kernel heap and is located in the Heap.c file in the %_WINCEROOT%\Private\Winceos\Coreos\Nk\Kernel directory.

InitMemoryPool() -> Physmem.c (Private)

The InitMemoryPool function initializes the kernel memory pool and is located in the Physmem.c file in the %_WINCEROOT%\Private\Winceos\Coreos\Nk\Kernel directory.

ProcInit() -> Schedule.c (Private)

The ProcInit function initializes the kernel process and is located in the Schedule.c file in the %_WINCEROOT\Private\Winceos\Coreos\Nk\Kernel directory.

SchedInit() -> Schedule.c (Private)

The SchedInit function initializes the scheduler and is located in the Schedule.c file in the %_WINCEROOT\Private\Winceos\Coreos\Nk\Kernel directory.

SchedInit creates the SystemStatupFunc thread.

FirstSchedule() -> Schedule.c (Private)

The FirstSchedule function starts the scheduler and is located in the Schedule.c file in the %_WINCEROOT\Private\Winceos\Coreos\Nk\Kernel directory.

SystemStartupFunc() -> Schedule.c (Private)

The SystemStartupFunc function is called after all the required initialization has been completed and when the system is ready to schedule startup and run kernel threads. SystemStartupFunc is
where calls are made to start kernel monitoring through CreateKernelThread, and execute IOCTL_HAL_POSTINIT through the OEMIoControl function.

SystemStartupFunc is located in the Schedule.c file in the %_WINCEROOT\Private\Winceos\Coreos\Nk\Kernel directory.

Conclusion

All Windows CE device development begins by creating a targeted BSP for the device. The BSP also becomes the foundation for applications that run on the device by exporting an SDK from the BSP. Because of this, you must be sure that the high level BSP process
is followed and the low-level function calls for the boot loader and kernel are implemented appropriately. With the information from this article, you should have a fundamental understanding of the BSP process and what the development effort is to get a boot
loader and kernel running on a device.

原文地址:http://embeddedsytem.blog.hexun.com/10570080_d.html

Microsoft Windows CE 5.0 Board Support Package, Boot Loader, and Kernel Startup Sequence的更多相关文章

  1. Visual Studio 2005 搭建Windows CE 6.0环境之准备

    Microsoft Visual Studio 2005 Visual Studio 2005 Professional 官方90天试用版英文版:http://download.microsoft.c ...

  2. windows CE 6.0编译报BLDDEMO: There were errors building MY283错误解决办法

    今天开始正式进入windows ce程序开发. 第一次编译windows ce6.0的系统,25分钟编译后报:BLDDEMO: There were errors building MY283 错误. ...

  3. Windows Embedded CE 6.0开发环境的搭建

    最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...

  4. Windows Embedded CE 6.0开发环境的搭建(2)

    最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...

  5. (转) 关于Windows CE和Windows Mobile

    转发自http://www.cnblogs.com/chump/articles/1281955.aspx 一.Windows CE Windows CE是微软的嵌入式操作系统主要的一种,面世于199 ...

  6. C:\Windows\system32\config\systemprofile\AppData\Local\Microsoft\Team Foundation\4.0\Cache\VersionControl.config is not valid and cannot be loaded.

    Recently, we experienced a strange problem with TFS 2010. We spent a few days before we figured it o ...

  7. Windows Embedded CE 6.0 下载地址和序列号

    Windows Embedded CE 6.0 下载地址和序列号 安装起来特麻烦 程序下载地址 http://download.microsoft.com/download/a/0/9/a09e587 ...

  8. 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\106f9ae8\cc0e1

    在本地开发环境没问题,但是发布到服务器出现:未能写入输出文件"c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.Ne ...

  9. [已解决]:调用 LoadLibraryEx 失败,在 ISAPI 筛选器 "c:\Windows\Microsoft.NET\Framework\v4.0.30319\\aspnet_filter.

    现象:我的是 win7, iis7, 64bit, 打开网站错误如下: 错误摘要 HTTP 错误 500.0 - Internal Server Error 调用 LoadLibraryEx 失败,在 ...

随机推荐

  1. 一篇文章告你python能做什么,该不该学?好不好学?适不适合学?

    一.python好学吗?简单吗?容易学吗?没有编程的领取能学吗? 最近有很多小伙伴都在问我这些问题.在这里,我想说,python非常简单易学. 1,简单, Python 非常易于读写,开发者可以把更多 ...

  2. 2.C# 输入一个整数,求质因数

    C# 输入一个整数,求质因数 List<int> results = new List<int>(); int number = Int32.Parse(Console.Rea ...

  3. Android实战简易教程-第四十九枪(两种方式实现网络图片异步加载)

    加载图片属于比较耗时的工作,我们需要异步进行加载,异步加载有两种方式:1.通过AsyncTask类进行:2.通过Handler来实现,下面我们就来看一下如何通过这两种方式实现网络图片的异步加载. 一. ...

  4. extjs动态添加列

    可以根据日期,动态的插入一列 controller层: StdDayWordQuery:function(btn,event){ var form=Ext.getCmp('queryFormSDW') ...

  5. HTML5 history API与ajax分页实例页面

    <ul id="choMenu" class="rel cho_menu"> <li><a href="ajax.php ...

  6. vue 自定义指令使用

    <template> <div> <!-- 让input元素在打开页面的时候就获得焦点 --> <input type="text" v- ...

  7. JavaScript在HTML中的应用

    JavaScript在HTML中的应用 制作人:全心全意 在HTML文档中可以使用<script>...</script>标记将JavaScript脚本嵌入到其中,在HTML文 ...

  8. Python:socket实现ftp程序

    刚开始学习socket编程,还不是特熟练,码了好长时间,中间遇到许多问题,记录一下用socketserver写ftp server端: #!/usr/bin/env python import soc ...

  9. hdu 2377 Bus Pass

    Bus Pass Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  10. python面向对象编程实例

    1.编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生 class Student: """学生类""" c ...