1. 程式人生 > >基於TQ2440開發板的U-boot-1.1.6的start.S程式碼分析

基於TQ2440開發板的U-boot-1.1.6的start.S程式碼分析

start.S彙編原始檔是U-boot執行的起始程式碼檔案,也是不容易理解的實現部分。執行流程如下:

.globl _start//定義_start是全域性標籤,其他檔案也可以使用。.globlGNU彙編語法。

_start:breset//跳轉到reset標籤出執行,由於reset操作是在MMU工作之前/之後都有可能使用,所以這裡用b來跳轉。

/*下面定義ARM異常向量表對應的跳轉程式碼*/

ldrpc, _undefined_instruction

ldrpc, _software_interrupt

ldrpc, _prefetch_abort

ldrpc, _data_abort

ldrpc, _not_used

ldrpc, _irq

ldrpc, _fiq

_undefined_instruction:.word undefined_instruction

_software_interrupt:.word software_interrupt

_prefetch_abort:.word prefetch_abort

_data_abort:.word data_abort

_not_used:.word not_used

_irq:.word irq

_fiq:.word fiq

/*其中.word的語法是用來指定該變數可以被C語言直接引用*/

.balignl 16,0xdeadbeef /* 這個指令用來填寫一個長字,即內容長度為長字,即

4個位元組的長度,填寫內容為0xdeadbeef */

當一個異常出現以後,ARM會自動執行以下幾個步驟:

1)把下一條指令的地址放到連線暫存器LR(通常是R14),這樣就能夠在處理異常返回時從正確的位置繼續執行。

2)將相應CPSR(當前程式狀態暫存器)複製到SPSR(備份的程式狀態暫存器)中。從異常退出的時候,就可以由SPSR來恢復CPSR

3)根據異常型別,強制設定CPSR的執行模式位。

4)強制PC(程式計數器)從相關異常向量地址取出下一條指令執行,從而跳轉到相應的異常處理程式中。

reset:

/*

* set the cpu to SVC32 mode

*/

mrsr0,cpsr/*

傳送CPSR的內容到通用暫存器指令*/

bicr0,r0,#0x1f/*位清除指令,即=r0&(~0x1f)*/

orrr0,r0,#0xd3/*邏輯或指令,即=r0|0xd3*/

msrcpsr,r0 /*傳送通用暫存器到CPSR指令*/

/* turn off the watchdog */

#if defined(CONFIG_S3C2400)

# define pWTCON0x15300000

# define INTMSK0x14400008/* Interupt-Controller base addresses */

# define CLKDIVN0x14800014/* clock divisor register */

#elif defined(CONFIG_S3C2410)

# define pWTCON0x53000000

# define INTMOD0X4A000004

# define INTMSK0x4A000008/* Interupt-Controller base addresses */

# define INTSUBMSK0x4A00001C

# define CLKDIVN0x4C000014/* clock divisor register */

#endif

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

ldrr0, =pWTCON

movr1, #0x0/*0x0值傳入r1暫存器*/

str/*r1, [r0] r1種的內容寫入到r0*/

/*

* mask all IRQs by setting all bits in the INTMR - default

*/

movr1, #0xffffffff

ldrr0, =INTMSK

strr1, [r0]

# if defined(CONFIG_S3C2410)

ldrr1, =0x3ff

ldrr0, =INTSUBMSK

strr1, [r0]

# endif

#endif/* CONFIG_S3C2400 || CONFIG_S3C2410 */

cpu_init_crit 主要完成記憶體管理相關的暫存器設定,CP15協處理器,配置記憶體區控制暫存器。另外這段程式碼中呼叫了lowlevel_init 函式,進行暫存器的具體設定,與採用的記憶體晶片有關。

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

blcpu_init_crit/*bl是帶跳轉返回指令*/

#endif

接下來看一下cpu_init_crit標籤的實現,如下:

cpu_init_crit:

/*

* flush v4 I/D caches

*/

movr0, #0

mcrp15, 0, r0, c7, c7, 0/* ARM 處理器暫存器到協處理器暫存器的資料傳送指令,清除ID cache分支運算快取(BTB*/

mcrp15, 0, r0, c8, c7, 0/* flush v4 TLBTranslation Lookaside Buffers */

/*

* disable MMU stuff and caches

*/

mrcp15, 0, r0, c1, c0, 0

bicr0, r0, #[email protected] clear bits 13, 9:8 (--V- --RS)

bicr0, r0, #[email protected] clear bits 7, 2:0 (B--- -CAM)

orrr0, r0, #[email protected] set bit 2 (A) Align

orrr0, r0, #[email protected] set bit 12 (I) I-Cache

mcrp15, 0, r0, c1, c0, 0

/*

* before relocating, we have to setup RAM timing

* because memory timing is board-dependend, you will

* find a lowlevel_init.S in your board directory.

*/

movip, lr

