ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
20楼#
发布于:2003-12-24 09:46
下面是HOOK中断的代码:


/* Interrupt to be hooked */
#define HOOKINT 0x09

头文件中的定义
***************************************

/* sidt instruction stores the base and limit of IDTR in this format */
typedef struct idtr {
short Limit;
unsigned int Base;
} Idtr_t, *PIdtr_t;

/* Decriptor Entry corresponding to interrupt gate */
typedef struct idtentry {
unsigned short OffsetLow;
unsigned short Selector;
unsigned char Reserved;
unsigned char Type:1;
unsigned char Always0:1;
unsigned char Dpl:3;
unsigned char Present:1;
unsigned short OffsetHigh;
} IdtEntry_t, *PIdtEntry_t;



************************************


/* Get the Base and Limit of IDTR Register */
_asm sidt buffer
IdtEntry=(PIdtEntry_t)Idtr->Base;

/* Index the interrupt number to be hooked in appropriate IDT
entry and save away the Old handler\'s address */
OldHandler=((unsigned int)IdtEntry[HOOKINT].OffsetHigh<<16U)|
(IdtEntry[HOOKINT].OffsetLow);

/* Plug into the interrupt by changing the offset field to point
to NewHandler function */
_asm cli
IdtEntry[HOOKINT].OffsetLow=(unsigned short)NewHandler;
IdtEntry[HOOKINT].OffsetHigh=(unsigned short)((unsigned int)NewHandler>>16);
// IdtEntry[HOOKINT].Dpl=6;
// IdtEntry[HOOKINT].Present=0;
_asm sti


新的服务程序
――――――――――――――――――――――――
void NewHandlerCFunc(int ServiceId)
{
if (ServiceId>NumberOfServices)
return;
ServiceCounterTable[ServiceId+1]++;
return;
}

―――――――――――――――――――――――――

另外的文件
###################################

_NewHandler proc near //NewHandler EIP 为FO9E2280
Ring0Prolog
STI
push eax
call _NewHandlerCFunc@4
CLI
Ring0Epilog
jmp dword ptr cs:[_OldHandler]
_NewHandler endp
END

###################################

SOFTICE中IDT命令:
运行前
0009 INTG32 0008:80466A6C DPL=0 P NTOSKRNL!KEI386EOIHELPORT+16B6

运行后

0009 INTG32 0008:FO9E2280 DPL=0 P HOOKINT!TEXT


但没有进入中断?
ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
21楼#
发布于:2003-12-24 09:53


***********************
改就改完,把中断服务所在段的权限全部弄成3,先看看能工作不,虽然这样做有点儿不安全。
***********************

 我改了段的权限,但运行SOFTICE提示
Break due unhandledexception NTSTATAUS=STATUS_ACCESS_VIOLATION
只有重起。
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
22楼#
发布于:2003-12-24 11:32
一点儿一点来,首先,INTG定义有问题,应该为:
/* Decriptor Entry corresponding to interrupt gate */
typedef struct idtentry {
unsigned short OffsetLow;
unsigned short Selector;
//unsigned char Reserved;
unsigned char ParamCount:5; <<<-----INTG里没用,但定义一下比较正规(符合CALL GATE)
unsigned char Reserved:3;
//unsigned char Type:1; <<<------错
unsigned char Type:4;
unsigned char Always0:1;
//unsigned char Dpl:3; <<<-----错
unsigned char Dpl:2;
unsigned char Present:1;
unsigned short OffsetHigh;
} IdtEntry_t, *PIdtEntry_t;

如果按以前你的定义,你设置DPL实际上把Type给改了,那哪能不出错?
而且DPL不用改,因为按照Intel的定义,硬件中断忽略INTG的DPL检查.

[编辑 -  12/24/03 by  cool-net]

[编辑 -  12/24/03 by  cool-net]

[编辑 -  12/24/03 by  cool-net]
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
23楼#
发布于:2003-12-24 14:59

太感谢啦!!
天那!可以进入中断啦!! :D :) :D :)

但是,我不知到IRQ0在2000的IDT中对应的是多少???
(我一直以为是0008,但是中断服务程序不执行,我用SOFTICE的BPINT 8,没进入SOFTICE(如果是时钟中断每秒产生18.2次中断,那该进入SOFTICE)。但我用GENINT 8产生一个中断,可以进入我的中断程序(上面的程序HOOKINT改为0X08))。
2000下的INT=IRQ+30,那是不是0038???
我用SOFTICE的BPINT 38,但没有进入SOFTICE,我用SOFTICE的BPINT 39,进入了SOFTICE,但39是时钟中断还是键盘中断???

