« 2015年4月 | トップページ | 2016年2月 »

2015/05/29

T2SPのT-Kernelソースコードのビルド(修正の詳細)

 前回の記事で予告した「修正の詳細」です。

■ライブラリのビルドで発生した問題
----
【問題】
make: /usr/local/te/etc/platform: Command not found
../../../etc/makerules:134: /usr/local/te/etc/sysdepend/tef_em1d/makerules.sysdepend: No such file or directory
make: *** No rule to make target '/usr/local/te/etc/sysdepend/tef_em1d/makerules.sysdepend'. Stop.
【対応】
 環境変数BDが設定されていなかったので、デフォルト値が使用されてエラーとなっていた。
 make実行前に、BDにソースコードのルートを設定するために、
export BD=/c/work/T-Kernel2.0/srcpkg/tkernel_source/
を実行で解決。
----
【問題】
/etc/sysdepend/tef_em1d/makerules.sysdepend:32: *** 'GNU_BD' is not defined. Stop.
【対応】
 環境変数GNU_BDが設定されていなかったのでエラーとなっていた。
 make実行前に、gccクロスコンパイラのインストールフォルダ(targetフォルダ)を設定するために、
export GNU_BD=/c/gnutools
を実行で解決。
----
【問題】
/etc/sysdepend/tef_em1d/makerules.sysdepend:36: *** 'GNUARM_2' is not defined. Stop.
【対応】
 環境変数GNUARM_2が設定されていなかったのでエラーとなっていた。
 make実行前に、gccクロスコンパイラのbinを格納しているフォルダを設定するために、
export GNUARM_2=${GNU_BD}/arm-*-eabi
を実行で解決。
----
【問題】
/bin/sh: line 1: make: command not found
/bin/sh: line 2: make: command not found
【対応】
 MSYSの/binにパスが通っていなかったので、make(の実行ファイル)が見つからず、エラーとなっていた。
 "/etc/sysdepend/tef_em1d/makerules.sysdepend"の45行目に":/usr/bin"を追加(GNUARM_2の場合に、MSYSの/binにパスを通す)することで解決。
----
【問題】
make[1]: /c/gnutools/arm-*-eabi/bin/gcc4arm: Command not found
【対応】
 makefileで使用する"gcc4arm"が存在していなかったためエラーとなっていた。
 "te.Cygwin-i686.common.13.tar.gz"に格納されている"tool/etc/gcc4arm"を"/c/gnutools/arm-*-eabi/bin"にコピーして解決。
----
【問題】
gcc4arm: line 27: /c/gnutools/bin/arm_2-unknown-tkernel-gcc: No such file or directory
【対応】
 環境変数_GNU_CONFIGが設定されていなかったので、デフォルト値が使用されてエラーとなっていた。
 make実行前に、gccクロスコンパイラのプレフィックスを設定するために、
export _GNU_CONFIG=arm-*-eabi
を実行して解決。
("GNUARM_2"は"${GNU_BD}/${_GNU_CONFIG}"でよいことになった)
----
【問題】
"libconv-2.dllが見つからなかったため、このアプリケーションを開始できませんでした。アプリケーションをインストールし直すとこの問題は解決される場合があります。"
のメッセージが表示される。
【対応】
 MinGWの/binにパスが通っていなかったので、必要なDLLファイルが見つからずにエラーとなっていた。
 "/etc/sysdepend/tef_em1d/makerules.sysdepend"の45行目に":/c/MinGW/bin"を追加(MinGWの/binにパスを通す)することで解決。
----

■カーネルのビルドで発生した問題
----
【問題】
-o kernel-ram.sys
ld.exe: target elf32-larm-tkernel not found
【対応】
 自前で用意した環境のBFDライブラリには、"elf32-larm-tkernel"の定義が無いためエラーとなっていた。
 "/kernel/sysmain/build/tef_em1d/kernel-ram.lnk"の19行目を、

"elf32-larm-tkernel"→"elf32-littlearm"
"elf32-barm-tkernel"→"elf32-bigarm"

に変更することで対応。
 以下のファイルでも同様の対応が必要。
"/kernel/sysmain/build/tef_em1d/kernel-rom.lnk"
"/config/build/tef_em1d/rominfo.lnk"
"/monitor/tmmain/build/tef_em1d/monitor.lnk"
"/config/launch-ramkernel/build/tef_em1d/rominfo.lnk"
----
【問題】
make: /c/gnutools/bin/arm_2-unknown-tkernel-objcopy: Command not found
【対応】
 makefileで使用されている"objcopy"のプレフィックスが固定になっていたため、実行ファイルが見つからずにエラーとなっていた。
 正しいプレフィクスを指定するために、"/etc/sysdepend/tef_em1d/makerules.sysdepend"の245行目の、
