嵌入式開發實作(Linux核心編譯及安裝)部分內容譯自《Embedded Linux kernel and driver development
》by Michael Opdenacker劉建文(http://blog.csdn.net/keminlau
)
KEY:Linux 核心編譯 核心配置 嵌入式
核心配置(Kernel configuration)Makefile版本修改
為了區別基於同一源碼構建(bulid)的不核心鏡像,可使用變數EXTRAVERSION(定義位於makefile的頂部):
$ head -4 makefile<br />VERSION = 2<br />PATCHLEVEL = 6<br />SUBLEVEL = 7<br />EXTRAVERSION = -acme1
運行“uname --r”會返回: 2.6.7--acme1
核心配置
先定義核心需要什麼特性,並進行配置。核心構建系統(The kernel build system)遠不是簡單用來構建整個核心和模組,想瞭解更多的進階核心構建選項,你可以查看 Documentation/kbuild 目錄內的核心文檔。
可用的配置命令和方式:
- make xconfig
- make menuconfig
- make oldconfig
- 或者 手動編寫
核心設定檔.config與核心編譯makefile?
核心是利用make編譯並安裝的一個C程式。而這個C程式很現代很複雜,僅憑單一個makefile難以完成編譯任務。假設核心編譯只需要一個makefile,這個makefile具體也會因編譯不同功能特性的核心而有所不同,也就是說在編譯核心先“編譯”編譯的所需要的makefile,這個makefile是動態產生的。那麼這個動態makefile從何而來呢?答案是config命令通過讀取[核心設定檔
](kernel configuration file)來產生編譯核心所需要所有檔案(包括makefile);那[核心設定檔
]又是哪來的呢?還是make產生的,各種make的config(xconfig/menuconfig)會產生所需要的[核心設定檔
]。
核心設定檔(kernel configuration file)儲存為核心原始碼的頂層目錄的.config檔案。發行版的核心設定檔通常在/boot/內。
命令:make xconfig
- qconf: 全新的基於QT的配置介面,2.6版本核心
- 更易使用(切記閱讀 help -> introduction: useful options!)
- 具有檔案瀏覽功能,更易的載入設定檔
命令:make menuconfig
- 老式字元介面,依然很管用。你夠自信,完全可以手寫設定檔!
命令:make oldconfig
- 用於升級早期發布核心的設定檔
- 對一些絕對符號(obsolete symbols)發出警告
- 詢問新符號的配置值
何為makefile?
makefile包含用以構建應用程式的一組規則集(set of rules)。並且第一條[規則
]是特殊的[規則
],叫[預設規則
](default rule)。一條[規則]由三部分組成:目標(target)、前提條件(prerequisites)和命令動作(command):
target: prereq1 prereq2<br />[tab]commands
[目標
]是被構建(made)的[檔案
]或其它東西。[前提條件
]或者叫依賴(dependents)是構建目標的“材料”。而[命令動作
]是利用[前提條件
]構建[目標
]的shell命令。
以下是編譯C源碼的規則例子:
foo.o: foo.c foo.h<br />[tab]gcc -c foo.c
注意格式,冒號前是[目標
],後是[前提條件
];[命令
]在第二行,並且開始於一個tab字元。
編譯核心編譯和安裝核心
編譯步驟:
$ cd /usr/src/linux2.6<br />$ make
安裝步驟 (logged as root!)
$ make install<br />$ make modules_install
以下的步驟在2.6版本不再使用:
$ make depends<br />$ make modules (done by make)
提升編譯速度
多花一些時間在核心配置上,並且只編譯那些你硬體需要的模組。這樣可以把編譯時間縮短為原來的1/30,並且節省數百MB的空間。另外,你還可以並行編譯多個檔案:
$ make -j <number>
make 可以並存執行多個目標(target)(KEMIN:前提是目標規則間沒有交叉依賴項,這個怎麼做到的?)
$ make -j 4
- 即便是在單一處理器的工作站上也會很快,讀寫檔案的時間被節省下來了。多線程讓CPU保持忙碌。
- number大於4不見得有效了,因為環境切換過多反而降低的工作的速度。
- make -j <4*number_of_processors>
核心編譯tips
- 查看完整的 (gcc, ld)命令列: $ make V=1
- 清理所有的組建檔案 (to create patches...): $ make mrproper
- 部分編譯:$ make M=drivers/usb/serial
- 單獨模組編譯:$ make drivers/usb/serial/visor.ko
- 別處編譯(假設源碼在CDROM):
- $ cd /mnt/cdrom/linux-2.6.17.11
- $ make O=~/linux/linux-2.6.17.11
最終產生的檔案
- vmlinux 原始核心鏡像,非壓縮的
- arch/<arch>/boot/zImage zlib壓縮的核心鏡像(Default image on arm)
- arch/<arch>/boot/bzImage bzip2壓縮的核心鏡像。通常很小,足夠放入一張磁碟片(Default image on i386)
安裝的檔案
- /boot/vmlinuz-<version> 核心鏡像;
- /boot/System.map-<version> 儲存有核心的符號地址(symbol addresses);
- /boot/initrd-<version>.img Initial RAM disk:儲存有你需要在引導時掛接最終根檔案系統的模組。安裝命令“make install”為替你運行“mkinitrd ”產生initrd;
- /etc/grub.conf or /etc/lilo.conf
- bootloader的設定檔:“make install”會為你的新核心更新相應的bootloader的設定檔。如果你使用的是LILO,它會在組建組態檔案後,執行/sbin/lilo,讓LILO的配置生效。
- /lib/modules/<version>/ Kernel modules + extras
- build/
為本<version>的核心添加模組所需的所有東西: .config file (build/.config), module symbol information (build/module.symVers), kernel headers (build/include/)
- kernel/
核心模組檔案 .ko (Kernel Object),目錄結構與原始碼目標一一對應。
- modules.alias
模組別名記錄(用於insmod和modprobe),例如:
alias sound--service--?-0 snd_mixer_oss
- modules.dep
模組依賴記錄(用於insmod和modprobe)
- modules.symbols
標識某符號是屬於哪個模組的。
這個目錄的所有檔案都是文字檔,可以直接查看。
小結編譯及安裝步驟:
- 編輯Makefile版本資訊
- 定義核心特性,組建組態檔案.config,用於編譯:make xconfig
- 編譯核心:make
- 安裝核心:make install
- 安裝模組:make modules_install
交叉編譯核心Makefile修改
通常通過修改已有的makefile獲得
你必須修改目標平台,假設目標平台是ARM,修改以下:
ARCH ?= arm<br />CROSS_COMPILE ?= arm-linux-
或運行帶參數的make:
$ cd /usr/scr/linuxXX<br />$ make ARCH=arm CROSS_COMPILE=arm-linux-
核心設定檔
配置過程和本地配置一樣;
可以把產生的設定檔(.config)分享給其他人,比如像:
$<br />$ cp .config arch/<arch>/config/acme_defconfig
這樣其他同樣開發ACME系統的開發人員可以通過以下命令編譯出同樣的核心:
$ make acme_defconfig<br />$
建立交叉編譯環境(Cross--compiling setup)
假設你有ARM的交叉編譯工具(cross--compiling toolchain)在 in /usr/local/arm/3.3.2/, 你得把它輸出到PATH:
$ export PATH=/usr/local/arm/3.3.2/bin:$PATH
注意查看核心文檔(在Documentation/Changes)有關最低工具版本要求。
編譯並安裝核心
1. $ make //如果你修改了Makefile
或者
1'. $ make ARCH=arm CROSS_COMPILE=arm-linux-
2. 拷貝 arch/<platform>/boot/zImage 到目標系統
$ make modules_install
3. 拷貝 /lib/modules/<version> 到目標系統
你可以通過 arch/<arch>/boot/install.sh 自訂安裝,讓”make install“自動代勞。
何為交叉編譯工具鏈(cross--compiling toolchain)?
有如任何其它開發活動一般,嵌入式開發的第一步是建立(setting up)用於構建嵌入式Linux核心(當然包括驅動程式)及應用程式的工具鏈(toolchains )。不過,嵌入式開發需要是跨平台工具鏈。跨平台是什麼意思呢?一般開發活動是在本地編譯,使用是本地的工具鏈;而由於嵌入式的軟硬資源(記憶體不足、沒有本地編譯器或作業系統都沒有)限制等沒法進行本地開發。需要在Linux-x86 主機(HOST)開發,使用主機的編譯器產生目標(TARGET)平台代碼,這個過程叫交叉編譯。
我們常常說的編譯器有廣義和狹義之分。狹義的編譯器只完軟體編譯(或者叫軟體構建)的第一步;廣義的編譯器包括了軟體編譯(或者叫軟體構建)所需要程式碼程式庫(比如libc)和其它構建工具(比如彙編器和連接器)。無論是什麼編譯器都需要支援的程式碼程式庫和各種構建工具,交叉編譯也不例外。一整套廣義的編譯器稱為交叉編譯工具鏈。
何為工具鏈?
In software, a toolchain is the set of computer programs (tools) that are used to create a product (typically another computer program or system of programs). The tools may be used in a chain, so that the output of each tool becomes the input for the next, but the term is used widely to refer to any set of linked development tools.
A simple software development toolchain consists of a text editor for editing source code, a compiler and linker to transform the source code into an executable program, libraries to provide interfaces to the operating system, and a debugger.
The GNU toolchain is a blanket term for a collection of programming tools produced by the GNU Project. These tools form a toolchain (suite of tools used in a serial manner) used for developing applications and operating systems.
Projects included in the GNU toolchain are:
- * GNU make: Automation tool for compilation and build;
- * GNU Compiler Collection (GCC): Suite of compilers for several programming languages;
- * GNU Binutils: Suite of tools including linker, assembler and other tools;
- * GNU Bison: Parser generator
- * GNU m4: m4 macro processor
- * GNU Debugger (GDB): Code debugging tool;
- * GNU build system (autotools):
- o Autoconf
- o Autoheader
- o Automake
- o Libtool
參考
- http://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/