linux源代码目录结构、linux内核模块

基本概念:在内核中添加程序需要完成下面3个步骤;

  1. 将编写的源代码copy到相应的目录;
  2. 在kconfig中添加新添加源代码的编译配置选项;(让用户选择是否编译)
  3. 在makefile中添加新添源代码的编译条目;(往往涉及到当前目录,子目录,父目录多个makefile文件)
linux 源代码目录结构及其实现的功能:
linux源代码目录结构、linux内核模块_第1张图片



linux设备驱动是以内核模块的形式出现的,下面将了解内核模块的概念和结构,然后对各个组成部分详解;
内核模块简介:编译内核时并不包括各种内核模块的功能,当需要某种功能时,以内核模块的形式动态的加载
  1. 内核编译不包括内核模块,保证了内核的大小;
  2. 一旦加载某个内核模块,它就和内核中的其他部分完全一样;
linux内核模块的程序结构:
  • 模块加载函数:_init标识声明
  • 模块卸载函数:_exit标识声明
linux源代码目录结构、linux内核模块_第2张图片

  • 模块参数:

可以使用module_param(参数名,参数类型,参数读/写权限) 为模块定义一个参数
例如:module_param(num, int, S_IRUGO);
模块也可以拥有参数数组,形式为“module_param_array(数组名,数组类型,数组长,参数读/写权限)”
使用insmod或者modprobe命令,可以给这些参数赋值
例如输入:insmod book.ko book_name='GoodBook' num=5000
(表示加载book.ko 模块,其中给字符串赋值“GoodBook”,给num赋值5000)

  • 导出符号:导出的符号可以被其他模块使用,使用前声明一下即可;感觉有点像函数的输出
  • 模块声明和描述:我们可以用 MODULE_AUTHOR、 MODULE_DESCRIPTION、MODULE_ VERSION、MODULE_DEVICE_TABLE、MODULE_ALIAS 分别声明模块的
    作者、描述、版本、设备表和别名。
MODULE_AUTHOR(author);
MODULE_DESCRIPTION(description);
MODULE_VERSION(version_string);
MODULE_DEVICE_TABLE(table_info);
MODULE_ALIAS(alternate_name);

  • 模块的使用计数:当开始使用某个设备时,内核使用try_module_get()增加管理此设备的owner的计数, 当不再使用此设备时,内核通过module_put()减少管理此设备的模块owner的计数。这样当该模块在使用中的时候,管理此设备的模块不能被卸载,只用未使用该设备时才能被卸载。
模块的编译和添加到内核中
1、为模块编写Makefile文件,例如:  obj-m :=hello.o
2、命令行编译命令,例如: make -C /usr/src/linux-2.6.15.5/  M=/driver_study/ modules
                                    或者: make -C /usr/src/linux-2.6.15.5  M=$(pwd) modules(与上面的等价,如果当前目录就是要编译的目录)

   这里-C后面跟的是linux内核源代码的目录,M=后面跟的是hello.c和Makefile所在的目录
3、编译过程经历的步骤:
  1. 生成hello.o文件
  2. 运行modpost,生成hello.mod.c文件
  3. 编译生成hello.mod.o文件
  4. 连接hello.o和hello.mod.o文件,生成hello.ko文件
  5. 最后离开linux内核所在的目录









你可能感兴趣的:(驱动开发,linux内核)