系統移植的四大步驟

最近在學習系統移植的相關知識,在學習和調試過程中,發現了很多問題,也解決了很多問題,但總是對于我們的開發結果有一種莫名其妙的感覺,糾其原因,主要對于我們的開發環境沒有一個深刻的認識,有時候幾個簡單的命令就可以完成非常復雜的功能,可是我們有沒有想過,為什么會有這樣的效果?如果沒有去追問,只是機械地完成,并且看到實驗效果,這樣做其實并沒有真正的掌握系統移植的本質。
在做每一個步驟的時候,首先問問自己,為什么要這樣做,然后再問問自己正在做什么?搞明白這幾個問題,我覺得就差不多了,以后不管更換什么平臺,什么芯片,什么開發環境,你都不會迷糊,很快就會上手。對于嵌入式的學習方法,我個人方法就是:從宏觀上把握(解決為什么的問題),微觀上研究(解決正在做什么的問題),下面以自己學習的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的選擇和移植
一、Boot Loader 概念
? ? ? ?就是在操作系統內核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設備、建立內存空間的映射圖,從而將系統的軟硬件環境帶到一個合適的狀態,以便為最終調用操作系統內核準備好正確的環境,他就是所謂的引導加載程序(Boot Loader)。

【圖1】Flash存儲中存放文件的分布圖
?二、為什么系統移植之前要先移植BootLoader?
? ? ??BootLoader的任務是引導操作系統,所謂引導操作系統,就是啟動內核,讓內核運行就是把內核加載到內存RAM中去運行,那先問兩個問題:第一個問題,是誰把內核搬到內存中去運行?第二個問題:我們說的內存是SDRAM,大家都知道,這種內存和SRAM不同,最大的不同就是SRAM只要系統上電就可以運行,而SDRAM需要軟件進行初始化才能運行,那么在把內核搬運到內存運行之前必須要先初始化內存吧,那么內存是由誰來初始化的呢?其實這兩件事情都是由bootloader來干的,目的是為內核的運行準備好軟硬件環境,沒有bootloadr我們的系統當然不能跑起來。

三、bootloader的分類。
????? 首先更正一個錯誤的說法,很多人說bootloader就是U-boot,這種說法是錯誤的,確切來說是u-boot是bootloader的一種。也就是說bootloader具有很多種類,大概的分類如下圖所示:
【圖2】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可以理解為是一個小型的操作系統。

四、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鏡像文件的工具;

五、u-boot的工作模式
? ? ??U-Boot的工作模式有啟動加載模式和下載模式。啟動加載模式是Bootloader的正常工作模式,嵌入式產品發布時,Bootloader必須工作在這種模式下,Bootloader將嵌入式操作系統從FLASH中加載到SDRAM中運行,整個過程是自動的。下載模式就是Bootloader通過某些通信手段將內核映像或根文件系統映像等從PC機中下載到目標板的SDRAM中運行,用戶可以利用Bootloader提供的一些令接口來完成自己想要的操作,這種模式主要用于測試和開發。

六、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的工作循環),接受用戶從串口輸入的命令,然后進行相應的工作。

七、基于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,并且運行系統初始化腳本

八、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啟動

第三部分:kernel的配置、編譯、和移植

一、將下載好的linux-2.6.35.tar.bz2拷貝到主目錄下解壓

二、修改頂層目錄下的Makefile,主要修改平臺的體系架構和交叉編譯器,代碼如下:
? ? ??ARCH ? ??= $(SUBARCH)
? ? ??CROSS_COMPILE ??=
? ? ??CROSS_COMPILE ??= $(CONFIG_CROSS_COMPILE:"%"=%)
??????修改以上代碼為:
? ? ??ARCH ? ??= arm ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ---->體系架構是arm架構
? ? ?CROSS_COMPILE ??= arm-cortex_a8-linux-gnueabi- ? ?---->交叉編譯器是arm-cortex_a8平臺的
????? 注意:這兩個變量值會直接影響頂層Makefile的編譯行為,即選擇編譯哪些代碼,用什么編譯器進行編譯。

三、拷貝標準版配置文件,目的是得到跟我們開發板相關的配置信息。

