Hatena::ブログ(Diary)

七誌の開発日記(旧) このページをアンテナに追加 RSSフィード

新ブログ Twitter OneDrive Wiki

2011-12-30

[][][]第5回 PE勉強会 MIPS編 完了報告

報告が大変遅くなりましたが、id:n7shi:20111112で告知した第5回 PE勉強会 MIPS編が無事に完了しました。ご参加の皆様、お疲れ様でした。

機材(NT4やシグマリオン)の準備に手一杯で、資料の作成が間に合いませんでした。当日は悪天候で荷物運びも難航したため、主催者が遅刻するという失態を犯しました。ご参加の方には大変ご迷惑をお掛けしたことをお詫び申し上げます。

参加者からのトラックバックがあれば、ご紹介させていただきます。

2011-11-12

[][][]第5回 PE勉強会 MIPS

f:id:n7shi:20111113214454j:image:medium:rightf:id:n7shi:20110917081107j:image:medium:right

Windowsの実行ファイル (EXE/DLL) で使われているPE (Portable Executable) 形式についての勉強会です。バイナリいじりの基礎から始めて、EXEファイルやDLLファイルをコンパイラなしで作って動かすことを目標にします。PEをきっかけにして、各種マシンコードやOSのメモリ管理について理解を深めるのが狙いです。

参加者全員分のNT4と、MIPSを搭載したCEマシンを10台ほど用意する予定です。NT4のMIPS版はQEMUインストールできます。CEマシンは実機での動作を確認できます。PEの観点から、x86MIPSの違い、NTとCEの違いなどを比較します。

特にセッションはなく、みんなで開発や質問をする形式です。初めて参加される方や途中の回に参加できなかった方には、前回までの資料による対応も可能ですので、お気軽にご参加ください。

2011-05-13

[][][][][][]クロスコンパイラ

第7回 IT初心者勉強会 アセンブラ大会に参加しました。色々なCPUのアセンブリ言語を比較していて、とても楽しかったです。

そこで使われていたクロスコンパイラWindows用にビルドしたので配布します。MSYS用です。MSYSはgccを動かすのに特化しており、Cygwinより手軽です。インストール方法はこちらを参照してください。

ダウンロード

インストール

/usr/localに展開するだけで完了です。以下にPowerPCのインストール例を示します。他のアーキテクチャのインストール方法も同様です。

$ mkdir /usr/local
$ tar xvJf gcc-4.6.1-msys-cross-powerpc-elf.tar.xz -C /usr/local

※ 既に/usr/localが存在する場合、mkdirは不要です。

使い方

配布バイナリにはlibcが含まれていないため、実行ファイルを出力する際には -nostdlib オプションを付けてください。出力ファイルを指定しないと a.out というファイル名で出力されます。

以下にPowerPCでの使用例を示します。他のアーキテクチャも同様です。

$ powerpc-elf-gcc -nostdlib hello.c
$ file a.out
a.out: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), statically linked, not stripped

詳しい使い方は全資料に含まれるMakefileを参照してください。

ビルド手順

バイナリを使うだけなら必要ないのですが、参考までに配布物のビルド手順を書いておきます。

IT初心者勉強会環境構築方法とは若干異なります。

  • 勉強会のサンプルではlibcを使っていないため、newlibは省略しています。
  • gccのバージョンを4.6.1に上げました。
依存ライブラリ

まずgcc-4.6.1の依存ライブラリをビルドします。

  • gmp-5.0.2.tar.bz2
$ tar xvjf gmp-5.0.2.tar.bz2
$ cd gmp-5.0.2
$ ./configure
$ make
$ make install
  • mpfr-3.0.1.tar.xz
$ tar xvJf mpfr-3.0.1.tar.xz
$ cd mpfr-3.0.1
$ CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure
$ make
$ make install
  • mpc-0.9.tar.gz
$ tar xvzf mpc-0.9.tar.gz
$ cd mpc-0.9
$ CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure
$ make
$ make install
binutils/gcc

