移植Linux內核到ARM上 的移植過程及分析

一. 前言
面向A R M 微處理器構架的嵌入式操作系統的使用量將在今後五年持續增長,在各種嵌入式操作系統中,Linux是獲得支持最多的第三大力量。

  目前,ARM Linux 支持包括A R M 6 1 0 、A R M 7 1 0、A R M 7 2 0 Tcores、ARM920T cores、StrongARM110、StrongARM 1100、XScale 等系列的 ARM 處理器。這些處理器都具有M M U 單元,與之相對應是NO MMU 的uClinux,主要是支持ARM7TDMI 系列的微處理器。在ARM Linux 的基礎上,很多開發者將其移植到了自己的硬件平臺上,並提交相應的 Machine Type。

本文以實例分析完整地介紹了移植的過程,對於準備在 ARM Linux 上做應用開發的技術人員有一定的借鑑作用。

二. ARM Linux 的移植過程

將ARM Linux 移植到特定的硬件平臺上,大致需要分成四個步驟:
1)首先是準備工作,包括下載源碼、建立交叉編譯環境等;
2)然後是配置和編譯內核,必要時還要對源碼做一定的修改;
3)第三步就是需要製作 RAM disk 來掛接根文件系統;
4)最後是下載、調試內核並在 RAM disk中添加自己的應用程序。

本文以StrongARM 爲例,說明如何將 ARM Linux 移植到 SA1110 微處理器上。
下面分四個部分介紹移植工作:

1.內核源碼及交叉編譯環境的準備
2.ARM Linux 的內核配置與編譯
3.製作RAM Disk
4.內核下載和運行

1.內核源碼交叉編譯環境和準備

1.1 內核源碼下載

 標準Linux 的內核源碼可以從ftp://ftp.kernel.org 下載,在很多的鏡像ftp 站點上也可以方便地獲得,建議使用 2.4 版本的內核。ARM Linux 是基於標準Linux、內核爲ARM 做的補丁,在ftp://ftp.arm.linux.org.uk上可以下載。當然也可以直接下載已經針對標準內核打好補丁的ARM Linux源碼包,例如 SkyEye 上提供的 linux-2.4.18-rmk7.tar.bz2,就是基於 2.4.18內核和 rmk7 補丁,可以直接解壓之後進行編譯。

1.2 交叉編譯環境的建立

 移植前需要在宿主機上建立ARM 的交叉編譯環境,主要用到的開發工具包括三個部分:binutils、gcc、glibc。其中,binutils 是二進制文件的處理工具;gcc 是編譯工具;glibc 是鏈接和運行庫。所有需要用到的工具既可以下載源碼自行編譯,也可以直接下載已經編譯好的二進制工具。

1.2.1. binutils 的安裝

 binutils主要包含了一些輔助開發工具,例如objdump顯示反彙編碼、nm列出符號表、readelf顯示elf文件信息及段信息、strip將不必要的代碼去掉以減少可執行文件大小等。這些工具在嵌入式開發初期,尤其是移植調試操作系統時非常有用。

安裝的步驟:

  1. 下載安裝包文件: binutils-2.11.2.tar.gz;

  2. 解開安裝包到當前目錄下:
    tar zxf binutils-2.11.2.tar.gz,此時在當前目錄下生成一個 binutils-2.11.2目錄。

  3. 配置安裝包:./configure --target=arm-linux --prefix=/usr/local
    target 選項表示選定的目標代碼格式,一般是 arm-linux,prefix 表示在執行 make install 時的安裝根路徑。

  4. 編譯和安裝:make、make install
    注意安裝時可能需要 root 權限,在prefix目錄下當前用戶有寫權限,安裝成功後,binutils工具將安裝在/usr/local/arm-linux 目錄下。

1.2.2. gcc 交叉編譯器

 gcc 是用來編譯內核代碼的工具,使用它可以編譯彙編語言和C語言的程序,生成ARM的代碼。建議使用gcc 2.95以上的版本來創建ARM開發環境,本文使用2.95.3版本。

安裝的步驟:

  1. 下載安裝包文件和補丁程序:gcc-2.95.3.tar.gz;gcc-2.95.3.diff.bz2

  2. 解開安裝包到當前目錄下:
    tar zxf gcc-2.95.3.tar.gz,此時在當前目錄下生成一個 gcc-2.95.3 目錄,進入該目錄。

  3. 對當前的安裝包打補丁:
    bzcat …/gcc-2.95.3.diff.bz2 | patch -p1。

  4. 修改 gcc/config/arm/t-linux 文件,在文件最後加上如下條件編譯選項:
    T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h。

  5. 配置安裝包:./configure --target=arm-linux --prefix=/usr/local --with-headers=arm linux源碼目錄下的include目錄。
    這裏前兩個選項和上面binutils的安裝類似,–withheaders是用來指定內核頭文件的目錄,一般就可以使用上面ARM linux的include目錄。需要注意的是這裏的路徑需要用全路徑名,而不能使用相對路徑。

