Linux學習筆記——零基礎詳解:什么是Bootloader?U-Boot啟動流程全解析!

零基礎詳解:什么是Bootloader?U-Boot啟動流程全解析!

    • 一、什么是Bootloader?
      • 📌 舉個例子:
    • 二、U-Boot 是什么?
    • 三、U-Boot啟動過程:分為兩個階段
      • 🔹 第一階段(匯編階段)
      • 🔹 第二階段(C語言階段)
    • 四、U-Boot是怎么啟動Linux內核的?
    • 五、U-Boot與Linux之間的參數傳遞機制
      • 💡 什么是 tag(啟動參數)?
    • 六、為什么U-Boot要關閉 Cache 和 MMU?
    • 七.為什么要給內核傳遞參數?
      • 為什么要傳遞這些參數?
    • 八、系統啟動完整流程回顧
    • 九、總結一句話
    • 📌 小貼士:常見面試題匯總

一、什么是Bootloader?

Bootloader(引導加載程序),是一段特殊的“小程序”,它運行在 系統剛上電時,主要目的是:

  • 初始化硬件環境(如:內存、時鐘、中斷、串口等)
  • 然后將 Linux內核從 flash(NAND, NOR FLASH,SD,MMC等)拷貝到SDRAM中,最后啟動Linux內核

通俗一點講,Bootloader 就像電腦中的 BIOS —— 當你按下電源開關,它最先啟動,完成最基礎的硬件檢測后,才將控制權交給操作系統(比如 Windows 或 Linux)。

📌 舉個例子:

項目PC系統嵌入式Linux系統
初始程序BIOSBootloader
操作系統WindowsLinux
存儲介質硬盤Flash / SD卡等

二、U-Boot 是什么?

U-Boot(全稱為 Universal Bootloader)是一種 開源、通用的Bootloader,支持多種架構(ARM、MIPS、x86等),被廣泛應用于嵌入式Linux開發中。

它的主要任務:

  • 初始化硬件資源(如內存、串口、存儲器等)
  • 加載Linux內核到內存中
  • 傳遞啟動參數給內核
  • 啟動Linux內核

三、U-Boot啟動過程:分為兩個階段

🔹 第一階段(匯編階段)

此階段主要用 匯編代碼編寫,功能包括:

  1. 初始化時鐘系統
  2. 關閉看門狗(防止系統誤復位)
  3. 關閉中斷
  4. 啟動指令Cache(ICache)
  5. 關閉數據Cache與TLB
  6. 關閉MMU
  7. 初始化SDRAM(用于加載后續程序)
  8. 初始化NAND Flash
  9. 代碼重定位(將U-Boot代碼搬運至SDRAM中運行)

💡 注意:這部分代碼位置受限(通常在片內RAM或FLASH運行),所以通常要寫得很精煉。


🔹 第二階段(C語言階段)

這部分用 C語言編寫,主要功能是:

  1. 初始化串口(便于調試)
  2. 打印啟動信息
  3. 檢測內存映射情況
  4. 從存儲介質讀取Linux內核鏡像和根文件系統(initrd)將內核映象和根文件系統映象從 Flash上讀到SDRAM空間中
  5. 設置內核啟動參數
  6. 跳轉到Linux內核執行入口

四、U-Boot是怎么啟動Linux內核的?

當U-Boot完成自身工作后,就會把控制權交給Linux內核。那么,怎么跳轉呢?

👉 本質就是:修改PC寄存器的值為內核所在地址

這樣CPU下一條執行指令就來自Linux內核,開始正式啟動!


五、U-Boot與Linux之間的參數傳遞機制

這部分是面試常考,請務必掌握!

在跳轉到內核之前,U-Boot 會設置好三個寄存器:

寄存器含義示例說明
R0保持為0固定寫0即可
R1機器ID(開發板型號)如友善之臂開發板是199,見mach-types.h
R2參數的地址(tag結構體)tag鏈表,里面保存了內存大小、命令行、根文件系統等

