VMware Playerユーザー限定 — 予想外にディスク領域が不足した時にチェックすべき点(Windowsホストの仮想環境でゲストOSとファイルコピーした際の一時領域)

VMware Playerで、Manjaro Linux XfceからManjaro Linux KDE Plasmaへ移行作業をした際、SSDの残りのディスク領域が30Gbyte以下になってしまい、警告が出た。具体的には、Xfceゲストのディスク領域内のファイルとフォルダを大量にコピーして、Windowsの適当なフォルダへopenVMtoolsの機能で貼り付けしていた途中に、エラーとなった。

SSDの空き領域が100Gbyte以上あったはずなので、ちょっとビックリした。「システム」の「ストレージ」で、ディスクのクリーンアップを行ったが、10Gbyte程度しか効果がなかった。ネットで検索すると、「VMware Player で仮想環境へファイルコピーした際の一時領域の場所」というトピックがあり、VMware Player でホストからゲストへファイルをコピーした際、一度ゲスト環境内(Winodowsホスト管理下)の一時領域にコピーされた後、目的のフォルダーへコピーされるという作業をするらしく、その際に一時的に保存された一時領域内のファイルはすぐには削除されないため、しばらく残ったままになるらしい。「大きいファイルをコピーしたときなどは急に仮想環境のディスク容量が減ってびっくりします。」とも書いてあった。まさに私のやっていた作業そのもので、そのトピックに書いてあった対処で解決することができた。

一時コピーに利用されるのは、Windowsの「C:\Users\<ユーザー名>\AppData\Local\Temp\vmware-<ユーザー名>\VMwareDnD」という、ちょっと特殊なフォルダの中で、乱数のようなフォルダが作られ、このフォルダ内に1回のコピー対象がまとめて保存される。なぜだか理由は分からないが、クリーンアップの対象にはならないらしい。過去にコピーした分も全て削除したら、さらに80Gbyte以上余裕ができた。VMwareをインストールして、WindowsホストとゲストOSの間で頻繁にファイルをコピーしている人は試してみた方がいい。

カテゴリー: VMware, パソコン | コメントする

デスクトップ用メモリ CFD DDR4 3200 PC4-25600 8Gbyte D4U3200CS-8G

旅行にも行けず、ゴールデンウィークの長すぎる退屈を紛らわすために、ドスパラのデスクトップPCのRAMを増設した。
Lightning AH5は8Gbyteのメモリだが、Steamの無料体験ゲームの動作環境が12Gbyteだったためだ。Amazonを検索すると、DDR4 3200の8Gbyteが三千円以内で買えることがわかり、衝動的に購入してしまった。

シー・エフ・デー販売 CFD販売 CFD Standard デスクトップ用 メモリ DDR4 3200 (PC4-25600) 8GB×1枚 288pin DIMM 相性保証 D4U3200CS-8G

パソコンの蓋を外して、メインボードの奥まったところにあるソケットへ慎重に差し込み、表と裏が良く分からなかったので、接続端子の形状を確認しながら挿し込んだ。標準のDDR4メモリと違うメーカーのものだが、PC4-25600の規格は同じなので動作するはずだ。差し込む時に、ソケットの留め金がなかなか嵌らず、力を籠めても駄目だった。壊しそうだったので、少し頭を冷やして、メモリの基盤をソケットへ正確に水平にして力を均等に押し込むようにしたら、カチっという音がして、あっけなく嵌った。力尽くで挿し込んでいたら壊していたかもしれない。

モニタやキーボードを接続して電源を入れると、問題なく起動した。PCのプロパティで見ると、ちゃんと16Gbyteで認識していた。Steamの体験版ゲームをインストールして、速くはないがそれなりに動作しているようだったが、グラフィックボードが物凄い呻りを上げて、熱を放射していた。正式版のゲームだと、グラフィックボードを高性能にしないときついかもしれない。それでも気分的にパソコンが高速になったように感じるので、良しとしよう。

カテゴリー: DIY/日曜大工, PCパーツ, ゲーム, パソコン | コメントする

OCNモバイルONEのSIMを解約した

五年以上利用してきたOCNモバイルONEのSIM契約を、解約した。

今まで利用してきたのはマクドナルドのWiFiのため(マクドナルドWiFiは一時間で一旦切断されて、15分経過しないとWiFiへ再接続できなかった)と、ガストのWiFiが月一回くらいでWiFi通信不調(ログインできない)になるためだった。

最近、ガストはなぜかずっとWiFiが不調な上に、電源コンセントが使える席が四席ほどに制限され、ノマドワーカーとビジネスマンの奪い合いで、私が入店してもその席が埋まっていると、すぐ外に出るしかなく、その上、市内にガストが二店舗あったのが、一店舗は潰れて別のレストランになって、もうガストは使わないことにした。COCOSとJoyfullもWiFi不調になることはあるが、合わせても、年に数回ある程度なので、その時だけ別の店へ移ればよく、そのために月々、千円近く払い続けるのは無駄金だ。

最初の購入の動機は、まだWiFiがファミレスで使えなかった時分であったことと、マクドナルドは一旦切断されて15分経過しないとWiFiへ再接続できなかったという理由だった。
現在のファミレスはどこでもWiFiが使えるようになって、ファミレスのWiFiが不調なのは一年にガストを除けば数回程度で、ほとんどガストとマクドナルドでしか利用することがなくなっていたが、最近、マクドナルドWiFiの抜け道を発見した。

