转载:http://www.embeddedlinux.org.cn/html/yingjianqudong/201403/23-2820.html

Linux内核是一种单体内核,但是通过动态加载模块的方式,使它的开发非常灵活 方便。那么,它是如何编译内核的呢?我们可以通过分析它的Makefile入手。以下是 一个简单的hello内核模块的Makefile.

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KERNELDIR ?= /root/work/latest_codes/linux-stable
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:
@rm -rf *.o *.mod.c *.mod.o *.ko *.order *.symvers .*.cmd .tmp_versions
endif

当我们写完一个hello模块,只要使用以上的makefile。然后make一下就行。

假设我们把hello模块的源代码放在/home/study/prog/mod/hello/下。

当我们在这个目录运行make时,make是怎么执行的呢?

LDD3第二章第四节“编译和装载”中只是简略地说到该Makefile被执行了两次,但是具体过程是如何的呢?


先,由于make
后面没有目标,所以make会在Makefile中的第一个不是以.开头的目标作为默认的目标执行。于是default成为make的目标。make会执
行  $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  shell是make内部的函数,

假设当前内核版本是2.6.13-study,所以 $(shell uname -r) 的结果是 2.6.13-study 这里,实际运行的是 
 make -C /lib/modules/2.6.-study/build M=/home/study/prog/mod/hello/ modules 
/lib /modules/2.6.13-study/build是一个指向内核源代码/usr/src/linux的符号链接。

可见,make执行了两次。

第一次执行时是读hello模块的源代码所在目录/home/s tudy/prog/mod/hello/下的Makefile。

第二次执行时是执行/usr/src/linux/下的Makefile时. 
但是还是有不少令人困惑的问题: 1.这个KERNELRELEASE也很令人困惑,它是什么呢?在/home/study/prog/mod/he llo/Makefile中是没有定义这个变量的,所以起作用的是else…endif这一段。

不过,如果把hello模块移动到内核源代码中。例如放到/usr/src/linux/driver/中,
KERNELRELEASE就有定义了。在/usr/src/linux/Makefile中有 162  KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION) 
这时候,hello模块也不再是单独用make编译,而是在内核中用make modules进行
编译。用这种方式,该Makefile在单独编译和作为内核一部分编译时都能正常工作。

2.这个obj-m := hello.o什么时候会执行到呢? 在执行: 
make -C /lib/modules/2.6.13-study/build M=/home/study/prog/mod/hello/ modules
时,make
去/usr/src/linux/Makefile中寻找目标modules:

 .PHONY: modules

 modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)

 @echo ' Building modules, stage 2.';

 $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost

可以看出,分两个stage:

1.编译出hello.o文件。

2.生成hello.mod.o hello.ko

在这过程中,会调用 make -f scripts/Makefile.build

obj=/home/study/prog/mod/hello


在 scripts/Makefile.build会包含很多文件:   -include .config include $(if $(wildcard $(obj)/Kbuild), $(obj)/Kbuild, $(obj)/Makefile)  其中就有/home/study/prog/mod/hello/Makefile 这时 KERNELRELEASE已经存在。

所以执行的是: obj-m:=hello.o 
关于make modules的更详细的过程可以在scripts/Makefile.modpost文件的注释 中找到。如果想查看make的整个执行过程,

可以运行make -n。

