Linux

Linux/嵌入式 Linux - 了解核心和其他 BSP 特定組件

  • November 11, 2015

*tldr; 我想大致了解 linux / 嵌入式 linux 的世界是如何工作的。我需要做什麼才能從頭開始採用 Linux 主線並在具有不同處理器和外圍設備的板上編譯/部署它。

我目前如何看待它的工作方式:

讓 Linux 在任意板上執行的步驟:

  • 獲取 uBoot(嵌入式)或 GRUB(桌面/x86 SOM)的原始碼
  • 為特定係統修改 uBoot 或 GRUB,編寫程式碼以初始化特定晶片並獲得所需的記憶體和控制台介面並執行
  • 修改uBoot/GRUB config.txt 配置上面寫的程式碼
  • 編譯這些並部署到板上,驗證引導載入程序控制台是否出現並可以與之互動
  • 獲取核心主線源
  • “make config”來選擇可用的驅動程序和模組(此時這些選擇將更改源 - 這些設置的儲存位置將不再與主線中的 git clone 匹配)(在原始碼管理中跟踪此 .config 文件以後的參考)
  • 獲取諸如 Busybox 或桌面替代品之類的工具?在源目錄中安裝
  • 獲取 ucLibc 或其他庫並安裝在源目錄中
  • 使用特定晶片的交叉編譯器工具鏈編譯核心原始碼
  • 為板創建設備樹文件 .dtb(嵌入式/桌面?或桌面不使用?)這將驅動程序連接到物理引腳
  • 使用 Uboot/GRUB 和 TFTP/串列控制台或記憶體卡等來載入編譯的核心映像。
  • 根據驅動程序和設備樹配置,通過串列/SSH 等啟動並驗證 shell 訪問
  • 修改 uEnv.txt(嵌入式)或神秘文件.txt(桌面)以進行板特定配置?這本質上是一個阻止或添加核心啟動步驟的腳本?什麼是桌面等價物?
  • apt-get 所需的軟體包和驅動程序
  • 編寫驅動程序和應用程式碼並測試(手動載入驅動程序)
  • 添加設備樹文件以說明上面實現的硬體和驅動程序(這些與創建的初始 BSP 是分開的)
  • 要將這些包含在核心映像中,請建構核心並使用文件夾結構中的所有這些源和配置文件 mods 創建文件結構(Linux 主線的添加/mods)
  • 可以為 Linux 主線和 mods 提供一個單獨的文件夾,直接複製 mods 覆蓋/添加文件到第三個暫存文件夾中的主線。這將允許所有添加和非主線模組單獨進行原始碼控制。

如果您可以獲得一個可以通過 SSH 連接的基本系統,並且此時您擁有所有常見組件(影片、USB、滑鼠等)的驅動程序,那麼此時您幾乎可以做任何事情(安裝 X11 伺服器、LXDE、網路等)?哪些驅動程序需要由引導載入程序/bios 處理,哪些驅動程序純粹在核心域中?

有用於配置核心建構的 Kconfig 文件。這是有道理的,我看到的核心模組開發文件似乎很好地描述了這一點。

還有像 uEnv.txt 和 config.txt 這樣的文件來處理執行時配置以及應該載入哪些設備。還有設備樹 blob 也確定應該載入哪些設備?

這些文件中的魔術字元串如何與核心相關聯,這些修改是否對特定板的主線進行?必須閱讀這些內容以確定是否應啟用 HDMI,並且這不能與 Linux 桌面版本上的程式碼完全相同。

一旦驅動程序進入主線,他們是否仍然獨立於主線開發?例如,我一直在使用幾個驅動程序,但有註釋它們現在包含在主線中,這是否意味著不再可以直接自行下載?我遵循的步驟下載了我的板的標題,原始碼,然後編譯並安裝它。如果它在主線中,我現在需要從那里拉它嗎?

背景和具體想法

我是一名 EE,有微控制器和 Windows 開發經驗,但沒有太多 Linux 經驗。我的問題的框架是“如果我開始使用這個任意(使用 linux 編譯器)處理器,以及這些外圍設備,我如何(以及我的選擇)來建構 linux 版本”

引導載入程序:

我已經能夠找到 RPI2 和 BBB(Beaglebone Black)的特定文件和操作方法,但是當您進入更高級的主題(如引導載入程序)時,只有一些碎片可以模糊地描述正在發生的事情。例如,RPI2 有一個 3 階段的引導載入程序(從讀取來看,它聽起來並不完全基於 uBoot),而 BBB 有一個更“傳統”的基於 uBoot 的引導載入程序。現在,新的 BBx15 具有跳線,您可以在其中選擇要從哪裡啟動。