OBJCOPY = $(GNU_BD)/bin/arm_2-unknown-tkernel-objcopy

OBJCOPY = $(GNU_BD)/bin/arm-*-eabi-objcopy
に変更して解決(その上のCPPも同様の修正が必要)。
----
【問題】
/ld.exe: section .ARM.exidx loaded at [700481a0,700481a7] overlaps section .data loaded at [700481a0,700481cf]
【対応】
 2つ上の.lnkファイルの修正により、セクション.ARM.exidxが必要となっていたが、.lnkファイルに記載が無いため、セクション.dataと衝突していたためエラーとなっていた。
 セクション.ARM.exidxを明示的に指定するため、"/kernel/sysmain/build/tef_em1d/kernel-rom.lnk"のセクション".text"の直後(38行目)に、
__ARM_exidx = .;
.ARM.exidx : { *(.ARM.exidx*) }
を追加して対応。
----

| | コメント (0) | トラックバック (0)

2015/05/27

T2SPのT-Kernelソースコードのビルド

 先日用意したgccクロスコンパイラを利用して、トロンフォーラムが用意しているARM用のT-Kernelソースコードをビルドした際の覚書です。

 トロンフォーラムのソースコードダウンロードのサイトでは、T-Kernelの学習用に「T-Kernel 2.0 Software Package(以下、T2SP)」が用意されています。
 これには、QEMUというPCエミュレータが付属しているので、開発ボードがなくても作成したソフトウェアの動作確認ができます。
 T2SPには、Cygwin用クロスコンパイラ+eclipseの開発環境も含まれていますが、目的が異なるので今回は使用しません。
 ちなみに、T2SPの開発環境とQEMUの使用方法については、CQ出版社の雑誌インターフェース2012年5月号の特集記事が参考になります(T2SPに含まれるドキュメントを簡潔に記載している感じです)。

 開発環境は、先日用意したgccクロスコンパイラeclipseを予定したので、まずは最新のeclipse(バージョンはLuna SR2 (4.4.2) 、パッケージはEclipse IDE for C/C++ Developers)をダウンロードしてcドライブに展開しました。

 ダウンロードしたT2SPは、"C:\work"に展開しました。ソースコードは、"/c/work/T-Kernel2.0/srcpkg"にある"tkernel_source.tar.gz"なので、MSYSで"tar xvf tkernel_source.tar.gz"により、このフォルダにそのまま展開しました。

 eclipseのWorkspaceを"C:\work\T-Kernel2.0\srcpkg"に切り替え、File->New->Makefile Project with Existing Codeを選択して、「Existing Code Location」に"C:\work\T-Kernel2.0\srcpkg\tkernel_source"を指定し、プロジェクトとしました。

 開発環境としてはeclipseを使用することにしたのですが、ビルドはmakefileを利用するので、まずはMSYSでビルドしてみることにしました。
 参考としたのは、T2SPのドキュメント、
"T-Kernel2.0/srcpkg/doc/ja/tkernel.txt"
"T-Kernel2.0/srcpkg/doc/ja/tmonitor.txt"
です。
 その結果、以下の設定やファイルの修正が必要なことが分かりました。

----
1.ビルド前の環境変数の設定
export BD=/c/work/T-Kernel2.0/srcpkg/tkernel_source/
export GNU_BD=/c/gnutools → gccクロスコンパイラをインストールしたフォルダ
export _GNU_CONFIG=arm-*-eabi → gccクロスコンパイラのプレフィクス(環境に合わせて"*"は変更してください)
export GNUARM_2=${GNU_BD}/${_GNU_CONFIG}

2."etc/sysdepend/tef_em1d/makerules.sysdepend"の修正
・45行目に":/usr/bin:/c/MinGW/bin"を追加する(GNUARM_2の場合に、MSYSの/binとMinGWの/binにパスを通す)
・245行目の、
OBJCOPY = $(GNU_BD)/bin/arm_2-unknown-tkernel-objcopy

OBJCOPY = $(GNU_BD)/bin/arm-*-eabi-objcopy
に変更する(その上のCPPも同様の修正が必要)

3."gcc4arm"のコピー
・"te.Cygwin-i686.common.13.tar.gz"に格納されている"tool/etc/gcc4arm"を"/c/gnutools/arm-*-eabi/bin"にコピーする

4.".lnk"のOUTPUT_FORMATの引数変更
・ファイル、
"/kernel/sysmain/build/tef_em1d/kernel-ram.lnk"
"/kernel/sysmain/build/tef_em1d/kernel-rom.lnk"
"/config/build/tef_em1d/rominfo.lnk"
"/config/launch-ramkernel/build/tef_em1d/rominfo.lnk"
"/monitor/tmmain/build/tef_em1d/monitor.lnk"
について、
"elf32-larm-tkernel"→"elf32-littlearm"
"elf32-barm-tkernel"→"elf32-bigarm"
を変更する

5."/kernel/sysmain/build/tef_em1d/kernel-rom.lnk"に".ARM.exidx"の追加
・セクション".text"の直後(38行目)に、
__ARM_exidx = .;
.ARM.exidx : { *(.ARM.exidx*) }
を追加する。

6.perlのフォルダ指定を変更
・"/etc/mergesrec"の1行目を、
/usr/local/bin/perl → /usr/bin/perl
に変更する(他の同様のファイルも修正しておいたほうが良い)
----

 以上でELFファイルは作成されました。
 修正がなぜ必要だったかは、次の記事で記載する予定です。
 eclipseで必要な設定は、さらにその次の記事の予定です。
 また、ここまでで作成したELFではバグがあるので、その修正については…そのうち記載します。

 なお、T2SPに付属されている開発環境を使用すれば、このような苦労はないものと思われます。

| | コメント (0) | トラックバック (0)

2015/05/03

ARM用のgccクロスコンパイラ他の作成について

 必要があって、Windows上でARM用のgccクロスコンパイラ(+GDB)を作成しました。
 これについては、ネット上に数多くの情報があるのですが、時代と共に陳腐化しているものも混ざっており、そのためにハマったこともあるので、覚書としてまとめておきます(当然、この情報もいずれ陳腐化することでしょう)。
 なお、作業にあたって、以下の資料を参考にしました。

Interface (インターフェース) 2015年 03月号
CとGNU開発ツールによる組み込みシステムプログラミング 第2版

 特に、インターフェースの特集記事は、環境は異なるものの勉強になりました。

 作成した環境は、WindowsXP+MinGWで、各ツールのバージョンは、
binutils 2.25
gcc 4.9.2
newlib 2.2.0-1
gdb 7.9
です。
 newlib以外は、GNUオペレーティングシステムのリンク先からダウンロードしました。

 MinGWは、バージョンによってインストーラーが異なるらしく、私が利用したインストーラー(現時点の最新)は「MinGW Installation Manager」を利用するものでした。
 MinGW Installation Managerで、以下をMark for Installationとしました。

[Basic Setup]
mingw-developer-toolkit
mingw32-base
mingw32-gcc-g++
msys-base

[All Packages]
mingw32-libexpat … gdbのビルドで必要
mingw32-gmp dev … gccのビルドで必要
mingw32-mpc dev … gccのビルドで必要
mingw32-mpfr dev … gccのビルドで必要

 マークした後に、[Installation]→[Apply Changes]の「Apply」ボタンでインストールし、インストール後に"C:/MinGW/msys/1.0/etc"にある"fstab.sample"をコピーして、(ActivePerlは使用しない予定なので)、
c:/ActiveState/perl /perl
をコメントアウトして、"fstab"としました。これにより、"/mingw"が"C:\MinGW"に置き換えられるようになるので、例えば"cd /mingw/bin"の実行などが有効となります。
 Msysは"C:/MinGW/msys/1.0/msys.bat"で起動しますが、起動後にタイトルバーを右クリックして、プロパティを表示して、オプションタブの編集オプションの「簡易編集モード」と「挿入モード」にチェックを入れると、右クリックで選択範囲をコピーしたり、選択していないときは右クリックでクリップボードの内容をペーストできるようになるので便利です。
 Msys上では、"C:/MinGW/msys/1.0"は"/usr"となります。
 また、ドライブの指定は、例えばCドライブなら"/c/"を使用します。例えば"C:/MinGW/msys/1.0"は"/c/MinGW/msys/1.0"となります。

 MinGWの他に、Pythonをインストールしました。これは、GDBビルド時に"libpython27.a"が必要となるので、Active Pythonではなく、python.orgのPython2.7.Xをインストールしました(最初にActive Pythonをインストールしたらビルドできなくて悩みました)。

 クロスコンパイラの作成は、

1.binutilsのビルド&インストール
2.newlibビルド用のgccのビルド&インストール
3.newlibのビルド&インストール
4.gccのビルド&インストール
5.gdbのビルド&インストール

