葉培順
(榆林學院 信息工程學院,陜西 榆林 719000)
嵌入式系統是以應用為中心,以計算機技術為基礎,軟硬件可裁剪,適用于應用系統,對功能、可靠性、成本、體積、功耗等方面有特殊要求的專用計算機系統[1]。在嵌入式系統里基于ARM的嵌入式處理已經成為市場主流。而Linux是免費運行的,快速高效的操作系統,在過去的幾年中,基于開源組織的Linux系統的嵌入式操作系統得到了長足的發展。Linux操作系統雖然不是微內核結構,但是其模塊化的結構使得用戶可以對其方便的進行配置,去除用戶系統不需要的模塊,減小系統的開銷可以做到幾百K大小。
本文所討論嵌入式系統目標平臺采用的是Samsung公司基于ARM 920T內核開發的一款嵌入式處理器S3C2440,用于PDA、Internet設備和手持設備,內部集成了LCD、USB等控制器。Linux內核采用2.6版本的內核,它吸收了一些新技術,在性能,可量測性支持和可用性方面有較大提高。
嵌入式Linux系統從軟件的角度看通常可以分為4個層次:
1)引導加載程序 包括固化在固件中的啟動代碼(可選)和Bootloader 2部分。
2)內核 特定于嵌入式板子的定制內核以及控制內核引導系統的參數。
3)文件系統 包括根文件系統和建立于Flash內存設備之上的文件系統。通常用RAMDISK作為根文件系統。它是提供管理系統的各種配置文件以及系統執行用戶應用程序的良好運行環境的載體[2]。
4)用戶應用程序 特定于用戶的應用程序。有時在用戶應用程序和內核層之間可能會包括一個嵌入式圖形用戶界面[3]。
嵌入式Linux的移植可以按照上面4個層次進行。本文將根據這4個方面分析嵌入式Linux系統在s3c2440上的移植過程。
Linux使用GNU的工具,社區的開發者已經編譯出了常用體系結構的工具鏈。免費提供的工具包括3個部分:binutils,gcc和glibc,其中binutils是二進制處理工具,gcc是編譯工具,glibc是鏈接和運行庫。交叉編譯工具的安裝步驟如下:
1)從 ARM Linux 的官方站點 http://arm.Linux.org.uk 下載 cross23.3.2.tar.bz2 包;
2)在/usr/local/arm 下解壓:$tar2jxvfcross23.3.2.tar.bz2;
3)在/etc/profile文件中修改PATH環境變量。在export之前添加一行:
PATH=$PATH: /usr/local/arm/3.3.2/bin 4)使以上配置生效:$source/etc/profile
1)主機環境配置:首先要確認主機的網絡接口驅動成功,并且配置網絡接口的IP地址。可以通過ifconfig命令查看所有網絡接口,還可以配置網口的IP地址。
2)串口控制臺工具:串口通信接口很適合作為控制臺,在各種操作系統上一般都有現成的控制臺操作程序可以使用。Windows操作系統有超級終端 (Hyper terminal)工具;Linux操作系統有minicom工具。
3)TFTP服務:TFTP是目標板下載映像所需要的網絡服務。以root身份登錄,完成下面的操作:
·編輯tftp配置文件:
$vi/etc/xinetd.d/tftp
修改disab l一行,把yes改為no;
·使用下面的命令使x inetd重新啟動TFTP服務:
$/etc/init.d/xinetd restart
4)N FS服務:N FS服務的主要任務是把本地的一個目錄通過網絡輸出,其他計算機可以遠程的掛接這個目錄并且訪問文件。以root的身份完成以下步驟:
·在/etc/export s中添加一行:
/opt/target/root fs3(rw,no_root_squash,no_all_squash)
·確認N FS守護進程已在運行。使用下面命令啟動或重啟N FS服務:
$/etc/rc.d/init.d/nfs restart
U-Boot作為通用的Bootloader,U-Boot可以方便地移植到其他的硬件平臺上。移植U-Boot工作就是添加開發板硬件相關的文件、配置選項,然后配置編譯。開始移植之前,需要先分析一下U-Boot已經支持的開發板,比較出硬件配置最接近的開發板[4]。選擇的原則是,首先處理器相同,其次處理器體系結構相同,然后是以太網接口等外圍設備。因為U-Boot代碼中的SMDK2410模板所采用的CUP是s3c2410與s3c2440相似,所以對于U-Boot移植,就是修改SMDK2410模板代碼。
這里使用的是u-boot-1.1.6,其移植的基本步驟如下:
1)在頂層Makefile中為開發板添加新的配置選項。
RSC2440_config: unconfig
@./mkconfig$(@:_config=) arm arm920t RSC2440 NULL s3c24x0
2)修改 flash驅動
修改 board/smdk2410/flash.c, 該文件為 RSCARM2440的Flash驅動程序。需要根據Flash芯片手冊實現它的驅動程序。
3)修改與RSCARM2440相關的頭文件
修 改 include/configs/smdk2410.h, 該 文 件 是 與 RSC ARM2440相關的頭文件。啟動方式有從nandflash啟動和從norflash啟動兩種,可根據自己的需要修改。
4)修改目標板的初始化文件
修改board/smdk2410/smdk2410.c,該文件為目標板的初始化文件,其中主要修改的函數有:
intboard_init( ); //板極初始化函數
int dram_init(); //SDRAM初始化函數
5)修改串口驅動
修改 cpu/arm920t/serial.c,該文件為 RSC ARM2440 的串口驅動程序,使用RSCARM2440的UART0。
6)修改網絡驅動
RSC ARM2440 使用的是 DM9000 網卡,u-boot-1.1.6 中支持DM9000,其代碼在drivers/dm9000x.c中,因此可以直接使用。另外,還需要把DM9000驅動在include/configs/rsc2440.h加以說明。
標準Linux內核相對于資源受到限制的嵌入式系統來說過于龐大,因此要將其移植到嵌入式系統上,就需要將Linux內核根據目標平臺的情況進行剪裁、配置,并對配置好的內核進行編譯生成內核映像文件。Linux2.6內核吸收了一些新技術,在性能、可量測性支持和可用性方面有有較大的提高[5]。
1)修改 Makefile
將makefile中直接將ARCH=$(SUBARCH)這行注釋掉,并加入一行ARCH=arm,目的就是要使編譯出來的目標文件面向的是arm平臺。
還要注釋掉CROSSCOMPILE=這行,加一行CROSS COMPILE=arm-linux-。修改這一行是為了在編譯過程中使用交叉編譯器。
2)配置內核
使用makemenuconfig來配置內核,盡量裁減內核,可以舍棄的部分都先去掉。
3)編譯內核
#make dep
#make clean
#make zImage(注意大小寫)
內核編譯成功以后,會在Linux2.6/arch/arm/boot目錄中生成一個新內核的映像文件zImage。
Ramdisk不是一個文件系統。在Linux中,可以把系統內存中的一部分仿真成一個硬盤塊,在它上面可以實現各種基于內存的文件系統,如Ext2 onRamdisk。內存的存儲速度要遠遠快于硬盤,所以可以用這個方法提高文件訪問速度。
3.3.1 制作Linux根文件系統
Linux在內核啟動以后,要裝載根文件。在嵌入式Linux中,受存儲器的限制,不能使用桌面Linux那樣復雜的root文件系統,需要對于文件系統進行重新設計和裁減[6]。通常的處理方法如下:
1)刪除處理 對一些在嵌入式系統中無關的目錄和文件進行直接刪除處理。
2)strip處理 在Linux中,庫文件和二進制可執行文件在發行時,都包括大量的調試信息,在嵌入式應用中,可以去掉這些代碼以減小程序的大小,采用這種方法有時可以使程序縮小30-50%,從而有效節約空間。如在嵌入文件系統制作中,可以采用下面命令:
objcopy——strip-all FROM TO
objcopy命令在復制文件時,帶strip-all.參數,將文件中的調試信息去掉。
3)文件替換處理 標準 Linux中有些文件功能強丸但體積過大,在嵌入式應用中,可以采用一些功能簡單和小巧的文件去替換原來的文件。如在標準的Linux發行套件中有數以千計的二進制命令文件,顯然這對嵌入式系統是不合適的,卻而代之,通常使用busybox來提供這些命令。
3.3.2 制作Ramdisk
Ramdisk就是把指定的內存區域模擬成磁盤設備,它屬于塊設備驅動程序,基于Ramdisk的塊設備,可以建立EXT2格式的磁盤文件系統。在內核啟動之前,通常需要把EXT2文件系統的壓縮鏡像解壓到內存指定的位置,然后就可以把Ramdisk設備掛載成根文件系統。制作Ramdisk映像的步驟如下:

