<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > ARM Linux啟動(dòng)過(guò)程分析

ARM Linux啟動(dòng)過(guò)程分析

作者: 時(shí)間:2012-08-17 來(lái)源:網(wǎng)絡(luò ) 收藏

5) 調用 內核映像

Bootloader完成的最后一項工作便是調用 內核。如果 內核存放在 Flash 中,并且可直接在上面運行(這里的 Flash 指 Nor Flash),那么可直接跳轉到內核中去執行。但由于在 Flash 中執行代碼會(huì )有種種限制,而且速度也遠不及 RAM 快,所以一般的嵌入式系統都是將 Linux內核拷貝到 RAM 中,然后跳轉到 RAM 中去執行。不論哪種情況,在跳到 Linux 內核執行之前 CUP的寄存器必須滿(mǎn)足以下條件:r0=0,r1=處理器類(lèi)型,r2=標記列表在 RAM中的地址。

3. Linux內核的

將 Linux 內核映像拷貝到 RAM 以后,可以通過(guò)下例代碼啟動(dòng) Linux 內核:call_linux(0, machine_type, kernel_params_base)。

其中,machine_tpye 是 檢測出來(lái)的處理器類(lèi)型, kernel_params_base 是啟動(dòng)參數在 RAM 的地址。通過(guò)這種方式將 Linux 啟動(dòng)需要的參數從 傳遞到內核。Linux 內核有兩種映像:一種是非壓縮內核,叫 Image,另一種是它的壓縮版本,叫zImage。根據內核映像的不同,Linux 內核的啟動(dòng)在開(kāi)始階段也有所不同。zImage 是 Image經(jīng)過(guò)壓縮形成的,所以它的大小比 Image 小。但為了能使用 zImage,必須在它的開(kāi)頭加上解壓縮的代碼,將 zImage 解壓縮之后才能執行,因此它的執行速度比 Image 要慢。但考慮到嵌入式系統的存儲空容量一般比較小,采用 zImage 可以占用較少的存儲空間,因此犧牲一點(diǎn)性能上的代價(jià)也是值得的。所以一般的嵌入式系統均采用壓縮內核的方式。

對于 系列處理器來(lái)說(shuō),zImage 的入口程序即為 arch/arm/boot/compressed/head.S。它依次完成以下工作:開(kāi)啟 MMU 和 Cache,調用 decompress_kernel()解壓內核,最后通過(guò)調用 call_kernel()進(jìn)入非壓縮內核 Image 的啟動(dòng)。下面將具體分析在此之后 Linux 內核的。

3.1 Linux內核入口

Linux 非壓縮內核的入口位于文件/arch/arm/kernel/head-armv.S 中的 stext 段。該段的基地址就是壓縮內核解壓后的跳轉地址。如果系統中加載的內核是非壓縮的 Image,那么bootloader將內核從 Flash中拷貝到 RAM 后將直接跳到該地址處,從而啟動(dòng) Linux 內核。不同體系結構的 Linux 系統的入口文件是不同的,而且因為該文件與具體體系結構有關(guān),所以一般均用匯編語(yǔ)言編寫(xiě)[3]。對基于 處理的 Linux 系統來(lái)說(shuō),該文件就是head-armv.S。該程序通過(guò)查找處理器內核類(lèi)型和處理器類(lèi)型調用相應的初始化函數,再建立頁(yè)表,最后跳轉到 start_kernel()函數開(kāi)始內核的初始化工作。

檢測處理器內核類(lèi)型是在匯編子函數__lookup_processor_type中完成的。通過(guò)以下代碼可實(shí)現對它的調用:bl __lookup_processor_type。__lookup_processor_type調用結束返回原程序時(shí),會(huì )將返回結果保存到寄存器中。其中r8 保存了頁(yè)表的標志位,r9 保存了處理器的 ID 號,r10 保存了與處理器相關(guān)的 struproc_info_list 結構地址。