WiFi設定の「ランダムなハードウェアアドレス」(=MACアドレス)を「毎日変更する」設定にして最初に接続し、一時間経過して切断されたら、今度は「ランダムなハードウェアアドレス」を「オフ」にして接続すると、別のWiFi機器として認識され、連続して接続できるようになった。元々、ネットワーク回路にMACアドレスという固定したアドレスが装備されているのだが、そのMACアドレスをプライバシー保護のため疑似的なMACアドレスを「ランダムに」生成してWiFiへ接続する機能が使えるようになっていた。つまりマクドナルドのWiFiはMACアドレスで機器を区別しているので、それをすり抜けることができる。そんなわけで、もうモバイルWiFiの必要性がなくなった。

解約はOCNのホームページから行うのだが、チェックを入れていく確認項目が多く、SMSの認証や解約通知のメールアドレスの入力など、少し面倒だった。
問題はモバイルルーターとクレードルとSIMの処理だ。SIMは郵送費負担でOCNへ送付することになっているが、返送しなくても罰則はないので、しばらく様子見することにした。モバイルルーターとクレードルは、ハードオフで受け付けてくれると思うが、しばらくは保持しておくことにした。

カテゴリー: 通信機器 | コメントする

ELECOM USB有線マウス M-XGL10U 握りの極み Lサイズ

家のノートパソコンで使っていたUSB有線マウスが壊れた。左クリックを一度押すと、ダブルクリックとなってしまう。
以前にもマウスが似たような壊れ方をしたことがあるので、機械的な摩耗による故障だろう。そのマウスはハードオフのジャンクで108円で購入したゲーミング用マウスで、大きめのサイズなので、手の平までキーボードのパームレストのようにマウスの上に置くことができて楽だった。同じように、手の平を休める大きめのマウスを探して、購入した。

ELECOM USB有線マウス M-XGL10U 握りの極み Lサイズ

5ボタンで機能割り当てのできるマウスみたいだが、不要な機能なので使うことはないだろう。実際に使ってみると、やはり大きめのマウスで手の平を休められるのは心地よい。出来るだけ長持ちしてくれるとありがたい。

カテゴリー: PCアクセサリ, パソコン | コメントする

BUFFALO NAS スマホ/タブレット/PC対応 ネットワークHDD LinkStation 1TB LS210D0101G

NASを購入した。家のパソコン間のファイル共有とかデータ移動に利用するためだ。パソコンでデータを移動する場合、共有フォルダを設定していても、別の部屋にあるパソコンの電源を入れに行かなければならず、少しの手間ではあるが、面倒臭かった。USBメモリがすぐ手元にあるわけでもなく、USB経由はコネクタへ抜き差しするのとコピー処理が遅いのが難点だ。
本当に欲しかったのはSynology NASキットだった。手元にある500GBの2.5inch SATA HDDを取り付けて利用しようと思っていたのだが、このNASケースは3.5inch専用のだった。

Synology NASキット 2ベイ DS220j/JP【ガイドブック付】 クアッドコアCPU 512MBメモリ搭載 ライトユーザー向け 国内正規代理店品 電話サポート対応品 DiskStation

新しい3.5inch HDDをわざわざ買うと無駄金になるし、NASキット自体が三万円近くするので、半額近く安くなる時期を待っていた。しかし、三年経過して全然値段が下がらないので、仕方なく、Amazonで一番値段の安かった、長持ちを期待しない経過措置として、バッファローのHDD付きの1TBのNASを購入した。

BUFFALO NAS スマホ/タブレット/PC対応 ネットワークHDD 1TB LS210D0101G 【エントリーモデル】 LinkStation

取り付けは簡単。ルーターへ接続して、電源を入れ、ルーターのセキュリティ設定でLinkStationのアクセスを許可したら、すぐWindowsからメディアサーバーとして認識された。NAS Navigater2という環境設定ツールをバッファローのサイトからダウンロードし、インストールし、ツールを起動するとLinkStationのアイコンをダブルクリックすると、何の躓きもなくファイルシステムを参照できた。家庭内でしか利用しない(しかも私一人だけ)ので、設定画面でshareフォルダーを公開フォルダーに設定し、アクセス制限なしにログイン認証なしにした。パソコンを起動したときに自動で共有フォルダを参照するように「ネットワークドライブの割り当て」でWindows側で、Zドライブに設定した。ここで気を付けるべきなのは、NASであるLinkStationが、デフォルトではDHCPでIPアドレスが可変なことだ。(固定IPで設定することも可能)だからマシン名で参照するように設定しなければならない。LinkStationのマシン名はデフォルトでは”LS210D75G”なので、そのままでもよいが、趣味で自分の好みの名前にした。”\\マシン名\share”(WordPressのエディタでは円マークが”\”に自動変換されてしまう)でエクスプローラーから参照できるになった。他のWindowsパソコンも同様に設定した。全て簡単に終わってしまった。
唯一気になったのは、近くに置くと、騒音というほどではないが、HDDのモーター音が少し気になる。コピーもギガビットLANとはいえ、SSDの速度に慣れた現在では早いとは言えない。機器情報では、HDDはTOSHIBA製で、ファイルシステムはxfsだった。

