編譯android的linux kernel goldfish

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

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

$ export ARCH=armandroid

$ export SUBARCH=armweb

$ export CROSS_COMPILE=arm-eabi-shell

$ make ARCH=arm goldfish_armv7_defconfigbash

$ 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。下面看一下這三個依賴:

一、 FORCE

首先分析一下這個依賴,它的規則定式義在1485行:

PHONY += FORCE
FORCE:

這個規則沒有命令也沒有依賴,它的目標也不是一個存在的文件名。在執行此規則時,目標FORCE總會被認爲是最新的。這樣當它做爲其它規則的依賴時,由於依賴總被認爲被更新過的,因此那個規則的中定義的命令總會被執行。

二、 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中並無定義。

三、 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這個腳本,出現配置界面

ui

相關文章
相關標籤/搜索