10年以上使ってきたmovaからイーモバイルのS12HTにメイン電話をかえました。
ひさしぶりにWindows機さわってます。
…だれかMSM7200のデータシートこっそり送ってくれませんか?(笑)
拡張端子
| 番号 | イヤホン | ビデオ | AC | PC | (ホスト) | ビット
|
Mic/V | 1 | Mic | Video
|
Right | 2 | R | R
|
ID | 3 | SW-AGND | AGND
|
ID | 4 | AGND |
|
AGND | 5 | AGND | AGND
|
Left | 6 | L | L
|
+5V | 1 | | | ←1A | ←0.5A | →8mA | 9800000c&0001
|
D- | 2 | | | | ↓15K | D-
|
D+ | 3 | | | | ↓15K | D+
|
ID | 4 | | | GND | | GND | !9800000c&0002
|
GND | 5 | AGND | AGND | GND | GND | GND
|
miniAケーブルがつながれた(ホスト)かどうかは通例IDで判断するんですが、
ここを1A充電できるかどうかに使ってますね。
ってUSB miniAって規格からキャンセルになってますね。
(08-9-12)
Touch pro
s12htは0xa9800000がMSM_USB_PHYSで、ここにフルスピードなOTG USBが見えていますが、
Touch Proは0xa0800000がMEM_HSUSB_PHYSで、
ここにehci互換なOTG USBが見えています。
下のようにアクセスできますが、USBに電源供給されないとoem_init.dllがクロック有効(サブCPUコマンド)にしてくれません。
mem= (BYTE*)VirtualAlloc(0, 4096, MEM_RESERVE, PAGE_READWRITE);
VirtualCopy(mem, (void*)((DWORD)0xa0800000>>8), 4096
, PAGE_READWRITE|PAGE_PHYSICAL|PAGE_NOCACHE);
VirtualSetAttributes(mem, 4096, 0x80, 0x80, &cur);
a0800000: 0042fa05 000005c2 04020001 00000021
a0800010: 80070b08 00000808 00000000...
a0800100: 01000040 00010011 00000006 00000000
a0800110: 00000000 00000000 00000000 00000000
a0800120: 00000001 00000190 00000000 00000000
a0800130: 00000000 00003000 00000000 00000000 ...
電源供給さえなんとかなればehci.dllを微改造してねえ。
s12htも互換チップのマニュアルはあるんですが結構ohci/ehciと違ってるんで面倒。
ruu_signed.nbhファイル
xda-developersを見ればわかるんだけど、要約。
ruuはrom update utilityの略、
nbはnaked binary(べたデータ)の略。
nbh→nbg
nbgファイルを0x10000バイト毎に区切り、署名をつけて、さらに全体に署名をつけたのがnbhファイル。
//nbhファイル
char マジック[7]= "R000FF\n";
char 不明[16]= 0;
struct ブロック {
int ブロック長= 0x10000; //最後のブロックは<=0x10000
int 署名長= 0x80; //リトルエンディアン
byte フラグ= 1;
byte nbgデータ[ブロック長];
byte 署名[0x80];
} ブロック1, ブロック2, ブロック3…
struct ブロック {
int ブロック長= 0;
int 署名長= 0x80;
byte フラグ= 2;
byte データ[0];
byte 署名[0x80]; //全体の署名
} 署名ブロック;
nbg→個別ファイル
ファイル種類により最大32ファイルを含みます。
//nbgファイル
int マジック[8]= (int)"HTCIMAGE";
char デバイス名[0x20]= "NIKI100**"; //未使用部分は0
int ファイル種類[32]= {0x301,0x200,…,0,0,0};
int オフセット[32]= {0x200,0x1120200,…}; //nbg先頭からのオフセット
int 長さ[32]= {0x1120000,0x40000,…};
char CID[0x20]= "HTC__001";
char バージョン[0x10]= "2.09.405.1";
char 言語[0x10]= "USA";
byte ファイル[32][長さ]; //最大32ファイル
ファイル種類
詳細はxda-developersを参照のこと。
nbhextract.exeによりnbhから個別ファイルへ展開されます。
コード | サイズ | 内容 | 展開ファイル名
|
0x100 | 128KB | IPL initial program loader | XX_IPL.nb
|
0x200 | 256KB | SPL secondary program loader | 01_SPL.nb
|
0x301 | 17MB | サブCPUコード | 00_Unknown.nb
|
0x400 | 100MB | メインCPUコード(CEOS) | 04_OS.nb
|
0x60x | 256KB | スプラッシュ画面 | XX_XXXXSplash.nb
|
ブートシーケンス (以下推測含みます)
最近の機種にはNANDフラッシュが採用されていますが、これは直接コード実行はできず、一度RAM上に展開してから実行するようになっています。
また、NANDフラッシュは出荷時点で不良ブロックがあることがあり、代替ブロックテーブルを参照して別のブロックにアクセスする必要があります。
起動時、MSM7200中のマスクROMによりNANDの最初のブロック(2048バイトx64ページ=128KB)がRAM中に読み込まれ制御が移されます。なお、最初のブロックは不良ブロックでないことが保障されています。これがIPLにあたります。
次にIPLがSPLを代替ブロックテーブルを参照しながらRAMに読み込み、SPLに制御がうつります。SPLはサブCPU(Radio)コードやメインCPUコード(CEOS)をRAMに展開し、それぞれのCPUを起動します。
CEOSにはXIPという仕組みがあり、これはNOR型フラッシュやマスクROMを用いてDLLやEXEの直接コード実行を可能とし、RAMを節約するものです。このアドレスマップの中の共用DLL領域がそれにあたります。
NANDフラッシュの場合いずれにせよRAM上にロードしなければならないのでXIPの意味はあまりないのですが、依然としてサポートされており、XIP DLLはRAM上の解決済みのアドレスへロードされます。
CEからNANDフラッシュはドライバ経由でアクセス可能ですが、代替ブロックや不良ブロック新発生時や書き込みウェアレベリングなどいろいろ面倒な処理をやっているので、素のNANDデバイスがアクセス可能なわけではないです。
サブCPUコード (OO_Unknown.nb)
//サブCPUコード(diam)
int マジック[2]= {0x8a914e07, 0xec55364b};
int 時刻; //1970-1-1 00:00:00からの経過秒
int 不明= 0x03f0;
int 本体長= 0x13c0000;
int 署名長= 0x0a00;
int 不明= 0x59600000; //署名ID?
int 不明= 0x5c260000;
byte 本体[本体長]= {
0000_0020:
struct ブロック { //qcsbl
int マジック[2]= {0x83838383, 0x73d71034};
int 不明= 1;
int ブロック長= 0xa9c;
int 不明= 0x280;
int アドレス= 0x8000e000;
int サイズ= 0x101d4;
int =サイズ;
int アドレス末=アドレス+サイズ;
int 不明= 0;
int =アドレス末;
int 不明= 0;
byte qcsbl情報[ブロック長-0x30];
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} qcsbl;
0002_0020:
struct ブロック {
int マジック[2]= {0xaa01de33, 0xdbfe99af};
int 不明= 1;
int 不明= 0;
byte ゼロ[0x800-16]= 0; //2KB単位に満つるまで
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} 不明;
0004_0020:
struct mibibブロック {
int マジック[2]= {0xfe569fac, 0xcd7f127a};
int 不明= 3;
int 不明= 2;
byte ゼロ[0x800-16]= 0; //2KB単位に満つるまで
struct dirページ {
int マジック[2]= {0x55ee73aa, 0xe35ebddb};
int タイプ= 3;
int 総数= 0x10;
struct {
char 名前[16]; //"0:MIBIB" など
int オフセット;
int 長さ;
int 不明= 0;
} エントリ[総数];
byte 詰め[]= 0xff; //ページが2KB単位に満つるまで
} ディレクトリ情報;
struct ページ {
int マジック[2]= {0xfa0f129c, 0x5a8fb6c9};
int タイプ= 1; //1はヘッダ情報
char 名前[16]; //"0:OEMSBL1"等
byte ゼロ[]= 0; //ページが2KB単位に満つるまで
} oemsblページ0;
struct oemsbl情報 {
int 不明= 1;
int 不明= 3;
int 不明= 0;
int アドレス=0x900000;
int サイズ =0x54724;
int =サイズ;
int =アドレス+サイズ;
int 不明=0;
int =アドレス+サイズ;
int 0;
byte 詰め[]= 0xff; //ページが2KB単位に満つるまで
} oemsbl1;
struct oemsbl情報 {
int 不明= 2;
int 不明= 3;
int 不明= 0;
int アドレス=0xa00000;
int サイズ= 0x1133014;
int =サイズ;
int =アドレス+サイズ;
int 不明=0;
int =アドレス+サイズ;
int 0;
byte 詰め[]= 0xff; //ページが2KB単位に満つるまで
} oemsbl2;
byte obmsblページ3[0x800]= 0xff;
byte obmsblページ4[0x800]= 0xff;
byte obmsblページ5[0x800]= 0xff;
byte obmsblページ6[0x800]= 0xff;
struct ページ {
int マジック[2]= {0xaa7d1b9a, 0x1f7d48bc};
int タイプ= 3;
int 総数= 0x10;
struct {
char 名前[16]; //"0:MIBIB" など
int コード長; (利用されず?)
int データ長; (利用されす?)
int フラグ; //FFFFFFFF=通常、FFFFFFFE=mibib
} エントリ[総数];
byte 詰め[]= 0xff; //ページが2KB単位に満つるまで
} ディレクトリ情報その2;
struct ページ {
int マジック[2]= {0x9d41bea1, 0xf1ded2ea};
int タイプ= 1;
int チェックサム?;
byte 詰め[]= 0xff; //ページが2KB単位に満つるまで
} チェックサム?;
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} OEMSBL1情報;
0006_0020:
struct mibibブロック {
int マジック[2]= {0xfe569fac, 0xcd7f127a};
int 不明= 3;
int 不明= 1; //ここが直前と異なる
byte ゼロ[0x800-16]= 0; //2KB単位に満つるまで
byte ディレクトリ情報[0x800]= 0xff;
struct ページ oemsblページ0;
struct oemsbl情報 oemsblページ1;
struct elf情報 oemsblページ2;
byte obmsblページ3[0x800]= 0xff;
byte obmsblページ4[0x800]= 0xff;
byte obmsblページ5[0x800]= 0xff;
byte obmsblページ6[0x800]= 0xff;
struct ディレクトリ情報その2; //前と全く同じ
struct チェックサム;
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} OEMSBL2情報;
0008_0020〜: 詰め=0xff;
0014_0020:
struct ブロック {
int マジック[2]= {0x5fe85ddf, 0x5264cebc};
int 0, 0;
char 名前[16]= "QCT_BOOT V522511";
byte ゼロ[0x800-0x20]= 0; //2KB単位に満つるまで
byte データ[]; //QCSBLデータ(プログラムコード)
0014_0820〜 コード
0014_f820〜 データ
0015_09f4〜 FF詰め
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} QCSBLデータ;
0016_0020〜: 詰め=0xff;
001c_0020:
struct ブロック {
int マジック[2]= {0xfa0f129c, 0x5a8fb6c9}; //既出マジック
int タイプ=0; //0はデータが続く
byte ゼロ[]= 0; //2KB単位に満つるまで
byte データ[]; //ブロックが128KB単位に満つるまで
} OEMSBL1-0;
001e_0020: struct (同上) OEMSBL1-1;
0020_0020: struct (同上) OEMSBL1-2; 埋めFFあり
//総サイズはmibibブロック.oemsbl1.サイズ=0x54724;
//このサイズはデータ本体、マジック用ページは含まない
0022_0020〜: 詰め=0xff;
0028_0020:
struct ELFブロック {
int マジック= 0x464c457f; //ELF
byte ELFデータ[0x1133014-4];
//サイズはmibibブロック.oemsbl2.サイズ=0x1133014;
//このサイズはelfマジックを含む
byte 詰め[]= 0xff; //ブロックが128KB単位に満つるまで
} OEMSBL2;
};
013c_0020:
byte 署名[署名長];
byte 詰め[]= 乱数; //サブCPUコードが128KB単位に満つるまで
//dirエントリ(diam)
//ディレクトリ情報はQCSBL、OEMSBL1、OEMSBL2の開始ブロック位置のみ有効
ディレクトリ情報 ディレクトリ情報その2 ロードアドレス
開始 (長さ) (コード) (データ) (フラグ)
0:MIBIB 00000000+0000000A 00000004:00000006:FFFFFFFE
0:QCSBL 0000000A+00000004 00000080:00000180:FFFFFFFF 8000e000+000101d4
IPL。OEMSBL1を読み込み。
0:OEMSBL1 0000000E+00000006 00000180:00000180:FFFFFFFF 00900000+00054724
SPL。フラッシュ書き換えやOEMSBL2の読み込み。
0:OEMSBL2 00000014+00000006 00000180:00000180:FFFFFFFF 00a00000+01133014/elf
サブCPUコード本体。このelfはプログラムヘッダはあるけど
セクションヘッダはないのでobjcopyではべたバイナリ化できない。
0:HTC 0000001A+00000010 00000400:00000400:FFFFFFFF
0:AMSS 0000002A+000000C0 00005680:00000980:FFFFFFFF
0:EFS2 000000EA+0000002C 00001100:00000500:FFFFFFFF
0:FOTA 00000116+00000008 00000200:00000200:FFFFFFFF
0:RESERVED 0000011E+00000002 00000080:00000080:FFFFFFFF
0:APPSBL 00000120+00000006 00000180:00000180:FFFFFFFF
0:MISC_MFG 00000126+00000002 00000080:00000080:FFFFFFFF
0:WLAN 00000128+00000002 00000080:00000080:FFFFFFFF
0:SPLASH1 0000012A+00000009 00000300:00000180:FFFFFFFF
0:SPLASH2 00000133+0000000E 00000500:00000200:FFFFFFFF
0:APPS 00000141+00000278 00013B80:00000080:FFFFFFFF
0:EXT_ROM 000003B9+00000047 00002300:00000080:FFFFFFFF
OEMSBL2.ELF //プログラムは仮想空間で実行される…ARM mapping
LOAD off 0x00001000 vaddr 0x17ea9000 paddr 0x17ea9000 align 2**0
filesz 0x0000017c memsz 0x00001000 flags --- 2200000
設定データ
LOAD off 0x00008000 vaddr 0xf0000000 paddr 0x00a00000 align 2**15
filesz 0x0001bfe4 memsz 0x0001fdd8 flags rwx
コード
LOAD off 0x00028000 vaddr 0xf0020000 paddr 0x00a20000 align 2**15
filesz 0x00006000 memsz 0x00006000 flags rw-
"NICTOKL4" "Open Kernel Labs" コードもあり
LOAD off 0x00030000 vaddr 0xb0000000 paddr 0x00a61000 align 2**15
filesz 0x0000e3ff memsz 0x0000e3ff flags r-x
コード "memsection" メモリ管理ライブラリ?
LOAD off 0x00040000 vaddr 0xb0040000 paddr 0x00af0000 align 2**15
filesz 0x00000178 memsz 0x00017000 flags rw-
"0000000..."
LOAD off 0x00041000 vaddr 0xb0d00000 paddr 0x00a38000 align 2**12
filesz 0x00002000 memsz 0x00002000 flags rw-
"ig_naming" "quartz_servers" "AMSS"
LOAD off 0x00044000 vaddr 0xb0e00000 paddr 0x00a3a000 align 2**12
filesz 0x00004000 memsz 0x00004000 flags rw-
"ig_naming" "quartz_servers" "AMSS"
LOAD off 0x00050000 vaddr 0xb0100000 paddr 0x00a26000 align 2**15
filesz 0x00006f9f memsz 0x00006f9f flags r-x
コード "naming.c" "asynch.c"
LOAD off 0x00058000 vaddr 0xb0140000 paddr 0x00a2d000 align 2**15
filesz 0x000000d8 memsz 0x000001b8 flags rw-
データ
LOAD off 0x00060000 vaddr 0xb0200000 paddr 0x00a2e000 align 2**15
filesz 0x000089b3 memsz 0x000089b3 flags r-x
コード "qdms_server"
LOAD off 0x00070000 vaddr 0xb0240000 paddr 0x00a37000 align 2**15
filesz 0x000000d8 memsz 0x0000028c flags rw-
データ
LOAD off 0x00071000 vaddr 0xb0300000 paddr 0x00a40000 align 2**2
filesz 0x00008120 memsz 0x00020a9c flags rwx 80000000
コード "QUARTZ_SERVERS" "KXMUTEX_FLASH_DRV_SHARED"
LOAD off 0x0007a000 vaddr 0x00b07000 paddr 0x00b07000 align 2**12
filesz 0x00003000 memsz 0x00003000 flags r-x 81000000
LOAD off 0x0007e000 vaddr 0x00b0a000 paddr 0x00b0a000 align 2**12
filesz 0x0086f000 memsz 0x0086f000 flags r-x 1200000
LOAD off 0x008ee000 vaddr 0x01379000 paddr 0x01379000 align 2**9
filesz 0x0001ffa4 memsz 0x00ab1100 flags rwx 1000000
LOAD off 0x0090e000 vaddr 0x17300000 paddr 0x17300000 align 2**12
filesz 0x007fa000 memsz 0x007fa000 flags r-x 1200000
thumbコード
LOAD off 0x01109000 vaddr 0x17afa000 paddr 0x17afa000 align 2**12
filesz 0x00029dfc memsz 0x0035e000 flags rw- 1000000
データ
LOAD off 0x01133000 vaddr 0x17e58000 paddr 0x17e58000 align 2**3
filesz 0x00000014 memsz 0x00050040 flags rw- 1600000
CEページへ戻る メモランダムに戻る