天天看點

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

1.  引言

目前,在嵌入式系統裡基于ARM微核的嵌入式處理器以其功耗低,功能強大的優點已經成為市場的主流。與此同時,在網絡上發展起來的Linux作業系統,以其功能強大,開放源代碼,支援硬體種類衆多的特點,越來越受到人們的青睐。然而如何把Linux作業系統移植到ARM平台上卻成了一個重點,也是一個難點問題。

嵌入式Linux系統包括引導程式(Bootloader),核心(kernel)和根檔案系統三個部分,其開發流程如圖1所示:嵌入式Linux 移植到特定的硬體平台上,一般需要以下五個步驟:(1)前期準備包括從網站http://kernel.org上下載下傳嵌入式Linux的源碼包, 搭建交叉編譯開發環境,配置主機的開發環境等(2)配置Bootloader,并将其燒寫到目标平台的Flash上,使其能正常的啟動核心;(3)配置和編譯Linux核心,首先要對源碼進行一定的修改, 并将其移植到目标平台上,然後再根據自己的硬體資源進行裁減,使核心達到最優;(4)制作RAMDISK來挂接Linux的根檔案系統,并在 RAMDISK上添加自己的應用程式;(5)部署Linux系統使目标闆脫離交叉開發環境,直接在目标機上本地啟動運作。本文就将根據實際項目開發中一個 ARM構架的嵌入式系統為例,闡述如何移植Linux到AT91RM9200的ARM平台上。

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

2.建立交叉編譯環境

一般而言,直接在移植的目标硬體平台上編寫和調試Linux比較困難,目前一般采用的辦法是首先在通用計算機上編寫程式,然後通過交叉編譯生成目标平台上可以運作的二進制代碼格式,最後再下載下傳到目标平台上的特定位置上運作。

移植前需要在主控端上建立如圖2所示的ARM的交叉編譯環境,建立ARM的交叉編譯環境主要用到的開發工具有: binutils、gcc、glibc,其中 binutils是二進制檔案的處理工具; gcc是編譯工具, 用來編譯核心代碼的工具; glibc 是連結和運作庫。社群的開發者和一些晶片廠商已經編譯出了常用體系結構的工具鍊,使用這些工具鍊,可以大大減少工作量。交叉編譯工具的安裝步驟如下: (1)從官方站點http://arm.Linux.org.uk下載下傳cross-2.95.3.tar.bz2;

(2)在usr/local/arm下解壓:#tar -jxvf cross-2.95.3.tar.bz2;

(3)在/etc/bashrc檔案中修改PATH環境變量,加入export PATH=/usr/local/arm/2.95.3/bin:$PATH。

3. ARM Linux系統的開發

3.1 Linux啟動代碼Bootloader的移植

Bootloader是在作業系統核心運作之前運作的一段小程式。這段程式完成硬體的初始化和建立記憶體空間的映射圖等重要工作,為核心的啟動建立正确的環境,并最終啟動核心,Bootloader在Linux嵌入式系統中所處的層次位置如圖3所示。Bootloader的實作依賴于CPU的體系結構,大多數的Bootloader都分為stage 1和stage 2兩大部分,圖4為兩階段Bootloader的結構框圖。依賴于CPU體系結構的代碼,如裝置初始化代碼等,通常都放在stage 1,而且用彙編語言實作。而stage 2則通常用C語言實作,這樣可以實作複雜功能,而且有更好的可讀性和移植性。

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

圖3  Bootloader所處的層次位置

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

圖4  硬體環境的狀态

目前基于嵌入式系統的Bootloader版本很多,如Blob、Redboot、Vivi和U-Boot等,下面就以現在最流行的U-Boot為例,詳細介紹如何将它移植到自己的目标闆上。U-boot移植主要步驟如下:

