Linux BSP開發需要完成的工作

2021-06-22 12:02:38 字數 4078 閱讀 1448

1.head.s -> start_kernel -> setup_arch

setup_arch 會獲取

平台檔案中定義的

struct machine_desc,

所有關於平台的初始化操作都依據

machine_desc

來進行。具體的編譯條件又是依據

arch/arm/configs

中的***_defconfig

2.根據上述判斷,hal(bsp)的編寫完全是以machine_desc為入口

需要編寫的內容包括

plat/xx

以及mach_xx/

下的核心節拍、中斷管理、時鐘、

gpio

、dma、io

記憶體對映、管腳復用、外部裝置註冊和資源提供

相關的**。

外部裝置和裝置資源在板子初始化中註冊,裝置驅動則放在

/drivers

目錄中。

linux bsp(這裡不考慮bootloader 以及 檔案系統 )

開發的層次有3個級別:1.體系結構級別的開發。2.soc級別的移植。3.裝置驅動的移植。體系結構級別的開發一般是由linux核心社群或體系結構廠商完成後加入到linux核心原始碼樹中,這一級別的開發主要完成記憶體管理、程序排程、異常、陷阱等,開發過程中需要參考體系結構的datasheet,比如arm920tdmi/cortex a8甚至還有armv6/armv7指令集架構。實際上在linux的arch目錄下幾乎已經支援了現今所有的體系結構,所以一般不會去進行體系結構級別的bsp開發。最常見的還是soc級別的bsp開發和驅動開發,soc級別的bsp開發只需要參考soc的datasheet,比如s3c2410/mx53。驅動開發不僅要參考soc的datasheet還要參考pcb設計原理圖。本文關注的就是soc級別的開發或移植。

通俗來講,就是要讓一套官方標準的linux原始碼在自己的板子上跑起來。

3.struct machine_desc

成員以及呼叫時機 在

setup_arch()

中init_irq, timer & init_machine

分別被賦值給下列變數:

init_arch_irq = mdesc->init_irq;

system_timer = mdesc->timer;

init_machine = mdesc->init_machine;

而這三個函式指標是在下列場景中被呼叫的:

start_kernel()-> init_irq()

[irq.c] ->init_arch_irq();

start_kernel()->time_init ()

[time.c] ->system_time->init();

customize_machine()-> init_machine();

customize_machine

是被放在

arch_initcall

段的,按照順序被呼叫。

***_initcall

段內的函式是按下列順序被呼叫的:

start_kernel()-> rest_init()

[啟動核心執行緒

]-> kernel_init() 

–> do_basic_setup()-> do_initcalls();

map_io

是在下列順序中被呼叫

start_kernel()-> setup_arch ()-> paging_init()

-> devicemaps_init()-> map_io()

fixup

是在下列順序中被呼叫

start_kernel()-> setup_arch ()->setup_machine_tags()

init_early

是在下列順序中被呼叫

start_kernel()-> setup_arch ()->init_early

它們在start_kernel()

中被呼叫的順序,可知它們執行的先後為:

fixup -> map_io -> init_early -> init_irq ->timer-> init_machine ,所以一般就應該按照各個順序依次來實現。

4.fixup

在mx53中雖然設定了,但是是乙個空函式

5.map_io

完成的工作

void __init mx6_map_io(void)

iotable_init

就是進行靜態記憶體對映,把一些實體地址永久的對映到固定的虛擬位址上去;這些虛擬位址必須是處於核心空間的;為什麼要進行對映呢?在驅動中可以使用

ioremap

函式進行動態對映,對於那種在系統執行期間都需要被頻繁訪問的實體地址就可以使用靜態對映;或許被靜態對映的區域不宜過大,

mx6q

上沒有超過

4m;被對映的實體地址,在以後的訪問中直接使用固定的虛擬位址就可以訪問到;或許使用靜態對映就可以把分散的實體地址集中對映到一片連續虛擬位址區域,這樣可以減少虛擬位址空間的碎片?

mxc_iomux_v3_init

設定iomuxc

暫存器塊對應的虛擬位址,因為這塊實體地址區域已經被靜態映**;

mxc_arch_reset_init

設定watchdog

暫存器塊對應的虛擬位址,因為這塊實體地址區域已經被靜態映**;

mx6_set_cpu_type

讀取暫存器,獲取處理器的型號

mx6sl/mx6q/mx6dl

以及型號的版本

1/2/3

mxc_cpu_lp_set

把cpu

設定為指定的低功耗狀態;這個函式會在系統功耗管理**中被使用;

6.init_early

在mx6中沒有被設定

7.init_irq

完成的工作

void mx6_init_irq(void)

for (i = mxc_int_start; i <= mxc_int_end; i++)

mx6q_register_gpios();

#ifdef config_cpu_freq_gov_interactive

for (i = 0; i < array_size(mxc_irq_tuner); i++)

cpufreq_gov_irq_tuner_register(mxc_irq_tuner[i]);

#endif

#ifdef config_pci_msi

imx_msi_init();

#endif

}gic_init

暫時不知道是什麼

mx6q_register_gpios()

初始化gpio

,或者可以把這裡看做是

gpio

驅動的入口,

gpio

作為一種系統必備資源,需要在

arch

初始化的時候被加入系統;

8.timer

完成的工作

static void __init mx6_sabresd_timer_init(void)

mx6_clocks_init

可以認為是時鐘驅動,這裡完成了所有外設控制器的時鐘初始化;

early_console_setup

在系統啟動期間也是需要串列埠輸出的,這裡趕緊設定好串列埠

uart

的時鐘?

really?

9.init_machine

完成的工作

無論在mx53

還是mx6

中,或者是在

s3cc24xx

系列中,

init_machine

所做的事情非常的一致,那就是向核心註冊控制器

device

;主要包括

uart

、i2c

、spi

、gpu

、ipu、fb

等等;此外還要新增一些板子上的裝置,比如

i2c裝置、固化的

mmc、網路的

phy晶元等等;其實這個函式完全就和

linux

驅動密切相關了,我就不把它歸入

bsp開發了;

架構 2013需要完成的 架構

伺服器集群框架 slithice 實現簡單方便的伺服器集群擴充套件,管理集群中所有伺服器的工作量,動態擴充套件集群能夠實現的功能。框架現狀 命名 slithice dota 中的 娜迦海妖 的名字 框架已經在今年春節開工,已經累計編碼 5小時 完成度 20 30 概念器 命名可能是 concept ...

男人30歲需要完成的事

男人30歲需要完成的事 1,事業永遠第一 雖然金錢不是萬能的,但沒有錢是萬萬不能的,雖然這句話很俗,但絕對有道理,所以30歲之前,請把你大部分精力放在你的事業上.2,別把錢看得太重 不要抱怨自己現在工資低,銀行存款4位數以下,看不到前途,現在要做的就是努力學習,即使你文憑再高,怎麼把理論運用到實踐還...

30歲前男人需要完成的事

30歲前男人需要完成的事 1,事業永遠第一 雖然金錢不是萬能的,但沒有錢是萬萬不能的,雖然這句話很俗,但絕對有道理,所以30歲之前,請把你大部分精力放在你的事業上.2,別把錢看得太重 不要抱怨自己現在工資低,銀行存款4位數以下,看不到前途,現在要做的就是努力學習,即使你文憑再高,怎麼把理論運用到實踐...