kazubits のすべての投稿

USBのバイナリ

USBをサポートしたバイナリを作ってみました。これも、ドキュメントが不足していて、どうやって作ったり使ったりするのかよくわからなかった。
使い方としては、ホストにフィルタードライバをインストールして、-usbオプションつきでプログラムを起動します。そして、QEMUモニターでinfo usbhostでUSBデバイスのIDを調べ、usb_add host:xxxx:yyyyします。Windows 2000ゲストならPnPで使えるようになると思います。
その他ホームページのほうに書いておきました。
Kqemuを使うと、-win2k-hackがいらなくなるということは、Windows 2000の問題もCPUの問題なんですかね。IDEの問題だとばかり思っていたんですけど。

Windows XP のインストール

以前、Windows XPをインストールしようとしてうまくいかず、ずっとあきらめていました。メーリングリストでは、SP1を当てるとインストールできるとか報告があったようですが、自分のSP1aではだめでした。インストールの途中でエラーのダイアログボックスが出て、無視して継続するとインストールは終わるけれど、その後再起動を繰り返してしまって立ち上がらないという症状でした。
久しぶりに、インストールしてみたところ、なんかすんなりできてしまいました。少し調べてみると、Kqemuを使わないと、WinXPを起動できないこともわかりました。と、いうことはKqemuを使えばQEMUの以前のバージョンでもインストールできるんですかね。未確認ですが。
Qvm86を使っても起動できるようです。ということは、インストールもできるかも。ただ、Qvm86はげストのPAE(Physical Address Extensions)をサポートしていないのでWindows XP SP2は無理かもしれません。SP2になると強制的にPAEを有効にしてしまうようです。SP2を当てたインストールイメージを作らないと確かめられないけど。
Qvm86でも、違いがあるということは、うまく使うとQEMUのデバッグができるかもしれません。遅くて使えないかもしれませんが。
QEMU 0.8.0
kqemu 0.7.2
Windows XP SP1a
という環境です。

Qvm86のバイナリ

久しぶりに、Qvm86のバイナリを更新しました。使ってる人どれくらいいるかわからないけど。開発が止まっているので、だんだん作るのが難しくなっています。
インターネットエクスプローラーのパッチも作りましたので、Windows 2000は、ちゃんと動くのではないかと思います。
Windows 98は、そのままでは動かないので、Qvm86をほとんど使わないようにしています。
それと、ユーザーマニュアルを更新しました。

-kernel-kqemuオプション

CVSに-kernel-kqemuオプションが導入されたようです。今までのユーザーモード(ring 3)に加えて、カーネルモード(ring 0)までできるだけ、実機のCPUで実行します、とのこと。LinuxとWin2k/XPのみのサポートだそうです。
早速、CVSをとってきて、kqemu-1.3.0pre3.tar.gzをダウンロードしてきて、Windows XPホストで動かしてみました。
結果は、動かず…。メールではなんか、テストしてないみたいなこと言ってる。
あきらめて、Fedora Core 4ホストで実験。すると、Win2kゲストは、起動時間が短くなることを確認しました。IEもきびきび動いてるみたいです。
でも、他のLinuxゲストがうまく動かないみたい。なんでだろ。

日本語キーボード

日本語キーボードの¥とパイプ'|'、バックスラッシュ''とアンダースコア'_'をX Windowで使えるようにするパッチを作りました。
http://www.h7.dion.ne.jp/~qemu-win/download/qemu-20060209-keyboard.patch
オプションなし、-k jaオプションありのどちらでも使えると思います。Fedora Core 4ホストで確認しています。patch -p0オプションであてられます。
もし、
Couldn't load keymap file '../pc-bios/keymaps/ja'
というエラーが出たら、keymapsをpc-bios以下にコピーしてください。
[qemu]$ cp -a keymaps ./pc-bios/
アンダースコアは、Xのキーコードが変更されたらしく、使えなくなっていました。XFree86からX.orgになったときに変更?
-k jaの方は、¥の設定がなかったことと、SDLが変なkeysymを返していました。
それにしても、Xのキーコード、SDLのキーコード、PCのスキャンコードに加えて、SDLのkeysymと複雑なのはなんとかならないのかな。

やれやれと思ったら

パッチを送ってみたのですがどうやらうまくない様子。
マルチキャストのほうは、bindするときにsin_addr.s_addr=INADDR_ANYでないと関数が成功しないというものです。でも、そうすると複数のマルチキャストアドレス扱えないらしく、さてどうしようということになりました。
調べてみたけど、いい方法がないので、マルチキャストアドレスでbindが失敗したとき、INADDR_ANYを使うことにしました。
-net socket,connectの方は、もっと難しくて、非同期モードでconnectしたとき、Linux上では、EINPROGRESSなのに、Windows上ではWSAEWOULDBLOCKになってしまうというものです。
Linuxでは、EWOULDBLOCKは、EAGINと同じなためもう1度connectを実行するのですが、WindowsだとWSAEINVALIDになって、パラメータが違っていることになってしまうのです。
いろいろ調べてみたのですが、なんかいい方法がないのです。
そこで、Windows上でBSDソケットを使うことはあきらめて、イベントを使うことにしました。
WSACreateEventして、WSAEventSelectして、WSAWaitForMultibleEventsで待つのですが、サーバーがダウンしていてもFD_CONNECTのシグナルが来ていることがわかり、なんでサーバーなして接続するんだ???でした。
結局、こちらでiErrorCode[FD_CONNECT_BIT]を調べればいいことがわかり、なんとか接続の完了を調べられることがわかりました。
http://forums.belution.com/ja/vc/000/206/45s.shtml
それにしても、なんて面倒なんだか。これでいいのかな。

UDPの双方向通信

UDPで、データを待ち受けるときは、recvfromを使います。このとき、データがくるとパラメータに指定した送信先に、データを送ったアドレスが格納されています。そこに、sendtoを使ってデータを送り返すことで、はじめにデータを送ってきたプログラムと通信することができます。
あまり、UDPでの双方向通信についていいサンプルがないですし、参考にしたサイトがなくなってしまったのでこちらで説明すると、
rc = recvfrom(sd, bufptr, buflen, 0, (struct sockaddr *)&clientaddr, &clientaddrlen);
のclientaddrに送ってきたアドレスが入っているので、それを使ってsendtoすると応答を返せます。
rc = sendto(sd, bufptr, buflen, 0, (struct sockaddr *)&clientaddr, clientaddrlen);
http://publib.boulder.ibm.com/html/as400/v4r5/ic2962/info/RZAB6UDPSXMP.HTM
片方向通信の例はたくさんあるんですけどね。

コードのシンプルさ

コードをシンプルに保つということは、余計な操作を削ぎ落とすことと同時に、1つの文章により多くの意味を持たせる、やらせるってことだと思う。要するにコピペはするなってことだけど。
また、大局的に見て必要な操作をまとめたり、戦略的な見方もある気がする。
それと、プログラマの力量によってもコードの見方が違ってくると思う。普通の文章と同じ側面がある。
細かなことまで書かないと、やってくれないとか、面倒なことでも文句も言わずやってくれるとか、コンピュータならではの側面もあるけれど。
人間にとってのわかりやすさってことかな。