uboot之relocate代碼的深入理解

2020-12-11 電子產品世界

在讀網絡原理時,發現Dave Clark說的一句話「我們拒絕國王,總統和選舉。我們信奉的是是大體的一致意見和正在執行的代碼」

在讀linux0.11內核時,發現linus說的一句話,「要了解系統真正的運行機制,一切盡在原始碼中」。

本文引用地址:http://www.eepw.com.cn/article/201611/323260.htm

在讀眾多的關於uboot移植的文檔如,大家卻在說「第一階段~~~~第二階段~~~~~」,「 這一段完成~~~~」卻很少見到講解過start_armboot()函數是怎麼實現的,只是籠統的說完成神馬神馬的初始化~~

在今天之前看了那麼多文檔,發現自己對uboot說的是頭頭是道,「第一階段~~第二階段~~」,然後移植到自己板子上,則是兩眼一摸黑,神馬都不知道~~~

然而就是今天,就在寫這篇文檔之前。我才發現了uboot真正的執行與實現原理。而達到這一步的最初動力就是:要看看uboot到底是怎麼執行的,而不光是知道它「應該」是怎麼執行的和它的流程。在不懂得代碼操作過程而只知道執行流程的時候,知道的執行流程只能是浮雲~~~而要根根據自己的板子實際的改動uboot中的代碼那就更別談了。於是,深入到uboot的代碼中去,儘管有些代碼很難懂,儘管有些函數,宏定義根本不知道放在哪,但總是能找到的,總是能看懂的~只要方向正確,哪怕多走點路,也總能是到達目的地的~~

至此,才真正算是明白學習之道:多看,多想,多寫~~~

還是那句話:除了代碼,神馬都是浮雲! 這兩天天氣突然轉冷,就剛才由大雪籽轉而飄起了大雪,手也開始不聽使喚的抖動起來了。自己的對uboot的理解也逐漸深入了,下面就一段段的寫下,加深印象吧

這兩天天氣突然轉冷,就剛才由大雪籽轉而飄起了大雪,手也開始不聽使喚的抖動起來了。自己的對uboot的理解也逐漸深入了,下面就一段段的寫下,加深印象吧

先貼上代碼吧:

relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* dont reloc during debug */
beq stack_setup

最初看到這個代碼的時候,發現功能還是很簡單的,就是判斷uboot是放在哪裡的,flash? or SDRAM?如果放在SDRAM中,就不需要再把uboot代碼從flash中搬移到SDRAM中,直接跳到stack_setup;如果是放在flash裡的話,則要把代碼從flash中搬移到指定的SDRAM地址(TEXT_BASE)中。細看之下,又發現了點問題:它是怎麼知道uboot到底放在哪呢;又要把uboot放到SDRAM的什麼地址去呢,也即TEXT_BASE是多少。

先說TEXT_BASE吧。TEXT_BASE在功能上是指示uboot將要SDRAM中存放的起始地址。(理解這個很重要)在ubootcpus3c44b0start.S中有如下聲明和定義:_TEXT_BASE:。word TEXT_BASE 而在ubootoardB2config.mk文件中有如下賦值:TEXT_BASE = 0x0c100000。在基於daveB2板子的uboot是把uboot放在SDRAM中的0x0c100000處的。(個人暫時認為這個TEXT_BASE應該是可以修改的,比如TEXT_BASE=0x0c100004)再說這個_start:當uboot在flash中運行的時候,_start是程序的開始,也即地址0。而當uboot在SDRAM的時候,這個_start應該是多少呢??經過反覆想,反覆想之後,才發現,這個_start就應該是TEXT_BASE。

 由於_start是整個uboot的開頭處,所以_start在uboot中的偏移地址_start_offset=0,這個無疑義。當uboot在flash中的時候,_start=0x00000000很好理解:flash映射起始地址為0x00000000。uboot放在flash當中的話,uboot起始地址就應該為0x00000000,而_start在uboot中的偏移地址為0,所以_start的絕對物理地址就應該是0x00000000。當uboot處於SDRAM中的時候,_start=??那麼它為什麼又會等於TEXT_BASE=0x0c1000000呢???原因就在於,我們要把(注意:是將要把,打算把)uboot搬到TEXT_BASE=0x0c100000(這個位置屬於SDRAM的映射)處。那麼uboot的絕對地址就應該是TEXT_BASE,而_start在uboot中的偏移地址是0,所以_start的絕對地址就是TEXT_BASE+0=TEXT_BASE。在ldr r1,_TEXT_BASE執行之後,r1=TEXT_BASE的;而adr r0,_start執行之後呢??adr指令是基於PC的相對尋址,執行之後r0=PC+_star_offset=PC。如果uboot放在SDRAM中的話,那麼_start的絕對地址是TEXT_BASE,也即PC=TEXT_BASE。

 至此,才明白了是如何判斷是否要進行代碼搬移的。