首先基于自己的目标闆的硬體資源,修改或添加U-Boot源代碼的board/at91rm9200目錄中如下源碼檔案:(1)重寫FLASH的裝置控制程式flash.c , U-Boot讀、寫和删除Flash裝置的源代碼檔案。由于在不同目标闆中FLASH存儲器種類各不相同,參照自己flash的datasheet重寫 flash的裝置控制程式flash.c,該程式完成的功能包括Flash初始化、列印Flash資訊、Flash擦除和Flash寫入等操作。(2)添加memsetup.s。該彙編源碼檔案初始化時鐘、SMC控制器和SDRAM控制器。(3)添加網卡晶片DM9161E的裝置控制程式dm9161.c 和dm9161.h,程式。(4)修改Makefile檔案。對上述修改或添加的源代碼檔案編譯後,在Makefile裡面主要做如下修改: OBJS :=at91rm9200dk.c at45.o dm9161.o flash.o  SOBJS:=memsetup.o(5) U-Boot.lds ,設定U-boot中各個目标檔案的連接配接位址,基本不做修改。(6)config.mk。根據目标闆的一級boot來修改,修改後TEXT BASE=0x21f00000。[page]

其次,修改目錄include/configs的頭檔案at91rm9200dk.h,根據目标闆的資源配置,修改内容包括CPU ,系統時鐘、RAM 、Flash等配裡資訊以及記憶體映射相關參數。該頭檔案還定義了U-Boot的一些環境變量和核心啟動參數.可在U-Boot啟動後通過setenv和 saveenv指令修改。U-Boot-1.1.2版本對at91rm9200處理器提供良好的支援,是以對于目錄CPU at91rm9200中的源碼基本不做修改。在U-Boot-1.1.2的Makefile中加入如下代碼:

at91rm9200dk_config: [email protected]/mkconfig $(@: _config=) arm at91rm9200 at91rm9200dk

其中“arm”是CPU的種類,at91rm9200是ARM CPU對應的代碼目錄,at91rm9200dk是目标闆對應的目錄。由于交叉編譯器安裝在目錄/usr/local/arm,應把環境變量 CROSS_COMPILE設定成相應路徑:CROSS_COMPILE=/usr/local/arm/2.95.3 /bin/arm-linux-

最後,調試U-Boot源代碼,直到U-Boot在開發闆上能正常啟動,調試成功後,燒寫U-Boot到FLASH,燒寫完成後,複位目标闆,序列槽終端就顯示U-Boot的啟動資訊。

3.2  Linux核心的移植、配置和編譯

圖6 系統硬體框圖示準Linux核心相對于資源受限的嵌入式系統來說是過于龐大,整個代碼分布如圖5所示,是以要将其移植到嵌入式系統上,就需要将Linux核心根據目标平台的情況進行剪裁、配置,該目标闆的主要硬體資源如圖6所示。和ARM體系結構相關的代碼都放在arch/arm/以及include/asm-arm/目錄下,将linux移植到ARM平台上,主要修改這兩個目錄下的代碼。要想使linux核心應用于自己的ARM平台AT91RM9200上,必須對核心的源代碼做一定的修改,主要修改部分如下:(1) 修改根目錄下的Makefile檔案,确認ARCH和CROSS_COMPILE的定義:ARCH :=arm; CROSS_COMPILE :=arm-linux- (2)修改arch目錄下的Makefile檔案,根據自己的電路設定TEXTADDR變量,TEXTADDR決定核心起始運作位址,即 image.ram應下載下傳的位址。(3)修改arch目錄下的config.in 檔案,添加CONFIG_ARCH_AT91RM9200自選項,config檔案決定了menuconfig菜單的内容,把使用的平台加在需要的地方,這樣在配置linux核心時就能夠選擇是否支你的平台了。

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法
基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

圖6 系統硬體框圖[page]

(4)修改arch/arm/boot目錄下的Makefile檔案,根據自己的電路設定ZTEXTADDR和ZRELADDR, ZTEXTADDR和ZRELADDR分别是自解壓代碼的起始位址和核心解壓後代碼輸出起始位址。(5)修改arch/arm/boot /compressed目錄下的Makefile檔案,加入head-at91rm9200.S (6)修改arch/arm/kernel目錄下的Makefile檔案,增加AT91RM9200的支援,同時在    debug-armv.S中加入關閉全部外圍裝置,保證系統正常運作的代碼,在entry-armv.S中加入關于CPU中斷處理部分的代碼。(7)修改 arch/arm目錄下的mm-armv.c檔案,将init_maps->bufferable=0改為init_maps-> bufferable=1;

