1.用make编译,编译代码如下
obj-m := filename.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
2.运行代码
insmod filename.ko
用insmod命令,将模块插入到内核中(root权限下)
dmesg命令查看信息
最后用命令rmmod filename从内核中移除该模块
3.链表的一些宏和函数
链表的定义
struct list_head {
struct list_head *next, prec;
}
若要定义data域须自己在代码中声明
eg:
struct my_list{
void *mydata;
struct list_head list;
}
#define LIST_HEAD_INIT(name) { &(name), &(name) } //初始化
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) //声明并初始化
static inline void list_add(); //向head后插入结点
static inline void list_add(struct list_head *new, struct list_head *head)
{
_list_add(new, head, head->next);
}
static inline void list_add_tail(); //向head前插入节点
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
_list_add(new, head->prev, head);
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = prev;
}
#define list_for_each(pos, head) for (pos = (head)->next; pos != head; pos=pos->next) //遍历链表(缺点是只能找到结点的指针域,却找不到data域)
#define list_for_each_safe(pos, n, head) for (pos = head->next, n=pos->next; pos!=head; pos=n,n=pos->next) //遍历链表(他采用年来暂时储存将要被删除的pos,从而使删除操作不影pos)
#define list_entry(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0) ->member))) //获得存有data域的结点的起始位置
用指针域的起始地址减去data域的偏移量得到整体的起始位置
static inline void __list_del(struct list_head *prev, struct list_head *next) //删除结点的代码
{
next->prev = prev;
prev->next = next;
}
static inline void liss_del (struct list_head *entry) //删除结点的函数
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POLSON1;
entry->prev = LIST_POISON2;
}