binutilsとgccは各アーキテクチャでソースを共用するため、ソースの外でビルドします。このようにすれば、ソースの展開は1回で済みます。

  • binutils-2.21.1.tar.bz2
  • gcc-core-4.6.1.tar.bz2
$ tar xvjf binutils-2.21.1.tar.bz2
$ tar xvjf gcc-core-4.6.1.tar.bz2

以下にPowerPC用クロスコンパイラのビルド手順を示します。

$ mkdir powerpc-elf
$ cd powerpc-elf
$ mkdir binutils
$ cd binutils
$ ../../binutils-2.21.1/configure --target=powerpc-elf
$ make
$ make install
$ cd ..
$ mkdir gcc
$ cd gcc
$ CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ../../gcc-4.6.1/configure --target=powerpc-elf
$ CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib make all-target-libgcc
$ make install-gcc
$ make install-target-libgcc

他のアーキテクチャはtargetを変えるだけで手順は同様です。ただしMSYSではMIPSのlibgccがメモリ不足でビルドできなかったため、配布バイナリにはNetBSDでビルドしたものを入れています。

アーカイブ

配布バイナリの作成では、make installを一時ディレクトリに対して行いアーカイブしています。

$ cd powerpc-elf/binutils
$ make prefix=/opt install
$ cd ../gcc
$ make prefix=/opt install-gcc
$ make prefix=/opt install-target-libgcc
$ cd /opt
$ find . -name "*.exe" | xargs strip
$ tar cvJf gcc-4.6.1-msys-cross-powerpc-elf.tar.xz *

このようにして作成したバイナリを配布しています。

2010-12-16

[][][][][]コンパイラ移植

Excelで動くコンパイラid:n7shi:20100519)をOpenOffice.org Calcに移植しました。マクロを使用しているため、セキュリティを中にしてご利用ください。

以下のアーキテクチャのバイナリを出力できます。

2010-06-21

[][]クロス開発

f:id:n7shi:20100621195932p:image:medium:right

ホスト側でExcel版コンパイラ(id:n7shi:20100519)を動かして、NT4/MIPSゲスト側(id:n7shi:20100609)から共有フォルダ経由でEXEを実行してみました。クロス開発です。

NT4/MIPSで動くExcelを持っていないので、このような形になりました。

2010-06-09

[]QEMUでNT4/MIPS

【追記】以前は2種類のQEMUを使い分ける複雑な手順を掲載していましたが、パッチによって0.13.0だけですべての作業が行えるようになったため、説明を修正しました。

Windows上のQEMUに、MIPS用のWindows NT 4.0 Workstationをインストールして動かしてみました。色々とハマりどころがあるので、手順をまとめておきます。

以下を参考にしました。

  1. MIPS!, Got it working!
  2. Installing Windows NT 4.0 on Qemu(MIPS)

準備

上記の参考1から setup.zip をダウンロードします。

以下からMIPS用の qemu-0.13.0 をダウンロードして展開します。NT4/MIPSが動くようにRTCやFDCにパッチを当てています。パッチやビルドの詳細については後でまとめます。

setup.zipから NTPROM.RAW を取り出して、名前を mipsel_bios.bin に変更して、qemuを展開したフォルダに入れます。

ディスクイメージの作成

Windows 7以降ではVHDがマウントできるため、ディスクイメージとして容量固定のVHDをお勧めします。VHDはVirtual PCやWindows 7の管理ツールで作成できます。

Windows 7でのVHD作成方法
  1. スタート→コンピュータを右クリック→管理
  2. 「コンピュータの管理」が表示されるので、左のツリーから「ディスクの管理」を選択
  3. 中央上欄のパーティション一覧を適当にクリック
    ※一度フォーカスを移さないとメニューが選択できないため
  4. 操作→VHDの作成
  5. 容量固定で512MB〜1GB程度のサイズで作成
  6. ディスク一覧に出てくるので右クリック→VHDの切断
    ※アタッチされたままだとアプリから操作できないため
QEMU付属ツールでの作成方法

