S3C44B0是Samsung公司推出的一款為手持設(shè)備或其他通用設(shè)備開發(fā)的32位處理器,它基于ARM7TDMI核,沒有內(nèi)存管理單元(MMU)。在采用無MMU的微處理器的嵌入式系統(tǒng)中廣泛采用的就是uClinux系統(tǒng),作為linux的衍生系統(tǒng),其具有支持多任務(wù)、內(nèi)核精簡、高效穩(wěn)定和源代碼開放的優(yōu)點(diǎn)。系統(tǒng)移植的基本過程包括:獲取較新版本的linux-2.6.9內(nèi)核源碼,根據(jù)目標(biāo)平臺對源碼中與硬件平臺相關(guān)部分進(jìn)行修改,添加必要的外設(shè)驅(qū)動程序,對系統(tǒng)進(jìn)行針對目標(biāo)平臺的交叉編譯,生成的內(nèi)核映像文件的下載調(diào)試等。
2 硬件環(huán)境介紹
硬件平臺以S3C44B0為核心,采用的外部晶振頻率為6MHZ,內(nèi)核主頻最高可達(dá)到66MHZ,平臺以2MB的AMD29LV160DB做 rom,其地址空間為0~1fffff,以HY57V1620HG sdram做內(nèi)存,地址空間為0c000000~0c7fffff,共8MB,以RTL8019as作為網(wǎng)絡(luò)控制芯片,接在S3C44B0的Bank5 上,通過JTAG與PC機(jī)的并口連接支持在線調(diào)試與程序燒寫。
圖1 硬件平臺框圖
3 uClinux的移植
3.1 交叉編譯環(huán)境的建立
交叉編譯是利用運(yùn)行在某機(jī)器(宿主機(jī))上的編譯器編譯某個源程序生成在另一臺機(jī)器(目標(biāo)機(jī))上運(yùn)行的目標(biāo)代碼的過程。本文的交叉編譯環(huán)境建立如下:在PC機(jī)上安裝Linux操作系統(tǒng)做為我們的宿主機(jī),版本為Fedore Core 5,從http : // www. uClinux .org/上下載交叉編譯工具鏈arm-elf-tools20040427并安裝在Linux 宿主機(jī)上,這樣就建立了uClinux-arm的交叉編譯環(huán)境。
3.2 U-Boot-1.1.2的移植
Bootloader是系統(tǒng)加電后運(yùn)行的第一段代碼,在一個基于ARM的嵌入式系統(tǒng)中,系統(tǒng)上電或復(fù)位時通常都從地址0X00000000處開始執(zhí)行,而這個地址處通常就是系統(tǒng)的bootloader,通過這段程序可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境調(diào)整到一個合適的狀態(tài),以便為最終的調(diào)用操作系統(tǒng)內(nèi)核準(zhǔn)備好正確的環(huán)境。
本文中bootloader采用對U-Boot進(jìn)行移植來實(shí)現(xiàn)的。U-Boot的全稱是Universal Boot Loader,是德國DENX小組開發(fā)的用于多種嵌入式CPU的Bootloader引導(dǎo)程序, 支持PowPC、ARM、MIPS、M68K等多種處理器平臺,支持Linux、VxWorks、NetBSD等多種嵌入式操作系統(tǒng),主要用來開發(fā)嵌入式系統(tǒng)初始化代碼bootloader,其易于裁剪和調(diào)試,尊循GPL (通用公共許可) 公約,完全開放源代碼。可以從http://sourceforge.net/projects/u-boot得到它多個版本的源碼,本文是以u- boot-1.1.2為例進(jìn)行移植的。
在移植前可以通過查看doc文檔了解U-Boot源碼的主要結(jié)構(gòu),在眾多的目錄中與移植相關(guān)的主要是board、cpu、drivers等幾個目錄。移植的基本過程如下:
(1) 查找以S3C44B0處理器為核心的硬件平臺,此目的是為了簡化移植難度;
在board/下運(yùn)行 find -exec grep -l 44B0 {} 找到/dave/B2/B2.c,由此我們知道dave公司的B2平臺是以S3C44B0處理器為核心的,所以移植可以參考B2平臺進(jìn)行;
(2) 建立我們目標(biāo)平臺的目錄lanlan,把B2板的文件拷到建立的目錄中,但需要修改文件的名稱;
(3) 修改新建目錄中的文件的名稱,將文件中所有的B2都改成lanlan;
(4) 在include/configs/添加目標(biāo)平臺的配置文件lanlan.h;此文件可以參考B2.h建立;
(5) 修改總目錄下的Makefile文件,添加目標(biāo)板的編譯信息;
這個過程完成后可以在u-boot/目錄下依次運(yùn)行make lanlan_config ; make進(jìn)行編譯,編譯完成后如果能生成u-boot.bin等文件,則說明前面的過程無誤,如果出現(xiàn)錯誤,則需要根據(jù)錯誤信息進(jìn)行相關(guān)修改;
(6) 修改硬件相關(guān)的文件,在cpu/中有S3C44B0的目錄,說明U-Boot已經(jīng)提供了對S3C44B0的支持,我們只是需要修改部分文件使其適合我們的目標(biāo)平臺,主要修改的是cpu/下start.S 和serial.c,include/configs/下的lanlan.h中關(guān)于cpu的頻率、串口波特率、PLLCON寄存器、flash和 sdram的大小、基地址和網(wǎng)絡(luò)控制芯片的基地址等內(nèi)容,確定修改正確后運(yùn)行make lanlan_config;make命令,編譯生成的u-boot.bin就是我們需要的引導(dǎo)程序;
(7) 通過JTAG將生成的u-boot.bin燒寫到目標(biāo)平臺的0x0地址,配置Linux下的minicom或者Windows下的超級終端,注意配置的串口及串口波特率要與U-Boot中設(shè)置的一樣,按復(fù)位鍵或上電重啟目標(biāo)平臺后可以從minicom或超級終端看到U-Boot在系統(tǒng)中運(yùn)行了。
通過以上步驟,完成了U-Boot移植的主要工作。
3.3 uClinux內(nèi)核的移植
3.3.1 uClinux-dist源碼包的準(zhǔn)備
從uClinux的官方網(wǎng)站下載uclinux-dist源碼包。源碼包中包含了uClinux內(nèi)核、uClibc庫和busybox等 uClinux下的用戶應(yīng)用程序,本文中下載的是uClinux-dist-20041215.tar.gz,在linux系統(tǒng)下解壓后會生成一個 uClinux-dist目錄,該目錄包含了編譯uClinux內(nèi)核需要的所有文件。在uClinux-dist目錄中包含有l(wèi)inux-2.2.x、 linux-2.4.x、linux-.2.6.x三個子目錄,就是三種版本的uClinux內(nèi)核的源碼,我們的目的是把uClinux-2.6.9版本移植到目標(biāo)平臺上,所以我們還需要從http://www.kernel.org上下載linux-2.6.9.tar.bz2,從http: //www.uClinux.org上下載linux-2.6.9-uc0.patch,從Samsung的網(wǎng)站http: //www.oprensrc.sec.samsung.com上下載補(bǔ)丁文件linux-2.6.9-uc0.hsc0.patch。在Linux系統(tǒng)下解壓內(nèi)核Linux-2.6.9.tar.bz2并打上補(bǔ)丁文件linux-2.6.9-uc0.patch和linux-2.6.9-uc0- hsc0.patch,將打上補(bǔ)丁的2.6.9內(nèi)核改名為linux-2.6.x并替換在uClinux-dist包中的linux-2.6.x,完成移植前的準(zhǔn)備工作。
3.3.2 uClinux-dist源碼的修改
按照如下步驟添加S3C44B0的相關(guān)文件:
# cp uClinux-dist/vendors/Samsung/4510b –r uClinux-dist/vendors/Samsung/44b0,將源代碼包中已經(jīng)有的Samsung的4510b的文件復(fù)制一份并改名為44b0 ,這一過程也可以直接用鼠標(biāo)完成;
# cp linux-2.6.x/arch/armnommu/configs/s3c44b0x_defconfig
vendors/Samsung/44b0/config.linux-2.6.x,該步驟是將s3c44b0x_defconfig文件復(fù)制到44b0目錄下,該步驟同樣可以復(fù)制、粘貼完成;
雖然已經(jīng)給linux-2.6.9內(nèi)核打了補(bǔ)丁文件,但是我們依然需要對源代碼進(jìn)行修改才能順理的編譯通過,文件的修改如下:
(1) 修改linux-2.6.x/arch/armnommu/arch/kernel/vmlinux.lds.S,添加以下內(nèi)容:
(.got)?Global offset table */
romfs_start = .;
romfs.o
romfs_end = .;
這樣修改的目的是把romfs文件系統(tǒng)連接到內(nèi)核映象中。
(2) 修改linux-2.6.x/arch/armnommu/kernel/setup.c, 添加變量romfs_start,romfs_end及修改
其設(shè)置如下:
default_command_line
extern int _stext, _text, _etext, _edata, _end;
extern int romfs_start,romfs_end;
char *from = default_command_line;
sprintf(default_command_line, "root=/dev/ram0 initrd=0x%08lx,%ldk keepinitrd", (unsigned
long)&romfs_start,((unsigned long)&romfs_end - (unsigned long)&romfs_start)>>10);
(3) 修改vendors/Micetek/44b0/rc文件中 /bin/expand /etc/ramfs.img /dev/ram1;
(4) 添加串口驅(qū)動程序,添加文件linux-2.6.x/drivers/serial/serial_s3c44b0.c和linux-2.6.x /include/asm-armnommu/arch-s3c44b0/uart.h,因為在linux-2.6.9內(nèi)核中對S3C44B0的支持并不是很好,系統(tǒng)只是提供了一個簡易的串口驅(qū)動,所以需要添加串口驅(qū)動。
3.3.3 內(nèi)核的配置與編譯
在編譯內(nèi)核之前需要進(jìn)行配置,可以通過三種方式對內(nèi)核進(jìn)行配置:在uClinux-dist目錄下運(yùn)行make config/make menuconfig/make xconfig,其中make config是在字符界面下,make menuconfig是在字符界面下實(shí)現(xiàn)的菜單界面,make xconfig為圖形界面,三種配置方式是一致的,xconfig界面比較友好,容易掌握,但它卻沒有menuconfig菜單穩(wěn)定,而且在有些機(jī)器上運(yùn)行不起來,本文是使用make menuconfig完成的。運(yùn)行make menuconfig時, 程序會依次出現(xiàn)開發(fā)平臺、內(nèi)核、文件系統(tǒng)、應(yīng)用程序的配置界面, 可以根據(jù)自己的需要進(jìn)行配置。配置時大部分選項可以使用其缺省值,只有小部分需要用戶根據(jù)需求進(jìn)行選擇,進(jìn)行內(nèi)核配置時,有3種選擇,它們分別代表的含義如下:
“Y” - 將該功能編譯進(jìn)內(nèi)核;
“N” -不將該功能編譯進(jìn)內(nèi)核;
“M” -將該功能編譯成可以在需要時動態(tài)插入到內(nèi)核中的模塊;
將與核心其它部分關(guān)系較遠(yuǎn)且不經(jīng)常使用的部分功能代碼編譯成為可加載模塊,有利于減小內(nèi)核的長度,減小內(nèi)核消耗的內(nèi)存,簡化該功能相應(yīng)的環(huán)境改變時對內(nèi)核的影響,許多功能都可以這樣處理,例如網(wǎng)卡的支持、對FAT等文件系統(tǒng)的支持等。
在配置好內(nèi)核后依次執(zhí)行以下命令:
make dep; make clean; make lib_ only; make user_ only; make romfs; make image; make編譯完成之后,會在uClinux-dist/linux-2.6.x/下會生linux.bin,在uClinux-dist/images /下會生成linux.data、linux.text、image.bin等目標(biāo)文件。在編譯中可能會產(chǎn)生錯誤,需要根據(jù)錯誤信息進(jìn)行調(diào)試修改。
3.4 內(nèi)核的下載運(yùn)行
(1) 我們將開始移植好的U-Boot的目標(biāo)文件u-boot.bin通過JTAG燒寫到目標(biāo)硬件平臺上,燒寫時開始地址要從0開始,目標(biāo)板上電后從0地址處運(yùn)行就開始運(yùn)行移植好的bootloader了,我們可以在windows下通過超級終端或者在linux下的minicom檢測目標(biāo)板的串口輸出;
(2) 通過U-Boot的命令tftpboot來下載我們移植好的內(nèi)核,tftpboot c008000 linux.bin;go c008000,通過以上兩個步驟就實(shí)現(xiàn)了uClinux的下載運(yùn)行。
系統(tǒng)啟動后,首先執(zhí)行了bootloader,完成了硬件設(shè)備的初始化任務(wù),然后將運(yùn)行的控制權(quán)交給了uClinux內(nèi)核,uClinux系統(tǒng)就開始運(yùn)行了。
4 結(jié)束語
由于Linux操作系統(tǒng)的源碼開放性及ARM微處理器的良好性能,如何將Linux系統(tǒng)移植到ARM平臺上得到越來越多的關(guān)注。操作系統(tǒng)的移植是構(gòu)建基于ARM微處理器的嵌入式系統(tǒng)的前題,將bootloader與系統(tǒng)內(nèi)核分開進(jìn)行設(shè)計能夠使軟件結(jié)構(gòu)更加清晰,而且可以利用前者的功能,靈活的實(shí)現(xiàn)多種引導(dǎo)系統(tǒng)的方式。
本論文的創(chuàng)新點(diǎn):本文采用移植U-Boot作為系統(tǒng)bootloader,從而實(shí)現(xiàn)了uClinux-2.6內(nèi)核移植。U-Boot作為一種功能強(qiáng)大的bootloader,適合多種平臺并可以引導(dǎo)多種操作系統(tǒng),利用其強(qiáng)大功能可以實(shí)現(xiàn)系統(tǒng)內(nèi)核的多種下載和引導(dǎo)方式,掌握其移植方法很有必要,uClinux2.6內(nèi)核對硬件平臺的支持更好,移植過程中要注意不同硬件平臺間的差別。
參考文獻(xiàn):
[1] 蘇義鑫,王子毅,張素文.uClinux在嵌入式系統(tǒng)中的移植研究[J].微計算機(jī)信息,2006, 11-2:58-60。
[2] 李巖,榮盤.基于S3C44B0嵌入式uClinux系統(tǒng)原理及應(yīng)用[M].北京:清華大學(xué)出版社.2005。
[3] 孫天澤,袁文菊,張海峰.嵌入式設(shè)計及Linux驅(qū)動開發(fā)指南[M].北京:電子工業(yè)出版社. 2005.2。
[4] 王田苗.嵌入式系統(tǒng)設(shè)計與實(shí)例開發(fā)[M].北京:清華大學(xué)出版社.2003。
[5] 常銀霞,張振東,唐繼英.利用Bootloader實(shí)現(xiàn)uClinux向S3C44B0上的移植[J].河北工業(yè)大學(xué)學(xué)報.Vol.34 No.2.2005.4。
[6] http://www.linuxforum.com。