内核模块编程初探

新浪微博 QQ空间

照着这里的简单教程(http://www.kerneltravel.net/?page_id=8)编写了第一个内核模块,对中断和内核模块注册形成了简单的认识。

Makefile文件:

# Makefile2.6
obj-m += first.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/kernels/$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

模块代码:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>

static int irq;
static char *interface;

module_param(irq, int, 0644);
module_param(interface, charp, 0644);

static irqreturn_t specialirq(int irq, void *dev_id/*, struct pt_regs *regs*/)
{
static int mycount = 0;
printk("irq: %d occured on device: %d!\n", irq, *(int*)dev_id);
mycount++;
return IRQ_NONE;
}

static int __init specialirq_init(void)
{
printk ("begin to init my firt module!\n");
if (request_irq(irq, &specialirq, IRQF_SHARED,interface, &irq))
{
printk(KERN_ERR "specialirq: cannot register IRQ %d.\n", irq);
return -EIO;
}
printk("registe callback on %s of IRQ %d successfully!\n", interface, irq);
printk("end to init my first module!\n");
return 0;
}

static void __exit specialirq_exit(void)
{
printk("begin to unloading my first module.\n");
free_irq(irq, &irq);
printk("end to unloading my firt module.\n");
return;
}

module_init(specialirq_init);
module_exit(specialirq_exit);
MODULE_LICENSE("GPL");

每个内核模块都有一个init方法和exit方法。

在init方法中,根据输入参数注册一个设备中断的回调函数:

如,注册中断响应模块之前的系统中断信息如下:

cat /proc/interrupts 
CPU0 CPU1
0: 271 0 IO-APIC-edge timer
1: 453 1 IO-APIC-edge i8042
3: 0 1 IO-APIC-edge
4: 0 1 IO-APIC-edge
6: 2 3 IO-APIC-edge floppy
7: 0 0 IO-APIC-edge parport0
8: 1 0 IO-APIC-edge rtc0
9: 0 0 IO-APIC-fasteoi acpi
12: 10534 2 IO-APIC-edge i8042
14: 0 0 IO-APIC-edge ata_piix
15: 12006 1 IO-APIC-edge ata_piix
16: 1505 0 IO-APIC-fasteoi vmci, Ensoniq AudioPCI
17: 27704 1008 IO-APIC-fasteoi ehci_hcd:usb1, BusLogic BT-958
18: 0 0 IO-APIC-fasteoi uhci_hcd:usb2
19: 42037 42 IO-APIC-fasteoi vmxnet ether
NMI: 0 0 Non-maskable interrupts
LOC: 394468 383646 Local timer interrupts
RES: 32430 46661 Rescheduling interrupts
CAL: 247 186 function call interrupts
TLB: 3181 3149 TLB shootdowns
TRM: 0 0 Thermal event interrupts
SPU: 0 0 Spurious interrupts
ERR: 0
MIS: 0
 
执行:insmod first.ko interface=eth0 irq=19

表示注册eth0设备的19号中断的响应程序。当eth0发出19号中断时,specialirq方法会被回调。
注册后系统的中断信息如下:
cat /proc/interrupts 
CPU0 CPU1
0: 271 0 IO-APIC-edge timer
1: 453 1 IO-APIC-edge i8042
3: 0 1 IO-APIC-edge
4: 0 1 IO-APIC-edge
6: 2 3 IO-APIC-edge floppy
7: 0 0 IO-APIC-edge parport0
8: 1 0 IO-APIC-edge rtc0
9: 0 0 IO-APIC-fasteoi acpi
12: 10534 2 IO-APIC-edge i8042
14: 0 0 IO-APIC-edge ata_piix
15: 12174 1 IO-APIC-edge ata_piix
16: 1505 0 IO-APIC-fasteoi vmci, Ensoniq AudioPCI
17: 27745 1008 IO-APIC-fasteoi ehci_hcd:usb1, BusLogic BT-958
18: 0 0 IO-APIC-fasteoi uhci_hcd:usb2
19: 42632 42 IO-APIC-fasteoi vmxnet ether, eth0
NMI: 0 0 Non-maskable interrupts
LOC: 397939 386623 Local timer interrupts
RES: 32784 47155 Rescheduling interrupts
CAL: 247 188 function call interrupts
TLB: 3201 3180 TLB shootdowns
TRM: 0 0 Thermal event interrupts
SPU: 0 0 Spurious interrupts
ERR: 0
MIS: 0
在19号中断的响应模块中多了一个eth0设备。
执行dmesg命令,可以发现:
irq: 19 occured on device: 19!
不断打印。

新浪微博 QQ空间

| 1 分2 分3 分4 分5 分 (5.00- 7票) Loading ... Loading ... | 这篇文章归档在:Linux内核. | 永久链接:链接 | 评论(0) |

评论

邮箱地址不会被泄露, 标记为 * 的项目必填。

8 - 2 = *



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <img alt="" src="" class=""> <pre class=""> <q cite=""> <s> <strike> <strong>

返回顶部