桌面系統使用 GRUB (IIRC),嵌入式系統通常使用 uBoot。我讀過 RPI 在啟動期間使用 GPU 並從單獨的 ROM 中讀取第一階段的引導載入程序。這就是所有可用的資訊。如果你想旋轉你自己的板子版本(為了討論,這不是很實用)那麼除了 uBoot 之外還有什麼?BBx15 的 uBoot 是否有額外的修改以允許選擇跳線啟動?

Linux 是否知道啟動階段的任何資訊,或者一旦它執行它就會忘記這一點?BBB 使用 uBoot 將映像從 eMMC 載入到 RAM 中,RPI2 使用 3 階段引導載入程序。我猜 BBB 使用 ARM 處理器來執行此操作,但 RPI2 使用 GPU。我認為在加電時 ARM 處理器開始執行,他們需要修改什麼來暫存這些載入過程?GPU 在完成其 ROM 程式碼之前是否會保持 ARM 處於復位狀態?由於 GPU 是引導過程的一部分,這是否意味著它執行的程式碼是從 uBoot 程式碼中取出的,沒有這個 GPU 的其他系統必須在 uBoot 程式碼中執行嗎?整個過程對我來說意味著,如果您修改第二或第三階段引導載入程序,您可以完全脫離 GPU 執行 Linux(如果核心是使用 GPU 工具鏈編譯的)?

第三階段的引導載入程序和config.txt實際上只是uBoot嗎?

關於正在使用的電路板的接頭。這些只是來自主線的標題,其中包含已覆蓋的驅動程序,還是還有更多內容。如果這是您開始執行的,那麼“標題”只是主線標題?

對於嵌入式微控制器開發,我習慣於使用 HAL 層。HAL 具有功能存根,您可以在其中設置外圍設備,然後將驅動程序指向這些資源。電路板支持包通常已經為相關電路板編碼了這些 HAL 存根。我確信這裡與 Linux 開發有一些相似之處,但我不太清楚這些部門在哪裡。

有 Buildroot 和 Yocto 等軟體包。這些只是帶有介面的 Linux 主線,可以自動選擇要包含的 ARM 處理器和驅動程序嗎?

從我玩過的路由器硬體的小經驗來看,我可以說這是一個愚蠢的小硬體,只是為了做一件事。

在硬體層面,這很簡單:

U-Boot 不僅有引導載入程序,還有 PC 術語中的 BIOS。所以它不僅是一個引導載入程序,而且它還能初始化所有硬體。開始時,CPU 直接執行它(例如從 FLASH 執行),並決定下一步做什麼,但通常它會將自己重新定位到記憶體中。然後它會做它需要做的事情:從快閃記憶體讀取配置,然後在指定地址載入圖像並將控制轉移到那裡。沒什麼特別的,但重要的是要知道。

U-Boot(嵌入在路由器硬體上)根本不訪問根文件系統。相反,整個核心映像(通常是壓縮的)都有一個專用空間。所以,至少在路由器上 - 沒有 /boot/vmlinuz 文件。

RPI 確實使用它自己的專有引導序列。他們有使用者放在 SD 快閃記憶體上的閉源二進製文件。第一階段的初始化程式碼被硬編碼到 CPU 或船上的某個地方。他們在 GPU 之後啟動 ARM 核心,整個程式碼都是為 GPU 完成的。更多關於這也許你已經找到了,但如果沒有:https ://raspberrypi.stackexchange.com/questions/10489/how-does-raspberry-pi-boot

所以,因為我用路由器做了一些有趣的事情,並且完全從原始碼將它們重新建構到我的小型伺服器中,所以我可以列出我自己的建構順序:

  • 獲取並建構平台的u-boot
  • 建構 Linux 核心
  • 建構使用者空間(核心和使用者空間通常是分開的,即使在快閃記憶體上也是如此)
  • 在程式器上將 u-boot 快閃記憶體到快閃記憶體中
  • 焊錫閃光到板上
  • 通過 UART 連接到電路板
  • 啟動它,驗證 u-boot 是否能正常啟動所有硬體
  • tftp 核心,寫入板內快閃記憶體
  • tftp rootfs,寫入板內快閃記憶體
  • 重置,驗證一切正常
  • 微調 rootfs:設置權限,通過 tftp 預載入預設配置
  • 轉儲整個圖像,在許多設備上刷新它

然後 Linux 核心可以或不能支持您的主機板。請確認。例如,您將無法獲取最新的核心並為您的路由器建構它。RPi 也是如此:它們有自己的核心樹。這在嵌入式世界中經常發生,只有少數(通常是通用的)平台被 Linux 核心直接支持。為此做好準備。

至於使用者空間,你可以選擇你需要的任何東西,在你需要的東西和剩餘空間之間平衡你的需求。通常在嵌入式中,您要麼壓縮任何東西,要麼剝離不需要的東西,或兩者兼而有之。

我希望這會有所啟發。如果您還有其他問題 - 歡迎評論!:-)

引用自:https://unix.stackexchange.com/questions/242371