Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239512
  • 博文数量: 69
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 15
  • 用 户 组: 普通用户
  • 注册时间: 2013-02-23 13:55
文章分类

全部博文(69)

文章存档

2016年(11)

2013年(58)

我的朋友

分类: LINUX

2013-03-30 18:23:54

原文地址:Linux内核Makefile简述 作者:Knivo

前言

       本文记录了本人通过阅读内核文档makefile.txt所提炼的本人认为对linux驱
       动开发有帮助的知识要点。敬请指出错误和不足。

----------------------------------------------------------------------------------

内核Makefile的框架



      

       ---------------------->
       |
       |- Makefile
       |
       |- .config
       |
       |- arch
       |      |- $(ARCH)
       |               |- Makefile
       |
       |- scripts
       |      |- Makefile.*
       |
       |-
       |      |- kbuild Makefile

      
#
顶层Makefile   

          
根据内核配置文件,通过向下访问makefile的方式,制作内核文件vmlinux与模块文件。

      
# .config

          
有内核配置程序所生成。

      
# arch/$(ARCH)/Makefile

          
向顶层Makefile提供硬件架构的特别信息,与对象机器硬件架构对应的Makefile会被顶

           层Makefile所包含。

      
#  scripts/Makefile.*

           
包含用于编译内核的kbuild Makefile规则。

      
#  kbuild Makefile

           
执行上层Makefile传递下来的命令,从.config中提取信息,生成Kbuild,完成内核编

           译所需的文件列表。

 

----------------------------------------------------------------------------------

.config

      .config文件可以被理解为一个Makefile的变量表,该文件记录了内核Makefile中与特定文件

      编译是否被编译相关变量的值。内核配置程序根据每个目录下的KCONFIG文件生成内核配置程序

      选项界面,用户通过该界面设定了需要编译的功能,内核配置程序再根据KCONFIG中的内容生成

      了不同的变量,并把该变量导入到.config,供内核编译时参照调用。

      

---------------------------------------------------------------------------------

架构Makfile

 

        顶层Makefile为各子目录下Makefile包含的公共部分,而顶层Makefile又首先包含了arch/

        $(ARCH)/Makefile。该架构Makefile包含了针对特定架构的配置信息,相关变量及目标等。

        一具体架构Makefile的具体目的就是,将生成并压缩 vmlinux 文件,写入启动代码,并将其拷

        贝到正确的位置。这就包含了多种不同的安装命令。该具体目的也无法在各个平台间进行标

        准化。一般,附加的处理命令入在arch/$(ARCH)/下的boot目录。

 

 

----------------------------------------------------------------------------------

Kbuild文件

 

       内核使用Kbuild组织Kbuild Makefile。如果同一目录中同时出现MakefileKbuild

       Kbuild将会被使用。

       编译内核文件的主要目标有两个:分别是obj-yobj-m

       Kbuild Makefile规定所有编译进内核的目标文件存在$(obj-y)列表中,编译成模块的

       目标文件存在$(obj-m)列表中。而这些列表依赖内核的配置文件。

       修改目标内容采用以下方式:

              obj-$(CONFIG_) = filename.o

       此语句告诉内核,当前目录下有一名为filename.o的目标。此目标将由filename.c

       filename.s文件编译得到。

       CONFIG_          

       Makefile只对当前目录对象负责,Kbuild通过辨别Kconfig中CONFIG_

      的值来判断是否应该递归操作,但是它指代的值只能够是y(编译进内核)m(编译成模块),其

       余值一律不会被编译链接, 如:

             #fs/Makefile

             obj-$(CONFIG_EXT2_FS) = ext2/

       如果,CONFIG_EXT2_FS的值有效,Kbuild就会递归访问ext2目录,递归的原因是ext2/是一个目录,

       再调用该目录下的Makefile进行编译操作。

 

