u boot基礎簡述

2021-05-28 01:59:56 字數 3382 閱讀 4559

u-boot是用於初始化目標板硬體,為嵌入式作業系統提供目標板硬體配置資訊,完成嵌入式作業系統裝載、引導和執行的韌體程式。它能夠將系統的軟硬體緊密銜接在一起。s3c2410是三星公司的一款基於arm920t核的嵌入式通用處理器。本文將詳細介紹u-boot在s3c2410開發板上的移植與執行。

開發板的主要配置包括三星arm9處理器s3c2410、1個串列埠和jtag介面,晶振為12mhz,系統主頻為200mhz。另外,開發板上還包括1片4m×16位資料寬度的flash,位址範圍為0x01000000~0x01800000和2片8m×16位資料寬度的sdram,位址範圍為0x30000000~0x32000000。flash使用了2410處理器的bank0單元,由於2410中位址是迴圈對映的,因而0x01000000?和0x0位址等同。

在本系統中,u-boot的主要功能包括:建立和初始化ram;初始化乙個串列埠;檢測機器的體系結構,傳遞mach_type_***的值(smdk2410)給核心;建立核心的標記列表(tagged list);呼叫核心映象。

u-boot移植步驟

為了使u-boot支援新的開發板,一種簡便的做法是在u-boot已經支援的開發板中選擇一種和目標板接近的,並在其基礎上進行修改。**修改的步驟如下:

1)在board目錄下建立smdk2410目錄,新增smdk2410.c、flash.c、memsetup.s、u-boot.lds和config.mk等;

2)在cpu目錄下建立arm920t目錄,主要包含start.s、interrupts.c、cpu.c、serial.c和speed.c等檔案;

3)在include/configs目錄下新增smdk2410.h,它定義了全域性的巨集定義等;

4)修改u-boot根目錄下的makefile檔案:

smdk2410_config:unconfig@./mkconfig $(@:_config=) arm arm920t smdk2410

5)執行make smdk2410_config,如果沒有錯誤,就可以開始進行與硬體相關的**移植工作。由於這部分**與硬體緊密相關,所以要熟悉開發板的硬體配置,可參考各晶元的使用者手冊。

u-boot啟動過程

u-boot的啟動過程可以分成3個階段。首先在flash中執行匯程式設計序,將flash中的啟動**部分複製到sdram中,同時創造環境準備執行c程式;然後在sdram中執行,對硬體進行初始化;最後設定核心引數的標記列表,複製映象檔案,進入核心的入口函式。

1) 程式首先在flash中執行cpu入口函式/cpu/arm920t/start.s。具體工作包括:設定異常的入口位址和異常處理函式;配置pllcon暫存器,確定系統的主頻;遮蔽看門狗和中斷;初始化i/o暫存器;關閉mmu功能;呼叫/board/smdk2410中的memsetup.s,初始化儲存器空間,設定重新整理頻率;將u-boot的內容複製到sdram中;設定堆疊的大小,ldr pc, _start_armboot。

當程式在flash中執行時,執行程式跳轉時必須要使用跳轉指令,而不能使用絕對位址的跳轉(即直接對pc操作)。如果使用絕對位址,那麼,程式的取指是相對於當前pc位置向前或者向後的32mb空間內,而不會跳入sdram中。

3) 裝載模式下系統將執行do_bootm_linux()函式,0x30008000是核心在sdram中的起始位址;0x30800000是ramdisk在sdram中的起始位址;0x40000是核心在flash中的位置,0x100000是資料塊的大小;0x140000是ramdisk在flash中的位置,0x440000是資料塊的大小。系統呼叫memcpy()函式將核心從flash和ramdisk複製到sdram中,具體如下:

memcpy((void*)0x30008000,(void*)0x40000,0x100000);//複製資料塊

memcpy((void*)0x30800000,(void*)0x140000,0x440000);//複製資料塊

