2010/07/19

PS3 linux (Fedra Core 9)にMARSライブラリを導入してみる

いまさらですが、 フィックスターズのWebサイトをみていてMARSライブラリを導入してみました。 fixstarsのサイトでは1.1.4までの情報が載っていますが、現時点での最新版は1.1.5のようです。

コンパイル済みのバイナリパッケージも配布されていましたが、自分の環境にフィットするか自信がなかったのでパッケージを作成することにしました。

今回の作業はFedra Core 9にCellSDK 3.1の環境で行なっています。

~/.rpmmacrosの準備とパッケージの作成

一般ユーザのHOMEディレクトリ以下で作業をするために~/.rpmmacrosファイルを準備します。 これがないと/usr/src/redhatにファイルが作成されるためrootユーザで作業をしなければいけませんが、そうする利点はないので、一般ユーザで作業を進めます。

$ echo %_topdir $HOME/rpm > ~/.rpmmacros

.rpmmacros ファイルで指定するディレクトリ名には ~/ などは使えないので、 ユーザ毎にフィアルを配布せずにskeltonファイルを準備したい場合には次のようにするのが良さそうです。

ディレクトリ名を決め打ちしない~/.rpmmacrosファイル

%_topdir %(echo $HOME)/rpm

.rpmmacrosファイルの準備ができたらパッケージを作成します。

$ sudo yum update
$ wget http://ftp.uk.linux.org/pub/linux/Sony-PS3/mars/latest/mars-1.1.5-1.src.rpm

ビルドに必要なディレクトリはあらかじめ作っておく必要があります。 簡単なのは決め打ちでディレクトリを作成しておく方法でしょう。

$ mkdir -p ~/rpm/{BUILD,RPMS/ppc64,SOURCES,SPECS}
$ rpm -ivh mars-1.1.5-1.src.rpm

これで~/rpm/SPECS/以下にmars.specファイルが作成されたので、rpmbuildコマンドでパッケージを作成します。


specファイルを編集する必要がなければ、"rpm -ivh"と"rpmbuild -bb"を合わせて次のコマンドでもパッケージを作成することができます。

$ rpmbuild --rebuild mars-1.1.5-1.src.rpm

いずれの方法でもrpmbuildを実行してエラーになります。

依存関係にある未インストールのパッケージを示すエラーメッセージ

error: Failed build dependencies:
	numactl-devel is needed by mars-1.1.5-1.ppc64

numactlパッケージもwww.bsc.esで配布されています。 apt-getでは入れられないので、やはりパッケージを作成しました。

$ wget http://www.bsc.es/projects/deepcomputing/linuxoncell/cellsimulator/sdk3.0/SRPMS/numactl-0.9.10-1.src.rpm
$ rpm -ivh numactl-0.9.10-1.src.rpm
$ cd ~/rpm/SPECS
$ rpmbuild -bb numactl.spec
$ sudo rpm -ivh ~/rpm/RPMS/ppc64/numactl-devel-0.9.10-1.ppc64.rpm
$ rpmbuild -bb mars.spec
$ sudo rpm -ivh ~/rpm/RPMS/ppc64/mars-*.rpm

ここまでで、一応パッケージは出きたのですが、spu版のzlib, opnessh-engineを試す際に32bit版ライブラリがないために問題がでました。

32bit版marsライブラリの作成

rpmbuildコマンドに --target ppc を渡すことで32bit版のパッケージを作成することができます。

$ mkdir ~/rpm/RPMS/ppc
$ cd ~/rpm/SPECS
$ rpmbuild -bb --target ppc numactl.spec
$ sudo rpm -ivh ../RPMS/ppc/numactl-devel-0.9.10-1.ppc.rpm
$ rpmbuild -bb --target ppc mars.spec
$ sudo rpm -ivh ../RPMS/ppc/mars-1.1.5-1.ppc.rpm

とりあえずこれでzlibやopenssh-enginesのコードをコンパイルする準備が出きました。

zlibからのmgzipの作成

srcパッケージを配布しているディレクトリにgzipの圧縮をspu対応にさせたサンプルが置かれています。

ただ対応しているバージョンのzlib-1.2.3は不具合がみつかり、zlib-1.2.5に置き換えられていて、現在はダウンロードができずにサンプルをコンパイルする事ができませんでした。

とりあえずMakefileを編集して、1.2.5をダウンロードするように修正しました。

zlib-mars/Makefileの編集個所

--- Makefile.orig	2010-07-18 09:44:32.482284357 +0900
+++ Makefile	2010-07-18 02:24:15.255286359 +0900
@@ -27,7 +27,7 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-ZLIB=zlib-1.2.3
+ZLIB=zlib-1.2.5
 MGZIP=smp_mgzip_1.2c
 HOST_FLAG=-m32
 LIBS=-lspe2 -lmars_task -lmars_base