----------------------------------------------------------------------------------

 Kbuild执行的步驟

 

             1) 根据内核配置生成文件 .config

             2) 将内核的版本号存储在 include/linux/version.h

             3) 生成指向 include/asm-$(ARCH) 的符号链接

             4) 更新所有编译所需的文件:

                 -附加的文件由 arch/$(ARCH)/Makefile 指定。

             5) 递归向下访问所有在下列变量中列出的目录:

                  init-* core* drivers-* net-* libs-*

                并编译生成目标文件。

                  -这些变量的值可以在 arch/$(ARCH)/Makefile 中扩充。

             6) 链接所有的目标文件,在源代码树顶层目录中生成 vmlinux

                 最先联接是在 head-y中列出的文件,该变量由

                   arch/$(ARCH)/Makefile 赋值。

             7) 最后完成具体架构的特殊要求,并生成最终的启动镜像。

                  -包含生成启动指令

                  -准备 initrd 镜像或类似文件

 

----------------------------------------------------------------------------------

目标 obj-y

              1). Kbuild编译所有的$(obj-y)文件,然后,然后将它们链接为build-in.o文件,最后

                  链接到vmlinux中。

              2). 相同的目标可以在obj-y列表中重复出现,已成功链接到built-in.o的目标会被忽略。

              3). 目标链接时是按顺序的。如果链接顺序出错,有可能造成硬盘数据出错。

 

----------------------------------------------------------------------------------

目标 obj-m

              1). 一个文件编译一个模块

                  obj-$(CONFIG_) = .o

              2). 多个文件编译一个模块

                  obj-$(CONFIG_) = .o
                  -objs := obj_file_1.o ... obj_file_n.o

                  Kbuild能够识别目标文件的后缀为-objs-ykbuild通过CONFIG_符号来判断对象是

                  否用于组合。

 

----------------------------------------------------------------------------------

编辑标志

       下面标志仅在它们所被指定的Kbuild makefile有效。

       ccflags-y 

         用于编译C源代码的编译选项。源代码树拥有。

       asflags-y  

          用于编译汇编源代码的编译选项。当前目录拥有。

       ldflags-y 

          用于链接目标文件的选项。当前目录拥有。

       CFLAGS_$(filename), AFLAGS_$(filenam)

          编译源代码选项,单个文件拥有的。

----------------------------------------------------------------------------------

依赖跟踪

       改变下面任意项内容,所有受影响文件将会重新被编译。

       1). 所有参与编译的文件(*.o*.h)

       2). 所有参与使用的CONFIG_

       3). 用于编译的命令行 

 

----------------------------------------------------------------------------------

                                   相关变量列表

----------------------------------------------------------------------------------

KERNELRELEASE


                $(KERNELRELEASE) 是一个字符串,类似"2.4.0-pre4",用于安装目录的命名或显示当前的版本号。

       一部分架构Makefile使用该变量。内容通过cat include/config/kernel.release所得。

 

ARCH


       该变量定义了目标架构,比如"i386","arm" "sparc"。有些Kbuild Makefile

       根据 $(ARCH) 决定编译哪些文件。


       默认情况下,顶层Makefile将其设置为本机架构。如果是跨平台编译,用户可以

       用下面的命令覆盖该值:


                make ARCH=m68k ...

 

INSTALL_PATH


      该变量为架构Makefile定义了安装内核镜像与 System.map 文件的目录。

      主要用来指明架构特殊的安装路径。


 

INSTALL_MOD_PATH,MODLIB


              $(INSTALL_MOD_PATH) 为了安装模块,给 $(MODLIB) 声明了前缀。该变量不能

      在Makefile中定义,但可以由用户传给Makefile


              $(MODLIB) 具体的模块安装的路径。顶层Makefile$(MODLIB)定义为

              $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用户可以通过命令行

      参数的形式将其覆盖。


INSTALL_MOD_STRIP

 

      如果该变量有定义,模块在安装之前,会被剥出符号表。如果

              INSTALL_MOD_STRIP "1",就使用默认选项 --strip-debug。否则,

              INSTALL_MOD_STRIP 将作为命令 strip 的选项使用。

 

---------------------------------------------------------------------------------------------

与设备驱动相关的琐碎

 

     . 编译额外模块

        make M=dir modules       顶层Makefile会调用dir目录下的Makefile去构造额外模块



阅读(1646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~