bllowlevel_init /*跳轉到lowlevel_init,處理完返回*/

movlr, ip

movpc, lr

lowlevel_init實現是在board/tq2440/ lowlevel_init.S中,主要完成初始化記憶體控制器,即SDRAM的初始化。

.globl lowlevel_init

lowlevel_init:

/* memory control configuration */

/* make r0 relative the current location so that it */

/* reads SMRDATA out of FLASH rather than memory ! */

ldrr0, =SMRDATA

ldrr1, _TEXT_BASE

subr0, r0, r1

ldrr1, =BWSCON/* Bus Width Status Controller */

addr2, r0, #13*4

0:

ldrr3, [r0], #4

strr3, [r1], #4

cmpr2, r0

bne0b

/* everything is fine now */

movpc, lr

接下來是設定堆疊,設定後的邏輯位置如下圖所示:

 

stack_setup:

ldrr0, _TEXT_BASE/* upper 128 KiB: relocated uboot*/

subr0, r0, #CFG_MALLOC_LEN/* malloc area*/

subr0, r0, #CFG_GBL_DATA_SIZE /* bdinfo*/

subsp, r0, #12/* leave 3 words for abort-stack*/

接下來呼叫:bl clock_init 用來完成初始化時鐘的目的。

下面的程式碼是將NandFlash資料搬運到SDRAM的核心實現程式碼,其最主要由C語言函式CopyCode2Ram函式來完成複製目的,該函式在board/tq2440/boot_init.c中實現。

relocate:/* relocate U-Boot to RAM*/

adrr0, _start/* r0 <- current position of code*/

ldrr1, _TEXT_BASE/* test if we run from flash or RAM */

cmpr0, r1/* don't reloc during debug*/

beqclear_bss

ldrr2, _armboot_start

ldrr3, _bss_start

subr2, r3, r2/* r2 <- size of armboot*/

blCopyCode2Ram/* r0: source, r1: dest, r2: size */

接下來就是清除BSS段,並進入C語言階段的高階初始化過程實現。

clear_bss:

ldrr0, _bss_start/* find start of bss segment*/

ldrr1, _bss_end/* stop here*/

mov r2, #0x00000000/* clear*/

clbss_l:strr2, [r0]/* clear loop...*/

addr0, r0, #4

cmpr0, r1

bleclbss_l

ldrpc, _start_armboot

_start_armboot:.word start_armboot /*start_armbootC程式碼函式,在lib_arm/board.c中實現*/

相關推薦

基於TQ2440開發U-boot-1.1.6的start.S程式碼分析

start.S彙編原始檔是U-boot執行的起始程式碼檔案,也是不容易理解的實現部分。執行流程如下: .globl _start//定義_start是全域性標籤,其他檔案也可以使用。.globl是GNU彙編語法。 _start:breset//跳轉到reset標籤出執行,由

普中PZ6806開發 STM32學習筆記1 環境配置

開發板介紹 普中PZ6806L (STM32-F1)開發板,使用STM32F103ZET6晶片,外觀圖: 功能模組 各模組功能: 蜂鳴器 DS18B20溫度感測器介面 紅外接收頭 電源開關 USB

