Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11565
  • 博文数量: 8
  • 博客积分: 290
  • 博客等级: 二等列兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-11 10:10
文章分类

全部博文(8)

文章存档

2011年(8)

我的朋友

分类: LINUX

2011-02-22 11:27:39

/*hello.c*/
#include
#include
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
    printk(KERN_ALERT "Hello, world\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT"Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);

/*Makefile*/
ifneq ($(KERNELRELEASE),)
    obj-m := hello.o
else
    OBJS = hello.c
    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

.PHONY:clean
clean:
    find -path "./*" ! -path "./$(OBJS)" ! -path "./Makefile" | xargs rm -rf


关于这个Makefile的几个注意事项(参考 http://blog.chinaunix.net/u/29845/showart_228802.html)

将上面的脚本保存为Makefile,注意必须保存为M为大写的Makefile,如果将该脚本保存为小写m开头的makefile,编译时会出现这样的提示:
scripts/Makefile.build:13: /root/zhou/Makeifle: No such file or directory.
 
另外,在Makefile中行首缩进需要用Tab键,否则会出问题,还有?=和:=和M=$(PWD)之类的中间千万不要有空格,而ifneq后面一定要有一个空格。


对于这个Makefile,我的理解是,首先看环境变量KERNELRELEASE是否定义,第一次是没有定义的,所以进入else分支,然后定义了KERNELDIR和PWD,再执行default后的那条命令,这条命令会跑到/lib/modules/$(shell uname -r)/build(设为A目录)执行A目录下的Makefile,而那个文件里面定义了KERNELRELEASE,此时会第二遍读取我们这个Makefile,此时已定义KERNELRELEASE,进入if分支,接着由内核A目录下的makefile编译当前工作目录下的hello模块。

至于最后那个clean,就是删除除了hello.c和Makefile以外的所有文件和目录



运行必须有root用户的权限,才能进行内核模块操作,sudo su先。
1执行insmod hello.ko命令,即可挂载并运行hello模块。insmod意思是insert module。成功挂载上hello模块后,会输出:
Hello, world

2执行rmmod hello命令(也可以执行rmmod hello.ko命令),即可卸载模块。rmmod意思是remove module。成功卸载模块后,会输出:
Goodbye, cruel world

3 lsmod或者cat /proc/modules都能查看加载的内核模块,配合grep查找想找的模块

4 modinfo hello.ko(在所在目录下)就可以查看你编译的模块信息


上面的屏幕输出是在文本控制台上得到的;如果读者在某个运行于Windows系统下的终端仿真器中运行insmod和rmmod,则不会在屏幕上看到任何输出。实际上,它可能输出到某个系统日志文件里,比如/var/log/messages。
关于这一点,下篇文章详解。



Makefile最后一个目标clean是伪目标。它规定了 make应该执行的命令。当 make处理到目标 clean时,会先查看其对应的依赖对象。由于 clean没有任何依赖对象,所以make会认为该目标是最新的而不会执行任何操作。为了编译这个目标体,必须手工执行如下命令:
make clean
作为惯例,clean目标一般用于删除最终生成的可执行文件和在编译过程中产生的所有目标文件。
问题是,如果恰巧有一个名为 clean的文件存在时该怎么办呢?此时因为在这个规则里没有任何依赖对
象,所以目标文件肯定是最新的,规则中的命令无论如何也不会被执行,即使用命令“make clean”也
无济于事。解决这一问题的方法是标明该规则中的目标是伪目标,并不对应于任何文件。这可以通
过.PHONY目标实现。它告诉 make不检查规则的目标文件是否存在于磁盘上,也不查找任何隐含规则,
而直接假设指定的目标需要被更新就行了。


内核模块编程中的make命令里有个M选项,如下:
$(MAKE) -C $(KERNELDIR) M = $(PWD) modules
M=$(PWD) 表明然后返回到当前目录继续读入,执行当前的Makefile。
M是makefile脚本中的一个变量(variable)
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRS
KBUILD_EXTMOD ?= $(SUBDIRS)
endif
ifdef M //如果没有定义或赋值M,此处M未定义(undefined)

ifeq ("$(origin M)", "command line") //如果定义了,此句用来判断M是否从命令行来

KBUILD_EXTMOD := $(M)
endif
endif

所以这一句
M = $(PWD)
也可以换成SUBDIRS=$(PWD)

阅读(271) | 评论(1) | 转发(0) |
0

上一篇:怎么样提取rpm包?

下一篇:没有了

给主人留下些什么吧!~~

chinaunix网友2011-03-06 17:49:38

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com