• 一个简单字符驱动kernel module以及对应测试程序example


    一个简单字符驱动kernel module以及对应测试程序example

    module Makefile

    ifneq ($(KERNELRELEASE),)
    MODULE_NAME = slub_debug_test_module
    $(MODULE_NAME)-objs := slub_debug_test_drv.o
    obj-m := $(MODULE_NAME).o
    else
    KERNEL_DIR = $PATH_TO_KERNEL_ROOT
    MODULEDIR := $(shell pwd)
    
    .PHONY: modules
    default: modules
    
    modules:
            make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
    
    clean distclean:
            rm -f *.o *.mod.c .*.*.cmd *.ko
            rm -rf .tmp_versions
    endif

    在此ko的目录下,比如drivers/slub_debug_test,执行make命令即可。

    上述Makefile里的KERNELRELEASE在上述Makefile里会判断为空,所以走else,在else里会跳到kernel根目录下去make,执行kernel根目录下的Makefile,然后又会跳到上述makefile里执行,此时KERNELRELEASE不是空的了,所以会去编译slub_debug_test_drv.ko

    注意执行make时可能需要带入CC、CROSS_COMPILE、LD变量值进去,另外在执行make前还需要先export clang toolchain的路径(这里以使用clang作为toolchain为例):

    make CC=clang CROSS_COMPILE=aarch64-linux-gnu- LD=ld.lld -j72

    slub_debug_test_drv.c

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/init.h>
    #include <linux/delay.h>
    
    #define    HELLO_MAJOR     231
    #define    DEVICE_NAME     "HelloModule"
    
    static int hello_open(struct inode *inode, struct file *file){
        printk(KERN_EMERG "hello open.
    ");
        return 0;
    }
    
    static int hello_write(struct file *file, const char __user * buf, size_t count, loff_t *ppos){
        printk(KERN_EMERG "hello write.
    ");
        return 0;
    }
    
    static struct file_operations hello_flops = {
        .owner  =   THIS_MODULE,
        .open   =   hello_open,     
        .write  =   hello_write,
    };
    
    static int __init hello_init(void){
        int ret;
        
        ret = register_chrdev(HELLO_MAJOR,DEVICE_NAME, &hello_flops);
        if (ret < 0) {
          printk(KERN_EMERG DEVICE_NAME " can't register major number.
    ");
          return ret;
        }
        printk(KERN_EMERG DEVICE_NAME " initialized.
    ");
        return 0;
    }
    
    static void __exit hello_exit(void){
        unregister_chrdev(HELLO_MAJOR, DEVICE_NAME);
        printk(KERN_EMERG DEVICE_NAME " removed.
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    MODULE_LICENSE("GPL");

    android C native测试程序

    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    int main(void)
    {
        int fd;
        int val = 1;
        fd = open("/dev/HelloModule", O_RDWR);
        if(fd < 0){
            printf("can't open!
    ");
        }
        write(fd, &val, 4);
        return 0;
    }

    编译完上述ko以及测试程序后,先insmod ko,insmod后可以cat /proc/modules,在这个文件里将会有HelloModule,主设备号是231;

    然后执行“mknod /dev/HelloModule c 231 0”以创建/dev/HelloModule结点;

    然后执行测试程序即可。

    参考:

    https://www.cnblogs.com/amanlikethis/p/4914510.html

  • 相关阅读:
    php开启伪静态(2转)
    php,apache伪静态(1转)
    sql 字段先计算后再拿比对的字段进行比对 效率提升100倍
    使用 PHP 读取文本(TXT)文件 并分页显示
    php给一张图片加上水印效果
    PHP命名空间(Namespace)的使用详解(转)
    php随机获取金山词霸每日一句
    网络报文分析利器eBPF
    这个世界变得有多复杂
    个人收藏网站推荐(一)
  • 原文地址:https://www.cnblogs.com/aspirs/p/15230677.html
Copyright © 2020-2023  润新知