CPUの温度取得に関するメモ5

Web Service から OpenLibSys を呼び出すと、InitializeOls(); を呼ぶところでOLS_DLL_DRIVER_NOT_FOUND エラーになってしまう。

この原因は、WinRing0.sys を Visual Studio のデバッグ環境で、Web Service から呼び出すときに、OlsDll.cpp の Initialize()関数の中で、ドライバーを呼び出すときのパスが、 “C:\Program Files\Common Files\Microsoft Shared\DevServer\9.0\WinRing0.sys” になってしまうためであることが判明した。暫定で、その場所に WinRing0.sys をコピーして先に進んでみる。

次に、Web Service をローカルの IIS に発行してみると、ドライバーを呼び出すときのパスが今度は、 “c:\windows\system32\inetsrv\WinRing0.sys” になってしまい、ドライバーを探しに行ってエラーになってしまう。そこに、WinRing0.sys をコピーすることで、Web Service から OpenLibSys を呼び出せるようになった。

image 

はまったメモ:

WinRing0が LoadLibrary で呼ばれていて、Web Service からデバッグできないので、ビルド環境を作って、メッセージを埋め込んでデバッグするしかなかった。もう少しいい方法があるのかな・・・

そこで、WinRin0\dll をビルドしてたら、DEF ファイルが外出しになっていて、リンカオプションに def ファイルを追加する必要があった。

/DEF:"C:\Users\uchukamen\Desktop\WinRing0_1_3_0\source\dll\OlsApi.def"

