linux 模块编程

makefile文件

obj-m := hello.o 
KERNELDIR := /lib/modules/2.6.20/build 
PWD := $(shell pwd) 

modules: 
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 

modules_install: 
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install 

如果有多个依赖文件的话:

obj-m := hello.o
hello-objs := file1.o file2.o
这里的-c选项是指首先改变目录到-C指定的位置(即内核源代码的目录), 其中保存着内核的顶层makefile文件。M=选项让该makefile在构造modules目标之前返回到模块源代码目录。然后,modules目标指向obj-m变量中指定的模块;在上面的例子中,我们将该变量设置为hello.o

obj-m:=rt_process.o
	PWD := $(shell pwd)
modules:
	$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

modules_install:
	$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install

模块示范代码

#include<linux/init.h>  
#include<linux/types.h>  
#include<linux/kthread.h>  
#include<linux/module.h>  
#include<linux/export.h>  
#include <linux/delay.h>  
#include<linux/slab.h>  
#include <linux/fs.h>  
#include<asm/uaccess.h>  
  
#ifndef SLEEP_MSEC  
#define SLEEP_MSEC(nMS) \  
do{\  
unsigned long timeout = (nMS)*HZ/1000;\  
while(timeout>0){\  
timeout=schedule_timeout(timeout);\  
}\  
}while(0);   
#endif  
  
static struct task_struct * MyThread = NULL;  
static int MyPrint(void *data)  
{  
    printk(KERN_ALERT "beginning  Thd!\n");  
    while(!kthread_should_stop())  
{  
        SLEEP_MSEC(10);  
     你的测试代码;  
}  
return 0;  
}  
static int __init   test_init(void)  
{  
    printk(KERN_ALERT "loading  module!\n");  
    MyThread = kthread_create(MyPrint,NULL,"mythread");  
    if(IS_ERR(MyThread)){  
        printk(KERN_ALERT" task creation fails!\n");              
        return -1;  
    }else{  
        kthread_bind(MyThread,1);  
    }  
    wake_up_process(MyThread);  
    printk(KERN_ALERT "Task waked!\n");  
    return 0;  
}  
  
static void __exit test_exit(void)  
{  
    if(MyThread)  
    {  
        kthread_stop(MyThread);  
        printk(KERN_ALERT "stop  thread!\n");         
        MyThread = NULL;  
    }  
    printk(KERN_ALERT "unload module!\n");    
    return 0;  
}  
  
module_init(test_init);  
module_exit(test_exit);  

makefile的一些总结:

在讲述Makefile之前,还是让我们先来粗略地看一看Makefile的规则。

target ... : prerequisites ...
command
...
...

target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

prerequisites就是,要生成那个target所需要的文件或是目标。

command也就是make需要执行的命令。(任意的Shell命令)

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

在默认的方式下,也就是我们只输入make命令。那么,

1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。

通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模块一般用来支持那些不经常使用的功能。例如,通常情况下你仅使用拨号网络,因此网络功能并不是任何时候都需要的,那么就应该使用可装入的模块来提供这个功能。仅在你进行拨号联接的时候,该模块才被装入。而在你断掉连接的时候它会被自动卸下。这样会使内核使用内存的量最小,减小系统的负荷。 当然,那些象硬盘访问这样时时刻刻都需要的功能,则必须作在内核里。如果你搭一台网络工作站或 web服务器,那么网络功能是时刻都需要的,你就应该考虑把网络功能编译到内核里。另外一个方法是在启动的时候就装入网络模块。这种方法的优点是你不需要重新编译内核。而缺点是网络功能不能特别高效。 按照以上的原则,我们首先列出一张清单,看看 kernel 中哪些选项是非有不可的,也就是说,这些东西是必须被编译到内核中的。将那些非必需的模块剔除到内核以外。 第一个是root所在的硬盘配置。 哪果您的硬盘是IDE接口,就把 ide 的选项标记下来。如果是SCSI接口,请把您的接口参数及 SCSI id 记标下来。 第二个是选择使用哪一个文件系统。 Linux的默认文件系统是是 ext2 ,那么就一定要把它标记下来。如果机器中还其它的操作系统,如win98或windows NT,您还会可能选择FAT32或NTFS的支持,不过后面你可以通过手工加载的方式来加入新的模块支持。 第三个是选择Linux所支持的可执行文件格式。这里有两种格式可供选择: elf:这是当前Linux普遍支持的可执行文件格式,必须编译到内核中 。 a.out: 这是旧版的Linux的可执行文件各函数库的格式,如果你确认肯定用不到这种格式的可执行文件,那么就可以不把它编译到内核当中。 以上这些内容,是必须要编译到内核中的。其它的内容凡是所有选项中m提示的,都选择m,这样可以通过手工的方式添加该模块。 ** Loadable module support*Enable loadable module support (CONFIG_MODULES) [Y/n/?]Set version information on all symbols for modules (CONFIG_MODVERSIONS) [N/y/?]Kernel daemon support (e.g. autoload of modules) (CONFIG_KERNELD) [Y/n/?] 分别回答 Y,N,Y 。其中 CONFIG_KERNELD 的 default 值是 N, 所以要注意选择Y。 make config 完后,仍旧是 make dep; make clean。 接下来要 make zlilo 或 make zImage。 然后 make modules ; make modules_install 。完成之后,就编译出一个没有调入多余模块的一个“干净的”内核映像文件了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值