一个简单字符驱动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.\n");
    return 0;
}

static int hello_write(struct file *file, const char __user * buf, size_t count, loff_t *ppos){
    printk(KERN_EMERG "hello write.\n");
    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.\n");
      return ret;
    }
    printk(KERN_EMERG DEVICE_NAME " initialized.\n");
    return 0;
}

static void __exit hello_exit(void){
    unregister_chrdev(HELLO_MAJOR, DEVICE_NAME);
    printk(KERN_EMERG DEVICE_NAME " removed.\n");
}

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!\n");
    }
    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

 

posted @ 2021-09-05 20:12  aspirs  阅读(83)  评论(0编辑  收藏  举报