https://source.android.com/source/building-kernels.html

$ export PATH=/home/hzh/oldhome/learn/android-4.2.2/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:${PATH}

$ export ARCH=arm

$ export SUBARCH=arm

$ export CROSS_COMPILE=arm-eabi-

$ make ARCH=arm goldfish_armv7_defconfig

$ make

Kernel Makefiles are part of the kbuild system, documented in various places on the web, for example http://lwn.net/Articles/21835/. The relevant excerpt is here:

--- 3.1 Goal definitions

Goal definitions are the main part (heart) of the kbuild Makefile. These lines define the files to be built, any special compilation options, and any subdirectories to be entered recursively.

The most simple kbuild makefile contains one line:

Example: obj-y += foo.o

This tell kbuild that there is one object in that directory named foo.o. foo.o will be build from foo.c or foo.S.

If foo.o shall be built as a module, the variable obj-m is used. Therefore the following pattern is often used:

Example: obj-$(CONFIG_FOO) += foo.o

$(CONFIG_FOO) evaluates to either y (for built-in) or m (for module). If CONFIG_FOO is neither y nor m, then the file will not be compiled nor linked.

So m means module, y means built-in (stands for yes in the kernel config process), and $(CONFIG_FOO) pulls the right answer from the normal config process.

linux kernel 的makefile的组织结构(转)
背景知识:
背景知识一:Kconfig介绍:
在#make menuconfig 时,所显示的Menu list是由各层Kconfig组成的。
最底层Kconfig存放在 ~/arch/i386/Kconfig. 以此为头,它会一层层使用source来把需要加入的各个目录中Keconfig添加近来。
例如:source "drivers/Kconfig"
则将~/drivers/Kconfig添加进Menu list中。

背景知识二:Kconfig写法语义:
config HID
tristate "Generic HID support"
depends on INPUT
default y
解释如下:
config HID :表示此条目与CONFIG-HID对应。CONFIG-HID会在Makefile中用到。

tristate "Generic HID support" 引号内的内容是会显示到Menu list中的。tristate表示这一项是三态的。

depends on INPUT:依赖于INPUT这一项。如果没有选中INPUT,则Menu list不会显示这项。

default y :缺省被选中。

背景知识三:built-in.o
vmlinux是Linux源码编译后未压缩的内核, vmlinux是由arch/i386/kernel/head.o和arch/i386/kernel/init_task.o以及各个相关子目录下的built-in.o链接而成的。

背景知识四:Kernel Makefile
Kernel中Makefile的体系以及如何编译的,其实Sam一直是一知半解的。
其中,kernel目录中的Makefile被称为底层Makefile。
当使用类似#make menuconfig配置内核成功后,会生成 .config文件。
换句话说:make menuconfig 时,Makefile会从~/arch/i386/Kconfig读取Kconfig.然后根据用户的选择。生成.config文件。
例如:在drivers/hid/Kconfig:
config HID
tristate "Generic HID support"
如果用户选中Y,则在.config中会反映出来:
CONFIG_HID=y
则在~/drivers/Makefile中可以看到:
obj-$(CONFIG_HID) += hid/
表明:如果CONFIG_HID是Y,则把hid目录添加到要编译的目录中了。
进入到/driver/hid目录,则看到:
hid-objs := hid-core.o hid-input.o
表明这两个.o文件是一定会被编译出的。
obj-$(CONFIG_HID) += hid.o
表明:如果CONFIG_HID是Y,则hid.o会被编译出来。并built-in.
如果是 =m. 则hid.o被编译出来,但最后被做成modules(ko)
 
背景知识五:KBuild Make:
Linux内核的Makefile与我们平时写的Makefile有所不同,它由五部分组成:
1.Makefile : 顶层Makefile。
2. .config: kernel配置文件。
3. arch/xxx/Makefile: 具体架构的Makefile。
4. scripts/Makefile.xxx : 通用规则。
5. kbuild Makefile: 整个kernel中大约有数百个这种文件。

