System initialization of OEM Adaptation Layer in WinCE
By iameasy_man, 23 visits, network Abstract, favorites, Edit
OAL (OEM Adaptation Layer) is an OEM adaptation layer, logically located between the Windows CE kernel and hardware. Physically speaking, the code of each oal module is compiled (. (LIB) and other kernel libraries are linked together to form the Windows ce's Executable File nk.exe. The Windows CE kernel exposes a large number of functions and global variables on the oal layer, with these functions and global variables, OEMs can write interrupt processing, RTC, power management, debugging ports, and general I/O control code. Figure 1 intuitively describes the oal structure. The subdirectory of the CE installation directory contains some source code of OAL. In most cases, developers only need to modify oal, and even do not need to modify it. By reading this article, developers can understand the oal structure and the functions of exposed interfaces, and can implement or even enhance the oal functions on this basis.
Because most oal-Layer Code is related to system initialization during Ce startup, this article takes the CE startup sequence as a clue. Other oal knowledge is explained in the next article.
1. After the boot loader unpacks the CE kernel image file (NK. Bin), it starts to jump to startup (). The startup function belongs to the oal layer, and the CE operating system kernel is not running yet. The startup function has two main functions: one is to initialize the known state of the CPU, and the other is to call the kernel initialization function (the X86 platform is kernelinitialize and the other platform is kernelstart ). The initialization of the CPU varies depending on the CPU. For the ARM Series, including setting CPU as Administrator mode, disabling IRQ and FIQ, disabling MMU, clearing commands and data buffering, checking startup causes, configuring gpio and memory controller, initializing RTC, and saving oemaddresstable addresses. Call kernetstart after execution. For the x86 series, including setting the CPU to the protection mode, initializing the memory controller, and saving the oemaddresstable address. Call kernetinitialize after execution.
2. The functions of the kernel initialization function vary with the CPU, but some functions are the same, such as initializing the serial port (to output debugging information) and calling the oeminit function. For the x86 series, in addition to the above functions, initialization also includes reading oemaddresstable content, determining the page size, kernel relocation, initializing the interrupt allocation table, initializing the paging table, memory initialization, and other initialization. For other series CPUs, see the CE help documentation.
1. Serial Port debugging:
Serial debugging functions include oeminitdebugserial, oemreaddebugbyte, and oemwritedebugbyte. From the source code of oeminitdebugserial, we can see that the system determines which serial port is currently connected from the structure of the boot_arg_ptr_location header address, and then configures this serial port. If the serial port I/o address of your device is set to the same as that of CE by default, you can get the debugging information through the serial port from CPU control to startup of the CE kernel.
2. oeminit
Generally, all peripheral hardware, system clock, RTC (real time clock), and kitl (kernel independent transport layer) are initialized in oeminit ). For example, the oeminit function of the IMG platform associates all IRQ and interrupt IDs first, and then initializes the PCI bus, network adapter, power management, PIC (Programmable Interrupt Controller), and system clock, finally, check whether there is extended memory. In addition, if the OEM wants to enhance the function through the function pointer or global variable exposed by oal, it should be implemented in this function (detailed description below ).
3. Detect extended memory
We all know that in config. set the total RAM usage of the CE system in the bib configuration file (if you do not know, refer to my article platform builder travel series). Note that the total Ram volume is not the total physical memory size. The Pb-compiled kernel contains the ulramend variable, which assigns the starting address of the ram defined in config. bib + the sum of the ram size to ulramend. During the CE kernel startup, The ulramend value is assigned to the global variable mainmemoryendaddress. The CE kernel obtains the total amount of RAM by accessing mainmemoryendaddress. If Ram is attached to the CE-based device, and the value of mainmemoryendaddress does not include the ram, the CE kernel cannot know that Ram has been attached. To enable the CE kernel to understand the Additional RAM information, the OEM should write a function to check the total amount of Ram and assign the total value to mainmemoryendaddress. OAL exposes a function pointer pnkenumextensiondram. The OEM should assign the written function address to this function pointer. If the OEM does not prepare its own memory detection function, it can also call oemgetextensiondram. The help document shows that the oemgetextensiondram function can detect the total amount of memory, however, ce does not write the implementation code of this function in the source code for the X86 platform (see % _ winceroot %/public/common/oak/CSP/i486/oal/cfwpc. c ). That is to say, calling oemgetextensiondram on the X86 platform cannot detect Ram. If the OEM is interested in writing a function that detects the total amount of RAM, it can call the ready-made function isdram. This function is also saved in cfwpc. C.
3. After the kernel initialization function is executed, perform the following steps:
1. Create an event object system/fsreadyused to synchronize with filesys.exe, and then start filesys.exe. The purpose of starting filesys.exeis to allow filesys.exe to read registry data.
2. the kernel waits for the Event System/fsreadyto be triggered. This event is triggered after filesys.exe completes a series of tasks. This series of work content is as follows:
2.1 First, check whether this is a cold start or a hot start. If it is a cold start, initialize the OSS memory area.
2.2 call the oemiocontrol function. The I/O control code is ioctl_hal_init_rtc, that is, initialize RTC.
2.3 initialize database subsystems and APIs, file system APIs, and Message Queue APIs.
2.4 If the operating system image (NK. Bin) includes the RAM file system, read the initobj. dat file and create a ram file system.
2.5 initialize the Registry (forming a registry in the memory ).
2.6 If strongdevice.exe is not started, read the value of "DLL" under HKEY_LOCAL_MACHINE/system/storagemanager (the value is the name of the. dll file where the Storage Manager is located) and load it To the memory. After loading, create a thread dedicated to initializing the Storage Manager. After initialization, the thread ends.
2.7 initialize NLS (National Language Support ). For more information about NLS, see my article "ce Chinese Input Method Editor".
2.8 set the local ID for the database engine.
2.9 read the initdb. ini file and install it in the database of OSS.
2.10 trigger the system/fsreadyevent. After that, filesys.exe is in the waiting state and waits for the kernel to send a notification to it.
3. At this time, the Registry already exists in the memory, and the kernel starts to read data from the following locations:
HKEY_LOCAL_MACHINE/loader/systempath HKEY_LOCAL_MACHINE/system/OOM/cblow and cplow HKEY_LOCAL_MACHINE/system/kernel/injectdll HKEY_LOCAL_MACHINE/Mui/enable and syslang HKEY_CURRENT_USER/Mui/curlang |
4. the kernel sets out of memory ). Low Memory Processing refers to the solution made by the kernel when the available memory is very small (detailed descriptions are provided in the CE help documentation ).
5. filesys.exeis notified after the internal audit completes the preceding work, and filesys.exe will do the remaining work. Filesys.exe does the following work:
5.1 read the names of all event objects contained in HKEY_LOCAL_MACHINE/system/events and create them one by one.
5.2 read the names of all applications included in HKEY_LOCAL_MACHINE/init and start them one by one. If device.exe is in the list and it has already been started, the system/bootphase2event is triggered, and device.exe will re-read the registry data to complete the final driver initialization.
5.3 Time Zone ).