📌 這些參數是內核“啟動時所需的環境信息”,如果不給內核傳遞參數,它無法知道設備的具體配置!

  1. R0寄存器:設置為0,通常用于標識內核啟動時的參數。
  2. R1寄存器:傳遞給內核一個“機器ID”。這是一個唯一標識當前硬件平臺的ID,每個開發板或CPU都會有一個唯一的ID。內核會根據該ID來判斷是否支持當前硬件平臺。
  3. R2寄存器:存儲一個指向參數列表的指針,該列表包含了內核啟動時需要的所有環境信息(例如內存大小、內存地址、文件系統等)。

💡 什么是 tag(啟動參數)?

tag 是一組結構體,存放了啟動參數,形式如下:

struct tag {struct tag_header {uint32_t size;   // tag大小(單位:4字節)uint32_t tag;    // tag類型(如ATAG_MEM、ATAG_CMDLINE等)} hdr;union {struct tag_mem32 mem;struct tag_cmdline cmdline;// 其他類型參數...} u;
};

📌 常見的tag有:

  • ATAG_CORE:表示起始
  • ATAG_MEM:內存起始地址與大小
  • ATAG_CMDLINE:命令行參數(如根文件系統路徑)
  • ATAG_NONE:表示結束

六、為什么U-Boot要關閉 Cache 和 MMU?

  • 上電后RAM未初始化前,Cache 不能正常工作。
  • 如果數據 Cache 開啟了,會導致從未初始化的Cache中讀取錯誤數據,程序可能崩潰!
  • 所以:必須關閉MMU和Data Cache,指令Cache可以開也可以不開。

七.為什么要給內核傳遞參數?

在啟動Linux內核之前,U-Boot完成了對硬件的基本初始化。此時,U-Boot已經“適應”了當前的開發板,但Linux內核并不一定能直接支持所有開發板。因為每個開發板的硬件配置都可能有所不同,例如不同的CPU型號、內存配置、外設接口等。而內核本身并不是為每個具體的開發板都做了硬件適配的,因此,內核在啟動時需要了解當前開發板的硬件環境。為此,U-Boot需要將這些硬件信息傳遞給內核,以幫助內核做相應的配置和適配。

為什么要傳遞這些參數?