#make menuconfig后,生成 kernel配置文件: .config。
顶层Makefile读取.config.
顶层Makefile通过解析 .config来决定递归访问哪些目录中的Kbuild Makefile .
这个过程中,Kbuild Makefile会按.config的设置,逐个添加文件列表,以供最后的编译使用。
最简单的KBuild Makefile如下:
obj-y += foo.o
表明:Kbuild在这目录里,有一个名为foo.o的目标文件。foo.o将从foo.c或foo.S文件编译得到。并且它会被包入built-in中去。
所 有编译进内核的目标文件都存在$(obj-y)列表中。而这些列表依赖内核的配置。Kbuild编译所有的$(obj-y)文件。然后,调用"$(LD) -r"将它们合并到一个build-in.o文件中。稍后,该build-in.o会被其父Makefile联接进vmlinux中。

如果foo.o要编译成一模块,那就要用obj-m了。所采用的形式如下:
obj-m += foo.o

例一:
在 ~/driver/hid/hid-core.c中,有以下语句,即内核insmod接口hid_init.
module_init(hid_init);
也就是说,当此模块被buildin或者作为module insmod时,kernel会自动调用hid_init.
然后查看 ~/driver/hid/Makefile,发现
hid-objs := hid-core.o hid-input.o
表明只要hid这个目录被加入,就会生成hid-core.o.
只好去看上一层目录中怎样会进入hid目录:
obj-$(CONFIG_HID) += hid/
表明只要CONFIG_HID=Y,m. 则hid目录被加入。
但用户作了什么,hid目录被加入编译呢?则看~/drivers/hid/Kconfig
config HID
tristate "Generic HID support"
以此得之只要在make menuconfig中选中此项,则hid-core.o被编译出来。

例2:
Sam想要研究USB Keyboard & Mouse driver. 在 make menuconfig时,需要选中:
config USB_HID
tristate "USB Human Interface Device (full HID) support"
则查看Makefile。发现只要选中CONFIG_USB_HID.则会编译出usb_hid.o
但~/drivers/hid/usbhid目录中却没有usbhid.c。那usbhid.o如何生成的呢?
drivers/hid/usbhid目录中,有个.usbhid.o.cmd文件。
 
_______________________________________________________________________________________________
 
 
linux kernel makefile
描述linux kernel 的makefile的组织结构,什么是linux kernel 和 makefile 不用说了。

1. 概述

kernel的makefile分为5个部分:

Makefile 最外面的Makefile
.config kernel的配置文件
arch/$(ARCH)/Makefile 不同架构cpu的makefile

scripts/Makefile.* 规则文件

kbuild Makefiles 500多个makefile文件

来看看kbuild makefile文件的构造规则定义。kbuild文件是组织kernel选项的文件。你会看到kbuild 和makefile 在一般同时存在一个目录里的。

目标定义:

一般都会用到此定义,此行的目的是要编译成foo.o 文件,而源文件是默认的foo.c或者是foo.s 。源文件在kbuild文件的同级目录里。

obj-y += foo.o

如果要将此编译成一个模块,则需要用ojb-m 。如果想通过kernel的配置传递此参数,则需要写下面的。

obj-$(CONFIG_FOO) += foo.o

(CONFIG_FOO) 就是你在kernel选项里配置的,如果你没有选中是built-in 还是 module,则此变量是y 或者 m的其他值,则不会编译此文件。

built-in 目标文件:

当你obj-y 的时候,他们将会把所有的obj-y files 都编译进去一个大的 built-in.o 目标文件。此后,会根据最上层的Makefile 链接成一个kernel image。

#drivers/isdn/i4l/Makefile # Makefile for the kernel ISDN subsystem and device drivers. # Each configuration option enables a list of files. obj-$(CONFIG_ISDN) += isdn.o obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
需要注意的是,您需要注意这些 目标文件的顺序。
因为一些函数例如(module_init() / __initcall) 是按照他们出现的顺序被调用的。

ojb-m 目标:

这个是指要编译成模块。一个模块可以由一个源文件或者多个组成。
linux/2.6.20.6/make menuconfig

当在顶层目录执行”make menuconfig”会执行顶层Makefile 第415行的规则

config %config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@

这里”menuconfig”与模式”%config”匹配。所以其执行的规则如下:

menuconfig: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig

这个规则有三个依赖:scripts_basic、outputmakefile、FORCE。下面看一下这三个依赖:

