向 LinuxSH 新增新開發板¶
Paul Mundt <lethal@linux-sh.org>
本文件嘗試概述將新開發板支援新增到 2.5 和 2.6 核心下的 LinuxSH 埠所需的步驟。本文件還嘗試概述 2.4 和 2.5/2.6 SH 後端之間的一些顯著變化。
1. 新的目錄結構¶
首先要注意的是新的目錄結構。在 2.4 版本下,大多數特定於開發板的程式碼(stboards 除外)最終都直接位於 arch/sh/kernel/ 中,而特定於開發板的標頭檔案最終位於 include/asm-sh/ 中。對於新核心,這些內容按開發板型別、配套晶片型別和 CPU 型別進行分解。此目錄層次結構的樹形檢視如下所示
特定於開發板的程式碼
.
|-- arch
| `-- sh
| `-- boards
| |-- adx
| | `-- board-specific files
| |-- bigsur
| | `-- board-specific files
| |
| ... more boards here ...
|
`-- include
`-- asm-sh
|-- adx
| `-- board-specific headers
|-- bigsur
| `-- board-specific headers
|
.. more boards here ...
接下來是配套晶片
.
`-- arch
`-- sh
`-- cchips
`-- hd6446x
`-- hd64461
`-- cchip-specific files
... 等等。配套晶片的標頭檔案以與特定於開發板的標頭檔案相同的方式處理。因此,include/asm-sh/hd64461 是所有 hd64461 特定標頭檔案的所在地。
最後,CPU 系列支援也被抽象出來
.
|-- arch
| `-- sh
| |-- kernel
| | `-- cpu
| | |-- sh2
| | | `-- SH-2 generic files
| | |-- sh3
| | | `-- SH-3 generic files
| | `-- sh4
| | `-- SH-4 generic files
| `-- mm
| `-- This is also broken out per CPU family, so each family can
| have their own set of cache/tlb functions.
|
`-- include
`-- asm-sh
|-- cpu-sh2
| `-- SH-2 specific headers
|-- cpu-sh3
| `-- SH-3 specific headers
`-- cpu-sh4
`-- SH-4 specific headers
應該注意的是,CPU 子型別_沒有_被抽象出來。因此,這些仍然需要由 CPU 系列特定程式碼來處理。
2. 新增新開發板¶
首先要確定的是,您要新增的開發板是獨立的,還是屬於一個開發板系列,該系列可以主要共享相同的特定於開發板的程式碼,只有細微的差異。
在第一種情況下,只需在 arch/sh/boards/ 中為您的開發板建立一個目錄,並新增規則以將您的開發板與構建系統掛鉤(更多內容將在下一節中介紹)。但是,對於開發板系列,最好有一個通用的頂層 arch/sh/boards/ 目錄,然後使用每個系列成員的子目錄填充該目錄。Solution Engine 和 hp6xx 開發板就是這方面的一個例子。
在設定好新的 arch/sh/boards/ 目錄後,請記住,您還應該在 include/asm-sh 中為本地化到此開發板的標頭檔案新增一個目錄(如果將有多個)。為了與構建系統無縫互操作,最好使此目錄與 arch/sh/boards/ 目錄名稱相同,但如果您的開發板再次屬於一個系列,則構建系統有處理此問題的方法(透過 incdir-y 過載),您可以隨意以系列成員本身命名該目錄。
每個開發板都需要在 arch/sh/boards 和 include/asm-sh/ 層次結構中都有一些東西。為了更好地解釋這一點,我們使用一些新增虛構開發板的例子。對於設定程式碼,我們至少需要提供 get_system_type() 和 platform_setup() 的定義。對於我們的虛構開發板,這可能如下所示
/*
* arch/sh/boards/vapor/setup.c - Setup code for imaginary board
*/
#include <linux/init.h>
const char *get_system_type(void)
{
return "FooTech Vaporboard";
}
int __init platform_setup(void)
{
/*
* If our hardware actually existed, we would do real
* setup here. Though it's also sane to leave this empty
* if there's no real init work that has to be done for
* this board.
*/
/* Start-up imaginary PCI ... */
/* And whatever else ... */
return 0;
}
我們的新虛構開發板還必須與 machvec 繫結才能發揮任何作用。
machvec 函式分為多個類別
到 IO 記憶體(inb 等)和 PCI/主記憶體(readb 等)的 I/O 函式。
I/O 對映函式(ioport_map、ioport_unmap 等)。
一個“心跳”函式。
PCI 和 IRQ 初始化例程。
一致的分配器(對於需要特殊分配器的開發板,特別是用於從一些特定於開發板的 SRAM 中分配 DMA 控制代碼的開發板)。
隨著時間的推移,machvec 函式會不斷新增和刪除,因此請務必查閱 include/asm-sh/machvec.h 以瞭解 machvec 的當前狀態。
核心會在啟動時自動包裝 machvec 中未定義函式指標的通用例程,因為 machvec 函式在整個樹中被無條件引用。一些開發板的 machvec 非常稀疏(例如 dreamcast 和 sh03),而另一些開發板則必須定義幾乎所有內容 (rts7751r2d)。
新增新機器相對簡單(以 vapor 為例)
如果特定於開發板的定義非常簡單,就像大多數開發板的情況一樣,只需一個特定於開發板的標頭檔案就足夠了。
新增一個新檔案 include/asm-sh/vapor.h,其中包含任何機器特定 IO 函式的原型,這些函式以機器名稱為字首,例如 vapor_inb。在填充機器向量時,將需要這些原型。
請注意,這些原型是透過將 __IO_PREFIX 設定為有意義的值自動生成的。一個典型的例子是
#define __IO_PREFIX vapor #include <asm/io_generic.h>在特定於開發板的標頭檔案中。任何仍在移植的具有舊 io.h 的開發板都應完全刪除它並切換到新模型。
將機器向量定義新增到開發板的 setup.c 中。至少,必須將其定義為類似
struct sh_machine_vector mv_vapor __initmv = { .mv_name = "vapor", }; ALIAS_MV(vapor)最後,新增一個檔案 arch/sh/boards/vapor/io.c,其中包含機器特定 io 函式的定義(如果足夠多)。
3. 掛鉤到構建系統¶
現在我們已經設定了相應的目錄,並且所有特定於開發板的程式碼都已就位,是時候研究如何將整個混亂的東西放入構建系統了。
現在,構建系統的很大一部分是完全動態的,只需要在這裡和那裡進行適當的條目才能完成任務。
首先要做的是在 arch/sh/Kconfig 中的“System type”選單下新增一個條目
config SH_VAPOR
bool "Vapor"
help
select Vapor if configuring for a FooTech Vaporboard.
接下來,必須將其新增到 arch/sh/Makefile 中。所有開發板都需要一個 machdir-y 條目才能構建。此條目需要是開發板目錄的名稱,因為它出現在 arch/sh/boards 中,即使它位於子目錄中(在這種情況下,需要列出 arch/sh/boards/ 下的所有父目錄)。對於我們的新開發板,此條目可以如下所示
machdir-$(CONFIG_SH_VAPOR) += vapor
前提是我們已將所有內容都放在 arch/sh/boards/vapor/ 目錄中。
接下來,構建系統假定您的 include/asm-sh 目錄也將被命名為相同。如果情況並非如此(就像屬於一個通用系列的多個開發板一樣),則需要將目錄名稱隱式附加到 incdir-y。現有程式碼管理 Solution Engine 和 hp6xx 開發板的此操作,因此請參閱這些示例。
一旦解決了這個問題,就該新增機器型別的條目了。這是透過將條目新增到 arch/sh/tools/mach-types 列表的末尾來完成的。這樣做的自解釋方法,因此我們不會浪費空間在這裡重述它。完成此操作後,如果您需要在通用程式碼中的某個地方使用它,您將能夠對您的開發板使用隱式檢查,例如
/* Make sure we're on the FooTech Vaporboard */
if (!mach_is_vapor())
return -ENODEV;
另請注意,無論 mach-types 條目都是大寫的,mach_is_boardname() 檢查都將被隱式強制為小寫。如果您真的關心,您可以閱讀指令碼,但它非常難看,所以您可能不想這樣做。
現在剩下要做的就是為您的新開發板提供一個 defconfig。這樣,最終獲得此開發板的其他人才可以直接使用此配置進行參考,而不是嘗試猜測應該在其上使用什麼設定。
此外,一旦您複製了新開發板的示例 .config(假設 arch/sh/configs/vapor_defconfig),您也可以直接將其用作構建目標,並且它將隱式地在幫助文字中列出。
檢視“make help”輸出,您現在應該看到類似
特定於架構的目標 (sh)
zImage
壓縮的核心映像 (arch/sh/boot/zImage)
adx_defconfig
為 adx 構建
cqreek_defconfig
為 cqreek 構建
dreamcast_defconfig
為 dreamcast 構建
...
vapor_defconfig
為 vapor 構建
這允許您執行
$ make ARCH=sh CROSS_COMPILE=sh4-linux- vapor_defconfig vmlinux
這將依次複製此開發板的 defconfig,透過 oldconfig 執行它(提示您自建立以來是否有任何新選項),並開始您為新開發板提供功能核心的過程。