10/31/2011

TX-50開発キットで遊ぶ その9

今日は、シリアルのドライバを作成するに先立って、ちょっとお勉強です。

まず、BLDKはEDKIIがベースになってます。以前に弄ってたEDKとはモジュールの扱いの流儀がちょっと違うようで、まだよくわかってません。なので、EDKIIのモジュール作成方法について調べてみます。

EDKIIのドキュメントは以下からゲットします。

http://sourceforge.net/projects/edk2/files/General%20Documentation/
http://sourceforge.net/projects/edk2/files/Specifications/

なんだか読み物がたくさんありますが、さしあたって、EDKII Module Writer_s Guide_0_7.pdfをざっくり眺めてみました。

まだ、完全に内容を理解できてないですが、まずドライバやアプリのモジュールを作成するにはxxxxPkgとかって名前でディレクトリを作って、複数のモジュールをまとめておくパッケージを作成することになってるようです。

んで、そのパッケージにはDECとDSCファイルというパッケージの定義やビルドの挙動を記述したファイルを作成することになってるっぽいです。あと、FDFファイルというのもあって、これは、フラッシュ(ROMイメージ)に何を含めるかということを記述するようです。これは全てのモジュールに必要ではなくて、最終成果物としてROMイメージを出力したいモジュールだけ必要になるようです。

そして、パッケージの中にドライバ等のモジュールを(必要なだけ複数でも)作成することになってて、DXEドライバならxxxxDxeとかっていうフォルダにするのがお勧めみたいです。このフォルダにソースコードやバイナリモジュールならバイナリを置くわけですが、それぞれのモジュールにINFファイルというのを作成する必要があるようです。


なんだか、DECやらDSCとかFDFとかINFとか複雑なことになってますが、ビルド時にこれらのメタデータを元にmakefileが自動生成されるようです。EDKIIでは以前のEDKと違い、ビルド環境が、クロスプラットフォームで、複数のコンパイラやビルドシステム、OSに対応しているため、こんなことになってるっぽいです。

あと、PCDなる機構があって、これをうまくつかうことで、メタデータから定数や機能のON/OFFをコントロールできる仕組みが用意されているようです。

で、これらメタデータの記述ルールに関しては別途Specificationのドキュメントが個々に用意されているのですが、まだ全部目を通せていません。

とはいえ、ドキュメント読んでばかりだと、つまらないので、とにかくなんか作ってみてみます。そのほうが理解も早いしね。

そんなわけで、今回は特に何もしてくれないテストドライバを適当に書いてみます。目的はどっちかというとビルドシステムに慣れることですね。とりあえず、BLDKにはいくつもドライバソースが含まれているので、それらを参考にします。8254TimerDxeあたりがシンプルな構造で参考になりました。

で、ごにょごにょ試行錯誤しつつ以下のコードを書いてみました。


//
// TestDriver.c
//

#include "TestDriver.h"

EFI_GUID gEfiTestDriverProtocolGuid = EFI_TEST_DRIVER_PROTOCOL_GUID;

EFI_HANDLE                mTestHandle = NULL;

//
// driver produces
//
EFI_TEST_DRIVER_PROTOCOL   mTest = {
  TestDriverFunction
};

EFI_STATUS
EFIAPI
TestDriverFunction (
)
{
  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
TestDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  //
  // Install the Test Driver Protocol onto a new handle
  //
  return gBS->InstallMultipleProtocolInterfaces (
                  &mTestHandle,
                  &gEfiTestDriverProtocolGuid,
                  &mTest,
                  NULL
                  );
}




//
// TestDriver.h
//

#ifndef __TEST_DRIVER_H__
#define __TEST_DRIVER_H__

#include <Library/UefiBootServicesTableLib.h>
#include "TestDriverProtocol.h"

EFI_STATUS
EFIAPI
TestDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  );

EFI_STATUS
EFIAPI
TestDriverFunction (
  );

#endif



//
// TestDriverProtocol.h
//

#ifndef __TEST_DRIVER_PROTOCOL_H__
#define __TEST_DRIVER_PROTOCOL_H__

#define EFI_TEST_DRIVER_PROTOCOL_GUID \
  { 0x8d37d58, 0x8c26, 0x4e39, { 0x92, 0xf3, 0x14, 0x97, 0x89, 0x5f, 0x60, 0x63 } }

typedef 
EFI_STATUS
(EFIAPI *EFI_TEST_DRIVER_FUNCTION)(
  );

typedef struct _EFI_TEST_DRIVER_PROTOCOL {
  EFI_TEST_DRIVER_FUNCTION          TestFunction;
}EFI_TEST_DRIVER_PROTOCOL;

extern EFI_GUID gEfiTestDriverProtocolGuid;

#endif





#
# TestDriver.inf
#

[Defines]
  INF_VERSION                    = 0x00010005
  BASE_NAME                      = TestDriver
  FILE_GUID                      = CD5E357E-94D9-484d-BA43-CB632FC50C03
  MODULE_TYPE                    = DXE_DRIVER
  VERSION_STRING                 = 0.1
  ENTRY_POINT                    = TestDriverEntryPoint

[Packages]
  MdePkg/MdePkg.dec
  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec

[LibraryClasses]
  UefiDriverEntryPoint
  UefiBootServicesTableLib
  UefiLib

[Sources]
  TestDriverProtocol.h
  TestDriver.h
  TestDriver.c

[Protocols]

[Depex]
  TRUE





で、DECやDSCも必要かと思いきや、どうやらパッケージ単体でビルドする場合は必要っぽいですが、この場合BLDKのROMイメージを作成するので、ビルド対象がCrownBayPlatformPkgになります。なので、このパッケージのDSCとFDFの適当な所にTestDriver.infへのパスを書いておけばビルドされるぽいです。ほんとはルールに則ってパッケージ毎にあったほうがいいんでしょうけどね。

で、ビルドは通ったものの、何もしないドライバなので、動かしても何も起きないです。ふんにゃかです。

でもまあ、パッケージ作成の理解は進んだし、概ね雰囲気も掴めてきたので、良しとします。来週はシリアルドライバ作成に着手したいところです。

週一の開発ペースだと、ボリュームの大きめな課題は中々進まないですねえ。ちまちまがんばります。


今週はここまでっす。

10/24/2011

TX-50開発キットで遊ぶ その8

そして、シリアルポートについて、考えます。

シリアルポートが使えるようにしたい理由は2つあって、一つは、シリアルコンソールを使えると、便利なのと、もう一つは、BLDKのドキュメントによれば、シリアルを使ってソースレベルデバッグができるっぽいのです。

で、BLDKには、この二つをサポートするためのコードが含まれているのですが、これが、残念ながら、SuperIOのレガシーシリアルポート向けのコードで、TX-50では使えません。しかしながらPCIシリアルでなんとかならんもんかと、考えてみます。

シリアルコンソールに関しては、恐らく、PCIシリアルのDXEドライバを書けば使える可能性が高いんじゃなかろうかと思います。とはいえ、ドライバ書くのは結構時間かかりそうですねえ。

デバッガに関しては、恐らく、BIOSのかなり前のほうでシリアルが初期化されてないと駄目っぽいですね。うーん。どちらにしても、とりあえず、TX-50のPCIバストポロジをもう少し、詳しく把握しておく必要がありそうです。というわけで、EFIShellのPCIコマンドでデバイス一覧をみてみます。

Shell>pci



   Seg  Bus  Dev  Func
   ---  ---  ---  ----
    00   00   00    00 ==> Bridge Device - Host/PCI bridge
             Vendor 8086 Device 4114 Prog Interface 0
    00   00   01    00 ==> Bridge Device - Host/PCI bridge
             Vendor 8086 Device 8183 Prog Interface 0
    00   00   02    00 ==> Display Controller - VGA/8514 controller
             Vendor 8086 Device 4108 Prog Interface 0
    00   00   03    00 ==> Multimedia Device - Video device
             Vendor 8086 Device 8182 Prog Interface 0
    00   00   17    00 ==> Bridge Device - PCI/PCI bridge
             Vendor 8086 Device 8184 Prog Interface 0
    00   00   18    00 ==> Bridge Device - PCI/PCI bridge
             Vendor 8086 Device 8185 Prog Interface 0
    00   00   1B    00 ==> Multimedia Device - UNDEFINED
             Vendor 8086 Device 811B Prog Interface 0
    00   00   1F    00 ==> Bridge Device - PCI/ISA bridge
             Vendor 8086 Device 8186 Prog Interface 0
    00   01   00    00 ==> Bridge Device - PCI/PCI bridge
             Vendor 8086 Device 8800 Prog Interface 0
    00   02   00    00 ==> Device does not fit in any defined classes - 
             Vendor 8086 Device 8801 Prog Interface 0
    00   02   00    01 ==> Network Controller - Ethernet controller
             Vendor 8086 Device 8802 Prog Interface 0
    00   02   00    02 ==> Device does not fit in any defined classes - 
             Vendor 8086 Device 8803 Prog Interface 0
    00   02   02    00 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 8804 Prog Interface 10
    00   02   02    01 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 8805 Prog Interface 10
    00   02   02    02 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 8806 Prog Interface 10
    00   02   02    03 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 8807 Prog Interface 20
    00   02   02    04 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 8808 Prog Interface FE
    00   02   04    00 ==> Base System Peripherals - UNDEFINED
             Vendor 8086 Device 8809 Prog Interface 1
    00   02   04    01 ==> Base System Peripherals - UNDEFINED
             Vendor 8086 Device 880A Prog Interface 1
    00   02   06    00 ==> Mass Storage Controller - UNDEFINED
             Vendor 8086 Device 880B Prog Interface 1
    00   02   08    00 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 880C Prog Interface 10
    00   02   08    01 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 880D Prog Interface 10
    00   02   08    02 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 880E Prog Interface 10
    00   02   08    03 ==> Serial Bus Controllers - USB
             Vendor 8086 Device 880F Prog Interface 20
    00   02   0A    00 ==> Device does not fit in any defined classes - 
             Vendor 8086 Device 8810 Prog Interface 0
    00   02   0A    01 ==> Simple Communications Controllers - Serial controller
             Vendor 8086 Device 8811 Prog Interface 2
    00   02   0A    02 ==> Simple Communications Controllers - Serial controller
             Vendor 8086 Device 8812 Prog Interface 2
    00   02   0A    03 ==> Simple Communications Controllers - Serial controller
             Vendor 8086 Device 8813 Prog Interface 2
    00   02   0A    04 ==> Simple Communications Controllers - Serial controller
             Vendor 8086 Device 8814 Prog Interface 2
    00   02   0C    00 ==> Device does not fit in any defined classes - 
             Vendor 8086 Device 8815 Prog Interface 0
    00   02   0C    01 ==> Serial Bus Controllers - Other bus type
             Vendor 8086 Device 8816 Prog Interface 0
    00   02   0C    02 ==> Serial Bus Controllers - Other bus type
             Vendor 8086 Device 8817 Prog Interface 0
    00   02   0C    03 ==> Serial Bus Controllers - UNDEFINED
             Vendor 8086 Device 8818 Prog Interface 0
    00   02   0C    04 ==> Device does not fit in any defined classes - 
             Vendor 8086 Device 8819 Prog Interface 0
    00   03   00    00 ==> Network Controller - Ethernet controller
             Vendor 8086 Device 10D3 Prog Interface 0


なにやら、デバイスてんこ盛りですな。これだと、ちょっとイメージ沸きづらいので、図にしてみました。デバイス名はデータシートと照らし合わせて調べました。

TX-50 BLDK Bus Topology

六角形のはブリッジです。データシートによればATOM側にはPCI Expressのルートポート(PCIバス上ではブリッジに見える)が4つあるはずですが、2つしか見えないので、残り2つは無効にされているっぽいです。(点線のやつ)