の順で行ないました。
 以下に、Msys上で実行した各ツールのビルド&インストール時のコマンドを記載します。なお、作業は"/usr/tmp"で行なうことを前提としています。
 また、作成したツールのインストール先は、"c:\gnutools"としています。prefixを指定しないと基本的に"/usr/local/bin"にインストールされるようですが、prefixのオプションを指定した方がパスを気にする必要性が少し減るようです。

1.binutilsのビルド&インストール
tar xvf binutils-2.25.tar.bz2
cd binutils-2.25
mkdir build
cd build
../configure --target=arm-*-eabi --prefix=/c/gnutools --disable-nls --enable-gold
make
make install

[補足]
 "arm-*-eabi"の"*"には適当な文字列を入れてください。
 ターゲットには"arm-elf"を指定することが紹介されていることが多いのですが、今回使用したgccのバージョンでは"arm-elf"はサポートされていませんでした。
 サポートしているターゲットについては、gccのソースコード解凍後の"INSTALL/specific.html"に記載されています。
 この件以外にも、解凍後の"README"や"INSTALL"には、必要な情報が記載されていることが多いので、目を通したほうが無難です(例えば、gccのconfigureは他のフォルダから実行しなければいけない("./configure"で実行してはいけない)、とか)。

 "--enable-gold"はリンカにgoldを使用することを有効にするオプションですが、指定しているとビルド時間がかなり長くなるようです。

2.newlibビルド用のgccのビルド&インストール
cd /usr/tmp
tar xvf gcc-4.9.2.tar.bz2
cd gcc-4.9.2
mkdir build
cd build
../configure --target=arm-*-eabi --prefix=/c/gnutools --disable-nls --disable-libssp --disable-shared --enable-languages=c
make
make install

[補足]
 make実行時に、
C:¥MinGW¥msys¥1.0¥bin¥make.exe: *** couldn't commit memory for cygwin heap, Win32 error 487
と出力されますが無視してmakeを再実行すれば良いらしいです(こちらのブログを参考にしました)。

3.newlibのビルド&インストール
cd /usr/tmp
tar xvf newlib-2.2.0-1.tar.gz
cd newlib-2.2.0-1
mkdir build
cd build
export PATH=/c/gnutools/bin:$PATH
../configure --target=arm-*-eabi --prefix=/c/gnutools
mkdir build
cd build

4.gccのビルド&インストール
cd /usr/tmp/gcc-4.9.2/build
../configure --target=arm-*-eabi --prefix=/c/gnutools --disable-nls --disable-libssp --disable-shared --enable-languages=c,c++ --with-newlib
make
make install

5.gdbのビルド&インストール
cd /usr/tmp
tar xvf gdb-7.9.tar.xz
cd gdb-7.9
mkdir build
cd build
export PATH=/c/gnutools/bin:/c/Python27:$PATH
../configure --target=arm-*-eabi --prefix=/c/gnutools --disable-nls --enable-gld --enable-gold --enable-expat --with-expat=yes
make
make install

[補足]
 MinGWで"mingw32-libexpat"をインストールしていないと、

checking for libexpat... no
configure: error: expat is missing or unusable

というエラーが出力されます。

 また、使用したgdbのソースバージョンだとmake実行時に、
----
gcc -DHAVE_CONFIG_H -I. -I../../../../gdb/gnulib/import -I.. -g -O2 -D__USE_MINGW_ACCESS -MT rename.o -MD -MP -MF .deps/rename.Tpo -c -o rename.o ../../../../gdb/gnulib/import/rename.c
In file included from ./sys/stat.h:44:0,
from ../../../../gdb/gnulib/import/rename.c:34:
c:¥mingw¥include¥parts¥time.h:65:8: error: redefinition of 'struct rpl_timespec'

struct timespec
^
./time.h:386:8: note: originally defined here
struct timespec
^
make[8]: *** [rename.o] Error 1
----
と出力されました。この問題については、"/c/MinGW/include/parts/time.h"の51行目の、

#if defined __need_struct_timespec && ! __struct_timespec_defined

#if defined __need_struct_timespec && ! __struct_timespec_defined && ! GNULIB_defined_struct_timespec

に変更することで対応しました。
 これは、"struct timespec"が"gdb-7.9/build/gdb/build-gnulib/import/time.h"の386行目で定義されているので、再定義を防ぐためです。

| | コメント (0) | トラックバック (0)

« 2015年4月 | トップページ | 2016年2月 »