Windows 7以外での方法として、QEMU付属ツールで1GB固定サイズのイメージを作成する方法を示します。

qemu-img create hda.img 1G

QEMUからの脱出方法

QEMUの画面をクリックするとマウスポインタが吸い込まれます。QEMUのウィンドウキャプションにも書いてありますが、[Alt]+[Ctrl]で抜けることができます。キーボードだけの操作ならマウスポインタを吸い込ませなくても可能です。

ファームウェアの初期設定

以下の引数でqemuを起動します。ディスクイメージやISOのファイル名は適宜修正してください。なお、上で配布している qemu-0.13.0 のアーカイブには、このコマンドを起動するためのバッチファイル(run-nt4mips.bat)が同梱されています。

qemu-system-mips64el -M magnum -localtime -L . -net nic -net user -hda hda.vhd -cdrom NTWKS40J1.ISO

f:id:n7shi:20100609190326p:image:medium

NVRAMの警告が出ますが、何かキーを押して先に進みます。

f:id:n7shi:20100609190324p:image:medium

ファームウェアのメニューが出ます。

f:id:n7shi:20100609190322p:image:medium

初期設定を行います。カーソルキーと[Enter]で選択します。キャンセルは[Esc]です。

  • Run setup
    • Initialize system
      • Set default configuration
        • 解像度を選択します。
          ※NT 4では任意の解像度が選べますが、NT 3.5では1280×1024でないとうまくいかないようです。
        • それ以外はデフォルトのままで結構です。
      • Set ethernet address
        • ゼロだとネットワークがエラーになるため、適当な値を入力します。

以上の設定が完了して[Esc]でメニューを抜けると、解像度を変更した場合は再起動が掛かります。

ブートパーティションの作成

ファームウェアのトップメニューからCD内のarcinstを実行します。

  • Run a program
    • cd:\mips\arcinst
      ※US配列での入力となります。日本語キーボードを使っているときは、コロンは[Shift]+[;]、バックスラッシュ(円マーク)は ] で入力します。
      • Configure Partitions
        • Create System Partition

ブートローダを置くFATパーティションを作成します。NT本体もFATに置く場合は最大サイズで作成します。NT本体をNTFSにインストールする場合は、後でNTのインストール中にパーティションを作成するため、ブートローダを入れるFATは最低限の1MBのサイズでも大丈夫です。

ブートデバイスの指定

ハードディスクからのブートを指定します。

  • Run setup
    • Initialize system
      • Set default environment
        • すべてデフォルトで[Enter]

インストール(初回再起動まで)

ファームウェアからインストーラを起動します。

  • Run a program
    • cd:\mips\setupldr
      ※US配列での入力となります。日本語キーボードを使っているときは、コロンは[Shift]+[;]、バックスラッシュ(円マーク)は ] で入力します。

起動中に以下の画面で固まることがよくあります。これはインストール時だけでなく、インストール後にも発生します。

f:id:n7shi:20100609190321p:image:medium

10秒以上待っても先に進まないようであれば、QEMUを強制終了(ウィンドウを[×]ボタンで閉じる)してください。再度QEMUを起動させて、setupldrの起動からやり直してください。何度もやっていると先に進みます。ファームウェアの設定はnvramというファイルに保存されて引き継がれるため、再設定する必要はありません。

無事にインストーラが起動すれば以下の画面が表示されます。これ以降はx86へのインストールと同じです。

f:id:n7shi:20100609190320p:image:medium

パーティションの選択画面で「未使用の領域」を選択してNTFSでフォーマットしてください。CドライブをNTFSにすることはできません。

再起動を促す画面になったら、再起動してください。

f:id:n7shi:20100609190319p:image:medium

インストール(2回目再起動まで)

再起動すると、ファームウェアのメニューにNTが追加されているので、それを起動してください。

f:id:n7shi:20100609190317p:image:medium

先ほどと同じ場面で起動中に固まることがありますが、その場合はすぐに強制終了して再起動してください。何度もやっていれば先に進みます。

