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位數以下,看不到前途,現在要做的就是努力學習,即使你文憑再高,怎麼把理論運用到實踐...