Exynos4412 核心移植(二)—— 核心編譯過程分析
核心的編譯同樣是從Makefile 來分析:
一、核心原始碼結構
Linux核心檔案數目近2萬,出去其他架構CPU的相關檔案,他們分別位於頂層目錄下的17個子目錄,各個目錄功能獨立,下面是常用目錄:
arch:體系結構相關程式碼
ipc:程式排程相關程式碼
mm:記憶體管理
Documentation:幫助文件
net:網路協議
lib:庫
scripts:編譯相關指令碼工具
tools:編譯相關工具
drivers:裝置驅動
fs:檔案系統實現
對於ARM 架構的Exynos4412,其體系相關的程式碼在arch/arm/目錄下,在後面進行的Linux移植時,開始的工作正式修改這個目錄下的檔案。
二、Linux Makefile分析
核心中的哪些檔案將被編譯?它們是怎樣被編譯的?它們連線時的順序如何確定?那個檔案在最前面?哪些檔案或函式先執行?這些都是通過Makefile 來管理的。從最簡單的角度來總結Makefile的作用,有以下3點:
1)-- 決定編譯哪些檔案;
2)-- 怎樣編譯這些檔案?
3)-- 怎樣連線這些檔案,最重要的是它們的順序如何?
Linux 核心原始碼中含有很多個Makefile檔案,這些Makefile檔案又要包含其他一些檔案(比如配置資訊、通用的規則等)。這些檔案構成了 Linux 的Makefile 體系,可以分為下表中的5類:
名稱 | 描述 |
頂層Makefile | 他是所有Makefile檔案的核心,從總體上控制核心的編譯和連結 |
.config |
配置檔案,在配置核心時產生。所有Makefile檔案(包括頂層目錄及各級子目錄)都是根據.config來決定使用哪些檔案
|
arch/$(ARCH)/Makefile |
對應體系結構的Makefile,它用來決定哪些體系結構相關的檔案參與核心的生成,並提供一些規則來生成特定格式的核心映像。
|
scripts/makefile.* | Makefile公用的通用規則、指令碼等 |
kbuild Makefiles |
各級子目錄下的Makefile,他們相對簡單,被上一層Makefile呼叫來編譯當前目錄下的檔案
|
以下根據見面總結的Makefile 的3大作用分析這5類檔案。
1、決定編譯哪些檔案
Linux核心的編譯過程從頂層Makefile開始,然後遞迴地進入各級子目錄呼叫他們的makefile,分為3個步驟:
a -- 頂層Makefile 決定核心根目錄下哪些子目錄將被編進核心;
b -- arch/$(ARCH)/Makefile 決定arch/$(ARCH)目錄下哪些檔案、哪些目錄將被編進核心;
c -- 各級子目錄下的Makefile決定所在目錄下哪些檔案將被編進核心,哪些檔案將被程式設計模組(即驅動程式),進入哪些子目錄繼續呼叫它們的Makefile。
a -- 先看步驟a, 頂層Makefile的編譯
在頂層Makefile 中可以看到如下內容:
可見,頂層Makefile將這14個子目錄分為5類:init-y、divers-y、net-y、libs-y和core-y。
我們可以看到,最重要的arch目錄沒有出現在核心中。它在arch/$(ARCH)/Makefile中被包含進核心,在頂層Makefile中直接包含了這個Makefile,如下所示:
對於ARCH變數,可以在執行make時傳入,比如“make ARCH=arm ...”。另外,對於非X86平臺,還需要指定交叉編譯工具,這也可以在執行make 命令時傳入,比如“make CROSS_COPILE=arm-linux- ..”。為了方便,常在頂層Makefile中進行如下修改。這樣執行make時就會將ARCH變數傳入
b -- 看步驟 b,arch/$(ARCH)/Makefile的編譯
對於步驟 b 的 arch/$(ARCH)/Makefile,以ARM為例,在arch/arm/Makefile 中可以看到如下內容:
從129行可知,除了剛面的5類子目錄外,又出現了一類:head-y,不過它直接以檔名出現;
arch/arm/Makefile 中類似第268-273行的程式碼進一步擴充套件了core-y的內容,第276行擴充套件了libs-y的內容,這些都是體系相關的目錄;第261-265行中的CONFIG_在配置核心時定義,它的值有3種:y、m或空。y表示編進核心,m表示編為模組,空表示不使用;
編譯核心時,將依次進入init-y、core-y、libs-y、drivers-y和net-y 所列出的目錄中執行它們的Makefile,每個子目錄都會生成一個 built-in.o(libs-y所列目錄下,有可能生成lib.a檔案)。最後,head-y所表示的檔案將和在這些built-in.o、lib.a 一起被連線成核心映像檔案 vmlinux。
c -- 步驟 c 是如何進行的,各級子目錄下的Makefile的編譯
在配置核心時,生成配置檔案.config。核心頂層Makefile使用如下語句間接包含.config 檔案,以後就根據.config中定義的各個變數決定編譯哪些檔案。值所以說是“間接”包含,試音為包含的是include/config/auto.conf 檔案,而它只是將.config檔案中的註釋去掉,並根據頂層Makefile中定義的變數增加一些變數而已。
2、怎樣編譯這些檔案
即編譯選項、連線選項是什麼。這些選項分3類:全域性的,適用於整個核心程式碼樹;區域性的,僅適用於某個Makefile中的所有檔案;個體的,僅適用於某個檔案。
全域性選項在頂層Makefile和arch/$(ARCH)/Makefile 中定義,這些選項的名稱為:CFLAGS、AFLAGS、LDFLAGS、ARFLAGS,他們分別是編譯C檔案的選項、編譯彙編問價你的選項、連線檔案的選項、製作庫檔案的選項。
3、怎樣連線這些檔案,它們順序如何
前面分析有哪些檔案要編進核心時,頂層Makefile和arch/$(ARCH)/Makefile定義了6類目錄(或檔案):head-y、init-y、drivers、libs-y 和 core-y。它們的初始值如下(以ARM體系為例)
arch/arm/Makefile 中:
頂層makefile 中:
可見,除head-y 外,其餘的init-y、drivers-y等都是目錄名。在頂層Makefile 中,這IE目錄名的後面直接加上built-in.o 或 lib.a,表示要連線進核心的檔案。
上面的patubst是個字串處理函式,它的用法如下:
(patsubst pattern, replacement,text)
表示尋找“text”中符合格式“pattern”的字,用”replacement"替換它們。比如上面的init-y初值為“init/”,經過793行的互動後,“init-y” 變為“init/built - in.o”。
頂層Makefile中,再往下看:
對於ARM體系,連線指令碼就是arch/arm/kernel/vmlinux.lds,它由 arch/arm/kernel/vmlinux/lds.S檔案生成,先將生成的arch/arm/kernel/vmlinux.lds摘錄如下:
總結:
a -- 配置檔案.config 中定義了一系列的變數,Makefile將結合它們來決定哪些檔案被編進核心、哪些檔案被編進模組、涉及哪些子目錄;
b -- 頂層Makefile和arch/$(ARCH)/Makefile決定根目錄下哪些子目錄、arch/$(ARCH) 目錄下哪些檔案和目錄將被編進核心;
c -- 最後,各級子目錄下的Makefile決定所在目錄下哪些檔案將被編進核心,哪些檔案將被變成模組(即驅動程式),進入哪些子目錄繼續呼叫它們的Makefile;
d -- 頂層Nakedfile和arch/$(ARCH)/Makefile設定了可以影響所有檔案的編譯、連線選項:CFLAGS、AFLAGS、LDFLAGS、ARFLAGS;
e -- 頂層Makefile按照一定的順序組織檔案,根據連線指令碼 arch/$(ARCH)/kernel/vmlinux.lds生成核心映像檔案vmlinux。
相關文章
- 編譯核心過程編譯
- openGauss核心:SQL解析過程分析SQL
- Ubuntu20.04linux核心(5.4.0版本)編譯準備與實現過程-編譯過程(2)UbuntuLinux編譯
- 編譯linux核心編譯Linux
- 編譯系統核心編譯
- 一個Linux愛好者的2.6.11核心編譯過程(轉)Linux編譯
- 高效學習Linux核心——核心模組編譯Linux編譯
- oracle索引核心過程Oracle索引
- JavaScript的預編譯過程分析JavaScript編譯
- Android Makefile 編譯過程分析Android編譯
- Linux核心模組編譯Linux編譯
- linux核心修改編譯Linux編譯
- 如何編譯 Linux 核心編譯Linux
- 核心編譯part5編譯
- 核心編譯part4編譯
- 核心編譯part3編譯
- 核心編譯part2編譯
- Linux核心建立一個程式的過程分析Linux
- 編譯過程編譯
- 如何編譯樹莓派核心編譯樹莓派
- 附錄A Linux 編譯核心Linux編譯
- Linux核心排程分析(程式排程)Linux
- Linux2.4.18核心移植到s3c2410全過程(轉)LinuxS3
- Javac編譯過程Java編譯
- 編譯器的編譯基本過程編譯
- Centos8編譯安裝核心CentOS編譯
- Android核心的編譯與裁剪Android編譯
- 編譯核心make dep 的意思(轉)編譯
- hi3520d核心編譯編譯方法編譯
- openGauss核心分析(九):資料庫表的建立過程資料庫
- Linux核心Kernel啟動過程Linux
- 編譯連結過程編譯
- 編譯過程簡介編譯
- C++ 編譯過程C++編譯
- nanoPI編譯核心的一些recordNaN編譯
- win7 64位編譯WebKit核心Win7編譯WebKit
- centos5.1編譯2.6.24.5核心總結CentOS編譯
- 核心編譯2.6.13.4(原創)part1編譯