そして、問題のシリアルはBus 2/Device 0Ah/Function 1ですね。このデバイスとHostブリッジの間にはPCI Expressのブリッジが2つ入ることがわかりました。(ピンクのやつ)それは、すなわち、このデバイスにアクセスするには2つのブリッジのI/O(またはメモリ)ウィンドウを設定する必要があるということです。
これらのブリッジがサブトラクティブデコードに対応していれば、もう少し話しは簡単だったかもしれませんが、残念ながら、データシートにそのような記述はみあたりませんでした。

しかも、PCI Expressブリッジ2つをBIOSの頭で初期化するにしても、PCI Expressにはリンクトレーニングというものがありまして、いきなり使えるとは限らないですね。そもそも、チップセットの特殊な領域を設定しないとリンクトレーニングが始まらないという可能性もあるため、うまくいくとも限りませんし、うまくいってないときに何が起きているのかも知る術がないですねー。

ま、試しに、やってみっか。

今週はここまでにしときます。来週またがんばるっすー。

TX-50開発キットで遊ぶ 開発ツール編

今週から新しい開発ツールの仲間が増えました。

ROMライターのEZP2010さんです。

EZP2010


これで、動作中にホットスワップという危険な行為をせずとも、BIOS焼けます。今までだと、元のBIOSをうっかり壊して、起動するBIOSが一個も無くなってしまったら、打つ手無しという危険もありましたが、これで、心おきなく焼きまくりです。

このROMライター、ぐぐってて、たまたま、デジダイブさんという方のブログで、このROMライターについて取り上げておられたのを見つけて、私も買うことにしました。ヤフーチャイナモールで3000円程度という、ハードボイルドな価格設定でしたが、デジダイブさんの記事を事前に読ませて頂いたので、思い切って買うことができました。デジダイブさん、ありがとうございます。
http://www.ddive.net/2011/08/23/ezp2010/


で、これ、見かけは、もはや大人の科学の付録にしかみえませんが、結構、高速に焼けます。ソフトもわりと、必要十分な出来栄えで、対応SPIの量もなかなかのものです。

EZP2010 soft
惜しいのは、ROMイメージを読み込む際に、2MBのSPIに1MBのイメージを後半のアドレスを指定してロードできないので、ちょっと不便です。前もって、ROMイメージを加工すればいいんですけどね。



次に紹介するのは、A390というUSBデータリンクケーブルです。
A390
これ、やべえっす。以前に紹介記事をみつけて、ずっと気になってたんですが、土曜日(10/22)に別件で秋葉原行ってきたので、ついでに探してたら、あきばおーで見つけました。

これ、簡単に言うと、PC上のファイルをマスストレージに見せて、メディアプレイヤーで再生できるという主旨の製品なんですが、ISOもイケます。なので、OSのCDイメージファイルをいちいち、CDに焼いたり、USBメモリに書き込まなくても、ケーブルつないで、ファイル指定するだけで、もう一方のPCはそのイメージでブートできちゃいます。
(早速これを使って、ネットブックにUbuntu11.10をインストールしてみましたが、問題なくできました。)

あらゆる面でエコです。すばらしいです。そして、当然ファイルもいけるので、EFIShellやBIOSイメージや、SpiUpdate.efi等を突っ込んだ、バーチャルディスクを作れば、それで、起動してBIOS書き込んだりできます。もう、これは開発ツールとしても、すばらしいです。

ちょっと残念なのは、書き込みができないようです。書き込みできたら最強なのになー。


ツールの紹介は以上です。



10/17/2011

TX-50開発キットで遊ぶ その7

じゃあ、今日はグラフィックを出すであります。

前回は、起動してるっぽいところまで行きましたが、やっぱりグラフィック出んと、面白くないよね。
というわけで、なんでグラフィック出ないのかを考えてみました。BLDKのドキュメント類をみてると
LVDSのみのサポートかも。LVDSの出力にはグラフィック出てるかもしれませんね。LVDSの液晶あればなー。といっても始まらないので、アナログVGAに出せる方法を考えて見ます。で、なぜ、出ないのかなー。可能性としては、恐らくEFIのグラフィックドライバがアナログVGAに対応していないんではなかろうか。
というか、TX-50の仕様書をみると、これsDVOの出力をCH7317Bというチップでアナログに変換しているようですね。

うーん。そうなるとグラフィックドライバをいじる必要があるかもです。で、BLDKのソースでグラフィック関係のソースを探してみたところ、そのあたりはバイナリ提供のようで、ソースコードないっぽ。
これは困ったちゃんです。なんか手が無いかとインテルのサイトを漁ってたら、いいものみっけました。

Intel EMGDというやつです。↓
http://www.intel.com/p/ja_JP/embedded/hwsw/software/emgd
(注:日本語版のダウンロードページは、なんだかバグってます。サイトの右上で英語に切り替えたらダウンロードできました。)

よく調べてみると、これ、組み込み向けのグラフィックドライバなわけですが、なんと、いろいろパラメータを調整してドライバを生成できるみたいっす。組み込みだと、固定の液晶ディスプレイだったり、変な解像度だったりするからですかね。そして、EFIのドライバやVBIOSを生成する機能もあるようです。Intelさん粋なブツをありがとー。

で、Atom E6xx向けのWindows用のブツをダウンロードしてインストールしてみました。すると、EMGD Configuration Editorなるアプリケーションが使えるようになりまして、GUIでパラメータをウィザード形式で設定していくとドライバが生成できるようになってます。よっしゃUserGuideをななめ読みしながらやってみます。まず、エディタを起動します。インストールされた「emgd-ced.exe」を起動すると以下のようなやつが起動します。


右のペインにコンフィグレーションやパッケージというフォルダがありますね。プリセットで設定例がいろいろ含まれているようです。で、手順としては、コンフィグレーションファイルをまず作って、そのコンフィグレーションを使用してパッケージを作って、そのパッケージのインストレーションを生成することで最終的なドライバが生成されるようです。いろいろ設定できるパラメータがあるようですが、まずは余計なことせず、無難な設定で画面が出ることだけを目指します。
まず、メニューから「New Configuration」をクリックします。すると以下のような画面が出ます。



「Configuration FIle Name」は「tx-50」としました。これは好きな名前つければよさそうです。「Display Configuration Mode」は「SIngle」にしました。デュアルとかもできるっぽいです。「Platform Chipset」は「Intel(R) Atom(TM) Processor E6xx」を選択します。「Port Devices」は「sDVO」を選択して左の「Port Order」へ移動させます。LVDSの併用もできるようですが、いまんとこsDVOのみでやってみます。「Next >」をクリックします。


次の画面です。「Readable Port Name」は「VGA」としました。好きにつけてよさそうです。「Select sDVO Device」では「Chrontel* CH7317 VGA」にチェックします。tx-50ではこの変換チップを使ってるのです。項目にあってラッキーです。その他の設定はとりあえず、デフォルトのままでよさげです。「Next >」をクリックします。



次の画面も今回はデフォルトのままで進めます。スプラッシュスクリーンとか指定できるっぽいので、今度やってみます。「Next >」をクリックします。


次の画面で、「Primary Display Mode」を「0x12 - 640x480x4bpp@60Hz」を選択します。いろいろ設定を試したんですが、どうも、うちのディスプレイはUse Defaultや70Hz系の設定だと画面がぐちゃぐちゃになります。この辺は使用するディスプレイによるかもしれません。で「Finish」です。
すると左のペインに今作った設定が「tx-50.cnfg」という形で保存されます。これをダブルクリックで設定を変更できるっす。
次にメニューから「New Package」をクリックしますと、以下の画面になります。




「Package File Name」は「tx-50」としました。好きな名前を付ければよさそうです。「Configurations」は先ほど作成した「tx-50.cnfg」を選択します。「Target OS」は「EFI」を選択します。それ以外はデフォルトのまま「Next >」をクリックです。



なんだか、「General」と「Fastboot Atom_E6xx」とあります。今回はとりあえずGeneralを使ってみます。「General」の枠の中の「Generate EFI」と「tx-50.cnfg」をチェックします。で、「Finish」です。

よし、そして、左のペインの「pakage」フォルダに今作った、「tx-50.pkg」ができてるので、これを選択して、メニューの「Generate Instaallation」をクリックします。すると、ごにょにょビルドされました。バイナリは「C:\IEMGD\IEMGD_1_8\workspace\installation\TX-50.pkg_installation\IEMGD_HEAD_EFI\Compiled_EFI\efi」にできてます。
ほんで、できた「iegd.efi」というのがEFIのグラフィックドライバちゅうわけですな。したらば、これをBLDKに組み込みます。「C:\bldk\CrownBayPlatformPkg\GopBinary」に同じファイル名のやつがいるので、これをおもむろに入れ替えてみます。そして、BLDKをビルドします。で、例の「70S01905D.EXE」改造作戦でBIOSを書き込みました。

そして起動しします。おお、見事グラフィックでましたであります。




うーん。ちょっと感動ですね。そして、もしやと思い、以前あきらめた「SpiUpdate.efi」でBIOS書き込みを試してみたところ、うまく書き込めました。これで、「70S01905D.EXE」改造作戦で動作中にBIOSチップをホットスワップしなくてもBIOS焼けるっす。

よし、今週はここまでにします。次はシリアルなんとかしたいっすー。

10/11/2011

TX-50開発キットで遊ぶ その6

とりあえず、なんとかBIOSを焼くことができましたが、なんだかまともに動いてなさげです。
それも、どこまで動いているのか判断もできないので、なんか動作を確認する術が必要です。

こういうときは、古から伝わるデバッグ術、シリアルポートに何か文字を出すとかして
動作を確認しようかなー。

と、その前に、まず、BLDKのデフォルト設定でまともに動く可能性はそもそも低いわけで、
まず、基板依存の設定をちゃんとやってみることにします。まずは、GPIOですかね。

ですが、TX-50の回路図も無く、GPIOの割り当てがどうなっているのか仕様も不明なため、
元のBIOSで起動してレジスタダンプして設定値をゲットする作戦でいきます。

方法としてはEFIShellを使います。ですが、元のBIOSの内臓EFIShellは簡易版のようで、最低限のコマンドしか入ってません。ここはフル機能版のEFIShellを使いたいところです。

で、久々に自分の過去のブログ記事を参考にEDKを使ってEFIShellをビルドしました。これを使えば、メモリやIOを読み書きできるMMコマンドや、PCIコマンド等、レジスタにアクセスし放題だー。
よく見たら、BLDKのソースツリー内にもバイナリのフル機能版と思われるEFIShell入ってますね。(C:\bldk\EdkShellBinPkg\FullShell)EDKでわざわざビルドする必要はなかったかもしれません。

EFIShellのバイナリは適当なUSBメモリに「EFI\BOOT\BOOTIA32.EFI」というパスにこのファイル名で置きます。ほんで、基板を起動して「F12」キーを押して、ブートメニューからそれっぽいのを選ぶと、このEFIShellから起動できました。

E600やEG20-TのデータシートからGPIOのレジスタがどうなっているかみてみました。
E600側のGPIOはLPCブリッジのPCIコンフィグレーション空間のオフセット44h-47hにベースアドレスを設定するようになってます。なので、PCIコマンドで覗いてみます。LCPブリッジはバス0、デバイス1fh、ファンクション0なのでコマンドは以下のようになります。

