2012年10月5日 星期五

編譯 ARM Linux 核心

編譯 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 開機。


沒有留言:

張貼留言