深夜には使わないので、スリープタイマーを設定することにした。設定条件は3つまで設定できるようだ。設定項目は「毎日」と「毎週」で、3つ共「毎週」を選択し、平日は午後5時に起動し、深夜の1時で電源オフする設定をした。その設定をしたとき、エラーとなったのだが、単純な勘違いで、深夜の一時は翌日なので、01時を指定すると当日の1時を指定したことになる。翌日の深夜1時は25時を選択する必要があった。土曜日は午後1時に起動して深夜1時(25時)で電源オフの設定。日曜日は朝8時から深夜1時までとした。祭日などで平日に使う場合は、LinkStation背面の電源スイッチを手動でOFF/ONして、電源を入れなければならないようだ。

その他、いろいろ機能がある。BitTorrentはネットワークファイル共有ソフトだが、何のために付属しているのかよく分からない。AFPはMacOS用のファイル共有機能のためのプロトコルだから不要。WEBアクセス機能はインターネット経由での外からのファイルアクセスだから必要ないし、公式サイトからツールを取得する必要があって、おそらくネームサーバーとかセキュリティとか面倒臭いと思われる。バックアップ機能にTime MachineというMacOS用の機能があるが不要。SSL認証も必要がないので、使うことはないだろう。

問題が発生したのはManjaro Linuxだった。Thunarで”smb://LinkStationのマシン名/共有フォルダ名”でアクセスしようとしたが、匿名でログインしようとすると、エラーとなってしまう。LinkStation側ではアクセス制限を設定せず、誰でもパスワードなしでフルアクセスできるようになっているし、実際、Windows10ではログイン設定も必要なく、簡単に接続できている。LinkStation側ではアクセス用のログインユーザーを設定していないが、試しにguestでログインしようとしたが、やはりエラーとなる。非常に不思議。
以前からWindowsネットワークへのアクセスエラーがあったが、Manjaro LinuxはSamba関連の不具合を抱えたままのように思える。Manjaro LinuxのつぎはぎOSプログラムのバックアップが主目的であったが、突破口を思い付かないので、保留としておく。

(2023/5/13 追記) パソコンのメモリを16Gbyteへ増やしたので、Linux Mint 21.1 CinnamonをVMwareへインストールして遊んでいた。ふと思いついて、Linux Mintの標準ファイルマネージャ―のNemoから「ローケーションパス形式の切替」で”smb://LinkStationのマシン名/共有フォルダ名”を実行したら、匿名ログインでLinkStationの共有フォルダへアクセスでき、ファイル参照ができた。やはりManjaro Linuxのファイルマネージャ―のThunarにはバグがあるのだろう。いつか修正されればよいが、、、、と、ここでまた思いついて、Manjaro LinuxのKDE Plasmaエディションを試すことにした。メモリが増えたのでXfceでなくても使えるようになったからだ。KDEの標準ファイルマネージャーはdolphinで、最初は使い方がよく分からなかったが、あっさりLinkStationの共有フォルダにアクセスできた。Manjaro + Xfceの組み合わせか、Manjaro + Thunarの組み合わせに問題があるのだろう。ただメモリの少ないVH-AD3S proではKDEが使えないので、私の問題の解決にはならないのは残念だ。

(2023/5/26 追記の追記) VH-AD3S proの液晶ユニットが折り畳めなくなって、液晶ユニットを取り外し、無線LANアンテナとmicroHDMIケーブルでキーボード型パソコンに改装したついでに、SSDのManjaro Linux Xfceを最新版をダウンロードして、USBメモリからクリーンインストールしたら、ThunarからLinkStationへ接続することができた。最新版でバグが修正されたのか、アップデートの不良の問題だったのかは不明だが、解決できたので良しとする。
(、、、の追記)なぜか翌日、接続しなくなった。不思議???

カテゴリー: PC周辺機器, パソコン | コメントする

マルチタスクへの長い道程 その2 — つぎはぎOS

タイマー機能について誤解していたようだ。T-Kernelではシステムタイマーと物理タイマーとで、別になっていて、今まで作成したPITを利用したタイマー割込みはT-Kernel2.0/SMの物理タイマー機能に当たるようだ。
何が違うかと言うと、システムタイマーでは1985年1月1日(GMT)からのミリ秒とマイクロ秒を保持しなければならず、PC-ATではCMOSのRTC(Real-Time Clock)でシステム時刻を持ってカレンダー情報を提供している機能に当たるようだ。PITをそのままシステムタイマーとして使うことも考えたが、どちらにしても、時分年月日の情報を取得するためにRTCへアクセスするのだし、RTCはIRQ8の周期的な割込みを発生させることもでき、CMOSのRTCを使う方が便利だと思った。

という訳で、今までのPITでの割込み機能は物理タイマー機能のAPIへと修正することにした。その前に、改めてCMOSへのアクセスと、RTCからのIRQ8の割り込みハンドラを作成しなければならなかったが、もう慣れたもので、T_Kernel2.0仕様ではミリ秒とマイクロ秒単位のカウンターを持つようになっているが、手抜きでマイクロ秒単位のシステムコールは実装せず、RTCは10msec周期でIRQ8割り込みを発生させるように作成した。
RTCはなぜかCMOS(というRAM領域)へ年、月、日、曜日、時、分、秒までしか書き込んでくれない。しかも、通常のバイナリ数値ではなく、BCD表現でCMOSの内部RAMへ値を書き込んでいる。最初はそれに気づかず、バイナリだと思ってプログラミングして、どハマリした。英語のサイトでは、レジスタBを最初に読んで、モードを確認するよう記述があった。レジスタBの値を見て、BCD表現なのか、12時間表現なのか、米国サマータイムが有効なのかを判定するよう推奨していた。

