uboot之位置無關代碼解析

来源:https://www.cnblogs.com/PanShen/archive/2018/02/23/8463108.html
-Advertisement-
Play Games

在之前的話 新年過去了,那麼久沒有好好學習,感覺好頹廢,現在就uboot的一些基礎問題做一些筆記,順便分享給大家,不過由於見識有限,如果有不足之處請多多指教。 位置無關?什麼意思?我們先瞭解一些基礎知識。。。。。 我們都知道我們寫的代碼最後是運行在記憶體(SDRAM或者SRAM,通常是SDRAM)中的 ...


 

在之前的話

  新年過去了,那麼久沒有好好學習,感覺好頹廢,現在就uboot的一些基礎問題做一些筆記,順便分享給大家,不過由於見識有限,如果有不足之處請多多指教。

 

位置無關?什麼意思?我們先瞭解一些基礎知識。。。。。

  我們都知道我們寫的代碼最後是運行在記憶體SDRAM或者SRAM,通常是SDRAM)中的,但是在運行之前他們是保存在諸如nandflash等非易失存儲設備中的,而這些存儲設備的地址要映射到CPU能夠尋找的地址上(一般映射在0X0地址上,這個後面詳細解釋),這樣才能得到要運行的代碼。而代碼要運行的記憶體(這裡就假設是SDRAM)也要映射到CPU上(肯定是和nand那些存儲器不一樣的地址,例如三星的2440的就映射到了0x30000000上),所以說存儲在nand或者flash的代碼最終得複製到記憶體上運行的。這裡就記住代碼存儲的地方(載入地址)和代碼要運行的地方(運行地址)是不一樣的

  現在說一下地址映射的問題。在學習ARM時,我們一般會遇到兩種啟動方式,一個是nand啟動,一個是nor啟動。這兩種啟動方式都是映射到0x0地址的,但是映射方式稍有不同。所以先瞭解一下這兩種介質的硬體特性:

     nand:由於nand存儲器的硬體特性,代碼是無法在他上面運行的,他只有存儲代碼的功能。

     nor:他不僅可以存儲代碼,還可以讓代碼運行,但是他只能進行讀,不能進行寫的操作,但畢竟是可以運行代碼啦。

 

  所以nand啟動的話,如果沒有進行特殊手段,代碼是無法得到的,在ARM中,他是通過硬體自動把nand前面的4K代碼複製到一塊映射到0x0地址上的SRAM中的,記住這是硬體自動完成的。這樣4K代碼就在SRAM上了,我們知道SRAM是能運行代碼的(可讀可寫)。但是這個SRAM只有4K大小,要是存儲在nand的代碼不止4K,只在SRAM上面運行是無法完成代碼設定的所有功能的。為瞭解決這個問題,於是就在這4K的代碼中完成一個可以將nand的代碼複製到其他更大的記憶體上(這裡是SDRAM),這樣就可以運行所有代碼了。

  nor啟動的話,由於nor可以運行代碼,所以就不用什麼SRAM了,直接把nor映射到0x0位置上就可了,如果nor空間夠大,甚至可以不用重定位代碼,只是nor無法進行寫功能,讀取的效率又沒SDRAM,加上為了相容nand啟動(不用寫兩套代碼),也就跟nand啟動一樣只運行前面4K,剩下複製到SDRAM上再繼續運行。

  問題又來了,我們知道代碼經過編譯,鏈接後才可以得到可以運行的代碼,而這代碼只有在鏈接時指定的位置上才能運行。對於2440,鏈接文件指定的位置一般是在SDRAM上面的,可是nand啟動時,前面的4K代碼卻在SRAM中運行了

  這會有什麼問題?我們知道編寫好的代碼的地址在鏈接時就已經安排好了。例如2440鏈接文件指定鏈接地址是0x30008000,那麼所有代碼地址就是從0x30008000開始的。而在啟動時,代碼卻是在0x0開始運行的,如果不進行特殊處理,肯定會有問題,比如我們調用一個函數,而這個函數地址是在SDRAM上的(鏈接時已經確定),並且這時代碼還沒複製到SDRAM上,也就是說代碼還在nand或者在4KSRAM裡面,在SDRAM是找不到要調用的函數的,那樣就會無法執行這個函數。

  如果在還在nand裡面肯定是沒辦法了,這個代碼是無法運行的必須廢棄,如果在4KSRAM就有辦法了。於是就出現了位置無關指令:

    位置無關/相關指令:

      B  BL  ADR  MOV  ADD等,這些指令都是位置無關指令

      LDR  STR等指令是位置有關指令

位置無關什麼意思呢?

  既然這個時候SDRAM還沒有代碼,那就不去那裡找了嘛,我們去別的地方找。別的地方是哪裡呢?這個時候代碼是運行在SRAM上的,處理器的PC寄存器也是指向這個地方的,有4K代碼也是在這個地方的。那我就不用鏈接指定的地址來尋找想要的代碼,我設計一些是與PC寄存器指向的位置有聯繫的定址指令來定址,這樣PC寄存器指向哪裡,我就在哪裡找我想要的代碼,而不是去鏈接指定的地址去找

  位置無關指令就是這樣的指令,他不去鏈接指定位置尋找代碼,而是在PC寄存器指向的位置相對它前後32M的範圍尋找代碼,也就是說只要我想要調用的代碼在PC指向位置前後的32M範圍內,就能找到(這是硬體完成的,我們知道位置無關指令就是這個意思就行)。當然,我們的SRAM只有4K,所以尋找的範圍肯定就只能在這4K裡面才行了,超過了也是找不到的。所以要求我們的重定位代碼必須在這4K裡面,必要的硬體初始化代碼,記憶體初始化代碼,nand初始化代碼等等,必須在4K以內完成,否則就會出問題。所以位置無關指令的定址是基於當前PC寄存器位置來定址的。

 