關於RK3288開發的學習(1

一、準備學習Rk3288的一些技術資料和檔案工具: 網路學習資源: (1).入門指南(初學者必看): http://wiki.t-firefly.com/index.php/Firefly-RK3288/Starter_guide (2).維基教程(入門教學、驅動開發

ERROR : arm-linux-ld:u-boot.lds:1: ignoring invalid character `#' in expression

今天在除錯rk3288的 uboot的 ./include/configs/rk_default_config.h檔案 我的本意是遮蔽掉uboot 的lcd驅動,然後我習慣用“//”用單行註釋雙斜槓註釋了一個巨集定義比如 //#define CONFIG_LCD 編譯後提示

創龍TMS320C6748開發———裝置時鐘介紹1

       圖中PLLCTL[CLKMODE]用於選擇時鐘源的波形,如果時鐘源OSCIN為方波,選擇1;如果為正弦波,選擇0。選擇後的時鐘可以直接從AUXCLK引腳上看到。CIN訊號實際上仍然直接到達PREDIV進行預分頻,預分頻後得到慢速的時鐘,然後到PLL單元進行倍頻。倍頻後的訊號,根據需要再進行後分

(二)U-boot開發上移植過程詳解--bootloader架構分析

 本例中採用的同樣是前邊一貫的實驗板,這裡就不對板子資源做進一步介紹了。     我們知道,bootloader是系統上電後最初載入執行的程式碼。它提供了處理器上電覆位後最開始需要執行的初始化程式碼。在PC機上載入程式一般由BIOS開始執行,然後讀取硬碟中位於MBR(Main Boot Record,主引

為64位ARMv8架構開發交叉編譯openssl-1.0.2l

因科研實驗需要,完成了針對64為ARM架構目標開發板的交叉編譯,之前網上查詢了一些方法,有些並不可行,且操作性與可讀性都較差,這裡給出自己親手編譯成功的過程。 本次編譯的目標環境和編譯環境如下: 目標

學習手記-基於iTOP4412開發NFS服務器搭建及測試

udp 都是 使用 共享目錄 none padding rgb 安裝 通訊 NFS特點:1)基於UDP/IP2)功能和網盤基本上差不多,但性能沒那麽強。NFS服務器搭建步驟:在ubantu上安裝nfs軟件:nfs-kernel-server配置文件1)打開配置文件:/etc

基於Omapl138開發linux3.3系統分析do_initcall()函式

參考了網上的很多內容,網上的分析基本上是基於linux2.6或者3.1的核心,對於這個函式而言,其實大同小異,但是幾乎沒有哪篇文章能一次性把我想要了解的東西全部呈現,所以自己嘗試整理如下: do_initcalls()-> static void __init do_init

嵌入式Linux開發——(十三)u-boot常用命令

1、幫助命令help 執行help命令可以看到U-Boot中所有命令的作用,如“help bootm”可以用“?”來替代,比如“?Bootm”。 2、下載命令 Boot支援串列埠下載、網路下載,相關命令有:loadb、loads、loadx、loady和tftpboot、nfs。 &

基於Arduino開發使用HC-12遠端無線通訊模組

在本篇文章中,我們將學習如何使用HC-12無線序列通訊模組,該模組能夠在多個Arduino開發板之間進行遠端無線通訊,距離可達1.8km。其中,我列舉了兩個基本的例子,來解釋瞭如何連線HC-12模組並在兩個Arduinos之間進行基本通訊,另外一個例子是通過使用第一個Arduino開發板

linux下基於vc088x開發分析CLK模型(時鐘管理)

Linux clk 模型   Linux clk模型採用面向物件的思想來設計實現的。 在porting層建立一個一個的clk節點物件,然後將所有的clk節點物件連成一個list。 當驅動層需要設定時鐘的時候,通過porting層與驅動層

網線連線PC、Ubuntu與Linux(基於itop4412開發

一直想開發板直接從Ubuntu虛擬機器上的tftp得到檔案程式,不需要一直通過掛載U盤再執行程式了,但是4412的手冊上的教程是使用路由器,太麻煩,我想能不能直接用網線把PC和4412開發板連上,我試了一下,虛擬機器、開發板、PC老是ping不通。網上找了一些資

Linux核心--01(基於armA9tiny4412開發

1、如何編譯核心 tar -Jxvf linux-3.5-20170929.tar.xz -C /~ 解壓核心壓縮包至自己的家目錄 建議刪除arch目錄與我們無關的其他架構的資料夾 通過./config生成Makefile,但是因為我們初學核心,不懂得用 m

基於OK6410開發Uboot原始碼簡單分析

2018-04-07 OK6410開發板是基於三星S3C6410晶片設計的一款開發板,資源比較豐富,可是想要使用這些資源就需要編寫相應的啟動載入程式,即BootLoader。當然,想要自己憑空寫出BootLoader那簡直就是天方夜譚,所以我們需要參考行業中現有的BootLoader,在其

基於am335x的u-boot 2013.01.01的啟動分析

1,am335x的cpu上電後,會跳到哪個地址去執行? 答: 晶片到uboot啟動流程 :ROM → MLO(SPL)→ uboot.img AM335x 中bootloader被分成了 3 個部分: 第一級 bootloader:引導載入程式,板子上電後會自動執

基於STC89C52RC開發的嵌入式交叉編譯環境的搭建

交叉編譯環境的搭建主要分為兩部分,一個是PC上的編譯環境,另一個是將檔案燒入板子的軟體。此處前者使用keil,後者使用PZ-ISP,即普中自帶的燒錄免安裝軟體。 首先keil的安裝,百度上可搜尋到安裝包,文末附csdn資源連結,一路next即可完成安裝。 如何編譯第一個程式? 第一步

【ARM-Linux開發U-Boot啟動過程--詳細版的完全分析

----------------------------------------------------------------------------------------------------------------------------------------

基於imx25開發音訊驅動理解

         之前在做關於音訊驅動的相關工作,學習到了一些知識,所以簡單的談一談對這方面的理解。        內容主要是基於imx255核心板,它是支援多種音訊處理晶片的。工作是配合音訊晶片SGTL5000進行的。這裡主要介紹該晶片在Linux下的驅動相關內容。我實際

基於Arduino開發使用MEMS加速度計、陀螺儀和磁力計的方法

在本篇文章中,我們將學習MEMS加速度計、陀螺儀和磁力計的工作原理以及如何將它們與Arduino開發部一起使用。通過使用Processing IDE,我們將使用感測器進行一些實際應用。 MEMS概述 MEMS是非常小的系統或器件,由尺寸範圍為0.001mm至0.1mm的微小元件組