檢測處理器類(lèi)型是在匯編子函數 __lookup_architecture_type 中完成的。與__lookup_processor_type類(lèi)似,它通過(guò)代碼:“bl __lookup_processor_type”來(lái)實(shí)現對它的調用。該函數返回時(shí),會(huì )將返回結構保存在 r5、r6 和 r7 三個(gè)寄存器中。其中 r5 保存了 RAM 的起始基地址,r6 保存了 I/O基地址,r7 保存了 I/O的頁(yè)表偏移地址。當檢測處理器內核和處理器類(lèi)型結束后,將調用__create_page_tables 子函數來(lái)建立頁(yè)表,它所要做的工作就是將 RAM 基地址開(kāi)始的 4M 空間的物理地址映射到 0xC0000000 開(kāi)始的虛擬地址處。對筆者的 S3C2410 開(kāi)發(fā)板而言,RAM 連接到物理地址 0x30000000 處,當調用 __create_page_tables 結束后 0x30000000 ~ 0x30400000 物理地址將映射到0xC0000000~0xC0400000 虛擬地址處。

當所有的初始化結束之后,使用如下代碼來(lái)跳到 C 程序的入口函數 start_kernel()處,開(kāi)始之后的內核初始化工作:

b SYMBOL_NAME(start_kernel)

3.2 start_kernel函數

start_kernel是所有 Linux 平臺進(jìn)入系統內核初始化后的入口函數,它主要完成剩余的與硬件平臺相關(guān)的初始化工作,在進(jìn)行一系列與內核相關(guān)的初始化后,調用第一個(gè)用戶(hù)進(jìn)程-init 進(jìn)程并等待用戶(hù)進(jìn)程的執行,這樣整個(gè) Linux 內核便啟動(dòng)完畢。該函數所做的具體工作有[4][5]

1) 調用 setup_arch()函數進(jìn)行與體系結構相關(guān)的第一個(gè)初始化工作;

對不同的體系結構來(lái)說(shuō)該函數有不同的定義。對于 平臺而言,該函數定義在arch/arm/kernel/Setup.c。它首先通過(guò)檢測出來(lái)的處理器類(lèi)型進(jìn)行處理器內核的初始化,然后通過(guò) bootmem_init()函數根據系統定義的 meminfo 結構進(jìn)行內存結構的初始化,最后調用paging_init()開(kāi)啟 MMU,創(chuàng )建內核頁(yè)表,映射所有的物理內存和 IO空間。

2) 創(chuàng )建異常向量表和初始化中斷處理函數;

3) 初始化系統核心進(jìn)程調度器和時(shí)鐘中斷處理機制;

4) 初始化串口控制臺(serial-console);

ARM-Linux 在初始化過(guò)程中一般都會(huì )初始化一個(gè)串口做為內核的控制臺,這樣內核在中就可以通過(guò)串口輸出信息以便開(kāi)發(fā)者或用戶(hù)了解系統的啟動(dòng)進(jìn)程。

5) 創(chuàng )建和初始化系統 cache,為各種內存調用機制提供緩存,包括;動(dòng)態(tài)內存分配,虛擬文件系統(VirtualFile System)及頁(yè)緩存。

6) 初始化內存管理,檢測內存大小及被內核占用的內存情況;

7) 初始化系統的進(jìn)程間通信機制(IPC);

當以上所有的初始化工作結束后,start_kernel()函數會(huì )調用 rest_init()函數來(lái)進(jìn)行最后的初始化,包括創(chuàng )建系統的第一個(gè)進(jìn)程-init 進(jìn)程來(lái)結束內核的啟動(dòng)。Init 進(jìn)程首先進(jìn)行一系列的硬件初始化,然后通過(guò)命令行傳遞過(guò)來(lái)的參數掛載根文件系統。最后 init 進(jìn)程會(huì )執行用 戶(hù)傳遞過(guò)來(lái)的“init=”啟動(dòng)參數執行用戶(hù)指定的命令,或者執行以下幾個(gè)進(jìn)程之一:

execve("/sbin/init",argv_init,envp_init);

execve("/etc/init",argv_init,envp_init);

execve("/bin/init",argv_init,envp_init);

execve("/bin/sh",argv_init,envp_init)。

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>