SyntaxHighlighter

2012年5月21日月曜日

mruby on EFI Shell

mruby on EFI Shell

mruby を 32bit, 64bit の EFI Shell 上で動かしてみました。

mruby

mruby は、Ruby の作者であるまつもとさんが開発されている「組込み向け軽量 Ruby」の実装です。

詳しくは ITPro の紹介記事などをご覧ください。

今回は、この mruby を EFI Shell 上で動かしてみました。

EFI と EFI Shell

EFI

EFI もしくは UEFI とは、BIOS の置き換えのために Intel などが中心となって策定したファームウェアの仕様です。

最近の PC はほぼ UEFI 対応していますが、だからといって、すべてのもので EFI Shell が立ち上げられるとは限りません。
また、UEFI Boot 自体も、まだそれほど一般的ではないかもしれません。
ベンダによっては、UEFI なのに、UEFI Native Boot ではなく Legacy Boot させている (つまり CSM Boot させている) ところも多いようです。

ただし、Windows 8 が出てくるころには、状況も変わってくると思います。

EFI Shell

詳しく書くときりがないので EFI の詳細については省略しますが、その仕様の中で、EFI Shell という DOS や bash のようなシェル環境が定義されており、実際にいくつかの UEFI Boot 対応 PC では、Firmware 内に組込まれています。

BIOS Setup 画面で Launch EFI Shell のような項目があれば、それが該当します。
また、EFI Shell バイナリを USB メモリなどから起動させることで起動することもできます。

で、今回、この EFI Shell 上で動くように mruby をコンパイルしてみました。

動作例とダウンロード

ダウンロードは GitHub から可能です。
展開して得られるバイナリのうち、mruby.efi は 32bit 用、mruby64.efi は 64bit 用です。

VMware Player 上で動かすと、以下のようになります。
図は [ 10, 2, 4, 1 ].sort.each{ |i| p i } を引数で直接指定して実行したところです。
ファイルを渡してももちろん動作します。

作業記録とソースコード

以下は、作業記録です。

ソースコード

EFI Shell アプリケーションを作るので、EDK と mruby の二つが必要です。

EDK は edk2_for_mruby として、 mruby は mruby_efi_shell として、どちらも GitHub 上に置いてあります。

まず、edk2_for_mruby をダウンロードして展開し、続いて AppPkg/Applications/mruby に mruby_efi_shell を展開します。
やったことがなかったので、サブモジュールなどの設定はまだしていません。

ビルド環境

少し古いですが、現在の Mac や Let's note を使い始める前に使っていた Ubuntu 9.10 (Karmic Koala) でビルドしました。
ただし、これはすでにサポート期限が切れているので、これから始める人は、12.X をインストールした方がよいでしょう。
(余談ですが、私の実機では、 12.X をインストールすると、画面の Refresh Rate がおかしくなったので、面倒になってインストールをやめました。)

また、32bit, 64bit いずれの mruby.efi をビルドする場合でも、32bit の Ubuntu で可能です。
ただし、64bit 版を試すには、VMware Player で 64bit の EFI をエミュレートできる必要があります。
よく分かっていませんが、64bit CPU を搭載している必要があるだろうと思います。また、 Intel-VT などが有効になっている必要があるかもしれません。

あとは、EDK の How to build を見ながら設定していきます。
Unix-like systems でのビルド方法にも、必要なライブラリ (build-essential など) が書かれているので、入れていなかったらインストールします。

ソースの変更

ビルドするために、いくつか変更を加えました。

詳しくは GitHub の履歴を見ていただければいいですが、悩んだのは EDK 側のバグでした。

EFI Application で C の標準ライブラリを使えるようにするためのラッパが用意されているのですが、その中の一つである StdLib/LibC/Main/Main.cmain 関数の宣言が間違っていました。

正確には、それを呼び出しているサンプルである AppPkg/Applications/Main/Main.c との整合性がとれておらず、呼び出し規約が異なったものになっていました。

そのため、偶然、32bit 環境では動作するのに、64bit では動作せず、かなり悩むはめになりました。

それ以外は、y.tab.c のように動的に生成されるものをいくつかあらかじめ作っておくなどをしました。

なお、EDK 側に関数が定義されていないものがあり、現状は math モジュールは除いてあります
今後、必要なら EDK 側に実装するなどして、対応しようと思います。

テスト環境

テスト環境には VirtualBoxVMware Player を用いました。

VirtualBox では、「システム」の「EFI を有効化」にチェックをすることで、Bootable Device がなければ、32bit の EFI Shell が自動で立ち上がります。

VMware Player では、*.vmx ファイルに、以下の行を加えることで EFI Boot させることができます。
efi は小文字にする必要があります。

firmware = "efi"

これで、 Bootable Device がなければ、EFI Shell が自動で立ち上がるはずです。
なお、私の環境では Network の部分でハングしていたので、 Network デバイスを削除しておきました。

以上で 32bit, 64bit ともにテストができるはずです。

今後

今後は、EFI の機能を簡単に呼べるようなライブラリを作っておこうと思います。

少なくとも、Boot Service, Runtime Service ぐらいは Ruby の関数として提供しようと思います。

可能なら、すでに EDK に入っている Python のように、mruby を EDK に含めてもらいたいです。

2012年5月5日土曜日

Subversion Ajax View

Subversion リポジトリを Ajax で見易く表示できるようにしてみました。

概要

以下が動作サンプルです。
ローカルに設置した mruby のソースを見ているところです。

Subversion リポジトリを公開しているサーバー側に設置するスクリプトです。
以下のような特徴があります。

  • サーバーサイドに置きますが、PHP, Ruby on Rails などのスクリプト環境を必要としません。 pure JavaScript で書かれています。
    そのため、ファイルを差し替えるなどすれば、 VisualSVN Server を Windows 上で動作させているような場合でも、見た目だけ容易に変更できると思います。
  • Ajax を活用しているので、静的なページ遷移を発生させずにスムーズなアクセスが可能です。
  • ログもブラウザ上で見ることができます。
  • 古いリビジョンも見ることができます。
  • 現在のところ、差分表示はできません。
    将来、対応するかは未定です。
  • Internet Explorer には対応していません。
    静的な従来の表示がされるだけです。今後、対応するかも未定です。

背景

最近は Subversion よりも、分散型の git や mercurial などが人気ですが、特に企業などではまだまだ Subversion を利用しているところも多いと思います。
特に、開発者ではない人達も閲覧する場合、ブランチが単なるディレクトリである、といったような Subversion の単純化された概念は受け入れられやすいように思います。

そのため、より Subversion を利用しやすくなればよいと思い、こんな拡張機能を作ってみました。

設置方法

詳しくは GitHub の README.md を見てください。
設置してみたいのによく分からないという方は、コメント欄などでお聞きください。

  1. ソースをダウンロードしてください。
    ダウンロードページから subversion_ajax_view.zip をダウンロードし、 Subversion リポジトリのあるサーバーの公開されたディレクトリに展開します。
    ここでは、例として /var/www/svn_ajaxview_dir に展開し、http://server/svn_ajaxview としてそのディレクトリにブラウザからアクセスできるとします。
  2. svn_ajaxview 以外の場所に置くときは、/var/www/svn_ajaxview_dir/svnindex.xsl を開き、中の link, script 要素の href, src の該当部分である二箇所を適宜修正してください。
    この時点で、ブラウザから http://server/svn_ajaxview/svnindex.xslhttp://server/svn_ajaxview/ajaxview/ajaxview.js にアクセスできるかを確認してみてください。
    アクセスできなければ、httpd.conf の Alias 設定などが正しいかを確認してください。
  3. httpd.conf 内の Location ブロック内に SVNIndexXSLT /svn_ajaxview/svnindex.xsl を追記してください。
  4. その後、Apache を再起動してください。

技術的な話

以上はどうでもよい話で、これからが書きたかったことです。
長くなりますが、覚え書きのために書いておきます。

目的

このプログラムを書いた目的は以下の通りです。

  • JavaScript について勉強する。
  • jQuery を使ってみたい。
  • pushState を使ってみたい。

そのため、 Subversion をブラウザ上で綺麗に表示することが目的ではありません。
そういうことであれば、WebSVN などを使うとよいと思います。(PHP を入っていなければ面倒ですが。)

Subversion と WebDAV

Subversion リポジトリを Apache 経由で公開する場合、通常は WebDAV という技術を用いて、つまり WebDAV プロトコルを用いてサーバーとクライアント間でやりとりが行われます。

WebDAV とは HTTP を拡張したプロトコルで、通常の HTTP 1.1 で定義されたメソッドに加え、いくつかのメソッドが定義されています。
HTTP 1.1 では、よく使われる GET, POST 以外にも OPTIONS などのメソッドが RFC では定義されていますが、WebDAV ではその他にも PROPFIND などが定義されています。

Subversion のサーバーとクライアントでは、これらのメソッドを用いて通信が行われています。

XMLHttpRequest で使えるメソッド

Ajax の中核となっているオブジェクトとして、 XMLHttpRequest があります。
これは、 JavaScript 経由でサーバーと通信できるようにするための仕組みです。

この XMLHttpRequest は、 WebDAV のメソッドも発行できるようになっています
Internet Explorer は知りませんが、少なくとも Firefox, Chrome, Safari では可能です。
確かに W3C の open メソッドの説明HTTP 1.1 の RFC を見る限りでは、 extension-method として他のメソッドを受け付けるようになっています。

ということは、 Subversion クライアントが WebDAV 通信をしている以上、 Subversion クライアントが行えることは、すべて Ajax で行えることになります。
(もちろん、ローカルストレージが必要なチェックアウトなどは別です。)

と思ったので、既に存在するかどうかは別にして、「pure JavaScript で Subversion クライアントを作ってみたい」というのがそもそもの動機でした。

今回はビューワを作りましたが、意味があるかは別として、その気になればコミットも可能だろうと思います。

pushState

せっかく Ajax を活用してみたので、 pushState を活用して、 URL も動的に追従するようにさせてみました。

その他

  • Chrome では XML の解析時に getElementsByTagName で名前空間を無視して要素を参照できるようですが、 Firefox ではきちんと getElementsByTagNameNS で名前空間を指定しないと無理でした。
  • あまりきちんとエラー処理していません。
  • Subversion の通信の手順の詳細な仕様がよく分からなかったので、Subversion のソースと Wireshark のパケット解析に基づいて実装しました。
    なので、何かおかしな挙動があるかもしれません。
  • もともとは Chrome の拡張機能として作成していました。
    いずれこちらも整理して公開するかもしれません。
  • Subversion リポジトリにブラウザからアクセスしたときの見た目を変更する方法は、 Subversion Book の "Customizing the look" に載っていました。
  • バグがありましたら、教えていただけると嬉しいです。(対応できるかは未定です。)

というわけで、あまり役には立たないような気もしますが、せっかく作ったので公開してみました。