$ cp arch/arm/configs/s5pc100_defconfig ? ?.config
? ? ? 這里拷貝arch/arm/configs/s5pc100_defconfig到 ?.config文件是選取跟我們開發板相關的代碼。因為Linux支持的平臺非常非常多,不僅僅是ARM處理器,當然我們編譯的時候只需要編譯跟我們平臺相關的代碼就可以了,平臺相關的不需要編譯,那么就有個問題,Linux系統中的源代碼文件有一萬多以個,面對這么龐大的文件數量,我們如何去選擇呢?
? ? ? ?其實,我們擔心的問題也是寫操作系統的那哥們早就擔心過的問題了,只不過人家已經把這個問題幫我們解決了,我們只需進行很簡單的操作,就可以選擇出我們要編譯的代碼,具體的方法就是把相應平臺的_deconfig直接拷貝到頂層目錄的.config文件中,這樣.config文件中就記錄了我們要移植平臺的平臺信息,因為在配置內核時,系統會把所有的配置信息都保存在頂層目錄的.config文件中。注意在第一次,進行make menuconfig時,系統會根據我們選取的平臺信息自動選取相關的代碼和模塊,因此我們只需要進入然后再退出,選擇保存配置信息就行了,系統會把這些跟我們移植平臺相關的所有配置信息全部保存在頂層目錄的.config文件中。

四、配置內核
? ? ? $make menuconfig
? ? ?注意:第一次進去,不做任何操作,直接推出,在推出時提示是否保存配置信息,一定要保存配置信息,點擊“YES”。這樣我們的.config中就已經保存了我們開發平臺的信息。
? ? ? ?在這個環節,我們需要關心一個問題,make menuconfig時,系統到低都做了哪些事情?為什么會出現圖形化的界面?圖形化的界面中的相關內容是從哪里來的?
????? ? 圖形化的界面當然是由一個特殊的圖形庫來實現的,還記得第一次make menuconfig時,系統并沒有出現圖形化的界面,而是報錯了,并且提示我們缺少 ncurses-devel ,此時只需要按照要求安裝一個libncurses5-dev就行了,sudo apt-get install libncurses5-dev,有了這個圖形化庫的支持,我們才能夠正常顯示圖形化界面。
? ? ? ?好了,圖形化界面的問題解決了,那還有另外一個問題就是圖形化界面里面的內容是從哪里來的?要回答這個問題,我們就要提一下Linux內核的設計思想了,Linux 內核是以模塊的方式來組織這個操作系統的,那么,為什么要用模塊的方式來組織呢?模塊的概念又是什么呢?在此來一一回答這個問題。
? ? ? Linux2.6內核的源碼樹目錄下一般都會有兩個文件:Kconfig和Makefile。分布在各目錄下的Kconfig構成了一個分布式的內核配置數據庫,每個Kconfig分別描述了所屬目錄源文件相關的內核配置菜單。每個目錄都會存放功能相對獨立的信息,在每個目錄中會存放各個不同的模塊信息,比如在/dev/char/目錄下就存放了所有字符設備的驅動程序,而這些程序代碼在內核中是以模塊的形式存在的,也就是說當系統需要這個驅動的時候,會把這個驅動以模塊的方式編譯到系統的內核中,編譯分為靜態編譯和動態編譯,靜態編譯內核體積比動態編譯的體積要大,前面已經說了每個目錄下面都會有一個Kconfig的文件,我們還會問,這個文件中都存放了什么信息?前面說了,每個目錄的Kconfig文件描述了所屬目錄源文件相關的內核配置菜單,有其特殊的語法格式,圖形化界面的文字正是從這個文件中讀取出來的,如果把這個文件中的相應目錄文件的信息全部刪除,那么在圖形化界面中將看不到該模塊的信息,因此也不能進行模塊的配置。
? ? ? ?在內核配置make menuconfig(或xconfig等)時,系統會自動從Kconfig中讀出配置菜單,用戶配置完后保存到.config(在頂層目錄下生成)中。在內核編譯時,主Makefile調用這個.config,(.config的重要性就體現在,它保存了我們的所有的配置信息,是我們選取源代碼并且進行編譯源代碼的最終依據!!!)就知道了用戶對內核的配置情況。上面的內容說明:Kconfig就是對應著內核的配置菜單。假如要想添加新的驅動到內核的源碼中,可以通過修改Kconfig來增加對我們驅動的配置菜單,這樣就有途徑選擇我們的驅動,假如想使這個驅動被編譯,還要修改該驅動所在目錄下的Makefile。因此,一般添加新的驅動時需要修改的文件有兩種,即:Kconfig 和相應目錄的Makefile(注意不只是兩個),系統移植的重要內容就是給內核添加和刪除相應的模塊,因此主要修改的內核文件就是Kconfig 和相應目錄的Makefile這兩個文件。

