| 2005-3-9 | 公開開始 |
| 2005-5-16 | 補足を追加 |
以前買ってあったDELLのPrecision 370用に、メモリを購入した。
カメラがD2Xになって、高解像度の写真が簡単に得られるようになったのはいいのだけど、あまりに解像度が高いために、こんどはこれまで使っていたメインマシン(Pentium 3s-1.13GHz)では力不足を感じるようになった。
そこで、ほったらかしにしてあったPrecisionをNikon Capture専用機にしようと思い、奮発して1GBのメモリを2本買った。このPrecisionは、メモリ倍増キャンペーンの際に購入したので、最初からメモリが1GB搭載されている。つまり、あわせて3GBメモリになるわけだ。
と、思ったら。
ECCとnon-ECCメモリの混在はサポートしない、というメッセージが出て立ち上がらない。
「なんですとーーーっ」
これは大きな誤算だ。
あわせて3GBとなるはずが、標準でついているECCメモリと、新規に買ったnon-ECCメモリは混在できない。どちらか一方を取るなら、当然新たに買ったほうなのだけど、うちには他にDDR2メモリを使うようなPCを持っていないので、取り外した1GB分は完全に無駄になる。
PC関係ではあまり買い物で失敗したことはないのだが、久々にでかい失敗といえよう。
せっかく買った2GBものメモリだが、それを入れると元の1GBが使えなくなるのでは、結局1GB増えたに過ぎない。これではあまりにもったいないので、元の1GBを使えるようにする手を考えてみる。
ECCメモリが載ってないものをECC化するのは不可能であるから、もしやるとすればECCメモリが載っている従来のメモリからECCメモリをひっぺがして、non-ECCに改造するという手段がもっとも手っ取り早い。
ただ、ECCメモリのチップをはずせばそれでnon-ECCに変わるのだろうか!?
ということで実験。
まずECCメモリとnonECCメモリのDIMMを見比べて、DIMMのどのピンがECCチップに繋がっているかを調べる。ECC DIMMではチップに繋がっているのに、nonECCではどこにも繋がっていないピンを探すのだ。
これはすぐわかった。新たに購入したnonECCのDIMMで、NCになっているピンはあからさまに目立っていたから。
そこで、ECCつきの方のDIMMで、そのピンをポリイミドテープでマスキングして、ECCビットへのアクセスができないようにした。これでPC側からは、ECC無しに見えるはず。と思って実験してみたら、やっぱり結果は同じだった。
つまりこのマザーはECCかどうかを、SPD(Serial Presence Detect)に書かれている情報によってのみ判断していると思われる。だから、実際にチップが存在しない(マスキングされている)状態でも、ECCだとみなしてしまうのだ。
つまり、このSPDを、ECC無しのものに取り替えれば、1GB分のメモリは使えるようになるはず。いや。SPDは一般にEEPROMになっているので、内容を書き換えてやれば、ハードウェアの改造をしなくてもソフト的にnonECCに「改造」できるはずだ。
そこらへんをちょっと調べてみたい。
SPD(Serial Presence Detect)とは、SIMMやDIMMなどのメモリモジュールに対し、そのモジュールの容量、アクセス速度、アクセス方法といった、メモリのスペックを記録したROMモジュールのこと。SPD導入以前は、取り付けられたメモリの容量は、マザーボード側からは簡単に調べることができず、リセット時のメモリチェック時などに容量を検査するなどしていた。しかしSPDを使えば、あらかじめ定められた方法で「読むだけ」でメモリの種類などがわかる。
SPDは、実際にはかなり以前から使われていて、IntelプラットフォームでいえばPentium 2の時代、440LXなどのチップセットですでに利用可能となっていた。
SPDに対応したメモリモジュール上には、専用のROMモジュールが搭載されている。8ピンの小さなパーツで、ほとんどの場合基板の端っこに置かれているはずだ。ROMと書いたけれど、殆どの場合は電気的に書込可能なプログラマブルROM(EEPROM)が使われていて、書込条件さえ揃えれば、原理的には外部から書き換えることもできるはずの代物だ。
SPDにどんな内容が書いてあるのかは、JEDECのWebサイトからデータシートを入手することができる(無料、ユーザー登録要)。必要な部分だけを抜粋すると、こんな感じ。
| Byte Number | Function Described |
|---|---|
| 0-10 | (略) |
| 11 | DIMM configuration type (Non-parity, Parity or ECC) |
| 12-62 | (略) |
| 63 | Checksum for Bytes 0-62 |
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|---|---|---|---|---|---|---|---|
| TBD | TBD | TBD | TBD | TBD | Address/Command Parity | Data ECC | Data Parity |
| 0 | 0 | 0 | 0 | 0 | 1 or 0 | 1 or 0 | 1 or 0 |
| 1 = Supported on this assembly, 0 = Not supported on this assembly. | |||||||
すなわち、SPDデータの先頭から11バイト目が0x02であればECCあり、0x00であればECC無しということになる。ここを書き換えれば、ECCメモリをnonECCであることにできちゃうわけだ。ただし、SPDデータにはチェックサムコードが含まれているので、ここも書き換える必要があるだろう。
あとはこいつを書き換えればいいだけなのだが、問題はどうやって書き換えるかだ。SPDチップはI²Cバスによりアクセス可能であるらしいので、これに対応したライターを準備すればよいことになる。
そんなものは持っていないのだが、こいつをなんとかすれば、ECCメモリをnonECCに化けさせることができそうだ。
SPDはI²Cバスでアクセスできるので、これに対応したライターを用意すれば書換えできることまではわかった。しかしその手のライターは高いのではないか、と思っていろいろ探したら「PonyProg」という、シリアルデバイス用のプログラミングソフトが、パラレルポートを使ったI²Cバス経由のプログラミングに対応していることがわかった。
しかも、リンク先のサイトでは、パラレルポートに接続するライタの回路図まで公開している。つまりフリーのプログラミングソフトと、ライターが一挙に手に入るわけ。
必要なパーツは、トランジスタ2本と、抵抗が4本だけ。あとは手持ちのコネクタやケーブル類でなんとかなりそうなので、さっそく部品を調達して作ってみた。
町田の電子パーツショップ「サトー電気」で購入したパーツの総額はおよそ300円ほど。あとは手持ちのRS-232Cケーブルをぶった切ってコネクタを入手、電源も面倒なのでPCのUSB端子から取るという横着な構成ででっちあげたのが写真のライター。
4本出ているクリップは、それぞれSPDのVdd(+5V)、Vss(GND)、それにSCLK(Serial Clock)、SDA(Serial Data)に繋がるべきもの。これを使って、SPDチップをボードから取り外さず、オンボードのままで書き換えてしまおう、というわけだ。
はてさて、うまく行くのかどうか。乞うご期待
ライターができたので、まずはSPDを読むところから。
SPDのピン配置は、以下の様になっている(写真の向きと表の構成をあわせてあります)

