一个简单字符驱动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