  1. 硬件適配:Linux內核需要了解當前硬件平臺的配置(例如內存大小、CPU架構、設備樹等)才能正確配置和初始化硬件資源。如果沒有這些信息,內核就無法正確識別或初始化硬件設備。
  2. 啟動過程的靈活性:開發板通常會有不同的硬件平臺,U-Boot的作用就是提供一個通用的引導機制,而通過參數傳遞,U-Boot使得內核在加載后可以根據傳遞的參數調整自身的行為和配置。
  3. 內核啟動時的配置:內核需要根據不同的硬件環境來調整內存、CPU等硬件的使用模式。例如,在某些開發板上可能需要配置特定的硬件接口,或者根據內存的大小調整內核的行為。通過參數傳遞,內核能夠靈活地進行這些調整。

八、系統啟動完整流程回顧

下面是系統上電到進入Linux系統的完整流程圖:

[ 上電/復位 ]↓
[ ROM代碼執行 ]↓
[ 初始化外設 & SDRAM ]↓
[ 加載并執行U-Boot ]↓
[ U-Boot初始化硬件 ]↓
[ 加載Linux內核 + initrd ]↓
[ 設置啟動參數(R0, R1, R2)]↓
[ 跳轉到內核入口 ]↓
[ Linux內核初始化 ]↓
[ 掛載根文件系統 ]↓
[ 啟動用戶空間進程 ]

九、總結一句話

Bootloader 就是操作系統的“搬運工 + 啟動器”,而 U-Boot 就是最流行的 Bootloader,它讓 Linux 成為可能!


📌 小貼士:常見面試題匯總

面試問題回答要點
什么是Bootloader?啟動時執行的第一段程序,初始化硬件,加載并啟動內核
U-Boot做了哪些事?兩階段:匯編(初始化)、C語言(加載內核+參數設置+跳轉)
U-Boot如何跳轉到Linux內核?設置PC寄存器為內核地址
參數是如何傳遞給內核的?用R0=0, R1=機器ID, R2=tag結構體地址傳遞
為什么要關閉Data Cache?避免RAM未初始化時Cache取錯誤數據導致程序異常
什么是tag結構?如何組織?struct tag,含header+聯合體,ATAG_CORE起始、ATAG_NONE結束

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74886.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Word 頁眉設置(不同章節不同頁眉)

需求分析 要給文檔設置頁眉,但是要不同的頁眉不同的頁眉 問題點:一旦設置頁眉 每個頁眉都是一樣的 現在要設置不一樣的 設置了頁眉但是整個文章的頁眉都一樣 問題解決 取消鏈接 前一節(不和前面的頁眉同步更新) 小結 不同的…

Debezium日常分享系列之:Debezium3.1版本之增量快照

Debezium日常分享系列之:Debezium3.1版本之增量快照 按需快照觸發一次臨時增量快照觸發臨時阻塞快照增量快照增量快照過程如何 Debezium 解決具有相同主鍵的記錄之間的沖突快照窗口觸發增量快照使用附加條件運行臨時增量快照使用 Kafka 信號通道觸發增量快照臨時增量…

音視頻開發從入門到精通:編解碼、流媒體協議與FFmpeg實戰指南

音視頻開發從入門到精通:編解碼、流媒體協議與FFmpeg實戰指南 音視頻技術作為數字媒體領域的核心,正在成為互聯網和移動應用的重要組成部分。本文將全面介紹音視頻開發的學習路徑,從基礎概念到高級應用,從編解碼原理到實戰案例&a…

bookkeeper基本概念

Apache BookKeeper 架構與基本概念 Apache BookKeeper 的架構 Apache BookKeeper 是一個高性能的分布式日志存儲系統,主要用于存儲和管理順序寫入的數據。它被設計用來提供低延遲、高吞吐量和強一致性的服務,常用于分布式系統中的日志存儲需求&#xf…

Scala相關知識學習總結3

包 - 包聲明:和Java類似,作用是區分同名類、管理類命名空間。Scala包名只能含數字、字母等,不能數字開頭、不能用關鍵字。 - 包說明:有類似Java的包管理風格,也有獨特嵌套風格。嵌套風格有兩個特點,一是&…

在Spring Boot中實現圖片上傳和修改

1. 圖片上傳實現步驟 1.1 添加依賴 確保 spring-boot-starter-web 和 spring-boot-starter-validation 已存在&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> <…

網絡原理 - HTTP/HTTPS

1. HTTP 1.1 HTTP是什么&#xff1f; HTTP (全稱為 “超文本傳輸協議”) 是?種應用非常廣泛的應用層協議. HTTP發展史&#xff1a; HTTP 誕生于1991年. 目前已經發展為最主流使用的?種應用層協議 最新的 HTTP 3 版本也正在完善中, 目前 Google / Facebook 等公司的產品已經…

第十屆MathorCup高校數學建模挑戰賽-A題:無車承運人平臺線路定價問題

目錄 摘 要 一、問題提出 1.1 背景 1.2 問題重述 二、基本假設 三、符號說明 四、問題分析 4.1 問題一的分析 4.2 問題二的分析 4.3 問題三的分析 4.4 問題四的分析 五、模型的建立與求解 5.1 問題一模型的建立與求解 5.1.1 數據預處理 5.1.2 問題一結果檢驗:因子分析模型 5.2…

C++假期練習

思維導圖 牛客練習

Go語言-初學者日記(四):包管理

眾所周知——“包”治百病。 理解包與模塊&#xff0c;是 Go 邁向工程化開發的關鍵一環&#xff01; &#x1f4c2; 一、包&#xff08;Package&#xff09;是 Go 的基本組織單位 在 Go 中&#xff0c;每個 .go 文件都屬于某個包&#xff08;package&#xff09;&#xff1a; …

Scala面向對象2

1. 抽象屬性和方法&#xff1a;用 abstract 關鍵字定義抽象類&#xff0c;其中抽象屬性無初始值&#xff0c;抽象方法無實現 。重寫抽象方法需用 override &#xff0c;重寫抽象屬性時&#xff0c;可變屬性用 var &#xff0c;不可變屬性用 val 。 匿名子類&#xff1a;和 Jav…

DiffAD:自動駕駛的統一擴散建模方法

25年3月來自新加坡公司 Carion 和北航的論文“DiffAD: A Unified Diffusion Modeling Approach for Autonomous Driving”。 端到端自動駕駛 (E2E-AD) 已迅速成為實現完全自動駕駛的一種有前途的方法。然而&#xff0c;現有的 E2E-AD 系統通常采用傳統的多任務框架&#xff0c…

Python四大核心數據結構深度解析:列表、元組、字典與集合

在Python編程語言中&#xff0c;數據結構是組織和存儲數據的基本方式。Python提供了四種內置的核心數據結構&#xff1a;列表&#xff08;List&#xff09;、元組&#xff08;Tuple&#xff09;、字典&#xff08;Dictionary&#xff09;和集合&#xff08;Set&#xff09;。這…

網絡編程—Socket套接字(TCP)

上篇文章&#xff1a; 網絡編程—Socket套接字&#xff08;UDP&#xff09;https://blog.csdn.net/sniper_fandc/article/details/146923670?fromshareblogdetail&sharetypeblogdetail&sharerId146923670&sharereferPC&sharesourcesniper_fandc&sharefro…

SkyWalking+Springboot實戰(最詳細)

本篇文章記錄了作者在0到1學習SkyWalking的過程&#xff0c;記錄了對SkyWalking的部署&#xff0c;學習&#xff0c;使用Bug解決等等過程 一、什么是SkyWalking 官方文檔&#xff1a; Apache SkyWalkinghttps://skywalking.apache.org/ SkyWalking 是一個開源的分布式追蹤、性…

Arduino示例代碼講解:Row-Column Scanning an 8x8 LED matrix with X-Y input LED矩陣

Arduino示例代碼講解:Row-Column Scanning an 8x8 LED matrix with X-Y input LED矩陣 Row-Column Scanning an 8x8 LED matrix with X-Y input LED矩陣功能概述硬件部分:軟件部分:代碼逐行解釋定義常量定義變量`setup()` 函數`loop()` 函數`readSensors()` 函數`refreshScr…

多線程編程中的鎖策略

目錄 1.悲觀鎖vs樂觀鎖 關鍵總結 悲觀鎖&#xff1a; 樂觀鎖&#xff1a; 選擇建議 用 悲觀鎖 當&#xff1a; 用 樂觀鎖 當&#xff1a; 2.重量級鎖vs輕量級鎖 選擇建議 用 輕量級鎖&#xff1a; 用 重量級鎖&#xff1a; 3.掛起等待鎖vs自旋鎖 關鍵細節說明 選擇…

負載均衡是什么,Kubernetes如何自動實現負載均衡

負載均衡是什么&#xff1f; 負載均衡&#xff08;Load Balancing&#xff09; 是一種網絡技術&#xff0c;用于將網絡流量&#xff08;如 HTTP 請求、TCP 連接等&#xff09;分發到多個服務器或服務實例上&#xff0c;以避免單個服務器過載&#xff0c;提高系統的可用性、可擴…

React-01React創建第一個項目(npm install -g create-react-app)

1. React特點 JSX是javaScript語法的擴展&#xff0c;React開發不一定使用JSX。單向響應的數據流&#xff0c;React實現單向數據流&#xff0c;減少重復代碼&#xff0c;比傳統數據綁定更簡單。等等 JSX是js的語法擴展&#xff0c;允許在js中編寫類似HTML的代碼 const …

小程序中的網絡請求

在小程序中&#xff0c;使用 wx.request( ) 這個方法來發送網路請求&#xff0c;整個請求的方式和 jQuery 里面的 $.ajax 方法是非常相似的。 在 wx.request( ) 這個方法中&#xff0c;接收一個配置對象&#xff0c;該配置對象中能夠配置的項目如下表&#xff1a; 關于服務器…