zlib-1.2.5_mars.patchファイルが作成できていないので、makeはエラーで停止します。 そこから手動で修正作業をして、最終的にzlib-1.2.5_mars.patchファイルを作成します。

$ cd zlib-1.2.5
$ patch -p1 < ../zlib-1.2.3_mars.patch

手動でzlib-1.2.5に対してzlib-1.2.3_mars.patchを当てた後は、*.rejファイルをみながら手で編集していきました。

zlib-1.2.3_mars.patch適用後の

diff -upNr zlib-1.2.5/zconf.h zlib-1.2.5.ported/zconf.h
--- zlib-1.2.5/zconf.h  2010-07-18 09:35:03.643539354 +0900
+++ zlib-1.2.5.ported/zconf.h   2010-07-18 09:18:52.314278202 +0900
@@ -356,7 +356,7 @@ typedef uLong FAR uLongf;
    typedef Byte       *voidp;
 #endif
 
-#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#if 1    /* was set to #if 1 by ./configure */
 #  define Z_HAVE_UNISTD_H
 #endif
 
diff -upNr zlib-1.2.5/zlib.h zlib-1.2.5.ported/zlib.h
--- zlib-1.2.5/zlib.h   2010-07-18 09:35:03.651543213 +0900
+++ zlib-1.2.5.ported/zlib.h    2010-07-18 02:53:42.232281033 +0900
@@ -179,6 +179,7 @@ typedef gz_header FAR *gz_headerp;
 #define Z_MEM_ERROR    (-4)
 #define Z_BUF_ERROR    (-5)
 #define Z_VERSION_ERROR (-6)
+#define Z_CELL_ERROR   (-7)
 /* Return codes for the compression/decompression functions. Negative values
  * are errors, positive values are used for special but normal events.
  */

Makefile.inはMakefile.in.rejファイルを見ながら手で修正しましたが、1.2.5では共有ライブラリも作成できるように1.2.3と比較して変更点が多いため、./configure --staticは通りますが、共有ライブラリも作成できる完全なMakefile.inはできていません。

それでもzlib-1.2.5_mars.patchを作成してみると、mgzipコマンドを手に入れることができました。

$ mv zlib-1.2.5 zlib-1.2.5.ported
$ tar xvzf zlib-1.2.5.tar.gz
$ diff -upNr zlib-1.2.5 zlib-1.2.5.ported > zlib-1.2.5_mars.patch
$ make HOST_FLAG=-m32

timeコマンドの出力は変な感じでしたが、実時間だけでみてもmgzipは2〜3倍程度の速度差があるようです。 これが自分でできるかというと時間がかかり過ぎる感じですが、なんとなく雰囲気は感じられたと思います。

marsサンプルのコンパイル

mars-samplesパッケージを導入すると/usr/share/mars-1.1.5/samples以下にサンプルが導入できます。 このコンパイルには32bit版のライブラリは必要ありませんでした。

そのままrootユーザ権限でmakeしても良いのですが、パッケージとして管理されている領域とは別の場所で行なうのがベストだと思います。

$ cp -r /usr/share/mars-1.1.5/samples .
$ cd samples
$ make

ここにあるhelloディレクトリやscheduleディレクトリにあるサンプルを眺めると、なんとなく概要は掴めると思います。

サンプルのコードを読んで気になったところ

host.cでexternされている変数の定義場所

ディレクトリに配置されている*.cファイルには定義されていない変数(mpu_task_prog)が唐突にexternされているように見えます。

MARSのドキュメントには何も書かれていませんが、makeの出力を確認するとppu-embedspuコマンドの引数にmpu_task_progが表われています。

このコマンドを引数なしに起動すると次のようなメッセージが表示され、symbol名が指定できることがわかりました。

Usage: embedspu [flags] symbol_name input_filename output_filename

        input_filename:  SPU ELF executable to be embedded
        output_filename: Resulting PowerPC object file
        symbol_name:     Name of program handle struct to be defined
        flags:           GCC flags defining PowerPC object file format
                         (e.g. -m32 or -m64)

元々SPEプログラムを組込むための仕組みとして準備されているもののようで、作成されたファイルに定義されているsymbol名をnmコマンドで表示させると変化の様子がわかります。

$ nm mpu_task2.task_o
         U mars_task_get_kernel_id
         U mars_task_get_name
00000000 T mars_task_main
         U printf
$ nm mpu_task2.task_eo 
0000000000000000 D mpu_task2_prog

自分で少し試すだけならMakefileを流用して、同じようなネーミングルールでコードを作成するのが楽そうです。

0 件のコメント: