歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 關於嵌入式系統的啟動(SHARE FOR ALL)

關於嵌入式系統的啟動(SHARE FOR ALL)

日期:2017/3/2 10:06:59   编辑:關於Linux

嵌入式Linux啟動分為兩個部分,系統引導與Linux啟動。系統引導將完成Linux裝入內存前,初始化CPU和相關IO設備,並將Linux調入內存的工作。系統引導主要由BootLoader實現。在BootLoader將Linux內核調入內存之後,將權力交給LinuxKernel,進入Linux的啟動部分。以下詳細分析啟動的過程與使用的文件。

一、系統引導與BootLoader
BootLoader因嵌入式系統的不同與PC機有很大不同,這裡將以Hyper250(Inter Xscale GDPXA250)的啟動為例來分析。由於沒有BIOS驅動主板,EnbeddedOS必須由bootloader驅動所有的硬件,並完成硬件的初始化工作。
所有的初始化文件在hyper250/Bootloader目錄下。

首先分析開機運行的分件:
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/start_xscale.S
文件包含兩個庫文件:
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/include/config.h
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/include/start_xscale.h
文件config.h主要完成系統各硬件的宏定義與設定,xscale.h主要完成對系統芯片的及系統操作的設定。

以下分析config.h文件:
(1)存儲總線設備的宏定義:定義Flash的大小、字長等信息,定義SRAM的基址、大小和塊大小。
(2)動態內存設定:定義DRAM的大小、基址。
(3)軟件包信息:包名稱、版本號。
(4)設定BOOT LOADER的位置:在DRAM和SRAM的最大值、DRAM裝入位置、棧的基址。
(5)設定kernel的位置:在DRAM和SRAM的基址、KERNEL的最大值、KERNEL中塊的數量。
(6)設定文件系統的位置:根目錄在DRAM和SRAM的基址、文件系統的最大值、文件系統中塊的數量。
(7)設定LOADER程序:LOADER程序的靜態內存基址、LOADER程序的最大值、塊的數量。
(8)網絡設定

以下分析start_xcalse.h文件:
(1)定義內存基址(A0000000)
(2)定義中斷基址(40D00000)和中斷保護棧的偏移量
(3)定義時鐘管理基址(41300000)和寄存器偏移及其初始值
(4)定義GPIO接口寄存器基址(40E00000)及各寄存器的偏移
(5)定義GPIO接口各寄存器的初始值
(6)定義內存控制寄存器基址(48000000)和各寄存器的偏移
(7)定義內存控制寄存器的初始值
(8)定義電源管理寄存器的參數
(9)定義FFUART寄存器的基址(40100000)和各寄存器的偏移
(10)定義FFUART各寄存器的初始值

以下分析start_xcalse.S文件:
(1)設定中斷基址(40D00000),完成中斷保護棧的初始化
(2)初始化GPIO接口
(3)初始化內存SDRAM
(4)將Bootloader從Flash拷貝到SDRAM中
(5)裝入Linux內核鏡像,將內核從Flash(000C 0000)裝入SDRAM(A0008000)中.
(6)設定保護棧
(7)調用main.c的主函數c_main()

以上start_xcalse.S通過APCS的編程標准書寫的匯編文件初始化了系統相關的硬件,並且完成了BootLoader的裝入內存和Linux內核的裝入,最後將權力轉交給main.c。
以下將分析main.c文件:
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/main.c
以及兩個庫文件
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/include/main.h
hyper250/Bootloader/X-Hyper250R1.1-Boot/src/include/scc.h
#2

二、Linux啟動過程分析

1.Makefile分析:
在分析arch/arm/boot/compressed目錄下的文件的時候,對於Makefile的分析是很重要的,因為內核將在這個目錄相產生。這裡主要工作是對內核的壓縮和解壓工作。本目錄在編譯完成後將產生vmlinux、head.o、misc.o、head-xscale.o、piggy.o這幾個文件。其中vmlinux是沒有壓縮過的內核。head.o是內核的頭部文件,負責初始設置。misc.o將主要負責內核的解壓工作,它在head.o之後。head-xscale.o文件主要針對Xscale的初始化,將在鏈接時與head.o合並。piggy.o是一個中間文件,其實是一個壓縮的內核,只不過沒有和初始化文件及解壓文件鏈接而已。

2.Decompress分析:
在BootLoader完成系統的引導以後並將Linux內核調入內存之後,調用bootLinux(),這個函數將跳轉到kernel的起始位置。如果kernel沒有壓縮,就可以啟動了。如果kernel壓縮過,則要進行解壓,在壓縮過的kernel頭部有解壓程序。壓縮過得kernel入口第一個文件源碼位置在arch/arm/boot/compressed/head.S。它將調用函數decompress_kernel(),這個函數在文件arch/arm/boot/compressed/misc.c中,decompress_kernel()又調用proc_decomp_setup(),arch_decomp_setup()進行設置,然後使用在打印出信息“Uncompressing Linux...”後,調用gunzip()。將內核放於指定的位置。
啟動首先運行的文件有:
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/head-xscale.S
arch/arm/boot/compressed/misc.c
這些文件主要用於解壓內核和以及啟動內核映象。一旦內核啟動,則這些文件所占內存空間將被釋放。而且,一旦系統通過reset重起,當BootLoader將壓縮過的內核放入內存中,首先執行的必然是這些代碼。

以下分析head.S文件:
(1)對於各種Arm CPU的DEBUG輸出設定,通過定義宏來統一操作。
(2)設置kernel開始和結束地址,保存architecture ID。
(3)如果在ARM2以上的CPU中,用的是普通用戶模式,則升到超級用戶模式,然後關中斷。
(4)分析LC0結構delta offset,判斷是否需要重載內核地址(r0存入偏移量,判斷r0是否為零)。
這裡是否需要重載內核地址,我以為主要分析arch/arm/boot/Makefile、arch/arm/boot/compressed/Makefile和arch/arm/boot/compressed/vmlinux.lds.in三個文件,主要看vmlinux.lds.in鏈接文件的主要段的位置,LOAD_ADDR(_load_addr)=0xA0008000,而對於TEXT_START(_text、_start)的位置只設為0,BSS_START(__bss_start)=ALIGN(4)。對於這樣的結果依賴於,對內核解壓的運行方式,也就是說,內核解壓前是在內存(RAM)中還是在FLASH上,因為這裡,我們的BOOTLOADER將壓縮內核(zImage)移到了RAM的0xA0008000位置,我們的壓縮內核是在內存(RAM)從0xA0008000地址開始順序排列,因此我們的r0獲得的偏移量是載入地址(0xA0008000)。接下來的工作是要把內核鏡像的相對地址轉化為內存的物理地址,即重載內核地址。

Copyright © Linux教程網 All Rights Reserved