日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

tiny4412--linux驱动学习(2)

發(fā)布時間:2023/12/10 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tiny4412--linux驱动学习(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在ubuntu下編寫驗證字符設備驅動

并移植到arm開發(fā)板上

1,準備工作

  •   uname -r? 查看電腦版本信息
  • ? ? ? ?apt-get? install? linux-source? 安裝相應版本的linux內核
  • ?

    2,編寫驅動程序

        Global CharDev.c

    /* 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; }/* 模塊卸載函數(shù) */ static void __exit GlobalChar_exit(void) {unregister_chrdev(char_major, DEV_NAME); /* 注銷設備驅動 */return; }/* 模塊驅動讀函數(shù) */ 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); }
    /* 模塊驅動寫函數(shù) */ 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");

    ?

      Makefile

    ifneq ($(KERNELRELEASE),) obj-m := GlobalCharDev.o else# KERNELDIR ?= /lib/modules/$(shell uname -r)/buildKERNELDIR ?= /usr/src/linux-headers-$(shell uname -r) //這兩個都可以PWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf rm -rf *.ko *.mod* *.o* *.sy* endif

    ?  理解:

          pwd-->? 驅動文件目錄

          kerneldir -->? 內核源碼目錄

          default -->? 表示到內核源碼目錄中去編譯pwd下的驅動文件

    ——————————————————————————————————————————————————————

    ? ? ? ? ? make 編譯

    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.oBuilding modules, stage 2.MODPOST 1 modulesLD [M] /home/arm/data/char_driver/GlobalCharDev.ko make[1]:正在離開目錄 `/usr/src/linux-headers-4.4.0-31-generic'

    ?

    出現(xiàn)Global CharDev.ko文件

    2,insmod Global CharDev.ko? 將模塊加入內核

    3,cat? /proc/devices? 查看驅動設備

    ?

    ?

    4,mknod? /dev/GlobalChar? ?c? 247? 0? ? ? 根據(jù)相應的設備號,建立設備節(jié)點。

    5,測試文件

    /* 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;}/* 讀取當前設備數(shù)值 */read(fd, &num, sizeof(int));printf("The GlobalChar is %d\n", num);printf("Please input a numble written to GlobalChar: ");scanf("%d", &num);/* 寫入新的數(shù)值 */write(fd, &num, sizeof(int));/* 重新讀取數(shù)值 */read(fd, &num, sizeof(int));printf("The GlobalChar is %d\n", num);close(fd);return 0;}

    ?

    ?  gcc -o? GlobalCharText? GlobalCharText.c? ? ? 編譯出可執(zhí)行文件

       執(zhí)行:

    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

    ?

    ——————————————————————————————————————————————————————————————————————

    通過NFS我們可以建立共享目錄,將編寫好的驅動加載到arm板,當然也需要配置環(huán)境變量。

    1,驅動文件:需要將Make file中KERNLDIR 改成 自己下載內核的地址,如:

        KERNELDIR ?= /home/arm/linux-4.4

    ?

    ?

    ?

    2,測試文件:理所當然我們需要使用交叉編譯去編譯出可執(zhí)行文件。

    注意:首先我們要知道自己制作的做小系統(tǒng)是采用靜態(tài)編譯還是動態(tài)編譯,我的采用靜態(tài)編譯

      1,靜態(tài):

      2,動態(tài):

    需要在制作最小系統(tǒng)時,在? /lib? 下加入所需的動態(tài)交叉編譯庫(所選交叉編譯工具目錄下的鏈接庫),但是我在制作randisk的過程中,提示內存不足,暫沒查找其原因。

    ?

    如果在靜態(tài)根文件系統(tǒng)內使用動態(tài)編譯鏈所編譯的elf,會提示:-sh:./test:no found? (這里 not found 指的是 鏈接庫)

    ?

    測試:

    ?

    卸載:

    1,刪除? /dev? 下的設備節(jié)點

      rm /dev/GlobalChar

    2,卸載驅動

      rmmod? GlopbalCharDev.ko 

    出現(xiàn)問題:

    ?

    ?

    ——————————————————————————————————————————————————————

    參考:

    http://tieba.baidu.com/p/3645403366

    https://blog.csdn.net/Ultraman_hs/article/details/53239455

    解決移植到arm上不兼容的問題

    ?

    https://blog.csdn.net/zqj6893/article/details/48439711

    解決驅動卸載問題

    轉載于:https://www.cnblogs.com/chu-yi/p/10671865.html

    總結

    以上是生活随笔為你收集整理的tiny4412--linux驱动学习(2)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。