編譯android的linux kernel goldfish

來源:互聯網
上載者:User

標籤:

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 [email protected]

這裡”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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.