這樣就生成了一個壓縮的根文件系統initrd.bin。
1)燒寫 U-Boot
燒寫U-Boot是在windows中通過JTAG進行的,燒寫工具是 SJF2440.exe。把 u-boot.bin 和 SJF2440.exe 拷貝到同一文件夾中。在保證開發板從nandflash方式啟動的情況下,運行“SJF2440/f:u-boot.bin”,此命令調入 u-boot.bin 文件燒寫 falsh。
2) 通過 u-boot把 zIamge和 initrd.bin燒寫到 flash對應的分區中。
燒寫zIamge:
#erase 100000 1fffff
#tftp 30000000 zImage
#cp.b 30000000 100000 b9072
燒寫 initrd.bin:
#erase 200000 6fffff
#tftp 30000000 initrd.bin
#cp.b 30000000 200000 312bf0
3)設置u-boot環境變量讓系統自動啟動
#setenv bootargs root=/dev/arm rw initrd=0x30800000,8M
#setenv bootcmd bootm 100000 200000
#setenv bootdelay 3
#saveenv
系統復位后,Linux系統就可以完全自動地從本地flash啟動了。
本文針對一個特定的目標平臺,提供了構建一個基本嵌入式Linux系統的過程與方法。對Linux內核版本進行裁減、
移植,編譯生成的內核在S3C2440處理器的目標板上成功運行,且保留了Linux原有的工作穩定的特點,制作的根文件系統可以通過Ramdisk方式正常加載進內核。將Linux操作系統移植于嵌入式系統中作為嵌入式系統的底層研發平臺是一件非常引人注目的事,同時又是一個復雜的課題,移植后系統的實時性、穩定性、安全性和精簡程度等方面都需要嵌入式技術開發人員在設計中進一步研究。
[1]孫紀坤,張小全.嵌入式Linux系統開發技術祥解[M].北京:人民郵電出版社,2006.
[2]孫天澤,袁文菊.嵌入式設計及Linux驅動程序開發指南[M].北京:電子工業出版社,2007.
[3]陳賾.ARM9嵌入式技術及linux高級實踐教程[M].北京:北京航空航天大學出版社,2005.
[4]王學龍.嵌入式系統設計與應用[M].北京:清華大學出版社,2002.
[5]北京革新科技有限公司.ARM9實驗指導書[M].北京:北京革新科技有限公司,2007.
[6]趙炯.Linux內核完全注釋[M].北京:機械工業出版社,2004.