將 Linux 移植到另一個平台要求
我知道 Linux 是可用的,並且已經移植到許多不同的平台上,例如 X86、ARM、PowerPC 等。
但是,在移植方面,究竟需要什麼?
我的理解是 Linux 是用 C 語言編寫的軟體。因此,當將 Linux 最初從 X86 移植到 ARM 或其他時,不只是用編譯器針對特定目標架構重新編譯程式碼的問題嗎?
拋開不同外圍設備的設備驅動程序,將 Linux 移植到新架構時還需要做些什麼。編譯器不會為我們處理好所有事情嗎?
儘管 Linux 核心中的大部分程式碼都是用 C 編寫的,但該程式碼的許多部分仍然非常特定於執行它的平台,並且需要考慮到這一點。
一個特別的例子是虛擬記憶體,它在大多數架構(頁表的層次結構)上以類似的方式工作,但對於每個架構都有特定的細節(例如每個架構中的級別數,甚至在 x86 上也一直在增加)引入新的更大的晶片。)Linux核心程式碼引入了宏來處理遍歷這些層次結構,編譯器可以在頁表級別較少的體系結構上省略這些宏(因此程式碼是用C編寫的,但會將體系結構的細節帶入考慮。)
許多其他領域都非常特定於每個架構,需要使用特定於架構的程式碼來處理。但是,其中大多數都涉及彙編語言中的程式碼。例子是:
- 上下文切換:上下文切換涉及為被切換出的程序保存所有寄存器的值,並從已保存的調度到 CPU 的程序集中恢復寄存器。甚至寄存器的數量和集合對於每個架構都是非常具體的。該程式碼通常在彙編中實現,以允許對寄存器的完全訪問並確保它盡可能快地執行,因為上下文切換的性能對系統至關重要。
- 系統呼叫:使用者空間程式碼觸發系統呼叫的機制通常特定於體系結構(有時甚至特定於特定的 CPU 型號,例如 Intel 和 AMD 為此引入了不同的指令,較舊的 CPU 可能缺少這些指令,所以詳情因為那些仍然是獨一無二的。)
- 中斷處理程序:如何處理中斷(硬體中斷)的詳細資訊通常是特定於平台的,並且通常需要一些彙編級膠水來處理平台使用的特定呼叫約定。此外,啟用/禁用中斷的原語通常是特定於平台的,並且也需要彙編程式碼。
- 初始化:初始化應該如何發生的細節通常還包括特定於平台的細節,並且通常需要一些彙編程式碼來處理核心的入口點。在具有多個 CPU (SMP) 的平台上,有關如何使其他 CPU 聯機的詳細資訊通常也因平台而異。
- 鎖定原語:鎖定原語(例如自旋鎖)的實現通常也涉及特定於平台的細節,因為一些架構提供(或更喜歡)不同的 CPU 指令來有效地實現這些。有些將實現原子操作,有些將提供一個 cmpxchg 可以自動測試/更新(但如果另一個編寫器先進入則失敗),其他將包含 CPU 指令的“鎖定”修飾符。這些通常還涉及編寫彙編程式碼。
在核心中(或者,特別是在 Linux 核心中),可能還有其他領域需要特定於平台或體系結構的程式碼。查看核心原始碼樹,您可以
arch/
在include/arch/
其中找到更多特定於體系結構的子樹。這方面的例子。有些實際上令人驚訝,例如,您會看到每個架構上可用的系統呼叫的數量是不同的,並且某些系統呼叫將存在於某些架構中而不是其他架構中。(即使在 x86 上,系統呼叫列表在 32 位和 64 位核心之間也是不同的。)
簡而言之,核心需要注意很多特定於平台的情況。Linux 核心試圖將其中的大部分抽像出來,因此更高級的算法(例如記憶體管理和調度的工作方式)可以在 C 中實現,並且在所有架構上都可以相同(或幾乎相同)工作。