五、編譯內核
? ? ? $make zImage
? ? ? ?通過上述操作我們能夠在 arch/arm/boot 目錄下生成一個 zImage 文件,這就是經過壓縮的內核鏡像。
? ? ? ?內核的編譯過程是非常復雜的,注意這里的編譯是靜態編譯,此時會執行頂層目錄下的Makefile中的zImage命令,在執行的過程中,會根據當前目錄的.config文件去選擇編譯源代碼。編譯內核的具體步驟比較復雜,有時間會另寫文章詳細描述。

六、通過tftp網絡服務下載測試內核
????? ?setenv bootcmd tftp 20008000(內存地址) zImage\;go 20008000
? ? ? ?setenv bootargs nfs nfsroot=192.168.1.199(虛擬機的ip):/source/rootfs ip=192.168.1.200(開發板的ip)??init=/linuxrc(第一個要啟動的用戶進程) ttySAC0,115200(設置中斷為串口1,波特率為:115200)??? ?
????? ?保存環境變量,復位開發板,測試是否能夠正常啟動(注意:在此之前應設置好需要nfs掛載的文件系統,最后才能看到效果).內核測試和啟動過程也是比較復雜的,在后續的文章中會詳細介紹。

第四部分:根文件系統的介紹
????由本文的第一張圖:Flash存儲中存放文件的分布圖可知,文件系統的制作和移植是系統移植的最后一道工序了,在這里首先要提幾個問題:
? ??1.什么是文件系統?
? ??2.如何實現文件系統?
? ? 3.常用的文件系統有哪些?為什么需要這些文件系統?
? ? 下面來一一回答這些問題:

文件系統我們在日常生活中則很少聽說,但是它確實存在,只是名字不叫文件系統罷了,一般叫資料庫。資料庫里面的文件眾多,我們如何快速準確的找到我們要的那份文件呢?資料庫采用了分類索引的方法來實現快速查找。類似于我們學校圖書館的管理方式,一樓可能是哲學類,二樓是社科類的,三樓是電子類的,四樓是計算機類的…………等等,我們把這種進行了分類索引的資料庫叫文件系統。
? ? 對于計算機而言,文件其實就是資料數據,只能存儲在物理介質上面,比如:硬盤,但是我們人不可能自己讀取物理介質上的文件,或者自己把文件寫入物理介質,物理介質上文件的讀寫只能采用程序來完成,為了方便實現,程序又被分成了物理介質驅動程序、內容存儲程序和文件內容存儲程序。物理介質驅動程序專門用于從物理介質上存取數據;內容存儲程序用于把文件內容和文件屬性信息打包;文件內容存儲程序用于把用戶輸入形成文件內容,或者取得文件內容顯示出來。

我們可以把一個文件系統(倒樹)分解成多個文件系統(倒樹)分別存放到存儲介質上,比如:一個存儲到光盤里,一個存儲到硬盤中,在使用時,我們把光盤里的文件系統的根目錄掛到硬盤文件系統的一個目錄下面,這樣訪問這個目錄就相當于是訪問光盤的根目錄了,找到了根目錄,我們也就可以訪問整個光盤上的文件系統了。

“在Linux系統中一切皆是文件”這句話是我們學習Linux系統的時候常常聽到的一句話。雖然有些夸張,但是它揭示了文件系統對于Linux系統的重要性;實際上文件系統對于所有的操作系統都很重要,因為它們把大部分的硬件設備和軟件數據以文件的形式進行管理。Linux系統對設備和數據的管理框架圖如下:


【圖3】文件系統實現

