linux内核链表操作demo(4)

下面将提供一个常见的内核驱动模块,对链表进行操作:

1.链表创建

2.链表插入节点

3.链表遍历

4.链表的销毁

5.下一节使用Linux内核链表结合netlink通信,实现连个本地程序的通信

下面的demo,假定C文件名为  link.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>  // for kmalloc
#include <linux/list.h>  // for kernel link
#include <linux/kernel.h>

#include <linux/netlink.h> //for netlink communication not used here

typedef struct car{
    int     door_number;
    char    *color;
    char    *model;
    struct list_head list;
} CAR ;


//声明并初始化链表头节点
LIST_HEAD(carlist);

//模块入口函数,必须有返回值,否则编译报警告或错误
static int test_netlink_init(void){
    //用于迭代的游标,作用类似于for循环中的 i
    struct car *acar; 
    
    //声明节点并申请内存,GFP_KERNEL是内存类型
    struct car *redcar   = kmalloc(sizeof(CAR), GFP_KERNEL);
    struct car *blackcar = kmalloc(sizeof(CAR), GFP_KERNEL);
    
    //初始化链表的list
    INIT_LIST_HEAD(&redcar->list);
    INIT_LIST_HEAD(&blackcar->list);   
    
    //填充节点的内容
    blackcar->door_number = 4;
    blackcar->color       = "black";
    blackcar->model       = "Y";

    redcar->door_number   = 2;
    redcar->color         = "red";
    redcar->model         = "E";

    //添加链表节点到内核链表中
    list_add(&redcar->list,   &carlist);
    list_add(&blackcar->list, &carlist);
    
    //链表遍历
    list_for_each_entry(acar, &carlist, list){
        printk("车门数[%d]\n",   acar->door_number);
        printk("车的颜色[%s]\n", acar->color      );
        printk("车的模具[%s]\n", acar->model      );

        if(!memcmp(acar->color, "black", sizeof("black"))){
            printk("存在黑色车\n");
        }

    }

    //入口函数需有返回值
    return 0;
}

static void test_netlink_exit(void){
    struct car *acar = NULL;
    printk("内核模块退出清理\n");
    list_for_each_entry(acar, &carlist, list){
        list_del(&acar->list);
        //使用kfree释放内存
        kfree(acar);
    }
    return;
}


module_init(test_netlink_init);
module_exit(test_netlink_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("everyone");
MODULE_DESCRIPTION("内核链表demo");
#
#    @makefile script
#    @version  0.01
#    author    none
#

LINUX_PATH=/lib/modules/$(shell  uname  -r)/build

CURRENT_PATH=$(shell pwd)

#这里注意需要与C文件的文件名保持一致
obj-m += link.o

all:
    make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules
clean:
    make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean

执行编译命令,生成对应的ko文件

sudo  make 

执行Linux下的模块插入命令

sudo insmod link.ko

使用命令    dmesg 或者查看内核log文件 就可以看到内核遍历产生的输出

tail /var/log/kern.log

使用命令   lsmod  | grep  link  可以看到我们手动注入的模块

使用命令 rmmod 可以移除模块

sudo  rmmod link

再次使用 dmesg 命令或者查看内核log,可以看到我们打印的日志信息。

happy 摁钉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值