6 ) 編譯源碼:make LANGUAGE=“C ”
這裏因爲還沒有一個ARM可用的glibc,所以只能編譯C 語言的交叉編譯工具。如果在編譯好 glibc 之後,就可以回來重新編譯gcc,以支持其他語言。

  1. 安裝編譯好的工具:make install LANGUAGE=“C”
    安裝成功以後,arm-elf-gcc將安裝在/usr/local/arm-linux目錄下。有了安裝好的binutils和gcc工具,就可以用來編譯ARM Linux內核了。如果需要在ARM Linux 做應用程序的開發,就還需要一個glibc庫的支持。

1.2.3. glibc 庫

   glibc 的編譯需要爲剛纔做好的ARM 交叉編譯器指定編譯器;否則編譯出的glibc代碼將會是同時有ARM和 x86代碼的混和體。

2.ARM Linux 的內核配置與編譯

  1. 解開安裝包:tar zxf glibc-2.2.3.tar.gz。
    此時在當前目錄下生成一個 glibc-2.2.3 目錄,進入該目錄。

  2. 解開glibc-linuxthreads安裝包: tar zxvf …/glibc-linuxthreads-2.2.3.tar.gz

  3. 設置編譯器: CC=arm-linuxgcc

  4. 配置安裝包: ./configure arm-linux --build=i586-linux --prefix=/usr/local/arm-linux -enable-add-ons
    arm-linux 表示選 ELF 格式的可執行格式,–build=i586-linux 表示用來製作交叉開發環境的宿主機的機器類型,–prefix=/usr/local/armlinux表示安裝的路徑,這裏不能指定爲/usr/local,否則會把 /usr/local下的庫覆蓋掉,需要非常留意。

  5. 編譯和安裝: make; make install
    安裝成功後,glibc 庫將安裝在/usr/local/arm-linux 目錄下。

  1. 製作RAM disk(RamDisk也就是內存盤的意思)
    所謂的RAM disk,實際上是把系統內存劃出一部分當作硬盤使用。對於操作系統來講內存的存取速度遠遠大於機械磁盤,所以RAM驅動器肯定要比機械的硬盤快得多。你可以把整個應用程序都安裝在RamDisk的驅動器中,然後用內存的速度運行它.

    ARM Linux採用RAM disk的方式來裝載根文件系統,所有在運行內核之前,需要先製作RAM disk,將必須的文件和設備加入到RAM disk中,當內核啓動後,會從指定地址去讀取根文件系統,這裏我們使用RAM disk,在內存中虛擬一個磁盤,具體方法如下:

1)首先創建一個512k的虛擬磁盤,文件名爲initrd.img:
dd if=/dev/zero of=initrd.img bs=1k count=512

2)將虛擬磁盤文件格式化成ext2文件系統格式:
mkfs.ext2 -c initrd.img
這就生成了一個支持ext2文件系統的ramdisk

3)添加文件和設備
mount這個文件系統到/tmp下,mount -o loop -t ext2 initrd.img /tmp

4)向/tmp中添加linux啓動必須的文件和設備
/bin/sh
/bin/init
/dev/console
/etc/rc
/etc/motd
以上這幾個程序和設備是啓動Linux必須的,這樣得到的ram disk大約是400k。

代碼:針對這幾個目錄的解釋(感謝david的蒐集整理)
.
/bin/sh (/bin/sh是一個SHELL,用來啓動系統時執行很多腳本程序的)
/bin/init init進程的啓動程序,在覈內引導完成後,LINUX KERNEL都會執行/sbin/init,/etc/init or /bin/init
/dev/console 是系統控制終端,可以理解爲console指向激活的那個tty(準確地說是激活的那個tty纔將輸出顯示到console)
/etc/rc 當改變服務的運行級別時,此文件負責啓動/停止服務
/etc/motd 在管理員希望向 Linux 服務器的所有用戶傳達某個消息時使用,比如登陸時會打印出來 這裏面的內容

4.內核的下載和執行
4.1.內核下載
內核的下載一般通過bootloader來完成的,當然也可以通過修改arch/arm/Makefile文件來設置自己的TEXTADDR;TEXTADDR的值在make時傳遞給arch/arm/vmlinux.lds,在鏈接時,arm-linux-ld將使用vmlinux.lds來定位內核的起始地址。

如果是壓縮的內核,則可以在make menuconfig時,選擇General setup->
Compressed boot loader in ROM/flash
(0) Compressed ROM boot loader base address
(c0000000) Compressed ROM boot loader BSS address

這裏缺省的Compressed ROM boot loader base address是0。

4.2. RAM disk下載

 RAM disk的下載也是通過bootloader來完成的,它的下載底子好是在內核源碼文件arch/arm/machsa1100/assaber.c中定義的,在fixup_addabet()函數中設置了:
 t->u.initrd.start = 0xc0800000;
   t->u.initrd.size = 3 * 1024 * 1024;

我們製作的ram disk只有512k,所以需要修改t->u.initrd.size = 512 * 1024;下載地址爲0xc0800000

4.3 內核運行
根據硬件情況修改源碼編譯之後,就可以通過bootloader下載執行了,內核運行時會通過串口向主機上的超級終端輸出啓動信息;當ARM linux啓動並進入shell之後,就可以運行用戶編寫的應用程序了,添加自己的應用一般分爲兩個步驟:
1)交叉編譯得到應用程序的可執行文件(elf格式)
2)將該可執行文件添加到ram disk中

【全文完】

原文地址:http://bbs.21ic.com/icview-303600-1-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章