向 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 執行它(提示您自建立以來是否有任何新選項),並開始您為新開發板提供功能核心的過程。