1、 FORCE

首先分析一下这个依赖,它的规则定式义在1485行:

PHONY += FORCE
FORCE:

这个规则没有命令也没有依赖,它的目标也不是一个存在的文件名。在执行此规则时,目标FORCE总会被认为是最新的。这样当它作为其它规则的依赖时,因为依赖总被认为被更新过的,所以那个规则的中定义的命令总会被执行。

2、 scripts_basic

这个依赖的规则在347行定义:

scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic

build这个变量定义在scripts/kbuild.include的114行:

build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj

所以上面的规则可写成如下形式:

scripts_basic:
$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/basic

这个规则的命令最终会进入scripts目录,执行Makefile.build文件,并传递参数obj=scripts/basic.

在Makefile.build的第5行有:

src := $(obj)

这就把传递进来的值赋给了src,所以

src := scripts/basic

从第16行开始的两行把src (即scripts/basic)目录下的Makefile包含进来(如果有Kbuild则包含Kbuild)

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)

在第19行包含了scripts/Makefile.lib进来,

在Makefile.build的第83行,是make在Makefile.build中遇到的第一个目标

__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
$(subdir-ym) $(always)
@:

KBUILD_BUILTIN在顶层Makefile的第207行定义

KBUILD_BUILTIN := 1

如果执行”make modules”,会在214行开始对其进行一些处理

ifeq ($(MAKECMDGOALS),modules)
KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
endif

所以我们这里 KBUILD_BUILTIN :=1

KBUILD_MODULES在顶层Makefile的第206行定义,

KBUILD_MODULES :=

如果执行”make all”、”make _all”、”make modules”、”make”中任一个命令,则在222行开始会对这个变量进行处理

ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
KBUILD_MODULES := 1
endif

ifeq ($(MAKECMDGOALS),)
KBUILD_MODULES := 1
endif

因此,我们这里KBUILD_MODULES :=

分析了这两个变量后,上面的规则可重新写为

__build: $(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)
@:

这就是通过规则

scripts_basic:
$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/basic

在scripts/Makefile.build文件中执行的第一个规则,

规 则中的依赖由几个变量$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)表示。规则的命令是一个冒号命令”:”,冒号(:)命令是bash的内建命令,通常把它看作true命令。bash的help解释 (help :)为:No effect; the command does nothing. A zero exit code is returned.(没有效果,该命令是空操作,退出状态总是0)。
__build: $(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)
@:

构建一些依赖目标,这里主要是构建$(always)变量指定的目标。其他变量在scripts/basic/Makefile中并没有定义。

3、 outputmakefile

回到顶层Makefile中看规则

menuconfig: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig

中的outputmakefile参数构建规则在357行开始定义

outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif

这个规则的命令运行一个shell脚本scripts/mkmakefile,并传递四个参数。这个脚本主要是在$(objtree)参数指定的目录中生成一个Makefile文件。由于这里KBUILD_SRC为空,所以这个脚本并不会被执行

回头再看看刚才那个规则

menuconfig: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig

在他的依赖被处理完后,开始执行规则的命令。第一个命令创建了两个目录,第二个命令扩展后为

$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj =scripts/kconfig menuconfig

这 个命令依然是执行scripts/Makefile.build这个makefile文件。并执行它里面menuconfig的规则。根据上面的分析,在 Makefile.build会包含scripts/kconfig/Makefile文件。然后执行以menuconfig为目标的规则,在 scripts/kconfig/Makefile的13行定义

menuconfig: $(obj)/mconf
$< arch/$(ARCH)/Kconfig

从这个命令可以看出,最终会运行arch/arm/Kconfig这个脚本,出现配置界面