f:id:n7shi:20100609190321p:image:medium

ネットワークの設定では検索して出てきたNICを追加して、DHCPを使用してください。QEMU独自のNATに隔離された環境となります。

再起動を促す画面になったら、再起動してください。

f:id:n7shi:20100609190306p:image:medium

以上でインストールは終了です。

ログオン

再起動するとログオン画面まで進みます。

f:id:n7shi:20100609190259p:image:medium

[Ctrl]+[Alt]+[Delete]を押してもホストのWindowsに取られるため入力できません。

[Ctrl]+[Alt]+[3]を押してmonitor consoleに入り、以下のコマンドを入力します。

sendkey ctrl-alt-delete

f:id:n7shi:20100609190539p:image:medium

[Ctrl]+[Alt]+[1]を押すと元の画面に戻ります。ユーザー入力画面になっているはずです。

f:id:n7shi:20100609190538p:image:medium

ログオンすればNT4/MIPSの世界が広がっています!

f:id:n7shi:20100609190537p:image:medium

ネットワーク

前述のようにNATで隔離された環境からネットワークを使用することができます。

FTP

NATは外部からのアクセスをルーティングしないため、FTPのアクティブモードは使用できません。パッシブモードで使用してください。

NT4付属のFTPコマンドはパッシブモードに対応していないため、別のFTPクライアントが必要となります。NT4/MIPSでは16bitのx86コードが動くため、Windows 3.1用のFTPソフトが使用できます。たとえば以下には3.1用のWS_FTPが残っています。

共有フォルダへのアクセス

NATで隔離されているため、ワークグループ内のマシンを名前解決することができません。IPアドレスを指定すればアクセスできます。NTドメインについては未確認です。

ネットワークがうまくいかない場合は、QEMUを終了させた状態で、VHDをマウントしてファイルをやり取りすることもできます。インストールされているMIPSバイナリを抜き出して調査するにはこの方法がお勧めです。

IE2

IE2がバンドルされています。Yahooを開いてみましたが文字化けしました。エンコーディングを指定できないようです。

f:id:n7shi:20100609190536p:image:medium

Googleは延々とリロードを繰り返して開きませんでした。F5攻撃と同様なため試さないでください。

IE2はHTTP/1.0しかサポートしていないため、バーチャルホストには接続できません。URLが合っているのに404になる場合は、ホストがバーチャルだと思われます。

IE1.5J

NT4の2枚目のCDには日本語版IE1.5が入っています。インストールしてYahooを開いてみましたが文字化けしました。レンダリング能力はIE2以下で、エンコーディングの指定もできないため、ほとんど使い物になりません。

IE2もIE1.5Jも使い物にならないため、Windows 3.1用のNetscapeをインストールした方が良いと思います。以下では32bitのNetscapeを動かす方法が紹介されていますが、Win32 x86 Emulation on RISC は既に入手不可能なので、残念ながら試すことができません。

【余談】この記事によればAlpha用の Win32 x86 Emulation on RISC が存在するようですが、これは有名な FX!32 とは別物のようです。性能の比較など詳しいことは不明です。

最後に

インストールレポートは以上です。

癖があってなかなかうまくいかなかったため、まとめるのに時間が掛かってしまいました。何度もインストールしましたが、ディスクアクセスはそれほど重くないという印象です。

昔から使っているWindows環境でMIPSの調査ができるという意味で、私にとっては面白い環境です。

2010-05-19

[][]コンパイラ

id:n7shi:20100305でExcel上のネイティブコンパイラをARMに対応しましたが、今回MIPSに対応しました。MIPS用のNT4とCEに対応しています。QEMU上のNT4/MIPSで動作を確認しました。

以下のアーキテクチャを切り替えられます。

2010-03-02

[][][]GOTエラー

OpenBSDでportsをビルドしていて、CUPSでエラーになりました。

Linking texttops...
(snip)
/usr/bin/ld: not enough GOT space for local GOT entries