Linuxでは、起動時にRTCの値を読むだけで、後はソフトウェアカウンターで加算しているらしい。私もRTCを読んでミリ秒へ変換し、IRQ8割り込みごとにカウントアップする方法を取ることにしていた。しかし、最初の一回だけIRQ8が発生するだけで、周期的に割込みが起こらなかった。サンプルプログラムも見ながら設定を確認したが、何をやっても駄目だった。
英語サイトによると、RTCからの割り込みはPIC回路との関連で相性が悪いらしく、割込みが”undefined state”となり、EOIができなくなるなどのトラブルがあるらしい。”IRQ danger”などという物騒な?短いチャプターで忠告までしていた。RTCは優先度が高いはずだが、IRQ8などというスレーブPICに接続されていることも関係しているのかもしれない。なぜ低い優先度の割り込みなのか理由は分からないが、PC-ATのつぎはぎの発展の歴史的経緯があるのかもしれない。
それで方針を変更し、RTCからは起動時に時刻を取得して初期値として保存し、PITのタイマーを使って10msec毎にカウントアップすることにした。PC-ATのPITで割込み使えるのはTimer0だけなので、結局、T-Kernel2.0/SMの物理タイマー機能は実装を止めることにした。

Linuxは1970年1月1日 00:00:00(UTC)からのミリ秒(設定によりマイクロ秒の高精度タイマーが使える)、Windowsは19701970年1月1日 00:00:00(ローカルタイム)からのミリ秒のカウント値持つらしいが、T-Kernel2.0では1985年1月1日(GMT)からのカウント値となっていた。理由は不明。拡張でマイクロ秒のカウンターも持つことになっている。困ったのは、「うるう年」と「うるう秒」の計算で、いろいろ調べて、うるう秒は諦め、うるう年の処理を適当に作成した。どうせ正確な時刻にはならないし、私個人では正確な検証はできない。将来インターネットに接続できるようになったら(いつのことやら)、NTPで時刻を補正する機能を実現する時に、また考えようと思う。グレゴリオ暦では、うるう年は以下のような条件を満たす年らしい。1985年以降で何回あるかをカウントして、日数を足すことにした。(2023年現在は9回。来年がうるう年)

・西暦が4で割り切れる年をうるう年とする (ユリウス暦と同じ)
・しかし、上記のうち、西暦が100で割り切れる年はうるう年としない
・だがしかし、上記のうち、西暦が400で割り切れる年はうるう年とする

うるう秒は、三年に一度、加算か減算するのだが、これは国際機関が原子時計との誤差を見ながら、いつ変更するかを決めているので、プログラムで計算することはできない。NTPで通知された時に変更するしか方法がない。

ミリ秒単位の時刻までは正確に検証できないので、2023/2/23という日付までの算出値が正しいかどうかを確認し、午後の15時までの時間だけのミリ秒を電卓の値と同じであることを確認した。うるう年も含めて、そこまでは何とか正しい値となっていた。
また、Timer-0によるカウントアップも行われ、T-Kernel2.0のtk_ref_tim()のシステムコールで、日時のミリ秒と合算した戻り値を返しているらしいことを確認した。(戻り値が正確なミリ秒の時刻かどうかは確認のしようがない)RTC回路への時刻補正は現時点では実装しなかったため、tk_set_tim()はTimer-0のソフトウェアカウンター値を訂正して、偽装した。GMTのままだと日本時間と9時間ずれるので、日本時間へのローカルタイムの変換は、NTPを実装する時に改めて実装し直そうと思う。

RTC/CMOSのIRQ8でのソフトウェアタイマーカウンターの実装は諦めたが、あるサイトの記事によると、RTCにも歴史的な発展の過程でいくつも種類があるらしく、CPU ID命令でTCSの種類を判定して、CPUの種類でRTCの種類を判定して処理を変えるらしい。サイト検索では、CPUの種類を調べるのはウィルスが使う基本テクニックらしく、それに関連したコンピューターウィルスの記事が多かった。面倒臭いので、深入りしないことにする。

カテゴリー: Linux, VirtualBox, つぎはぎOS | コメントする

マルチタスクへの長い道程 その1 — つぎはぎOS

T-Kernel2.0そのものの移植は断念して、includeファイルの定数やシステムコールのextern宣言などのヘッダファイルだけをコピーして、仕様書を読みながら自分なりに「つぎはぎ」に少しずつ構築していくことにした。

割り込み管理機能関係を、まず実装した。割り込みができなければ、マルチタスクは実現できないからだ。割込み関連のシステムコール(割り込みハンドラはタスク独立部、とか仕様書に書いてあった)tk_def_int()、tk_ret_int()、EI()、DI()などの簡単なシステムコールを実装した。T-Kernel/SMにも割り込みコントローラー用のAPI機能があり、自作したプログラムを流用できそうだったので、それも実装した。これでTimer割り込みだけでも動作すれば、ラウンドロビンのマルチタスクのタスクスイッチングを実現できるのではないかと思った。プリエンプティブでないのでリアルタイム性はない。それで、NTR、、、、ではなく、NRT(Non-Real-Time)-OS(仮称)とでも呼ぶことにしようか、、、、

