`
izuoyan
  • 浏览: 8913392 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

今天搞定getch在linux下的实现

阅读更多
一般的终端模式下,使用的是('\n'),EOF,orEOL这样一些结束符,可是在某些情况下,我们需要对某些键盘输入做响应,所以,采用的就是非经典模式终端,
structtermios{
tcflag_tc_iflag;/*输入模式旗标*/
tcflag_tc_oflag;/*输出模式旗标*/
tcflag_tc_cflag;/*控制模式旗标*/
tcflag_tc_lflag;/*区域模式旗标*/
cc_tc_line;/*行控制(linediscipline)*/
cc_tc_cc[NCCS];/*控制特性*/
};

void
set_input_mode(void)
{
structtermiostattr;
char*name;

/*Makesurestdinisaterminal.*/
if(!isatty(STDIN_FILENO))
{
fprintf(stderr,"Notaterminal.\n");
exit(EXIT_FAILURE);
}

/*Savetheterminalattributessowecanrestorethemlater.*/
tcgetattr(STDIN_FILENO,&saved_attributes);
atexit(reset_input_mode);

/*Setthefunnyterminalmodes.*/
tcgetattr(STDIN_FILENO,&tattr);
tattr.c_lflag&=~(ICANON);/*ClearICANON*/
tattr.c_cc[VMIN]=1;
tattr.c_cc[VTIME]=0;
tcsetattr(STDIN_FILENO,TCSAFLUSH,&tattr);
}
标签:
diaryids+=','+206313813;
2005-04-19 02:25:20晴
KERNEL UNDSTAND
Linux中宏定义很多,而且又分散在各个头文件中,你可以预处理一下,比如gcc-D__KERNEL__-Econsole.c>console.i
这样,console.c中的很多结构定义就在console.i中清晰的暴露了出来;有时可以用nm命令检查一下目标模块的包含的符号名,比如nmconsole.o,这样可得知console.o引用了那些外部符号,它自已定义了哪些符号;
另 一个方法是剖析运行中的系统.编绎内核产生的System.map文件非常重要,它包含了内核地址空间中各种符号名的地址,你可以用 System.map,结合源码,通过/dev/kmem检查内核中的各种数据结构,你也可以通过/dev/mem用物理地址来检查内存数据
标签:
diaryids+=','+206313824;
2005-04-19 02:12:41晴
rh9 2.4.20下模块printk 找不到连接
编译都没有了问题。
在加载模块时,出现了说printk这个符号无法解释的问题,
与一般模式下相同,一定是这个printk找不到实现,
原来是在kenel中有一个exporttable包含了所有kernel中
可以使用的function,ksyms-a
得到c0216ba0drive_info_R744aa133
c01e4a44boot_cpu_data_R660bd466
c01e4ac0EISA_bus_R7413793a
c01e4ac4MCA_bus_Rf48a2c4c
c010cc34__verify_write_R203afbeb。。。
入口对应的就是函数名,可是这个函数名太诡异了啊,其实这是一个
版本号,来保证内核的稳定开发的,所以我们在使用printk时
需要指定这个版本号,
解决的办法:
要嘛就是将kernel里的setversion选项关掉,
#ifdefMODVERSIONS
#include<linux/modversions.h>
#endif
要嘛就是将modulecompile成kernel有办法接受的型式。这个办法可以使用宏替换
不过何必呢。呵呵

#ifndef__KERNEL__
#define__KERNEL__
#endif

#include</usr/src/linux-2.4.20-8/include/linux/version.h>

#ifndefMODULE
#defineMODULE
#endif

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>

#ifdefMODVERSIONS

#include<linux/modversions.h>
#endif
staticint__initinit(void)
{
printk("<0>init\n");
return0;
}

staticvoid__exitfini(void)
{
printk("<0>exit\n");
}

module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
/*module.c*/

INCLUDEDIR=/usr/src/linux-2.4.20-8/include
CC=gcc
LD=ld
CFLAGS=-D__KERNEL__-DMODULE-DMODVERSIONS-O-Wall-Wstrict-prototypes-I$(INCLUDEDIR)
VER=2.4.20-8
OBJS=hello.o
all:$(OBJS)
hello.o:hello.c
$(CC)$(CFLAGS)-c$^-o$@
clean:
rm-f*.o
rm-fcore

标签:
diaryids+=','+206314311;
2005-04-16 02:06:56晴
iptables下udp穿越基础篇----iptables与stun [zz]

Stun协议(Rfc3489、详见::URL::http://www.ietf.org/rfc/rfc3489.txt)将NAT粗略分为4种类型,即FullCone、RestrictedCone、PortRestrictedCone和Symmetric。举个实际例子(例1)来说明这四种NAT的区别:
A机器在私网(192.168.0.4)
NAT服务器(210.21.12.140)
B机器在公网(210.15.27.166)
C机器在公网(210.15.27.140)
现在,A机器连接过B机器,假设是A(192.168.0.4:5000)->NAT(转换后210.21.12.140:8000)->B(210.15.27.166:2000)。
同时A从来没有和C通信过。
则对于不同类型的NAT,有下列不同的结果:
FullConeNAT:C发数据到210.21.12.140:8000,NAT会将数据包送到A(192.168.0.4:5000)。因为NAT上已经有了192.168.0.4:5000到210.21.12.140:8000的映射。
RestrictedCone: C无法和A通信,因为A从来没有和C通信过,NAT将拒绝C试图与A连接的动作。但B可以通过210.21.12.140:8000与A的 192.168.0.4:5000通信,且这里B可以使用任何端口与A通信。如:210.15.27.166:2001-> 210.21.12.140:8000,NAT会送到A的5000端口上。
PortRestrictedCone:C无法与A通信,因为A从来没有和C通信过。而B也只能用它的210.15.27.166:2000与A的192.168.0.4:5000通信,因为A也从来没有和B的其他端口通信过。该类型NAT是端口受限的。
SymmetricNAT: 上面3种类型,统称为ConeNAT,有一个共同点:只要是从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。但是 Symmetric有点不同,具体表现在:只要是从同一个内部地址和端口出来,且到同一个外部目标地址和端口,则NAT也都将它转换成同一个外部地址和端 口。但如果从同一个内部地址和端口出来,是到另一个外部目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。而且 和PortRestrictedCone一样,只有曾经收到过内部地址发来包的外部地址,才能通过NAT映射后的地址向该内部地址发包。
现针对SymmetricNAT举例说明(例2):
A机器连接过B机器,假使是A(192.168.0.4:5000)->NAT(转换后210.21.12.140:8000)->B(210.15.27.166:2000)
如 果此时A机器(192.168.0.4:5000)还想连接C机器(210.15.27.140:2000),则NAT上产生一个新的映射,对应的转换可 能为A(192.168.0.4:5000)->NAT(转换后210.21.12.140:8001)->C (210.15.27.140:2000)。此时,B只能用它的210.15.27.166:2000通过NAT的210.21.12.140:8000 与A的192.168.0.4:5000通信,C也只能用它的210.15.27.140:2000通过NAT的210.21.12.140:8001 与A的192.168.0.4:5000通信,而B或者C的其他端口则均不能和A的192.168.0.4:5000通信。
通过上面的例子,我们清楚了Stun协议对NAT进行分类的依据。那么,我们现在根据上述分类标准(或例子),来简要分析一下iptables的工作原理(仅指MASQUERADE、下同),看看他又是属于哪种NAT呢?
首先,我们去网上下载一个使用Stun协议检测NAT的工具,网址在::URL::http://sourceforge.net/projects/stun/,使用该工具对iptables的检测结果是PortrestrictedNATdetected。
我们先不要急着接受这个检测结果,还是先来分析一下iptables的工作原理吧

iptables在转换地址时,遵循如下两个原则:
1、尽量不去修改源端口,也就是说,ip伪装后的源端口尽可能保持不变。(即所谓的Preservesportnumber)
2、更为重要的是,ip伪装后只需保证伪装后的源地址/端口与目标地址/端口(即所谓的socket)唯一即可。
仍以前例说明如下(例3):
A机器连接过B机器,假使是A(192.168.0.4:5000)->NAT(转换后210.21.12.140:5000)->B(210.15.27.166:2000)。(注意,此处NAT遵循原则1、故转换后端口没有改变)
如 果此时A机器(192.168.0.4:5000)还想连接C机器(210.15.27.140:2000),则NAT上产生一个新的映射,但对应的转换 仍然有可能为A(192.168.0.4:5000)->NAT(转换后210.21.12.140:5000)->C (210.15.27.140:2000)。这是因为NAT(转换后210.21.12.140:5000)->B (210.15.27.166:2000)和NAT(转换后210.21.12.140:5000)->C(210.15.27.140: 2000)这两个socket不重复。因此,对于iptables来说,这既是允许的(第2条原则)、也是必然的(第1条原则)。
在该例中,表 面上看起来iptables似乎不属于SymmetricNAT,因为它看起来不符合SymmetricNAT的要求:如果从同一个内部地址和端口出 来,是到另一个目标地址和端口,则NAT将使用不同的映射,转换成不同的端口(外部地址只有一个,故不变)。相反,倒是符合除SymmetricNAT 外的三种ConeNAT的要求:从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。加上iptables具有端口受限的属性 (这一点不容置疑,后面举反例证明之),所以好多检测工具就把iptables报告为PortrestrictedNAT类型了。
下面仍以前例接着分析(例4):
在前例中增加D机器在A同一私网(192.168.0.5)
A机器连接过B机器,假使是A(192.168.0.4:5000)->NAT(转换后210.21.12.140:5000)->B(210.15.27.166:2000)
D机器连接过C机器,假使是D(192.168.0.5:5000)->NAT(转换后210.21.12.140:5000)->C(210.15.27.140:2000)
由iptables转换原则可知,上述两个转换是允许且必然的。
如 果此时A机器(192.168.0.4:5000)还想连接C机器(210.15.27.140:2000),则NAT上产生一个新的映射,但对应的转换 则变为A(192.168.0.4:5000)->NAT(转换后210.21.12.140:5001)->C (210.15.27.140:2000)。这是因为,如果仍然将其转换为210.21.12.140:5000的话,则其所构成的socket (210.21.12.140:5000->210.15.27.140:2000)将和D->C的socket一致,产生冲突,不符合 iptables的第2条原则(注意,此处以5001表示转换后不同的端口,但事实上,iptables却并不按照内部端口+1的原则来产生新的端口)。 在本例中我们注意到,从同一个内部地址和端口A(192.168.0.4:5000)出来,到不同的目标地址和端口,则NAT使用了不同的映射,转换成不 同的端口。
上面这个例子在实际环境中比较少见,我们再以QQ为例举一个真实且常见的例子(例5)。
假设
A(192.168.0.4)和D(192.168.0.5)是同一NAT服务器(210.21.12.140)保护的两台私网机器,都运行了QQ客户端程序。
B机器在公网(210.15.27.166),运行QQ服务器程序。
C机器在公网(210.15.27.140),运行QQ客户端程序。
A上QQ先登陆到B,按照原则1,使用如下映射:
A(192.168.0.4:4000)->NAT(转换后210.21.12.140:4000)->B(210.15.27.166:8000)(原则1,端口不变)
接着D上QQ也登陆到B,按照原则2,使用如下映射:
D(192.168.0.5:4000)->NAT(转换后210.21.12.140:4001)->B(210.15.27.166:8000)(原则2,scoket不能有重复,此处4001仅表示转换后不同的端口,实际环境中决不是4001)
然后D欲和公网C(210.15.27.140)上的QQ通信,按照iptables转换原则,使用如下映射:
D(192.168.0.5:4000)->NAT(转换后210.21.12.140:4000)->C(210.15.27.140:4000)
到此我们发现,和上例一样,从同一个内部地址和端口D(192.168.0.5:4000)出来,到不同的目标地址和端口,则NAT使用了不同的映射,转换成不同的端口。但和上例不一样的是,本例显然普遍存在于实际环境中。
上面所举两例表明,结论刚好和例3相反,即iptables应该属于SymmetricNAT。
为 什么会出现彼此矛盾的情况呢?首先从NAT分类的定义上来看,Stun协议和iptables对映射的理解不同。Stun协议认为,一个映射的要素是: 内部地址端口和NAT转换后地址端口的组合。而在iptables看来,一个映射的要素是:NAT转换后地址端口和外部目标地址端口的组合。另一方面则是 Stun协议里DiscoveryProcess给出的测试环境不够全面之故,他只考虑了NAT后面仅有一台私网机器的特例(例3),没有考虑NAT后 面可以有多台私网机器的普遍例子(例5)。正是由于这两个原因,直接导致了上述矛盾的发生。所以,凡按照Stun协议标准设计的NAT分类检测工具对 iptables的检测结果必然是PortrestrictedNAT。(事实上,在例3那样的特例下,iptables确实是一个标准的 PortrestrictedNAT)
那么,iptables究竟属于哪种NAT呢?我们再来回顾一下Stun协议对ConeNAT的要 求:所有(或只要是)从同一个内部地址和端口出来的包,NAT都将它转换成同一个外部地址和端口。虽然iptables在部分情况下满足“从同一个内部地 址和端口出来的包,都将把他转换成同一个外部地址和端口”这一要求,但它不能在所有情况下满足这一要求。所以理论上,我们就只能把iptables归为 SymmetricNAT了。
下面,我们再来分析一下iptables的端口受限的属性,我们举一个反例证明之(例6),仍以前例说明如下:
A机器连接过B机器,假使是A(192.168.0.4:5000)->NAT(转换后210.21.12.140:5000)->B(210.15.27.166:2000)
D机器连接过C机器,假使是D(192.168.0.5:5000)->NAT(转换后210.21.12.140:5000)->C(210.15.27.140:2000)
现 假设iptables不具有端口受限的属性,则另一E机器在公网(210.15.27.153:2000)或C(210.15.27.140:2001) 向210.21.12.140:5000发包的话,应该能够发到内部机器上。但事实是,当这个包到达NAT(210.21.12.140:5000)时, NAT将不知道把这个包发给A(192.168.0.4:5000)还是D(192.168.0.5:5000)。显然,该包只能丢弃,至此,足以证明 iptables具有端口受限的属性。
所以,iptables是货真价实的SymmetricNAT。

附:
1、Stun全称SimpleTraversalofUDPThroughNATs,所以本文所涉及的包,皆为UDP包。
2、 本文虽然是针对linux下iptables的分析,但倘若把本文中关键词“iptables”换成“Win2000下的ics或nat”,则本文的分析 过程完全适用于Win2000下的ics或nat。即理论上Win2000下的ics或nat也是货真价实的SymmetricNAT,但实际上,凡按 照Stun协议标准设计的NAT分类检测工具对其检测结果也必然是PortrestrictedNAT。其实,不光是linux下iptables、 或者Win2000下的ics或nat、再或者任何其他NAT产品,只要他们遵循和iptables一样的两条转换原则,那么他们在Stun协议下的表现 是完全一样的。
3、虽然Win2000下的ics或nat在Stun协议下的表现和iptables完全一样,但其NAT时所遵循的原则1和 iptables还是略有差别:iptables对内部私网机器来的所有源端口都将适用Preservesportnumber,除非确因原则2发生 冲突而不得不更换源端口号,但在更换端口号时并不遵循内部端口+1原则(似乎没有规律)。Win2000下的ics或nat则仅对内部私网机器来的部分源 端口(1025--3000)适用Preservesportnumber,对于那些超过3000的源端口号或者因原则2发生冲突的端口号,系统从 1025开始重新按序分配端口,在此过程中,仍然遵循如前两个原则,只是原则1不再Preservesportnumber而已(在不与原则2发生冲 突的前提下,尽量重复使用小的端口号,故使用1025的几率远远大于1026、1027…)。

即将推出其姊妹篇----iptables下udp穿越实用篇----“iptables与natcheck”

::URL::http://www.linuxforum.net/docnew/showflat.php?Board=new&Number=722
标签:
diaryids+=','+206313843;
2005-04-15 01:35:38晴
一个诡异的C调用
实现的是一个空调用实现一个函数调用,这话说得就很奇怪吧。^_^

看程序

voidf()
{
printf("thisisacall");
}

intmain()
{
intbuf[1];
buf[2]=(int)f;
return0;
}j
这个函数没有一个地方是调用f的,注意这一点哦
这是因为buf[2]的溢出覆盖了main的返回地址
高--》低
[eip][ebp][buf[0]]
f函数f的地址被放到了ebp+8的地方,也就是刚好是[eip]的位置。
ebp+8是怎么产生出来的呢?嘿嘿。对于栈的访问c的策略就是ebp+位置,ebp-8放的是buf[0]的值
ebp是buf[1]嘿嘿。知道了吧
可以cl/FA来产生汇编码细细的看这个。
movDWORDPTR_buff$[ebp+8],OFFSETFLAT:_f
标签:
diaryids+=','+206313872;
2005-04-15 01:04:56晴
经典CC++面试题(han)
链表与数组的区别
A从逻辑结构来看
A-1.数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。

A-2.链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)


B从内存存储来看
B-1.(静态)数组从栈中分配空间,对于程序员方便快速,但是自由度小
B-2.链表从堆中分配空间,自由度大但是申请管理比较麻烦.



堆和栈的区别

solost于2004年10月09日发表

一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器(Compiler)自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。-程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。



二、例子程序
这是一个前辈写的,非常详细
//main.cpp
inta=0;全局初始化区
char*p1;全局未初始化区
main()
{
intb;栈
chars[]="abc";栈
char*p2;栈
char*p3="123456";123456\0在常量区,p3在栈上。
staticintc=0;全局(静态)初始化区
p1=(char*)malloc(10);
p2=(char*)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1,"123456");123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}


二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。例如,声明在函数中一个局部变量intb;系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1=(char*)malloc(10);
在C++中用new运算符
如p2=(char*)malloc(10);
但是注意p1、p2本身是在栈中的。


2.2申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会 遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内 存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大 小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数 据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总 之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。


2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

2.5堆和栈中的存储内容
栈:在函数调用时,(1)第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,(2)然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,(3)然后是函数中的局部变量。注意:静态变量是不入栈的。
当本次函数调用结束后,(1)局部变量先出栈,(2)然后是参数,(3)最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

2.6存取效率的比较
chars1[]="aaaaaaaaaaaaaaa";
char*s2="bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
voidmain()
{
chara=1;
charc[]="1234567890";
char*p="1234567890";
a=c[1];
a=p[1];
return;
}
对应的汇编代码
10:a=c[1];
004010678A4DF1movcl,byteptr[ebp-0Fh]
0040106A884DFCmovbyteptr[ebp-4],cl
11:a=p[1];
0040106D8B55ECmovedx,dwordptr[ebp-14h]
004010708A4201moval,byteptr[edx+1]
004010738845FCmovbyteptr[ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。


2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。


深度优先搜索与广度优先搜索算法有何区别呢?
  通常深度优先搜索法不全部保留结点,扩展完的结点从数据库中弹出删去,这样,一般在数据库中存储的结点数就是深度值,因此它占用空间较少。所以,当搜索树的结点较多,用其它方法易产生内存溢出时,深度优先搜索不失为一种有效的求解方法。
  广度优先搜索算法,一般需存储产生的所有结点,占用的存储空间要比深度优先搜索大得多,因此,程序设计中,必须考虑溢出和节省内存空间的问题。但广度优先搜索法一般无回溯操作,即入栈和出栈的操作,所以运行速度比深度优先搜索要快些

标签:
diaryids+=','+206313904;
2005-04-13 01:17:48晴
inside Win2k (1)
insidewin2k中,提到IRQL高于DPC级别的就无法使用页式内存,因为要是出现缺页不在物理内存的情况需要
调用磁盘IO换页,这样的响应时间就无法保证了,这是很好理解的。可是问题是:无法使用页式内存就要求
是使用物理内存,这样的话,要是这些物理内存是没有数据的还讲的通,页表在对这些页面访问时就都无法
访问。可是要是物理内存是分配出去的,被某些页表使用,那数据需要换出,这样不也就违背了不使用页式
内存的初衷?页式内存VS物理内存!GDTL.全局页表。LDT。局部页表。
还有,DPC的设置,感觉是比较好的防止优先权倒置的好的办法,把中断处理的任务尽可能的拖到DPC去实现
就保证IRQL不是老是处于高级别,这样有中断发生时,OS可以快速的响应。D可是,理解来说还是没有问题
现在的问题是,要是驱动的中断响应结束了,这余下的任务拖到DPC去在有时间的时候实现,这样如何保证
同步性,因为下次中断又接着马上就到了了,要是它依赖与上次事件的话,这样可怎么不?我想应该
没有问题,可是详细的理解又有问题。
OS高得头都大了。唉。

标签:
diaryids+=','+206314340;
2005-04-13 00:02:15晴
2.6内核模块编译的变化
::URL::http://www.nsfocus.net/index.php?act=sec_doc&do=view&doc_id=949&keyword=

2
。4的不行了老的编译
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/module.h>

staticintdummy_init(void)
{
printk("hello,world.\n");
return0;
}
staticvoiddummy_exit(void)
{
return;
}

module_init(dummy_init);
module_exit(dummy_exit);

MODULE_LICENSE("GPL")
------------------------------8cuthere8-----------------------------------
#gcc-c-O2-DMODULE-D__KERNEL__-I/usr/src/linuxtest.c
#insmodtest.o
Nomodulefoundinobject
insmod:errorinserting'test.o':-1Invalidmoduleformat
准确的做法是:
正确的做法是写一个Makefile,由内核的Kbuild来帮你编译
-------------------------------8Makefile8-----------------------------------
obj-m:=module.o
KDIR:=/lib/modules/$(shelluname-r)/build
PWD:=$(shellpwd)
default:
$(MAKE)-C$(KDIR)SUBDIRS=$(PWD)modules
--------------------------------8cuthere8----------------------------------
标签:
diaryids+=','+206314364;
2005-04-10 01:33:15晴
M$太e了
现在觉得被人逼着换技术的郁闷了。居然不再使用VC6。我考
Youcannot-IreceivedwordfromtheSDKteamthatVC++6.0isnolongera
supportedproduct.ThelastversiontosupportVC++6.0istheFebruary
2003SDK.

NofurtherPlatformSDKswillbereleasedthatsupportVC++6.0.This
includestheupcomingreleaseoftheWindows2003ServerSP1SDK.Please
makeyourviewsknowntoMicrosoftwhetheryouagreewiththisdecision.

Oneworkaroundistocopyonlythelibfilesyouarehavingproblemswith
(e.g.uuid.lib,shell32.lib,msxml2.lib,andpossiblyothers)fromtheFeb
2003version.Thisalsomeansthatiftheyaddanynewfunctionstothose
libsyouwillbemissingout.
分析原因呢?
M$SDK组说是BUG,编译器产生了叫连接器无法识别的符合。按照MSDN给出
的解决方法,关优化,EnableFunction-LevelLinking都不行
我觉得是m$把库给更新了
新的库中使用了新的符合定义,只有V7的连接才认。我FT.
标签:
diaryids+=','+206314267;
2005-04-05 21:34:39晴
vmvare&bochs
vmvare是有linux/win下两个版本,有点吃内存,不过还是很爽的,装了redhat9.
注意:要实现shareddoc,
首先要选好共享的文件夹
就需要在启动redhat后,安装工具。然后
su
/sbin/telinit3进入文字界面。
mount/dev/cdrom/mnt/cdrom
cpvmvare_tools.tar.gz/tmp
tarzxfvmvare_tools.tar.gz
./install.pl
然后再telinit5进入图形界面
/mnt/fsgh下的就是一个共享文件夹了
就不需要什么网络了,不过注意的是,要是安装网络的话,主要要把网卡
高级选项选为可为其它网络共享。

::URL::http://purec.binghua.com/Article/Class12/Class13/200402/10.html

bochsbochs.sourceforge.net
BochsisaprogramthatsimulatesacompleteIntelx86computer
BochsiswrittenintheC++programminglanguage,andisdesignedtorunonmanydifferent
hostplatforms,includingx86,PPC,Alpha,Sun,andMIPS
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics