TOPPERS/ASPをLinux(i386 / x86_64)で動かす

# はじめに

組み込み機器向けRTOSのひとつ [TOPPERS/ASP](https://www.toppers.jp/asp-kernel.html) を Linux に移植しました。

TOPPERS/ASPは、個別のプラットフォーム向けに移植されるとともに、シミュレータ環境として Mac OS X で動作するものが公式から提供されています。しかし、Linuxで動作するものは用意されていません。

Mac OS X ターゲット依存部をもとに Linux ターゲット依存部を作成しました[^1]。Mac OS X版と同じく、シミュレータ環境としての位置づけです。TOPPERS付属サンプルの sample1 は動作します。

[^1]: 必要に迫られたので、勉強がてら自宅作業でとりかかりました。

# コード

* https://github.com/morioka/toppers-asp-for-linux に置いています。

# 対象

* Linux (i386, x86_64)
 * Ubuntu 15.10 (x86_64)で確認しています

# 使い方

TOPPERS/ASPに添付されている sample1 をビルドして実行するまでを示します。

```shell-session:build-sample1.sh

git clone https://github.com/morioka/toppers-asp-for-linux
cd toppers-asp-for-linux/asp
cd cfg
make clean
make depend
make
cd ..
mkdir obj
cd obj
../configure -T linux_gcc
make depend
make
./asp

```

# Mac OS X 版からの変更点

TOPPERS/ASP の "Mac OS Xターゲット依存部 ユーザーズマニュアル" には、移植に際しての注意点が次のように記述されています。

<pre>
5.1 類似のターゲットへのポーティング

Mac OS Xのカーネルは，BSD UNIXベースであり，Mac OS Xターゲット依存部に
おいても，Mac OS Xに特有の機能はほとんど使用していない．そのため，他の
BSD UNIXベースのOSや，Linuxへのポーティングも可能と思われる．

ただし，明らかにOSやプロセッサに依存する部分として，タスクの起動時にタ
スクのメインルーチンに分岐するために，jmp_buf構造体にPCやSPを直接設定し
てlongjmpしているコードがある．jmp_buf構造体の中でPCやSPの位置はプロセッ
サやOS（厳密にはライブラリ）によって異なるし，プロセッサによっては他の
レジスタも設定しなければならない場合がある．
</pre>

これに倣って作業しました。比較的大きな修正は以下の3点です。

## jmp_buf 構造体の PC, SPの書き換え

jmp_buf構造体の PC, SP の位置を glibc-2.2 の i386, x86_64 のそれぞれの場合に合わせて修正しました。

ここで注意すべきことは、jmp_buf構造体の PC, SP は　Linux 2.6辺りから後のglibcでは長寿命のポインタは PTR_MANGLE マクロで難読化されているということです[^2]。

[^2]: [setjmp用の__jmpbuf の スタックポインタがエンコードされている件 - Higepon’s blog](http://d.hatena.ne.jp/higepon/20070131/1170257744) や [最近のglibcではatexit関数やjmp_bufを狙った攻撃は効かない (PTR_MANGLE) - memologue](http://d.hatena.ne.jp/yupo5656/20060820/p1)を参照。これに気付くのに時間を要しました。作業時間の大半はこの部分で停滞したことでした。

以前はこの難読化処理を無効にしてアプリケーションを起動する方法がありましたが、 脆弱性 [CVE-2015-8777](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2015-8777) への対策の結果、使えなくなりました。現在は、難読化が常に有効になっています。

ですので、[タスクコンテキストの初期化 (activate_context)](http://www.nces.is.nagoya-u.ac.jp/NEXCESS/blog/index.php?itemid=102) で各TCB のjmp_buf構造体要素のPC, SPの値を書き換える際には、PTR_MANGLEマクロで難読化された値と同等の値を設定してやる必要があります[^3]。今回は、glibc-2.2のソースコードからPTR_MANGLEマクロを転記しました[^4]。PTR_MANGLEマクロの具体的な実装はglibcのバージョンやプラットフォームで異なっているようです。今後 PTR_MANGLEマクロが変更された場合、その変更に追従する必要があります[^5]。

[^3]: [日々雑感&#12289;覚書: TOPPERSにトライ](http://etc2day-linux.blogspot.jp/2015/12/toppers.html) や [ふふふのブログ 【toppers】toppers-jsp linuxエミュレーション](http://sakaihdt.blog.shinobi.jp/oss%E9%96%A2%E9%80%A3/%E3%80%90toppers%E3%80%91toppers-jsp%20linux) など、TOPPERS/JSP での対応を含め、試みている方はいらっしゃいます。

[^4]: glibc由来のコード片を取り込むことによって、コード全体が GPLv2 の適用となるかはよくわかりません。

[^5]: これらの方法と異なり、[(toppers-users 4041) Re: jsp 1.4.3でアボートします](https://www.toppers.jp/TOPPERS-USERS/2012-November/003864.html) や[(toppers-users 2712) Re: JSPシミュレーション環境へのパッチ](http://www.toppers.jp/TOPPERS-USERS/2008-January/002534.html) にあるように、タスクのスタック領域の確保方法を変更して対応された方もいらっしゃいます(TOPPERS/JSPの場合)。


## バッファオーバーフローのチェック機能の無効化

glibcのバッファオーバーフローのチェック機能を無効化する( -UFORTIFY_SOURCE )必要がありました。

## シグナル番号の変更

BSD系のMacOSX と Linuxとでシグナル番号の割り当てに違いがありましたので、変更しました。

# TOPPERS/ASP3の場合

[TOPPERS/ASP3](https://www.toppers.jp/asp3-kernel.html) でも同様の修正でOKでした。 
コードは https://github.com/morioka/toppers-asp3-for-linux に置いています。