Shell>pci 0 1f 0 

  PCI Segment 00 Bus 00 Device 1F Func 00 [EFI 00001F0000]
  00000000: 86 80 86 81 03 00 00 00-01 00 01 06 00 00 80 00  *................*
  00000010: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000020: 00 00 00 00 00 00 00 00-00 00 00 00 86 80 70 72  *..............pr*
  00000030: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*


  00000040: 40 10 00 80 80 10 00 80-00 10 00 80 C0 10 00 80  *@...............*
  00000050: 00 00 00 00 3F 00 06 00-00 00 00 00 50 00 00 00  *....?.......P...*
  00000060: 0B 0B 0B 0A 80 80 80 80-80 00 00 00 00 00 00 00  *................*
  00000070: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000080: 00 00 00 00 00 11 00 80-00 00 00 00 00 00 00 00  *................*
  00000090: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000A0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000B0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000C0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000D0: 33 22 11 00 00 00 00 FF-00 01 00 00 00 00 00 00  *3"..............*
  000000E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000F0: 01 C0 D1 FE 00 00 00 00-AD 0F 00 00 00 00 00 00  *................*


バイト単位で表示されるのでアレですが、GPIOベースアドレスは80001080hのようです。
おっと、データシートによると最上位ビットはEnableビットなので、アドレスは1080hですな。
これはI/O空間なんですって。なので、MMコマンドでこのアドレスのI/Oを覗いてみます。
オフセットはデータシートによれば、ベースアドレス+00h ~3Chまでで、それぞれ32ビットのレジスタとのことです。
なのですが、BLDKの設定ツールで設定できるのは以下の6つです。


  • GPIO[4:0] Enable
  • GPIO[4:0] Select
  • GPIO[4:0] Level
  • GPIOSUS[8:0] Enable
  • GPIOSUS[8:0] Select
  • GPIOSUS[8:0] Level


この値に対応するのはオフセット0、4、8、20h、24h、28hですな。
コマンドは以下のような感じです。

Shell> mm -io -w 4 -n 1080
IO  0x0000000000001080 : 0x0000001F

Shell> mm -io -w 4 -n 1084
IO  0x0000000000001084 : 0x0000001E

Shell> mm -io -w 4 -n 1088
IO  0x0000000000001088 : 0x00000001

Shell> mm -io -w 4 -n 10a0
IO  0x00000000000010A0 : 0x000001F8

Shell> mm -io -w 4 -n 10a4
IO  0x00000000000010A4 : 0x000001E0

Shell> mm -io -w 4 -n 10a8
IO  0x00000000000010A8 : 0x00000098


続いて、EG20-T側のGPIOの設定値をゲットします。データシートによると、ふむふむ、こちらは
GPIOが一般的なPCIデバイス(というか、GPIOのPCIデバイス)になってるようです。PCIコンフィグレーション空間のオフセット14hにメモリーベースアドレスがセットされるようです。そして、デバイスIDは8803hということなので、PCIコマンドを使って該当デバイスを探してみました。どうやらバス2、デバイス0、ファンクション2にいるようです。早速レジスタを覗いてみます。今回は通常のPCIデバイスなので、「-i」オプションを使って見やすくして貰います。

Shell> pci 2 0 2 -i

 PCI Segment 00 Bus 02 Device 00 Func 02 [EFI 0002000200]
  00000000: 86 80 03 88 06 00 10 00-00 00 00 FF 00 00 80 00  *................*
  00000010: 00 00 00 00 00 40 00 A7-00 00 00 00 00 00 00 00  *.....@..........*
  00000020: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000030: 00 00 00 00 40 00 00 00-00 00 00 00 0B 01 00 00  *....@...........*

  00000040: 05 50 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *.P..............*
  00000050: 01 00 02 08 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000060: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000070: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000080: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  00000090: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000A0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000B0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000C0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000D0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000E0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*
  000000F0: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  *................*

Vendor ID(0): 8086                     Device ID(2): 8803

Command(4): 0006
  (00)I/O space access enabled:       0  (01)Memory space access enabled:    1
  (02)Behave as bus master:           1  (03)Monitor special cycle enabled:  0
  (04)Mem Write & Invalidate enabled: 0  (05)Palette snooping is enabled:    0
  (06)Assert PERR# when parity error: 0  (07)Do address/data stepping:       0
  (08)SERR# driver enabled:           0  (09)Fast back-to-back transact...:  0

Status(6): 0010
  (04)New Capabilities linked list:   1  (05)66MHz Capable:                  0
  (07)Fast Back-to-Back Capable:      0  (08)Master Data Parity Error:       0
  (09)DEVSEL timing:               Fast  (11)Signaled Target Abort:          0
  (12)Received Target Abort:          0  (13)Received Master Abort:          0
  (14)Signaled System Error:          0  (15)Detected Parity Error:          0

Revision ID(8):     00                 BIST(0F):  Incapable
Cache Line Size(C): 00                 Latency Timer(D): 00
Header Type(0E):    80, Multi-function, PCI device
Class: Device does not fit in any defined classes -  -
Base Address Registers(10):
     Start_Address  Type  Space    Prefetchable?     Size             Limit
  --------------------------------------------------------------------------
          A7004000  Mem   32 bits  No             00000040          A700403F
  --------------------------------------------------------------------------
Expansion ROM Disabled(30)

Cardbus CIS ptr(28):   00000000
Sub VendorID(2C):          0000      Subsystem ID(2E):      0000
Capabilities Ptr(34):        40
Interrupt Line(3C):          0B      Interrupt Pin(3D):       01
Min_Gnt(3E):                 00      Max_Lat(3F):             00


というわけで、ベースアドレスはA7004000hです。これはいわゆるメモリマップドIOです。なので、メモリー空間を見ます。レジスタの範囲はベースアドレス+00h ~ 3Chです。ですが、例によってBLDKのツールで設定するのは以下の8つです。

  • IOH_GPIO_IEN[11:0]
  • IOH_GPIO_IMASK[11:0]
  • IOH_GPIO_IMASKCLR[11:0]
  • IOH_GPIO_PO[11:0]
  • IOH_GPIO_PM[11:0]
  • IOH_GPIO_IM0
  • IOH_GPIO_IM1
  • IOH_GPIO_SRST[0]

これに対応するレジスタオフセットは0、10h、14h、18h、20h、24h、28h、3ch ですね。
コマンドは以下な感じです。

Shell> mm -w 4 -n a7004000
MEM  0x00000000A7004000 : 0x00000000