编译android的linux kernel goldfish的更多相关文章

  1. 在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel)

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6564592 在前一篇文章提到,从源代码树下载下 ...

  2. 【Android 系统开发】下载 编译 Android源代码 和 Android kernel源代码

    下载Android源码简要流程 : a. 获取repo文件: curl http://commondatastorage.googleapis.com/git-repo-downloads/repo ...

  3. 下载 编译 Android源代码 和 Android kernel源代码

    下载Android源码简要流程 : a. 获取repo文件: curl http://commondatastorage.googleapis.com/git-repo-downloads/repo ...

  4. [原]Ubuntu 14.04编译Android Kernel

    如何编译android kernel参考官方文档:https://source.android.com/source/building-kernels.html   在Ubuntu 14.04上编译a ...

  5. How to download and compile Android kernel goldfish ?

    Prerequisites Assuming that we already downloaded the android-ndk-r12b and sdk. w4118@w4118:~/utils$ ...

  6. 【转】编译Android系统源码和内核源码

    原文网址:http://blog.csdn.net/jiangwei0910410003/article/details/37988637 好长时间没有写blog了,之所以没有写,主要还是工作上的事, ...

  7. 编译Android源代码与内核总结

    这些天花了些时间自己下载了android源代码来编译,当中走了一些弯路导致耗了些时间,如今又一次梳理总结下,让有同样想法的人自己编译的时候能少走些弯路,官方指导文档在http://source.and ...

  8. FW 编译Android系统源码和内核源码

    编译Android系统源码和内核源码 分类: Android2014-07-21 20:58 7287人阅读 评论(28) 收藏 举报 好长时间没有写blog了,之所以没有写,主要还是工作上的事,发现 ...

  9. 编译Android系统源码和内核源码

    [日期:2016-01-11] 来源:Linux社区  作者:jiangwei [字体:大 中 小]     把我之前编译Android系统源码和内核源码的过程记录一下,因为这个过程真的是受益匪浅,看 ...

随机推荐

  1. 无法绑定到新的显示成员,参数名:newDisplayMember

    此问题不是网上说的 DisplayMember 等先后顺序问题,即使更换绑定数序,只是把错误覆盖而已(绑定的是对象的类名) ValueMember = "Id"; DisplayM ...

  2. 利用SQL进行推理

    数据库环境:SQL SERVER 2008R2 有如下需求: Baker, Cooper, Fletcher, Miller and Smith住在一座房子的不同楼层.Baker 不住顶层.Coope ...

  3. 修改tomcat默认的端口号

    协同管理系统黙认使用Tomcat默认的端口8080,除8080端口外Tomcat还会占用8005,8009和8443端口.如果这4个端口已被占用,可以将协同管理系统修改为使用其它端口. 修改方法如下: ...

  4. ios7--系统自带的向右滑动手势返回上一个界面

    当从控制器A push到控制器B,我们返回控制器A,除了使用按钮返回 [self.navigationController pushViewController:Vc animated:YES]; 还 ...

  5. iOS截屏代码

    转载自:http://m.open-open.com/m/code/view/1420469506375 1.普通界面 /** *截图功能 */ -(void)screenShot{ UIGraphi ...

  6. Gulp-入门教程 搭配环境

    之前一直听朋友谈起gulp,但没有使用过,最近有机会接触到,现在给大家分享下,不对的地方还请指正.我一直以为互相分享是学习的一种好方式.下面进入正题: 首先来了解下gulp,最起码要知道:我们为什么要 ...

  7. php中如何实现网上商城用户历史浏览记录的代码

    /如是COOKIE 里面不为空,则往里面增加一个商品ID if (!empty($_COOKIE['SHOP']['history'])){ //取得COOKIE里面的值,并用逗号把它切割成一个数组 ...

  8. JS-SDK微信支付开发攻略

    一.吐槽篇 一个字——坑!两个字——很坑!三个字——非常坑!首先,微信支付接口作为微信开发接口的一部分,竟然有一本书那么厚的官方文档,共36页,更重要的是,这36页还不能把开发的流程说清楚,描述过于分 ...

  9. Windowsphone 之xml序列化和反序列化的应用(WebService解析返回的数据DataSet )

    关于Xml的序列化和反序列化: 可以看这篇文章,http://www.cnblogs.com/Windows-phone/p/3243575.html WebService解析返回的数据DataSet ...

  10. IS脚本学习

    OnFirstUIBefore:函数块用于第一安装应用时安装部件前所要完成的任务.一般在这里进行下列设: 1. 设置屏蔽 2. 显示欢迎信息,软件协议书或关于软件安装的其他说明信息 3. 从用户处获取 ...