系統移植與交叉編譯
㈠ 嵌入式linux系統移植包含哪三部分內容
嵌入式Linux系統的移植主要有U-Boot、Linux內核、文件系統這三部分。
Uboot是在系統上電時開始執行,初始化硬體設備,准備好軟體環境,然後才調用Linux操作系統內核。文件系統是Linux操作系統中用來管理用戶文件的內核軟體層。文件系統包括根文件系統和建立於Flash內存設備之上文件系統。根文件系統包括系統使用的軟體和庫,以及所有用來為用戶提供支持架構和用戶使用的應用軟體,並作為存儲數據讀寫結果的區域。
可將Linux系統移植過程大致需要分成6個步驟:
1) 准備工作,包括下載源碼、建立交叉編譯環境等。交叉開發是指在開發主機上安裝開發工具,編輯、編譯目標板的引導程序、內核和文件系統,使其能在目標板上運行。
2) 配置和編bootloader(引導裝載程序)。通過這段小程序,可以初始化硬體設備、建立內存空間的映射表,從而建立適當的系統硬體環境,為最終調用操作系統內核做好准備。
3) 配置和編譯Linux內核,對其進行相應的裁剪,修改內核以支持相關的硬體設備。
4) 為大容量NAND Flash移植YAFFS文件系統,並將該文件系統加入Linux內核中;
5) 製作RAMdisk來掛載根文件系統。Linux系統中的文件和設備是通過文件系統來組織的。文件系統的存在使得數據和設備可以被有效而透明地存取訪問。一個linux的最簡根文件系統應該包括支持linux系統正常運行的基本內容,包括系統使用的軟體和庫,以及所有用來為用戶提供基本支持的架構和指令。
6) 燒寫、調試系統;如果調試出錯,則需要重新配置,返回上述步驟(2)。
㈡ 「干貨」嵌入式Linux系統移植的四大步驟(上)
在學習系統移植的相關知識,在學習和調試過程中,發現了很多問題,也解決了很多問題,但總是對於我們的開發結果有一種莫名其妙的感覺,糾其原因,主要對於我們的開發環境沒有一個深刻的認識,有時候幾個簡單的命令就可以完成非常復雜的功能,可是我們有沒有想過,為什麼會有這樣的效果?
如果沒有去追問,只是機械地完成,並且看到實驗效果,這樣做其實並沒有真正的掌握系統移植的本質。
在做每一個步驟的時候, 首先問問自己,為什麼要這樣做,然後再問問自己正在做什麼? 搞明白這幾個問題,我覺得就差不多了,以後不管更換什麼平台,什麼晶元,什麼開發環境,你都不會迷糊,很快就會上手。對於嵌入式的學習方法,我個人方法就是:從宏觀上把握(解決為什麼的問題),微觀上研究(解決正在做什麼的問題),下面以自己學習的arm-cortex_a8開發板為目標,介紹下自己的學習方法和經驗。
嵌入式Linux系統移植主要由四大部分組成:
一、搭建交叉開發環境
二、bootloader的選擇和移植
三、kernel的配置、編譯、和移植
四、根文件系統的製作
第一部分:搭建交叉開發環境
先介紹第一分部的內容:搭建交叉開發環境,首先必須得思考兩個問題,什麼是交叉環境? 為什麼需要搭建交叉環境?
先回答第一個問題,在嵌入式開發中,交叉開發是很重要的一個概念,開發的第一個環節就是搭建環境,第一步不能完成,後面的步驟從無談起,這里所說的交叉開發環境主要指的是:在開發主機上(通常是我的pc機)開發出能夠在目標機(通常是我們的開發板)上運行的程序。嵌入式比較特殊的是不能在目標機上開發程序(狹義上來說),因為對於一個原始的開發板,在沒有任何程序的情況下它根本都跑不起來,為了讓它能夠跑起來,我們還必須要藉助pc機進行燒錄程序等相關工作,開發板才能跑起來,這里的pc機就是我們說的開發主機,想想如果沒有開發主機,我們的目標機基本上就是無法開發,這也就是電子行業的一句名言:搞電子,說白了,就是玩電腦!
然後回答第二個問題,為什麼需要交叉開發環境?主要原因有以下幾點:
原因 1: 嵌入式系統的硬體資源有很多限制,比如cpu主頻相對較低,內存容量較小等,想想讓幾百MHZ主頻的MCU去編譯一個Linux kernel會讓我們等的不耐煩,相對來說,pc機的速度更快,硬體資源更加豐富,因此利用pc機進行開發會提高開發效率。
原因2: 嵌入式系統MCU體系結構和指令集不同,因此需要安裝交叉編譯工具進行編譯,這樣編譯的目標程序才能夠在相應的平台上比如:ARM、MIPS、 POWEPC上正常運行。
交叉開發環境的硬體組成主要由以下幾大部分 :
1.開發主機
2.目標機(開發板)
3.二者的鏈接介質,常用的主要有3種方式:(1)串口線 (2)USB線 (3)網線
對應的硬體介質,還必須要有相應的軟體「介質」支持:
1.對於串口,通常用的有串口調試助手,putty工具等,工具很多,功能都差不多,會用一兩款就可以;
2.對於USB線,當然必須要有USB的驅動才可以,一般晶元公司會提供,比如對於三星的晶元,USB下載主要由DNW軟體來完成;
3.對於網線,則必須要有網路協議支持才可以, 常用的服務主要兩個
第一:tftp服務:
主要用於實現文件的下載,比如開發調試的過程中,主要用tftp把要測試的bootloader、kernel和文件系統直接下載到內存中運行,而不需要預先燒錄到Flash晶元中,一方面,在測試的過程中,往往需要頻繁的下載,如果每次把這些要測試的文件都燒錄到Flash中然後再運行也可以,但是缺點是:過程比較麻煩,而且Flash的擦寫次數是有限的;另外一方面:測試的目的就是把這些目標文件載入到內存中直接運行就可以了,而tftp就剛好能夠實現這樣的功能,因此,更沒有必要把這些文件都燒錄到Flash中去。
第二: nfs服務:
主要用於實現網路文件的掛載,實際上是實現網路文件的共享,在開發的過程中,通常在系統移植的最後一步會製作文件系統,那麼這是可以把製作好的文件系統放置在我們開發主機PC的相應位置,開發板通過nfs服務進行掛載,從而測試我們製作的文件系統是否正確,在整個過程中並不需要把文件系統燒錄到Flash中去,而且掛載是自動進行掛載的,bootload啟動後,kernel運行起來後會根據我們設置的啟動參數進行自動掛載,因此,對於開發測試來講,這種方式非常的方便,能夠提高開發效率。
另外,還有一個名字叫 samba 的服務也比較重要,主要用於文件的共享,這里說的共享和nfs的文件共享不是同一個概念,nfs的共享是實現網路文件的共享,而samba實現的是開發主機上 Windows主機和Linux虛擬機之間的文件共享,是一種跨平台的文件共享 ,方便的實現文件的傳輸。
以上這幾種開發的工具在嵌入式開發中是必備的工具,對於嵌入式開發的效率提高做出了偉大的貢獻,因此,要對這幾個工具熟練使用,這樣你的開發效率會提高很多。等測試完成以後,就會把相應的目標文件燒錄到Flash中去,也就是等發布產品的時候才做的事情,因此對於開發人員來說,所有的工作永遠是測試。
通過前面的工作,我們已經准備好了交叉開發環境的硬體部分和一部分軟體,最後還缺少交叉編譯器,讀者可能會有疑問,為什麼要用交叉編譯器?前面已經講過,交叉開發環境必然會用到交叉編譯工具,通俗地講就是在一種平台上編譯出能運行在體系結構不同的另一種平台上的程序,開發主機PC平台(X86 CPU)上編譯出能運行在以ARM為內核的CPU平台上的程序,編譯得到的程序在X86 CPU平台上是不能運行的,必須放到ARM CPU平台上才能運行,雖然兩個平台用的都是Linux系統。相對於交叉編譯,平常做的編譯叫本地編譯,也就是在當前平台編譯,編譯得到的程序也是在本地執行。用來編譯這種跨平台程序的編譯器就叫交叉編譯器,相對來說,用來做本地編譯的工具就叫本地編譯器。所以要生成在目標機上運行的程序,必須要用交叉編譯工具鏈來完成。
這里又有一個問題,不就是一個交叉編譯工具嗎?為什麼又叫交叉工具鏈呢?原因很簡單,程序不能光編譯一下就可以運行,還得進行匯編和鏈接等過程,同時還需要進行調試,對於一個很大工程,還需要進行工程管理等等,所以,這里 說的交叉編譯工具是一個由 編譯器、連接器和解釋器 組成的綜合開發環境,交叉編譯工具鏈主要由binutils(主要包括匯編程序as和鏈接程序ld)、gcc(為GNU系統提供C編譯器)和glibc(一些基本的C函數和其他函數的定義) 3個部分組成。有時為了減小libc庫的大小,也可以用別的 c 庫來代替 glibc,例如 uClibc、dietlibc 和 newlib。
那麼,如何得到一個交叉工具鏈呢?是從網上下載一個「程序」然後安裝就可以使用了嗎?回答這個問題之前先思考這樣一個問題,我們的交叉工具鏈顧名思義就是在PC機上編譯出能夠在我們目標開發平台比如ARM上運行的程序,這里就又有一個問題了,我們的ARM處理器型號非常多,難道有專門針對我們某一款的交叉工具鏈嗎?若果有的話,可以想一想,這么多處理器平台,每個平台專門定製一個交叉工具鏈放在網路上,然後供大家去下載,想想可能需要找很久才能找到適合你的編譯器,顯然這種做法不太合理,且浪費資源!因此,要得到一個交叉工具鏈,就像我們移植一個Linux內核一樣,我們只關心我們需要的東西,編譯我們需要的東西在我們的平台上運行,不需要的東西我們不選擇不編譯,所以,交叉工具鏈的製作方法和系統移植有著很多相似的地方,也就是說,交叉開發工具是一個支持很多平台的工具集的集合(類似於Linux源碼),然後我們只需從這些工具集中找出跟我們平台相關的工具就行了,那麼如何才能找到跟我們的平台相關的工具,這就是涉及到一個如何製作交叉工具鏈的問題了。
通常構建交叉工具鏈有如下三種方法:
方法一 : 分步編譯和安裝交叉編譯工具鏈所需要的庫和源代碼,最終生成交叉編譯工具鏈。該方法相對比較困難,適合想深入學習構建交叉工具鏈的讀者。如果只是想使用交叉工具鏈,建議使用下列的方法二構建交叉工具鏈。
方法二: 通過Crosstool-ng腳本工具來實現一次編譯,生成交叉編譯工具鏈,該方法相對於方法一要簡單許多,並且出錯的機會也非常少,建議大多數情況下使用該方法構建交叉編譯工具鏈。
方法三 : 直接通過網上下載已經製作好的交叉編譯工具鏈。該方法的優點不用多說,當然是簡單省事,但與此同時該方法有一定的弊端就是局限性太大,因為畢竟是別人構建好的,也就是固定的,沒有靈活性,所以構建所用的庫以及編譯器的版本也許並不適合你要編譯的程序,同時也許會在使用時出現許多莫名其妙的錯誤,建議讀者慎用此方法。
crosstool-ng是一個腳本工具,可以製作出適合不同平台的交叉編譯工具鏈,在進行製作之前要安裝一下軟體:
$ sudo apt-get install g++ libncurses5-dev bison flex texinfo automake libtool patch gcj cvs cvsd gawk
crosstool腳本工具可以在http://ymorin.is-a-geek.org/projects/crosstool下載到本地,然後解壓,接下來就是進行安裝配置了,這個配置優點類似內核的配置。主要的過程有以下幾點:
1. 設定源碼包路徑和交叉編譯器的安裝路徑
2. 修改交叉編譯器針對的構架
3. 增加編譯時的並行進程數,以增加運行效率,加快編譯,因為這個編譯會比較慢。
4. 關閉JAVA編譯器 ,減少編譯時間
5. 編譯
6. 添加環境變數
7. 刷新環境變數。
8. 測試交叉工具鏈
到此,嵌入式Linux系統移植四大部分的第一部分工作全部完成,接下來可以進行後續的開發了。
第二部分:bootloader的選擇和移植
01 Boot Loader 概念
就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬體設備、建立內存空間的映射圖,從而將系統的軟硬體環境帶到一個合適的狀態,以便為最終調用操作系統內核准備好正確的環境,他就是所謂的引導載入程序(Boot Loader)。
02 為什麼系統移植之前要先移植BootLoader?
BootLoader的任務是引導操作系統,所謂引導操作系統,就是啟動內核,讓內核運行就是把內核載入到內存RAM中去運行,那先問兩個問題:第一個問題,是誰把內核搬到內存中去運行?第二個問題:我們說的內存是SDRAM,大家都知道,這種內存和SRAM不同,最大的不同就是SRAM只要系統上電就可以運行,而SDRAM需要軟體進行初始化才能運行,那麼在把內核搬運到內存運行之前必須要先初始化內存吧,那麼內存是由誰來初始化的呢?其實這兩件事情都是由bootloader來乾的,目的是為內核的運行准備好軟硬體環境,沒有bootloadr我們的系統當然不能跑起來。
03 bootloader的分類
首先更正一個錯誤的說法,很多人說bootloader就是U-boot,這種說法是錯誤的,確切來說是u-boot是bootloader的一種。也就是說bootloader具有很多種類,
由上圖可以看出,不同的bootloader具有不同的使用范圍,其中最令人矚目的就是有一個叫U-Boot的bootloader,是一個通用的引導程序,而且同時支持X86、ARM和PowerPC等多種處理器架構。U-Boot,全稱 Universal Boot Loader,是遵循GPL條款的開放源碼項目,是由德國DENX小組開發的用於多種嵌入式CPU的bootloader程序,對於Linux的開發,德國的u-boot做出了巨大的貢獻,而且是開源的。
u-boot具有以下特點:
① 開放源碼;
② 支持多種嵌入式操作系統內核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS;
③ 支持多個處理器系列,如PowerPC、ARM、x86、MIPS、XScale;
④ 較高的可靠性和穩定性;
⑤ 高度靈活的功能設置,適合U-Boot調試、操作系統不同引導要求、產品發布等;
⑥ 豐富的設備驅動源碼,如串口、乙太網、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、鍵盤等;
⑦ 較為豐富的開發調試文檔與強大的網路技術支持;
其實,把u-boot可以理解為是一個小型的操作系統。
04 u-boot的目錄結構
* board 目標板相關文件,主要包含SDRAM、FLASH驅動;
* common 獨立於處理器體系結構的通用代碼,如內存大小探測與故障檢測;
* cpu 與處理器相關的文件。如mpc8xx子目錄下含串口、網口、LCD驅動及中斷初始化等文件;
* driver 通用設備驅動,如CFI FLASH驅動(目前對INTEL FLASH支持較好)
* doc U-Boot的說明文檔;
* examples可在U-Boot下運行的示常式序;如hello_world.c,timer.c;
* include U-Boot頭文件;尤其configs子目錄下與目標板相關的配置頭文件是移植過程中經常要修改的文件;
* lib_xxx 處理器體系相關的文件,如lib_ppc, lib_arm目錄分別包含與PowerPC、ARM體系結構相關的文件;
* net 與網路功能相關的文件目錄,如bootp,nfs,tftp;
* post 上電自檢文件目錄。尚有待於進一步完善;
* rtc RTC驅動程序;
* tools 用於創建U-Boot S-RECORD和BIN鏡像文件的工具;
05 u-boot的工作模式
U-Boot的工作模式有 啟動載入模式和下載模式 。啟動載入模式是Bootloader的正常工作模式,嵌入式產品發布時,Bootloader必須工作在這種模式下,Bootloader將嵌入式操作系統從FLASH中載入到SDRAM中運行,整個過程是自動的。 下載模式 就是Bootloader通過某些通信手段將內核映像或根文件系統映像等從PC機中下載到目標板的SDRAM中運行,用戶可以利用Bootloader提供的一些令介面來完成自己想要的操作,這種模式主要用於測試和開發。
06 u-boot的啟動過程
大多數BootLoader都分為stage1和stage2兩大部分,U-boot也不例外。依賴於cpu體系結構的代碼(如設備初始化代碼等)通常都放在stage1且可以用匯編語言來實現,而stage2則通常用C語言來實現,這樣可以實現復雜的功能,而且有更好的可讀性和移植性。
1、 stage1(start.s代碼結構)
U-boot的stage1代碼通常放在start.s文件中,它用匯編語言寫成,其主要代碼部分如下:
(1) 定義入口。由於一個可執行的image必須有一個入口點,並且只能有一個全局入口,通常這個入口放在rom(Flash)的0x0地址,因此,必須通知編譯器以使其知道這個入口,該工作可通過修改連接器腳本來完成。
(2)設置異常向量(exception vector)。
(3)設置CPU的速度、時鍾頻率及中斷控制寄存器。
(4)初始化內存控制器 。
(5)將rom中的程序復制到ram中。
(6)初始化堆棧 。
(7)轉到ram中執行,該工作可使用指令ldrpc來完成。
2、 stage2(C語言代碼部分)
lib_arm/board.c中的start armboot是C語言開始的函數,也是整個啟動代碼中C語言的主函數,同時還是整個u-boot(armboot)的主函數,該函數主要完成如下操作:
(1)調用一系列的初始化函數。
(2)初始化flash設備。
(3)初始化系統內存分配函數。
(4)如果目標系統擁有nand設備,則初始化nand設備。
(5)如果目標系統有顯示設備,則初始化該類設備。
(6)初始化相關網路設備,填寫ip,c地址等。
(7)進入命令循環(即整個boot的工作循環),接受用戶從串口輸入的命令,然後進行相應的工作。
07 基於cortex-a8的s5pc100bootloader啟動過程分析
s5pc100支持兩種啟動方式,分別為USB啟動方式和NandFlash啟動方式:
1. S5PC100 USB啟動過程
[1] A8 reset, 執行iROM中的程序
[2] iROM中的程序根據S5PC100的配置管腳(SW1開關4,撥到4對面),判斷從哪裡啟動(USB)
[3] iROM中的程序會初始化USB,然後等待PC機下載程序
[4] 利用DNW程序,從PC機下載SDRAM的初始化程序到iRAM中運行,初始化SDRAM
[5] SDRAM初始化完畢,iROM中的程序繼續接管A8, 然後等待PC下載程序(BootLoader)
[6] PC利用DNW下載BootLoader到SDRAM
[7] 在SDRAM中運行BootLoader
2. S5PC100 Nandflash啟動過程
[1] A8 reset, 執行IROM中的程序
[2] iROM中的程序根據S5PC100的配置管腳(SW1開關4,撥到靠4那邊),判斷從哪裡啟動(Nandflash)
[3] iROM中的程序驅動Nandflash
[4] iROM中的程序會拷貝Nandflash前16k到iRAM
[5] 前16k的程序(BootLoader前半部分)初始化SDRAM,然後拷貝完整的BootLoader到SDRAM並運行
[6] BootLoader拷貝內核到SDRAM,並運行它
[7] 內核運行起來後,掛載rootfs,並且運行系統初始化腳本
08 u-boot移植(基於cortex_a8的s5pc100為例)
1.建立自己的平台
(1).下載源碼包2010.03版本,比較穩定
(2).解壓後添加我們自己的平台信息,以smdkc100為參考版,移植自己s5pc100的開發板
(3).修改相應目錄的文件名,和相應目錄的Makefile,指定交叉工具鏈。
(4).編譯
(5).針對我們的平台進行相應的移植,主要包括修改SDRAM的運行地址,從0x20000000
(6).「開關」相應的宏定義
(7).添加Nand和網卡的驅動代碼
(8).優化go命令
(9).重新編譯 make distclean(徹底刪除中間文件和配置文件) make s5pc100_config(配置我們的開發板) make(編譯出我們的u-boot.bin鏡像文件)
(10).設置環境變數,即啟動參數,把編譯好的u-boot下載到內存中運行,過程如下:
1. 配置開發板網路
ip地址配置:
$setenv ipaddr 192.168.0.6 配置ip地址到內存的環境變數
$saveenv 保存環境變數的值到nandflash的參數區
網路測試:
在開發開發板上ping虛擬機:
$ ping 192.168.0.157(虛擬機的ip地址)
如果網路測試失敗,從下面幾個方面檢查網路:
1. 網線連接好
2. 開發板和虛擬機的ip地址是否配置在同一個網段
3. 虛擬機網路一定要採用橋接(VM--Setting-->option)
4. 連接開發板時,虛擬機需要設置成 靜態ip地址
2. 在開發板上,配置tftp伺服器(虛擬機)的ip地址
$setenv serverip 192.168.0.157(虛擬機的ip地址)
$saveenv
3. 拷貝u-boot.bin到/tftpboot(虛擬機上的目錄)
4. 通過tftp下載u-boot.bin到開發板內存
$ tftp 20008000(內存地址即可) u-boot.bin(要下載的文件名)
如果上面的命令無法正常下載:
1. serverip配置是否正確
2. tftp服務啟動失敗,重啟tftp服務
#sudo service tftpd-hpa restart
5. 燒寫u-boot.bin到nandflash的0地址
$nand erase 0(起始地址) 40000(大小) 擦出nandflash 0 - 256k的區域
$nand write 20008000((緩存u-boot.bin的內存地址) 0(nandflash上u-boot的位置) 40000(燒寫大小)
6. 切換開發板的啟動方式到nandflash
1. 關閉開發板
2. 把SW1的開關4撥到4的那邊
3. 啟動開發板,它就從nandflash啟動
㈢ 嵌入式中的移植是什麼意思,移植系統呢
與其它操作系統相比,Linux最大的特點:它是一款遵循GPL的操作系統,我們可以自由
地使用、修改、和擴展它。正是由於這一特色,Linux受到越來越多人士的青睞。於是,
一個經常會被探討的問題出現了,即關於Linux系統的移植。對於操作系統而言,這種移
植通常是跨平台的、與硬體相關的,即硬體系統結構、甚至CPU不同。下面就讓我們來看
看在Linux系統移植方面,我們都需要做些什麼。
一、Linux系統移植的兩大部分
對於系統移植而言,Linux系統實際上由兩個比較獨立的部分組成,即內核部分和系
統部分。通常啟動一個Linux系統的過程是這樣的:一個不隸屬於任何操作系統的載入程
序將Linux部分內核調肢兄慧入內存,並將控制權交給內存中Linux內核的第一行代碼。載入程
序的工作就完了,此後Linux要將自己的剩餘部分全部載入到內存(如果有的話,視硬體
平台的不同而不同),初始化所有的設備,在內存中建立好所需的數據結構(有關進程
、設備、內存等)。到此為止Linux內核的工作告一段落,內核已經控制了所有硬體設備
。至於操作和使用這些硬體設備,則輪到系統部分上場了。內核載入根設備並啟動init
守護進程,init守護進程會根據配置文件載入文件系統、配置網路、服務進程、終端等
。一旦終端初始化完畢,我們就會看到系統的歡迎界面了。小結一下:
(1)內核部分初始化和控制所有硬體設備(嚴格說不是所有,而是絕大部分),為內存
管理、進程管理、設備讀寫等工作做好一切准備。
(2)系統部分載入必需的設備,配置各種環境以便用戶可以使用整個系統。
二、系統移植所必需的環境
在進一步敘述之前,我們有必要提一下做系統移植所必需的環境。
首先,需要一個新版本的gcc。對於一個准備系統移植的程序員而言,「新」到什麼
程度應該心裡有數。做跨平台編譯,gcc也許是最好的選擇。另外,Linux內核依賴許多
gcc特有的特性,非它不可。如果你已經會使用gcc並實地操練過多回,那你只需要再進
一步鞏固一下跨平台編譯的操作即可。兩種編譯環境是可用的:非目標平台上的Linux或
目標平台上的非Linux系統,除非你的開發平台過於特殊,否則你一定能夠找到你能用的
gcc。
其次,編譯鏈接庫是必需的,而且必須是目標平台的編譯鏈接庫。通常這歷答是一個枯
燥、繁瑣、又絲毫沒有成就感的過程。幸運的話,會有現成的鏈接庫可以用。否則,你
需要自己用gcc建立它。
最後,需要目標平台的所有文檔,越多越好。如果有一定的開發支持/模擬環境,L
oader(載入程序)則最好,這些可以幫助你減少移植過程中浪費在瑣事上的時間。
三、Linux系統移植
接下來我們從內核和系統兩個方面描述一下移植中的關鍵。
(1) 內存移植
Linux系統採用了相對來說並不是很靈活的單一內核機制,但這絲毫沒有影響Linux
系統的平台無關性和可擴展性。Linux使用了兩種途徑分別解決這些問題,很乾凈利落,
絲毫不拖泥帶水,而且十分清晰易懂。分離硬體相關代碼和硬體無關代碼,使上層代碼
永遠不必關心低層換用了什麼代碼,如何完成了操作。不論對x86上還是在Alpha平台上
分配一塊內存,對上層代碼而言沒什麼不同。硬體相關部分的代碼不多,占總代碼量的
很少一部分。所以對更換硬體平台來說,沒有什麼真正的負擔。另一方面,Linux使用內
核機制很好地解決了擴展的問題,一堆代碼可以在需要的時候輕松地載入或卸下,象隨
身聽,需要的時候帶上,不需要時則鎖在抽屜里。
Linux內核可以視為由五個功能部分組成:進程管理(包括調度和通信)、內存管理
、設備管理、虛擬文件系統、網路。它們之間有著復雜的調用關系,但幸運的是,在移
植中不會觸及到太多,因為Linux內核良好的分層結構將硬體相關的代碼獨立出來。何謂
硬體相關,何謂無關?以進程管理為例,對進程的時間片輪轉調度演算法在所有平台的Li
nux中都是一樣的,它是與平台無關的;而用來在進程中切換的實現在不同的CPU上是不
同的,因此需要針對該平台編寫代碼,這就是平台相關的。上面所講的五個部分的順序
不是隨便排的,從前到後分別代表著它們與硬體設備的相關程度。越靠前越高,後面的
兩個虛擬文件系統和網路則幾乎與平台無關,它們由設備管理中所支持塵森的驅動程序提供
底層支持。因此,在做系統移植的時候,需要改動的就是進程管理、內存管理和設備管
理中被獨立出來的那部分即硬體相關部分的代碼。在Linux代碼樹下,這部分代碼全部在
arch目錄下。
如果你的目標平台已經被Linux核心所支持的話,那麼你是幸運的,因為已經沒有太
多的工作讓你去做。只要你的交叉編譯環境是正確的,你只需要簡單的配置、編譯就可
以得到目標代碼。否則,需要你去編寫,或修改一些代碼。只需修改平台相關部分的代
碼即可。但需要對目標平台,主要是對CPU的透徹理解。在Linux的代碼樹下,可以看到
,這部分的典型代碼量為:2萬行左右C代碼和2千行左右的匯編(C代碼中通常包含許多
偽匯編指令,因此實際上純C代碼要少很多),這部分工作量是不可小看的。它包含了對
絕大多數硬體的底層操作,涉及IRQ、內存頁表、快表、浮點處理、時鍾、多處理器同步
等問題,頻繁的埠編程意味著需要你將目標平台的文檔用C語言重寫一遍。這就是為什
么說目標平台的文檔極其重要。
代碼量最大的部分是被核心直接調用的底層支持部分,這部分代碼在arch/xxx/ker
nel下(xxx是平台名稱)。這些代碼重寫了內核所需調用的所有函數。因為介面函數是固
定的,所以這里更象是為硬體平台編寫API。不同的系統平台,主要有以下幾方面的不同
:
進程管理底層代碼:從硬體系統的角度來看,進程管理就是CPU的管理。在不同的硬
件平台上,這有很大的不同。CPU中用的寄存器結構不同,上下文切換的方式、現場的保
存和恢復、棧的處理都不同,這些內容主要由CPU開發手冊所描述。通常來說,CPU的所
有功能和狀態對於Linux不一定有意義。實現時,需要在最小的開發代價和最好的系統性
能之間加以權衡。
* BIOS介面代碼:這一名稱似乎並不太准確,因為它沿用了PC一貫的叫法。但在不致引
起混淆的情況下我們還是這么叫它。在通用平台上,通常有基本輸入輸出系統供操作系
統使用,在PC上是BIOS,在SPARC上是PROM,在很多非通用系統上甚至並沒有這樣的東西
。多數情況下,Linux不依賴基本輸入輸出系統,但在某些系統里,Linux需要通過基本
輸入輸出系統中得到重要的設備參數。移植中,這部分代碼通常需要完全改寫。
* 時鍾、中斷等板上設備支持代碼:即使在同一種CPU的平台上,也會存在不同的板上外
設,異種CPU平台上更是如此。不同的系統組態需要不同的初始化代碼。很典型的例子就
是MIPS平台,看看arc/mips/的代碼,與其它系統比較一下就知道。因為MIPS平台被OEM
得最廣,在嵌入式領域應用最多(相對其它幾種CPU而言)。甚至同一種MIPS晶元被不同
廠家封裝再配上不同的晶元組。因此要為這些不同的MIPS平台分別編寫不同的代碼。
* 特殊結構代碼:如多處理器支持等。其實每一種CPU都是十分特殊的,熟悉x86平台的
人都知道x86系列CPU著名的實模式與虛模式的區別,而在SPARC平台上根本就沒有這個概
念。這就導致了很大的不同:PC機上的Linux在獲得控制權後不久就開始切換到虛模式,
SPARC機器上則沒有這段代碼。又如電源管理的支持更是多種多樣,不同的CPU有著不同
的實現方式(特殊的電源管理方式甚至被廠商標榜)。在這種情況下,除非放棄對電源
管理的支持,否則必須重寫代碼。
還有一部分代碼量不多,但不能忽視的部分是在arch/xxx/mm/下的內存管理部分。
所有與平台相關的內存管理代碼全部在這里。這部分代碼完成內存的初始化和各種與內
存管理相關的數據結構的建立。Linux使用了基於頁式管理的虛擬存儲技術,而CPU發展
的趨勢是:為了提高性能,實現內存管理的功能單元統統被集成到CPU中。因此內存管理
成為一個與CPU十分相關的工作。同時內存管理的效率也是最影響系統性能的因素之一。
內存可以說是計算機系統中最頻繁訪問的設備,如果每次內存訪問時多佔用一個時鍾周
期,那就有可能將系統性能降低到不可忍受。在Linux系統里,不同平台上的內存管理代
碼的差異程度是令人吃驚的,可以說是差異最大的。不同的CPU有不同的內存管理方式,
同一種CPU還會有不同的內存管理模式。Linux是從32位硬體平台上發展起來的操作系統
,但是現在已經有數種64位平台出現。在64位平台上,可用內存范圍增大到原來的232倍
,其間差異可略窺一斑了。鑒於這部分代碼的重要性和復雜性,移植工作在這里變得相
當謹慎。有些平台上甚至只是用最保守的內存管理模式。如在SPARC平台上的頁面大小可
以是多種尺寸,為了簡單和可靠起見,SPARC版的Linux只是用了8K頁面這一種模式。這
一狀況直到2.4版才得以改善。
除了上面所講的之外,還有一些代碼需要考慮,但相對來說次要一些。如浮點運算
的支持。較完美的做法是對FPU編程,由硬體完成浮點運算。但在某些時候,浮點並不重
要,甚至CPU根本就不支持浮點。這時候就可以根據需求來取捨。
對於內核移植的討論到此為止。實際上,還有一些移植工作需要同時考慮,但很難
說這是屬於內核范疇還是屬於驅動程序范疇,比如說顯示設備的支持,和內核十分相關
,但在邏輯上又不屬於內核,並且在移植上也更像是驅動程序的開發。因此不在這里討
論。
(2)系統移植
當內核移植完畢後,可以說所有的移植工作就已經完成大半了。就是說,當內核在
交叉編譯成功後,載入到目標平台上正常啟動,並出現類似VFS: Can抰 mount root fi
le system的提示時,則表示可以開始系統移植方面的工作了。系統移植實際上是一個最
小系統的重建過程。許多Linux愛好者有過建立Linux系統應急盤的經驗,與其不同的是
,你需要使用目標平台上的二進制代碼生成這個最小系統。包括:init、libc庫、驅動
模塊、必需的應用程序和系統配置腳本。一旦這些工作完成,移植工作就進入聯調階段
了。
一個比較容易的系統部分移植辦法是:先著手建立開發平台上的最小系統,保證這
套最小系統在開發平台上正確運行。這樣可以避免由於最小系統本身的邏輯錯誤而帶來
的麻煩。由於最小系統中是多個應用程序相互配合工作,有時出現的問題不在代碼本身
而在系統的邏輯結構上。
Linux系統移植工作至少要包括上述的內容,除此之外,有一些看不見的開發工作也
是不可忽視的,如某個特殊設備的驅動程序,為調試內核而做的遠程調試工作等。另外
,同樣的一次移植工作,顯然符合最小功能集的移植和完美移植是不一樣的;向16位移
植和向64位移植也是不一樣的。
在移植中通常會遇見的問題是試運行時鎖死或崩潰,在系統部分移植時要好辦些,
因為可以容易地定位錯誤根源,而在核心移植時確實很讓人頭疼。雖然可以通過串口對
運行著的內核進行調試,但是在多任務情況下,有很多現象是不可重現的。又如,在初
始化的開始,很多設備還沒法確定狀態,甚至串口還沒有初始化。對於這種情況沒有什
么很好的解決辦法,好的開發/模擬平台很重要,另外要多增加反映系統運行狀態的調試
代碼;再者要吃透硬體平台的文檔。硬體平台廠商的專業支持也是很重要的。
還有一點很重要:Linux本身是基於GPL的操作系統,移植時,可以充分發揮GPL的優
勢,讓更多的愛好者參與進來,向共同的目標前進。
㈣ arm-linux-gcc交叉編譯器的製作,以及版本選擇問題。
,需要必須有足夠動經驗來支持。
另外,用 RH9 的都是高手,我想你的知識不需要來提問了吧?
1、在 PC 上編譯 arm 的程序當然需要較差編譯器,這個需要自己安裝,或者著現成的交叉編譯器環境,一般是一個特殊參數編譯出來的 gcc + binutils + glibc + linux-header。這個每個人動環境不同,一般都需要自己編譯一個,當然沒有特殊需求,也可以找現成的。不過很難找,因為這套環境還要和你動系統搭配,不然環境不匹配,連這個環境都不能運行,那就更談不上編譯東西了。
有關自己編譯搭建交叉編譯環境,可以看看一個特殊的 Linux 發行版 LFS 的分支: CLFS 。
2、移植分很多意思,移植有可能就意味著這套源代碼不能在目標系統上面編譯,需要你根據相應的知識去修改源代碼來讓這套代碼適應目標編譯器的要求,比如源代碼有 SSE4 的優化,這套程序在非 SSE4 CPU 上無法編譯運行,但目標機器連 SSE1 都不支持。那麼就需要移植。
或者移植僅僅是根據新的環境進行編譯,不需要進行源代碼修改,只需要進行一下編譯就能運行的程序,也可以稱為移植,就是從一個環境、架構 -》另一個環境、架構。都可以稱為移植,但真正的移植意味著修改程序源代碼來適應新環境。你說的這種移植是最簡單的移植。
3、決定目標硬體環境 -》搭建目標編譯器 -》製作目標環境(內核,基礎軟體庫)-》進行應用移植(移植需要的軟體、主應用程序)-》搭建系統文件系統 -》導入目標系統-》啟動目標系統&應用。說起來很簡單,因為這是完全沒有問題的條件下。
至於超級終端。那是用來控制目標系統的。目標系統有可能不能插鍵盤滑鼠顯示器,這就需要一個遠程網路鏈接來進行控制。以及通過遠程鏈接來發送數據。這都需要終端的支持。
虛擬機下面進行開發,不能發揮你的計算機的性能。而且因為隔著 VMware 的軟體模擬層,可能還不會很方便的讓你鏈接目標設備。
至於用 socket ,我還沒見到你的目標需要這個東西,因為所有的東西都是現成的源代碼。不需要你從 0 開始寫,當然你想自己寫一個系統內核,或者伺服器程序,或者全套的系統+應用,我絕對不攔你,但希望你寫完這套東西,能把源代碼發布出來。
ads 可以認為是一個支持環境,他本身不是一個系統的開發 SDK 。
-------------------------------------
ads 沒用過,印象里他還有模擬器,調試器什麼的程序。功能上要比 Linux 開發環境,WinCE 環境下面的東西更多更偏向於硬體方面,畢竟 ads 是 arm 出品的,不太可能偏向於軟體部分設計。Linux 和 WinCE 都是系統而不是硬體工具。
你可以認為交叉編譯器是一個應用程序,一個輸出器。把源代碼輸出為 arm 的代碼,這個應用程序的輸出,是靠他自己的環境,而不是當前系統的環境的。
當前系統的各個軟體的版本,不能影響交叉編譯器輸出的環境(理論上,現實有的時候總是從別的地方給你打擊……),交叉編譯器一般至少有 gcc 、binutils 、glibc 庫、linux kernel 頭文件。
在軟體需求上。
頭文件誰都不依賴,glibc 只需要內核頭文件,其他程序全都依賴於 glibc 。也就是所有程序都不依賴內核,僅僅是依賴於內核頭文件。
gcc 和 binutils 是把程序源代碼根據上面各個環節的需提供的功能來輸出為上面環節裡面的二進製程序。依賴你當前環境的,只有 gcc 和 binutils 兩個程序的執行、控制環節。只有他們兩個依賴的,而不是你的交叉編譯後的程序。
至於編譯器版本的選擇,新版本功能更好,舊版本兼容更好。
這個要看你的實際需要了。應用程序源代碼也調編譯器的,同時也依賴於軟體庫的功能。
arm 開發建議穩定、兼容優先。當然也可以嘗試最新的編譯環境,來獲取更好的優化(前提是還有什麼代碼優化的話)。
另外,團IDC網上有許多產品團購,便宜有口碑
㈤ 為什麼做系統移植要用交叉編譯環境
如果不交叉編譯的話就得在目標架構體系的實體機或者專門的虛擬機裡面完成編譯。這還要涉及到不同機器之間的編譯環境匹配問題。你說是在現有開發平台加一個交叉編譯參數方便還是重新配置開發環境還要手動作代碼文件轉移、新建工程這些步驟加起來麻煩
㈥ 如何使用ARM+Cortex-A9的移植一個Linux操作系統,作為伺服器
要在ARM Cortex-A9上移植Linux操作系統並將其用作伺服器,需要執行以下步驟:
選擇適當的Linux發行版:首先,需要選擇適合ARM Cortex-A9的Linux發行版。一些流行的ARM Linux發行版包括Ubuntu、Debian、Fedora、OpenSUSE等。您可以從官方網站下載適合您的ARM Cortex-A9的版本。
下載交叉編譯工具鏈:由於ARM Cortex-A9是基於ARM架構的,因此需要使用交叉編譯工具鏈來編譯Linux內核和應用程序。您可以從ARM官方網站下載適合您的交叉編譯工具鏈。
編譯內核:使用交叉編譯工具鏈編譯Linux內核。您可以從Linux內核官方網站下載最新版本的內核源代碼,並使用交叉編譯工具鏈進行編譯。編譯完成後畝塵,將內核鏡像文件復制到ARM Cortex-A9的啟動設備中。
配置文件系統:在ARM Cortex-A9上運行Linux操作系絕耐敏統需要一個文件系統。您可以使用BusyBox等工具來創建一個最小的文件系統。將文件系統復制到並枝ARM Cortex-A9的啟動設備中。
啟動Linux操作系統:將啟動設備插入ARM Cortex-A9,並將其連接到計算機。使用串口或SSH等工具連接到ARM Cortex-A9,並啟動Linux操作系統。如果一切正常,您應該能夠登錄到Linux系統並使用它作為伺服器。
配置伺服器:根據您的需求配置Linux伺服器。您可以安裝Web伺服器、資料庫伺服器、FTP伺服器等,以滿足您的需求。