T-Kernel2.0の割り込みマスク関係のシステムコールの仕様では、変更前の割込みフラグの状態を変数へ保持するようになっている。多重割込みへの対応のためか?必要なのだろうか?理由は不明?それで、80386の割り込みフラグはどこにあるかというと、EFLAGSレジスタにあった。pushfdという、EFLAGSをスタックへ書き込むアセンブラ命令があるのを初めて知った。これを使って、フラグレジスタの値を取得することができる。しかし、アセンブルでエラーになった。16bit命令のはずのpushfはOKだった。調べてみると、pushfとpushfdは、どちらも0x9cという命令コードが同じで、実際に実行する時のCPUモードで動きが違うようになるらしい。だから、gasは区別せず、同じものとしてコードを作成するようだ。いいのか?ちょっと不安。
試行錯誤でブートモニターのサブルーチンをT-Kernel用へ修正をしていて、PIC操作の自作ルーチンにバグを見つけた。T-Kernel2.0の割込みコントローラー操作のAPI仕様では、タイマー割込みやキーボード割込みなどを一つずつ割込み許可、禁止の制御をするようになっているが、私はなぜだかPICコマンドのOCW3コマンドで、割込みマスクの現在の状態を保持するIMRレジスタを読み出しするのだと思っていて、steploaderやboot_monitorは、PIC初期化の時に数日試してもOCW3コマンドでIMRが読み出しできなかったので、初期化で一度に全ての割り込みマスク設定をして、個別での変更はできないのだと諦めていた。実際はICW1–>ICW4で初期化した後に、OCW1の読み出しで、いつでもIMRを読み出しできるらしい。マスク設定値を書き込みすることしかできないと思い込んでいた(マスクする時は同じレジスタへ値を書き込む)。
できるのが当たり前と言えば当たり前で、参考文献の解説記事の簡便なサンプルプログラムでは、一度にPICのマスクを設定する仕方は掲載されていたが、現在のマスク値を読みだして、当該ビットだけを変更して再設定するようにはなってなかったため、読み出しできないものと思い込んだようだ。自作OSを始めた初期の頃で、まだ回路関係の知識がない時期に作成した部分なので、こんな初歩的な思い違いをしていた。修正して、当該IRQだけ割り込み許可、禁止できることを確認できた。
少し話が違うが、PICにはIRRとISRというレジスタがあり、IRRは割り込みを「要求」している割り込み番号の情報を保持し、ISRは割り込み「処理」を受け付けた割り込み番号のビットを保持する。割り込みが複数発生して、待ち(CPUへの要求)状態になっている割り込み番号のIRRの各ビットがオンになり、割り込み要求が受け付けられて、割り込みハンドラが起動されると、割り込み処理中ということでIRRのビットがオフになり、ISRの割り込み番号のビットがオンになる。つまり、割り込みハンドラは自分の割り込み番号のIRRは参照できず、他の割り込みの要求状態だけ参照することができるということで、何に使うのかよくわからない。これも多重割り込みのためか?割り込みを禁止して、ポーリングする時に使うのか?とりあえず、T-Kernel2.0/SMにCheckInt()というAPIがあり、今後利用する場面があるかもしれないので、ついでに実装しておいた。

キーボード割り込みも自作のものを流用したが、どうしても割り込みハンドラが起動しない。それで思い出したのが、キーボードは入力回路上、マウスと一体になっていて、スレーブPICのマウス割り込みにも接続していることだ。マスターPICのスレーブPICとカスケード接続しているIRQ2の割り込みを許可したら、あっさりキーボード割り込みが起動できた。もう数か月前のことで、うっかり忘れていた。

T-Kernelには割り込みハンドラの高級言語対応ルーチンの機能を持っていて、一体どうやって実現しようか何日も悩んだ。
割り込みが発生して、ハンドラが動き出したらすぐ現在の、タスク実行していた時のレジスタ情報を退避し、終了前に同じ状態へ復帰しなければならない。そこはアセンブラが必要だ。しかし、T-Kernel仕様では割り込みハンドラはiret命令で終了してはならないことになっている。これは割り込みハンドラ内でタスク起動のシステムコールを実行した場合、タスク切り替えをしなければならず、割り込み発生時のタスクには戻らない可能性があるからだ。つまり、メモリの何処かへ退避したレジスタ情報をタスクディスパッチャーへ渡して、そこでタスクの実行中情報として保存してから、新たに実行するタスクのレジスタ情報をCPUへ設定しなければならない。
結論として、80386では高級言語対応ルーチンは実現が難しい、不可能ではないが、効率が悪すぎる、ということが分かって、断念した。理由は、タスク独立部である割り込みハンドラはIDTを利用するプロテクトモードでは、起動されても自分の割り込みベクタ番号を知ることができないからだ。つまり、高級言語対応ルーチンのアセンブラからどのC言語処理関数を実行するべきか判断できない。割り込みベクタごとに関数名を決め打ちにしてしまい、システムコールがなくてもリンクで自動的に結合できるが、最大255個の個別の割り込みハンドラを用意しなければならない。ARM-CPU用のサンプルプログラムでは、ハンドラ起動時のプログラムカウンタから割り込みベクタテーブルの先頭アドレスを引いて、4で割ることでベクタ番号を算出していた。おそらく8086モードのような単純な構造のベクタテーブルなのだろう。IDTはディスクリプタの内部に割り込みハンドラのアドレスを自由に書き込めるので、その方法は使えない。やるとしたら、アセンブラ部分を含めてC言語で丸ごと割り込みサブルーチンを作成するしかない。調べた限りでは、”_attribute__(interrupt)”のような指定をして、インラインアセンブラでレジスタ退避や復帰、tk_ret_int()の実行などを記述しなければならず、そうなると、もはや通常の関数ではないので、TA_ASM指定で登録することになり、せっかくの高級言語対応ルーチンが無意味になる。
割り込みはできるだけ処理を短くしなければならないのだから、アセンブラで記述するメリットはあるし、上記のようにC言語で記述することが生産性に寄与することがないのならば、少なくとも80386の仕様では、できないことはないが効率的ではない、と考えられる。そういうわけで、NTR-OS・・・・じゃなかった、、、NRT-OSでは高級言語対応ルーチンは実装しないことにした。(それとも何か解決策があるのだろうか?全く思いつかない)