Shell> mm -w 4 -n a7004010
MEM  0x00000000A7004010 : 0x0000FFFF

Shell> mm -w 4 -n a7004014
MEM  0x00000000A7004014 : 0x00000000

Shell> mm -w 4 -n a7004018
MEM  0x00000000A7004018 : 0x00000000

Shell> mm -w 4 -n a7004020
MEM  0x00000000A7004020 : 0x00000000

Shell> mm -w 4 -n a7004024
MEM  0x00000000A7004024 : 0x00000000

Shell> mm -w 4 -n a7004028
MEM  0x00000000A7004028 : 0x00000000

Shell> mm -w 4 -n a700403c
MEM  0x00000000A700403C : 0x00000000


これで、GPIOに関する必要な設定値はゲットできました。あと、BLDKツールにはSuperIOのGPIOの設定項目があるんですが、TX-50にはSuperIOが乗っかっていないので、設定不能です。というか、SuperIOの余分なコードは本来除去すべきですが、今のところ、ほっときます。

レジスタ値からゲットした値をBLDKツールに入力します。

E600側GPIO設定

EG20-T側GPIO設定


よし。できた。ビルドします。そして、できたBIOSイメージを「70S01905D.EXE」改造作戦で、BIOSチップに書き込んで、起動させてみました。すると、フロッピーがウイーンって、USBメモリのLEDがチカチカしてます。なんか動いてそうです。しかし、依然として、画面やシリアルには何もでないですねー。試しに、キーボードから「reset」(EFIShellのリセットコマンド)と打ってみたら、なんとリセットしました。
どうやら画面表示していないだけで、EFIShellが起動しているようです。おお、やったー。もっと起動中の問題で苦戦するかと思ってましたが、思いのほか動いているようです。(もしかするとGPIO設定前から動いてのかもしれません。)

なんだか、半信半疑なので、EFIShellの「Startup.nsh」(起動スクリプト)にコマンドを書いて結果をファイルにリダイレクトして確認して
みます。
内容は以下のようにしてみます。

fs0:
drivers > drivers.txt
devices > devices.txt
pci > pci.txt

で、やってみたところ、driversコマンド以外はコマンドが無いよエラーでした。どうやらUSBメモリ内のEFIShellではなく、簡易版の内臓EFIShellが起動しているっぽいです。driversコマンドの結果は以下のようになってました。


            T   D
