• [linux驱动]linux驱动模块


    一,内核模块的概念

    经常在内核驱动代码看到类似fs_init()等驱动初始化函数,那么这个和module_init()函数的差别在哪里,宏定义__define_initcall(level,fn)对于内核的初始化很重要,他指示编译器在编译的时候,将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化段,do_initcalls() 将按顺序从该section中以函数指针的形式取出这些函数的起始地址,来依次完成相应的初始化。于内核某些部分的初始化需要依赖于其他某些部分的初始化的完成,因此这个顺序排列常常很重要

    点击打开链接

    其中module_init()对应的是如下的device_initcall(fn)

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. 189 #define core_initcall(fn)               __define_initcall("1",fn,1)  
    2. 190 #define core_initcall_sync(fn)          __define_initcall("1s",fn,1s)  
    3. 191 #define postcore_initcall(fn)           __define_initcall("2",fn,2)  
    4. 192 #define postcore_initcall_sync(fn)      __define_initcall("2s",fn,2s)  
    5. 193 #define arch_initcall(fn)               __define_initcall("3",fn,3)  
    6. 194 #define arch_initcall_sync(fn)          __define_initcall("3s",fn,3s)  
    7. 195 #define subsys_initcall(fn)             __define_initcall("4",fn,4)  
    8. 196 #define subsys_initcall_sync(fn)        __define_initcall("4s",fn,4s)  
    9. 197 #define fs_initcall(fn)                 __define_initcall("5",fn,5)  
    10. 198 #define fs_initcall_sync(fn)            __define_initcall("5s",fn,5s)  
    11. 199 #define rootfs_initcall(fn)             __define_initcall("rootfs",fn,rootfs)  
    12. 200 #define device_initcall(fn)             __define_initcall("6",fn,6)  
    13. 201 #define device_initcall_sync(fn)        __define_initcall("6s",fn,6s)  
    14. 202 #define late_initcall(fn)               __define_initcall("7",fn,7)  
    15. 203 #define late_initcall_sync(fn)          __define_initcall("7s",fn,7s)  
    16.   
    17. 170 #define __define_initcall(level,fn,id)   
    18. 171         static initcall_t __initcall_##fn##id __used   
    19. 172         __attribute__((__section__(".initcall" level ".init"))) = fn  


     二,内核模块和应用程序之间的差别
    1,应用程序可以使用一些库函数,而内核模块只能使用内核其它模块导出的一些函数
    2,处理错误的方式不一样。
    3,应用程序是从头到尾执行单个任务,而模块是预先注册自己以便服务于将来某个请求。

    三,构建内核模块
    构建hello.ko模块 obj-m := hello.o
    构建module.ko模块,并由两个源文件生成(file1.c和file2.c)

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. obj-m := module.o  
    2. module-objs := file1.o file2.o  

     
    四,模块操作相关的命令
    insmod:装载一个模块
    modprobe:装载一个模块,同时检查模块是否引用了一些当前内核不存在的符合,如果有,modprobe会在当前模块搜索路径中查找定义了这些符合的其它模块并加载
    rmmod,卸载一个模块。

    五,模块之间的引用
    将一个模块的函数或者变量导出让其它模块可以使用

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. EXPORT_SYMBOL(name);  
    2. EXPORT_SYMBOL_GPL(name);  //导出的模块只能被GPL许可证下的模块使用  


    六,模块参数
    insmod hello howmany=10 whom="Mom"
    在hello.c的驱动程序中

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. static char*whom="world"  
      2. static int howmany=1;  
      3. module_param(howmany,int,S_IRUGO);  
      4. module_param(whom,charp,S_IRUGO)
  • 相关阅读:
    IOS调试问题集
    sql常用语句及日期格式
    事件的简单面试题
    首博
    T-SQL查询进阶--详解公用表表达式(CTE)
    c++分布式计算类库
    MSSQL on Linux
    使用supervisor实现.NET Core程序后台运行
    CentOS下安装Nginx并安装服务实现自启动
    macOS安装MongoDB
  • 原文地址:https://www.cnblogs.com/zhiliao112/p/4237209.html
Copyright © 2020-2023  润新知