linux驱动入门(转)
时间:2011-02-22 来源:Mingxx
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Marion");
MODULE_DESCRIPTION("An example of device driver!");
MODULE_LICENSE("GPL");
/* End the hello*/
(2)在内核配置文件中添加一个菜单项,以允许在编译内核时可以选择编译examples(编译进内核或编译成模块);
(3)在.../driver/char/Makefile文件中添加一个子目录项examples以对应于前述第二步骤的菜单项;
(4)为.../driver/char/examples目录创建一个makefile文件,在其中为前述第二个步骤中创建的菜单项添加hello.o模块对象以进行编译; (5)添加驱动程序源码; 下面详细描述前面的几个步骤: 首先,在内核源码目录的.../driver/char目录中创建examples子目录,而后再创建两个文件:一个是前面例子中的驱动源码,一个是为其创建的makefile文件。makefile文件非常简单,其内容只有如下一行即可:
obj-$(CONFIG_EXAMPLES) += hello.o 添加菜单项至内核配置工具的过程可能稍有些绕。首先需要在.../driver/char/Kconfig文件中添加一个"config"项以启用前文中的examples配置项。添加位置是menu "Character devices"一行的后面,添加内容如下: config EXAMPLES
tristate "Enable Examples"
default m
---help---
Enable compilation option for driver examples 而后回到内核目录中,运行内核编译命令make gconfig(需要xwindow的支持)后,可以Device Drivers->Character drivers找到我们添加的“Enable Examples”项,默认为“-”(通过default项指定),即编译为内核模块。如果指定为“对号”则表示以静态方式编译进内核;如果为空,则表示 不编译此项。如下图所示: 接下来还需要在.../drivers/char/Makefile文件中添加一个选项,以指示内核编译程序在我们选择了 CONFIG_EXAMPLES时会到examples子目录中编译hello1模块。这需要在 “obj-$(CONFIG_IPMI_HANDLER) += ipmi/”一行附近添加如下行: obj-$(CONFIG_EXAMPLES) += examples/ 至此,此示例驱动构建基础结构已经完成,而且会在内核编译过程中自动选择此项进行编译了。在执行完前面的"make gconfig"命令后,此时再执行如下命令即可完成驱动模块的编译。 # make modules
CHK include/linux/version.h
CHK include/linux/utsrelease.h
CC [M] drivers/char/examples/hello.o
Building modules, stage 2.
MODPOST
CC drivers/char/examples/hello.mod.o
LD [M] drivers/char/examples/hello.ko 如果您的编译过程显示有如上信息,则表示内核模块编译完成。接下来就可以使用如下命令安装刚刚编译完成的内核模块:
# make modules_install 使用此种方式安装时,安装过程会重新安装所有已编译的内核模块,包括此前编译的其它模块,而这并非是必须的。 在一个通过标准方式安装的Linux系统上,内核模块通常位于/lib/modules/<kernel-version>/…之 中,其中的<kernel-version>即当前系统运行中的内核版本号,并且此目录的结构组织方式跟内核源代码树的结构是类似的。通常使 用“make modules_install”命令安装的模块就位于此目录中。因此,在单独安装某个或某些内核模块时,可以通过在此目录中创建跟编译时内核源码树中一 样的内核模块驱动相关的目录,并把编译完成的*.ko文件复制到新建的对应目录中来实现。 5、加载/卸载内核模块 安装完成后,便可以手动加载或卸载这些模块了,这可以使用modprobe实现。我们首先去加载hello模块。 # modprobe hello
# tail -1 /var/log/messages
Sep 14 22:06:23 localhost kernel: Hello Device Driver World! 此模块在加载时会调用模块初始化函数,程序中使用module_init()宏(macro)来指定的模块初始化函数,如 module_init(hello_init)。在此模块中,初始化函数仅用来打印一行信息至系统日志,信息内容是在hello_init()中定义好 的。在实际驱动程序编写中,初始化函数常用来执行资源分配及硬件设备初始化。 接下来可以使用lsmod命令以格式化列表的形式显示系统中加载的所有模块。如果其中有hello模块出现则表示前面的加载是成功的。例如: # lsmod
Module Size Used by
hello 5632 0
ipv6 274208 18
autofs4 25092 2
i2c_core 25344 1 i2c_piix4
………… 其中Used by一列表示当前模块正在被使用的信息,以及依赖于当前模块的其它模块。如最后一行表示i2c_piix4模块依赖于i2c_core模块。 内核模块的卸载可以通过使用modprobe的-r选项来实现。 # modprobe -r hello
# tail -1 /var/log/messages
Sep 14 22:14:33 localhost kernel: Goodbye, Cruel World! hello模块退出时会调用exit例行函数,这使用module_exit()宏来实现。其工作方式类似前面的加载过程。
相关阅读 更多 +