软盘的IRQ=6,我用BPINT 36,点软驱可以响应中断,那????


ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
24楼#
发布于:2003-12-24 15:47


**************************
2000下的INT=IRQ+30,那是不是0038???
我用SOFTICE的BPINT 38,但没有进入SOFTICE,我用SOFTICE的BPINT 39,进入了SOFTICE,但39是时钟中断还是键盘中断???

**************************

不好意思!!又写错啦!

2000下的INT=IRQ+30,那是不是0030???
我用SOFTICE的BPINT 30,进入了SOFTICE,30是时钟中断???
我用SOFTICE的BPINT 31,进入了SOFTICE,31是键盘中断???


我把HOOKINT设为30,在中断中设置断点,可以进入中断,单步但在
void NewHandlerCFunc(int ServiceId)
{
if (ServiceId>NumberOfServices)
return;
ServiceCounterTable[ServiceId+1]++;
return;                ――――――//****此处重起***
}

为什么???

如果不设置断点,驱动程序一运行就跳到SOFTICE,显示
Break due to page fault(0Eh)fault=0002

又是为何???



cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
25楼#
发布于:2003-12-24 16:41
首先,我已经说过,由于外部中断在IDT中的位置是可以软件设置的,所以象时钟或键盘之类的可能已经被移到别的地方了(初始化时是8和9没错,但由于8和9同被CPU当成别的trap用,所以我想OS一定把时钟和键盘给移到别的地方了),具体在什么地方我也不是很清楚(你可以先按照自己的想法试试).

至于出错,我还没有肯定,只是猜测:
你得看看NewHandlerCFunc生成的汇编码,注意最后的ret,是不是以__stdcall的方式返回的(反汇编之后应该是 retn 4),如果不是,你需要把NewHandlerCFunc显式声明成__stdcall(按理说DDK默认调用方式是__sdtcall,但我还是想确认一下)或者加一句:

_NewHandler proc near //NewHandler EIP 为FO9E2280
Ring0Prolog
STI
push eax
call _NewHandlerCFunc@4
pop eax <<<---------这句
CLI
Ring0Epilog
jmp dword ptr cs:[_OldHandler]
_NewHandler endp
END

如果我的猜测正确,那问题就算解决了,否则就再找找看.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
26楼#
发布于:2003-12-25 11:44



出错是因为中断服务程序,我把它删了,可能是内存泄露。

我发现时钟中断是30,键盘31。
INT=IRQ+30:2000下
INT=IRQ+50:98下

我发现在中断服务程序中用OUT操作0X378不行,数据口电平没变。
用WRITE_PORT_UCHAR宏可以,但是一条指令用了800NS,我用示波器测。
可不可以,直接在驱动程序中用OUT/IN汇编访问并口?

我想把8253的中断频率提高到100K,每次中断进入我的处理程序,55MS后调用系统老的时钟中断程序,可不可行?






 :D :D
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
27楼#
发布于:2003-12-25 12:14
>> 我发现在中断服务程序中用OUT操作0X378不行
>> 用WRITE_PORT_UCHAR宏可以
检查一下你的代码,WRITE_PORT_UCHAR没什么特别的:
mov EDX, 0378h
mov AL, value
out DX, AL

>> 我想把8253的中断频率提高到100K,每次中断进入我的处理程
>> 序,55MS后调用系统老的时钟中断程序,可不可行?
最好不要这样干,会影响系统的运行.
我到现在还没搞明白你为什么要截时钟中断,用Kernel定时器不行吗?
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
28楼#
发布于:2003-12-25 16:35
没问题啊,我觉得只要保持系统原来的计数器不混乱就可以了,你的中断服务可以保证这点的。
对了,兄弟,我想说一句,我突然想到你们说的中断服务号被WIN重新分配,这个确定不?因为我觉得软中断和硬中断可以共享一个中断号的,做法和硬件共享中断号一样,只要这个中断服务里面可以判断得出来这是什么就可以了,比如硬件来的中断可以通过检查状态寄存器判断出来,如果状态寄存器显示无中断打过来,那么再通过AX等的值当成软中断(自陷)处理,这样也是可以的嘛。你们怎么认为
根据地的兄弟们,团结就是力量
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
29楼#
发布于:2003-12-25 16:44
>> 没问题啊,我觉得只要保持系统原来的计数器不混乱就可以了,
>> 你的中断服务可以保证这点的。
关键是时间,你要是在里面不及时STI,操作系统所使用的那个高精度时钟可就废了(那个可不象每秒18.2次这么慢).

>> 我突然想到你们说的中断服务号被WIN重新分配,这个确定不
确定.

