Hack BBS

[全部のスレッド一覧][新規投稿][記事の削除・変更] [Home Page]

返信投稿はタイトルのリンクをクリックして下さい
スレッド【No.115】の中の記事をすべて表示しています

【No.115】のスレッド
04/03/21(日) 00:22:10 投稿者[たつや] [No.115]のスレッド内
【No.115】 タイトル[akmem の状況] この記事がスレッドの最初です
No.57 で
>それより、作成したカーネルを HDD 上においておき、フ
>ラッシュから起動した後に HDD 上のカーネルで再起動す
>ることができれば、安全にカーネルの入れ替えが可能なの
>ではないかと思い、その方法を考えてみたいと思っていま
>す。

と書いて以来、このプログラム (akmem) の移植作業をやっています。まだまだ完成にはほど遠そうなのですが、どんな物なのかという説明も含めて、現状の報告をいたします。

akmem 概要

・もともとは mips ベースの PDA/HHC で Windows CE を立ち上げずにカーネルの入れ替え(リブート)を行うために開発された。カーネル起動中に他のカーネルイメージをメモリ中に展開し、そちらに制御を渡してしまうため、Another Kernel Memory -> akmem と名付けられたらしい。

・現在、私が作業している LinkStation 版のベースは、PS2用 Linux (MontaVista 2.4.17) にポーティングされた akmem を使用。(ターゲットの CPU は異なるが、ベースとなるカーネルバージョンが同じなため。もし、PowerPC にポーティングされた akmem が存在すれば、かなり助かるのですが、、、、)

・akmem はカーネルメモリにアクセスするためのデバイス/dev/akmem と、このデバイス経由で新規に起動するカーネルを読み込ませるための akload コマンドから構成される。
 操作としては、akload を実行したあと、reboot するとメモリ中にロードされたカーネルから起動する。

・akmem は具体的には以下のような動作をする。

1) /dev/akmem をオープン

2) ioctl(AKMEMIOCTL_ALLOC) で必要なサイズのメモリを割り当てる

3) write() でカーネルの内容を割り当てたメモリに保存

4) ioctl(AKMEMIOCTL_COMMIT) で、カーネルパラメータの設定を行い、メモリ上にカーネルが展開済みであること(akmem_commit フラグ)を設定する

5) カーネル内の reboot ルーチンで akmem_commit フラグを検査し、フラグがセットされていれば akmem の起動ルーチンを呼び出す

6) akmem 起動ルーチンは、自身が作成したマップテーブルを元に、論理アドレス上に点在するカーネルのページを物理アドレス上(?)にコピーしなおす。(現在動作しているカーネルのメモリを強制的に上書きする)

7) カーネルのエントリアドレスへジャンプする。

上記 1) 〜 4) は akload というコマンドで行い、5) 以降はカーネルの reboot ルーチン内で行われる。

akmem 実装の現状

・akmem デバイスをモジュール化する改造は完了。

・上記 5) についてはカーネル内の reboot ルーチンをモジュールから変更することができないため、リブート実行のための ioctl コマンドを追加し、reboot コマンド等から呼び出す。このため、reboot/halt コマンドも akmem 対応バージョンに入れ替える必要がある。
 akmem 対応 reboot の改造は完了。

・現在、6) にあたる部分のデバッグ中。デバッガもなにも使えないので、ひたすら trap が発生した際のレジスタダンプだけを頼りに格闘中。

現時点でわかっている問題点

・akmem は zImage ファイルに対応しているが、LinkStation のファームウェアは、ELF ヘッダを持たない圧縮カーネルイメージなので、akmem を使用してバッファローが提供するカーネルを起動することができない。(カーネルを自分で再構築した場合は、zImage を作成すれば使用できる)

・PS2 版の akmem はカーネルパラメータの受け渡しが動作しないという未確認情報がある。LinkStation のブートローダは root=/dev/hda1 を指定しているので、カーネルパラメータの受け渡しをする必要がある。(これができないと、root デバイスのデフォルト値をカーネルに埋め込まないと起動しない)

これらの問題点は、いずれも akmem 経由でバッファローのカーネルを起動する場合に引っかかります。実際には、自分で再構築したカーネルを起動するのが目的なので、それほど大きな問題ではないでしょう。(強いて言うなら、ファームのアップデートを実行せずに新しいファームウェアのカーネルを試すことができないくらいでしょうか。)

余談
・Linux カーネル 2.5/2.6 の新機能 kexec は、この akmem の機能を kernel の標準機能として取り込んだもののようである。新規に書き直されているが、リブート部分のコードに似た部分があるので、もしかしたら akmem が基になっているのかもしれません。

参考URL
現在の作業で参考にしているページを適当に、、、、

akmem:
http://hp.vector.co.jp/authors/VA008536/ps2linux/akmem.html
http://www.jp.netbsd.org/ja/JP/ml/port-hpcmips-ja/200106/msg00026.html

akmem PS2 版入手先:
http://www.sony.net/Products/Linux/notice.html

Linux PPC/Embedded 関連
http://penguinppc.org/embedded/howto/index.html

ブートローダ関連
http://www-6.ibm.com/jp/developerworks/linux/020510/j_l-embdev.html
http://www.linux.it/kerneldocs/kconf/
http://www.linux.or.jp/JF/JFdocs/kernel-docs-2.2/initrd.txt.html
http://www.jtw.zaq.ne.jp/hiromu/BootUpintro.html

(おまけ)kexec について
http://developer.osdl.org/~andyp/bloom/Code/Linux/Kexec/
http://japan.linux.com/kernel/03/06/25/1825255.shtml