Bootloader的結構和啟動過程

来源:https://www.cnblogs.com/zhangshuaifeng/archive/2018/11/25/10017929.html
-Advertisement-
Play Games

CPU上電後,會在某個地址開始執行,比如MIPS結構的CPU會從0xBFC00000取第一條指令,而ARM結構的CPU則從0x00000000開始,嵌入式開發板中,需要把存儲器件ROM或Flash等映射到這個地址。而Bootloader就存在這個地址的開始處,這樣一上電後就會從這個地址處執行。Boo ...


CPU上電後,會在某個地址開始執行,比如MIPS結構的CPU會從0xBFC00000取第一條指令,而ARM結構的CPU則從0x00000000開始,嵌入式開發板中,需要把存儲器件ROM或Flash等映射到這個地址。而Bootloader就存在這個地址的開始處,這樣一上電後就會從這個地址處執行。Bootloader執行後從板子上的某個固態存儲設備上將操作系統OS載入到RAM中運行。(一些功能強大的Bootloader,比如U-boot在正常啟動載入後可以延時若幹秒(也可以自己設置),等待終端用戶按下任意鍵後便可進入到下載模式;如果在指定的時間內沒有按鍵,U-boot則會啟動Linux內核,內核的啟動參數可以是預設的或是由U-boot傳遞給它的)。

**註意:有的CPU在運行Bootloader之前 先運行一段固件(firmware)中固化的boot代碼,比如x86結構的CPU就是先運行BIOS中的 固件然後才開始運行硬碟第一個分區中的Bootloader。在大多數的嵌入式系統中並沒有固件,Bootloader是上電後運行的第一個代碼。**

下麵便更細緻得說明Bootloader的啟動過程:
從固態存儲器上啟動的Bootloader大多數是分二個階段來啟動的。
**第一個階段**使用彙編代碼來實現,它主要完成一些依賴於CPU體繫結構的初始化,比如關看門狗、關中斷、初始化RAM、將第二階段調用的C語言代碼複製到RAM(非必須,例如對於NOR Flash等設備可以直接在上面執行,只不過比在RAM上執行效率低),設置CPU的速度和時鐘頻率(非必需,也可以放在第二階段),設置好棧,跳轉到第二階段的C語言入口處等;
**第二個階段**通常用C語言來實現,它主要用來:初始化本階段要用到的硬體設備、檢測系統記憶體映射(就是確定板上使用了多少記憶體,他們的地址空間是什麼)、將內核映像和根文件系統映像從Flash上複製到記憶體RAM並且在記憶體中的某個固定位置為內核設置啟動參數Boot parameters(Flash上的內核映像有可能是經過壓縮的,那麼讀到RAM後還要進行解壓。對於有自解壓功能的內核不需要Bootloader來解壓。另外將根文件系統映像複製到RAM是非必須的,這取決於是什麼類型的根文件系統,以及內核訪問它的方法)、調用內核(內核啟動後會掛載根文件系統,所以典型的嵌入式Linux系統的分區結構為Botloader + Boot parameters + Kernel + Root filesystem)。

**從上面的分析可知將內核放到適當的位置後,直接跳到其入口點便可以啟動內核,在內核之前需要滿足那些條件呢,下麵我們來具體分析:**

**CPU寄存器R0、R1和R2值的設置**
由於U-boot在設置完啟動參數標記列表後最終是調用theKernel函數來跳轉執行linux內核的,uboot調用這個函數(其實就是linux內核)時會直接傳遞給linux內核3個參數,而這3個參數就是通過寄存器來實現傳參的。其中第1個參數固定為0,就放在r0寄存器中,第二個參數為機器類型ID也就是我們常說的機器碼,就放在r1寄存器中,第3個參數就是啟動參數標記列表在RAM中的首地址,就放在r2寄存器中。

**CPU工作模式的設置**
必須禁止中斷(IRQs和FIQs),並且要將CPU設置為SVC模式。
這是因為uboot只是完成硬體初始化,環境參數設置,代碼搬運等工作,用不到中斷。屏蔽中斷是為了避免因為意外中斷使得boot失敗,畢竟很多外設還沒有初始化,對應中斷代碼也都沒有準備好。
那麼為什麼要將CPU設置為SVC模式呢?我們先簡單的來分析一下CPU的7種模式:
中止abt和未定義und模式:
首先可以排除的是,中止abt和未定義und模式,那都是不太正常的模式,此處程式是正常運行的,所以不應該設置CPU為其中任何一種模式,所以可以排除。

快中斷fiq和中斷irq模式:
其次,對於快中斷fiq和中斷irq來說,此處uboot初始化的時候,也還沒啥中斷要處理和能夠處理,而且即使是註冊了終端服務程式後,能夠處理中斷,那麼這兩種模式,也是自動切換過去的,所以,此處也不應該設置為其中任何一種模式。

