Passive KITL to the rescue
I'm sure many of you have been in a situation where your device hangs during field testing. Or sometimes you are trying to track down a problem which only repros at a certain location. The best thing you can have in these situations is, of course, a live KITL connection to the device. This can be challenging at times because you can't run around with a phone connected to your laptop with a short USB cable. Its just not practical.
This is where Passive KITL can be used. (Read the “Active and Passive KITL” article in the Windows Mobil 6.0 documentation for an introduction to Passive KITL.) Note that, when you don't have live KITL connection, you can't just press "go" when your device tried to break into KITL. This might happen, for example, when you mistakenly use a wrong Debug DLL with a lot of asserts you don't care about. So a word of advice, use only debug dlls for the components you are debugging at the moment. Better yet, try to stay with a retail image this way if it breaks it will be most likely in the place you are debugging.
Another thing to remember is battery life. You need to act quickly when your device breaks. If you let it sit too long your battery might run out and you will lose your repro.
Yet another thing you can do before working with Passive KITL is to use non-optimized version of the components you are trying to debug. Use the -Od switch in your SOURCES file to turn off Compiler optimization. This will turn off the optimization and preserve with assembly flow which in turn will make your assembly match your sources files. You can add -Od to the existing command line by doing this:
Alternatively, you can set DISABLE_OPTIMIZER=1 in your build environment which will disable optimization
No really, how do I enable Passive KITL?
We are going to use the GSample platform that can be downloaded from JetStream or you can just use FSample. Your particular platform will be very similar.
In a nutshell enabling Passive KITL is very simple. All you need to do is to OR OAL_KITL_FLAGS_ENABLED and OAL_KITL_FLAGS_PASSIVE from \PLATFORM\COMMON\SRC\INC\oal_kitl.h into OAL_KITL_ARGS->flags in the OALKitlStart() function.
There are several ways to do this. If you have a boot-loader menu you can do it there (We will not be describing it here, because not everyone has a boot-loader menu).
Another way is to use FIXUPVARs.Which can be configured so that all you need to do is to set a DOS environment variable and run MAKEIMG to make an image with Passive KITL enabled.
Take a look at the CONFIG.BIB file located in your \PLATFORM\<YOUR PLATFORM>\FILES directory or look at the sample (\PLATFORM\GSAMPLE\FILES\CONFIG.BIB).
You will see a section that looks something like this:
ARGS 87AFF800 00000800 RESERVED
GSM 87C00000 00400000 RESERVED
dwOEMFailPowerPaging 00000000 00000001 FIXUPVAR
dwOEMDrWatsonSize 00000000 0004B000 FIXUPVAR
dwOEMPagingPoolSize 00000000 00200000 FIXUPVAR
You can add a new value here that is conditional on a makeimg flag:
dwOEMEnablePassiveKITL 00000000 00000001 FIXUPVAR
The value dwOEMEnablePassiveKITL should live in \PLATFORM\GSAMPLE\SRC\KERNEL\OAL\init.c . If you take a look at that file you will see something similar to this:
// Global FixUp variables
// Note: This is workaround for makeimg limitation // no fixup on variables
// initialized to zero.
DWORD dwOEMFailPowerPaging = 1;
DWORD dwOEMDrWatsonSize = 0x0004B000;
DWORD dwOEMPagingPoolSize = 0x00200000;
DWORD dwOEMPlatform = OAL_IOCTL_PLATFORM_WINCE;
DWORD gdwFailPowerPaging; extern DWORD cbNKPagingPoolSize; extern LPCWSTR g_pPlatformManufacturer; extern LPCWSTR g_pPlatformName;
You need to add the actual value that will be modified in the makeimg process. In the example above, that would be:
DWORD dwOEMEnablePassiveKITL = 0xFFFFFFFF;
extern DWORD g_dwEnablePassiveKITL;
Why is this initialized to 0xFFFFFFFF and not 0x0? Because you cannot have fixup variables initialized to 0x0 (See the comments in the init.c file above).
The extern in front of g_dwEnablePassiveKITL is important because this global variable is used in this file but is declared and initialized in kitl.c.
Next, you need to copy the FIXUPVAR dwOEMEnablePassiveKITL to g_dwEnablePassiveKITL in OEMInit(). Search for OEMInit() in init.c and add this line somewhere in the function:
g_dwEnablePassiveKITL = dwOEMEnablePassiveKITL;
In order to make use to the new FIXUPVAR, you need to modify \PLATFORM\GSAMPLE\SRC\kernel\oal\kitl.c. First, you must define and initialize the global at the top of kitl.c:
DWORD g_dwEnablePassiveKITL = 0xFFFFFFFF;
NOTE: this global must be defined in both KITL and non-KITL builds or else you will not be able to build properly. In the case of non-KITL, it will be ignored. If you separate your KITL functions for non-KITL builds into a separate file with empty stubs for the KITL functions, make sure you also declare this global there. In our case this is done in \PLATFORM\GSAMPLE\SRC\kernel\oal\kitl.c.
Finnaly, in OALKitlStart(), you need to add the flag. You probably call OALArgsQuery() to get the current value. If you set this value in the bootloader, this is how it is passed in. Once you have a pointer to OAL_KITL_ARGS (we will call it pArgs in this example) you need to OR in OAL_KITL_FLAGS_PASSIVE:
(0xFFFFFFFF != g_dwEnablePassiveKITL)
pArgs->flags |= OAL_KITL_FLAGS_PASSIVE;
That is it. Now, after building, you can enable passive KITL by setting IMGPASSIVEKITL=1 in your build environment and running makeimg.
1. Make sure you only use debug dlls that are relevant
2. Plug the device into a PC as quickly as possible when the device hits an exception and KITL is activated. Otherwise, the battery will drain and the crash will be lost
3. Turn off Compiler Optimization to the components you are debugging if possible
4. Add a FIXUPVAR in config.bib
5. Copy value of FIXUPVAR to the global in init.c
6. OR OAL_KITL_FLAGS_PASSIVE to pArgs->flags in kitl.c if your global (g_dwEnablePassiveKITL) is set