總結:開始一直以為,uboot在SDRAM中的話,其開始地址應該是SDRAM的映射開始地址,即0x0c000000,也即_start的絕對地址應該是0x0c000000。後來才發現,uboot放在SDRAM中的位置是由程序控制的,即放在TEXT_BASE處。這才明白上面那幾行代碼是怎麼回事了~~~

 話外音::突然間想到---TEXT_BASE是uboot在SDRAM的開始處,所以在SDRAM中的時候_start=TEXT_BASE。只有這樣才能判斷正確~~


相關焦點

  • Cortex-A9 uboot啟動代碼詳解
    現在完善整理成該篇文章,有想學習uboot啟動的代碼詳細流程的老鐵可以進入我B站空間配合視頻一起學習。本篇給大家介紹一款比較常用的bootloader:uboot,通過uboot的介紹以及原始碼的詳細分析,讓大家把之前所有ARM相關的知識點融會貫通起來。一、uboot1.
  • Uboot學習(三)之Uboot的工作方式
    一、從裸機程序鏡像uboot.bin說起:——Uboot學習(二)之Uboot能夠實現哪些功能,這篇裡面我們已經知道了,Uboot它也是一個裸機程序,不是作業系統;而且Uboot它是由若干個.c文件和.h文件組成,配置編譯之後會生成一個uboot.bin,這就是uboot這個裸機程序的鏡像文件,所以才說它是一個裸機程序,這裡如果對單片機熟悉的話,都是這種方式,先通過編譯,
  • 番外篇 | uboot中常用命令
    看著裝修的這麼漂亮的公眾號,必須要更新文章了是不是~今天我們一起來看一下uboot中的常用命令。     講uboot常用命令之前,我們先來引入一下bootloader的概念,那什麼是bootloader呢?簡單來說,bootloader就是一小段程序,一小段引導程序,從系統上電就開始執行,初始化硬體並準備軟體環境,最終調用系統內核,這個就是bootloader。
  • Floods force 20,000 to relocate
    Floods force 20,000 to relocate
  • 用代碼理解數學符號
    你越深入地理解核心數學,你就越有可能靈光一現地創造出一種新方法。對於已經學習數學多年的任何人,可以將這樣的方程式解析為代碼。但是對於許多其他人來說,這看起來像象形文字。事實是,古代數學領袖似乎似乎選擇了最有趣的外觀符號來描述相當直觀的方法。結果是:方程和變量看起來比實際複雜得多。
  • 資料|深入理解Python特性
    from=leiphonecolumn_res0721內容簡介 · · · · · ·本書致力於幫助Python開發人員挖掘這門語言及相關程序庫的優秀特性,避免重複勞動,同時寫出簡潔、流暢、易讀、易維護的代碼。
  • 深入理解GOT覆寫技術
    動態連接器並不會把動態庫函數在編譯的時候就包含到ELF文件中,僅僅是在這個ELF被加載的時候,才會把那些動態函庫數代碼加載進來,之前系統只會在ELF文件中的GOT中保留一個調用地址.GOT覆寫PLT能覆寫嗎?既然GOT能覆寫,那麼PLT能覆寫嗎?
  • 初學VBA人員要反覆理解程序文件中的代碼
    但是,對於初學VBA的學員,僅靠這些是無法完全理解面向對象編程的含義的。如果你能深入的學習VBA,或許你可以看到我的第五套教程「VBA中類的解讀和應用」,在這套教程中我們會學習到什麼是對象?什麼是類?什麼是過程?什麼是方法?什麼是屬性?什麼是事件?什麼是接口?等等。掌握了這些理論,對於自己VBA的應用會更加遊刃有餘。
  • 深入理解 Dart Function & Closure
    (本文中可能會出現 函數 / 方法 二者僅叫法不同)而本文將帶你深入理解 Dart 的函數 (Function)&閉包(Closure)。什麼是 Closure(閉包)如果你從未聽說過閉包,沒關係,本節將會從零開始引入閉包這個概念。
  • 深入學習SAP UI5框架代碼系列之五:SAP UI5控制項的實例數據修改和...
    下圖是一段簡單的SAP UI5代碼:每點擊一次button,就會在press事件的響應函數裡,給button的text屬性值尾部附上一個字符「1」.點了三次按鈕後,其渲染出的HTML代碼如下圖所示,button的text屬性後面多了三個"1":單步調試進入setText方法內部,發現該方法最終執行的實現是ManagedObject.setProperty:我們可以通過上圖右邊調用棧裡實現,複習本系列之前文章學到的兩個知識點:(1) 文章 深入學習SAP UI5框架代碼系列之一:UI5 Module的懶加載機制裡提到的
  • 深入理解.NET Core的基元(二) - 共享框架
    .NET Core的基元(二) - 共享框架 作者:Lamond Lu本篇是之前翻譯過的《深入理解.NET Core的基元: deps.json, runtimeconfig.json, dll文件[2]》的後續,這個系列作者暫時只寫了3篇,雖然有一些內容和.NET Core 3.0已經不兼容了,但是大部分的原理還都是相通的,所以後面的第三篇我也會翻譯。
  • 深入理解 Kotlin 協程 Coroutine(3)
    前面有兩篇文章介紹過協程,加上這篇,基本上介紹得差不多了~深入理解 Kotlin Coroutine 深入理解 Kotlin
  • 乾貨 TensorFlow之深入理解AlexNet
    前言前面看了一些Tensorflow的文檔和一些比較有意思的項目,發現這裡面水很深的,需要多花時間好好從頭了解下,尤其是cv這塊的東西,特別感興趣,接下來一段時間會開始深入了解ImageNet比賽中中獲得好成績的那些模型: AlexNet、GoogLeNet、VGG(對就是之前在nerual network用的pretrained的model
  • 深入理解計算機系統系列
    以下研究將陸續推出,敬請期待~深入理解計算機體系- 1 -計算機晶片的基礎: 門電路及觸發器、周期信號深入理解計算機體系- 2 - cpu核心-ALU(運算器)及四則運算方法深入理解計算機體系- 3 - cpu構造簡介深入理解計算機體系- 4 - 彙編深入理解計算機體系- 5 - x64 cpu及當代cpu技術發展
  • 深入理解 Mybatis 插件開發
    關於Mybatis插件,大部分人都知道,也都使用過,但很多時候,我們僅僅是停留在表面上,知道Mybatis插件可以在DAO層進行攔截,如列印執行的SQL語句日誌,做一些權限控制,分頁等功能;但對其內部實現機制,涉及的軟體設計模式,編程思想往往沒有深入的理解
  • 深入理解Objective-C的Runtime機制
    下面通過分析Apple開源的Runtime代碼(我使用的版本是objc4-646.tar)來深入理解Objective-C的Runtime機制。Runtime數據結構在Objective-C中,使用[receiver message]語法並不會馬上執行receiver對象的message方法的代碼,而是向receiver發送一條message消息,這條消息可能由receiver來處理,也可能由轉發給其他對象來處理,也有可能假裝沒有接收到這條消息而沒有處理。
  • 深入理解C#的委託和事件:事件的由來
    【IT168 專稿】我們繼續思考上面的程序:上面的三個方法都定義在Programe類中,這樣做是為了理解的方便,實際應用中,通常都是 GreetPeople 在一個類中,ChineseGreeting和 EnglishGreeting 在另外的類中。