/* GlobalCharDev.c */ #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <asm/uaccess.h> #define DEV_NAME "GlobalChar" static ssize_t GlobalRead(struct file *, char *, size_t, loff_t *); static ssize_t GlobalWrite(struct file *, const char *, size_t,loff_t *); static int char_major = 0; static int GlobalData = 0; /* "GlobalChar"設備的全局變量 */ /* 初始化字符設備驅動的 file_operations 結構體 */ struct file_operations globalchar_fops = { .read = GlobalRead, .write = GlobalWrite }; /* 模塊初始化 */ static int __init GlobalChar_init(void) { int ret; ret = register_chrdev(char_major, DEV_NAME, &globalchar_fops);/* 註冊設備驅動,_driver_char_misc.c 第290行參考 */ if(ret < 0 ) printk(KERN_ALERT "GlobalChar Reg Fail\n"); else { printk(KERN_ALERT "GlobalChar Reg Success\n"); char_major = ret; printk(KERN_ALERT "Major = %d\n", char_major); } return ret; } /* 模塊卸載函數 */ static void __exit GlobalChar_exit(void) { unregister_chrdev(char_major, DEV_NAME); /* 註銷設備驅動 */ return; } /* 模塊驅動讀函數 */ static ssize_t GlobalRead(struct file *file, char *buf, size_t len, loff_t *off) { if (copy_to_user(buf, &GlobalData ,sizeof(int))) { /* 從內核複製 GlobalData 到用戶空間*/ return -EFAULT; } return sizeof(int); }
/* 模塊驅動寫函數 */ static ssize_t GlobalWrite(struct file *file, const char *buf, size_t len, loff_t *off) { if (copy_from_user(&GlobalData, buf, sizeof(int))) { /* 從用戶複製 GlobalData 到內核 */ return -EFAULT; } return sizeof(int); } module_init(GlobalChar_init); module_exit(GlobalChar_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("dongjin");
ifneq ($(KERNELRELEASE),) obj-m := GlobalCharDev.o else # KERNELDIR ?= /lib/modules/$(shell uname -r)/build KERNELDIR ?= /usr/src/linux-headers-$(shell uname -r) //這兩個均可以 PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -rf rm -rf *.ko *.mod* *.o* *.sy* endif
理解:linux
pwd--> 驅動文件目錄shell
kerneldir --> 內核源碼目錄ubuntu
default --> 表示到內核源碼目錄中去編譯pwd下的驅動文件函數
——————————————————————————————————————————————————————工具
root@ubuntu:/home/arm/data/char_driver# make make -C /usr/src/linux-headers-4.4.0-31-generic M=/home/arm/data/char_driver modules make[1]: 正在進入目錄 `/usr/src/linux-headers-4.4.0-31-generic' CC [M] /home/arm/data/char_driver/GlobalCharDev.o Building modules, stage 2. MODPOST 1 modules LD [M] /home/arm/data/char_driver/GlobalCharDev.ko make[1]:正在離開目錄 `/usr/src/linux-headers-4.4.0-31-generic'
/* GlobaiCharText.c 測試文件*/ #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #define DEV_NAME "/dev/GlobalChar" int main() { int fd, num; /* 打開設備文件 */ fd = open(DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR); if(fd < 0) { printf("Open Device Fail!\n"); return -1; } /* 讀取當前設備數值 */ read(fd, &num, sizeof(int)); printf("The GlobalChar is %d\n", num); printf("Please input a numble written to GlobalChar: "); scanf("%d", &num); /* 寫入新的數值 */ write(fd, &num, sizeof(int)); /* 從新讀取數值 */ read(fd, &num, sizeof(int)); printf("The GlobalChar is %d\n", num); close(fd); return 0; }
root@ubuntu:/home/arm/data/char_driver# ./a.out The GlobalChar is 0 Please input a numble written to GlobalChar: 111 The GlobalChar is 111
——————————————————————————————————————————————————————————————————————測試
須要在製做最小系統時,在 /lib 下加入所需的動態交叉編譯庫(所選交叉編譯工具目錄下的連接庫),可是我在製做randisk的過程當中,提示內存不足,暫沒查找其緣由。ui
若是在靜態根文件系統內使用動態編譯鏈所編譯的elf,會提示:-sh:./test:no found (這裏 not found 指的是 連接庫)spa
卸載:.net
1,刪除 /dev 下的設備節點3d
rm /dev/GlobalChar
2,卸載驅動
rmmod GlopbalCharDev.ko
出現問題:
——————————————————————————————————————————————————————
http://tieba.baidu.com/p/3645403366
https://blog.csdn.net/Ultraman_hs/article/details/53239455
解決移植到arm上不兼容的問題
https://blog.csdn.net/zqj6893/article/details/48439711
解決驅動卸載問題