128MB化の作業手順を書き上げました。後継者求む。
ページ作成: ヤマケン Page created: YamaKen <yamaken at bp.iij4u.or.jp>
Use Excite_web_translation to translate this page into English. Sorry for inconvenience.
dd </dev/urandom >/dev/null count=1 bs=110M
やはりハードが怪しい。OpenZaurus環境で何回か起動を試みたが、再現性のないSEGVやIllegal Instruction等が発生し、時々はrootでログインできるところまで行く。uname -aした時の文字化けパターンからアドレスが正しく入力できてない(間に合ってない)気がする
ちょっとハズレ。SDRAMの後半64MB部分(内部的に別チップとして扱われている部分)のSDRAM初期化プロセスが正しく行われていなかった。詳しくはMRS(Mode Register Set)コマンドの発行部分のコードにバグがあり、コマンドが発行されていなかった。これにより正常動作していなかった。
今のところこれが一番疑わしい。
ページテーブル初期化後に後半64MB全域にアクセスしてみる。arch/arm/mm/init.cあたり
ブートローダがCS0パーティションに対して行ったはずのpowerup sequenceをCS1にも行ってみる。プリチャージ、auto refresh、MRSの各コマンド発行
SDRAMチップとPXA255共同購入のアンケート実施中。
これがなければe550GX購入には踏み切れませんでした。感謝します
コラム「SL-C700メモリ増設への挑戦」(ヤマケン)を掲載
SDRAMの各種動作解説。MRS等
e550GXから取り出したもの。2.5V動作
本来C700に適合するもの。3.0 or 3.3V動作
SL-5500, SL-A300に搭載されているもの。3.0 or 3.3V動作
SDRAMチップ2個分のリボール作業にかかる時間は以下の通り。ただし再融解が不要な場合
| チップのクリーニング | 20分 |
| Solderquik BGA preformを使ったハンダボール装着 | 32分 |
| 洗浄 | 42分 |
| 仕上げ | 31分 |
| 合計 | 2時間5分 |
SDRAMチップ2個分の除去作業にかかる時間は以下の通り。
| SDRAMチップを外す | 12分 |
| 冷却 | 10分 |
| ハンダ除去 | 5分 |
| フラックス除去 | 7分 |
| 強制乾燥 | 5分 |
| 合計 | 39分 |
1個外すたびに5分間自然冷却する
SDRAMチップ2個分のハンダづけ作業にかかる時間は以下の通り。
| フラックス塗布 | 19分 |
| 位置合わせ | 10分 |
| リフロー | 12分 |
| 冷却 | 10分 |
| LEDライトを使った目視検査 | 4分 |
| 電圧測定による動作確認 | 4分 |
| 合計 | 59分 |
素人BGAリワークの最重要ノウハウ。通常BGAのハンダ付けではクリームハンダを端子に塗布するが、個人レベルの作業では塗布しない方がうまく行く。以下のような理由による
一度基板上にチップを置いてから位置合わせを行う事になる。このため、クリームハンダが塗布してあるとそれが塗り広げられてハンダブリッジの原因になる
クリームハンダは熱すると表面張力が落ちて平面的に広がるのに加え、フラックスが混入されているので融解時に近くのハンダと結合する力が大きい。このため位置合わせを正確に行わないとハンダブリッジを誘発する触媒になってしまう。これに対して、基板上の予備ハンダは強い表面張力で端子のパッド内に留まっているため、ブリッジを誘発せず位置合わせマージンを大きくできる
一つ一つの端子に竹串等で塗布しても精度が出ないのでハンダブリッジや接続不良の原因になる。ステンシルを使った塗布が一般的だが、CSP54パッケージ用には安価な使い捨てステンシルが存在しない
Linuxザウルス開発メモ/ハードウェア/BGAリワークの「ヒートガンの扱い」に従ってSDRAMチップを1個づつハンダづけする
5分間自然冷却する
横から照らし、ハンダボールの欠損が無いか確認する。ブリッジが発生している場合、端子の位置にハンダボールが無くなっている場合がある。内側の端子は確認できないので、大きな失敗を発見するのが目的。明らかに失敗していたらチップを除去して作業をやり直す
SDRAMチップの後半領域を利用可能にするため、CS1(Chip Select 1)をジャンパ配線する
eCosで使われているブートローダ。Dreamcast Linuxのブート等にも使われており汎用性が高い。(今のところ)ソースの質はメンテナによりまちまち
--- linux-c700-b500-20021214-rom1_00.orig/arch/arm/kernel/head-armv.S Thu Aug 29 12:27:20 2002 +++ linux-c700-b500-20021214-rom1_00/arch/arm/kernel/head-armv.S Sun Apr 13 08:25:29 2003 @@ -145,6 +145,9 @@ teq r7, #0 @ invalid architecture? moveq r0, #'a' @ yes, error 'a' beq __error +#if defined(CONFIG_PXA_CORGI_128MB) || defined(CONFIG_PXA_CORGI_64MB) + bl cpu_xscale_sl_modify_sdram_config +#endif bl __create_page_tables adr lr, __ret @ return address add pc, r10, #12 @ initialise processor
--- linux-c700-b500-20021214-rom1_00.orig/arch/arm/mach-pxa/sharpsl_suspend.S Tue Jan 14 12:07:55 2003 +++ linux-c700-b500-20021214-rom1_00-yk3/arch/arm/mach-pxa/sharpsl_suspend.S Sun Apr 27 13:54:40 2003 @@ -43,6 +43,24 @@ #include "sharpsl_param.h" + +#define PXA_PHYS_MD_BASE 0x48000000 +#define CORGI_PHYS_DISABLED_SDRAM 0xac000000 +#define PXA_MDCNFG_ORG_MASK 0xff +#define PXA_MDREFR_DRI_SHIFT 12 + +#if defined(CONFIG_PXA_CORGI_128MB) +#define PXA_MDCNFG_ORG 0xCB +#define PXA_MDREFR_DRI 0x17 +#elif defined(CONFIG_PXA_CORGI_64MB) +#define PXA_MDCNFG_ORG 0xC9 +#define PXA_MDREFR_DRI 0x17 +#else +#define PXA_MDCNFG_ORG 0xA9 +#define PXA_MDREFR_DRI 0x27 +#endif + + /* * cpu_pxa_do_suspend() * @@ -1047,6 +1068,37 @@ .align 5 .text +ENTRY(cpu_xscale_sl_modify_sdram_config) + mov r2, #PXA_PHYS_MD_BASE - - + ldr r3, [r2, #MD_MDCNFG] + bic r3, r3, #PXA_MDCNFG_ORG_MASK + orr r3, r3, #PXA_MDCNFG_ORG + str r3, [r2, #MD_MDCNFG] + ldr r3, [r2, #MD_MDCNFG] + + ldr r3, [r2, #MD_MDREFR] + mov r3, r3, lsr #PXA_MDREFR_DRI_SHIFT @clear DRI(1) + mov r3, r3, lsl #PXA_MDREFR_DRI_SHIFT @clear DRI(2) + orr r3, r3, #PXA_MDREFR_DRI + str r3, [r2, #MD_MDREFR] + ldr r3, [r2, #MD_MDREFR] + + @power-up sequence to initialize CS1 partition of the SDRAM + ldr r2, =CORGI_PHYS_DISABLED_SDRAM + str r3, [r2] @issue Precharge All and Auto Refresh #1 + str r3, [r2] @issue Auto Refresh #2 + str r3, [r2] @issue Auto Refresh #3 + str r3, [r2] @issue Auto Refresh #4 + str r3, [r2] @issue Auto Refresh #5 + str r3, [r2] @issue Auto Refresh #6 + str r3, [r2] @issue Auto Refresh #7 + str r3, [r2] @issue Auto Refresh #8 + + @issue MRS command to the SDRAM including partition 1 + mov r2, #PXA_PHYS_MD_BASE + @ldr r3, [r2, #MD_MDMRS] + mov r3, #0 @some MRS field is overridden by MDCNFG value + str r3, [r2, #MD_MDMRS] + + mov pc, lr
Linuxカーネルが認識するメモリ容量を変更。神木さんのメモを参考にした。
--- linux-c700-b500-20021214-rom1_00.orig/arch/arm/mach-pxa/corgi.c Tue Jan 14 12:07:55 2003
+++ linux-c700-b500-20021214-rom1_00-yk3/arch/arm/mach-pxa/corgi.c Sun Apr 27 13:34:52 2003
@@ -258,7 +258,17 @@
fixup_corgi(struct machine_desc *desc, struct param_struct *params,
char **cmdline, struct meminfo *mi)
{
- SET_BANK (0, 0xa0000000, 32*1024*1024);
+ u32 corgi_ram_size;
+
+#if defined(CONFIG_PXA_CORGI_128MB)
+ corgi_ram_size = 128;
+#elif defined(CONFIG_PXA_CORGI_64MB)
+ corgi_ram_size = 64;
+#else
+ corgi_ram_size = 32;
+#endif
+
+ SET_BANK (0, PHYS_OFFSET, corgi_ram_size * 1024 * 1024);
mi->nr_banks = 1;
#if defined(CONFIG_BLK_DEV_INITRD)
setup_ramdisk (1, 0, 0, 8192);
@@ -271,7 +281,7 @@
#ifdef CONFIG_SHARPSL_BOOTLDR_PARAMS
if (params->u1.s.page_size != PAGE_SIZE) {
params->u1.s.page_size = PAGE_SIZE;
- params->u1.s.nr_pages = 32 * 1024 * 1024 / PAGE_SIZE;
+ params->u1.s.nr_pages = corgi_ram_size * 1024 * 1024 / PAGE_SIZE;
params->u1.s.ramdisk_size = 0;
params->u1.s.flags = FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT;
params->u1.s.rootdev = ROOT_DEV;
クロック変更時に実行されるFCSまわりのコードでMDCNFG, MDREFRの値がハードコーディングされている。これをメモリ容量の設定に応じた値に変更した。
--- linux-c700-b500-20021214-rom1_00.orig/arch/arm/mach-pxa/sharpsl_suspend.S Tue Jan 14 12:07:55 2003 +++ linux-c700-b500-20021214-rom1_00-yk2/arch/arm/mach-pxa/sharpsl_suspend.S Thu Apr 17 01:13:37 2003 @@ -43,6 +43,23 @@ #include "sharpsl_param.h" + +#define PXA_PHYS_MD_BASE 0x48000000 +#define PXA_MDCNFG_ORG_MASK 0xff +#define PXA_MDREFR_DRI_SHIFT 12 + +#if defined(CONFIG_PXA_CORGI_128MB) +#define PXA_MDCNFG_ORG 0xCB +#define PXA_MDREFR_DRI 0x17 +#elif defined(CONFIG_PXA_CORGI_64MB) +#define PXA_MDCNFG_ORG 0xC9 +#define PXA_MDREFR_DRI 0x17 +#else +#define PXA_MDCNFG_ORG 0xA9 +#define PXA_MDREFR_DRI 0x27 +#endif + + /* * cpu_pxa_do_suspend() * @@ -840,8 +859,8 @@ MD_BASE: .word io_p2v(0x48000000) CodeOnCacheAdr: .word CodeOnCache -MDCNFG_ValAdr: .word 0x01A819A9 -MDREFR_ValAdr: .word 0x000BC027 +MDCNFG_ValAdr: .word 0x01A81900 | PXA_MDCNFG_ORG +MDREFR_ValAdr: .word 0x000BC000 | PXA_MDREFR_DRI CCCR_ValAdr: .word 0x00000145 MSC0_ValAdr: .word 0x7ff03DD8 MSC1_ValAdr: .word 0x2274225C @@ -898,9 +917,9 @@ .text CodeOnCacheAdr_100: .word CodeOnCache_100 -MDCNFG_ValAdr_100: .word 0x01A81AA9 +MDCNFG_ValAdr_100: .word 0x01A81A00 | PXA_MDCNFG_ORG @@MDREFR_ValAdr_100: .word 0x0009C02F -MDREFR_ValAdr_100: .word 0x0009C027 +MDREFR_ValAdr_100: .word 0x0009C000 | PXA_MDREFR_DRI CCCR_ValAdr_100: .word 0x00000241 MSC0_ValAdr_100: .word 0x7ff01888 MSC1_ValAdr_100: .word 0x1244123C @@ -942,9 +961,9 @@ LCCR3VALUE_121: .word 0x04000007 CodeOnCacheAdr_121: .word CodeOnCache_121 -MDCNFG_ValAdr_121: .word 0x01A81AA9 +MDCNFG_ValAdr_121: .word 0x01A81A00 | PXA_MDCNFG_ORG @@MDREFR_ValAdr_121: .word 0x0009C02F -MDREFR_ValAdr_121: .word 0x0009C027 +MDREFR_ValAdr_121: .word 0x0009C000 | PXA_MDREFR_DRI CCCR_ValAdr_121: .word 0x00000121 MSC0_ValAdr_121: .word 0x7ff01888 MSC1_ValAdr_121: .word 0x1244123C @@ -993,8 +1012,8 @@ LCCR3VALUE_145: .word 0x0400000C CodeOnCacheAdr_145: .word CodeOnCache_145 CCCR_ValAdr_145: .word 0x00000145 -MDCNFG_ValAdr_145: .word 0x01A819A9 -MDREFR_ValAdr_145: .word 0x000BC027 +MDCNFG_ValAdr_145: .word 0x01A81900 | PXA_MDCNFG_ORG +MDREFR_ValAdr_145: .word 0x000BC000 | PXA_MDREFR_DRI MSC0_ValAdr_145: .word 0x7ff03DD8 MSC1_ValAdr_145: .word 0x2274225C MSC2_ValAdr_145: .word 0x7FF024F4
以下のコメントにあるように、レジューム時にはカーネルの制御下を離れたブートローダ(ファームウェアと呼んだ方が適切だと思うが)上のコードが実行されている。その中でMDCNFGがハードコーディングされているのではないかと予想し、
/* * cpu_pxa_resume() * * entry point from bootloader into kernel during resume * * Note: Yes, part of the following code is located into the .data section. * This is to allow sleep_save_sp to be accessed with a relative load * while we can't rely on any MMU translation. We could have put * sleep_save_sp in the .text section as well, but some setups might * insist on it to be truely read-only. */ .data .align 5 ENTRY(pxa_cpu_resume)
ここにSDRAM設定の修正を突っ込めばレジュームが動作するようになるのではないかと思って以下のようにcpu_xscale_sl_modify_sdram_config()を呼び出すようにしてみたが、動作しなかったのでコメントアウトしてある。この追求は後回し。128MB化が先。
--- linux-c700-b500-20021214-rom1_00.orig/arch/arm/mach-pxa/sleep.S Mon Aug 26 15:01:51 2002
+++ linux-c700-b500-20021214-rom1_00/arch/arm/mach-pxa/sleep.S Sun Apr 13 08:41:24 2003
@@ -104,6 +104,9 @@
mov r0, #I_BIT | F_BIT | MODE_SVC @ set SVC, irqs off
msr cpsr_c, r0
+#if defined(CONFIG_PXA_CORGI_128MB) || defined(CONFIG_PXA_CORGI_64MB)
+@ bl cpu_xscale_sl_modify_sdram_config
+#endif
ldr r0, sleep_save_sp @ stack phys addr
ldr r2, =resume_after_mmu @ its absolute virtual address
ldmfd r0, {r4 - r9, sp} @ CP regs + virt stack ptr
brendanさんの指摘により、問題は解決した。上記の推理と対策は正しかったのだが、pxa_cpu_resume()と同等の機能を実装したcpu_pxa_resume()が存在し、実際のレジューム時にはそちらが使われているのでSDRAM設定の修正が実行されていなかった。見事に罠にはまってしまっていた。
ENTRY(cpu_pxa_resume) +#if defined(CONFIG_PXA_CORGI_128MB) || defined(CONFIG_PXA_CORGI_64MB) + bl cpu_xscale_sl_modify_sdram_config +#endif ldr r3, sleep_param_p @ Sleep mode information data structure mov r0, r3
linux-c700-b500-20021214-rom1_00-yk3.diff
項目追加お願いします。こちらで気付かない項目もあるので。こちらで調整するんでホントに適当でOKです。
ノウハウの交換(と祭)。みんなでやれば怖くない。ただしあくまでも自己責任で。
Linuxザウルス開発メモ/ハードウェア/共同購入でSDRAMチップとPXA255共同購入を試みましたが、SDRAMの方は通常ルートではダメでした。Genio e550GXを潰して128MB化しようという方はいませんか? 伝統工芸の後継者が見つからないような寂しさを感じます。
「もしやるなら参加したい」という方は下のコメント欄にアピールして下さい
都内で電源が確保でき、工作しても文句の出ない場所
「カーネル改変」の「ブート直後のレジスタ設定変更」で以下のように書いた通り。
NetBSDのソースも見てみたかったが、何となくライセンス的に気持ち悪くなりそうな気がした(丸写しに近いコードになりそう)のでやめておいた。非GPLなソースを参考にする際のガイドライン的な資料をご存じの方は教えて下さい
入手できたら即換装します → 共同購入しました