通常,將核心引數傳遞給linux作業系統有兩種方法:採用struct param_struct結構體或標記列表。本系統中採用了第二種方法。

乙個合法的標記列表開始於atag_core,結束於atag_none。atag_core可以為空,乙個空的atag_core的size欄位設為「2」(0x00000002)。atag_none?的size欄位必須設為「0」。標記列表可以有任意多的標記(tag)。在嵌入式linux系統中,通常由u-boot設定的啟動引數有:atag_core、atag_mem、atag_cmdline、atag_ramdisk、atag_initrd等。

在本系統中,傳遞引數時分別呼叫了以下tag:

setup_start_tag(bd);  //標記列表開始

setup_memory_tags(bd); //設定記憶體的起始位置和大小

setup_commandline_tag(bd,?commandline); /*linux核心在啟動時可以命令列引數的形式來接收資訊,利用這一點可以向核心提供那些核心不能檢測的硬體引數資訊,或者過載(override)核心檢測到的資訊,這裡char *commandline "initrd=0x30800000,0x440000 root=/dev/ram init=/linuxrc console=ttys0";*/

setup_ramdisk_tag(bd); //表示核心解壓後ramdisk的大小

setup_initrd_tag(bd, initrd_start,?initrd_end); //設定ramdisk的大小和物理起始位址

setup_end_tag(bd);  //標記列表結束

其中bd_t *bd = gd->bd是指向bd_t?結構體的指標,在該結構體中存放了關於開發板配置的基本資訊。標記列表應該放在核心解壓和initrd的bootp程式都不會覆蓋的記憶體區域,同時又不能和異常處理的入口位址相衝突。建議放在ram起始的16k大小處,在本系統中即為0x30000100處。

u-boot呼叫 linux 核心的方法是直接跳轉到核心的第一條指令處,也即直接跳轉到 mem_start+0x8000位址處。在跳轉時,要滿足下列條件:

a)cpu暫存器的設定:r0=0;r1=機器型別id,本系統的機器型別id=193。r2=啟動引數標記列表在ram中的起始基位址;

b)cpu模式:必須禁止中斷(irqs和fiqs);cpu必須工作在svc模式;

c)cache和mmu的設定:mmu 必須關閉;指令cache可以開啟也可以關閉;資料cache必須關閉。

系統採用下列**來進入核心函式:

thekernel=(void(*)(int,int))ntohl(hdr->ih_ep);

thekernel(0,bd->bi_arch_number);其中,hdr是image_header_t型別的結構體,hdr->ih_ep指向核心的第一條指令位址,即linux作業系統下的/kernel/arch/arm/boot/compressed/head.s匯程式設計序。thekernel()函式呼叫應該不會返回,如果該呼叫返回,則說明出錯。

Java基礎 static簡述

靜態變數 例項變數 靜態方法 非靜態方法。在語法定義上的區別 靜態變數前要加 static 關鍵字,而例項變數前則不加。在程式執行時的區別 例項變數屬於某個物件的屬性,必須建立了例項物件,其中的例項變數才會被分配空間,才能使用這個例項變數 靜態變數不屬於某個例項物件,而是屬於類,所以也稱為類變數,只...

簡述Spark基礎及架構

五 spark資料核心 rdd 六 建立rdd spark是基於記憶體的分布式計算框架,特點是快速 易用 通用及多種執行模式。spark架構主要由以下元件構成 cluster manager 在集群 standalone mesos yarn 上獲取資源的外部服務 task 被送到某個 execut...

Python基礎 裝飾器簡述

作用 向原本的函式新增功能,但是不改變原函式的內部結構 在 執行期間,可以動態增加函式功能的方式,被稱為裝飾器 decorator 也就是說,在不修改原函式的基礎上,給原函式增加功能 好處 在團隊開發中,如果兩個或者兩個以上的程式設計師會用到相同的功能,但是功能又有細微的差別,採用裝飾器 相互不影響...