众所周知,Linux内核是使用make命令来配置和编译的,所以Makefile肯定是不可缺少的。 如此复杂庞大的内核源码的配置和编译是绝对不可能用一个或几个Makefile来完成的,而是需要为Linux内核定制一个同样复杂庞大的Makefile系统。
本文引用地址:
虽然她是一个复杂的系统linux 内核 源码编译,但大多数内核开发者只需要知道如何使用它,而不需要了解细节。 她对大多数内核开发人员来说基本上是透明的,隐藏了大部分实现细节,有效减轻了开发人员的负担,使他们能够专注于内核开发,而不是在编译过程上浪费时间和精力。
1.1 Linux内核中的Makefile
1.1.1 顶层Makefile
源代码目录树顶层的Makefile是整个内核源代码管理的入口,对整个内核源代码的编译起着决定性的作用。 编译内核时,顶层Makefile会按照规则递归遍历内核源码所有子目录下的Makefile,完成每个子目录下内核模块的编译。 熟悉Makefile,对内核编译等方面都有帮助。
1. 内核版本号
打开顶楼的Makefile。 前几行记录了内核源码的版本号,通常如下:
第620章 620
显示代码版本为2.6.35.3。 编译好的内核在目标板上运行后,输入uname -a命令得到确认
2. 编译控制
(1) 架构
Linux是支持多种架构的操作系统,编译时需要指定架构以对应实际平台。 在顶层的Makefile中,是通过变量ARCH指定的:
第620章 620
如果编译命令行中没有指定ARCH参数,系统将进行本地编译,通过获取本地机器信息手动指定:
第620章 620
如果要开发ARM嵌入式Linux,必须指定ARCH为arm(注意大小写,必须与arch/目录下的arm一致),如:
第620章 620
当然,你也可以更改Makefile,将ARCH ?= $(SUBARCH)更改为ARCH = arm,直接在命令行make即可。
(2)编译器
如果不是本地编译,则必须指定交叉编译器,由CROSS_COMPILE指定。 Makefile和交叉编译器的规范如下:
第620章 620
CONFIG_CROSS_COMPILE 是一个可以在内核配置期间指定的配置选项。 如果配置内核时没有指定CONFIG_CROSS_COMPILE,也没有在编译参数中指定CROSS_COMPILE,则将使用本地编译器进行编译。
对于ARM嵌入式Linux开发,必须指定交叉编译器,可以通过CONFIG在内核中配置
_CROSS_COMPILE指定交叉编译器,也可以通过CROSS_COMPILE指定。 假设使用的交叉编译器是arm-linux-gnueabihf-gcc,指定CROSS_COMPILE为arm-linux-gnueabihf-:
第620章 620
或者在Makefile中直接指定CROSS_COMPILE的值:
第620章 620
注意:CROSS_COMPILE指定的交叉编译器必须提前安装好,并且系统环境变量必须设置正确; 如果没有设置环境变量,则必须使用绝对地址linux 内核 源码编译,例如:
第620章 620
如果同时指定ARCH和CROSS_COMPILE,则编译时只需要简单的make即可。
1.1.2 子目录Makefile
在内核源码的子目录中,几乎每个子目录都有对应的Makefile文件,它管理对应目录下的代码。 对该目录下的文件或子目录的编译控制,Makefile中有两种表示方法,一种是默认选择编译,用obj-y表示,如:
第620章 620
另一种表示与内核配置选项相关,是否编译以及如何编译取决于内核配置,例如:
第620章 620
是否编译wdt.c文件,或者以什么形式编译,取决于内核配置后变量CONFIG_WDT的值:如果在配置中设置为[*],则会静态编译到内核中,如果配置为[M],将编译为wdt.ko模块,否则不编译。
说明:受控目标是一个目录。 obj-y并不直接判断受控目录下的文件和子目录下的文件,而只是与受控目录下的Makefile进行交互。 实际的编译由controller子目录下的Makefile控制。 比如“obj-y += gpio/”,最终编译出gpio目录下的哪些文件,完全取决于gpio目录下的Makefile。 “obj-$(CONFIG_PCI) += pci/”具有相同的含义。