现在的位置: 首页 > 综合 > 正文

KernelIoControl和KernelLibIoControl

2013年06月08日 ⁄ 综合 ⁄ 共 2115字 ⁄ 字号 评论关闭

 

KernelIoControl
应用调用会先跳转到Oalioctl的IOControl,判断此ioctl是否有执行权限(默认只支持五种,IOCTL_HAL_GET_CACHE_INFO、
IOCTL_HAL_GET_DEVICE_INFO、IOCTL_HAL_GET_DEVICEID、IOCTL_HAL_GET_UUID、IOCTL_PROCESSOR_INFORMATION),有的话则触发OEMIoControl调用(会查找OAL中的表g_oalIoCtlTable);内核调用则直接跳转到相应ioctl执行。

KernelLibIoControl
在驱动中调用和ISR进行通讯,这个似乎与GIISR机制有关系。如果第一个参数赋值为KMOD_OAL,其作用等同KernelIoControl
// Predefined Kernel Module numbers
#define KMOD_INVALID    0
#define KMOD_CORE       1
#define KMOD_DBG        2               // Debugger specific extensions
#define KMOD_CELOG      3
#define KMOD_APPVERIF   4
#define KMOD_OAL        5               // Pass through to OEMIoControl
#define KMOD_KITL       6
#define KMOD_MAX        6
====================
关于可安装ISR
一般说来,OEM在OEMInit函数中关联IRQ和SysIntr,当硬件设备发生中断时,ISR会禁止同级和低级中断,然后根据IRQ返回关联的SysIntr,内核根据ISR返回的SysIntr唤醒相应的IST(SysIntr与IST创建的Event关联),IST处理中断之后调用InterruptDone解除中断禁止。在OEMInit中关联的缺点是一旦编译了CE内核后就无法添加这种关联了,而一些硬件设备会随时插拔或者共享中断,要关联这样的硬件设备解决方法就是可安装ISR,可安装ISR专用于处理指定的硬件设备发出的中断,所以如果硬件设备需要可安装ISR必须在注册表中添加IsrDll、IsrHandler。多数硬件设备采用CE默认的可安装ISR
giisr.dll,格式如下:

IsrDll"="giisr.dll" 
"IsrHandler"="ISRHandler"

如果一个硬件驱动程序需要可安装ISR而开发者又不想自己写一个,那么可以利用giisr.dll来实现。除了在注册表中添加如上所示外,还要在驱动程序中调用相关函数注册可安装ISR。伪代码如下:

g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq); 
GIISR_INFO Info;
PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0};
TransBusAddrToStatic(BusType, dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, &(PVOID)PhysAddr)
Info.SysIntr = dwSysIntr;
Info.CheckPort = TRUE;
Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE;
Info.UseMaskReg = TRUE;
Info.PortAddr = PhysAddr + 0x0C;
Info.PortSize = sizeof(DWORD);
Info.MaskAddr = PhysAddr + 0x10;
KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL);

LoadIntChainHandler函数负责注册可安装ISR,参数1为DLL名称,参数2为ISR函数名称,参数3为IRQ。TransBusAddrToStatic函数在后面讲。如果要利用giisr.dll作为可安装ISR,必须先填充GIISR_INFO结构体,CheckPort=TRUE表示giisr要检测指定的寄存器来确定当前发出中断的是否是这个设备。PortIsIO表示寄存器地址属于哪个地址空间,FALSE表示是内定空间,TRUE表示IO空间。UseMaskReg=TRUE表示设备有一个掩码寄存器,专用于指定当前设备是否是中断源,也就是发出中断,而MaskAddr表示掩码寄存器的地址。如果对Info.Mask赋值,那么PortAddr表示一个特殊的寄存器地址,这个寄存器的值与Mask的值&运算的结果如果为真,则证明当前设备是中断源,否则返回SYSINTR_CHAIN(表示当前ISR没有处理中断,内核将调用ISR链中下一个ISR),如果UseMaskReg=TRUE,那么MaskReg寄存器的值与PortAddr指定的寄存器的值&运算的结果如果为真,则证明当前设备是中断源。

抱歉!评论已关闭.