嵌入式Linux系统BSP的设计与实现
生活随笔
收集整理的這篇文章主要介紹了
嵌入式Linux系统BSP的设计与实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 引言
??? 嵌入式系統由硬件環境、嵌入式操作系統和應用程序組成,硬件環境是操作系統和應用程序運行的硬件平臺,它隨應用的不同而有不同的要求。硬件平臺的多樣性是嵌入式系統的主要特點,如何使嵌入式操作系統在不同的硬件平臺上有效地運行,是嵌入式系統開發中需要解決的關鍵問題。解決的方法是在硬件平臺和操作系統之間提供硬件相關層來屏蔽這些硬件的差異,給操作系統提供統一的運行環境,這種硬件相關層就是嵌入式系統中的板級支持包BSP(Board Support Package,簡稱BSP)。本文以PXA250處理器為硬件環境,研究了在嵌入式Linux系統中不同開發階段BSP的設計與實現。
2. BSP及其作用
????BSP是嵌入式系統中介于硬件平臺和操作系統之間的中間層軟件,主要目的是為了屏蔽底層硬件的多樣性,根據操作系統的要求完成對硬件的直接操作,向操作系統提供底層硬件信息并最終啟動操作系統。BSP具有硬件相關性和操作系統相關性的特點,其主要作用包括:
????(1)初始化底層硬件,為操作系統提供底層硬件信息;
????(2)初始化相關硬件設備,主要是存儲設備、通信設備;
????(3)檢測系統硬件是否正常;
????(4)加載操作系統并啟動系統運行。
3. 嵌入式Linux系統BSP的實現
????BSP是相對于操作系統而言的,不同的操作系統有不同定義形式的BSP,要求BSP所實現的功能也有所不同。在嵌入式Linux系統中,主要是初始化底層硬件并引導操作系統;同時,BSP又是和硬件相關的,還要考慮對硬件的初始化操作。在基于PXA250的系統中,這些初始化操作主要是對cPU、內存、中斷等相關的寄存器及PXA25O的協處理器進行正確的配置。在不同的開發階段,因為核心和文件系統所處的位置不同,BSP所要完成的工作也有所不同:在開發調試階段,BSP要能夠與主機通信并從主機下載核心;在目標產品中,BSP要能夠從非易失存儲設備中加載核心。?
3.1. 開發調試階段BSP的實現
????開發初期由于調試系統的需要,BSP需把核心和文件系統從主機直接下載到目標板的內存中運行,其開發環境如圖1所示。
??? 與BSP通信 操作系統及上層應用程序
??? BSP的程序 P
????硬件層
????圖1 嵌入式系統開發調試環境
????由圖1中BSP所處的位置可知,BSP要完成如下工作:
????(1)硬件的初始化和配置。
????????① 設置PXA250的協處理器,將內存管理單元(MMU)關掉,清空讀、寫緩沖和TLB。
????????②設置CPU的核心寄存器和各種控制寄存器,將CPU從加電時的缺省狀態設置為系統所要求的工作狀態叫。
????????③設置內存配置寄存器和內存刷新寄存器,確定內存的大小和刷新頻率[】]。
????(2)通信設備的初始化。
????????BSP需與主機通信,從主機下載核心和文件系統,因此要完成相應通信設備的初始化。與主機通信的設備一般是網卡和串口。串口間通信要遵循一定的協議,包括數據格式、同步方式、傳輸速率、糾錯方式等。對串口的初始化就是對這些協議進行設定,使通信雙方處于相同的傳輸模式。在目標板上初始化串口是通過設置其寄存器實現的:設置串口的行控制寄存器確定串口接收數據的格式,設置串口的波特率產生寄存器確定串口接收數據的速率。設置串口的通信協議為:八個數據位、一個停止位,沒有奇偶校驗位,9 600波特率。串口初始化后就可以從其數據接收寄? 存器中讀取數據。
??????? 對網卡初始化也是通過設置其寄存器實現的,設置控制寄存器,使網卡處于接收模式。用網卡與主機通信時,主機端的通信程序要知道目標板上網卡的MAC地址才能發送數據。因此,我們要把網卡的MAC地址設定為指定值。
從網卡的數據接收寄存器讀取數據時要把數據包中的非數據信息(包的狀態、長度、原地址、目的地址和類型)丟掉。
BSP從主機接收文件,因此必須要提供主機與BSP通信的程序。主機端的通信程序可用操作系統提供的系統調用直接設置串口的屬性,使主機端串口的通信協議與目標板串口的通信協議一致。主機端的程序通過與目標板連接的串口線將數據寫到目標板串口的數據寄存器中。用網卡時,用原始套接口對網卡進行寫操作,把數據包發送到目標板上網卡的數據接收緩存寄存器中。
????(3)從主機接收核心和文件系統,啟動核心運行。
????????系統加電時,BSP從位于0地址的非易失存儲器FLASH中執行,和運行在主機上的程序通信,從串口或網卡的數據寄存器中讀取數據,把核心和文件系統下載到內存中指定的位置,最后將CPU中的程序計數器PC置為核心在內存中的起始地址,實現核心啟動。但是,程序在FLASH中執行時不能對變量進行寫操作,為了使程序能正確執行,BSP必須將自己重定位(即把自己搬運到)到內存中,并且在進入c語言函數執行前要設置好堆棧指針。
????其主要實現過程的偽碼如下:
????????硬件(cup、內存等)初始化;
????????通信設備(網卡、串口)初始化;
????????將自己重定位到內存中;
????????設置系統的堆棧指針;
????????跳轉到從串口讀取核心和文件系統的函數;
????????從串口讀取核心和文件系統的函數(void)
????????{
????????????while(核心沒讀取完){
????????????????while(串口的接收數據寄存器為空)(等待);
????????????????從串口的數據寄存器讀取數據到內存中;
????????????????核心大小減去已讀取的大小,確定核心是否讀取完;
????????????????if(核心讀取完){
??????????????????? -asm{mov pc,一核心在內存中的起始地址;}
????????????}
????????}
3.2. 目標產品中BSP的實現
3.2.1 BSP獨立實現
????把核心和文件系統直接從主機下載到內存中運行,只適用于開發調試階段。目標產品中核心和文件系統燒寫在非易失性存儲設備上,因此BSP要從這些設備中加載并啟動核心。此時,BSP不需要與主機通信,可以將其單獨實現在產品中。將BSP單獨實現時,可以根據需要向其中靈活地添加多種功能:啟動核心前檢測內存是否能被正確讀寫,通過判斷網卡、聲卡等硬件的屬性寄存器確定硬件設備是否正常等。此時,BSP要完成的工作如下:
????(1)初始化硬件及存儲設備。
????(2)測試硬件設備是否正常。
????(3)從相應的存儲設備中加載核心到內存中,并啟動核心。
????硬件的初始化和配置與前面相同,主要完成CPU和內存的初始化。此時,BSP要從存儲設備中加載并啟動核心,因此要對存儲設備(一般是FLASH或CF卡)進行初始化,使其能被正確尋址。BSP中讀取核心的代碼與具體的操作系統及文件格式無關,不能從文件系統層把核心作為一個文件讀進來,只能從硬件接口來實現具體的操作,把核心從存儲設備讀入內存,然后把核心的開頭當作一段程序的起點,使CPU轉入核心執行[ 。
????非易失性存儲器FLASH和內存統一尋址,對它的訪問和訪問內存是一樣的,可以利用寄存器將核心直接從FALSH讀取到內存。CF卡相對內存來說屬于外設,對其進行讀取操作是通過控制其寄存器(數據寄存器、狀態與控制寄存器)來實現的,向其控制寄存器發布ATA命令OA何處讀取,讀取數據的大小等)后,判斷其狀態寄存器是否準備好,才能從其數據寄存器中讀取數據到內存中。把核心從非易失性存儲設備讀到內存中后,將CPU中的程序計數器PC置為核心在內存中的起始地址,實現系統的啟動。
????對應的偽碼如下:
????硬件(cup、內存等)初始化;
????存儲設備(FLASH、CF卡)初始化;
????測試硬件設備是否正常;
????根據CF卡的屬性寄存器判斷CF卡是否存在;
????如果存在,跳轉到從CF卡加載核心到內存的函數;
????如果不存在,直接將核心從FLASH加載到內存中;
????mov pc,一核心在內存中的起始地址;
????從CF卡加載核心到內存的函數(void)
????{
????????while(核心沒加載完){
????????????向CF卡發布ATA命令,確定從CF卡的哪一塊開始讀,
????????????讀多少塊
????????????while(CF卡的狀態沒準備好){等待;}
????????????從CF卡的數據寄存器讀數據到內存中;
????????????核心大小減去所讀的塊數乘以塊大小;
????????????if(核心加載完){
??????????????? -asm{mow pc,=核心在內存中的起始地址;}
????????}
????}
3.2.2 在核心中實現BSP
????BSP單獨實現易于修改,當硬件改變時,只需要對相關硬件的初始化代碼進行修改并重新編譯。但是,對于嵌入式系統的存儲介質FLASH,有些文件系統對它的分區有字節對齊性的要求,也就是說分區必須是特定大小或特定大小的倍數才能有寫訪問權限,如果把BSP單獨寫在一個分區中會造成存儲空間的浪費。實質上,BSP是屬于操作系統的一部分且和操作系統綁定在一起運行,在開發板硬件固定的情況下,可以將其實現在Linux核心中。在核心中實現BSP時,BSP應能向核心提供必要的底層硬件信息,實現核心從非易失性存儲器FLASH到內存的加載和啟動。
????在嵌入式系統的存儲介質FLASH中沒有所謂的引導扇區,相應的嵌入式Linux內核映象zImage也沒有如PC機上的引導扇區代碼bootsect及輔助代碼setup,而是由head.o、misc.o、head-xscale.o和piggy.o幾個文件順序連接而成。其中,head.o是由/arch/arm/boot/compressed/head.S匯編而成,是核心最先執行的代碼,主要作用是用misc.o解壓縮核心并使CPU轉到核心解壓縮后所在的內存地址執行。head-xscale.o是體系結構相關的代碼。piggy.o是系統啟動后保留在內存中的全部有用程序[3],也就是head.o要解壓縮的代碼。由以上分析可知,嵌入式Linux的內核不能自啟動,要啟動核必須滿足以下兩個條件:
????(1)系統硬件已被正確初始化;
????(2)核心在內存中,并且CPU中的程序計數器被置為核心在內存中的起始地址。
????在核心中實現BSP時,BSP必須位于核心代碼的最前面,即將其實現在head.S文件的最前面,完成如PC 機上的BIOS、bootsect和setup的功能。同時,要保證核心在加載到內存后必須能跳轉到和沒有BSP時核心中相同的地方執行。重新編譯核心后,就將BSP實現在核心映象zImage中的開始代碼中。把核心燒到FLASH的0地址,系統啟動時首先執行上述代碼,將核心加載到內存中執行,實現核心的自啟動。
??? 嵌入式系統由硬件環境、嵌入式操作系統和應用程序組成,硬件環境是操作系統和應用程序運行的硬件平臺,它隨應用的不同而有不同的要求。硬件平臺的多樣性是嵌入式系統的主要特點,如何使嵌入式操作系統在不同的硬件平臺上有效地運行,是嵌入式系統開發中需要解決的關鍵問題。解決的方法是在硬件平臺和操作系統之間提供硬件相關層來屏蔽這些硬件的差異,給操作系統提供統一的運行環境,這種硬件相關層就是嵌入式系統中的板級支持包BSP(Board Support Package,簡稱BSP)。本文以PXA250處理器為硬件環境,研究了在嵌入式Linux系統中不同開發階段BSP的設計與實現。
2. BSP及其作用
????BSP是嵌入式系統中介于硬件平臺和操作系統之間的中間層軟件,主要目的是為了屏蔽底層硬件的多樣性,根據操作系統的要求完成對硬件的直接操作,向操作系統提供底層硬件信息并最終啟動操作系統。BSP具有硬件相關性和操作系統相關性的特點,其主要作用包括:
????(1)初始化底層硬件,為操作系統提供底層硬件信息;
????(2)初始化相關硬件設備,主要是存儲設備、通信設備;
????(3)檢測系統硬件是否正常;
????(4)加載操作系統并啟動系統運行。
3. 嵌入式Linux系統BSP的實現
????BSP是相對于操作系統而言的,不同的操作系統有不同定義形式的BSP,要求BSP所實現的功能也有所不同。在嵌入式Linux系統中,主要是初始化底層硬件并引導操作系統;同時,BSP又是和硬件相關的,還要考慮對硬件的初始化操作。在基于PXA250的系統中,這些初始化操作主要是對cPU、內存、中斷等相關的寄存器及PXA25O的協處理器進行正確的配置。在不同的開發階段,因為核心和文件系統所處的位置不同,BSP所要完成的工作也有所不同:在開發調試階段,BSP要能夠與主機通信并從主機下載核心;在目標產品中,BSP要能夠從非易失存儲設備中加載核心。?
3.1. 開發調試階段BSP的實現
????開發初期由于調試系統的需要,BSP需把核心和文件系統從主機直接下載到目標板的內存中運行,其開發環境如圖1所示。
??? 與BSP通信 操作系統及上層應用程序
??? BSP的程序 P
????硬件層
????圖1 嵌入式系統開發調試環境
????由圖1中BSP所處的位置可知,BSP要完成如下工作:
????(1)硬件的初始化和配置。
????????① 設置PXA250的協處理器,將內存管理單元(MMU)關掉,清空讀、寫緩沖和TLB。
????????②設置CPU的核心寄存器和各種控制寄存器,將CPU從加電時的缺省狀態設置為系統所要求的工作狀態叫。
????????③設置內存配置寄存器和內存刷新寄存器,確定內存的大小和刷新頻率[】]。
????(2)通信設備的初始化。
????????BSP需與主機通信,從主機下載核心和文件系統,因此要完成相應通信設備的初始化。與主機通信的設備一般是網卡和串口。串口間通信要遵循一定的協議,包括數據格式、同步方式、傳輸速率、糾錯方式等。對串口的初始化就是對這些協議進行設定,使通信雙方處于相同的傳輸模式。在目標板上初始化串口是通過設置其寄存器實現的:設置串口的行控制寄存器確定串口接收數據的格式,設置串口的波特率產生寄存器確定串口接收數據的速率。設置串口的通信協議為:八個數據位、一個停止位,沒有奇偶校驗位,9 600波特率。串口初始化后就可以從其數據接收寄? 存器中讀取數據。
??????? 對網卡初始化也是通過設置其寄存器實現的,設置控制寄存器,使網卡處于接收模式。用網卡與主機通信時,主機端的通信程序要知道目標板上網卡的MAC地址才能發送數據。因此,我們要把網卡的MAC地址設定為指定值。
從網卡的數據接收寄存器讀取數據時要把數據包中的非數據信息(包的狀態、長度、原地址、目的地址和類型)丟掉。
BSP從主機接收文件,因此必須要提供主機與BSP通信的程序。主機端的通信程序可用操作系統提供的系統調用直接設置串口的屬性,使主機端串口的通信協議與目標板串口的通信協議一致。主機端的程序通過與目標板連接的串口線將數據寫到目標板串口的數據寄存器中。用網卡時,用原始套接口對網卡進行寫操作,把數據包發送到目標板上網卡的數據接收緩存寄存器中。
????(3)從主機接收核心和文件系統,啟動核心運行。
????????系統加電時,BSP從位于0地址的非易失存儲器FLASH中執行,和運行在主機上的程序通信,從串口或網卡的數據寄存器中讀取數據,把核心和文件系統下載到內存中指定的位置,最后將CPU中的程序計數器PC置為核心在內存中的起始地址,實現核心啟動。但是,程序在FLASH中執行時不能對變量進行寫操作,為了使程序能正確執行,BSP必須將自己重定位(即把自己搬運到)到內存中,并且在進入c語言函數執行前要設置好堆棧指針。
????其主要實現過程的偽碼如下:
????????硬件(cup、內存等)初始化;
????????通信設備(網卡、串口)初始化;
????????將自己重定位到內存中;
????????設置系統的堆棧指針;
????????跳轉到從串口讀取核心和文件系統的函數;
????????從串口讀取核心和文件系統的函數(void)
????????{
????????????while(核心沒讀取完){
????????????????while(串口的接收數據寄存器為空)(等待);
????????????????從串口的數據寄存器讀取數據到內存中;
????????????????核心大小減去已讀取的大小,確定核心是否讀取完;
????????????????if(核心讀取完){
??????????????????? -asm{mov pc,一核心在內存中的起始地址;}
????????????}
????????}
3.2. 目標產品中BSP的實現
3.2.1 BSP獨立實現
????把核心和文件系統直接從主機下載到內存中運行,只適用于開發調試階段。目標產品中核心和文件系統燒寫在非易失性存儲設備上,因此BSP要從這些設備中加載并啟動核心。此時,BSP不需要與主機通信,可以將其單獨實現在產品中。將BSP單獨實現時,可以根據需要向其中靈活地添加多種功能:啟動核心前檢測內存是否能被正確讀寫,通過判斷網卡、聲卡等硬件的屬性寄存器確定硬件設備是否正常等。此時,BSP要完成的工作如下:
????(1)初始化硬件及存儲設備。
????(2)測試硬件設備是否正常。
????(3)從相應的存儲設備中加載核心到內存中,并啟動核心。
????硬件的初始化和配置與前面相同,主要完成CPU和內存的初始化。此時,BSP要從存儲設備中加載并啟動核心,因此要對存儲設備(一般是FLASH或CF卡)進行初始化,使其能被正確尋址。BSP中讀取核心的代碼與具體的操作系統及文件格式無關,不能從文件系統層把核心作為一個文件讀進來,只能從硬件接口來實現具體的操作,把核心從存儲設備讀入內存,然后把核心的開頭當作一段程序的起點,使CPU轉入核心執行[ 。
????非易失性存儲器FLASH和內存統一尋址,對它的訪問和訪問內存是一樣的,可以利用寄存器將核心直接從FALSH讀取到內存。CF卡相對內存來說屬于外設,對其進行讀取操作是通過控制其寄存器(數據寄存器、狀態與控制寄存器)來實現的,向其控制寄存器發布ATA命令OA何處讀取,讀取數據的大小等)后,判斷其狀態寄存器是否準備好,才能從其數據寄存器中讀取數據到內存中。把核心從非易失性存儲設備讀到內存中后,將CPU中的程序計數器PC置為核心在內存中的起始地址,實現系統的啟動。
????對應的偽碼如下:
????硬件(cup、內存等)初始化;
????存儲設備(FLASH、CF卡)初始化;
????測試硬件設備是否正常;
????根據CF卡的屬性寄存器判斷CF卡是否存在;
????如果存在,跳轉到從CF卡加載核心到內存的函數;
????如果不存在,直接將核心從FLASH加載到內存中;
????mov pc,一核心在內存中的起始地址;
????從CF卡加載核心到內存的函數(void)
????{
????????while(核心沒加載完){
????????????向CF卡發布ATA命令,確定從CF卡的哪一塊開始讀,
????????????讀多少塊
????????????while(CF卡的狀態沒準備好){等待;}
????????????從CF卡的數據寄存器讀數據到內存中;
????????????核心大小減去所讀的塊數乘以塊大小;
????????????if(核心加載完){
??????????????? -asm{mow pc,=核心在內存中的起始地址;}
????????}
????}
3.2.2 在核心中實現BSP
????BSP單獨實現易于修改,當硬件改變時,只需要對相關硬件的初始化代碼進行修改并重新編譯。但是,對于嵌入式系統的存儲介質FLASH,有些文件系統對它的分區有字節對齊性的要求,也就是說分區必須是特定大小或特定大小的倍數才能有寫訪問權限,如果把BSP單獨寫在一個分區中會造成存儲空間的浪費。實質上,BSP是屬于操作系統的一部分且和操作系統綁定在一起運行,在開發板硬件固定的情況下,可以將其實現在Linux核心中。在核心中實現BSP時,BSP應能向核心提供必要的底層硬件信息,實現核心從非易失性存儲器FLASH到內存的加載和啟動。
????在嵌入式系統的存儲介質FLASH中沒有所謂的引導扇區,相應的嵌入式Linux內核映象zImage也沒有如PC機上的引導扇區代碼bootsect及輔助代碼setup,而是由head.o、misc.o、head-xscale.o和piggy.o幾個文件順序連接而成。其中,head.o是由/arch/arm/boot/compressed/head.S匯編而成,是核心最先執行的代碼,主要作用是用misc.o解壓縮核心并使CPU轉到核心解壓縮后所在的內存地址執行。head-xscale.o是體系結構相關的代碼。piggy.o是系統啟動后保留在內存中的全部有用程序[3],也就是head.o要解壓縮的代碼。由以上分析可知,嵌入式Linux的內核不能自啟動,要啟動核必須滿足以下兩個條件:
????(1)系統硬件已被正確初始化;
????(2)核心在內存中,并且CPU中的程序計數器被置為核心在內存中的起始地址。
????在核心中實現BSP時,BSP必須位于核心代碼的最前面,即將其實現在head.S文件的最前面,完成如PC 機上的BIOS、bootsect和setup的功能。同時,要保證核心在加載到內存后必須能跳轉到和沒有BSP時核心中相同的地方執行。重新編譯核心后,就將BSP實現在核心映象zImage中的開始代碼中。把核心燒到FLASH的0地址,系統啟動時首先執行上述代碼,將核心加載到內存中執行,實現核心的自啟動。
總結
以上是生活随笔為你收集整理的嵌入式Linux系统BSP的设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式系统HAL原理与BSP的实现方法
- 下一篇: 浮点数的二进制表示学习笔记