版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
基于Linux的嵌入式軟件開發(fā)2023/2/61內(nèi)容提要:3.1嵌入式軟件結(jié)構(gòu)3.2嵌入式軟件開發(fā)流程3.3嵌入式linux開發(fā)環(huán)境3.4嵌入式系統(tǒng)引導(dǎo)代碼3.5linux內(nèi)核結(jié)構(gòu)及移植3.6嵌入式文件系統(tǒng)及移植3.7linux設(shè)備驅(qū)動概述3.8設(shè)備驅(qū)動程序接口3.9linux設(shè)備驅(qū)動開發(fā)流程2023/2/623.1嵌入式軟件結(jié)構(gòu)3.1.1嵌入式軟件體系結(jié)構(gòu)3.1.2基于Linux的嵌入式軟件2023/2/633.1.1嵌入式軟件體系結(jié)構(gòu)2023/2/641.設(shè)備驅(qū)動層設(shè)備驅(qū)動層是嵌入式系統(tǒng)中必不可少的重要部分,使用任何外部設(shè)備都需要有相應(yīng)驅(qū)動程序的支持,它為上層軟件提供了設(shè)備的操作接口。上層軟件不用理會設(shè)備的具體內(nèi)部操作,只需調(diào)用驅(qū)動層程序提供的接口即可。驅(qū)動層一般包括硬件抽象層HAL、板級支持包BSP和設(shè)備驅(qū)動程序。2023/2/652.實時操作系統(tǒng)RTOS對于使用操作系統(tǒng)的嵌入式系統(tǒng)而言,操作系統(tǒng)一般以內(nèi)核映像的形式下載到目標系統(tǒng)中。以Linux為例,在系統(tǒng)開發(fā)完成之后,將整個操作系統(tǒng)部分做成內(nèi)核映像文件,與文件系統(tǒng)一起傳送到目標系統(tǒng)中;然后通過BootLoader指定地址運行Linux內(nèi)核,啟動已經(jīng)下載好的嵌入式Linux系統(tǒng);再通過操作系統(tǒng)解開文件系統(tǒng),運行應(yīng)用程序。整個嵌入式系統(tǒng)與通用操作系統(tǒng)類似,功能比不帶有操作系統(tǒng)的嵌入式系統(tǒng)強大了很多。2023/2/663.中間件層中間件(middleware)是基礎(chǔ)軟件的一大類,屬于可復(fù)用軟件的范疇。顧名思義,中間件處于操作系統(tǒng)軟件與用戶的應(yīng)用軟件的中間。中間件在操作系統(tǒng)、網(wǎng)絡(luò)和數(shù)據(jù)庫之上,應(yīng)用軟件的下層,總的作用是為處于自己上層的應(yīng)用軟件提供運行與開發(fā)的環(huán)境,幫助用戶靈活、高效地開發(fā)和集成復(fù)雜的應(yīng)用軟件。2023/2/674.應(yīng)用程序?qū)嶋H的嵌入式系統(tǒng)應(yīng)用軟件建立在系統(tǒng)的主任務(wù)(MainTask)基礎(chǔ)之上。用戶應(yīng)用程序主要通過調(diào)用系統(tǒng)的API函數(shù)對系統(tǒng)進行操作,完成用戶應(yīng)用功能開發(fā)。在用戶的應(yīng)用程序中,也可創(chuàng)建用戶自己的任務(wù)。任務(wù)之間的協(xié)調(diào)主要依賴于系統(tǒng)的消息隊。2023/2/683.1.2基于Linux的嵌入式軟件基于嵌入式Linux的軟件結(jié)構(gòu)如圖所示,在硬件之上的是引導(dǎo)程序BootLoader,然后是Linux內(nèi)核,最上層是應(yīng)用程序。2023/2/691.BootLoader引導(dǎo)裝載程序通常是在任何硬件上執(zhí)行的第一段代碼。在象臺式機這樣的常規(guī)系統(tǒng)中,通常將引導(dǎo)裝載程序裝入主引導(dǎo)記錄(MasterBootRecord,(MBR))中,或者裝入Linux駐留的磁盤的第一個扇區(qū)中。通常,在臺式機或其它系統(tǒng)上,BIOS將控制移交給引導(dǎo)裝載程序。而在嵌入式系統(tǒng)中,通常并沒有像BIOS那樣的固件程序,因此整個系統(tǒng)的加載啟動任務(wù)就完全由BootLoader來完成。通過這段小程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準備好正確的環(huán)境。常見的BootLoader有uboot、vivi等。引導(dǎo)程序的開發(fā)主要是做一些移植工作。2023/2/6102.內(nèi)核Linux內(nèi)核的開發(fā)主要包括Linux內(nèi)核的定制、裁剪等工作。在嵌入式開發(fā)中經(jīng)常要面對設(shè)備驅(qū)動程序的開發(fā),嵌入式系統(tǒng)通常有許多設(shè)備用于與用戶交互,象觸摸屏、小鍵盤、滾動輪、傳感器、RS232接口、LCD等等。除了這些設(shè)備外,還有許多其它專用設(shè)備,包括閃存、USB、GSM等。內(nèi)核通過所有這些設(shè)備各自的設(shè)備驅(qū)動程序來控制它們,包括GUI用戶應(yīng)用程序也通過訪問這些驅(qū)動程序來訪問設(shè)備。2023/2/6113.應(yīng)用程序?qū)τ谇度胧絃inux的應(yīng)用,大多數(shù)的應(yīng)用并不需要圖形界面,比如交換機、路由器、嵌入式網(wǎng)關(guān)以及服務(wù)器等等。但是,隨著消費類電子的普及,越來越多的嵌入式產(chǎn)品如多媒體播放、手機等手持設(shè)備需要圖形用戶界面(或稱GUI)的支持。因此基于GUI的應(yīng)用程序的開發(fā)越來越重要。目前比較流行的GUI平臺有Qt/Embedded、緊縮的XWindows系統(tǒng)、MicroWindows以及MiniGUI系統(tǒng)。2023/2/6123.2嵌入式軟件開發(fā)流程3.2.1嵌入式Linux設(shè)計概述3.2.2基于開發(fā)板的二次開發(fā)3.2.3基于linux的嵌入式軟件開發(fā)流程2023/2/6133.2.1嵌入式Linux設(shè)計概述2023/2/614嵌入式系統(tǒng)的軟件開發(fā)采用一種交叉編譯調(diào)試的方式。交叉編譯調(diào)試環(huán)境建立在宿主機(即一臺PC機)上,對應(yīng)的開發(fā)平臺叫做目標板。運行Linux的PC(宿主機)開發(fā)時使用宿主機上的交叉編譯、匯編及連接工具形成可執(zhí)行的二進制代碼,(這種可執(zhí)行代碼并不能在宿主機上執(zhí)行,而只能在目標板上執(zhí)行。)然后把可執(zhí)行文件下載到目標機上運行。2023/2/615宿主機(host)是編輯和編譯程序的平臺,一般是基于X86的PC機,通常也稱為主機。而目標機(target)是用戶開發(fā)的系統(tǒng),通常都是非X86平臺。Host編譯得到的可執(zhí)行代碼在target上運行。2023/2/6163.2.2基于開發(fā)板的二次開發(fā)所謂二次開發(fā)是利用現(xiàn)成的開發(fā)板進行開發(fā),不同于通用計算機和工作站上的軟件開發(fā)工程,一個嵌入式軟件的開發(fā)過程具有很多特點和不確定性。其中最重要的一點是軟件跟硬件的緊密耦合特性。由于嵌入式系統(tǒng)的靈活性和多樣性,這樣就給軟件設(shè)計人員帶來了極大地困難。第一,在軟件設(shè)計過程中過多地考慮硬件,給開發(fā)和調(diào)試都帶來了很多不便;第二,如果所有的軟件工作都需要在硬件平臺就緒之后進行,自然就延長了整個的系統(tǒng)開發(fā)周期。這些都是應(yīng)該從方法上加以改進和避免的問題。為了解決這個問題,通常的做法是基于某種開發(fā)板做二次開發(fā),從這個角度看,硬件開發(fā)所占的比重不到20%,而軟件開發(fā)的比重占到了80%。2023/2/6173.2.3基于linux的嵌入式軟件開發(fā)流程1.建立開發(fā)環(huán)境。2.配置開發(fā)主機。3.建立引導(dǎo)裝載程序BOOTLOADER。4.移植Linux操作系統(tǒng)5.建立根文件系統(tǒng)6.建立應(yīng)用程序的文件系統(tǒng)7.開發(fā)應(yīng)用程序8.燒寫內(nèi)核、根文件系統(tǒng)、應(yīng)用程序。9.發(fā)布產(chǎn)品。2023/2/618根文件系統(tǒng):Linux系統(tǒng)運行所需的一些文件、命令組成的整個文件目錄結(jié)構(gòu)。文件系統(tǒng):用來方便管理文件存儲和數(shù)據(jù)組織的一種方法。2023/2/6193.3嵌入式linux開發(fā)環(huán)境3.3.1ARM處理器硬件開發(fā)平臺3.3.2建立嵌入式交叉編譯環(huán)境3.3.3配置開發(fā)環(huán)境2023/2/6203.3.1ARM處理器硬件開發(fā)平臺2023/2/621UP-CUP6410具有良好的外部存儲器結(jié)構(gòu)。存儲系統(tǒng)擁有兩個外部存儲器接口、DRAM和Flash/ROM。DRAM的端口可支持移動DDR。UP-CUP6410包括許多硬件外設(shè),如相機接口、16位真彩液晶LCD控制器、系統(tǒng)管理(電源管理等)、4通道UART接口、32通道DMA、5通道32位定時器與2PWM輸出、通用I/O端口、I2S接口、總線接口、I2C總線接口、USB主機、高速USB接口OTG設(shè)備(480Mbps的傳輸速度)、3通道SD/MMC記憶主機控制器和的PLL時鐘發(fā)生器。ARM子系統(tǒng)是基于的ARM1176JZF-S核心。其包括獨立的16KB指令和16KB數(shù)據(jù)高速緩存,16KB指令和16KB數(shù)據(jù)TCM(Terminal-to-ComputerMultiplexer終端設(shè)備至計算機多路轉(zhuǎn)接器)。它還含有一個完整的MMU進行處理虛擬內(nèi)存管理。2023/2/622UP-CUP6410平臺可運行Linux2.4.x和Linux2.6.x內(nèi)核,支持QT/E、miniGUI等嵌入式圖形界面。集成了USB、SD、LCD、Camera等常用設(shè)備接口,適用于各種手持設(shè)備、消費電子和工業(yè)控制設(shè)備等產(chǎn)品的開發(fā)。2023/2/6233.3.2建立嵌入式交叉編譯環(huán)境嵌入式LINUX開發(fā)環(huán)境有幾個方案:1.基于PC機WINDOWS操作系統(tǒng)下的CYGWIN;2.在WINDOWS下安裝虛擬機后,再在虛擬機中安裝LINXUX操作系統(tǒng);3.直接安裝LINUX操作系統(tǒng)。2023/2/6243.3.3配置開發(fā)環(huán)境1.NFS服務(wù)2.minicom設(shè)置2023/2/6251.NFS服務(wù)NFS是NetworkFileSystem的簡稱,也就是網(wǎng)絡(luò)文件系統(tǒng)的意思,NFS可以使不同的計算機之間通過網(wǎng)絡(luò)進行文件共享的一種網(wǎng)絡(luò)協(xié)議,一般用于Linux網(wǎng)絡(luò)系統(tǒng)中。實際上,一臺NFS服務(wù)器就如同一臺文件服務(wù)器,只要將文件系統(tǒng)共享出來,NFS客戶端就可以將它掛載到本地系統(tǒng)中,從而可以像使用本地文件系統(tǒng)中的文件一樣使用那些遠程文件系統(tǒng)中的文件2023/2/626使用NFS進行嵌入式開發(fā)配置試驗箱開發(fā)板IP是0,假設(shè)PC虛擬機上IP為12023/2/6271。如果機器上沒安裝nfsserver,先執(zhí)行如下命令安裝:$sudoapt-getinstallnfs-kernel-server2。配置/etc/exports比如要將home目錄中的/home/unsp/develop目錄讓0的IP共享,則在該文件末尾添加下列語句:/home/unsp/develop0(rw,sync,no_root_squash)3.配置/etc/hosts.deny(禁止任何host(主機)能和你的NFS服務(wù)器進行NFS連接),加入:2023/2/628###NFSDAEMONSportmap:ALLlockd:ALLmountd:ALLrquotad:ALLstatd:ALL2023/2/6294.配置/etc/hosts.allow允許那些你想要的主機和你的NFS服務(wù)器建立連接。下列步驟將允許任何IP地址以192.168.1開頭的主機(連接到NFS服務(wù)器上),加入:###NFSDAEMONSportmap:192.168.1.lockd:192.168.1.rquotad:192.168.1.mountd:192.168.1.statd:.重啟NFS服務(wù)sudo/etc/init.d/portmaprestartsudo/etc/init.d/nfs-kernel-serverrestart2023/2/6306。在板子上執(zhí)行如下命令,掛載PC上的目錄(假設(shè)你的IP是21)到板子的/mnt目錄:mount-onolock-tnfs1:/home/unsp/develop//mnt這樣你就可以在PC上/home/unsp/develop目錄進行交叉編譯,在板子/mnt目錄上運行編譯好的程序看效果了。2023/2/631一點說明:鑒于開發(fā)板網(wǎng)絡(luò)可能不太穩(wěn)定,建議將/mnt下程序拷貝到開發(fā)板其他本地目錄下運行。2023/2/6323.minicom設(shè)置(1)在Linux平臺的Xwindow界面下建立一個終端,在終端的命令行提示符后鍵入如下命令并回車。[root@JLUZHroot]#minicom2023/2/6332023/2/634(2)minicom啟動后,先按Ctrl+A鍵,再按Z鍵(注意不是連續(xù)按,Ctrl+A松開后才按Z),進入主配置界面,
2023/2/635按”O(jiān)”進入配置界面2023/2/636選擇Serialportsetup,進入端口設(shè)置界面,這里有幾個重要選項改為如下值:A——SerialDevice:/dev/ttyS0(端口號使用串口1)E——BPS/par/bits:/1152008N1(波特率)F,E硬件流,軟件流都改為NO,若要使用PC機的串口2來接板子的串口1做監(jiān)控,改為:/dev/ttyS1即可。2023/2/6372023/2/638(3)選好后按ESC鍵退出到配置界面,選擇Savesetupasdf1保存退出,以后只要啟動minicom就是該配置,無需再做改動。2023/2/639Windows下超級終端設(shè)置臺式機操作演示2023/2/640ubuntu10.04下的配置tftp服務(wù)器第1步:
安裝tftp所需的軟件。首先需要安裝tftp-hpa,tftpd-hpa,前者是客戶端,后者是服務(wù)程序,在終端下輸入sudoapt-getinstalltftp-hpatftpd-hpa,安裝tftp-hpa和tftpd-hpa。然后還需要安裝xinetd,在終端下輸入sudoapt-getinstallxinetd,安裝好xinetd。2023/2/641第2步:
配置相關(guān)服務(wù)文件。進入根目錄下的etc文件夾(cd/etc/),首先看目錄中有沒有一個xinetd.conf文件,如果沒有則新建一個,有的話查看內(nèi)容,看是否與下面的一致,若不一致則修改,內(nèi)容如下:
#Simpleconfigurationfileforxinetd
#
#Somedefaults,andinclude/etc/xinetd.d/
defaults
{
#Pleasenotethatyouneedalog_typelinetobeabletouselog_on_success
ont-size:12pt;">#log_type=SYSLOGdaemoninfo
}
includedir/etc/xinetd.d
2023/2/642第3步:
配置tftp服務(wù)器
命令:
sudovim/etc/default/tftpd-hpa
將內(nèi)容修改成
#/etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot"
#這是你tftp服務(wù)器的工作目錄,自行修改,注意,在新建工作目錄時,最好修改其權(quán)限為777,命令sudochmod777
/tftpboot
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l-c-s"
2023/2/643第4步:
然后進入xinetd.d文件夾(cdxinetd.d),查看是否有一個tftp文件,如果沒有就新建一個,如果有的話就查看內(nèi)容是否與下面的一致,不一致則修改,內(nèi)容如下:
servicetftp
{
socket_type=dgram
wait=yes
disable=no
user=root
protocol=udp
server=/usr/sbin/in.tftpd
server_args=-s/tftpboot
#log_on_success+=PIDHOSTDURATION
#log_on_failure+=HOST
per_source=11
cps=1002
flags=IPv4
}
其中server_args一行是配置服務(wù)器的文件存放的位置,就是進行tftp傳輸?shù)臅r候,都是從該文件夾中搜索文件的2023/2/644第5步:
修改所需文件夾的權(quán)限。需要修改的文件夾也就是上一步提到的那個服務(wù)器文件存放的文件夾,以我的配置文件為例,創(chuàng)建一個文件夾(sudomkdir/tftpboot),然后把它可以設(shè)置成訪問權(quán)限最寬松的(sudochmod777/tftpboot),也可以設(shè)置成合適的權(quán)限。
第6步:
重新啟動服務(wù)。sudoservicetftpd-hparestart,當配置好tftp的配置文件后,需要重新啟動一下xinetd,在終端中輸入sudo/etc/init.d/xinetdreload,重新加載一下進程,再輸入sudo/etc/init.d/xinetdrestart,重啟服務(wù)。記住,每次修改完配置文件后,都需要重新啟動一下服務(wù)。
執(zhí)行次序:
sudoservicetftpd-hparestart
sudo/etc/init.d/xinetdreload
sudo/etc/init.d/xinetdrestart2023/2/645測試首先在/tftpboot中新建一個文件file,然后在其中隨便輸入內(nèi)容;然后進入一個不是/tftpboot的目錄下(原因是避免混淆,因為在獲取文件是,默認是將想要獲取的文件存放在當前目錄下的);再在終端中輸入sudotftplocalhost,進入tftp命令符下(可以在其中輸入help查看命令和命令的作用),輸入getfile,如果沒有任何提示,就說明傳輸成功了,然后輸入q退出tftp命令符,在當前目錄下就可以看到一個file文件,內(nèi)容是與開始新建的那個file的內(nèi)容是一致的。同樣也可以在tftp命令符中輸入putxx,把xx文件上傳到服務(wù)器文件夾中。如果一切ok,那就么一個可用的tftp服務(wù)器就順利搭建成功了。2023/2/6463.4嵌入式系統(tǒng)引導(dǎo)代碼3.4.1Bootloader簡介3.4.2常用的bootloader3.4.3Bootloader基本原理3.4.4Bootloader移植實例一:U_Boot3.4.5Bootloader移植實例二:vivi2023/2/6473.4.1Bootloader簡介1.Bootloader的作用2.bootloader操作模式2023/2/6481.Bootloader的作用BootLoader就是在操作系統(tǒng)內(nèi)核運行之前運行的一段小程序。通過這段小程序,我們可以初始化硬件設(shè)備、建立內(nèi)存空間的映射圖,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調(diào)用操作系統(tǒng)內(nèi)核準備好正確的環(huán)境。2023/2/6492.bootloader操作模式大多數(shù)BootLoader都包含兩種不同的操作模式:“啟動加載”模式和“下載”模式,這種區(qū)別僅對于開發(fā)人員才有意義。但從最終用戶的角度看,BootLoader的作用就是用來加載操作系統(tǒng),而并不存在所謂的啟動加載模式與下載工作模式的區(qū)別。2023/2/650啟動加載(Bootloading)模式:這種模式也稱為“自主”(Autonomous)模式。也即BootLoader從目標機上的某個固態(tài)存儲設(shè)備上將操作系統(tǒng)加載到RAM中運行,整個過程并沒有用戶的介入。這種模式是BootLoader的正常工作模式,因此在嵌入式產(chǎn)品發(fā)布的時侯,BootLoader顯然必須工作在這種模式下。下載(Downloading)模式:在這種模式下,目標機上的BootLoader將通過串口連接或網(wǎng)絡(luò)連接等通信手段從主機(Host)下載文件到目標機的RAM中,然后再被BootLoader寫到目標機上的FLASH類固態(tài)存儲設(shè)備中.工作于這種模式下的BootLoader通常都會向它的終端用戶提供一個簡單的命令行接口。因此產(chǎn)品開發(fā)時通常使用這種模式。2023/2/6513.4.2常用的bootloader1.ARMBootArmboot是一個bootloader,是為基于ARM或者StrongARMCPU的嵌入式系統(tǒng)所設(shè)計的。它支持多種類型的Flash;允許映像文件經(jīng)由bootp、、tftp從網(wǎng)絡(luò)傳輸;支持從串口線下載S-record或者binary文件;允許內(nèi)存的顯示及修改;支持jffs2文件系統(tǒng)等。Armboot源碼公開,可以在/projects/armboot下載。2023/2/6522.PPCBootPPCBoot是德國DENX小組開發(fā)的用于多種嵌入式CPU的Bootloader引導(dǎo)程序,主要由德國的工程師WolfgangDenk和Intemet上的一群自由開發(fā)人員對其進行維護和開發(fā)。支持PowerPC、ARM、MIPS、m68K等多種處理器平臺,易于裁剪和調(diào)試。PPCBoot遵循GPL(通用公共許可)公約,完全開放源代碼。PPCBoot源代碼可以在sourceforge網(wǎng)站的社區(qū)服務(wù)器中獲得,它的項目主頁是http:///projects/ppcboot,也可以從DENX的網(wǎng)站htrp://www.denx.de下載。2023/2/6533.U-Bootu-boot是sourceforge網(wǎng)站上的一個開放源代碼的項目。它可對powerpc、MPC5xx、MPC8xx、MPC82xx、MPC7xx、MPC74xx、ARM(ARM7、ARM9、StrongARM、Xscale)、MIPS、X86等處理器提供支持,支持的嵌入式操作系統(tǒng)有l(wèi)inux、Vx-work、NetBSD、QNX、RTEMS、ARTOS、LynxOS等,主要用來開發(fā)嵌入式系統(tǒng)初始化代碼bootloader。軟件的主站點是/projects/u-boot。u-boot最初是由PPCboot發(fā)展而來的,它對PowerPC系列處理器的支持最完善,對linux操作系統(tǒng)的支持最好。源代碼開放的u-boot軟件項目經(jīng)常更新,是學(xué)習(xí)硬件底層代碼開發(fā)的很好樣例。目前已成為Armboot和PPCboot的替代品。2023/2/6544.RedBootRedBoot是一個專門為嵌入式系統(tǒng)定制的開發(fā)工具,最初由Redhat開發(fā),是嵌入式操作系統(tǒng)eCos的一個最小版本,現(xiàn)在交由自由軟件組織FSF管理,遵循GPL的發(fā)布協(xié)議。集Bootloader、調(diào)試、Flash燒寫于一體。支持串口、網(wǎng)絡(luò)下載,執(zhí)行嵌入式應(yīng)用程序。既可以用在產(chǎn)品的開發(fā)階段(調(diào)試功能),也可以用在最終的產(chǎn)品上(Flash更新、網(wǎng)絡(luò)啟動)。2023/2/6555.BlobBlob是BootLoaderObject的縮寫,是一款功能強大的Bootloader。它遵循GPL,源泉代碼完全開放。Blob既可以用來簡單的調(diào)試,也可以啟動Linuxkernel。Blob最初是Jan-DerkBakker和ErikMouw為一塊名為LART(LinuxAdvancedRadioTerminal)的板子寫的,該板使用的處理器是StrongARMSA-1100。現(xiàn)在Blob已經(jīng)被移植到了很多CPU上,包括S3C44B0。2023/2/6566.ViViVivi是韓國mizi公司開發(fā)的bootloader,適用于ARM9處理器。Vivi有兩種工作模式:啟動加載模式和下載模式。啟動加載模式可以在一段時間后(這個時間可更改)自行啟動linux內(nèi)核,這時vivi的默認模式。在下載模式下,vivi為用戶提供一個命令行接口,通過接口可以使用vivi提供的一些命令。2023/2/6573.4.3Bootloader基本原理同時裝有BootLoader、內(nèi)核的啟動參數(shù)、內(nèi)核映像和根文件系統(tǒng)映像的固態(tài)存儲設(shè)備的典型空間分配結(jié)構(gòu)圖。2023/2/658在嵌入式世界里建立一個通用的BootLoader幾乎是不可能的。盡管如此,我們?nèi)匀豢梢詫ootLoader歸納出一些通用的概念來,以指導(dǎo)用戶特定的BootLoader設(shè)計與實現(xiàn)。大多數(shù)BootLoader都分為stage1和stage2兩大部分。依賴于CPU體系結(jié)構(gòu)的代碼,比如設(shè)備初始化代碼等,通常都放在stage1中,而且通常都用匯編語言來實現(xiàn),以達到短小精悍的目的。而stage2則通常用C語言來實現(xiàn),這樣可以實現(xiàn)給復(fù)雜的功能,而且代碼會具有更好的可讀性和可移植性。2023/2/659stage1BootLoader的stage1通常包括以下步驟(以執(zhí)行的先后順序):硬件設(shè)備初始化。為加載BootLoader的stage2準備RAM空間??截怋ootLoader的stage2到RAM空間中。設(shè)置好堆棧。跳轉(zhuǎn)到stage2的C入口點。2023/2/660stage2BootLoader的stage2通常包括以下步驟(以執(zhí)行的先后順序):初始化本階段要使用到的硬件設(shè)備。檢測系統(tǒng)內(nèi)存映射(memorymap)。將kernel映像和根文件系統(tǒng)映像從flash上讀到RAM空間中。為內(nèi)核設(shè)置啟動參數(shù)。調(diào)用內(nèi)核。2023/2/661第一階段:BootLoader的stage11.基本的硬件初始化這是BootLoader一開始就執(zhí)行的操作,其目的是為stage2的執(zhí)行以及隨后的kernel的執(zhí)行準備好一些基本的硬件環(huán)境。它通常包括以下步驟(以執(zhí)行的先后順序):(1)屏蔽所有的中斷。為中斷提供服務(wù)通常是OS設(shè)備驅(qū)動程序的責任,因此在BootLoader的執(zhí)行全過程中可以不必響應(yīng)任何中斷。中斷屏蔽可以通過寫CPU的中斷屏蔽寄存器或狀態(tài)寄存器(比如ARM的CPSR寄存器)來完成。(2)設(shè)置CPU的速度和時鐘頻率。2023/2/662(3)RAM初始化。包括正確地設(shè)置系統(tǒng)的內(nèi)存控制器的功能寄存器以及各內(nèi)存控制寄存器等。(4)初始化LED。典型地,通過GPIO來驅(qū)動LED,其目的是表明系統(tǒng)的狀態(tài)是OK還是Error。如果板子上沒有LED,那么也可以通過初始化UART向串口打印BootLoader的Logo字符信息來完成這一點。(5)關(guān)閉CPU內(nèi)部指令/數(shù)據(jù)cache。2023/2/6632.為加載stage2準備RAM空間為了后面的敘述方便,這里把所安排的RAM空間范圍的大小記為:stage2_size(字節(jié)),把起始地址和終止地址分別記為:stage2_start和stage2_end(這兩個地址均以4字節(jié)邊界對齊)。因此:
stage2_end=stage2_start+stage2_size另外,還必須確保所安排的地址范圍的的確確是可讀寫的RAM空間,因此,必須對你所安排的地址范圍進行測試。2023/2/6643.拷貝stage2到RAM中拷貝時要確定兩點:(1)stage2的可執(zhí)行映象在固態(tài)存儲設(shè)備的存放起始地址和終止地址;(2)RAM空間的起始地址。2023/2/6654.設(shè)置堆棧指針sp堆棧指針的設(shè)置是為了執(zhí)行C語言代碼作好準備。通常我們可以把sp的值設(shè)置為(stage2_end-4),也即在上面所安排的那個1MB的RAM空間的最頂端(堆棧向下生長)。此外,在設(shè)置堆棧指針sp之前,也可以關(guān)閉led燈,以提示用戶我們準備跳轉(zhuǎn)到stage2。經(jīng)過上述這些執(zhí)行步驟后,系統(tǒng)的物理內(nèi)存布局應(yīng)該如下圖2023/2/6662023/2/6675.跳轉(zhuǎn)到stage2的C入口點在上述一切都就緒后,就可以跳轉(zhuǎn)到BootLoader的stage2去執(zhí)行了。比如,在ARM系統(tǒng)中,這可以通過修改PC寄存器為合適的地址來實現(xiàn)。2023/2/668第二階段:BootLoader的stage21.初始化本階段要使用到的硬件設(shè)備這通常包括:(1)初始化至少一個串口,以便和終端用戶進行I/O輸出信息;(2)初始化計時器等。在初始化這些設(shè)備之前,也可以重新把LED燈點亮,以表明我們已經(jīng)進入main()函數(shù)執(zhí)行。設(shè)備初始化完成后,可以輸出一些打印信息,程序名字字符串、版本號等。2023/2/6692.檢測系統(tǒng)的內(nèi)存映射(memorymap)所謂內(nèi)存映射就是指在整個4GB物理地址空間中有哪些地址范圍被分配用來尋址系統(tǒng)的RAM單元。比如,在SA-1100CPU中,從0xC000,0000開始的512M地址空間被用作系統(tǒng)的RAM地址空間,而在SamsungS3C44B0XCPU中,從0x0c00,0000到0x1000,0000之間的64M地址空間被用作系統(tǒng)的RAM地址空間。雖然CPU通常預(yù)留出一大段足夠的地址空間給系統(tǒng)RAM,但是在搭建具體的嵌入式系統(tǒng)時卻不一定會實現(xiàn)CPU預(yù)留的全部RAM地址空間。2023/2/6703.加載內(nèi)核映像和根文件系統(tǒng)映像(1)規(guī)劃內(nèi)存占用的布局這里包括兩個方面:內(nèi)核映像所占用的內(nèi)存范圍;根文件系統(tǒng)所占用的內(nèi)存范圍。在規(guī)劃內(nèi)存占用的布局時,主要考慮基地址和映像的大小兩個方面。(2)從Flash上拷貝由于像ARM這樣的嵌入式CPU通常都是在統(tǒng)一的內(nèi)存地址空間中尋址Flash等固態(tài)存儲設(shè)備的,因此從Flash上讀取數(shù)據(jù)與從RAM單元中讀取數(shù)據(jù)并沒有什么不同。2023/2/671用一個簡單的循環(huán)就可以完成從Flash設(shè)備上拷貝映像的工作:while(count){
*dest++=*src++;/*都是以字方式對齊*/
count-=4;/*字節(jié)數(shù)*/
};2023/2/6724.設(shè)置內(nèi)核的啟動參數(shù)應(yīng)該說,在將內(nèi)核映像和根文件系統(tǒng)映像拷貝到RAM空間中后,就可以準備啟動Linux內(nèi)核了。但是在調(diào)用內(nèi)核之前,應(yīng)該作一步準備工作,即:設(shè)置Linux內(nèi)核的啟動參數(shù)。2023/2/6735.調(diào)用內(nèi)核BootLoader調(diào)用Linux內(nèi)核的方法是直接跳轉(zhuǎn)到內(nèi)核的第一條指令處,也即直接跳轉(zhuǎn)到MEM_START+0x8000地址處。2023/2/6743.4.4Bootloader移植實例一:U_Boot1.U-Boot概述U-Boot可支持的主要功能如下。系統(tǒng)引導(dǎo):支持NFS掛載、RAMDISK(壓縮或非壓縮)形式的根文件系統(tǒng)。支持NFS掛載,并從FLASH中引導(dǎo)壓縮或非壓縮系統(tǒng)內(nèi)核?;据o助功能:強大的操作系統(tǒng)接口功能;可靈活設(shè)置、傳遞多個關(guān)鍵參數(shù)給操作系統(tǒng),適合系統(tǒng)在不同開發(fā)階段的調(diào)試要求與產(chǎn)品發(fā)布,尤其對Linux支持最為強勁;支持目標板環(huán)境參數(shù)多種存儲方式,如FLASH、NVRAM、EEPROM;CRC32校驗,可校驗FLASH中內(nèi)核、RAMDISK鏡像文件是否完好。設(shè)備驅(qū)動:串口、SDRAM、FLASH、以太網(wǎng)、LCD、NVRAM、EEPROM、鍵盤、USB、PCMCIA、PCI、RTC等驅(qū)動支持。上電自檢功能:SDRAM、FLASH大小自動檢測;SDRAM故障檢測;CPU型號。特殊功能:XIP內(nèi)核引導(dǎo)。2023/2/675U-Boot源代碼分析1第一階段(Stage1)第一階段的啟動代碼在cpu\<cputype>\start.S中,完成的工作主要有:CPU自身初始化:包括MMU,Cache,時鐘系統(tǒng),SDRAM控制器等的初始化重定位:把自己從非易失性存儲器搬移到RAM中分配堆??臻g,設(shè)置堆棧指針清零BSS數(shù)據(jù)段跳轉(zhuǎn)到第二階段入口函數(shù)start_armboot()2023/2/6762第二階段(Stage2)第二階段是U-Boot的主體,入口點是lib_arm\board.c中的start_armboot()函數(shù),完成的主要工作包括:為U-Boot內(nèi)部私有數(shù)據(jù)分配存儲空間,并清零依次調(diào)用函數(shù)指針數(shù)組init_sequence中定義的函數(shù)進行一系列的初始化如果系統(tǒng)支持NORFlash,調(diào)用flash_init()和display_flash_config()初始化并顯示檢測到的器件信息(AT91SAM9260EK不需要)如果系統(tǒng)支持LCD或VFD,調(diào)用lcd_setmem()或vfd_setmem()計算幀緩沖(Framebuffer)大小,然后在BSS數(shù)據(jù)段之后為Framebuffer分配空間,初始化gd->fb_base為Framebuffer的起始地址(AT91SAM9260EK不需要)調(diào)用mem_malloc_init()進行存儲分配系統(tǒng)(類似于C語言中的堆)的初始化和空間分配2023/2/677如果系統(tǒng)支持NANDFlash,調(diào)用nand_init()進行初始化如果系統(tǒng)支持DataFlash,調(diào)用AT91F_DataflashInit()和dataflash_print_info()進行初始化并顯示檢測到的器件信息調(diào)用env_relocate()進行環(huán)境變量的重定位,即從Flash中搬移到RAM中如果系統(tǒng)支持VFD,調(diào)用drv_vfd_init()進行VFD設(shè)備初始化(AT91SAM9260EK不需要)從環(huán)境變量中讀取IP地址和MAC地址,初始化gd->bd->bi_ip_addr和gd->bd->bi_enetaddr調(diào)用jumptable_init()進行跳轉(zhuǎn)表初始化,跳轉(zhuǎn)表在global_data中,具體用途尚不清楚2023/2/678調(diào)用console_init_r()進行控制臺初始化如果需要,調(diào)用misc_init_r()進行雜項初始化調(diào)用enable_interrupts()打開中斷如果需要,調(diào)用board_late_init()進行單板后期初始化,對于AT91SAM9260EK,主要是以太網(wǎng)初始化進入主循環(huán):根據(jù)用戶的選擇啟動linux,或者進入命令循環(huán)執(zhí)行用戶輸入的命令2023/2/6792.源碼閱讀從網(wǎng)站上下載得到U-Boot源碼包,例如:U-Boot-1.1.6.tar.bz2,解壓就可以得到全部U-Boot源程序。在頂層目錄下有18個子目錄,分別存放和管理不同的源程序。這些目錄中所要存放的文件有其規(guī)則,可以分為3類?!?/p>
第1類目錄與處理器體系結(jié)構(gòu)或者開發(fā)板硬件直接相關(guān);·
第2類目錄是一些通用的函數(shù)或者驅(qū)動程序;·
第3類目錄是U-Boot的應(yīng)用程序、工具或者文檔。2023/2/6802023/2/681Board目錄:存放和一些已有開發(fā)板有關(guān)的文件,比如Makefile和U-Boot.lds等都和具體開發(fā)板的硬件和地址分配有關(guān),Common目錄:存放與體系結(jié)構(gòu)無關(guān)的文件,實現(xiàn)各種命令的C文件。Cpu目錄:存放CPU相關(guān)文件,其中的子目錄都是以U-BOOT所支持的CPU為名,比如有子目錄arm926ejs、mips、mpc8260和nios等,每個特定的子目錄中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、設(shè)置指令Cache和數(shù)據(jù)Cache等。interrupt.c設(shè)置系統(tǒng)的各種中斷和異常,比如快速中斷、開關(guān)中斷、時鐘中斷、軟件中斷、預(yù)取中止和未定義指令等;start.S是U-BOOT啟動時執(zhí)行的第一個文件,它主要是設(shè)置系統(tǒng)堆棧和工作方式,為進入C程序奠定基礎(chǔ)。2023/2/682Disk目錄:存放disk驅(qū)動的分區(qū)處理代碼。Doc目錄:存放開發(fā)使用的文檔。Drivers目錄:存放通用設(shè)備驅(qū)動程序,比如各種網(wǎng)卡、支持CF1的Flash、串口和USB總線等。Fs目錄:存放支持文件系統(tǒng)的文件,U-BOOT現(xiàn)在支持cramfs、fat、fdos、jffs2和目錄:存放與網(wǎng)絡(luò)有關(guān)的代碼,BOOTP協(xié)議、TFTP協(xié)議、RARP協(xié)議和NFS文件系統(tǒng)的實現(xiàn)。lib_arm目錄:存放與ARM體系結(jié)構(gòu)相關(guān)的代碼。tools目錄:存放創(chuàng)建S-Record格式文件和U-BOOTimages的工具。Include存放:頭文件,還有對各種硬件平臺支持的匯編文件,系統(tǒng)的配置文件和對文件系統(tǒng)支持的文件。2023/2/6833.u-boot的移植(1)在頂層Makefile中為開發(fā)板添加新的配置選項(2)創(chuàng)建一個新目錄存放開發(fā)板相關(guān)的代碼,并且添加文件。(3)為開發(fā)板添加新的配置文件(4)配置開發(fā)板(5)編譯U-Boot(6)添加驅(qū)動或者功能選項(7)調(diào)試U-Boot源代碼,直到U-Boot在開發(fā)板上能夠正常啟動。2023/2/6844.燒寫U-Boot新開發(fā)的電路板沒有任何程序可以執(zhí)行,也就不能啟動,需要先將U-Boot燒寫到Flash中。多數(shù)嵌入式單板通過處理器的調(diào)試接口,直接對板上的Flash編程。最簡單方式就是通過JTAG電纜,轉(zhuǎn)接到計算機并口連接。把Bootloader下載并燒寫到Flash中。燒寫完成后,復(fù)位實驗板,串口終端應(yīng)該顯示U-Boot的啟動信息。2023/2/6853.4.5Bootloader移植實例二:vivi1.vivi概述vivi是由韓國Mizi公司開發(fā)的一種Bootloader,適合于ARM9處理器,支持S3C2410x處理器,其源代碼可以在網(wǎng)站下載。和所有的Bootloader一樣,vivi有兩種工作模式,即啟動加載模式和下載模式。當vivi處于下載模式時,它為用戶提供一個命令行接口,通過該接口能使用vivi提供的一些命令集。大多數(shù)Bootloader都分為stage1和stage2兩部分,stage2的代碼通常用C語言來實現(xiàn),以便于實現(xiàn)更復(fù)雜的功能并取得更好的代碼可讀性和可移植性。2023/2/6862.vivi源碼導(dǎo)讀代碼基本結(jié)構(gòu)2023/2/687arch:此目錄包括了所有vivi支持的目標板的子目錄,例如s3c2410目錄。Documentation:存放一些使用VIVI的幫助文檔。drivers:其中包括了引導(dǎo)內(nèi)核需要的設(shè)備的驅(qū)動程序(MTD和串口)。MTD目錄下分map、nand和nor三個目錄。init:這個目錄只有main.c和version.c兩個文件。和普通的C程序一樣,vivi將從main函數(shù)開始執(zhí)行。2023/2/688include:頭文件的公共目錄,其中的s3c2410.h定義了這塊處理器的一些寄存器。Platform/smdk2410.h定義了與開發(fā)板相關(guān)的資源配置參數(shù),我們往往只需要修改這個文件就可以配置目標板的參數(shù),如波特率、引導(dǎo)參數(shù)、物理內(nèi)存映射等。lib:一些平臺公共的接口代碼,比如time.c里的udelay()和mdelay()。Scripts:存放VIVI腳本配置文件。Test:存放一些測試代碼文件。Util:存放一些NANDFlash燒寫image相關(guān)的工具實現(xiàn)代碼。2023/2/6893.vivi的移植vivi作為Linux系統(tǒng)的啟動代碼,在編譯配置時需要用到函數(shù)庫,包括交叉編譯器庫和頭文件,交叉編譯開關(guān)選項設(shè)置,還包括Linux內(nèi)核代碼中的庫和頭文件,所以,通常需要修改vivi工程管理文件Makefile。2023/2/690(1)vivi中與硬件相關(guān)的初始化(2)對不同F(xiàn)lash啟動的修改(3)內(nèi)核啟動參數(shù)設(shè)置2023/2/6913.5linux內(nèi)核結(jié)構(gòu)及移植3.5.1linux內(nèi)核結(jié)構(gòu)3.5.2linux的移植3.5.3修改linux內(nèi)核源碼3.5.4內(nèi)核的裁剪3.5.5內(nèi)核的編譯和下載2023/2/6923.5.1linux內(nèi)核結(jié)構(gòu)2023/2/693Linux內(nèi)核可以進一步劃分成3層。最上面是系統(tǒng)調(diào)用接口,它實現(xiàn)了一些基本的功能,例如read和write。系統(tǒng)調(diào)用接口之下是內(nèi)核代碼,可以更精確地定義為獨立于體系結(jié)構(gòu)的內(nèi)核代碼。這些代碼是Linux所支持的所有處理器體系結(jié)構(gòu)所通用的。在這些代碼之下是依賴于體系結(jié)構(gòu)的代碼,構(gòu)成了通常稱為BSP(BoardSupportPackage)的部分。這些代碼用作給定體系結(jié)構(gòu)的處理器和特定于平臺的代碼。2023/2/6942.Linux內(nèi)核的主要子系統(tǒng)2023/2/695(1)進程調(diào)度(2)進程間通信(3)內(nèi)存管理(4)虛擬文件系統(tǒng)(5)網(wǎng)絡(luò)堆棧(6)設(shè)備驅(qū)動程序(7)依賴體系結(jié)構(gòu)的代碼2023/2/696(1)進程調(diào)度SCI層提供了某些機制執(zhí)行從用戶空間到內(nèi)核的函數(shù)調(diào)用。SCI實際上是一個非常有用的函數(shù)調(diào)用多路復(fù)用和多路分解服務(wù)。在./linux/kernel中您可以找到SCI的實現(xiàn),并在./linux/arch中找到依賴于體系結(jié)構(gòu)的部分。2023/2/697(2)進程間通信支持進程間各種通信機制,包括管道、FIFO、共享內(nèi)存、信號、消息隊列、套接字等。2023/2/698(3)內(nèi)存管理內(nèi)核所管理的另外一個重要資源是內(nèi)存。為了提高效率,如果由硬件管理虛擬內(nèi)存,內(nèi)存是按照所謂的內(nèi)存頁方式進行管理的(對于大部分體系結(jié)構(gòu)來說都是4KB)。Linux包括了管理可用內(nèi)存的方式,以及物理和虛擬映射所使用的硬件機制。2023/2/699(4)虛擬文件系統(tǒng)虛擬文件系統(tǒng)(VFS)是Linux內(nèi)核中非常有用的一個方面,因為它為文件系統(tǒng)提供了一個通用的接口抽象。VFS在SCI和內(nèi)核所支持的文件系統(tǒng)之間提供了一個交換層。2023/2/6100(5)網(wǎng)絡(luò)堆棧網(wǎng)絡(luò)堆棧在設(shè)計上遵循模擬協(xié)議本身的分層體系結(jié)構(gòu)?;叵胍幌?,InternetProtocol(IP)是傳輸協(xié)議(通常稱為傳輸控制協(xié)議或TCP)下面的核心網(wǎng)絡(luò)層協(xié)議。TCP上面是socket層,它是通過SCI進行調(diào)用的。2023/2/6101(6)設(shè)備驅(qū)動程序Linux內(nèi)核中有大量代碼都在設(shè)備驅(qū)動程序中,它們能夠運轉(zhuǎn)特定的硬件設(shè)備。Linux源碼樹提供了一個驅(qū)動程序子目錄,這個目錄又進一步劃分為各種支持設(shè)備,例如Bluetooth、I2C、serial等。設(shè)備驅(qū)動程序的代碼可以在./linux/drivers中找到。2023/2/6102(7)依賴體系結(jié)構(gòu)的代碼盡管Linux很大程度上獨立于所運行的體系結(jié)構(gòu),但是有些元素則必須考慮體系結(jié)構(gòu)才能正常操作并實現(xiàn)更高效率。./linux/arch子目錄定義了內(nèi)核源代碼中依賴于體系結(jié)構(gòu)的部分,其中包含了各種特定于體系結(jié)構(gòu)的子目錄(共同組成了BSP)。2023/2/61033.Linux內(nèi)核的技術(shù)特點Linux內(nèi)核最注重實用和效率:Linux內(nèi)核被設(shè)計成分層的微內(nèi)核,所以效率高,緊湊性強。Linux內(nèi)核純粹是一種被動調(diào)用服務(wù)對象。所謂被動是指Linux內(nèi)核為用戶進程服務(wù)的唯一方式是用戶進程通過系統(tǒng)調(diào)用來請求在內(nèi)核空間運行某個函數(shù)。內(nèi)核本身是一種函數(shù)和數(shù)據(jù)結(jié)構(gòu)的集合,不存在運行的內(nèi)核進程為用戶進程服務(wù)。雖然Linux的確存在一種被稱為內(nèi)核線程的進程,但它并不是用來服務(wù)于用戶進程的,僅僅作為系統(tǒng)自身的服務(wù)目的。2023/2/6104Linux內(nèi)核采用虛擬內(nèi)存技術(shù),每個進程的虛擬內(nèi)存空間為4GB。其中0-3G屬于用戶空間,稱為用戶段,3G-4G屬于內(nèi)核空間,稱為內(nèi)核段。Linux最新的一個增強是可以用作其他操作系統(tǒng)的操作系統(tǒng)(稱為系統(tǒng)管理程序)。2023/2/61053.5.2linux的移植1.linux的源代碼結(jié)構(gòu)2.linux的移植2023/2/61061.linux的源代碼結(jié)構(gòu)2023/2/6107(1)linux目錄:該是源代碼的主目錄,在該主目錄中包括所有的子目錄,還含有唯一的一個Makefile文件。該文件是編譯輔助工具軟件make的參數(shù)配置文件。make工具軟件的主要用途是通過識別哪些文件已被修改過,從而自動地決定在一個含有多個源程序文件的程序系統(tǒng)中哪些文件需要被重新編譯。因此,make工具軟件是程序項目的管理軟件。linux目錄下的這個Makefile文件還嵌套地調(diào)用了所有子目錄中包含的Makefile文件。這樣,當linux目錄(包括子目錄)下的任何文件被修改過時,make都會對其進行重新編譯。因此為了編譯整個內(nèi)核所有的源代碼文件,只要在linux目錄下運行一次make軟件即可。2023/2/6108(2)arch目錄:包含和硬件體系結(jié)構(gòu)相關(guān)的代碼,每種平臺占一個相應(yīng)的目錄。該目錄包含了此內(nèi)核源碼所支持的硬件體系結(jié)構(gòu)相關(guān)的內(nèi)核源碼。在這個目錄下,針對不同體系結(jié)構(gòu)所移植的版本都有三個子目錄:kernel、lib和mm。kernel子目錄包含依賴于體系結(jié)構(gòu)實現(xiàn)的一般內(nèi)核功能,如信號處理、時鐘處理等;lib子目錄包含庫函數(shù)的本地實現(xiàn),如果從依賴于體系結(jié)構(gòu)的源碼編譯,則運行更快;mm子目錄包含存儲管理實現(xiàn)的代碼。2023/2/6109(3)block目錄:存放部分塊設(shè)備驅(qū)動程序。(4)crypto目錄:存放常用加密和散列算法(如AES、SHA等),還有一些壓縮和CRC校驗算法。(5)Documentation目錄:存放關(guān)于內(nèi)核各部分的通用解釋和注釋。(6)drivers目錄:存放設(shè)備驅(qū)動程序,每個不同的驅(qū)動占用一個子目錄,如聲卡的驅(qū)動對應(yīng)于drivers/sound。這個目錄擁有50%以上的內(nèi)核源碼,系統(tǒng)中所有的設(shè)備驅(qū)動程序都位于該目錄中。(7)fs目錄:Linux支持的文件系統(tǒng)代碼。不同的文件系統(tǒng)有不同的子目錄與之對應(yīng)。如ext、fat、ntfs等。(8)include目錄:存放頭文件,包括了內(nèi)核的大多數(shù)頭文件,另外對每種支持的體系結(jié)構(gòu)分別有一個子目錄。其中,和系統(tǒng)相關(guān)的頭文件被放置在linux子目錄下。2023/2/6110(9)init目錄:存放內(nèi)核初始化代碼(注意不是系統(tǒng)引導(dǎo)代碼)。包含了所有系統(tǒng)的初始化源碼,許多主要的文件,如main.c就位于該目錄下。該文件還包含了許多核心代碼——如實現(xiàn)fork()的代碼和最常執(zhí)行的代碼——cpuidle()循環(huán)。(10)ipc目錄:處理進程間通信的全部所需的代碼都放在該目錄下。(11)kernel目錄:內(nèi)核的最核心部分,許多最常調(diào)用的內(nèi)核函數(shù)放在該目錄下。包括調(diào)度器fork()和timer.c等,和平臺相關(guān)的一部分代碼放在arch/*/kernel目錄下。(12)lib目錄:存放庫文件代碼。該目錄放置內(nèi)核其他部分經(jīng)常所需要的代碼,如inflate.c就放在這里,它能夠在引導(dǎo)時解壓內(nèi)核并裝入內(nèi)存。與處理器結(jié)構(gòu)相關(guān)的庫代碼放在arch/*/lib目錄下。2023/2/6111(13)mm目錄:包含了所有Linux實現(xiàn)虛擬內(nèi)存管理的源碼。與具體硬件體協(xié)結(jié)構(gòu)相關(guān)的內(nèi)存管理代碼位于arch/*/mm目錄下,如對應(yīng)X86的就是arch/i386/mm/fault.c(14)modules目錄:存放已編譯好的可動態(tài)加載的模塊。(15)net目錄:存放所有提供網(wǎng)絡(luò)支持的代碼代碼,實現(xiàn)了各種常見的網(wǎng)絡(luò)協(xié)議,每個子目錄對應(yīng)網(wǎng)絡(luò)的一個方面。(16)scripts目錄:存放用于配置內(nèi)核的腳本文件及用戶開發(fā)和維護手冊。(17)security目錄:主要是一個SELinux的模塊。(18)sound目錄:常用音頻設(shè)備的驅(qū)動程序等。(19)usr目錄:/usr這是最龐大的目錄,我們要用到的應(yīng)用程序和文件幾乎都存放在這個目錄下2023/2/6112一般在每個目錄下都有一個.depend文件和一個Makefile文件。這兩個文件都是編譯時使用的輔助文件。仔細閱讀這兩個文件對弄清各個文件之間的聯(lián)系和依托關(guān)系很有幫助。另外有的目錄下還有Readme文件,它是對該目錄下文件的一些說明,同樣有利于對內(nèi)核源碼的理解。2023/2/61132.linux的移植所謂Linux移植就是把Linux操作系統(tǒng)針對具體的目標平臺做必要改寫之后,安裝到該目標平臺使其正確的運行起來。其基本過程是這樣的(以Linux2.6.18為例):(1)下載內(nèi)核:到.uk上下載Linux2.6.18內(nèi)核及其關(guān)于ARM平臺的補?。ㄈ纾篜atch-2.6.18-rmk1.gz)。(2)給Linux2.6.18打補?。簔cat../patch-2.6.18-rmk1.gz|patch–p1(前面../表示補丁文件放在內(nèi)核文件上一層目錄)2023/2/6114(3)準備交叉編譯環(huán)境。交叉編譯環(huán)境工具鏈一般包括binutils(含AS匯編器,LD鏈接器等),arm-gcc,glibc等。交叉編譯環(huán)境的搭建也是個復(fù)雜的過程,請參照3.2節(jié)。(4)修改相關(guān)的配置文件,如修改內(nèi)核目錄下的makefile文件中關(guān)于交叉編譯工具相關(guān)的內(nèi)容,此后就可以使用這個makefile進行編譯了。(5)修改linux內(nèi)核源碼,主要是修改和CPU相關(guān)的部分。(6)內(nèi)核的裁剪,根據(jù)項目的需要裁剪內(nèi)核模塊。(7)內(nèi)核的編譯,將裁剪好的內(nèi)核進行編譯,生成二進制映像文件。(8)內(nèi)核的下載,將生成的二進制映像文件,燒寫到目標平臺。2023/2/61153.5.3修改linux內(nèi)核源碼linux的移植是個繁重的工作,其主要包含啟動代碼的修改,內(nèi)核的鏈接及裝入,參數(shù)傳遞,內(nèi)核引導(dǎo)幾個部分。linux內(nèi)核分為體系結(jié)構(gòu)相關(guān)部分和體系結(jié)構(gòu)無關(guān)部分。在Linux啟動的第一階段,內(nèi)核與體系結(jié)構(gòu)相關(guān)部分(arch目錄下)首先執(zhí)行,它會完成硬件寄存器設(shè)置,內(nèi)存映像等初始化工作。然后把控制權(quán)轉(zhuǎn)給內(nèi)核中與系統(tǒng)結(jié)構(gòu)無關(guān)部分。而我們在移植工作中要改動的代碼主要集中在與體系結(jié)構(gòu)相關(guān)部分。2023/2/61163.5.4內(nèi)核的裁剪Linux內(nèi)核的裁剪與編譯看上去是個挺簡單的過程。只是對配置菜單的簡單選擇。但是內(nèi)核配置菜單本身結(jié)構(gòu)龐大,內(nèi)容復(fù)雜。具體如何選擇卻難住了不少人。因此熟悉與了解該菜單的各項具體含義就顯得比較重要。2023/2/6117常用有如下幾種方式1.makeconfig:2.makemenuconfig3.makexconfig2023/2/61182.makemenuconfig2023/2/61193.makexconfig2023/2/6120在選擇相應(yīng)的配置時,有三種選擇方式,它們分別代表的含義如下:Y--將該功能編譯進內(nèi)核N--不將該功能編譯進內(nèi)核M--將該功能編譯成可以在需要時動態(tài)插入到內(nèi)核中的模塊2023/2/61213.5.5內(nèi)核的編譯和下載1.內(nèi)核的編譯2.內(nèi)核的下載2023/2/61221.內(nèi)核的編譯在完成內(nèi)核的裁減之后,內(nèi)核的編譯就是一個非常簡單的過程。你只要執(zhí)行以下幾條命令就行:(1)makeclean這條命令是在正式編譯你的內(nèi)核之前先把環(huán)境給清理干凈。有時你也可以用makerealclean或makemrproper來徹底清除相關(guān)依賴,保證沒有不正確的.o文件存在。(2)makedep這條命令是編譯相關(guān)依賴文件。(3)makezImage這條命令就是最終的編譯命令。有時你可以直接用make(2.6.X版本上用)或makebzImage(給PC機編譯大內(nèi)核時用)。(4)makeinstall這條命令可以把相關(guān)文件拷貝到默認的目錄。當然在給嵌入式設(shè)備編譯時這步可以不要。因為具體的內(nèi)核安裝還需要你手工進行。2023/2/61233.7linux設(shè)備驅(qū)動概述3.7.1linux設(shè)備驅(qū)動作用3.7.2linux設(shè)備驅(qū)動程序的基本結(jié)構(gòu)3.7.3linux設(shè)備驅(qū)動的分類3.7.4linux設(shè)備文件和設(shè)備文件系統(tǒng)2023/2/61243.7.1linux設(shè)備驅(qū)動作用
驅(qū)動程序,英文名為“DeviceDriver”,全稱為“設(shè)備驅(qū)動程序”,是一種可以使計算機和設(shè)備通信的特殊程序,可以說相當于硬件的接口,操作系統(tǒng)只有通過這個接口,才能控制硬件設(shè)備的工作,假如某設(shè)備的驅(qū)動程序未能正確安裝,便不能正常工作。Linux系統(tǒng)內(nèi)核通過設(shè)備驅(qū)動程序與外圍設(shè)備進行交互,設(shè)備驅(qū)動程序是Linux內(nèi)核的一部分,它是一組數(shù)據(jù)結(jié)構(gòu)和函數(shù),這些數(shù)據(jù)結(jié)構(gòu)和函數(shù)通過定義的接口控制一個或多個設(shè)備。對應(yīng)用程序而言,設(shè)備驅(qū)動程序隱藏了設(shè)備的具體細節(jié),對各種不同設(shè)備提供一致的接口。不同于windows驅(qū)動程序,Linux設(shè)備驅(qū)動程序在與硬件設(shè)備之間建立了標準的抽象接口。通過這個接口,用戶可以像處理普通文件一樣,通過open,close,read,write等系統(tǒng)調(diào)用對設(shè)備進行操作,如此一來也大大簡化了linux驅(qū)動程序的開發(fā)。2023/2/6125設(shè)備驅(qū)動程序的主要功能對設(shè)備進行初始化。啟動或停止設(shè)備的運行。把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù)。讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請求的數(shù)據(jù)。檢測和處理設(shè)備出現(xiàn)的錯誤等。2023/2/6126設(shè)備驅(qū)動程序有如下特點:驅(qū)動程序是與設(shè)備相關(guān)的。驅(qū)動程序的代碼由內(nèi)核統(tǒng)一管理。驅(qū)動程序在具有特權(quán)級別的內(nèi)核態(tài)下運行。設(shè)備驅(qū)動程序是輸入輸出系統(tǒng)的一部分。驅(qū)動程序是為某個進程服務(wù)的,其執(zhí)行過程仍處在進程運行的過程中,即處于進程的上下文中。若驅(qū)動程序需要等待設(shè)備的某種狀態(tài),它將阻塞當前進程,把進程加入到該設(shè)備的等待隊列中。2023/2/61273.7.2linux設(shè)備驅(qū)動程序的基本結(jié)構(gòu)2023/2/61282023/2/61293.7.3linux設(shè)備驅(qū)動的分類
Linux的方式看待設(shè)備可區(qū)分為三種基本設(shè)備:字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備。字符設(shè)備:一個字符(char)設(shè)備是一種可以當作一個字節(jié)流來存取的設(shè)備(如同一個文件);一個字符驅(qū)動負責實現(xiàn)這種行為。這樣的驅(qū)動常常至少實現(xiàn)open,close,read,和write系統(tǒng)調(diào)用。文本控制臺(/dev/console)和串口(/dev/ttyS0)是字符設(shè)備的例子,因為它們很好地展現(xiàn)了流的抽象。字符設(shè)備通過文件系統(tǒng)結(jié)點來存取,例如/dev/tty1和/dev/lp0。在一個字符設(shè)備和一個普通文件之間唯一有關(guān)的不同就是,你經(jīng)常可以在普通文件中移來移去,但是大部分字符設(shè)備僅僅是數(shù)據(jù)通道,你只能順序存取。當然,也存在看起來象數(shù)據(jù)區(qū)的字符設(shè)備,你可以在里面移來移去。例如,framegrabber經(jīng)常這樣,應(yīng)用程序可以使用mmap或者lseek存取整個要求的圖像。2023/2/6130塊設(shè)備:如同字符設(shè)備,塊設(shè)備通過位于/dev目錄的文件系統(tǒng)結(jié)點來存取。一個塊設(shè)備(例如一個磁盤)應(yīng)該是可以駐有一個文件系統(tǒng)的。在大部分的Unix系統(tǒng)中,一個塊設(shè)備只能處理這樣的I/O操作,傳送一個或多個長度經(jīng)常是512字節(jié)(或一個更大的2的冪的數(shù))的整塊。Linux中則相反,允許應(yīng)用程序讀寫一個塊設(shè)備象一個字符設(shè)備一樣--它允許一次傳送任意數(shù)目的字節(jié)。結(jié)果就是,塊和字符設(shè)備的區(qū)別僅僅在內(nèi)核在內(nèi)部管理數(shù)據(jù)的方式上,并且因此在內(nèi)核/驅(qū)動的軟件接口上不同。如同一個字符設(shè)備,每個塊設(shè)備都通過一個文件系統(tǒng)結(jié)點被存取的,它們之間的區(qū)別對用戶是透明的。塊驅(qū)動和字符驅(qū)動相比,與內(nèi)核的接口完全不同。2023/2/6131網(wǎng)絡(luò)設(shè)備:任何網(wǎng)絡(luò)事務(wù)都通過一個接口來進行,就是說,一個能夠與其他主機交換數(shù)據(jù)的設(shè)備。通常,一個接口是一個硬件設(shè)備,但是它也可能是一個純粹的軟件設(shè)備,比如回環(huán)接口。一個網(wǎng)絡(luò)接口負責發(fā)送和接收數(shù)據(jù)報文,在內(nèi)核網(wǎng)絡(luò)子系統(tǒng)的驅(qū)動下,不必知道單個事務(wù)是如何映射到實際的被發(fā)送的報文上的。2023/2/6132字符設(shè)備與塊設(shè)備的主要區(qū)別是:在對字符設(shè)備發(fā)出讀/寫請求時,實際的硬件I/O一般緊接著發(fā)生。塊設(shè)備則不然,它利用一塊系統(tǒng)內(nèi)存作為緩沖區(qū),若用戶進程對設(shè)備的請求能滿足用戶的要求,就返回請求的數(shù)據(jù);否則,就調(diào)用請求函數(shù)來進行實際的I/O操作。塊設(shè)備主要是針對磁盤等慢速設(shè)備設(shè)計的,以免耗費過多的CPU時間用來等待。網(wǎng)絡(luò)設(shè)備可以通過BSD套接口訪問數(shù)據(jù)。2023/2/61333.7.4linux設(shè)備文件和設(shè)備文件系統(tǒng)Linux是一種類Unix系統(tǒng),Unix的一個基本特點是“一切皆為文件”,它抽象了設(shè)備的處理,將所有的硬件設(shè)備都像普通文件一樣看待,也就是說硬件可以跟普通文件一樣來打開、關(guān)閉和讀寫。系統(tǒng)中的設(shè)備都用一個設(shè)備特殊文件代表,叫做設(shè)備文件,設(shè)備類型、主次設(shè)備號是內(nèi)核與設(shè)備驅(qū)動程序通信時所使用的,但是對于開發(fā)應(yīng)用程序的用戶來說比較難于理解和記憶,所以Linux使用了設(shè)備文件的概念來統(tǒng)一對設(shè)備的訪問接口,在引入設(shè)備文件系統(tǒng)(devfs)之前Linux將設(shè)備文件放在/dev目錄下,設(shè)備的命名一般為設(shè)備文件名+數(shù)字或字母表示的子類,例如/dev/hda1、/dev/hda2等。2023/2/6134每個設(shè)備文件都有其文件屬性(c/b),表示是字符設(shè)備還是塊設(shè)備。另外每個文件都有2個設(shè)備號,第一個是主設(shè)備號,唯一標識一個設(shè)備。主設(shè)備號相同的設(shè)備使用相同的驅(qū)動程序;第二個是從設(shè)備號,標識使用同一個設(shè)備驅(qū)動程序的、不同的硬件設(shè)備。在Linux-2.4內(nèi)核中引入了設(shè)備文件系統(tǒng)(devfs),所有的設(shè)備文件作為一個可以掛載的文件系統(tǒng),這樣就可以被文件系統(tǒng)進行統(tǒng)一管理,從而設(shè)備文件就可以掛載到任何需要的地方。命名規(guī)則也發(fā)生了變化,一般將主設(shè)備建立一個目錄,再將具體的子設(shè)備文件建立在此目錄下。比如在UP-NETARM2410-S中的MTD設(shè)備為:/dev/mtdblock/0。2023/2/61353.8設(shè)備驅(qū)動程序接口
3.8.1linux設(shè)備驅(qū)動的加載方式3.8.2設(shè)備驅(qū)動程序接口3.8.3linux設(shè)備控制方式2023/2/61363.8.1linux設(shè)備驅(qū)動的加載方式設(shè)備驅(qū)動程序是Linux內(nèi)核的重要組成部分,控制了操作系統(tǒng)和硬件設(shè)備之間的交互。Linux的設(shè)備管理是和文件系統(tǒng)緊密結(jié)合的,各種設(shè)備都以文件的形式存放在/dev目錄下,成為設(shè)備文件。應(yīng)用程序可以打開、關(guān)閉、讀寫這些設(shè)備文件,對設(shè)備的操作就像操作普通的數(shù)據(jù)文件一樣簡便。2023/2/6137在LINUX下加載驅(qū)動程序可以采用動態(tài)和靜態(tài)兩種方式。靜態(tài)加載就是把驅(qū)動程序直接編譯到內(nèi)核里,在執(zhí)行makemenuconfig命令進行內(nèi)核配置裁剪時,在窗口中可以選擇是否編譯入內(nèi)核,還是放入/lib/modules/下相應(yīng)內(nèi)核版本目錄中,還是不選。驅(qū)動編譯進內(nèi)核后,系統(tǒng)啟動后可以直接調(diào)用。靜態(tài)加載的缺點是調(diào)試起來比較麻煩,每次修改一個地方都要重新編譯下載內(nèi)核,效率較低。下圖是將一個設(shè)備驅(qū)動模塊動態(tài)掛接、卸載和系統(tǒng)調(diào)用的全過程。2023/2/61382023/2/6139動態(tài)加載利用了LINUX的module特性,可以在系統(tǒng)啟動后用insmod命令把驅(qū)動程序(.o文件)添加上去,在不需要的時候用rmmod命令來卸載。在臺式機上一般采用動態(tài)加載的方式。在嵌入式產(chǎn)品里可以先用動態(tài)加載的方式來調(diào)試,調(diào)試完畢后再編譯到內(nèi)核里。動態(tài)加載動態(tài)加載是將驅(qū)動模塊加載到內(nèi)核中,而不能放入/lib/modules/下。2023/2/6140下面來看一下有關(guān)模塊的命令,在加載驅(qū)動程序要用到它們:lsmod、modprob、insmod、rmmod、modinfo。lsmod命令:lsmod查看當前加載到內(nèi)核中的所有驅(qū)動模塊,同時提供其它一些信息,比如其它模塊是否在使用另一個模塊。例如:2023/2/6141#lsmod(與cat/proc/modules得出的內(nèi)容是一致的)ModuleSizeUse
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 嚴重精神障礙患者管理指南
- 《GB-T 26599.1-2011激光和激光相關(guān)設(shè)備 激光光束寬度、發(fā)散角和光束傳輸比的試驗方法 第1部分:無像散和簡單像散光束》專題研究報告
- 《GBT 29493.7-2013紡織染整助劑中有害物質(zhì)的測定 第7部分:聚氨酯涂層整 理劑中二異氰酸酯單體的測定》專題研究報告
- 《GB-T 38909-2020民用輕小型無人機系統(tǒng)電磁兼容性要求與試驗方法》專題研究報告
- 《GBT 29534-2013溫鍛冷鍛聯(lián)合成形鍛件 通 用技術(shù)條件》專題研究報告
- 《GBT 35618-2017 社會保險基金預(yù)算編制基本業(yè)務(wù)規(guī)范》專題研究報告
- 《GB-T 39588-2020靜電屏蔽包裝袋要求及檢測方法》專題研究報告
- 《GB-T 13465.2-2014不透性石墨材料試驗方法 第2部分:抗彎強度》專題研究報告
- 2026年陜西省西安市單招職業(yè)適應(yīng)性考試題庫及完整答案詳解1套
- 云計算遷移咨詢協(xié)議
- 醫(yī)學(xué)高數(shù)期末考試題及答案
- 預(yù)征預(yù)儲協(xié)議書
- 單純性腎囊腫護理
- 表面摩擦磨損機理-深度研究
- DB11-T 1073-2014 城市道路工程施工質(zhì)量檢驗標準
- 資金監(jiān)管三方協(xié)議范本
- 2022年9月國家開放大學(xué)??啤陡叩葦?shù)學(xué)基礎(chǔ)》期末紙質(zhì)考試試題及答案
- 2023-2024學(xué)年廣東省廣州市荔灣區(qū)九年級(上)期末數(shù)學(xué)試卷(含答案)
- GB/T 45015-2024鈦石膏綜合利用技術(shù)規(guī)范
- 孕期膽囊炎的臨床特征
- 《飼料添加劑枯草芽孢桿菌》編制說明
評論
0/150
提交評論