超簡易リモートリセッタの制作

/ やってみた / その3 – 05.09.05

何、これ?

 以前ぷらっとほーむだかのコラムでも似たような話を見ましたが、VPN+WOL+RDTというのは一度経験してしまうと手放せない、極めて便利なソ リューションです。ネットに繋がる場所からVPNで接続し、WOLでPCを叩き起こしてRDTでログインすれば、もういつものデスクトップが目の前に。

 ところが、こういうことをやっていると稀にドツボにハマることがあります。というのは、うっかりPCがハングしてしまった時・・・普段なら文句垂れながらリセットスイッチを「ぽちっ」とやるのですが、この「ぽちっ」が出来ない。

 で、前述のぷらっとほーむのコラムでは「ハングったら有無を言わせず電源OFF&ONで強制再起動じゃい」とリモート電源管理装置を紹介しているワケですが、この電源管理装置ってのは実は¥が結構いいんですよ。
 ということは、私のような人間にはお呼びではない。

 しかし、私の場合はふと特殊事情があることを思い出しましたよ。というのは、自宅のPCが1台だけではないんですな。1台はWindowsが入っているが、もう1台は自宅サーバとしてLinuxが常時動いているということ。

 「だったら、WindowsがハングしたらLinuxからリセットしてやればいいやん」

 ということで、これを超手抜きで実装した記録がこのページというワケですよ。

今回のコンセプト

 Linux機のパラレルポートを使ってリセット信号を発行し、Windows機をハードウェアリセットする。

今回のパーツ

  • Dsub25オス/RJ45ユニバーサル変換(¥620@千石電商)
  • RJ45(=LAN)ケーブル
  • ジャンクのLANカード
  • 適当な光リレー(東芝TLP227G/¥80@秋月電子)
  • 330Ω抵抗(1/8wで十分)
  • 万能基盤少々
  • ピンヘッダ少々
  • 配線材少々

 適当にジャンク箱なんか漁れば出て来そうなものばかりなので、少々特殊&ヘンなものだけ。

 まず、Dsubのユニバーサル変換コネクタ。少々¥は高いのですが、これを使うと太いパラレルケーブルを使わず、抜き差しも簡単で長さも太さも選べるLANケーブルをPC間接続に使用できます。

#モノのイメージが湧かないという方は、こちらへ>千石電商の通販ページ

 次はジャンクのLANカード。こいつはリセット回路(ってそんな大袈裟なものでもないけど)を乗せるための「土台」で、PCIコネクタ部分を切断した後 カードの空き部分に万能基板を乗せ、LANカードに付いているRJ-45コネクタから線を引き出してパラレルポートの出力を取り出します、はい。
 なんでこんなことするかって、こうしておけば一度PCに内蔵してしまえば、後はPCIスロットになにやら怪しげなRJ-45コネクタがあるという以外の変化が無いので、見てくれも取り扱いも良いワケですよ。

 さて、その次はフォトリレー。これは今回のこだわりのパーツです。
というのは、フォトリレーを使って「リセットする側」「される側」完全に電気的に絶縁することで、通電状態等を一切気にせずに接続・解放が出来るからです。

 逆に絶縁していないと、グランドループ等の問題が発生する可能性があるので電源ON/OFFや接続・解放について相当面倒な話になってしまいます。

 そうそう、最後に。電流制限用の330Ωを省略すると(過電流で)確実にPCのパラレルポートが吹っ飛びます。運が悪ければマザーボードまるごと吹っ飛ぶかも知れませんので、気を付けて。

今回の回路とハードウェア制作

 回路なんて、そんな難しいものはありません。

 単純に、パラレルポートの出力にフォトリレーと電流制限用の330Ωの抵抗が直列に繋がるようにするだけです。
 但し、見かけだけはある程度スマートになるように気を付けたため、上のような各種パーツが必要になったわけです。

 一応、以下に回路図、その下に犠牲になるLANカードの使い方(笑。
 あと、管理人によるバッチイ工作の画像をどうしても見たい人はこれ


ハードウェアにはソフトウェアを

 ということで、次は上のリセット回路を動作させる為のソフトウェアが必要なのですが。
 実際問題、パラレルポートにぽいぽいっと出力すればいいだけなので、簡単なもので良いワケですよ。

 以下はCでの作成例ですが、まるっきり必要最低限なものでしかないので、必要に応じて機能を追加して下さいな。

 #といっても私はこのまんま使ってますけどね(笑。

#include <stdio.h>
#include <sys/io.h>

#define PIOADDR 0x378

main()
{
ioperm(PIOADDR, 3, 1);

outb(0x0d, PIOADDR+2);
outb(0x01, PIOADDR);

sleep(1);

outb(0x00, PIOADDR);

ioperm(PIOADDR, 3, 0);
}

 プログラム上には工夫等は一切無し。まずioperm()でパラレルポートを開始し、outb()でパラレルポートの動作モードを設定、続いて1バイト を出力(リセットボタンを「押す」)。ここで1秒待ってもう一度1バイト出力(リセットボタンを「放す」)、最後にioperm()でパラレルポート操作 を完了。

 注意する点があるとすればPIOADDRで置換しているプリンタポートのアドレスですかね。
 本来のLPT1のI/Oアドレスは0x3bcらしいのですが、最近のM/Bでは0x387(本来LPT2のアドレス)に初期設定がなっているものが多い模様です(当方の環境もそうでした)。
 まあ、初期値が0x287(LPT3)ってのは私は見たことは無いのですが。

 あぁ、後このプログラム、ioperm()の権限の関係でroot権限で動作させないと動きません
 rootになって実行するとか、s-bit立てるとか、その辺りはお好きにどうぞ。

注意点「超簡易」の由縁

 さて、この回路。実は重大な欠点があるんですよ。

 というのは、もしLinuxサーバを再起動しなければならない場合、再起動時のハードウェア周りの初期化に伴ってパラレルポートへ意図しない出力が行われ、結果としてリセット回路が稼働しまう可能性がある、というかほぼ確実にリセットされてしまうということです。

 これを回避するのは実は簡単で、タイマ回路を組み込んで「一定時間以上出力しなければリセットを開始しない」ようにすれば良いのですが、正直「めんどい」ので「運用上の配慮」で逃げ切ることにします、はい。

Share