如何编写Linux设备驱动程序( 四 )


言归正传,要注意kmalloc最大只能开辟128k-16,16个字节是被页描述符结构占用了 。kmalloc用法参见khg.
内存映射的I/O口,寄存器或者是硬件设备的RAM(如显存)一般占用F0000000以上的地址空间 。在驱动程序中不能直接访问,要通过kernel函数vremap获得重新映射以后的地址 。
另外,很多硬件需要一块比较大的连续内存用作DMA传送 。这块内存需要一直驻留在内存,不能被交换到文件中去 。但是kmalloc最多只能开辟128k的内存 。
这可以通过牺牲一些系统内存的方法来解决 。
具体做法是:比如说你的机器由32M的内存,在lilo.conf的启动参数中加上mem=30M,这样linux就认为你的机器只有30M的内存,剩下的2M内存在vremap之后就可以为DMA所用了 。
请记住,用vremap映射后的内存,不用时应用unremap释放,否则会浪费页表 。
3.中断处理
同处理I/O端口一样,要使用一个中断,必须先向系统登记 。
int request_irq(unsigned int irq,
void(*handle)(int,void *,struct pt_regs *),
unsigned int long flags,
const char *device);
irq: 是要申请的中断 。
handle:中断处理函数指针 。
flags:SA_INTERRUPT 请求一个快速中断,0 正常中断 。
device:设备名 。

如果登记成功,返回0,这时在/proc/interrupts文件中可以看你请求的中断 。
4.一些常见的问题 。
【如何编写Linux设备驱动程序】对硬件操作,有时时序很重要 。但是如果用C语言写一些低级的硬件操作的话,gcc往往会对你的程序进行优化,这样时序就错掉了 。如果用汇编写呢,gcc同样会对汇编代码进行优化,除非你用volatile关键字修饰 。最保险的办法是禁止优化 。这当然只能对一部分你自己编写的代码 。如果对所有的代码都不优化,你会发现驱动程序根本无法装载 。这是因为在编译驱动程序时要用到gcc的一些扩展特性,而这些扩展特性必须在加了优化选项之后才能体现出来 。

推荐阅读