Linux 內核的編譯系統
Linux 的編譯使用 GNU make 工具來檢查整個系統的文件和調用 gcc 工具以及腳本完成編譯源代碼生成 image 等操作。要了解整個編譯系統,我們首先要了解 Linux 內核的 Makefile 文件。
Linux 的 編譯系統包括 5 個部分
Makefile 頂層的 Makefile 文件
.config 內核配置文件
arch/$(ARCH)/Makefile 平臺 Makefile 文件
scripts/Makefile.* 腳本規則
kbuild Makefiles 大概 500 多個其他的 Makefile 文件
Makefile
查看版本
在內核源代碼的根目錄有一個 Makefile 文件,這是編譯內核的入口,不管執行配置還是編譯,make 命令首先讀取這個文件。這個文件首先指明瞭內核的版本: 我們這裡是 3.10
VERSION = 3
PATCHLEVEL = 10
SUBLEVEL = 0
EXTRAVERSION =
NAME = Unicycling Gorilla
處理參數
然後處理 command line ,一共有 5 個 command line
V : 設定編譯時,輸出信息的等級,例如你可以用 make V=1, 查看編譯時執行的所有命令,包括 gcc 參數都會打印出來
C : 代碼檢查,使用 sparse,檢查源文件。
M : 指定不在當前目錄(外部模塊)的編譯,也可以指定當前目錄的子目錄,那麼將只會編譯子目錄的內容
O :指定編譯生成的目標文件位置,當設置了 O 參數,內核生成的 obj 和 builtin 文件都會按照目錄結構組織到 O 參數指定的目錄裡面
W: 使能外部 gcc 檢查
這幾個命令參數,在特定的情況下,將會非常有用,比如我們想編譯一個單獨的模塊就經常使用 M 參數,用 M 指定模塊的路徑,make 的時候將會不編譯整個內核,而編譯我們需要的模塊:(M 參數會覆蓋 KBUILD_EXTMOD 變量)
make M=drivers/misc/
LD drivers/misc/eeprom/built-in.o
CC [M] drivers/misc/eeprom/eeprom_93cx6.o
LD drivers/misc/built-in.o
Building modules, stage 2.
MODPOST 1 modules
CC drivers/misc/eeprom/eeprom_93cx6.mod.o
LD [M] drivers/misc/eeprom/eeprom_93cx6.ko
O
參數的指定,會改變整個編譯出來的文件的結構,例如哦我們有多個平臺要編譯,你就需要為每個平臺 clone 一份內核代碼了,只需要設置不同的輸出路徑即可:
make O=atmel, make O=asus (O 參數會覆蓋 KBUILD_OUTPUT 變量),相應的文件也會生成在目標路徑下,例如 uImage 就在 atmel/arch/arm/boot/uImage
獲取信息
接下來系統就會獲取交叉編譯環境和選擇不同的 gcc 和 bin 工具集
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
arch 變量設置目標平臺, cross compile 設置交叉編譯鏈。
偽目標
當系統信息獲取成功,就可以執行編譯命令了,每一個偽目標都可以作為一個編譯命令:(大概有 40 個左右的偽目標),但是我們會使用到的並沒有這麼多,可以用 make help 查看我們使用的編譯命令:
make help
Cleaning targets:
clean - Remove most generated files but keep the config and
enough build support to build external modules
mrproper - Remove all generated files + config + various backup files
distclean - mrproper + remove editor backup and patch files
Configuration targets:
config - Update current config utilising a line-oriented program
nconfig - Update current config utilising a ncurses menu based program
menuconfig - Update current config utilising a menu based program
xconfig - Update current config utilising a QT based front-end
gconfig - Update current config utilising a GTK based front-end
oldconfig - Update current config utilising a provided .config as base
localmodconfig - Update current config disabling modules not loaded
localyesconfig - Update current config converting local mods to core
silentoldconfig - Same as oldconfig, but quietly, additionally update deps
defconfig - New config with default from ARCH supplied defconfig
savedefconfig - Save current config as ./defconfig (minimal config)
allnoconfig - New config where all options are answered with no
allyesconfig - New config where all options are accepted with yes
allmodconfig - New config selecting modules when possible
alldefconfig - New config with all symbols set to default
randconfig - New config with random answer to all options
listnewconfig - List new options
olddefconfig - Same as silentoldconfig but sets new symbols to their default value
Other generic targets:
all - Build all targets marked with [*]
* vmlinux - Build the bare kernel
* modules - Build all modules
modules_install - Install all modules to INSTALL_MOD_PATH (default: /)
firmware_install- Install all firmware to INSTALL_FW_PATH
(default: $(INSTALL_MOD_PATH)/lib/firmware)
dir/ - Build all files in dir and below
dir/file.[oisS] - Build specified target only
dir/file.lst - Build specified mixed source/assembly target only
(requires a recent binutils and recent build (System.map))
dir/file.ko - Build module including final link
modules_prepare - Set up for building external modules
tags/TAGS - Generate tags file for editors
cscope - Generate cscope index
gtags - Generate GNU GLOBAL index
kernelrelease - Output the release version string
kernelversion - Output the version stored in Makefile
headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH
(default: /media/android/jiangxd/workspace/Miura/kernel/usr)
Static analysers
checkstack - Generate a list of stack hogs
namespacecheck - Name space analysis on compiled kernel
versioncheck - Sanity check on version.h usage
includecheck - Check for duplicate included header files
export_report - List the usages of all exported symbols
headers_check - Sanity check on exported headers
headerdep - Detect inclusion cycles in headers
coccicheck - Check with Coccinelle.
Kernel packaging:
rpm-pkg - Build both source and binary RPM kernel packages
binrpm-pkg - Build only the binary kernel package
deb-pkg - Build the kernel as a deb package
tar-pkg - Build the kernel as an uncompressed tarball
targz-pkg - Build the kernel as a gzip compressed tarball
tarbz2-pkg - Build the kernel as a bzip2 compressed tarball
tarxz-pkg - Build the kernel as a xz compressed tarball
perf-tar-src-pkg - Build perf-3.10.0.tar source tarball
perf-targz-src-pkg - Build perf-3.10.0.tar.gz source tarball
perf-tarbz2-src-pkg - Build perf-3.10.0.tar.bz2 source tarball
perf-tarxz-src-pkg - Build perf-3.10.0.tar.xz source tarball
Documentation targets:
Linux kernel internal documentation in different formats:
htmldocs - HTML
pdfdocs - PDF
psdocs - Postscript
xmldocs - XML DocBook
mandocs - man pages
installmandocs - install man pages generated by mandocs
cleandocs - clean all generated DocBook files
Architecture specific targets (arm):
* zImage - Compressed kernel image (arch/arm/boot/zImage)
Image - Uncompressed kernel image (arch/arm/boot/Image)
* xipImage - XIP kernel image, if configured (arch/arm/boot/xipImage)
uImage - U-Boot wrapped zImage
bootpImage - Combined zImage and initial RAM disk
(supply initrd image via make variable INITRD=<path>)
* dtbs - Build device tree blobs for enabled boards
install - Install uncompressed kernel
zinstall - Install compressed kernel
uinstall - Install U-Boot wrapped compressed kernel
Install using (your) ~/bin/installkernel or
(distribution) /sbin/installkernel or
install to $(INSTALL_PATH) and run lilo
內容非常之多。這裡只介紹幾個常用的:
make menuconfig 圖形化配置 config
make uImage 編譯生成 uImage
make clean 刪除大部分生成的文件,但是保留配置,以便可以編譯模塊
make distclean 刪除所有生成的文件,補丁和配置,以及一些備份文件
make mrproper 刪除所有生成的文件,補丁和配置
總的來說,頂層 Makefile 文件讀取 config 文件生成 Linux 的兩大目標文件 vmlinux 和 模塊文件