热门关键字:  ubuntu  分区  函数  Fedora  linux系统进程

当前位置 :| 主页>Linux教程>内核研究>

内核模块编程(hellomod)

来源: 作者: 时间:2008-03-28 Tag: 点击:
说明:
    这是我做的第一个内核模块的编程,其中的每一步我都认真检查过了,最终也按照其要求成功的加载和注销模块。

项目:Hellomode
    本节介绍了一些基本概念,这是理解稍后将讨论的其他Linux概念和数据结构必备的知识。该项目重点在于使用新的2.6驱动程序结构来创建一个可加载模块,并为后面的项目编译该模块。提到设备驱动程序,问题马上就变得复杂了,因此,我们只介绍Linux模块的基本结构,在后面的项目中再来介绍这个驱动程序。该模块在PPC上和x86上均可运行。
准备工作:
1....(环境) ubuntu 7.10
    (kernel) 2.6.22-14-generic        可在终端输入“ uname  -r ”查看,或            到/usr/src/目录下查看.下面的例子要用到.
    (gcc版本) 4.1.3                    可在终端输入“ gcc  -v ”查看
2....安装kernel必须的开发库 ( 重要! )
#sudo apt-get install linux-kernel-devel
安装内核头文件
#sudo apt-get install linux-headers-`uname -r`
重启.
另外, gcc,make等工具是必须的,请通过查看软件包管理器确保他们的存在.
第一步:构造Linux模块的框架
    我们写的第一个模块是基本的“hello world”字符设备驱动程序。首先,考虑该模块的基本代码,然后示范怎样使用新的2.6 Makefile系统(详情参见第九章),最后,分别使用insmod命令和rmmod命令加载或移除1该模块。
-----------------------------------------------------------------------
hellomod.c

001
// hello world driver for Linux 2.6

004  #include <linux/module.h>
005  #include <linux/kernel.h>
006  #include <linux/init.h>
007  #MODULE_LICENCE("GPL"); //get rid of taint message
//此处有错,应为  MODULE_LICENSE(“GPL”);
//前边不带#,且原文中的LICENCE应为LICENSE,否则编译无法通过.

009  static int __init lkp_init( void )          //注意,在int与__init(两下划线)之间要有空格                    //,也可直接去掉__init
{
  printk("<1>Hello,World! from the kernel space...\n");
  return 0;
013  }

015  static void __exit lkp_cleanup( void )  //注意,在void与__exit(两下划线)之间要有空格                    //,也可直接去掉__exit

{
  printk("<1>Goodbye, World! leaving kernel space...\n");
018  }

020  module_init(lkp_init);
021  module_exit(lkp_cleanup);
-----------------------------------------------------------------------
4行:
    所有模块都要使用头文件module.h,此文件必须包含进来。
5行:
    头文件kernel.h包含了常用的内核函数。
6行:
    头文件init.h包含了宏_init和_exit,它们允许释放内核占用的内存。建议浏览一下该文件中的代码和注释。
7行:
    提示可能没有GNU公共许可证。有几个宏是在2.4版的内核中才开发的(详情参见modules.h)。
9-12行:
    这是模块的初始化函数,它必需包含诸如要编译的代码、初始化数据结构等内容。11行用printk()从内核发送消息,并提示加载模块后从何处读取该消息。
15-18行:
    这是模块的退出和清理函数。此处可以做所有终止该驱动程序时相关的清理工作。
20行:
    这是驱动程序初始化的入口点。对于内置模块,内核在引导时调用该入口点;对于可加载模块则在该模块插入内核时才调用。
21行:
    对于可加载模块,内核在此处调用cleanup_module()函数,而对于内置的模块,它什么都不做。
    在该驱动程序中,仅有一个初始化(module_init)点和一个清理(cleanup_exit)点。加载或卸载模块时,内核会来寻找这些函数。
最新评论共有 4 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册