そこで、fprintf (stderr でと思ったが、出力先がないので、エラーを出せない。イベントログも面倒なので、とりあえず、ファイルにエラーメッセージを書き出した。

やっぱりワナがあった w

ここまでくれば、あとは OpenLibSys も気にせず、管理者モードに移行する必要もなく、簡単にアプリができる。ただ、OpenLibSys 強力な分、セキュリティ上注意が必要。

ASP.NET で偽装する

温度計を Web Service にしてなんてことを考えて、Administrator 権限が必要な OpenLibSys を Web Service 化するには、偽装しなければならない。その他、きっとはまるだろうと思いつつ、やっぱり引っかかりますね。

Web.config で

<configuration>
  <system.web>
    <identity impersonate="true" userName="ホスト名\Administrator" password="パスワード" />
   …

と追加して、実行すると、

‘/’ アプリケーションでサーバー エラーが発生しました。 構成にエラーがあります。

説明: この要求を処理するために必要な構成ファイルの処理中にエラーが発生しました。以下のエラーの詳細を確認し、構成ファイルに変更を加えてください。
パーサー エラー メッセージ: 構成ファイルで指定された資格情報から Windows ユーザー トークンを作成できません。オペレーティング システム ‘ログオン失敗: アカウントは現在無効に設定されています。
‘ のエラーです。

というエラーが発生。Vista では、Administrator アカウントが無効になっているので、

[管理ツール] → [ローカル セキュリティ ポリシー]

image

これを有効にしてみた。すると、このエラーは、無事解決。

しかし、InitializeOls(); を呼ぶところで引っかかっている。サービス側なので、デバッグが厄介だな・・・

この原因は、WinRing0.sys を Visual Studio のデバッグ環境で、Web Service から呼び出すときに、OlsDll.cpp の Initialize()関数の中で、ドライバーを呼び出すときにディレクトリが、 “C:\Program Files\Common Files\Microsoft Shared\DevServer\9.0\WinRing0.sys” になってしまい、OLS_DLL_DRIVER_NOT_FOUND エラーになってしまう。暫定で、その場所に WinRing0.sys をコピーして先に進んでみる。

次に、Web Service をローカルの IIS に発行してみると、こんどは “c:\windows\system32\inetsrv\WinRing0.sys” を探しに行ってエラーになる。そこに、WinRing0.sys をコピーすることで、Web Service から OpenLibSys を呼び出せるようになった。

あれ? Vista IIS 7 で Web Service が動かない・・・

温度計をWeb Serviceにしてしまおうかと思って、久々にWeb Service を作って、ローカルの Vista に発行してみたら、

「IIS 7.0 でホストされている Web サイトにアクセスすると、エラー メッセージ:"HTTP エラー 500.19-内部サーバー エラー"」 というエラーで Web Service が動かない。

http://support.microsoft.com/kb/942055/ja

に対処方法が書かれていたので、その通りにしてみたが症状は変わらず。

あれれ? ということで、いろいろ調べていたら、[コントロール パネル] → [プログラムと機能] → [Windows の機能を有効化または無効化] → [アプリケーション開発機能] の ASP.NET のチェックがされていなかった。

VISTA を入れて、Visual Studio 2008 を標準インストールしただけで特に何もしていないはずなので、標準インストールでは ASP.NETは ON にならないのかな?

image

このチェックを入れたら、無事動いた。

Windows Vista IIS で ASP.NET を動かすための設定は、

http://msdn.microsoft.com/ja-jp/library/aa964620.aspx

に書かれています。
エラーメッセージからサポートオンラインの情報を引いたのだけれど、その情報に惑わされてしまった。というわけで、またはまりそうなので、一応メモっておこう。

CPUの温度取得に関するメモ4

Intel® 64 and IA-32 Architectures Software Developer’s Manual によると、今使用中の ASUS P5LD2-V + Pentium 4 D では、MSR から CPU の温度が取れないことが判明した。

で、http://kariunten.homeip.net/programming/winring0.html

にマザーボードのI/Oコントローラからデータを取得する方法が載っていたので、OpenLibSys で試してみた。

ASUS P5LD2-Vのマニュアルを調べてみると、コントローラは W83627EHF だったので、そのマニュアル

http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_W83627EHG.pdf

を調べてみた。それによると、このチップには温度センサーが3つ搭載されている。ただし、マザーボード上で使用されているのは、CPUTIN Temperature、SYSTIN Temperature の2つのみで、AUXTIN Temperatureは使用されていない模様。

このコントローラーからデータを取得するには、IO ポートからデータを取得すればよい。

取得する方法は、0x295 ポートにレジスタを指定、0x296 ポートからデータを取得するという手順。

ただし、バンクが 0, 1, 2, 3, 4 とあり、0x50 以上のレジスターにアクセスするには、バンクを切り替える必要がある。バンクの切り替え方法は、0x4E ポートの下位3ビットで指定する。

CPUTIN (CPUの温度)は、

バンク1、0x50 レジスタにハイビット(温度 ℃)

バンク1、0x51 レジスタにロービット(温度 7ビット目が立っていれば +0.5℃)

となっているので、次のようなコードになる。

//=======================================
// CPUTIN Temperature
//=======================================
// バンク1
ols.WriteIoPortByte(0x295, 0x4E);
ols.WriteIoPortByte(0x296, 0x81);
// データ読出し(50h Bank1)
ols.WriteIoPortByte(0x295, 0x50);
hi = ols.ReadIoPortByte(0x296);

// バンク1
ols.WriteIoPortByte(0x295, 0x4E);
ols.WriteIoPortByte(0x296, 0x81);
// データ読出し(10h Bank1)
ols.WriteIoPortByte(0x295, 0x51);
lo = ols.ReadIoPortByte(0x296);

Console.WriteLine("CPUTIN Temperature Low : …." + lo.ToString("X") + "\r\n");
Console.WriteLine("CPUTIN Temperature High: …." + hi.ToString("X") + "\r\n");

float CPUTIN = hi + ((lo & 0x80) != 0 ? 0.5f : 0);

Console.WriteLine("CPUTIN Temperature: …." + CPUTIN.ToString() + "\r\n");

同様に、SYSTIN (マザーボードの温度)は、バンク0、0x27 レジスタなので、

//=======================================
// SYSTIN Temperature
//=======================================

// バンク0 を指定
ols.WriteIoPortByte(0x295, 0x4E);
ols.WriteIoPortByte(0x296, 0x81);
// データ読出し(27h Bank0)
ols.WriteIoPortByte(0x295, 0x27);
hi = ols.ReadIoPortByte(0x296);

Console.WriteLine ("SYSTIN Temperature: …." + hi.ToString() + "\r\n");

なお、SYSTINでは、0.5℃単位の測定はできない仕様になっている。

結果は次の通り。

[CPUTIN Temperature]
CPUTIN Temperature Low : ….80
CPUTIN Temperature High: ….21
CPUTIN Temperature: ….33.5

[SYSTIN Temperature]
SYSTIN Temperature: ….24

下は、ASUS のおまけアプリの Probe II のデータ

image

image

おおおおっ、ちゃんと取れるじゃないですか。OpenLibSys 偉大だ。

というか、Core2にアップしてしまえば、MSRで取れるので、こんなことしないですむんだけどなぁ・・・

というか、こんなハード固有の実装させないように頑張ってよ >> MS

というか、温度を気にしないといけないような CPU 勘弁してよ >> Intel, AMD

CPUの温度取得に関するメモ3

MSR(Model Specific Register) 0x19C Bits [22:16] で温度が取得できることは確認できたが、このセンサーの値は、Tjmax への相対値であることがマニュアルに書かれている。しかし、そのTjmaxの値をMSRから取得する方法がマニュアルに書かれていない。

いろいろ探していたらば、

http://software.intel.com/en-us/forums/deleted-posts/topic/51574/page/1/

で、MSR 0xEE で取得が可能なようだが、undocumented だそうだ。ちょっと古い資料なので、85度か100度と書かれている。

http://www.xtremesystems.org/forums/showthread.php?t=179044&page=23

によると、0xEE の bit:30 で、0=100 1=85 といううわさもある。

一方、Q6600 では、95度らしいという書き込みもある。

http://www.xtremesystems.org/forums/showthread.php?t=179044&page=27

Atom の場合、20度室温で 0x19C Bits [22:16] から88前後が返されているので、100度にしても合わない。

http://download.intel.com/design/processor/datashts/320032.pdf

によると、a catastrophic processor temperature of 125°C (maximum), or if the THERMTRIP#
signal is asserted, ということで、125度とすると、ちょうど37度となり、それらしい値になる。

MSR 0xEE で取得してみると、

000000EE: 00000000 02F90002

となり、仕様が分からない。

http://www.bugtrack.almico.com/view.php?id=1150

によると、

if bit 30 of MSR(0x00EE) is 1 then
  Tjmax=85
else
  Tjmax=100
endif
if CPUID=0x06F2 then Tjmax=100
if CPUID=0x06FB then Tjmax=100
if CPUID=0x10676 then Tjmax=Tjmax+5

こんな情報もある。

それにしても、xtremesystems.org のスレッドがものすごいことになっているのには、驚いた。

いずれにしても、インテルが仕様をはっきり書いていない(NDAを結ばないともらえないらしい)のが悪いということがよくわかった。

CPUの温度取得に関するメモ2

石坂さん、渋木さんに教えていただいたサイドバーガジェットを Windows 7 Beta on Atom N280で動かしてみました。こんな感じ。

image 

原理はデバイスドライバーで、Ring0のカーネルモードに移行して、そこでアセンブラでRDMSRにより、Model Specific Register を叩いて、直接モードスペシフィックレジスターからデータを読み取っていますね。そのためのライブラリがOpenLibSysから提供されている。なるほど、それなら早いはずだ。それにしても、OpenLibSysを作った人は偉いなぁ・・・とひとしきり感動しました。

なお、Vista on Pentium4 Dでは、温度が取得できない。orz。MSR的には、0x19C の 22:16 で同じ仕様に見えるんだけど、どこか細かいところで違うのかな・・・

image

なお、MSRは、文字通りモデル固有のレジスタであるため、プロセッサのモデルごとに仕様が異なっている。Intel のIntel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3Bによると、Core2、Atom、P4 and Xeon、Core Solor and Core Duo、Pentium M、P6、Pentiumとファミリーごとに説明が分かれています。

CPU 温度の取得に関するメモ

だんだんと暑い季節になってきて、Core2ではない Pentium 4 Dにとっては、辛い季節になってきました。室温が上がると、調子が悪くなるので、まじめに深刻な問題です。そこで、先日ケースにファンを増設したら、だいぶ効果があるようで、35度ぐらいでおちついていますが、CPUの温度のモニタリングしたいと思って、ちょっと調べてみました。

WMI の “Win32_TemperatureProbe” が一番まともな方法のようだが、現在のPC “ASUS P5LD2-V”, eee PC 1000 HE では、このインターフェースがサポートされていない模様。

いろいろ調べてみると、MSAcpi_ThermalZoneTemperature を使った記事がいくつかある

http://groups.google.co.jp/group/microsoft.public.win32.programmer.wmi/browse_thread/thread/d462fd6d271cc98d

が、そもそもそんな I/F の情報は MSDNに載っていない。もう使われていないということか?

さらに調べてみると、

http://kariunten.homeip.net/programming/winring0.html

にマザーボードのコントローラを直接操作する方法が載っていた。そうきますか~~~w。

と思って、そのコードを見てみると、

http://openlibsys.org/

で、Windowsからハードウェア(I/O port, MSR, PCI bus, and etc…)へのアクセスを可能とする WinRing0 が提供されているコードを利用している。

さらに、そこから

http://www.techpowerup.com/realtemp/

で、all Intel single Core, Dual Core, Quad Core and Core i7、さらにはNvidia のGPUの温度まで取得できるプロジェクトを発見。

試してみたが、Pentium 4 Dは、サポートされていない;;

image

eee PC 1000 HE の Atom N280だと? 1℃  !  すばらしい CPUだ w

image

ASUS からProbe II というモニターツールがあるから問題ないんだけどね。

image

温度、ファン回転数ぐらい WMI でちゃんと取れるようにしてよね。>> MS

それより、せめてCore2にしろよという突っ込みは却下。

eee PC 1000HE 届いて、速攻で Windows 7に化けた

注文していた eee PC 1000HE が今日の夕方届きました。

20090404 eeePC 002

PC DEPOT で 2GB メモリ、16GB SD カード付きで 47700円。

20090404 eeePC 003

意外と大きい。

バッテリーも9時間もつ6セルなので、1.5Kgぐらいで、かなりずっしりくる。

20090404 eeePC 004

Windows XP が標準で載っています。

20090404 eeePC 005

裏側はこんな感じ。すぐさま、1GBメモリを取り出して、2GBに交換。

20090404 eeePC 006

D: ドライブに Windows 7 Build 7000 をインストール。

一応、安全のため、C: ドライブの XPは残して、デュアルブート。

20090404 eeePC 007

風呂からあがってみると、もうWindows 7 の設定画面になっている。早っ!

20090404 eeePC 009

設定はすぐ終わり、あっさり Windows 7 が動いてしまった。

20090404 eeePC 010

インテルのチップセットは、Aeroにも対応。

20090404 eeePC 011

ハイパースレッド。

20090404 eeePC 012

無線LANも、デフォルトのインストールで問題なし。

ただし、デフォルトではイーサーコントローラーと、ACPIのドライバーが未対応。

20090404 eeePC 016 20090404 eeePC 021

イーサネットは、ASUSからVista用をダウンロードして、問題なく動く。

意外と、早いじゃん!いい感じ。

Visual Studio 2008 で、ASP.NET 開発サーバーが動かない原因判明

http://blogs.msdn.com/webdevtools/archive/2009/03/13/asp-net-web-development-server-stops-working.aspx

Visual Studio Web Developer Team Blog より、ASP.NET Web Development Server Stops Workingという記事を発見。

Windows Defender and Microsoft Forefront Client Security signature file (1.53.256.0) に対応するために、2009年3月9日 8:45 PM (PST) の対応で、ホストファイルから localhostが削除されている。

解決するためには、 C:\Windows\System32\drivers\etc\hosts

のエントリを次のように修正すればよい。

127.0.0.1       localhost

1.53.288.0での修正版がその直後の March 9, 2009  8:57 PM に出ているということで、それ以降は大丈夫みたいだけど。

で、hosts ファイルをみてみたら、

::1             localhost

となっている。IPV6?

とりあええず、これを

127.0.0.1       localhost

と修正して、無事復旧。

Visual Studio 2008 Pro を再インストールしたが

フルにアンインストールして、VS 2008 Pro を再インストール

ASP.NET アプリのプロジェクトを作成して実行すると、

Internet Explorer ではこのページは表示できません

可能性のある原因:
  • インターネットに接続されていない。
  • Web サイトに問題が発生している。
  • アドレスに入力の間違いがある可能性がある。

というエラー。

Gushwell さんも同じような状況

http://blog.livedoor.jp/gushwell/archives/51341969.html

こちらでも、

http://social.msdn.microsoft.com/forums/ja-JP/vwdexpressja/thread/27747fb7-b12f-422a-9800-8f0d28334042/

にも同じような人が・・・

どうも ASP.NET 開発用サーバーに接続できていないようだが、原因が分からない。