zoukankan      html  css  js  c++  java
  • 内核 模块开发

    linux内核的整体结构非常庞大,组件合成分为2种:

    (1):把所有的组件都编译进内核文件,即zImage或bzImage。这种有两个缺点:

      a、生成的内核文件过大。

      b、如果想要添加或删除某个组件,需要重新编译整个内核。

    (2)内核模块机制:需要该组件时,动态地添加到正在运行的内核中。

    内核模块特点:

    (1)模块本身并不被编译进内核文件(ZImage/bzImage).

    (2)可以根据需求,在内核运行期间动态的安装或卸载。

    模块加载函数

    安装模块时被系统自动调用的函数,通过module_init宏来指定,如hello_init。

    模块卸载函数:

    卸载模块时被系统自动调用的函数,通过module_exit宏来指定,如hello_exit。

    模块编译:在linux2.6下编译内核模块,通常使用makefile

    单个源文件(hello.c)编译:

    ifneq ($(KERNELRELEASE),)                //如果KERNELRELEASE不等于空
    
    obj-m := hello.o
    
    else
    
    KDIR := /lib/modules/2.6.18-53.el5/build    //内核源代码路径
    all:
    
        make -C $(KDIR)  M=$(PWD)   modules    //modules:makefile的目标, 
      //-C:进入后面紧跟的目录中使用它的makefile来编译,后面紧跟的是一个目录。
      //M:build文件中要求的,表示内核代码所在。
    clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif

    多个源文件(main.c add.c)编译

    ifneq  (($KERNELRELEASE),)
    
    obj-m := hello.o            //内核模块的名字
    hello-objs := main.o  add.o   //hello-objs中hello与模块名字必须一样,如果多个文件,add文件名
    
    else 
    
    KDIR := /lib/modules/2.6.18-53.el5/build
    all:
    
        make  -C  $(KDIR)  M=$(PWD)  modules
    clean:
        rm -f  *.ko  *.o  *.mod.o  *.mod.c  *.symvers
    
    endif

    1.加载insmod  (insmod hello.ko)

    2.卸载rmmod   (rmmod hello)

    3.查看 lsmod

    4.加载modprobe (modprobe hello)

    modprobe如同insmod,也就是加载一个模块到内核。它的不同之处在于它会根据文件

    /lib/modules/<$version>/modules.dep

    来查看要加载的模块,看它是否还依赖于其他模块,如果是,modprobe会首先找到这些模块,把它们先加载到内核。

    1.许可证申明:

    MODULE_LICENSE用来告知内核,该模块遵守的许可证协议,如“GPL”、“GPL v2”。

    MODULE_LICENSE("遵守的协议")

    MODULE_LICENSE("GPL")

    2.作者申明

    MODULE_AUTHOR("作者")

    3.模块描述

    MODULE_DESCRIPTION("模块的功能描述")

    4.模块版本

    MODULE_VERSION("V1.0")

    5.模块别名

    MODULE_ALIAS("别名");

    6.模块参数:通过宏module_param指定保存模块参数的变量。模块参数用于在加载模块时传递参数给模块。

    module_param(name,type,perm)

    name:变量的名称

    type:变量类型,bool:布尔型  int:整形  charp:字符串型

    perm是访问权限。 S_IRUGO:读权限  S_IWUSR:写权限

    如:

    在hello.c中  int a = 9;
    module_param(a,int,S_IRUGO);
    
    
    命令行中输入:insmod  test.ko  a=100   //把100赋给a

    内核符号导出:

    EXPORT_SYMBOL(符号名)

    EXPORT_SYMBOL_GPL(符号名)    //只能用于包含GPL许可证的模块

    如两个模块A、B模块:需在A(定义变量或者函数)中利用EXPORT_SYMBOL(符号名)导出,在B模块中用extern 再声明下。

    uname -r   //查看内核版本

    内核打印:printk。允许根据严重程度,通过附加不同的“优先级”来对消息分类

    printk(KERN_WARNING  "hello world");
    printk("<0> hello world");

    在<linux/kernel.h>中定义了8种记录级别:

    KERN_EMERG     "<0>"     紧急消息

    KERN_ALERT      "<1>"    需要立即处理

    KERN_CRIT        "<2>"    严重情况

    KERN_ERR        "<3>"    错误情况

    KERN_WARNING  "<4>"   有问题的警告

    KERN_NOTICE    "<5>"    正常情况,但仍然需要注意

    KERN_INFO       "<6>"     信息型消息 

    KERN_DEBUG   "<7>"     用作调试消息

    注意:没有指定优先级printk默认使用DEFAULT_MESSAGE_LOGLEVEL优先级,定义在kernel/printk.c中

    如:

    #define DEFAULT_MESSAGE_LOGLEVEL 4

    屏幕上没有打印的消息全在:/var/log/message

    内核打印控制台优先级配置

    在/proc/sys/kernel/printk文件中,cat  /proc/sys/kernel/printk

    6 4 1 7   //console_loglevel    default_message_loglevel   minimum_console_level   default_console_loglevel

  • 相关阅读:
    WCF、Net remoting、Web service概念及区别
    新浪微博技术架构分析
    谈SOA和云的分层架构
    开发人员眼中最好的代码编辑器是什么?
    调试脚本,远离alert
    struts2与cookie实现自动登录和验证码验证
    把旧的项目改变名称重新部署到tomcat下发现项目名称还是原来的项目名称,解决方案
    myeclipse2014 安装maven3.3.9和mave配置本地仓库
    mysql在表的某一位置增加一列、删除一列、修改列名
    Java实现对cookie的增删改查
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/8280334.html
Copyright © 2011-2022 走看看