T-Kernel2.0/SMのシステムメモリ管理機能のシステムコールを手抜きで実装した。VirtualBoxのRAMは1Gbyteに設定しているので、空き領域が数百Mbyteあるので、払い出しの機能だけで、解放や再配置、再利用はしない(Freeの時、何もしない)ことにした。払い出し用のメモリポインタだけインクリメントで管理し、領域を使い切ったらメモリ不足としてエラーを返す。当面、使い切る可能性はないので、手を抜けるところは抜いて、NRT-OSの機能を増やすことに専念しようと思う。

未だにタスクスケジューリングやタスクディスパッチへ辿り着けないが、長い道程を少しずつ歩いていこうと思う。

カテゴリー: Linux, VirtualBox, つぎはぎOS | コメントする

小説 サラゴサ手稿 岩波文庫

ポーランドの大貴族が書いた長編小説。今までポーランドの作品は読んだことがなかったので、Amazonのお勧めに出てきたものを購入した。次から次へと、話が横滑りしていき、しかも奇想天外なエピソード(時代的に宗教関連とスペインやイスラムの風俗に関するものが多い)が連続して、宗教関連はちょっと辟易するが、慣れれば、ラノベ的な異世界魔法世界のような感覚で面白くなった。

— 小説 サラゴサ首肯 上・中・下 岩波文庫

三百ページ以上の三分冊で、一向に話が終息する様子がなく、登場人物も増えて行って、途中で誰が何をしているのか混乱するのは、ガルシア・マルケスの「百年の孤独」みたいで、ある意味、時代を先取りしたような先駆的な要素もある。
ずっと無名で一部の知識人にしか知られてなかったそうで、その面白さは、当時の有名作家の何人かがエピソードを丸ごとパクって自分の作品として発表したというほどだ。こんな結末になるとは、読んでいるうちには予想もできなかったが、ラスト近くで話が次第に収束していくと、読み終わるのが寂しいような気持ちになった。長編小説へ気長に付き合うことのできる人へお薦めしたい。

カテゴリー: 書籍 | コメントする

システムメモリマップ取得、ページング、マルチタスク — つぎはぎOSの方針

とりあえず、「つぎはぎOS」はページングで仮想記憶を実現した上で、マルチタスクOSを移植することにした。

以前挫折したページングに再度挑戦しようとして調べていたら、リアルモードのステップローダーで、ACPI仕様の拡張BIOSでシステムメモリマップを取得する必要があることが分かった。その理由は、i686のRAMは最大4G-byteなのだが、その全てが使えるわけではないからだ。ハードウェアから作成するような組み込みシステムだと、固定情報として内部に持てばよいが、パソコンは実際のRAMのサイズは各マシンで個別だし、BIOS領域やDMA領域、VRAM領域があって、そこは使えない。そういった個別のマシン情報をBIOSから取得してテーブルマップのようなものを内部で作成する必要がある。動的メモリ割り当てのmalloc()とかも、そういった情報を基にRAMの領域を割り当てているらしい。拡張BIOS機能の0xE820のINT 0x15というシステムメモリマップ取得で、ループで情報を読み出し、BOOT_INFOにそのまま格納して、ステップローダーからブートモニターへ渡すようにした。実際のシステムメモリマップ生成と参照は、ブートモニターの初期化処理で行った。新しくコマンドを作成し、BOOT_INFOの内容を画面へ表示させるようにした。システムメモリマップのエントリー情報は20バイトのサイズだったので、VirtualBoxのACPIは3.0より前の仕様のようだ。これで実メモリのどこを使ってよいか、利用可能なRAMサイズがどれくらいかが明確になった。
余談だが、Windows用のVirtualBoxは利用しない方が良い。というのは、テストのためにWindows10へVirtualBoxをインストールしたら、VMwareのネットワーク機能と競合して、VMwareの動作がおかしくなった。アンインストールも簡単ではない、ネットで検索すれば分かるが、レジストリや隠しファイルのようなものがそこかしこに残っていて、削除が面倒だ。Oracleがわざとやっているのか、フリーソフトのため手が回らないかのどちらかだろう。

このシステムメモリマップは、malloc()などの動的メモリ管理にも必要な情報であり、ページングのPDE/PTEの作成でも、この情報を基に物理アドレスの上位10bitと続きの中位10bitを設定することになる。下位12bitは実行プログラムでのオフセットを使ってアクセスするらしい。32bitモードでの仮想メモリは4Gbyteのリニアアドレスなのだが、実メモリは1Gbyteしかなかったりすることは普通にあるわけで、実メモリと仮想メモリの対応付けをするテーブル情報をPDE/PTEで持つわけだ。仮想メモリのどこに実メモリを割り付けるか、スワップするのかという設定もこのテーブル情報で行う。
はっきり言って、ディスクへのスワップ機能がないなら、実メモリをセグメント分割してアプリケーションへ割り当てた方が簡単だが、将来的な拡張を考えて、ページングを実装することにした。実メモリを割り付けない領域にアクセスしたら、ページフォールトが発生することになる。常識的に考えれば、OSのプログラムをディスクへスワップさせてはならないのだから、スワップする領域はアプリケーションに割り当てることになる。現状、ディスクへのスワップ機能を実装しないので、実メモリ=仮想メモリという対応付けとなる。だから、仮想メモリ4GBのどの領域をOSが使って、アプリケーションにどの領域を割り当てるかという計画的な配分を考えなければならない。
ちょっと頭を悩ませたのが、PDEとPTEのデータ形式だ。資料では4-byteのフラグビットとアドレスの簡便な形式なのだが、メモリ上に作成しなければなない。知っての通り、x86はリトルエンディアンで、メモリ上にもリトルエンディアンで作成しなければならないのか、ビッグエンディアンで作成しなければならないのか、資料では0-bitから31-bitまでの意味付けしか書いてなくて迷った。結論から言うと、リトルエンディアン形式でメモリ上に作成するのが正解だった。そういうものだと受け入れるしかないのだろうが、自分は生理的にビッグエンディアンの方が精神衛生上、好ましい。