D           Y C I
R           P F A
V  VERSION  E G G #D #C DRIVER NAME                         IMAGE NAME
== ======== = = = == == =================================== ===================
5C 0000000A B - -  1 35 PCI Bus Driver                      PciBusDxe
5D 00000030 D - -  2  - Usb Ehci Driver                     EhciDxe
5E 00000010 D - -  6  - Usb Ohci Driver                     OhciDxe
5F 0000000A B - -  8  4 Usb Bus Driver                      UsbBusDxe
60 0000000A D - -  1  - Usb Keyboard Driver                 UsbKbDxe
61 0000000A D - -  1  - Usb Mouse Driver                    UsbMouseDxe
62 00000011 D - -  1  - Usb Mass Storage Driver             UsbMassStorageDxe
63 00000020 D - -  2  - EFI SD Host Controller Driver       SDController
64 00000020 D - -  2  - UEFI MMC/SD Media Device Driver     SDMediaDevice
65 0000000A D - -  1  - Generic Disk I/O Driver             DiskIoDxe
66 0000000A ? - -  -  - Partition Driver(MBR/GPT/El Torito) PartitionDxe
67 00000010 D - -  1  - SATA Controller Init Driver         AhciDxe
68 0000000A D - -  1  - AHCI Bus Driver                     AhciDxe
69 00000001 ? - -  -  - <UNKNOWN>                           Lpc47m17x
6A 0000000A B - -  1  3 ISA Bus Driver                      IsaBusDxe
6B 0000000A ? - -  -  - ISA Serial Driver                   IsaSerialDxe
6C 0000000A ? - -  -  - PS/2 Keyboard Driver                Ps2KeyboardDxe
6D 0000000A ? - -  -  - PS/2 Mouse Driver                   Ps2MouseDxe
6E 0000000A D - -  1  - Platform Console Management Driver  ConPlatformDxe
6F 0000000A D - -  1  - Platform Console Management Driver  ConPlatformDxe
70 0000000A B - -  1  1 Console Splitter Driver             ConSplitterDxe
71 0000000A B - -  1  1 Console Splitter Driver             ConSplitterDxe
72 0000000A ? - -  -  - Console Splitter Driver             ConSplitterDxe
73 0000000A B - -  1  1 Console Splitter Driver             ConSplitterDxe
74 0000000A ? - -  -  - Console Splitter Driver             ConSplitterDxe
77 0000000A D - -  1  - UGA Console Driver                  GraphicsConsoleDxe
78 0000000A ? - -  -  - Serial Terminal Driver              TerminalDxe
7B 01082032 B X -  1  1 IEGD GOP Driver                     FvFile(FF0C8745-32
7C 0000000A D - -  1  - FAT File System Driver              FvFile(961578FE-B6


うーん。元のBIOSのDriversコマンドの結果と比較しても明らかに違います。間違いなく起動しているようです。

よし、次はなんとかして、画面を出すか、せめてシリアルコンソールが使えるようにしたいところです。


今週はここまでにします。また来週ー。

TX-50開発キットで遊ぶ その5

今週はなんとかして、BIOSを焼いて起動テストまで行きたいところです。

先週の続きで、BLDK付属のSpiUpdate.efiを使って焼いてみようという作戦です。

いんぐりもんぐりして、SST 25VF016Bをゲットしました。(このチップは一時期のマザーボードでよく使われていたようです。)で、やってみたんですが、なんとエラーです。チップ以外にも何かをチェックしているっぽいです。うーん。どうしよっかな。

考えました。ひらめきました。開発元のイノテックさんの主催するEM-CLUBというTX-50のフォーラムでBIOSのアップデートがダウンロードできるのを思い出しました。これを使ってなんとかできないかやってみることにしました。

で、まず、どんな感じか感触を掴むためにアップデートを実行してみます。まず、EM-CLUBから「70S01905D.EXE」を頂きました。これはどうやらDOSで起動させて実行するタイプのようです。
なので、DOSの起動ディスクが必要になります。FreeDOSとかでやるという手もありそうですが、
今回は、王道のフロッピーでやります。久々にUSBフロッピードライブが活躍だー。
Window7のマシンにUSBフロッピードライブつないで、ディスク入れてフォーマット時に、
「MS-DOSの起動ディスクを作成する(M)」にチェックです。Windows7でこれをやるのは初めてでしたが、まだこの機能残ってるんですね。よかったです。


で、このフロッピーに「70S01905D.EXE」を入れればいんですが、なんとこのファイル約2.5MBもあります。フロッピーは1.44MBなので当然、入らんのです。あーあ。

あきらめるのは、まだ早いっす。USBメモリに「70S01905D.EXE」を入れて、フロッピーからDOSを起動させたあとで、別ドライブとしてUSBメモリが認識すれば、実行できるはずです。


よし。FDDとUSBメモリを両方挿して起動です。DOSは普通に起動しました。そして、USBメモリにカレントディスクを移動してみます。なんと、「C:」と思いきや、「B:」ドライブとして認識するようです。「70S01905D.EXE」も見えてますので、実行してみます。せっかくなので、BIOSチップを入れ替えて焼けるかやってみたところ、うまくいきました。別チップに焼いたBIOSで起動成功です。
試しに、SST 25VF016B以外のチップでも試してみましたが、エラーになりました。結局SST 25VF016B必須ですな。

最近気づいたんですが、BIOS中に「F12」キーで起動ドライブの選択メニュー画面に入れます。

で、本題に戻ります。「70S01905D.EXE」を使ってBLDKのBIOSを焼けないかなー。
とりあえず、「/?」を付けて実行してみたらヘルプがでてきました。かなりいろんなオプションがあるようです。どうやら「/G」オプションで現在のBIOSをファイルに保存できるようです。でやってみたら、「NO FILE」というファイル名で現在のBIOSが保存されたっぽいです。これでBIOSのバックアップファイルゲットです。他のオプションもいろいろ試してみましたが、なんだか無視されているような感じです。どうやこのツールは「Insyde Flash Utility for InsydeH2O 1.8.7」というものに、BIOSのROMイメージを合体させたもので、自動的に「/ALL」というオプションが優先されて実行されるようです。

オプションで任意のROMイメージファイルを指定できないかやってみたところ、試した範囲では無視されてだめでした。そこで、ちょっと考え方を変えて、「70S01905D.EXE」をバイナリエディタで編集してBIOSイメージ部分を自分のBIOSイメージと入れ替えてしまうことができれば、焼けるかも。

バイナリエディタで「70S01905D.EXE」を開いて、先ほどファイルに保存したBIOSイメージと同じ内容の箇所を探してみました。なんと、BIOSイメージ2MBはそのまま実行ファイルのお尻から2MBと一致しました。つうことは、この2MBをまんま入れ替えれば、行けるかも。

という訳で、BLDKをビルドしたBIOSイメージと入れ替えてみます。ぬ。BLDKのイメージは1MBですね。うーん。ここは単純に0で埋め尽くしたジャスト1MBのファイルを作ってくっつけます。
で、「70S01905D.EXE」のBIOSイメージ以外のところを切り出したファイルを作ってくっつけます。

そんなこんなして作ったアップデータをDOSで実行してみましたところ、見事動いて、焼けたようです。やったー。めでたくBLDKを動かすことができそうです。

しかし、電源入れたが起動せず。というか、どこまで動いているのか?まったく動いてないのかも判断不能です。

POSTコードを表示する7segLEDとかあればいいんだけどな。

その6に続く。

10/10/2011

CEATEC 2011へ行く

10/08(土)にCEATEC行ってきました。

家電系はなんだか、全体的にタブレットとかのネット端末と家電を直接and/orクラウドで連携みたいなコンセプトが多かったような印象を受けました。あとは、フルHDの4倍の画素数に対応した4k2kのテレビがかなり綺麗な感じがしました。けど、一般放送やゲームや、映画コンテンツが揃わないと無用の長物ですな。今後の動向が気になる気がするところです。

で、個人的に一番見たかったのはFujituのスーパーコンピュータ「京」の実物です。
見てきました。かっちょええっす。SPARC64の8コアCPUが基板に4発乗ってて、水冷です。
で、これが1U(かな?)に入ってて、ラックに積みまくってるのです。
で、本来はこのラックがたくさんあつまって、ひとつのシステムを形成するようです。
ほんで、6次元トーラスなるネットワークでノード間を接続して、効率がよいという話です。

京のシステムボード
京のラック
TOP500で1位ですって。8.162ぺタフロップスですって。うーん。しびれます。
最近のTOP500ではGPUを使ったシステムが多くなってきているようですが、SPARCで1位ってところが、硬派なかんじで素敵です。

10/07/2011

Steve Jobs氏 死去のショックを考える

Steve Jobs氏が死去してしまいました。とても悲しいです。なんだか涙が出てきます。
自分でもここまで、ショックを受けるとは思っていませんでした。

なぜ、こんなに悲しいのか、考えてみました。そう、今日の身の回りにコンピュータが傍らにある
生活は彼が創造してきたものだからです。
思い返してみれば、彼が、コンピュータを身近な物にしてきたのです。彼が居なければ、
もしかすると、現代でもコンピュータは単なる高速計算機か、つまらないオフィス機器でしかなかったかもしれません。
そして、個人が所有するものではなかったかもしれません。また、創造的でエキサイティングでエンターテイメントで、楽しく、美しい物ではなかったかもしれません。

もしそんな世界だったら、恐らく私も若かりし頃にコンピュータに興味を抱くことは、なかったかもしれません。そして、この分野で飯を食ってないかもしれません。

彼について、MacやiPod、iPhone、iPadをヒットさせた功績が取り上げられがちですが、私は、彼の最大の功績は、コンピュータと人の距離を近くしたことだと思います。デバイスはそれを実現するための媒体でしかありません。ハイテクに明るくない女の子でも初めて使った時から快適に使える高度で洗練されたユーザーインターフェイスと、それを実現する美しいハードウェアとソフトウェアデザインは、彼なくして創造されなかったでしょう。

そして、それらを普及させるのに、デバイスをリリースするタイミングのセンスも絶妙です。例えば、iPadはあれより、早くても遅くても、駄目だったと思います。というより、この一連のヒットの流れは、恐らく、かなり前から計算していたんじゃないかと思います。よく、天下を取るには天地人、すなわち天の時、地の利、人の輪がなければ駄目だと言われますが、彼は、それら全てを備えていた(それを得るだけの才能があった)んだと思います。

この世界にとって本当に偉大な人を亡くしました。私もほんのちょっぴりでもJobs氏のようにコンピュータ技術で世界に貢献できるよう日々努力していこうと改めて思います。

命を削りながら私たちにコンピュータの未来を切り開いてくれたJobs氏に感謝を捧げると共に、ご冥福をお祈りいたします。

10/03/2011

TX-50開発キットで遊ぶ その4

よし。BLDKのビルド環境は整ったので、今週は基板側の改造について語ります。

ビルドしたROMを起動させるには、どうにかして、基板にBIOSを焼く必要があります。
考えられる手としては、以下のような手段があります。

  • BIOSチップを外して、ROMライタで焼いて付け直す
  • インサーキットで焼けるROMライタを接続して書き込む
  • 現在のBIOSで起動して、ソフトで書き換える

前者2つが、本来は理想的ですが、ライタの機器が別途必要になってきます。そして、それらの機器は買うと結構高価で、おいそれとは買えないっす。(貧乏なのです)

ライタを自作すると安価にできる可能性もありますが、それなりに手間暇かかるので、さしあたって、
ソフトでなんとかできないか考えます。

幸いBLKDには「SpiUpdate.efi」というEFIシェル上で動作するBIOS書き換えツールが付属しているので、これを使ってみようと思います。
(ソースツリーのCrownBayPlatformPkg\Application\に入ってます。)

なのですが、BLDKのデフォルト設定でビルドしたBIOSがまともに起動する保障はまったく無く、
いきなり書き込んで起動しないと、成仏してしまうので、BIOSチップにソケットをつけて、元々の
BIOSは取っておいて、別のチップをとっかえひっかえできるようにします。
ROMライタが手に入った時もこのほうが便利です。

で、ヒートシンクを外して、どれがBIOSチップかなーと眺めてみて、それっぽいのが乗っかってたのでこれを外して、ソケットをつけます。確証はないです。経験則ですが、まず間違いないでしょう。


で、ここで、問題が生じます。ここにソケットつけると、ヒートシンクと干渉してしまいます。
これは困ったなー。策としては、ソケットを直付けせず、リード線を引っ張ってソケットを付けるか、
小さいヒートシンクを手に入れる。前者の方法はかっちょ悪いし、強度的に不安な感じなので、
後者で行きます。ただ、元々ついてたヒートシンクの大きさだからこそ、ファンレスが実現できてた
んだと思われるので、小さいヒートシンクでは、発熱がやばそうです。なので、ファンを付けることを
考えます。


で、いいのないかなーとAmazonを物色してみました。CPUのサイズを計ってみたところ、22x22mmです。このサイズの汎用ヒートシンクってあんまりないですねー。そしてそのサイズのファンも無いっす。(Amazonで探すのが間違いかもしれませんが。)で、以下の物を注文してみました。



Amazonで買える22x22mmの汎用ヒートシンクはこれしかなかったっす。形状は心もとない感じですが、レッツトライです。そして、ファンはヒートシンクに直接つけられないので、困ってたんですが、クリップ式のやつをみつけたので、これにします。あと、ファンの電源をHDDの電源から分岐して取るためのケーブルです。

後から気づいたんですが、クリップ式のファンを基板の淵にでも付ければいいや位に思ってたんですが、甘かったっす。基板にそんなスペースは無かったっす。ですが、奇跡的にクリップの位置と
ヒートシンクを取り付けるためのネジ部分の突起の寸法が一致してたので、ネジが半分くらい飛び出るようにして、うまいこと固定できました。

で、以下のような感じになりました。




BIOSのソケットは半田ごて的にかなりシンドイ隙間しかないですが、鉄の精神力で何とか付けました。にしても、ヒートシンクが心細いです。コンシューマ向けとはいえ、ヒートシンクの肝である表面積を犠牲にしてまで、なんでこんな形状にしてしまったのか、理解に苦しみます。そのうちいいのが見つかったら交換したいですねー。

一応、元のBIOSをソケットに入れて、起動してみたところ、動いてくれました。EFIShellでしばらく放置しててもサーマルシャットダウンしなかったので、なんとかいけそうです。(OS起動して重い処理させたら落ちるかも)

本題のBIOS書き換えです。作戦としては、元のBIOSでEFIShellを起動して、電源入ったまま別のチップに交換してSpiUpdate.efiを実行してしまおうという、少々荒っぽい方法です。
で、手持ちの適当なSPIチップでやってみたんですが、なんと、このコマンドSSTの25VF016BというSPIチップしかサポートしてないよ的なメッセージがでて、書き換えできませんでした。

うーん。これはコマンドの制約なのか、元のBIOSの制約なのかわかりませんが、困ったちゃんです。
せめてコマンドのソースがあれば別のチップもサポートできるように書き換えできたかもしれませんが、これバイナリのみの提供のようです。

しばらく他の策を考えてたんですが、現状では25VF016Bを手に入れるのが最も安価で手っ取り早そうなので、その方向で考えます。

というわけで、今週はここまでです。また来週がんばります。