ターゲット
今回の移植ターゲットはSH2007(http://sh2000.sh-linux.org)。SH-4A(http://japan.renesas.com)のインストラクションセットを持つ。まずはシングルプロセッサのSH2007がターゲットである。SH2007はSH7780を搭載する。
OKL4ソースツリー
OKL4 3.0をhttp://wiki.ok-labs.com/Release/3.0からダウンロードする。
クロスコンパイラ
CrossToolsを利用する。http://www.kegel.com/crosstool/からダウンロードする。現時点でバージョンは0.43。クロスコンパイラのビルドは基本的に説明通り。gccのバージョンは3.4.5とした。Ubuntuの場合、これ以外にビルトに使うコンパイラを4.2とする必要があるかもしれない。
demo-sh4.shの変更点
gcc 4.2を指定することと、3.4.5をビルドするよう指定すること。
export CC=gcc-4.2 eval `cat sh4.dat gcc-3.4.5-glibc-2.3.5.dat` sh all.sh --notest
ディレクトリの追加
アーキテクチャ依存コードを格納するディレクトリを追加する。現段階ではマイクロカーネルと周辺ライブラリのみの移植を目指す。追加したディレクトリは以下のようになる。
arch/sh/ktest arch/sh/libs/atomic_ops/include arch/sh/libs/atomic_ops/src arch/sh/libs/c/crt arch/sh/libs/c/include arch/sh/libs/c/src arch/sh/libs/compat/include arch/sh/libs/kernel/include arch/sh/libs/l4/cpu/sh7780 arch/sh/libs/l4/include arch/sh/libs/l4/src arch/sh/libs/okl4/include arch/sh/libs/soc/include arch/sh/pistachio/cpu/sh7780/include arch/sh/pistachio/include arch/sh/pistachio/kdb arch/sh/pistachio/src/gnu arch/sh/tools platform/sh2007/pistachio/include platform/sh2007/pistachio/kdb platform/sh2007/pistachio/src platform/sh2007/tools
ビルドスクリプトの変更
OKL4のビルドは以下のようなコマンドで実行する。
./tools/build.py PYFREEZE=false MACHINE=pxa PROJECT=iguana
これを以下のようにしたい。
./tools/build.py PYFREEZE=false MACHINE=sh2007 PROJECT=ktest
まずは、SHクロスコンパイラを起動するようにビルドスクリプトを変更する。編集するのはtools/toolchains.py。クラスsh_toolchainを定義し、登録する。
class sh_toolchain(generic_gcc):
def __init__(self, *args):
generic_gcc.__init__(self, *args)
# gccのフラグに追加
self.dict["CCFLAGS"] += ["-m4-nofpu"]
# g++のフラグに追加
self.dict["CXXFLAGS"] += ["-m4-nofpu"]
gnu_sh_toolchain = sh_toolchain("sh-linux-")
アーキテクチャ毎の設定
アーキテクチャ毎の設定はarch/sh/tools/machines.pyに書く。各アーキテクチャはクラスとして表現される。ここでクロスコンパイラを指定する。
from machines import Machine, Region
from toolchains import gnu_sh_toolchain
class sh(Machine):
# サポートしているページサイズ(1KiB, 4Kib, 64KiB, 1MiB)
page_sizes = [0x400, 0x1000, 0x10000, 0x100000]
# プログラムをアラインするときの標準のサイズ
preferred_alignment = 0x10000L
# 標準のワードサイズ
wordsize = 32
# アーキテクチャの名前
#(アーキテクチャ依存コードを格納するディレクトリの名前)
arch = "sh"
# エンディアン
endian = "little"
# エミュレータを指定する。SHのエミュレータがないのでここは空。
default_method = ''
# 標準のクロスコンパイラ
default_toolchain = gnu_sh_toolchain
# SH-4 (SH7750 series)
class sh4(sh):
# 有効なアドレス範囲のリスト。tools/machines.pyで定義されている。
memory = sh.memory.copy()
# 有効な仮想アドレスの範囲を定義
memory['virtual'] = [Region(0x1000, 0x7ef00000)]
# アーキテクチャのバージョン(SH4なので4とした)
arch_version = 4
# SH-4A (SH7780 series)
class sh4a(sh):
memory = sh.memory.copy();
memory['virtual'] = [Region(0x1000, 0x7ef00000)]
# アーキテクチャのバージョン
#(アルファベットを指定できないので4とした)
arch_version = 4
class sh7780(sh4a):
# CPU依存コードを格納するディレクトリの名前
cpu = "sh7780"
class sh7785(sh4a):
cpu = "sh7785"
プラットフォーム毎の設定
プラットフォーム毎の設定はplatform/tools/machines.pyに記述する。各プラットフォームはクラスとして表現される。
import copy
class sh2007(sh7780):
virtual = False
# ビルドスクリプトを起動するときにMACHINEで指定する文字列
platform = "sh2007"
# プラットフォーム依存コードを格納するディレクトリ
platform_dir = "sh2007"
# タイマードライバーの名前
timer_driver = ""
# シリアルポートドライバーの名前
serial_driver = ""
# ビルドするドライバーのリスト
drivers [timer_driver, serial_driver] + sh7780.drivers
memory = sh7780.memory.copy()
# RAMがマッピングされる仮想アドレス
memory['physical'] = [Region(0x88000000, 0x90000000)]
# ROMがマッピングされる仮想アドレス
memory['rom'] = [Region(0xA0000000, 0xA80000000)]
# プリプロセッサに与える文字列。ソースコード内で
# プラットフォーム依存部を切り替えるのに使うことが出来る。
cpp_defines = sh7780.cpp_defines = [("PLATFORM_SH2007", 1)]
pyelf
pyelfはELFファイルを編集するプログラムである。ELFとは実行可能ファイルの形式の一種である。ELFファイルには機種依存の部分がある。したがって、IA32アーキテクチャ、ARMアーキテクチャ、SHアーキテクチャのELFファイルはそれぞれ微妙に異なる。pyelfはELFファイルを編集するのでこの微妙な違いを理解しなければならない。機種依存のコードは、tools/pyelf/elf/abiに格納する。SHのコードは他のファイルに倣ってsh.pyとする。
ELFファイルの機種依存部の形式はgccでも定義されているので、gccのソースコードから必要な部分だけをコピーしてくる。