wince5.0的KernelIoControl分析和应用
JNU_kinke
初学wince的时候,下载运行NK,经常看到内核输出如下的信息:
OEMIoControl: Unsupported Code 0x xx - device 0x xxxx func xx
当时查了不少资料,由于水平所限,只是一知半解,即调用KernelIoControl函数不支持的IoControlCode所致云云。下面我详细说说这个流程。
首先要了解KernelIoControl是一个内核函数,不开源的。但调用KernelIoControl会调用OAL层的OEMIoControl函数去执行实际的调用。OEMIoControl函数实现在
Ioctl.c (%_WINCEROOT%/platform/common/src/common/ioctl)文件中
OEMIoControl函数并复杂,分析OEMIoControl前,必须先来认识一下OAL_IOCTL_HANDLER g_oalIoCtlTable[]数组,该数组定义了OAL层OEMIoControl实际要执行的代码。g_oalIoCtlTable的类型见下。
typedef struct {
UINT32 code; //IoctlCode控制码
UINT32 flags; //标志,实际定义为0
BOOL (*pfnHandler)(UINT32, VOID*, UINT32, VOID*, UINT32, UINT32*);//该code要关联函数的指针。
} OAL_IOCTL_HANDLER, *POAL_IOCTL_HANDLER;
g_oalIoCtlTable[]在
Ioctl.c (%_WINCEROOT%/platform/smdk2440/src/kernel/oal)中定义,实际内容在
Ioctl_tab.h (%_WINCEROOT%/platform/smdk2440/src/inc),见图1,我就数组中的一些code做了注释(个人观点)。
图1
OEMIoControl简单分析见图2.
图2
编写自己的KernelIoControl控制代码。
1、定义I/O控制码,在Pkfuncs.h (%_WINCEROOT%/public/common/oak/inc) 合适位置添加
#define IOCTL_HAL_SHUTDOWN CTL_CODE(FILE_DEVICE_HAL, 2048, METHOD_NEITHER, FILE_ANY_ACCESS)
这里要注意,系统保留了0-2047的code自用,2048-4095可有客户自由使用。因此在此定义了2048(红色标注部分)。
2、定义控制码要执行的函数。例如在
Reboot.c (%_WINCEROOT%/platform/smdk2440/src/common/ioctl)中添加
BOOL OALIoCtlHalShutdown(UINT32 code, VOID *pInpBuffer,
UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
/*在此添加关机代码*/
}
3、在Oal_ioctl.h (%_WINCEROOT%/platform/smdk2440/src/inc)添加声明。
4、把该Ioctlcode和函数添加到g_oalIoCtlTable[]数组中。
5、重新编译后,在应用程序或者驱动中调用KernelIoControl(IOCTL_HAL_SHUTDOWN, NULL, 0, NULL, 0, NULL)函数,具体参数参见帮助文档。