GOTというのはGlobal Object Tableのことで、どうやらグローバル変数が収まりきらないというエラーのようです。初めて見るエラーなので、対処方法のメモを残しておきます。

パッチ

texttops.cには巨大なグローバル配列が定義されていますが、これらは他のソースからは参照されていないので、staticにしただけでビルドが通りました。

--- filter/texttops.c.orig
+++ filter/texttops.c
@@ -33,16 +33,16 @@
 
 
 /*
- * Globals...
+ * Locals...
  */
 
-char		*Glyphs[65536];	/* PostScript glyphs for Unicode */
-int		NumFonts;	/* Number of fonts to use */
-char		*Fonts[256][4];	/* Fonts to use */
-unsigned short	Chars[65536];	/* 0xffcc (ff = font, cc = char) */
-unsigned short	Codes[65536];	/* Unicode glyph mapping to fonts */
-int		Widths[256];	/* Widths of each font */
-int		Directions[256];/* Text directions for each font */
+static char		*Glyphs[65536];	/* PostScript glyphs for Unicode */
+static int		NumFonts;	/* Number of fonts to use */
+static char		*Fonts[256][4];	/* Fonts to use */
+static unsigned short	Chars[65536];	/* 0xffcc (ff = font, cc = char) */
+static unsigned short	Codes[65536];	/* Unicode glyph mapping to fonts */
+static int		Widths[256];	/* Widths of each font */
+static int		Directions[256];/* Text directions for each font */
 
 
 /*

他の方法

もし他からも参照されていたらstaticにするだけでは対処できません。マクロでアクセス関数を変数に見立てるようにするしかなさそうです。

static char *Glyphs[65536];
char **_Glyphs() { return Glyphs; }

これをヘッダで以下のように公開します。

extern char **_Glyphs();
#define Glyphs (_Glyphs())

理由は異なると思いますが、errnoが似たような方法で公開されています。

int *__errno(void);
#define errno (*__errno())

2010-03-01

[][][]パッケージ

私が手も足も出ないでまごまごしているうちに、GdiumにOpenBSDが移植されました!

さっそくportsを色々とビルドしています。ものすごく時間が掛かるため消えると痛いので、自分用のバックアップを兼ねてSkyDriveに置いておきます。

SkyDriveはダウンロードにワンクッションあるため1つずつダウンロードするのは苦痛ですが、「その他→ZIP形式でダウンロードする」とすれば無圧縮ZIPで丸ごと落ちてきます。

2010-01-13

[][][][][]クロス開発環境構築

GdiumでOpenBSDの動作確認を行うため、カーネルをクロスビルドしました。最初は無難にOpenBSD上で行い、同じ動作を他のOSで再現するという手順を採りました。

  1. OpenBSD(i386)上でOpenBSD(mips64el)カーネルとユーザーランドをクロスビルド
  2. Interix上でOpenBSD(mips64el)カーネルをクロスビルド
  3. Hurd上でOpenBSD(mips64el)カーネルをクロスビルド

ビルドしたカーネルはGdiumで起動中にパニックします。それを修正するため、日常的に使っている環境でクロス開発できるようにしました。Interix上でOpenBSDの開発というのは一見無茶な組み合わせですが、実はそうでもありません。なぜかというとInterixのlibcの一部はOpenBSD由来で、他のUNIXに比べて親和性があるためです。

OpenBSD(i386)

OpenBSD上で他のアーキテクチャのカーネルをクロスビルドする手順は驟雨さんがまとめています。

Gdiumはloongsonアーキテクチャですが、loongsonサポートはつい最近CVSにコミットされたばかりで、CVSからcurrentを取得する必要があります。sgiもloongsonもmips64ですがエンディアンが異なるため、ビルド時にエンディアンを区別する必要がありますが、そのための修正はCVSにはコミットされていません。後述のビルドツールに同梱しているので参照してください。

エンディアンに関する修正を施せば、カーネルはすんなりビルドできました。

Interix

OpenBSD上でのビルドの動きを見ていると、ビルドに必要なコマンドを用意すれば他のOSでもビルドできそうです。

真っ先に必要になるのはmakeです。OpenBSD特有のマクロを使用するため、GNU makeでは代用できません。OpenBSDのソースから抜き出してビルドできるように改変しました。GNU makeなどと区別するためobmakeという名前で/usr/local/binに入れてビルドプロセスを試しました。

TARGET=loongson obmake cross-gcc

プロセスが進むうちにコマンドがなかったり非互換だったりでエラーが出ます。その度にコマンドを持って来ることを繰り返して、最終的には以下のコマンドを用意すればカーネルのビルドまで完了しました。

  • make, mkdep, config, mtree, readlink, rpcgen, compile_et

binutilsやgccは本来のビルドプロセスに含まれているため、別途用意しなくても問題ありません。

ビルド中に構築される仮想ルートで所有権の設定を試みますが、Interixにはrootやwheelなどが存在しないためエラーになります。そのため所有権を無視したコマンドも用意しました。

  • chown, install

こうして用意したコマンドだけを、OpenBSDのソースツリーから抜き出してビルドできるようにまとめました。

Debian/Interix環境で以下のパッケージがインストールされていることが前提です。Debian/Interixについてはid:n7shi:20091214id:n7shi:20091215を参照してください。

  • binutils, bison, flex, gcc, groff, install-info, libreadline5-dev, texinfo

環境が整えばクロスツールのインストールは簡単です。

make install

OpenBSDのソースを/usr/srcに展開します。前述のエンディアンやInterix特有の問題などを修正したパッチがpatch/cross.diffにあるため適用します。CVSの時期によってははじかれる可能性があるため、はじかれた場合は手動で対処が必要です。

パッチを適用後、ソースツリーに移動してビルドします。カーネルのビルドには大量の環境変数を設定する必要があるため、cross-wrapperとして環境変数をシェルスクリプトにダンプできるように改変しています。

cd /usr/src
TARGET=loongson obmake cross-gcc
TARGET=loongson obmake cross-wrapper ← 独自拡張
mv cross-wrapper /usr/local/bin/loongson
cd sys/arch/loongson/conf
obconfig GENERIC
cd ../compile/GENERIC
loongson obmake depend
loongson obmake

この手順は複雑なため一発でできるようにも改変しましたが、今回はカーネルを修正しながら何度もビルドするのが目的のため、あまり意味はありません。

cd /usr/src
TARGET=loongson obmake cross-kernel ← 独自拡張

RAMDISKカーネルにはディスクイメージを入れる必要がありますが、前述の所有権やディスクイメージのマウントなど問題が山積しているため、OpenBSDでビルドしたイメージを持って来るのが現実的です。

それ以前の問題として、現段階ではルートのマウントの前にカーネルパニックしてしまうため、RAMDISKカーネルを用意しても意味がありません。パニックせずにルートのマウントまで進むようにカーネルをハックするのが先です。RAMDISKについてはその後で考えることにします。

Hurd

Interixで成功したので、Hurdでも試みました。基本的なやり方はInterixと同じですが、前述のようにInterixはOpenBSDに近いため比較的簡単で、Hurdではそれよりもかなり手間が掛かりました。一部の関数はOpenBSDから持って来るのが困難だったため、NetBSDのpkgsrcの互換レイヤ(libnbcompat)から持って来ました。

Hurdで動くようにしたものを置いておきます。readlineは注意が必要で、libreadline6-devではなくlibreadline5-devをインストールしてください。基本的にInterix版にHurd対応コードを付け足したものなので、config.mkを書き換えればInterixでも使えます。

Hurd対応というより実質的にglibc対応です。そのためglibcを使用する他のOS(Debian GNU/kFreeBSDなど)でも少しの修正で使用できると思われます。

ちなみにこれをkではないオリジナルのFreeBSDに持って行くと大量のエラーが出ます。OpenBSDとFreeBSDとで同じ定義が重複するためです。それらはもともと存在して互換レイヤとして必要ないものですから、削ればうまくいくと思われます。