LANDISK で USB シリアルケーブルを使う

[戻る]

とある野望のため USB シリアル変換ケーブル (BHC-US01/GP) を買いました. 当初は別のものを買う予定だったんですが, 店頭で価格差が激しかったので 「え〜い Linux でも動くだろ」と賭けに出ちゃいました.

帰宅早々ネットで調べてみると Prolific 社の PL-2303 のようで使えるようです. ガッツ.

っという訳で Plamo の入ってる PC に挿してみると認識できます.

# /sbin/agetty 9600 ttyUSB0 vt100
っと打ってみると, 改行が変で「デバイスに対する不適切な ioctl です」などと ワーニングが出ますが一応ログインできます. よしよし.

っと言っても, とある野望のためには AT 互換機で動いても嬉しくありません. LANDISK (HDL-160U) で動かしたいのです. っという訳で LANDISK で動くため 苦労した事柄について記録したいと思います.

とりあえずカーネルソースから usbserial と pl2303 のモジュールを作ればいいんだ と考えました. もろもろの事情で 以前 カーネルコンパイルした時とは別の LANDISK を使ったのですが, ソースを get として以前と同じカーネルパラメータを与えても, なぜか USB に関する項目が出てこず, usbserial/pl2303 が作れません. 結構悩んだのですが, プロセッサタイプを SH7751SolutionEngine から Julian にすると安直に出てきました.

usbserial.o と pl2303.o を作成し insmod しようとすると usb-ohci と usbcore を先に入れとかないとだめでした. そういえば以前の LANDISK は外付け HDD を付けていた気がします.

# mknod /dev/ttyUSB0 c 188 0
でデバイスを作った後, usb-ohci, usbcore, usbserial, pl2303 を insmod して 先と同じように
# /sbin/getty 9600 ttyUSB0 vt100
と打ったのですが, 失敗します.

調査の結果

# cat /dev/ttyUSB0
は上手くいくようですが, 逆:
# echo hoge > /dev/ttyUSB0
が失敗します. 受信は上手くいくけど送信が駄目のようです.

こまったもんだなとまたまたネットをさまよってみると こんな ページを見つけました. これによると PL-2303 じゃなくて PL-2303X である 可能性が大です. っという訳で get して pl2303.o を作り直してみました. その結果, 送受信共一見上手く動いてくれるようになりました. っが「一見」だけでした. 複数行の送信ができません.

いよいよ手詰まりかと思ったのですが, ふと 「Plamo では動くのはなぜだろう」と考えました. Plamo のカーネルのバージョンは 2.4.31, それに対し LANDISK は 2.4.21 です. pl2303.c を覗いてみると先のパッチは当たってます. となると pl2303.c だけを 2.4.31 のそれにしてみればいいようです.

っという訳で作り方ですが,

  1. 2.4.31 のソースから pl2303.c と pl2303.h をかっぱらう
  2. pl2303.c の適当な所 (例えば id_table[] の定義直前) に
    static void *usb_get_serial_port_data(struct usb_serial_port *port){
      return port->private;
    }
    
    static void usb_set_serial_port_data(struct usb_serial_port *port, void *data){
      port->private = data;
    }
    
    というフレーズを追加する
とうまく作ることができました.

念のためソース生成物を置いておきます.

早速送受信テストをしてみるとうまく動くようになりました. めでたしめでたし っと言いたいのですが, 次なるテストとして先ほど書いた getty を実行してみると なぜか "Password:" の表示がシリアル端末側に出ず, 呼び出し側に出てしまいます.

usbserial が原因かと usbserial.c と usb-serial.h もコピーして, 2.4.21 でも コンパイルが通るよう手を加えてがんばってみたのですが改善されません.

ここまで来たんだからといろいろ調べてみたのですが, どうも /sbin/getty は /bin/login を呼び出すが, 実はその中身は /bin/tinylogin で, tinylogin の中では getpass() 関数を使ってパスワードの入力を行っている. んで, getpass() は /dev/tty からパスワード入力を求めるもんだから 呼び出し側でパスワード入力されているんだということが分かりました.

getpass() 呼び出し直前で ttyname(0) の結果は /dev/ttyUSB0 になっているん ですが, /dev/tty に出力してみると呼び出し側のままです. どっかで /dev/tty の切り替えが上手くいってないと考えられますが, なぜなのか, どうすればいいのか, なぜ LAN 経由だと上手くいくのか, はたまた Plamo だと上手くいくのかはさっぱりでくじけました. まぁ呼び出し方が悪いってことも考えられますが...

でも件の野望にはあまり影響が無いのではと期待できるので, 当面この問題は あきらめてほっとこうということになりました.


2006.3