[說明]

A.?VFS(virtual?file?system)是虛擬文件系統,它管理特殊文件(虛擬文件)、磁盤文件和設備文件

B.?fs_operations結構是由一系列文件操作接口函數組成,由文件系統層來完成,為VFS提供文件操作;

C.?在文件系統層,磁盤文件要實現各種文件系統(如:ext2),設備文件要實現各種抽象的設備驅動

D.?在設備驅動層,磁盤驅動要實現各種磁盤的驅動程序,其他設備驅動要實現具體的設備驅動

E.?物理層就是設備自身

?

?


? ?為什么會有不同的文件類型?

由于存儲介質有很多種,所以沒有辦法用一種統一的格式存放文件系統到各種不同的存儲介質上,而是需要多種不同的存儲格式來適應各種存儲介質的特性,以求達到存取效率和空間利用率的最優化,這樣就需要對每種存儲格式制定一個規范,這寫規范就叫文件系統類型。常見的文件系統類型有:
1.Dos
? FAT16
2.windows
? FAT16、FAT32、NTFS
3.Linux
? Minix、ext、ext2 、ext3 、ISO9660 、jffs2, yaffs, yaffs2、cramfs, romfs, ramdisk, rootfs、proc、sysfs、usbfs、devpts、 tmpfs & ramfs、 NFS

?

? ? 由此可見,Linux支持的文件系統最多。以不同的介質來分類,如下所示:
? ?磁盤
? ??FAT16、 FAT16、FAT32、NTFS、ext、ext2 、ext3、Minix
? ?光盤
? ??ISO9660、
? ?Flash
? ??jffs2, yaffs, yaffs2、cramfs, romfs
? ?內存
? ??Ramdisk、tmpfs & ramfs
? ?虛擬
? ??rootfs、proc、sysfs、usbfs、devpts、NFS
????

常用的存儲介質理論上都可以用于存儲Linux支持的文件系統;因為我們這里只研究嵌入式系統,而嵌入式系統由于體積和移動特性的限制,不能采用磁盤和光盤,所以只能采用flash類的存儲設備、內存和虛擬存儲設備作為文件系統的存儲介質;?

flash芯片的驅動程序是由系統來提供,所以它的存取特點完全是flash自身的特點,這時最好有更加適合flash的文件系統——Jffs、Yaffs、Cramfs和Romfs。這些文件系統都是嵌入式Linux系統中常用的文件系統,可以根據特點來選擇使用它們,特點如下:
共同點
基于MTD驅動
Jffs
??A.針對NOR Flash的實現
??B.基于哈希表的日志型文件系統
??C.采取損耗平衡技術,每次寫入時都會盡量使寫入的位置均勻分布
??D.可讀寫,支持數據壓縮
??E.崩潰/掉電安全保護
??F.當文件系統已滿或接近滿時,因為垃圾收集的關系,運行速度大大放慢
Yaffs
? A.針對Nand Flash的實現
??B.日志型文件系統
??C.采取損耗平衡技術,每次寫入時都會盡量使寫入的位置均勻分布
??D.可讀寫,不支持數據壓縮
??E.掛載時間短,占用內存小
??F.自帶Nandflash驅動,可以不使用VFS和MTD
Cramfs
??A.單頁壓縮,支持隨機訪問,壓縮比高達2:1
??B.速度快,效率高
??C.只讀,有利于保護文件系統免受破壞,提高了系統的可靠性,但是無法對其內容進行擴充
Romfs
??A.簡單的、緊湊的、只讀的文件系統?
??B.順序存放數據,因而支持應用程序以XIP(execute In Place,片內運行)方式運行,在系統運行時,節省RAM空間?