ページング機能を実装して思ったのは、ディスクへのスワップ機能がなければ、不要な機能だということだ。仮想メモリは、OSやタスク、プロセスを仮想的なメモリ配置へ再編するために、OSのアドレッシングが物理アドレスと違うため、リンクファイルでアドレス設定を工夫しなければならなくなる。全体的にシステムが複雑化して、デバッグが難しくなるというデメリットが大きい。(あるサイトでは、にわたま問題—-鶏が先か、卵が先か—-と書いてあった。それくらい悩ましい問題らしい)
それに、PDEの設定にはU/S-bit(user-privilegeとsupervisor-privilege)があって、つまり、supervisor-privilegeのPDEで指定した4M-byte分のPTEの仮想メモリは、ユーザーアプリケーションでアクセスできない領域になるわけで、結局、PTEテーブル一つ分の4M-byte単位でOS領域とユーザーアプリケーション領域を考えて配置することになり、柔軟性が全くない。それなら実メモリをGDT/LDTでセグメントで配分する方が簡単に思える。PTE毎にもU/S-bitはあるのだが、PDEレベルで設定された時は無視されるのだろうか?それなら、PDEにU/S-bitは必要ない。整合性を考えると不思議な仕様だ。それとも私の理解不足か。
ディスクへのスワップでメモリ不足を気にしなくても良いなら、その見返りはあるかもしれないが、HDDなどのディスク装置へのスワップは遅すぎて、RAMを増設した方が、ずっと効率的で費用対効果が高い。SSDの速度ならスワップも気にならないのだが、SSDでないなら、実記憶のまま、注意深く自分でメモリ配置をした方が、解りやすくて処理速度も早くて、絶対的に良い(と思う)。今回、BIOSで取得したシステムメモリマップを見ても、BIOSの利用領域などがあって、自由に使えるメモリ領域は途中で分断されていて、リニアに使えない。だから、仮想メモリに物理マップをマッピングする時も、OSやタスクでアクセスできない領域を避けるように考慮してマッピングする必要があり、それなら実メモリのまま、使えない領域を避ければ良いだけで、何のために仮想メモリという機能があるのか、どんな利便性があるのか分からなくなる。今回は勉強と将来の拡張(スワップ機能の実装)のために、ページングだけ実装して、見かけ上、今までと違和感なく動作させることができた。

マルチタスクには、T-Kernel2.0を採用することにした。理由はフリーで、日本語ドキュメントがきちんと整備されていること、ミドルウェアでTCP/IPのモジュールやFatFsと同程度のファイルシステムのモジュールが、フリーで提供されていることが理由だ。
詳しいことは分からないが、μT-Kernel仕様というのが、IEEEで採用され、国際標準になっていることも考慮した。Linuxは普通に動いて、皆が使っているし、自分で何かしようにも英語情報ばかりでは、自分でできることはほとんどない。T-KernelはARM CPUをターゲットにしているので、ハードウェア関連の初期化関数などを用意すれば、使えるのではないかと思っていた、、、、

しかし、その考えは甘かった。おそらく東京大学の頭のいい人が作成したのだろうが、スパゲッティプログラムではないが、システム合理的に最高性能を出すために最適化されているために、普通の人間が理解するには、既に組込みシステムやマルチタスクの経験豊富な人であれば別だが、余りにも複雑怪奇すぎて、勉強用の教材には向かない。FatFsを移植する時は、自作すべき関数の名称や機能が明確になっていて、何をしていいのか分からないということはなかった。改めてFatFsの出来の良さが分かった。
T-Kernel2.0は、特にMakefileの構造が複雑で、Perlスクリプトまで使った超絶技巧を用いてmakeしている。私はOSを勉強して移植したいだけであって、makeやPerlの超難度テクニックの習得を前提とされると、肝心のOSの内容にまで辿り着くことができない。頭のいい人の罪のない欠点だが、自分が理解できることは、普通の頭しか持たない人間でも同じように理解できるのだという単純な思い込みがあると思う。こんな複雑だと、全体構造をある程度は理解できないと、移植して再利用などできはしない。しばらくは解析をしようとおもうが、別のマルチタスクOSを探すことになるかもしれない。

