日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析

發布時間:2023/12/9 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

uboot啟動流程分析如下:

第一階段:

a -- 設置cpu工作模式為SVC模式
b -- 關閉中斷,mmu,cache
v -- 關看門狗
d -- 初始化內存,串口
e -- 設置棧
f -- 代碼自搬移
g -- 清bss
h -- 跳c

第二階段

a -- 初始化外設,進入超循環
b -- 超循環處理用戶命令


可見, U-Boot 屬于兩階段的Bootloader

第一階段的文件:

arch/arm/cpu/armv7 /start.S? ? ? ? ? ? ? ? ? ? ? ?平臺相關,CPU工作模式設為SVC模式,關MMU,關icahce(CPU相關)

board/samsung/fs4412/lowlevel_init.S? ? ?開發板相關:關看門狗,內存初始化,時鐘初始化,串口初始化(board相關,初始化最基本設備)


第二階段的文件:

arch/arm/lib/crt0.S? ? ? ? ? ? ? ? ? ? ?_main 函數所在處,初始化SP,為C語言準備,代碼重定位,清BSS,設置R0 R1 R2 R8相應寄存器

arch/arm/lib/board.c? ? ? ? ? ? ? ? ? ?board_init_f 函數 ,填充GD結構體,初始化外設, main_loop()函數超循環

arch/arm/cpu/armv7 /start.S?代碼自搬移時會用到

針對uboot2013啟動流程圖如下:



下面是具體分析:

一、U-Boot 第一階段代碼分析

通常我們通過連接文件知曉程序入口點,入口查看?u-boot.lds


通過鏈接腳本可知入口為_start,位于arch/arm/cpu/armv7/start.o


第一階段開始:

1、進入arch/arm/cpu/armv7/start.S

a -- 異常向量表設置



b -- 設置CPU處于SVC工作模式



d -- 協處理器 p15 的 c12 寄存器來重新定位



e、Bl ?cpu_init_cp15(使分支預測無效,數據)


關閉數據預取功能;

DSB:多核CPU對數據處理指令

ISB:流水線清空指令;


關閉MMU,使能I-cache

NOTE:

分支預測:在流水線里,會將后面的代碼優先加載到處理器中,由于是循環,會使后面加載的代碼無效,故出現了分支預測技術。(統計跳的次數來選擇裝載循環的代碼還是下面的代碼)。


f、Bl ?cpu_init_crit




2、跳到Low_level_init,位于board/samsung/fs4412/lowlevel_init.S

a、關閉看門狗


b、比較當前pc指針域TEXT_BASE的高8位是否一樣來判斷,當前代碼是否在內存中



c、對系統時鐘初始化



d、對內存初始化


e、對串口初始化


結束后返回 start.S

第一階段結束,總結如下:

1 前面總結過的部分,初始化異常向量表,設置svc模式

2 配置cp15,初始化mmu cache tlb

3 板級初始化,clk,memory,uart初始化


二、第二階段開始:


按"CTRL + ] ", 發現 _main 在兩處有定義:


這里我們選擇第一個Bl??_main?,跳轉到arch/arm/lib/crt0.S


1、初始c運行環境(看注釋就知道,初始化C運行環境,并調用board_init_f 函數


功能:

初始化sp ,為支持C語言做準備;

保存128B 放GD結構體,存放全局信息,GD的地址存放在r8中;

跳轉到 board_init_f 函數,其在arch/arm/lib/board.c 處定義;


2、跳轉到arch/arm/lib/board.c


功能:

對全局信息GD結構體進行填充:

291行:mon_len 通過鏈接腳本可以知道存放的是uboot代碼大小;

294行:fdt_blob 存放設備數地址;

303行:循環執行init_fnc_t數組的函數,作硬件初始化;


a --?init_fnc_t數組的函數定義

? ? ?初始化硬件


b -- Dram_init初始化成功之后,剩余代碼將會對sdram空間進行規劃。


可以看到addr的值由CONFIG_SYS_SDRAM_BASE加上ram_size。也就是到了可用sdram的頂端。


e--繼續對gd結構體填充


如果icahe 與 dcache 是打開的,就留出 64K 的空間作為 tlb 空間,最后 addr 就是tlb 地址,4K對齊。


f --填充完成將信息拷貝到內存指定位置




2 -- 繼續回到 _main

按"CTRL + O"回到跳轉前的函數,即?arch/arm/lib/crt0.S


功能:

將 r8 指向新的 gd 地址;

代碼重定位;

?對lr 的操作為了讓返回時,返回的是重定位的here處


3 -- 代碼自搬移

代碼自搬移,防止與內核沖突,代碼位于arch/arm/cpu/armv7/start.S

循環將代碼搬移到指定高地址

這里只是將鏈接腳本中_image_copy_end_start中的代碼,其它段還沒有操作。

在這里我們有疑惑就是將代碼重定位到高地址,那運行的地址不就和鏈接地址不一樣了,那運行可能不正常?這個疑惑就是.rel.dyn幫我們解決了,主要還是編譯器幫我們做的工作,在鏈接中有如下:【參考:http://blog.csdn.net/skyflying2012/article/details/37660265


4 -- 重定位到高地址之后,再次回到 _main(arch/arm/lib/crt0.S)

? ? ? 此時回到的是剛才的重定位的 here 處


關 icache,保證數據從SDRAM中更新,更新異常向量表,因為代碼被重定位了;

清BBS;



調用board_init_r主要是對外設的初始化。

R0=gd

R1=RELOCADDR


5 -- Main_loop 函數進入超循環(arch/arm/lib/board.c)


Main_loop函數主要功能是處理環境變量,解析命令

install_auto_complete();??//安裝自動補全的函數,分析如下?

getenv(bootcmd)

bootdelay(自啟動)

如果延時大于等于零,并且沒有在延時過程中接收到按鍵,則引導內核。

總結

以上是生活随笔為你收集整理的Exynos4412 Uboot 移植(二)—— Uboot 启动流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。