SL-B500で USBストレージ その3


 と言うことで、軽くスクリプトについて調べてみる。

 まぁ、細かい話はさておき、結局のところは /sbin/hotplugの動作が全てってコトになる。
 つまり、最終的にはこいつを置き換えないといけないワケなんだけど、 /sbinが、リードオンリーの領域に置かれてるのがネック。

 逆に言えば、 humorumさんがわざわざカーネルモジュールをコンパイルしなおしたのも、一重に /sbin/hotplugを見に行かないようにするためだったりするワケか。ふむむ。


 と、ここまで来たトコではたと気付く。USBストレージ使うだけなんだったら、必ずしも hotplug経由させる必要も無いんでないかい???。

 要は、標準の USB一旦殺して、静的にモジュールロードすれば良いんでは無いかと。
 つか、現在の実装だと明示的に SDか CFをコマンドラインから指定してやらんといかんワケで、そもそもが静的な実装と言えなくもない。

 問題があるとすれば、USBケーブルが抜かれてもモジュールが動的にアンロードされないことですか。
 とは言え、標準でもそもそも USBネットワークのモジュール居座ったまんまになってるから、あんまり変わんないか(^^;)。
 
 むしろ、ストレージ対象になってるデバイスの挿抜の方に影響しないかどうかが気にはなるけど、まぁこのへん気にしだしたらキリは無いってことで(^^;)。


 ってことで、簡単なスクリプトを書いてみる。

#!/bin/sh

KERNEL_VER=`/bin/uname -r`
MODULE_PATH="/lib/modules/${KERNEL_VER}/kernel/drivers/usb/device"
DEVICE_SD="/dev/mmcda1"
DEVICE_CF="/dev/hda1"
STORAGE="${DEVICE_SD}"

# Define Function
 module_unload(){
 lsmod | while read LINE;
  do
   if echo "${LINE}" | grep -q "^pxa_bi"; then
 	rmmod pxa_bi
   elif echo "${LINE}" | grep -q "^net_fd"; then
 	rmmod net_fd
   elif echo "${LINE}" | grep -q "^storage_fd"; then
 	rmmod storage_fd
   elif echo "${LINE}" | grep -q "^usbdcore"; then
	rmmod usbdcore
   elif echo "${LINE}" | grep -q "^usbdmonitor"; then
	rmmod usbdmonitor
   fi
  done
 }

# Main routine
 if [ $# != 1 ];then
	echo "usage: usbstorage < sd | cf | net | unload >"
	exit 0
 fi

 if echo "$1" | grep -q '^[sS][dD]$';then
	STORAGE="${DEVICE_SD}"
 elif echo "$1" | grep -q '^[cC][fF]$';then
	STORAGE="${DEVICE_CF}"
 elif echo "$1" | grep -q '^[nN][eE][tT]$';then
	echo "Starting USB network."
	module_unload
	/etc/rc.d/init.d/usb start
	exit 0	
 elif echo "$1" | grep -q '^[uU][nN][lL][oO][aA][dD]$';then
	echo "Modules unload."
	module_unload
	exit 0
 else
 	echo "Invalid arguments."
	exit 1
 fi

 echo "Provided USB Storage from ${STORAGE}."
 module_unload
 insmod ${MODULE_PATH}/usbdcore.o
 insmod ${MODULE_PATH}/storage_fd/storage_fd.o storage_device=${STORAGE}
 insmod ${MODULE_PATH}/bi/pxa_bi.o
 exit 0

 とりあえず、手元で試してみた限りではちゃんと動いてるみたい。
 USBネットワークへの復帰も問題なさげ。

 ってことで、上記のスクリプトに必要なモジュール含めてパッケージ化してみました。

 当然のごとく、無保証です。念の為。
 一応、SL-B500以外の SL-C700SL-C760でも動作確認しましたが、この二機種に関しては、そもそもhumorumさんトコの元パッケージが動きますんで、あんま意味ないです。
 つか、明らかにこっちの処理は行儀悪いんで、危険度が増すだけだと思います(^^;)。

・使い方

 コマンドラインから下記のコマンドを叩きます。

usbstorage < sd | cf | net | unload >

 単純に、sd、cfを指定した場合はそれぞれを対象に USBストレージが有効に。
 netで、標準の USBネットワークに戻ります。

 また、念の為 unloadを指定すると、現在読み込み中の USB関係のモジュールをまとめて rmmodします。動作不安定になった時は、一旦 unloadしてみると良いかもしれません(^^;)。

 ちなみに、引数無しで叩いた場合は、単純に usage: が表示されます。


 現時点で、把握している問題としては
 前記の通り、明示的にunloadを指示してやらないと、最前にロードしたモジュールが居座ったままになるくらいですか。

 万全を期すなら、 cardctlと sdcontrolにも手を加えてやると良いかもしれないけど、とりあえず、これで個人的に困ってないんで、このへんで作業終了(おひ)。

 ま、困ったら、ちゃんと考えることにします。さて、次は A300かな・・・気が向けば(^^;)。

SL-A300でUSBストレージ その1

 気が向いた(笑)。


 とりあえず、B500でパッケージングまで終了したのは良いけど、このへん rmmod,insmodの詳細な動作については疎いんで一応念の為、もう一度それらの動作について JM Projectの manページあたりを見てみることに。いや、んなコトはパッケージ化して公開する前にしろっつー話もあるけど(^^;)。

 で、調べてみると、 insmodのオプションの中に kernelバージョンを無視する -f --forceオプションってのがあることを知る。
 と言っても、無視出来るのはバージョンNo.だけで、どのみちカーネル中のシンボルテーブルが一致しないと組み込みは出来ないらしい。
 ま、でも、逆にそれなら試してみてもそれ程致命的な事態にもならんだろー、ってことで SL-A300で再チャレンジ。

 usbdcore.o、pxa_bi.oは B500と同じく標準で持ってるんで、 storage_fd.oだけ適当なディレクトリにコピー。
 で、

rmmod pxa_bi
rmmod net_fd
rmmod usbdcore
rmmod usbdmonitor

cd /lib/modules/2.4.13-ac5-rmk2-cotulla.1/kernel/drivers/usb/device/

insmod ./usbdcore.o
insmod -f ./storage_fd/storage_fd.o storage_device=/mmcda1
insmod ./bi/pxa_bi

 -f 指定してもいちお warningは表示されますが、 lsmodで確認すると一応ちゃんとモジュールはロードされてます。

 ってことで、おもむろに PCと USB接続すると・・・キター!(^^)。
 あっさり、動作成功。

 storage_device=/dev/hda1の指定で、CE-JC1に挿した CFもちゃんとストレージとして認識出来た。
 ただ、CFに関してはメモリカード挿してる分には問題ないんだけど、マイクロドライブだと正常に認識出来ないみたい。
 A300ローカルからは問題ないんだけど・・・。カードスロットの駆動電圧の問題かねぇ?。この場合 USB端子も同時に駆動さしてるワケだし。


 ってことで、 A300でも USBストレージ可能なことが確認出来ましたが、パッケージ化については、ちと考えちゅ。

 前述のように、CF側の認識に多少制限あるし、そもそも A300は標準でターミナルどころかキーボードも存在しないワケで、そうなるとコマンドラインで設定させるのもどうかなー、と。
 もっと言うと、現状では -fオプションで強引に認識させてるよーな状態だし(^^;)。


 ・・・ってことで、どーしましょう?(笑)