當然,一些大的晶片開發商在發行晶片的同時,針對自己晶片的體系結構對linux核心作了一些更新檔。實驗中使用的是針對AT91RM9200體系結構的更新檔patch-2.4.19-rmk7給标準核心源代碼打上更新檔後,該核心就可應用于AT91RM9200了,這樣可以大大減少開發的工作量。

移植之後要做的工作就是編譯核心,要想編譯适合自己工程中需要的核心,首先要對核心進行配置,常用的配置指令有:make config;make oldconfig;make menuconfig;make xconfig;make defconfig;Linux核心包允許使用者對其各類功能逐項配置,在配置時, 大部分選項可以使用其預設值, 隻有小部分需要根據使用者不同需要選擇。選擇的原則是将與核心其它部分關系較遠部分且不經常使用的部分功能代碼編譯成為可加載子產品, 有利于減小核心的長度, 減小核心消耗的記憶體,不需要的功能就不要選, 與核心緊密且經常使用的部分功能代碼直接編譯到核心中。主要是進行以下幾項配置: (1)選擇處理器類型;(2)選擇闆級支援;(3)選擇對RAMDISK支援、對裝置驅動的支援以及對檔案系統的支援。在配置工作完成後, 就可以進行核心編譯。

編譯核心有壓縮方式和非壓縮兩種方式。非壓縮方式使用make vmlinux來編譯核心,或者直接運作make指令。壓縮方式用make bzImage來編譯核心。編譯成功後會在arch/arm/boot目錄中生成核心的鏡像,此鏡像下載下傳到flash中就可以通過bootloader引導。具體的編譯步驟如下:(1) 進入打上更新檔修改好的核心源代碼目錄下,執行make mrproper;make clean這兩條指令,将源代碼清理幹淨(防止以前編譯産生的“垃圾”幹擾)。(2)執行make at91rm9200dk_config,使源代碼按照AT91RM9200體系結構來配置。 (3)執行make o1dconfig(儲存原編譯配置)(4)執行make menuconfig進入核心編譯前配置界面,進行配置。(5)執行make dep聲稱編譯要用的依賴檔案。(6)執行make zImage生成核心鏡像。

3.3 檔案系統的移植

linux采用檔案系統組織系統中的檔案和裝置,為裝置和使用者程式提供統一接口。linux要啟動起來還需要有根檔案系統。根檔案系統的作用是存放各種工具(如Linux指令)、應用程式、必需的連結庫等等。通常用busybox來制作根檔案系統,在busybox中包含一百多種Linux上标準的工具程式, 而這些工具程式僅需幾百k空間。busybox使用非常友善, 隻要建立一個符号連接配接即可, 使用者可以通過配置Config.h 和Makefile檔案來定制busybox。将busybox複制到bin目錄中,分别使用ln-s 建立每一個指令的符号連接配接。但應該注意的是busybox需要glibc支援(如果使用靜态連接配接則不需要glibc 庫檔案),是以還需要将運作busybox所需的庫檔案copy到lib目錄中, 并建立符号連接配接。到此為止, ARM Linux 的根檔案系統就已經建立起來了。

ARM Linux采用RAMDISK的方式來裝載根檔案系統,是以在運作核心之前,需要先制作RAMDISK,将必須的檔案和裝置加人到RAMDISK中。核心啟動後,會從指定位址去讀取根檔案系統,這裡我們使用RAMDISK在記憶體中虛拟一個磁盤,具體方法如下:

(1)首先建立一個2048k的虛拟磁盤,檔案名為initrd.img:# dd  if= dev/zero of=initrd.img bs= lk count= 2048  (2)将該虛拟磁盤檔案格式化成Ext2格式:# mkfs ext2 -c initrd.img這就生成了一個支援Ext2檔案系統的ramdisk  (3)mount這個檔案系統到/tmp下,# mount -o loop -t ext2 initrd.img /tmp  (4)向/tmp中添加linux啟動必須的檔案和裝置。 # cd  /tmp;  # mkdir bin dev etc lib mnt proc sbin sys usr  以上這幾個程式和裝置是啟動Linux必須的,這樣得到的ramdisk大約400k  (5)建立裝置節點,添加相應的程式,将已經訂制好的一個檔案系統全部複制過來。# cp –a  myfs/*  /tmp  (6)壓縮映像,把loop裝置解除安裝下來,然後用gzip指令把映像壓縮一下。# umount /tmp ;  #gzip –best –c initrd.img > initrd.img.gz現在我們就得到了一個壓縮的RAMDISK映像initrd.img.gz制作好了。

4. 核心的下載下傳和執行

要想使目标闆的Linux系統脫離交叉開發環境,直接在目标機上本地啟動運作,必須通過U-boot将U-boot映像,核心映像和RAMDISK 映像燒寫到FLASH中,因為使用U-boot引導程式需要使用U-boot格式的核心映像和RAMDISK映像,可以通過以下指令來實作:

基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法
基于at91rm9200的arm linux的移植方法,基于AT91RM9200的ARM Linux的移植方法

($U-BOOT-PATH)/tools /mkimage -A arm -O linux -T kernel -C gzip –a 0x20008000 -e 0x20008000 –n “linux-2.4.19”-d linux.bin.gz uImage

($U-BOOT-PATH)/tools/mkimage-A arm -O linux -T ramdisk -C gzip –a 0x21100000 -e 0x21100000 –n “RAMDISK”-d ramdisk.bin ramdisk

通過U-boot将uImage和ramdisk燒寫到flash相應的分區中去,燒寫到flash相應分區的位址如圖7所示:燒寫完畢後設定u- boot的環境變量,讓系統自動啟動,系統複位後,Linux系統就可以完全自動從本地flash啟動了,啟動後,進行位址映射,u-boot會把u- boot壓縮映像,kernel壓縮映像,ramdisk壓縮映像全部拷貝到SDRAM的相應位址,SDRAM的映射位址如圖8所示,這時Linux系統完全在SDRAM中運作了,Linux系統真正啟動起來了。

5. 總結

本文根據一個特定的目标平台,結合AT91RM9200的開發經驗,詳細介紹了将Linux移植到ARM建構的嵌入式系統上的主要技術和整個流程,實作了Linux 向目标系統AT91RM9200的移植,移植後的作業系統在目标闆上運作穩定,并且可以根據實際需要編寫相應的控制程式,将其應用于實際工業控制中。掌握這些技術,對于開發嵌入式系統十分重要,對開發其他類型的嵌入式系統同樣具有參考意義。

本論文作者創新點:從軟體與硬體的互相關系, 硬體對軟體的制約、硬體對軟體的支援這個角度對裁減和移植進行了分析,同時在Bootloader(啟動代碼)的移植,Kernel(核心)的裁減和移植過程中,把代碼分成了兩部分,一部分是和硬體相關的部分,一部分是和硬體無關的部分,這樣做不僅思路清晰,而且可以大大減少工作量。

參考文獻:

[1] 許先斌, 熊慧君, 李淵, 楊芬. 基于ARM9 的嵌入式Linux開發流程的研究[J]微計算機資訊. 2006,11:87-90

[2] 劉振綱,劉成安,盧劍翔. 移植标準Linux 到S3C2410[J] 微計算機資訊.2006,32:152-154

[3] 羅緻,王仲東. ARM Linux在AT91RM9200平台上的移植.軟體技術,2006年第25卷第1期

[4] 李明,ARM Linux的移植過程及分析[J ].電子設計應用, 2003,7

[5] 劉峥嵘等編著,嵌入式Linux應用開發詳解[M].北京:機械工業出版社,2004. 7