关于linux内核模块Makefile的解析的更多相关文章

  1. Linux内核模块Makefile学习

    在<Linux设备驱动程序>一书中读到的内核模块编译Makefile,不是非常理解,在查询很多资料后,在这里做个总结. 书中Makefile代码: ifneq ($(KERNELRELEA ...

  2. Linux笔记-Makefile伪指令解析

    本文是我在博客里面找到的,觉得对makefile的伪指令介绍得非常详细了!也提到了伪指令为何要用.PHONY:来声明!希望我的这篇转过来的文章能够帮助大家理解makefile的伪指令! 我的理解: 拿 ...

  3. linux 内核模块makefile通用模板

    ifneq ($(KERNELRELEASE),)# 在 mylist 后面添加需要编译的模块数量 mylist=hello.o a.o# 为每一个模块添加所需的文件 hello-objs := ma ...

  4. [ARM-LInux开发]linux设备驱动makefile入门解析

    以下内容仅作参考,能力有限,如有错误还请纠正.对于一个普通的linux设备驱动模块,以下是一个经典的makefile代码,使用下面这个makefile可以完成大部分驱动的编译,使用时只需要修改一下要编 ...

  5. linux内核模块编译makefile

    linux内核可加载模块的makefile 在开发linux内核驱动时,免不了要接触到makefile的编写和修改,尽管网上的makefile模板一大堆,做一些简单的修改就能用到自己的项目上,但是,对 ...

  6. linux中Makefile文件相关内容

    第一章.概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional(专业)的程序员,m ...

  7. 5.linux内核模块基础,内核模块学习

    linux内核模块基础 一.定义 Linux 内核的整体结构非常庞大,其包含的组件也非常多,如何使用这些组件呢: 方法 1:把所有的组件都编译进内核文件,即:zImage 或 bzImage,但这样会 ...

  8. Linux内核模块简介

    一. 摘要 这篇文章主要介绍了Linux内核模块的相关概念,以及简单的模块开发过程.主要从模块开发中的常用指令.内核模块程序的结构.模块使用计数以及模块的编译等角度对内核模块进行介绍.在Linux系统 ...

  9. 【转载】Linux下makefile详解--跟我一起写 Makefile

    概述 —— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makef ...

随机推荐

  1. Hadoop学习之--Fair Scheduler作业调度分析

    Fair Scheduler调度器同步心跳分配任务的过程简单来讲会经历以下环节: 1. 对map/reduce是否已经达到资源上限的循环判断 2. 对pool队列根据Fair算法排序 3.然后循环po ...

  2. 转】MyEclipse使用总结——设置MyEclipse使用的Tomcat服务器

    原博文出自于: http://www.cnblogs.com/xdp-gacl/p/3935499.html 感谢! 一.设置使用的Tomcat服务器 如果不想使用MyEclipse自带的tomcat ...

  3. 解析XtraBackup备份MySQL的原理和过程(转)

    原文:http://ourlinux.blog.51cto.com/274624/844859 XtraBackup是percona公司提供的开源工具,以热备Innodb表著称而被广泛采用. Xtra ...

  4. pyQt 每日一练习 -- 登录框

    #coding=utf-8 #第一个练习,登录框 import sys from PyQt4 import QtGui,QtCore #登录框 class LoginBox(QtGui.QWidget ...

  5. gdb之x命令

    [gdb之x命令] 可以使用examine命令(简写是x)来查看内存地址中的值.x命令的语法如下所示: x/<n/f/u> <addr> n.f.u是可选的参数. n是一个正整 ...

  6. Mcafee两个Mac版本之间的区别

    近期打算为Mac安装个杀毒软件,由于自己windows平台下用的是VSE,所以Mac平台也首选Mcafee家的东西了.到Mcafee官网下载点一看,有以下几个版本可以用在Mac上: 有点懵了,查看了一 ...

  7. CodeForces 711B Chris and Magic Square (暴力,水题)

    题意:给定n*n个矩阵,其中只有一个格子是0,让你填上一个数,使得所有的行列的对角线的和都相等. 析:首先n为1,就随便填,然后就是除了0这一行或者这一列,那么一定有其他的行列是完整的,所以,先把其他 ...

  8. js set

    function ff(){ var sArray = ['a','b','b','b','b','b','d','b']; var iSet = {}; for(var i=0;i<sArra ...

  9. 【转】删除已经存在的 TFS Workspace

    删除已经存在的 TFS Workspace 分类: TFS2010-03-03 16:59 1239人阅读 评论(2) 收藏 举报 serverpathcommandcachefilegoogle 工 ...

  10. 利用 Heritrix 构建特定站点爬虫

    http://www.ibm.com/developerworks/cn/opensource/os-cn-heritrix/