基於TQ2440開發板的U-boot-1.1.6的start.S程式碼分析
start.S彙編原始檔是U-boot執行的起始程式碼檔案,也是不容易理解的實現部分。執行流程如下:
.globl _start//定義_start是全域性標籤,其他檔案也可以使用。.globl是GNU彙編語法。 _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 /* 這個指令用來填寫一個長字,即內容長度為長字,即 |
當一個異常出現以後,ARM會自動執行以下幾個步驟:
(1)把下一條指令的地址放到連線暫存器LR(通常是R14),這樣就能夠在處理異常返回時從正確的位置繼續執行。
(2)將相應CPSR(當前程式狀態暫存器)複製到SPSR(備份的程式狀態暫存器)中。從異常退出的時候,就可以由SPSR來恢復CPSR。
(3)根據異常型別,強制設定CPSR的執行模式位。
(4)強制PC(程式計數器)從相關異常向量地址取出下一條指令執行,從而跳轉到相應的異常處理程式中。
reset: /* * set the cpu to SVC32 mode */ mrsr0,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 處理器暫存器到協處理器暫存器的資料傳送指令,清除I、D cache和分支運算快取(BTB)*/ mcrp15, 0, r0, c8, c7, 0/* flush v4 TLB(Translation 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_armboot是C程式碼函式,在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的微小元件組