SDHCドライバ

SL-A300、SL-Cシリーズ、SL-6000用のSD+SDHCドライバです。

SL-A300/C700/C750/C760/C860/6000 ではSDHCだけでなく、オリジナルドライバでは認識しない 2GB, 4GB SDにも対応しています。

動作報告も多くあり、だいぶ安定していますが、動作保証はできません。自己責任でご使用ください。

また、オリジナルのインストーラ(SL-C3200以外)では、2GB以上のSD, CFの容量計算が正しくできず、ipkg をインストールできません。この問題を解消するには qinstall-fix をインストールしてください。SL-A300のみ、SDドライバに同梱されています。

ipkパッケージ

v2.x 系 (32GB SDHC 対応)

v1.x 系 (4GB以下の SD, SDHC に対応)

※注意※ v1.x系では4GBを超えるメディアは絶対に差し込まないでください!壊れます!

開発用ソース&パッチファイル

SL-Cxx00用にはtetsuさんのところのSDドライバからSDHC対応ドライバへ修正する環境一式が入っています。

4桁機以外は、SL-A300/C750/C760/C860/6000のオリジナルSDドライバは同梱されていません。実機からsharp_mmcsd_m.oをコピーするとビルドできるようになっています。

v1.x 系については更新履歴のリンクから取得してください。

動作環境

SL-A300/C700/C750/C760/C860/C1000/C3000/C3100/C3200/6000 で動作報告があります。

私が動作確認したのは SL-A300, SL-C760, SL-C1000, SL-C3000, SL-6000 の5機種です。

また、以下のSDで確認しました。

  • KINGMAX MSD-128M (miniSD 128MB)
  • Sandisk SDSDM-512 (miniSD 512MB)
  • pqi QMSD-512 (miniSD 512MB)
  • ハギワラシスコム SD-M512 (SD 512MB)
  • GREEN HOUSE GH-SDCM1GC (miniSD 1GB)
  • A-DATA MCSD2GB (microSD 2GB)
  • アイオーデータ SDMC-2G (microSD 2GB)
  • Transcend TS4GSDC (SD 4GB) ※ SL-A300で認識せず
  • Transcend TS4GSD133 (SD 4GB) ※ SL-A300で認識せず
  • Sandisk SDSDQ-4096 (microSDHC 4GB)
  • A-DATA SDHC8GB (SDHC 8GB)
  • PCI PL-SDHC08G (SDHC 8GB)

制限事項

  • 4GBを超えるSDHCは使用不可能 (v1.x)
  • 非SDHC 4GSDが認識せず (SL-A300用 v2.x)

インストール

SL-A300

本体のROMバージョンが1.50Jか確認してください。
ROM 1.50J でないとインストールできません。

SL-A300用のパッケージを本体にインストールしてください。
自動的に再起動はしませんので、インストール後再起動してください。

SL-A300用だけは特別に qinstall-fix 相当の修正も同梱されてきます。

SL-C700/750/760/860, SL-6000

2GB以上の SD を認識させるために他のSDドライバ(SD-Link11b用など)をインストールされている場合は、アンインストールしてください。

機種にあったパッケージ(SL-C700, SL-6000は別なので注意)を本体にインストールしてください。
再起動すると2GB以上のSD、SDHCが使用可能になります。

2GB以上の SD,SDHC への ipkg インストールを可能にするqinstall-fix もあわせてインストールすることをお勧めします。

SL-C1000/3000/3100/3200

tetsuさんのところで配布されているSDドライバをインストールしている場合は、アンインストールして、再起動した後に本パッケージをインストールしてください。

インストールする際には本体にインストールしてください。SDカードなどの外部メディアにはインストールできません。

本体にインストールし、「ソフトウェアの追加/削除」アプリを終了後、再起動すると2GB以上のSD, SDHCが使用可能になります。

SL-C3200 以外の機種をお持ちの方は、2GB以上の SD,SDHC への ipkg インストールを可能にするqinstall-fix もあわせてインストールすることをお勧めします。

使い方

今までと同じです。SDHCカードを入れると下にSDのアイコンが表示されます。

ファイル操作も取り出し方も通常のSDと同じです。

注意事項

無保証です。自己責任でご使用ください。

以下のことを絶対に行わないでください。

  • 4GBを超えるSDHCカードの挿入 (v1.x)

更新履歴