下麵根據uboot的代碼進行講解

1.記憶體控制器初始化代碼

_TEXT_BASE:

      .word     TEXT_BASE   /*根據鏈接地址得知這是0x30000000*/

 

  .globl lowlevel_init       /*定義lowlevel_init為全局函數*/

  lowlevel_init:

      ldr     r0, =SMRDATA  /*鏈接後,SMRDATA是在SDRAM上某個位置的,但是這時候SDRAM還沒任何代碼,代碼現在還在SRAM上,也就說ldr指令是位置相關指令*/

      ldr   r1, _TEXT_BASE  /*0x30000000*/

      sub  r0, r0, r1          /* SMRDATA _TEXT_BASE就是13個寄存器在SRAM上的地址 */

      ldr   r1, =BWSCON   /* R1指向記憶體控制器的寄存器地址上 */

      add     r2, r0, #13*4 /*13個寄存器,每個32位寬度*/

  0:

      ldr     r3, [r0], #4    /*13個寄存器的值逐一賦值給對應的寄存器*/

      str     r3, [r1], #4

      cmp     r2, r0

      bne     0b

 

      /* everything is fine now */

      mov       pc, lr

 

      .ltorg

  /* the literal pools origin */

 

  SMRDATA:            /*  下麵是13個寄存器的值  */

   .word  … …

   .word  … …

 … …

 

2.nor啟動的重定位代碼

  adr  r0, _start              /*adr是位置無關指令,因為nor啟動,這時第一條指令被映射到nor上的0x0位置,所以R0=0x0,如果是RAM啟動,那_start就是存在0x30000000 */

      ldr   r1, _TEXT_BASE            /* 位置相關指令,R1=0x30000000 */

 

/* 判斷U-Boot是否是下載到RAM中運行,若是,則不用 再複製到RAM中了,這種情況通常在調試U-Boot時才發生 */

      cmp      r0, r1      /*_start等於_TEXT_BASE說明是下載到RAM中運行 */

      beq stack_setup

  /* 以下直到nand_boot標號前都是NOR Flash啟動的代碼 */

      ldr   r2, _armboot_start  /*這裡其實就是_start的地址*/

      ldr   r3, _bss_start

      sub  r2, r3, r2              /* 得到代碼大小   */

      add r2, r0, r2              /* 得到代碼結束地址   */

  /* 搬運U-Boot自身到RAM*/

  copy_loop:

      ldmia     r0!, {r3-r10} /* 從地址為[r0]NOR Flash中讀入8個字的數據 */

      stmia      r1!, {r3-r10} /* r3r10寄存器的數據複製給地址為[r1]的記憶體 */

      cmp       r0, r2                    /* until source end addreee [r2]    */

      ble  copy_loop

      b     stack_setup         /* 跳過NAND Flash啟動的代碼 */

 

以上就是位置無關代碼的解析了,uboot在運行第二階段之前,絕大部分的指令都是位置無關指令,這樣才能保證代碼能夠運行。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 資料庫訪問性能優化 資料庫的連接和關閉 訪問資料庫資源需要創建連接、打開連接和關閉連接幾個操作。這些過程需要多次與資料庫交換信息以通過身份驗證,比較耗費伺服器資源。ASP.NET中提供了連接池(Connection Pool)改善打開和關閉資料庫對性能的影響。系統將用戶的資料庫連接放在連接池中 ...
  • 運行程式,如果資料庫已經存在,則刪除重建。當打開 連接以及單獨使用OpenAsync和ExecuteNonQueryAsync方法執行SQL命令時,我們使用了I/O非同步操作。 在這個任務完成後,我們創建了一張新的表並插入了一些數據,除了之前提到的方法,我們還使用了ExceuteS... ...
  • 2017晃眼就過去了,2018開工了。閑暇之餘,我想為自己訂個小小目標。 作為一名.NET菜逼程式員。 肯定是希望自己在2018學的更多,做的更多,具體的我想了想: 2017年工作也算比較順利,換了兩家公司,感覺任務都不是特別繁重,也很少加班。第一家公司是做WPF的,我之前沒有做過,但公司願意給我時 ...
  • 1、破解版下載&安裝 參考:https://bbs.feng.com/read htm tid 6939481.html 2、session導入 查看 SecureCRT Preferences General Configuration Paths ,就可以查看session具體目錄,將已有ses ...
  • 前言 今天部門老大開了一個會,期間說到,以後我們部署東西,都是純粹命令部署的,但是用習慣了windows的自己,剛開始用Linux真的是一種折磨,但是折磨歸折磨,想進步就要能夠忍受折磨,所以,還能怎麼辦呢?只好在虛擬機中裝一個沒有界面的centOS,然後藉助secureCRT進行相關連接了.... ...
  • HAProxy介紹 HAProxy HAProxy支持兩種主要的代理模式 HAProxy負載均衡策略非常多 HAProxy優缺點 HAProxy功能 HAProxy 組成 ...
  • 1、簡介: RCU(Read-Copy Update)是數據同步的一種方式,在當前的Linux內核中發揮著重要的作用。 RCU主要針對的數據對象是鏈表,目的是提高遍歷讀取數據的效率,為了達到目的使用RCU機制讀取數據的時候不對鏈表進行耗時的加鎖操作。這樣在同一時間可以有多個線程同時讀取該鏈表,並且允 ...
  • KeepAlived介紹 keepalived 相關縮略詞 術語 keepalived的主要作用 keepAlived有三個進程 keepAlived組件 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...