用戶usr模式:
雖然從理論上來說,可以設置CPU為用戶usr模式,但是由於此模式無法直接訪問很多的硬體資源,而uboot初始化,就必須要去訪問這類資源,所以此處可以排除,不能設置為用戶usr模式。

系統sys模式 vs 管理svc模式:
首先,sys模式和usr模式相比,所用的寄存器組,都是一樣的,但是增加了一些訪問一些在usr模式下不能訪問的資源。

而svc模式本身就屬於特權模式,本身就可以訪問那些受控資源,而且,比sys模式還多了些自己模式下的影子寄存器,所以,相對sys模式來說,可以訪問資源的能力相同,但是擁有更多的硬體資源。

所以,從理論上來說,雖然可以設置為sys和svc模式的任一種,但是從uboot方面考慮,其要做的事情是初始化系統相關硬體資源,需要獲取儘量多的許可權,以方便操作硬體,初始化硬體。

從uboot的目的是初始化硬體的角度來說,設置為svc模式,更有利於其工作。

因此,此處將CPU設置為SVC模式。

另外uboot作為一個bootloader來說,最終目的是為了啟動Linux的kernel,在做好準備工作(即初始化硬體,準備好kernel和rootfs等)跳轉到kernel之前,本身就要滿足一些條件,其中一個條件,就是要求CPU處於SVC模式的。

所以,uboot在最初的初始化階段,就將CPU設置為SVC模式,也是最合適的。

**Cache和MMU的設置**
MMU和數據Cache必須必須關閉,指令Cache可以打開也可以關閉。
由於MMU在上電之初是沒有任何作用的,也就是說U-boo第一階段的彙編代碼以及第二階段的源代碼初始化相關外設時訪問的都是都是實際地址,MMU起不到任何作用,為了啟動之初不影響對程式的啟動常關閉MMU。
Cache是位於RAM和CPU內部寄存器之間的一個存儲設施,用來加速二者之間的數據傳輸速度,即用來加快CPU從記憶體中取出指令的速度。但是在上電後CPU的初始化要比記憶體RAM快一拍,當CPU初始化完成後需要讀取來自記憶體的數據,若記憶體還沒有準備好那勢必會造成異常,系統就掛掉了,因此需要關閉數據Cache,而指令Cache關與不關影響不大。


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

-Advertisement-
Play Games
更多相關文章
  • 一、具備的基礎知識 1.扎實的HTML/CSS/Javascript基本功,這是前置條件。 2.不要用任何的構建項目工具,只用最簡單的<script>,把教程里的例子模仿一遍,理解用法。不推薦上來就直接用 vue-cli 構建項目,尤其是如果沒有 Node/Webpack 基礎。 另外在這裡大家補充 ...
  • 一、我們來給按鈕增加一個懸停效果:#content a:hover {border: 1px solid #000000;color: #000000;text-shadow: 0px 1px white;}兩種狀態下的效果如下,先看預設狀態: 再看懸停狀態: 這裡只是在滑鼠懸停時簡單地修改了一下文 ...
  • 我們在使用Vue作為weex中的前端框架的開發過程中,某次 npm start 遇到瞭如下的錯誤: Vue packages version mismatch: - [email protected] - [email protected] This may cause things to ...
  • 1、圖片圓角顯示 例如(非常簡單): HTML: CSS: 如果圖片只為圓角,這種方式確實沒問題,但如果還要加上居中的效果,這種方式就有問題,下麵會說明。 2、圖片居中顯示(鋪滿父容器且不變形) 效果圖如下: PS:為了實現上圖居中的效果,單靠CSS是不行的,還需要JS處理。 例如: HTML: C ...
  • 以前有小伙伴自己做了個小游戲,類似掃雷這種,都覺得簡單好玩,老師還提名錶揚呢,那時沒深究是怎麼開發的,現在想想就是純前端的簡單小游戲啊。 工作後,發現前端才是王道啊,先不說大家說的什麼“整個互聯網都缺前端啊”這種話題,就說要抓取用戶眼球,讓用戶有點擊的欲望,這都是前端工作啊,畢竟用戶才不關心“你咋實 ...
  • 日常在群里討論一些概念性的問題,比如變數提升,作用域和閉包相關問題的時候,經常會聽一些大佬們給別人解釋的時候說執行上下文,調用上下文巴拉巴拉,總有點似懂非懂,不明覺厲的感覺。今天,就對這兩個概念梳理一下,加深對js基礎核心的理解。 1. 執行上下文(execution context)與可執行代碼( ...
  • H5中拖拽屬性: draggable: auto | true | false 拖動事件: - dragstart 在元素開始被拖動時觸發 - dragend 在拖動操作完成時觸發 - drag 在元素被拖動時觸發 釋放區事件: ...
  • 上一篇給大家的三段代碼不知到大家有沒有練習呢?今天再給大家帶來兩段DOM的練習! 4.封裝函數,實現children功能,最好哎原型鏈上編程 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...