(2023/2/4 追記)T-Kernel2.0のソースを解析していくと、T-Kernel2.0はARMコアの機能と仕様に強く依存していて、また、市場に出回っていない特殊なボード仕様にも依存していて、移植性がなかった。一応、ソースプログラム内でハードウェア依存部とかを切り分けてはいるが、プログラムのロジック全体が、ARM独自のアセンブラ命令や機能でないと実現できないプログラミング(至るところにARMのインラインアセンブラが埋め込まれていた)になっており、他のCPUに移植する場合、ARMのアセンブラや機能を把握できてないと移植作業もできない、、、、、というか、教材にもならないし、実用性もないOSだと分かった。
MakefileやPerlスクリプトも複雑で、自分の開発環境用に修正するのも容易ではない。FatFsは移植部分をdiskio.cというファイルで基本ロジックと機能の外形を提供していて、そこだけ理解してしまうと、実質的に数時間で移植できた。
μT-Kernelのソースも見てみたが、T-Kernel2.0と作りが同じで、ARM依存が強く、移植できそうにない。実際、STM32とかルネサスとかARM系(?)の4種類の開発環境と移植例しかなく、FreeRTOSのようにx86を含めた数十種類もの移植例はない。宣伝用のデモにでもVMwareなどの仮想マシン環境上で動作するサンプルを提供しても良さそうなものだが、開発元であっても、それが容易ではないくらい移植が難しいのだろう。
FreeRTOSは英語が基本だし、Amazonに買収されていて、情報を検索すると強制的にAWS関係の広告へ誘導されてしまう。つぎはぎOSの拡張のためにはマルチタスク化は避けて通れないが、他に適当なOSSが見つからない。ラウンドロビン方式でのリアルタイム性のない簡単なマルチタスクだけ自作してみるか、、、、、困った、、、、、

カテゴリー: Linux, VirtualBox, つぎはぎOS, 自作OS | コメントする

自作OS — ソースファイルの整理、ライブラリ作成、Timer機能の追加、、、そして、つぎはぎOSの道へ

ステップローダーの不要になった機能を削除してスリム化し、ステップローダーとブートモニターで共通に使う関数をcommonディレクトリへ集約した。今回、i686-elf-arというライブラリ作成用のツールがあることを初めて知り、自作のmemcpy()などの汎用関数をライブラリ化して、common/lib/へlibstring.aとして作成した。静的ライブラリをつくるため、rcsというオプションを意味も分からずサイトの情報通りに付けて作成したが、コンパイルとリンクもできて、VirtualBoxで動作したからうまくいっているのだと思う。FatFsなどの<string.h>参照のために、pseude_string.hへlnコマンドでファイルリンクを設定した。
これから肥大化していくであろう開発に備えて、Makefileを含めて全体の整理を行った。commonディレクトリへ移動したインクルードファイルをMakefileのi686-elf-gccのオプションで-I指定、ライブラリはオプションの「最後の位置」で-Lと-lの指定で参照するように変更した。FatFsを共通化することも考えたが、ffconf.hのリードオンリー構成とリード/ライト構成のオブジェクトサイズの違いがあるし、今後FatFsがバージョンアップしても、安定して動いているなら旧バージョンのままでよいし、新しくビルドするモジュールにだけそれぞれリンクする方が賢明だと思った。ステップローダーの自作ソースは3ファイルだけになり、ロードモジュールはFatFs(リードオンリー構成)を含めて16.2K-byteに収まった。ブートモニターの自作分は6ファイルで現在40.6K-byte(リード/ライト構成のFatFsを含む)となった。普通の開発だとstdxxxなどのシステム共通ライブラリの更新はしないものだが、自作のものなので、しょっちゅう思い付いて修正や追加を行っていて、そんな時のcommonを含めたmakeの依存関係の設定が私にはよく理解できておらず、一部の再コンパイル漏れがでたりして、結局make cleanでオブジェクトを削除してから全部をmakeしなおすことが多い。どこかに頭のいいMakefileのサンプルがないだろうか、、、、、

関係ないかもしれないが、ステップローダーでリードオンリー構成のFatFsをできるだけ小さくしようとffconf.hを設定したら、以下のような警告が出るようになった。
ff.c:809:13: warning: ‘put_utf’ defined but not used [-Wunused-function]809 | static UINT put_utf ( /* Returns number of encoding units written (0:buffer overflow or wrong encoding) */
警告なので、リンクと実行に何の影響もないのだが、put_utfという変数名からすると、UNICODE関連のような気もする。宣言しても使われてない(defined but not used)ということなので、コメントアウトしてしまおうかと思ったが、ff.cのソースを見ると、LNF関連定義の#ifdefでコードの生成が複雑に絡み合っているみたいだったので、そのままにしておいた。

ずっと後回しにしていたが、ブートモニターにTimer割り込みを追加した。PITの初期化は簡単なので、割込み間隔は取り敢えず10msecとして、すぐに動くようになった。シングルタスクなので、単純にウェイトするためにしか使えないが、OSにタイマー機能は必要だ。

思いがけず、ブートローダーの起動に成功して、その感動でここまで突っ走ってきたが、プログラミングと関係ない仕事をしながらでは、可処分自由時間の確保が難しい。今はもう満足感もあるが、疲れたというのが正直なところ。FatFsの作者の方に感謝するとともに、すごい人の作った、すごいプログラムを使わせてもらう方針へ転換することにした。
今はOSSが盛んな時代でもあるし、既にオープンソースがあるものについて、自己満足で作成することに疑問を持つようになった。やるのなら、それらを使った新しいことをやりたい。これからもOSは作り続けるが、オープンソースを利用し、謂わば「つぎはぎOS」として、自分なりのアイディアを盛り込んだOSを少しずつ構築しようと思う。

カテゴリー: Linux, VirtualBox, 自作OS | コメントする