>> 我觉得软中断和硬中断可以共享一个中断号
没有总是,就象你可以在程序里直接 INT 08h 一样的道理.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
30楼#
发布于:2003-12-25 17:09
高精度时钟恐怕不是用中断计数的吧,奔腾以后的内部TIMER有几个?谁有资料
COOL_NET兄弟,你说的用INT 8什么的啥子意思?:)没懂
根据地的兄弟们,团结就是力量
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
31楼#
发布于:2003-12-25 18:56
>> 高精度时钟恐怕不是用中断计数的吧
肯定是中断

>> 奔腾以后的内部TIMER有几个
我记得386里就已经有至少两个不同的时钟了吧?一个18次的和一个um级的。

>> 谁有资料
手边没有,网上肯定有

>> COOL_NET兄弟,你说的用INT 8什么的啥子意思?:)没懂
就是可以在代码里直接触硬中断(在ASM里写一行 int 08h或写机器码 CD 08):):):)
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
makefriend8
驱动小牛
驱动小牛
  • 注册日期2003-08-01
  • 最后登录2014-06-27
  • 粉丝0
  • 关注0
  • 积分84分
  • 威望111点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
32楼#
发布于:2003-12-25 19:07
好好。。。做好了之后那为老兄能否贴一下源码?
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
33楼#
发布于:2003-12-25 19:40
>> 高精度时钟恐怕不是用中断计数的吧
肯定是中断

>> 奔腾以后的内部TIMER有几个
我记得386里就已经有至少两个不同的时钟了吧?一个18次的和一个um级的。

>> 谁有资料
手边没有,网上肯定有

>> COOL_NET兄弟,你说的用INT 8什么的啥子意思?:)没懂
就是可以在代码里直接触硬中断(在ASM里写一行 int 08h或写机器码 CD 08):):):)


兄弟,那么肯定啊,片子里面的时钟自己计数的很多啊,这种高精度时钟用中断让CPU计数想想不太可能吧,0.1US一个时钟中断?不太好吧,当然,这个东西和OS于HARDWARE PALTFORM的整合有关
根据地的兄弟们,团结就是力量
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
34楼#
发布于:2003-12-25 22:35
呵呵,这得看操作系统如果处理了。
0.1us一个中断也没什么不可以的,也许系统仅仅给某个ULONGLONG加个1而已,加到一定的时候(比如计数器%10000000==0)再执行别的操作(比如派个APC之类的),同数计数器还往上加... ...:):):)
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
35楼#
发布于:2003-12-26 10:55


************************
我到现在还没搞明白你为什么要截时钟中断,用Kernel定时器不行吗?

***********************
我要在中断服务程序里,把端口置高后又置底,输出脉冲,脉冲频率要均匀,平稳,可调。Kernel定时器能达到10US,或者更高,而且不受干扰?如果行的话,可以试试!!

我真是太笨啦,把汇编写错啦,还以为不能用OUT,不好意思。只怪当初学习不用功。

ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
36楼#
发布于:2003-12-26 11:03


我把8253定时初值改到20(原来1700),大概是40K左右。输出脉冲也有40K,但是有杂波,为什么?

我把W2K自带并口驱动程序卸载了,就输不出波形。难道OUT还要用并口驱动程序才能工作?

ZHULUSHENG
驱动牛犊
驱动牛犊
  • 注册日期2003-10-27
  • 最后登录2006-07-04
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
37楼#
发布于:2003-12-26 11:13

***************************
0.1us一个中断也没什么不可以的,也许系统仅仅给某个ULONGLONG加个1而已,加到一定的时候(比如计数器%10000000==0)再执行别的操作(比如派个APC之类的),同数计数器还往上加... ...

***************************

如何设置一个计数器,不受8253干扰,能保证55MS调到老的中断程序?

8253的中断好象只处理系统时种和一些简单的定时吧??

cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
38楼#
发布于:2003-12-26 11:20
哥们儿,你的这些问题对我而言太难了,在硬件控制方面我肯定没你在行.:):):):)

你先试试把,我得先研究研究资料才能知道怎么回事.:(:(:(
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
39楼#
发布于:2003-12-26 11:24


我把8253定时初值改到20(原来1700),大概是40K左右。输出脉冲也有40K,但是有杂波,为什么?

我把W2K自带并口驱动程序卸载了,就输不出波形。难道OUT还要用并口驱动程序才能工作?

 

杂波问题应该是有别的什么干扰源存在(也许就是并口驱动,PnP可能要时不时检查一下并口上有没有连上什么新打印机之类的).

如果你卸掉并口驱动,那么你得自己得并口控制器的初始化工作(具体要做哪些我也不太清楚),否则并口能不能用就很难说.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
游客

返回顶部