| 1 | A0 | ○ | Vcc | 8 |
|---|---|---|---|---|
| 2 | A1 | WP | 7 | |
| 3 | A2 | SCL | 6 | |
| 4 | GND | SDA | 5 |

| Pin # | x72 ECC |
|---|---|
| 118 | VSS(GND) |
| 119 | SDA |
| 120 | SCL |
| 238 | VDDSPD |
| 239 | SA0 |
| 240 | SA1 |
238と119,120番は表裏ほぼ同じ位置にあるのでクリップを挟みづらく、このためチップのピンの方に直接接続した方がやりやすかった。
で、この状態でデータを読んでみた結果が下の図。ちゃんと読めていることがわかる。これらのデータのうち、バイト11(ECCの有無)とバイト63(チェックサム)を書き換えてやれば(反転表示加工済み)、みごとこのメモリはECC無しに化けてくれるはずだ。

いよいよ、SPDの書換え。
書き換えるべきは、11バイト目の0x02の値だ。これを0x00にすればSPD上ではECC無しということになる。63バイト目のチェックサムは、0〜62バイト目までの単純な足し算の下位1バイト分なので、11バイト目が2→0になったのにあわせて、2だけ減じる。すなわち0xa8→0xa6にすればよいわけだ。
このまま書き込んでやれば、これでnonECCメモリのできあがり。
実際にPCに刺して確かめてみた結果が、左の写真。どのスロットもnon ECCメモリとして認識されていることがわかる。これで、わずか300円あまりで使えなかったDDR2メモリ1GB分が生き返ったことになる。めでたし。
さて、このように当初の目的は達成することができたわけだけど、実をいうと、この作業の過程で気づいたことがある。なにかというと、
「今回行ったようなSPD書換は、ソフトウェアだけで実現可能である」
という事実だ。
これまで書いてきたように、SPDはチップセットとI²Cバスで接続されている。チップセットはこれで容量の認識をするわけだが、CPUからは、チップセットに対してI/O命令を発行することで、I²Cバスにアクセス可能だ。事実、Webを検索すると、この機能を用いてSPDを読み出すプログラムがいくつか見つかる。
SPDは、SCLとSDA、たった2本のデータラインだけで、データを読むことも書くことも可能だ。つまりSPDの内容を読み出すことができるなら、書込コマンドを発行さえすれば、データを書き込むことも原理的には可能なはず。
つまり、私が今回やったように、わざわざ書込み用のハードウェアを作らずとも、特定のチップセットからI²Cバスにアクセスする方法と、SPDの書込コマンドさえわかってしまえば、ソフトウェア的な書換は可能なのだ。そしてこの2つの情報は、いろいろ調べる過程で、すでに入手することができた。あとはプログラムを書きさえすれば、今回と同じ事は実現できるはず。
もっとも、すでに目的を達成した今となっては、そんなことする気も起きないのだけど...
まぁ、つまらんオチではあるけど、そういうこと。
このページにリンクしてくださっていた、[のぶ]氏の日記ページの方が、ソフトウェアだけでSPDを書き換えるプログラムを作って下さったようです。上の方で私は「できるだろう」と無責任に書いただけでけっきょく何もしないで済ませてしまったところを、すばらしいです。このバイタリティには感服します。
さて、それはともかくとして、上記[のぶ]氏の日記に書かれていますが、DDR2メモリに関しては、マザーボードに装着した時点でSPDをライトプロテクト状態にプログラムするよう推奨されているそうです。
SPDが一旦ソフトウェアライトプロテクト状態にプログラミングされると、二度とライト許可の状態に戻すことはできません。つまり本ページに書いてあるハードウェア的な方法や、[のぶ]氏が作成したようなプログラムでnonECC化している場合、ここでライトプロテクトがプログラミングされてしまうと、SPDはnonECCの状態で固定されてしまいます。一度こうなると、二度とECCイネーブルにできません。金輪際そのDIMMではECCなど使わない、ということであればいいのですが、せっかくECCメモリチップがついているのにそのECCを生かせないというのは、釈然としないものがあります。
この問題を避けるためには、SPDをライトプロテクト状態にプログラミングしてしまうよう極悪マザーに装着しないようにするのが一番です。しかし[極悪]とはいえ、わざわざJEDECの規格書で「ライトプロテクトすべし」と推奨されているわけですから、この操作をしているマザーボード(のBIOS)のことを一方的に責めるわけにはいきません。
[のぶ]氏のページにも書かれているように、PowerEdge SC420も私が使っているPrecision 370も、現在のところ、この「再プログラミング」は行いません。したがって今は決してあせる必要はありません。これらのPC以外には決してメモリを取り付けない、また新しいBIOSがリリースされても、それをすぐに適用したりしないよう気をつけていれば、勝手にライトプロテクトされてしまうことはないでしょう。
それではあまりに不自由だと思う場合には、SPDのWPピン(7番ピン)をVccにプルアップするという手があります。たいていのDIMMは、SPDの7番ピンはGNDに接続されているはずですが、これをはずしてVcc(8番ピン)との間に、抵抗を経由して接続します。これでSPDは書き込み禁止の状態となり、同時に、ソフトウェアでライトプロテクト状態にプログラミングすることもできなくなります。
基板に手を入れることになるので中古販売等はできなくなりますが、抵抗を外して再プログラミングすれば、もういちどECCメモリに戻すことが可能となります。もしもう一度ECCメモリに戻すことが必要と思うようなことがあるなら、この加工をしておいてもいい[かも]しれません。
注意していただきたいのは、決してハードウェア加工をしなさい、と強制しているわけではない点です。失敗のリスクを考えて、やるかやらないかは自己責任、ということでお願いします。