UBUNTU下第一次写简单驱动(笔记)

发布时间 2023-10-21 16:46:05作者: imxiangzi


一、环境

Ubuntu14.04 +vmware tools

二、步骤

先写个.c文件,驱动文件一般没有printf,有自己的一套,先写一个helloword.c

  1.  
    /*
  2.  
    * helloworld.c
  3.  
    *
  4.  
    * 宇文凌风
  5.  
    *
  6.  
    */
  7.  
     
  8.  
     
  9.  
    #include "linux/init.h"
  10.  
    #include "linux/module.h"
  11.  
     
  12.  
    static int helloworld_init(void)
  13.  
    {
  14.  
    printk(KERN_ALERT "Hello World linux_driver_module,entry helloworld.ko\n");
  15.  
    return 0;
  16.  
    }
  17.  
     
  18.  
    static void helloworld_exit(void)
  19.  
    {
  20.  
    printk(KERN_ALERT "exit the linux_driver_module helloworld.ko\n");
  21.  
    }
  22.  
     
  23.  
    module_init(helloworld_init);
  24.  
    module_exit(helloworld_exit);
  25.  
    MODULE_LICENSE("GPL");
  26.  
    MODULE_AUTHOR("ywlf");
  27.  
     
  28.  
     
  29.  
     
  30.  
    /*
  31.  
    //MODULE_LICENSE("GPL"); // "GPL" 是指明了 这是GNU General Public License的任意版本
  32.  
     
  33.  
    // “GPL v2” 是指明 这仅声明为GPL的第二版本
  34.  
     
  35.  
    // "GPL and addtional"
  36.  
     
  37.  
    // "Dual BSD/GPL"
  38.  
     
  39.  
    // "Dual MPL/GPL"
  40.  
     
  41.  
    // "Proprietary" 私有的
  42.  
     
  43.  
    // 除非你的模块显式地声明一个开源版本,否则内核会默认你这是一个私有的模块(Proprietary)。
  44.  
     
  45.  
    //MODULE_AUTHOR // 声明作者
  46.  
     
  47.  
    //MODULE_DESCRIPTION // 对这个模块作一个简单的描述,这个描述是"human-readable"的
  48.  
     
  49.  
    //MODULE_VERSION // 这个模块的版本
  50.  
     
  51.  
    //MODULE_ALIAS // 这个模块的别名
  52.  
     
  53.  
    //MODULE_DEVICE_TABLE // 告诉用户空间这个模块支持什么样的设备
  54.  
    */

紧接着Makefile写起来

  1.  
    KVERS = $(shell uname -r)
  2.  
    MODENAME = helloworld
  3.  
    obj-m += $(MODENAME).o #这个地方务必写成+=,不可写成: ,否则会出现cc -c -o helloworld.o #helloworld.c
  4.  
    #helloworld.c:9:24: fatal error: linux/init.h: 没有那个文件或目录
  5.  
    # include "linux/init.h"这样的错误
  6.  
     
  7.  
     
  8.  
    build:kernel_modules
  9.  
     
  10.  
    kernel_modules:
  11.  
    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
  12.  
    rm *.order && rm *.symvers && rm *.mod.c && rm *.mod.o && rm *.o
  13.  
    clean:
  14.  
    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
  15.  
    rm *.order && rm *.symvers && rm *.ko && rm *.mod.c && rm *.mod.o && rm *.o

也可以这样写:

  1.  
    KVERS = $(shell uname -r)
  2.  
    MODENAME = helloworld
  3.  
    obj-m += $(MODENAME).o
  4.  
    #build:kernel_modules
  5.  
     
  6.  
    #kernel_modules:
  7.  
    all:
  8.  
    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
  9.  
    rm *.order && rm *.symvers && rm *.mod.c && rm *.mod.o && rm *.o
  10.  
    clean:
  11.  
    make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
  12.  
    rm *.order && rm *.symvers && rm *.ko && rm *.mod.c && rm *.mod.o && rm *.o

 

三、运行

这里什么原理呢?

初步的想法就是:

make -C dir:在读取makefile 之前改变到指定的目录dir;

“M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件。

四、运行驱动

查看ko模块的信息 modinfo helloworld.ko

加载驱动

insmod helloworld.ko

sudo insmod helloworld.ko
如果先在另一终端中运行: sudo cat /proc/kmsg 就可以看到有 hello world 打印。

 

卸载驱动也是:sudo rmmod helloworld

对驱动的初步映像就是,依赖于内核的模块编译,最后依赖于内核加载,初步学习,借鉴了很多,切记不可直接拷贝,Makefile我直接从网上拷贝,大佬们写的没毛病,只不过编码不一致,编译了好久不过,最后重新自己敲了一遍,又借鉴了已有的另一个大佬的编好的东西才搞定

 
版权声明:本文为yuwenlingfeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yuwenlingfeng/article/details/111084422

 

https://www.freesion.com/article/83831518068/