一. 前言
面向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將不必要的代碼去掉以減少可執行文件大小等。這些工具在嵌入式開發初期,尤其是移植調試操作系統時非常有用。
安裝的步驟:
-
下載安裝包文件: binutils-2.11.2.tar.gz;
-
解開安裝包到當前目錄下:
tar zxf binutils-2.11.2.tar.gz,此時在當前目錄下生成一個 binutils-2.11.2目錄。 -
配置安裝包:./configure --target=arm-linux --prefix=/usr/local
target 選項表示選定的目標代碼格式,一般是 arm-linux,prefix 表示在執行 make install 時的安裝根路徑。 -
編譯和安裝:make、make install
注意安裝時可能需要 root 權限,在prefix目錄下當前用戶有寫權限,安裝成功後,binutils工具將安裝在/usr/local/arm-linux 目錄下。
1.2.2. gcc 交叉編譯器
gcc 是用來編譯內核代碼的工具,使用它可以編譯彙編語言和C語言的程序,生成ARM的代碼。建議使用gcc 2.95以上的版本來創建ARM開發環境,本文使用2.95.3版本。
安裝的步驟:
-
下載安裝包文件和補丁程序:gcc-2.95.3.tar.gz;gcc-2.95.3.diff.bz2
-
解開安裝包到當前目錄下:
tar zxf gcc-2.95.3.tar.gz,此時在當前目錄下生成一個 gcc-2.95.3 目錄,進入該目錄。 -
對當前的安裝包打補丁:
bzcat …/gcc-2.95.3.diff.bz2 | patch -p1。 -
修改 gcc/config/arm/t-linux 文件,在文件最後加上如下條件編譯選項:
T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h。 -
配置安裝包:./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,以支持其他語言。
- 安裝編譯好的工具: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 的內核配置與編譯
-
解開安裝包:tar zxf glibc-2.2.3.tar.gz。
此時在當前目錄下生成一個 glibc-2.2.3 目錄,進入該目錄。 -
解開glibc-linuxthreads安裝包: tar zxvf …/glibc-linuxthreads-2.2.3.tar.gz
-
設置編譯器: CC=arm-linuxgcc
-
配置安裝包: ./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下的庫覆蓋掉,需要非常留意。 -
編譯和安裝: make; make install
安裝成功後,glibc 庫將安裝在/usr/local/arm-linux 目錄下。
-
製作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