編譯 ARM Linux 核心
檔案位置:
~/qemu_image/ -> 所有虛擬 ARM 檔案目錄
/kernel/ -> 編譯 ARM Linux 核心目錄
/modules -> 編譯 ARM Linux 核心模組目錄
0. 判別我們所要使用之 ARM CPU
我們的模擬目標為 Beagle Board,其 CPU 為 OMAP 3530,有關 Beagle Board 的詳細規格可以參考官方網站 (http://beagleboard.org/),而 OMAP 3530 是由德洲儀洲所生產之 ARM CPU,其資料可以參考德儀網站 (http://www.ti.com/product/omap3530?247SEM)。
OMAP 3530 是一顆 Cortex A8 的 ARM CPU,目前已被 Qemu ARM 完整支援,我們可以使用
qemu-system-arm -cpu ?
來觀看 Qemu ARM 版所支援之 CPU 清單,如下所示:
Available CPUs:
arm1026
arm1136
arm1136-r2
arm1176
arm11mpcore
arm926
arm946
cortex-a15
cortex-a8
cortex-a9
cortex-m3
pxa250
pxa255
pxa260
pxa261
pxa262
pxa270
pxa270-a0
pxa270-a1
pxa270-b0
pxa270-b1
pxa270-c0
pxa270-c5
sa1100
sa1110
ti925t
any
因此我們可以使用 Qemu 來模擬 beagle board 平台,底下將介紹如何編譯 Linux 核心:
1. 下載 & 解壓縮
請切換至 ~/qemu_image/kernel 目錄,進行底下操作:
wget ftp://ftp.twaren.net/pub/Unix/Kernel/linux/kernel/v3.x/linux-3.2.30.tar.xz
tar xfva linux-3.2.30.tar.xz
此時會出現 linux-3.2.30 目錄
2. 設定編譯參數
cd linux-3.2.30
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- omap2plus_defconfig
** ARM 版之核心設定參數檔在 linux-3.2.30/arch/arm/configs 目錄 **
此時會出現以下訊息:
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
這表示我們已經完成基本參數設定,接著我們要作細部微調。請執行:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
如果出現底下錯誤的話,表示我們還沒有安裝 libncurses5-dev 這個函式庫:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
***
*** Install ncurses (ncurses-devel) and try again.
***
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2
請以底下指令安裝 libncurses5-dev 函式庫:
apt-get install libncurses5-dev
然後再重新執行底下指令即可:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
請設定以下部份:
General setup ---> Kernel compression mode (Gzip) --->XZ
System Type ---> TI OMAP2/3/4 Specific Features --->
[*] OMAP3 BEAGLE board
[*] DEVKIT8000 board
File systems --->
<*> The Extended 4 (ext4) filesystem
設定完畢後請跳出 Linux 設定畫面,如此一來我們即完成 Linux 核心設定。
3. 編譯核心及核心模組
a. 編譯核心
time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage -j 4
假設在編譯時有底下訊息:
make: arm-linux-gnueabi-gcc: Command not found
scripts/kconfig/conf --silentoldconfig Kconfig
make: arm-linux-gnueabi-gcc: Command not found
WRAP arch/arm/include/generated/asm/auxvec.h
WRAP arch/arm/include/generated/asm/bitsperlong.h
WRAP arch/arm/include/generated/asm/cputime.h
WRAP arch/arm/include/generated/asm/emergency-restart.h
WRAP arch/arm/include/generated/asm/errno.h
WRAP arch/arm/include/generated/asm/ioctl.h
WRAP arch/arm/include/generated/asm/irq_regs.h
WRAP arch/arm/include/generated/asm/kdebug.h
WRAP arch/arm/include/generated/asm/local.h
WRAP arch/arm/include/generated/asm/local64.h
WRAP arch/arm/include/generated/asm/percpu.h
WRAP arch/arm/include/generated/asm/poll.h
WRAP arch/arm/include/generated/asm/resource.h
WRAP arch/arm/include/generated/asm/sections.h
WRAP arch/arm/include/generated/asm/siginfo.h
WRAP arch/arm/include/generated/asm/sizes.h
CHK include/linux/version.h
UPD include/linux/version.h
HOSTCC scripts/dtc/checks.o
HOSTCC scripts/dtc/data.o
SHIPPED scripts/dtc/dtc-lexer.lex.c
SHIPPED scripts/dtc/dtc-parser.tab.h
SHIPPED scripts/dtc/dtc-parser.tab.c
HOSTCC scripts/dtc/dtc.o
HOSTCC scripts/dtc/flattree.o
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
Generating include/generated/mach-types.h
CC kernel/bounds.s
/bin/sh: 1: arm-linux-gnueabi-gcc: not found
make[1]: *** [kernel/bounds.s] Error 127
make: *** [prepare0] Error 2
make: *** Waiting for unfinished jobs....
HOSTCC scripts/dtc/fstree.o
HOSTCC scripts/dtc/livetree.o
HOSTCC scripts/genksyms/genksyms.o
HOSTCC scripts/dtc/srcpos.o
HOSTCC scripts/dtc/treesource.o
SHIPPED scripts/genksyms/lex.lex.c
SHIPPED scripts/genksyms/keywords.hash.c
SHIPPED scripts/genksyms/parse.tab.h
SHIPPED scripts/genksyms/parse.tab.c
HOSTCC scripts/genksyms/lex.lex.o
HOSTCC scripts/dtc/util.o
HOSTCC scripts/dtc/dtc-lexer.lex.o
HOSTCC scripts/dtc/dtc-parser.tab.o
HOSTCC scripts/genksyms/parse.tab.o
HOSTLD scripts/dtc/dtc
CC scripts/mod/empty.o
/bin/sh: 1: arm-linux-gnueabi-gcc: not found
make[2]: *** [scripts/mod/empty.o] Error 127
make[1]: *** [scripts/mod] Error 2
make[1]: *** Waiting for unfinished jobs....
HOSTLD scripts/genksyms/genksyms
make: *** [scripts] Error 2
real 0m3.743s
user 0m4.576s
sys 0m0.304s
上面錯誤訊息是因為 arm-linux-gnueabi-gcc 這個指令找不到,我們可以切換至 /usr/bin 目錄來觀察 gcc cpp g++ 三個指令,如下所示:
root@debian:/usr/src# cd /usr/bin
root@debian:/usr/bin# ls -l arm-linux-gnueabi-gcc-4.7 arm-linux-gnueabi-cpp-4.7 arm-linux-gnueabi-g++-4.7
-rwxr-xr-x 1 root root 559672 10月 12 2012 arm-linux-gnueabi-cpp-4.7
-rwxr-xr-x 1 root root 562936 10月 12 2012 arm-linux-gnueabi-g++-4.7
-rwxr-xr-x 1 root root 558840 10月 12 2012 arm-linux-gnueabi-gcc-4.7
這個錯誤是因為編譯指令要的是 arm-linux-gnueabi-gcc、arm-linux-gnueabi-cpp 以及 arm-linux-gnueabi-g++ 三個檔案,而目前系統沒有,因此我們要手動建立連結:
root@debian:/usr/bin# ln -s arm-linux-gnueabi-cpp-4.7 arm-linux-gnueabi-cpp
root@debian:/usr/bin# ln -s arm-linux-gnueabi-g++-4.7 arm-linux-gnueabi-g++
root@debian:/usr/bin# ln -s arm-linux-gnueabi-gcc-4.7 arm-linux-gnueabi-gcc
接著再執行剛剛沒有成功的指令來編譯核心:
time make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage -j 4
若是編譯過程中出現底下錯誤:
SHIPPED arch/arm/boot/compressed/ashldi3.S
AS arch/arm/boot/compressed/lib1funcs.o
AS arch/arm/boot/compressed/ashldi3.o
AS arch/arm/boot/compressed/piggy.xzkern.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
"mkimage" command not found - U-Boot images will not be built
make[1]: *** [arch/arm/boot/uImage] Error 1
make: *** [uImage] Error 2
這表示編譯程式找不到 mkimage 這個指令,我們可以上 packages.debian.org 來查詢,得知此檔案在 u-boot-tools 套件中,因此要再安裝 u-boot-tools 套件,然後再下編譯指令。編譯完畢後會出現以下訊息,告訴我們 uImage 已經編譯完成。
Image Name: Linux-3.2.30
Created: Fri Oct 5 15:43:49 2012
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2475104 Bytes = 2417.09 kB = 2.36 MB
Load Address: 0x80008000
Entry Point: 0x80008000
Image arch/arm/boot/uImage is ready
我們可以執行底下指令來看 /arch/arm/boot/uImage 的屬性:
file arch/arm/boot/uImage
其輸出如底下所示:
file uImage
uImage: u-boot legacy uImage, Linux-3.2.30, Linux/ARM, OS Kernel Image (Not compressed), 2475104 bytes, Fri Oct 5 15:43:49 2012, Load Address: 0x80008000, Entry Point: 0x80008000, Header CRC: 0x3A120CB2, Data CRC: 0x1508ED43
b. 編譯核心模組
核心要正常工作必須要有相對應的核心模組,否則無法載入驅動程式,
# Compile Kernel Modules
time make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules -j $CPU_CORE
# Install Kernel Modules
time make -s ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- modules_install INSTALL_MOD_PATH=../modules/ -j $CPU_CORE
cd ../modules
time tar cfa ../modules-$KERNEL_VERSION.tar.xz lib
編譯完成後我們會有一個名為 modules-核心編號.tar.xz 的檔案,此檔案可以用來取代原始 rootfs 中 /lib/modules 目錄中舊版的驅動核心模組。因此我們必須將舊版驅動核心模組移除,再放入我們剛剛編完之驅動核心模組。
4. 準備虛擬 SD card -> 請看講義
5. 將 /dev/loop1 掛載至 /mnt/sdcard1 目錄
mount /dev/loop1 /mnt/sdcard1
將以下檔案複製至 /mnt/sdcard1 目錄:
-rwxr-xr-x 1 root root 45444 2012-10-05 16:52 MLO
-rwxr-xr-x 1 root root 1370958 2012-10-05 16:52 u-boot
-rwxr-xr-x 1 root root 344872 2012-10-05 16:52 u-boot.bin
-rwxr-xr-x 1 root root 344936 2012-10-05 16:52 u-boot.img
-rwxr-xr-x 1 root root 2475168 2012-10-05 16:54 uImage
6.
qemu-system-arm -M beagle -m 256 -nographic -sd sdcard.img
此時即可看到 qemu 使用虛擬 sdcard 開機。