SL-6000用

  • ver2.0 (2010/10/01ipk src
    SL-6000用、初リリース。32GBまでのSD, SDHC に対応。

SL-A300用

  • ver2.0 (2010/03/23ipk src
    SL-A300用、初リリース。32GBまでのSD, SDHC に対応。

SL-C700用

  • ver2.0 (2010/02/20ipk src
    SL-C700用、初リリース。32GBまでのSD, SDHC に対応。

SL-C750/760/860用

  • ver2.1 (2010/03/05ipk src
    取り外し操作後の電源OFF中のカード交換に対応。
  • ver2.0 (2010/02/15ipk src
    4GBを超える容量に対応。
  • ver1.0 (2010/02/05ipk src
    初リリース。2GB以上のSD、4GB SDHCに対応

SL-Cxx00用

  • ver2.1 (2010/02/13ipk src
    Read性能が著しく低下する問題を修正。
  • ver2.0 (2010/02/06ipk src
    4GBを超える容量に対応。
  • ver1.2 (2010/02/02ipk src
    SDHC カードで 2GB 以降にアクセスするとフリーズする問題を修正。
    ipkファイルに不要なファイルが入っていたのを削除。
  • ver1.1 (2010/02/01ipk src
    一部のSDカードが認識できない問題を修正。
  • ver1.0 (2010/01/24ipk src
    初リリース。4GB SDHCに対応

免責事項

このソフトウェアで発生したいかなる損害も、作者は責任を負いません。

使用する本人の責任でご使用ください。

SDHCを使いたい!その2

まず SD と SDHC の違いをまとめると、以下の違いがあるようです。

  • 初期化フェーズのACMD41の前にCMD8(SEND_IF_COND)を実行する必要がある
  • ACMD41の送信時に、HCSビットを1にする必要がある
  • CMD9(SEND_CSD)のレスポンスのフォーマットがCSD v2.0になる
  • CMD17,18,24,25,32,33(READ, WRITE, ERASE)の引数がアドレス指定からブロック指定(1ブロック 512byte固定)になる

ドライバを改造するポイントとしては、初期化処理にCMD8送信とCSDデコードの修正を入れ、READ/WRITE処理でアドレスを512で割れば何とかなるかな??

ということで解析開始。

まずは readelf でシンボルをざっと見てみます。elf フォーマット自体はアーキテクチャ非依存なので、x86 ホストの readelf で ARM の elf バイナリのシンボルを見ることも可能です。

$ readelf -sW sharp_mmcsd_m.o 

とりあえず気になったシンボルは以下の通り

     86: 000032e0   448 FUNC    LOCAL  DEFAULT    1 sd_get_csd
134: 00006cb8 1212 FUNC LOCAL DEFAULT 1 pxa_sd_put_command
142: 00007188 480 FUNC LOCAL DEFAULT 1 pxa_sd_wait_response
143: 00007368 344 FUNC LOCAL DEFAULT 1 pxa_sd_wait_id_response
144: 000074c0 96 FUNC LOCAL DEFAULT 1 pxa_sd_get_response_value

この辺を突破口に解析を進めます。

まずはサイズが小さくて解析しやすそうな pxa_sd_get_response_value から。

$ arm-linux-objdump -Dr sharp_mmcsd_m.o
.....snip....
  000074c0 <pxa_sd_get_response_value>:
74c0: e1a0c00d mov ip, sp
74c4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
74c8: e59f303c ldr r3, [pc, #3c] ; 750c <pxa_sd_get_response_value+0x4c>
74cc: e5932000 ldr r2, [r3]
74d0: e59f3038 ldr r3, [pc, #38] ; 7510 <pxa_sd_get_response_value+0x50>
74d4: e5802000 str r2, [r0]
74d8: e5932000 ldr r2, [r3]
74dc: e59f3030 ldr r3, [pc, #30] ; 7514 <pxa_sd_get_response_value+0x54>
74e0: e5802004 str r2, [r0, #4]
74e4: e5932000 ldr r2, [r3]
74e8: e59f3028 ldr r3, [pc, #28] ; 7518 <pxa_sd_get_response_value+0x58>
74ec: e5802008 str r2, [r0, #8]
74f0: e5932000 ldr r2, [r3]
74f4: e59f3020 ldr r3, [pc, #20] ; 751c <pxa_sd_get_response_value+0x5c>
74f8: e580200c str r2, [r0, #12]
74fc: e5932000 ldr r2, [r3]
7500: e24cb004 sub fp, ip, #4 ; 0x4
7504: e5802010 str r2, [r0, #16]
7508: e91ba800 ldmdb fp, {fp, sp, pc}
750c: 00000268 andeq r0, r0, r8, ror #4
750c: R_ARM_ABS32 .bss
7510: 0000026c andeq r0, r0, ip, ror #4
7510: R_ARM_ABS32 .bss
7514: 00000270 andeq r0, r0, r0, ror r2
7514: R_ARM_ABS32 .bss
7518: 00000274 andeq r0, r0, r4, ror r2
7518: R_ARM_ABS32 .bss
751c: 00000278 andeq r0, r0, r8, ror r2
751c: R_ARM_ABS32 .bss

これをC言語に直していきます。まず、関数の初めと終わりは4GSD へ ipk インストールの道 – その2にも書いたとおり、stmdb でレジスタを保存して、ldmdb でレジスタ復元&リターンをしています。なのでそれ以外の処理を解析します。

内容からC言語風の記述に直すと以下のようになります。

000074c0 <pxa_sd_get_response_value>:
74c0: e1a0c00d mov ip, sp
74c4: e92dd800 stmdb sp!, {fp, ip, lr, pc}
74c8: e59f303c ldr r3, [pc, #3c] ; 750c <pxa_sd_get_response_value+0x4c> // .bss + 0x268
74cc: e5932000 ldr r2, [r3]
74d0: e59f3038 ldr r3, [pc, #38] ; 7510 <pxa_sd_get_response_value+0x50>
74d4: e5802000 str r2, [r0]
// r0 しか使われていないので、引数は1つっぽいとりあえず arg0 と命名
arg0[0] = *(.bss + 0x268);

74d8: e5932000 ldr r2, [r3]
74dc: e59f3030 ldr r3, [pc, #30] ; 7514 <pxa_sd_get_response_value+0x54>
74e0: e5802004 str r2, [r0, #4]
// r0 のオフセットは 4 の倍数なので int か unsigned int っぽい
arg0[1] = *(.bss + 0x26c);

74e4: e5932000 ldr r2, [r3]
74e8: e59f3028 ldr r3, [pc, #28] ; 7518 <pxa_sd_get_response_value+0x58>
74ec: e5802008 str r2, [r0, #8]
arg0[2] = *(.bss + 0x270);

74f0: e5932000 ldr r2, [r3]
74f4: e59f3020 ldr r3, [pc, #20] ; 751c <pxa_sd_get_response_value+0x5c>
74f8: e580200c str r2, [r0, #12]
arg0[3] = *(.bss + 0x274);

74fc: e5932000 ldr r2, [r3]
7500: e24cb004 sub fp, ip, #4 ; 0x4
7504: e5802010 str r2, [r0, #16]
arg0[4] = *(.bss + 0x278);

7508: e91ba800 ldmdb fp, {fp, sp, pc}
return;

750c: 00000268 andeq r0, r0, r8, ror #4
750c: R_ARM_ABS32 .bss
7510: 0000026c andeq r0, r0, ip, ror #4
7510: R_ARM_ABS32 .bss
7514: 00000270 andeq r0, r0, r0, ror r2
7514: R_ARM_ABS32 .bss
7518: 00000274 andeq r0, r0, r4, ror r2
7518: R_ARM_ABS32 .bss
751c: 00000278 andeq r0, r0, r8, ror r2
751c: R_ARM_ABS32 .bss

C言語風記述だけを抜き出して、関数風にすると

void pxa_sd_get_response_value (int *arg0)
{
arg0[0] = *(.bss + 0x268);
arg0[1] = *(.bss + 0x26c);
arg0[2] = *(.bss + 0x270);
arg0[3] = *(.bss + 0x274);
arg0[4] = *(.bss + 0x278);
return;
}

こんな感じになりました。

.bss + 0x268 に何かシンボルが定義されてないか調べてみると・・・

$ readelf -a sharp_mmcsd_m.o
:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
:
[10] .bss NOBITS 00000000 009b14 000280 00 WA 0 0 4
:
Symbol table '.symtab' contains 310 entries:
Num: Value Size Type Bind Vis Ndx Name
:
136: 00000268 0 NOTYPE LOCAL DEFAULT 10 w0
137: 0000026c 0 NOTYPE LOCAL DEFAULT 10 w1
138: 00000270 0 NOTYPE LOCAL DEFAULT 10 w2
139: 00000274 0 NOTYPE LOCAL DEFAULT 10 w3
140: 00000278 0 NOTYPE LOCAL DEFAULT 10 w4

.bss (section 10) の 0x268 〜 0x278 は w0 〜 w4 として定義されているようです。

以上のシンボルを反映させて、さらに引数名をそれらしく命名すると、

void pxa_sd_get_response_value (int *resp)
{
resp[0] = w0;
resp[1] = w1;
resp[2] = w2;
resp[3] = w3;
resp[4] = w4;
return;
}

こんな感じになります。こうして処理を理解しながら改造ポイントを探っていきます。

とりあえず、今回はここまで。

リナザウでも SDHC を使いたい!

久しぶりに Amazon をのぞいてみたら非SDHCの4GSD (TS4GSDC)がついに品切れになってました。
もう手に入らないのかぁ。今となっては 2GSD じゃ物足りないしなぁ。SDHC使えるようにならないかなぁ。

Angstrom 環境(kernel-2.6)なら SDHC も使えるらしいので、純正環境(kertnel-2.4)でもドライバ次第で使えるはずなんですが、SD ドライバのソースが開示されていないので手も足も出ない状態です。

無謀にも kernel-2.6 からバックポートしようかなぁとも思ったんですが、ブロックデバイスのドライバは書いたことないし、SDHCの規格知らないし。。。
あと、うまくポーティングできたとしても、タスクトレイのアイコンと同期させるのは無理だろうし。。。
うーむ。

と、まぁ、以前からそんなことを考えてはいたのですが、ある日、SDHC のドライバを書いたことがある会社の先輩にSDHCについて何気なく聞いてみると、「SDとSDHCは初期化位しか差はないよ。あとはほとんど同じ」と言われました。

え?まじ? 初期化だけごまかせればいいってこと?
それくらいなら Binary Hack で何とかなるかも?? <- 無謀 ^^;

ということで、今月の初めくらいからtetsuさんのとこで配布されている4GSD対応SDドライバの解析を始めてみました。少しずつですが解析が進んでいるのと、ちょうど最近コメントでSDHC関係の書き込みがあったりしたので、4GSD へ ipk インストールの道シリーズのように経過を書いていこうと思います。

あ、解析の結果、ダメだったという可能性もありますので、あまり期待せず、ゆるーく見守っていただけるとありがたいです (^^;

まず、必要なものを集めます。

まずSD AssociationからSDHC の簡易仕様書がダウンロードできます。簡易仕様書ではSDHCドライバは書けないと勝手に思っていたのですが、そんなことはなく、ちゃんとすべて書いてあるようです(と前述の先輩が言ってました)。英語だからってちゃんと読んでなかったのがバレバレです。

あとは参考になりそうなのが、Angstrom の kernel 2.6 カーネルです。kernel 2.6 用ではありますが、PXA270のちゃんと動作するドライバのソースはとても貴重です。

Angstrom はカーネルだけポンと取得することができない(沢山パッチを当てて最終ツリーになる)ので、bitbake 環境を構築する必要があります。ここを参考に作業します。
カーネルツリーだけが欲しいので、最後の bitbake コマンドは以下のように linux-rp で実行します。

$ bitbake linux-rp 

とりあえず、最低限ですが、情報元は準備できました。次回からはドライバを解析していきます。

qgmap-0.2.0 リリース (続き)

qgmap 0.2.0 リリースの続きです。
昨日書いていたのですが力尽きてしまいました (^^;

カスタムPOI機能は、 ユーザが自由に位置情報を追加できる機能のことです。
本物のモバイルGPS機器ではPOIの検索等もできますが、今のところ表示と情報表示の機能だけ使えます。

カスタムPOIのフォーマットは、カンマで項目を区切ったCSV形式で、以下の順番で項目が並んでいます。

経度,緯度,名称,コメント

緯度、経度指定は小数点を含む度指定です。度.分秒指定ではありませんので注意です。

カスタムPOIの設定はメニューのカスタムPOIから行います。

メニュー
メニュー

CustomPOIをクリックすると、以下のようなダイアログが表示されます。

カスタムPOI設定ダイアログ
カスタムPOI設定ダイアログ

左から id , 表示の有無, 表示ズームレベル, 名前とアイコンが表示されます。
「表示」のチェックアイコンをクリックすることで表示の有無を切り替えることができます。

「追加」を押すと以下のダイアログが表示されます。

カスタムPOI追加
POI追加ダイアログ

上の「POI:」の欄にCSVファイルを指定します。
「Zoom:」 にはアイコンを表示するズームレベルを指定します。7の場合、ズームレベルが7〜0の時にアイコンが表示されます。
「Icon:」には表示するアイコンを設定します。「追加」ボタンからアイコンを追加できます。POIアイコンに指定できる画像は 16×16 ドットまでです。
「名前:」には、カスタムPOIの分類の名前を入力します。

OK を押下すると、カスタムPOIファイルを内部のデータベースに追加します。大量のPOIを登録する時は時間がかかり、固まったように見えますが処理しているので辛抱強く待ってください。
いずれ、プログレスバー表示をつける予定です。

ちなみに、データベースは /home/zaurus/Settings/qgmap-poi.db に作られます。
HDD機以外では内蔵フラッシュに書き込むので、空き容量に注意してください。いずれSD等の外部メディアに置けるようにしたいと思っています。

POIが表示されると以下のようにPOIファイルの座標の場所に指定したアイコンが表示されます。


POI表示

256x256dot の地図画像 1 枚あたりアイコンは 500 個まで表示できます。それを超えると以下のように「たくさんあるよ」アイコンが表示されます。

500個を超えると・・・

POIアイコンをクリックすると、そのアイコンが中央に位置するようスクロールし、以下のような情報表示ウィンドウが表示されます。

POI情報表示
POI情報表示

POIの説明文は改行を含むことができます。ただ、あまり多くの行は表示できないのでご注意ください。大体、名称3行、詳細3行くらいまででしょうか。

 

と、0.2.0 の新規機能の説明を駆け足で書きましたが、説明が下手なのでなんか複雑そうに読めるかと思いますが、使ってみればすぐわかると思います。

カスタムPOIのデータはGetLocInfoというソフトを使うとYahoo!電話帳などから簡単に作れるようです。(まだ使ってみてないですが^^;)

今回結構大幅な変更を加えたため、ミドルバージョンをあげて0.2.0にしてみました。
ただ、地図の描画をスレッド化するにあたり、本来はやってはいけない処理を行っているため、もしかすると若干不安定になっているかもしれません。

私が軽くテストした感じでは問題なかったためリリースしていますが、固まったり、落ちたりする可能性もあるので、そういった症状に遭遇した場合はコメントをいただけるとありがたいです。あまりに不安定な場合は元の処理にもどします。

0.2.x は POI 関係の機能を充実させようかなと思っています。例えば、名称検索や最寄りのPOI検索など。コンビニのPOIを入れておいて、最寄りのコンビニ検索とか、都内でスタバなどの最寄りのカフェ検索とかができたら便利かなーと。

SQLiteによるちゃんとしたデータベースを実装したので、POIとはちょっと違いますが、ようやく住所検索も実現できそうです。

少しずつ改良していきます。

新年のごあいさつ & qgmap-0.2.0 リリース

あけましておめでとうございます。
去年は色々と大変な一年でしたが、多くの方々に助けていただいた一年でもありました。
そのぶん、今年は少しでもいろいろな人のお役に立てればと思っています。
今年もよろしくお願いします。

ということで、2010年初リリースは qgmap 0.2.0 です。→ダウンロードページ

本当は冬休み前にリリースして、テストがてら自分でも帰省や旅行に使おうと思っていたのですが、間に合いませんでした ^^;

今回の変更点は以下の通りです。

  • カスタムPOI対応 (アイコン表示、クリックによる情報表示)
  • 地図描画のスレッド化
  • 地図座標表示

まず、カスタムPOIの最低限の機能を実装しました。
GARMINと同じ CSV 形式のカスタムPOIファイルを読み込ませ、アイコンを登録することで、地図上にアイコンを表示することができます。

カスタムPOI表示
カスタムPOI表示 (駅の位置に電車アイコンを表示)

また、地図上のアイコンをタップすることで情報表示を行うことが可能です。

POI情報表示
POI情報表示

今後は名前による検索や最寄りのPOI検索などもできるようにしたいと思っています。

また、今回地図描画周りを大きく変更しました。 地図のロードやカスタムPOIのアイコン描画を別スレッドで処理するようにしたので、描画中は「Loading…」と表示され、描画完了次第表示するようになりました。

この様子のスクリーンショットを撮ろうとしたのですが、うまく撮れませんでした。起動してみるとすぐわかると思います。

最後は、sugarware さんご要望の、座標表示(?)機能です。GM_Liteの「!」キー相当です。地図を追加ダウンロードする際に、down_imgs.pl に書く座標を表示します。
qgmapでは ! キー(Shift+1)がポジション保存で使用しているので、「Z」キーに割り当ててあります。

座標表示
座標表示機能

ちょっと長くなってしまったので、細かい使い方は次のエントリで書きたいと思います。