????特有的文件系統類型:Ramdisk文件系統
????在Linux系統中,內存經常用于存儲文件系統,這種叫做Ramdisk,Ramdisk有兩種,一種是完全把內存看成物理存儲介質,利用內存模擬磁盤,運用磁盤的文件系統類型;另一種只是在內存中存儲了文件系統邏輯結構,運用tmpfs?&?ramfs文件系統類型:
????tmpfs & ramfs
??? 1.?概述
????用物理內存模擬磁盤分區,掛載這種分區后,就可以跟讀寫磁盤文件一樣讀寫這里面的文件,但是操作速度要比磁盤文件快得多;所以一般應用在下面幾個方面:
? ? 1)讀寫速度要求快的文件應該放在這種文件系統中
? ? 2)磁盤分區為flash的情況下,把需要經常讀寫的文件放在這種文件系統中,然后定期寫回flash
? ? 3)系統中的臨時文件,如/tmp、/var目錄下的文件應該放在這種文件系統中
? ? 4)/dev設備文件(因為設備文件隨驅動和設備的加載和卸載而變化),應該放在這種文件系統中
? ? 2.?特點?
? ? 1)由于數據都存放在物理內存中,所以系統重啟后,這個文件系統中的數據會全部丟失
? ? 2)ramfs在沒有指定最大的大小值情況下,會自動增長,直到用掉系統中所有的物理內存為止,這時會導致系統的崩潰,建議掛載時最好限定其最大的大小值
? ? 3)tmpfs如果指定了大小值,自動增長至大小值后,系統會限定它的大小;這個文件系統占用的物理內存頁可以背置換到swap分區,但是ramfs不行

?

?

? ? 不同的文件系統具有不同的制作方法,有的比較復雜,有的比較簡單,在此由于篇幅限制,先不做介紹,在后續的文章中會單獨介紹文件系統的制作。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457445.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457445.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457445.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bem什么意思_bem是什么意思_bem的翻譯_音標_讀音_用法_例句_愛詞霸在線詞典

全部Methods Three different concentrations of the n - butanol extract of MOH ( BEM ) : 0.038 g L ~ ( - 1 ), 0.11 g L ~ ( - 1 ) and 0.34 g L ~ ( - 1 ) were prepared.巴戟天醇提取物 ( BEM ) 配成含生藥0.038gL~ ( -1)、0.11gL~ ( -1 ) 、 0.34gL~ ( -1 ) 三種濃度…

display:flex

