《Linux内核模块编程指南》(一)

主题:《Linux内核模块编程指南》(一)
发信人: kevintz()
整理人: softlag(2000-06-22 00:52:41), 站内信件
<<Linux 内核模块编程指南>>
<<Linux Kernel Module Programming Guide>>
作者:Ori Pomerantz 中译者:kevintz(lkmpg@21cn.com)
  
译者注:
1、LKMPG是一本免费的书,英文版的发行和修改遵从GPL version 2的许可。为了
节省时间,我只翻译了其中的大部分的大意,或者说这只是我学习中的一些中文
笔记吧,不能算是严格上的翻译,但我认为这已经足够了。本文也允许免费发布
,但发布前请和我联系,但不要把本文用于商业目的。鉴于本人的水平,文章中
难免有错误,请大家不吝指正。
2、本文中的例子在Linux(kernel version 2.2.10)上调试通过。你用的Linux必
须支持内核模块的加载,如果不支持,请在编译内核时选上内核模块的支持或升
级你的内核到一个支持内核模块的版本。


                       第一章 Hello,world

1、第一个内核模块程序

    相信很多学C的人从书上学的第一个程序是Hello,world。这几乎已经是一个
传统。所以我们的内核模块编程也从Hello,world开始。

    一个内核模块必须至少有两个函数:当模块被插入内核时调用的init_modul
e函数和模块从内核中清除时调用的cleanup_module。通常,init_module既可以
在内核中注册(register)处理某些情况的函数,也可以用它自己的代码代替某个
内核函数(通常是先做一些自己的处理,在调用原来的函数)。cleanup_module函
数应该做init_module函数相反的工作,以便模块能够被安全地卸载。

译者注:我会保留英文版的注悉,只在关键的地方用中文做注悉
例子:hello.c    

/* hello.c 
 * Copyright (C) 1998 by Ori Pomerantz
 * 
 * "Hello, world" - the kernel module version. 
 */

/* The necessary header files */

/* Standard in kernel modules */
#include <linux/kernel.h>   /* We're doing kernel work */
#include <linux/module.h>   /* Specifically, a module */


/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif        



/* Initialize the module */
int init_module()
{
  printk("Hello, world - this is the kernel speaking/n");

  /* If we return a non zero value, it means that init_module
 failed and the kernel module can't be loaded */
  return 0;
}


/* Cleanup - undid whatever init_module did */
void cleanup_module()
{
  printk("Short is the life of a kernel module/n");
}
/* end of hello.c*/


2、编译hello.c的Makefile文件

    一个内核模块不是一个独立的可执行文件,只是一个在运行时连接入内核的
目标文件。所以他们应该用-c选项编译成目标文件。另外,所有的内核模块都必
须用某些宏定义来编译。

__KERNEL__ 
这个宏定义告诉头文件这些代码是用于运行内核模块,不是作为用户进程的一部
分。

MODULE 
这个宏定义告诉头文件给出适当的内核模块的定义。

LINUX   
技术上讲,这个宏定义并不是必需的。然而,如果你想写一个在多个操作系统上
编译的内核模块,你应该为你定义了该宏而高兴。它允许你有条件地编译操作系
统相关的部分。还有其他一些必需或不需要的宏定义,这视乎你的内核编译选项
的需要。如果你不肯定你的内核是如何编译的,你可以看一下/usr/include/lin
ux/config.h文件。

__SMP__   
对称多处理器的支持。当你的内核是用支持对称多处理器选项编译的时候,必须
使用该宏定义来编译你的内核模块。如果你使用对称多处理器,你还一些其他的
事情要做,这在以后会说到。

CONFIG_MODVERSIONS
如果你的内核编译选项允许了CONFIG_MODVERSIONS,你编译内核模块时要定义宏
MODVERSIONS,而且要包含/usr/include/linux/modversions.h头文件。这些可以
在你的代码中做。

Makefile例子

 
# Makefile for a basic kernel module

CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX

hello.o: hello.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c hello.c
#end of Makefile

    现在剩下来的唯一事情就是su到root用户(一般你都不用root用户来执行编译
的,是吧?),然后执行insmod hello来加载hello模块,rmmod hello来卸载内核
中的hello模块。当你执行这些命令时,注意/proc/modules前后的变化。
    注意:用printk打印的内核信息是输出到控制台的,当你不用X界面时,它输
出到你所使用的虚拟终端(通过Alt-F<n>选定的),你可以看到这些信息。当你用
X图形界面时,有两种可能性。一种是你用xterm -C运行一个终端,信息的输出将
送到那里显示,否则,就是另外一种情况:信息被送到虚拟终端7,将会被X窗口
所掩盖,你将看不到printk所显示的信息。

    如果你的内核变得不稳定,你不应该使用X界面来得到调试信息。不用X时,
信息直接从内核到控制台。在X里面,printk打印的信息输出到用户进程xterm -
C,当该进程取得CPU运行时间时,它将信息传给X的服务器进程。然后当X服务器进
程取得CPU运行时间,信息才显示出来。但一个不稳定的内核通常意味着系统将会
崩溃或重启,所以你不想延迟错误信息的输出的话,建议你使用控制台来调试内
核模块。

译者注:这个简单的例子可以直接在命令行上编译:
cc -D__KERNEL__ -DLINUX -DMODULE -c hello.c
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值