flex:彈性布局 常用屬性介紹: flex-direction: column (設置主容器主軸方向) flex-flow: row wrap (第一個參數為flex-direction,第二個為flex-wrap) align-items: flex-start (設…

Linux(Ubuntu 19.10)下 Qt5 連接 MySQL(QMYSQL driver not loaded)

Linux(Ubuntu 19.10)下 Qt5 連接 MySQL 安裝好 MySQL 和 Qt Qt 連接 MySQL 的代碼 QSqlDatabase dQSqlDatabase::addDatabase("QMYSQL");//加載mysql驅動,這個字符串是固定的 d.setHostName("127.0.0.1"); d.setDatabas…

華為消息推送 有透傳通道嗎_求解在推送用透傳消息-使用廠商通道(我用的是基座測試) 用手機測試出現了“clientId離線”問題...

// #ifdef APP-PLUS// uni.showModal({// title: 提示,// content: 您的用戶在其它的app登錄,如果有問題,請修改密碼或重新登錄!,// cancelText:"修改密碼",// confirmText:"好的",// success: function (res) {// if (r…

oneuijs/You-Dont-Need-jQuery

oneuijs/You-Dont-Need-jQuery https://github.com/oneuijs/You-Dont-Need-jQuery/blob/master/README.zh-CN.mdYou Dont Need jQuery 前端發展很快,現代瀏覽器原生 API 已經足夠好用。我們并不需要為了操作 DOM、Event 等再學習一下 jQuery 的 API。同時由于 React…

Wpf 數據綁定簡介、實例1

簡介:1.WPF綁定使用的源屬性必須是依賴項屬性,這是因為依賴項屬性具有內置的更改通知支持,元素綁定表達式使用了Xaml擴展標記, WPF綁定一個控件是使用Binding.ElementName, 綁定非控件對象時使用Source,RelativeSource,DataContex…

【設計模式 04】代理模式

代理模式 代理模式( Proxy):為其他對象提供一種代理以控制對這個對象的訪問。 參考:refactoringguru | proxy 什么是代理模式 有時候如果想要訪問某個對象,但又沒辦法直接訪問或不方便直接訪問,可以使用代理模式,代理…

css 大于號 標簽_CSS設計基礎選擇器篇

點擊上方 Java項目學習 ,選擇 星標 公眾號重磅資訊、干貨,第一時間送達前言:如果將CSS樣式應用于特定的網頁對象上,需要先找到目標元素。在CSS樣式中執行這一任務的部分被稱為選擇器。1 標簽選擇器優點:為頁面中同類型…

CSDN博客投票活動開始了

自己堅持寫博客,一方面是為了將自己對知識點的理解做一個總結,另一方面也是因為自己看到了很多無私奉獻分享自己知識的小伙伴們,因此自己也想像他們那樣盡自己微薄之力把自己對某一知識點的理解分享給大家,或許算不上什么特高級的…

crontab 提示 command not found 解決方案

crontab 提示 command not found 解決方案 今天遇見一個問題,crontab的定時任務會報錯:java command not found,但是手動執行腳本一直能成功。 猜想是環境變量的問題。 在crontab里添加個打印環境變量的任務: * * * * * echo $PAT…

java中文亂碼decode_Java中文亂碼處理

java編碼轉換過程我們總是用一個java類文件和用戶進行最直接的交互(輸入、輸出),這些交互內容包含的文字可能會包含中文。無論這些java類是與數據庫交互,還是與前端頁面交互,他們的生命周期總是這樣的:1、程序員在操作系統上通過編…

【設計模式 05】工廠方法模式

工廠方法模式 define an interface or abstract class for creating an object but let the subclasses decide which class to instantiate. 參考: refactoringguru | factory-methodjavatpoint | factory-method-design-pattern博客園| 工廠方法 簡單工廠的問題 …

[C++]宏定義#define A B C

C關于宏定義的用法,有形如#define A B C的格式,此時B和C都是已知的字符串常量. 在宏定義中. 可以把兩個常量字符串連在一起 如果#define A "a" 那么宏定義#define STRING A "bc" 就相當于 #define STRING "abc" 這里&…

LinkedList類源碼淺析(二)

1、上一節介紹了LinkedList的幾個基本的方法,其他方法類似,就不一一介紹; 現在再來看一個刪除的方法:remove(Object o) remove方法接受一個Object參數,這里需要對參數做空與非空處理; 但是刪除一個Object元…

【設計模式 06】原型模式(克隆??)

原型模式(clone?) Prototype pattern refers to creating duplicate object while keeping performance in mind. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object. 參考: tutori…

2016OSC源創會年終盛典-綜合技術專場-張小剛

2019獨角獸企業重金招聘Python工程師標準>>> 綜合技術專場 講師/SPEAKERS 張小剛 網易云負載均衡項目負責人 《網易蜂巢負載均衡技術實踐》從網易蜂巢中的實踐出發,分享網易蜂巢負載均衡服務從無到有,從私有云到公有云過程中的技術實踐。重點…

python策略模式包含角色_詳解Python設計模式之策略模式

雖然設計模式與語言無關,但這并不意味著每一個模式都能在每一門語言中使用。《設計模式:可復用面向對象軟件的基礎》一書中有 23 個模式,其中有 16 個在動態語言中“不見了,或者簡化了”。1、策略模式概述策略模式:定義…

mysql 日期

數據類型 數據類型格式date YYYY-MM-DD datetime YYYY-MM-DD HH:MM:SS timestamp YYYY-MM-DD HH:MM:SS year YYYY 或 YY 具體實現的函數 1、now() 返回當前的日期和時間 SELECT NOW(); 2、curdate() 返回當前的日期 SELECT CURdate(); 3、curtime()返回當…

【Go】panic: reflect: call of reflect.Value.FieldByName on ptr Value

產生原因 調用 FieldByName()方法時,調用者與預期類型不相符。 // 錯誤代碼 func setNewArticleInfoToCache(article *Article) {fields : []string{"Title", "Abstract", "ID", "AuthorID", "CreateTime",}im…

超完整的 Chrome 瀏覽器客戶端調試大全

2019獨角獸企業重金招聘Python工程師標準>>> 引言 “工欲善其事,必先利其器” 沒錯,這句話個人覺得說的特別有道理,舉個例子來說吧,厲害的化妝師都有一套非常專業的刷子,散粉刷負責定妝,眼影刷負…