2010年09月15日

ベースバージョンをr237に変更

qi-hardware が ingenic が出しているソースを Ingenic Linux 2.6.31.3, READ ONLY: live Ingenic development tree として管理している。

いままでベースにしていた r108 は 4 月頃にここから svn で取得したものだが、大分違ってきているので、再度 svn でダウンロードした。(r237) 。

どうせ全然動かせていないし、(追加はしたが)変更もしていないに近いので今のうちにベースを上げておこうとおもう。

例によって 次に整理したものを置いておく。


これをベースにして、いまで使ってきた config ベースでビルドできるようにして、さらに ソース Tree の シュリンク版も作る。

さて、最初の問題は、JZ4750L ではビルドできない所がある点。あと、JZ4750L だけサポート外にされている Kconfig がある JZCHAR と MMC(HOST) 。

jz_ubcomm は入れずに、これらだけを直す変更をしたパッチを作ることにする。

また、JZ4750 がどのようにコンパイルされるか知りたいので、JZ4750 の apus もビルドできるようにしておく。(ただし USB HOST や ETHERNET , WIRERESS , YAFFS 関係 と NFS_V4関係は入れない )

ECC 関係で変なところがある。CONFIG_HW_BCH_ECC=y とすると YAFFS の中のコードを call するのだ。

    -- 適当に取ってきたスナップショットなので、コードが中途半端なのかも。

.. それはともかく、JZ4725B は JZ4750 と同じ機能を持っているのかどうかが重要だ。

データシートを見てみると、JZ4725B は、4/8/12 bit ECC をサポートしているのに対して JZ4725 は 4 bit ECC しかサポートしていない。データシートを見ると記述がいろいろ違うのだが、

  • JZ4740 まで Hamming or Reed-Solomon ECC をサポート。
    -- CONFIG_MTD_HW_HM_ECC or CONFIG_MTD_HW_RS_ECC
  • JZ4750 4/8/12 bit BCH ECC をサポート
    -- CONFIG_MTD_HW_BCH_ECC (CONFIG_MTD_HW_BCH_4BIT or CONFIG_MTD_HW_BCH_8BIT)

ということなのだろう。APUS は CONFIG_MTD_HW_BCH_8BIT を使っており、JZ4725B も同じで良いはず。

JZ4750L(JZ4725B) を同じにするには、ソースで JZ4750L が仲間はずれにされているところを修正していかなければならない。Kconfig だけでなく nand_base.c にもこのようなコードがあった。

    drivers/char/Kconfig の RTC_JZ , drivers/usb/gadget/Kconfig の UDC_USE_LB_CACHE , あと、driver/usb/gadget/udc_hotplug.c
    他にもあるが、touch-panel サポートなど、JZ4725B にない機能とかは外す。

ところで、ECC の種類の意味が判ったが、それがどのように OOB に格納されるのか?

used free
off len off len
2Kpage
Hamming 40 24 22 38
Reed-Solomon 28 36 2 26
4bit-BCH(?) 24 28 2 22

4Kpage
Hamming 80 48 2 78
Reed-Solomon 28 72 2 26 100 28
4bit-BCH 24 56 2 22 80 48
8bit-BCH 24 104 2 22

nand_base.c に テーブルがあって こんな風に定義されていた。(Hamming はオリジナルからあるが、それ以外は ingenic が定義している)

  • 8bit-BCH は、4Kpage で 104 バイト使用する。512B あたり 13バイト。4bit-BCHは、512B あたり 7 バイト。RS は 9 で、HM は、6 。

  • あとオフセット 0,1 の 2 バイトは free じゃないし特定の目的に使われるようだ。

  • 2Kpage では、8bit-BCH は 4bit-BCH と同じ定義 .. 入らないのだが ..

それはそうとして、USBBOOT の OOB の定義はこれとどう関わるのだろう? あと NAND からの boot では、ECC をチェックすると書いてあるが、どの ECC を使うか分かるのだろうか?
疑問は尽きない。特に JZ4750 系の資料を持っていないので、カーネルのコードから推測する以外にないのがつらい。

まぁ、ここではコードの詳細に入りたくないのだが ... この部分が変なので、ベースとしてどう扱おうか 困っているので、ちょっと見ているわけだ。でも、ついでなので続ける。

前からの疑問がある。USBBOOT の config で NAND_ECCPOS という項目があるのだが、これだけどう扱って良いのかわからない。

512B 毎に ECC を取って 6-13 バイトのデータを OOB に格納するらしいということは分かった。で、オフセットはどうも ECC の種類や ページサイズ で違うということも分かった。

で、NAND_ECCPOS とどう関係してくるのだろう?

    ちょっと USBBOOT の方を見てみる。

    NAND_ECCPOS は、stage2 で使う。これが nand_4750_init() のパラメータとして渡り eccpos という変数に格納される。(もし 0 なら 3 を入れておく)

    nand_4750_init() では、bchbit という変数も持っていて、それもパラメータで受ける。デフォルトは 8bit 。
    -- config に NAND_BCHBIT というのがあった。

    これが 8bit の場合 par_size = 13 としていて、それ以外(4bit) では 7 としている。

    オリジナルファームウェアがどのように使っているのか定かではないのだが、どうも 24 をいれればよいらしい。

    2Kpage だと 入らないので 4bit 以外の選択はないが、4Kpage はどうなのだろう? 8bit なのか 4bit なのか?

      対応しようと思っているものはほとんど 4Kpage なのだが、Neo Slim 3000 だけが 2Kpage。config で定義しないといけないので、とりあえず 4bit としておく。

    もうすこし見てみる。パラメータに NAND_BADBLOCKPOS(defualt 0) と NAND_BADBLOCKPAGE(default 127) がある。

    これは、消去ブロック(128ページ分) 全体を バッドブロック とするための情報で 127ページの oob の先頭 1 バイトが 0xff でなければ バッドブロックと判断している。

    それとは別に nand_mark_bad_page() という 関数があって page 単位で バッドブロックとする処理がある。これは、データと OOB に対して 0x00 を Write する。(バッドブロックなので 結果が 0x00 になるとは限らない )

    消去ブロック全体を バッドブロックとする nand_mark_bad_4750() では、nand_mark_bad_page() を NAND_BADBLOCKPAGE に対して行っている。

      NAND_BADBLOCKPAGE を 128 にすると、ブロックの最初 2 ページと 最後 2 ページに対して nand_mark_bad_page() する。

    ちなみに、Jz4740 では、PAR_SIZE は define で 9 になっている。ecc_pos は設定できるがデフォルト 6 で 2Kpage を想定。Reed-Solomon 固定ということなのだろう。ただし、offset のデフォルトは (ingenic の)Linux と合わない。

だいぶ分かってきた。

YAFFS の中のコードを call する点については、r108 → r237 で、nand_sw_bch_ops() という関数が追加されたことに関係するもので、nand_base.c と jz4750_nand.c だけを r108 ベースに戻してしまえば問題なくなる。

これで、コードのベースを確定できた。



ingenic オリジナル r237 の ソース tree に対して、linux-jz4725b-r237-base.patch を当てたもの から FILES-shrinked.list のファイルだけにしたものが開発のベース。

付属の config_jz4725b_base, config_apus_test, config_lyra_test で ビルドできることを確認。(その他の config はたぶんファイルが足りない)


こちらは、上記のパッチをあてて、shrink した
ソース tree 。

さて、OOB についてもう少し。

    A-41 や P5-5 の OOB を dump すると次のようなデータになっている。

    A-41
    011700 ff ff ff ff ff ff ff ff 57 59 4b b0 8b e5 53 90
    011710 9e 57 e5 96 be 61 37 3e 97 c8 45 27 dc 88 1d c6
    011720 14 58 75 2d 33 8a d6 f5 55 fe c5 62 53 09 3f 85
    011730 e3 b4 ac 14 bc 67 42 d0 77 64 0e 8d 39 f3 e6 98
    011740 96 bc 00 53 97 3b b8 0e 16 57 59 4b b0 8b e5 53
    011750 90 9e 57 e5 96 be 61 37 3e 97 c8 45 27 dc 88 1d
    011760 c6 14 58 75 2d 33 8a d6 f5 55 fe c5 62 53 09 3f
    011770 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    P5-5
    026180 ff ff ff ff ff ff ff ff 77 6d 9f 45 e5 81 c5 4e
    026190 14 c6 58 f0 9e 81 bb 91 79 8a 41 9b bf 82 5d ce
    0261a0 1d 91 8f 5f cd 5f a2 29 eb de 63 1e 87 2a 13 b6
    0261b0 ce ce d8 36 96 ae 3c 74 3e 99 75 78 e0 a4 f3 33
    0261c0 95 5b 31 19 55 6e 5b c0 cc 27 85 c0 fc 4b b5 6d
    0261d0 6f a6 31 57 f7 31 7b f6 83 fd ab 17 7f ca 32 d4
    0261e0 b7 5b 23 e0 2d 5f f2 a8 66 96 f9 eb 16 8c 7f b7
    0261f0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    A-33
    061400 ff ff ff ff ff ff ff ff 2a 18 bd 90 dd e4 90 3d
    061410 6d f2 d3 fd 53 44 aa 74 52 9e cf 9b b0 71 81 77
    061420 6f 05 44 aa 74 52 9e cf 9b b0 71 81 77 6f 05 44
    061430 c8 a1 c2 41 0f af ba e1 ab 6a 7c 73 44 aa 74 52
    061440 9e cf 9b b0 71 81 77 6f 05 44 aa 74 52 9e cf 9b
    061450 b0 71 81 77 6f 05 33 86 fb 18 0a ce 41 84 a3 5f
    061460 b4 1f 60 44 aa 74 52 9e cf 9b b0 71 81 77 6f 05
    061470 44 aa 74 52 9e cf 9b b0 71 81 77 6f 05 44 aa 74

    先頭 8 バイト目からデータがはじまり、(最初の2つ)後ろ 16 バイトは 0xff 。データの量は 104 バイト。

    -- ということは、8bit BCH を使っており OOBPOS=8 ということだ。

    104 バイト以外が全部 0xff ということは、書き換え回数などの管理データは、まだ初期状態? (A-33 は、後ろ 16 バイトにデータが入っている )

    こういうデータだから Linux の管理に合わず Linux で NAND を使うなら共有できない。( ECC の位置だけ無理やり合わせても、管理データの使い方が同じとは思えないので無理 )

    ちなみに、2Kpage の Neo Slim 3000 を見てみたが、全然パターンが違う。原則にも合わない。ひょっとしたらバグで ちゃんとデータが取れていないのかも。

    Neo Slim 3000 の分析は後回しにしようと思う。


追記:jz_ubcomm-001 パッチを作った。

linux-jz4725b-r237-base をいれた上でこのパッチを当てる。

jz_ubcomm は、とりあえず作った分まで 入れた(= 動かない)。

いままでは、f4750l を借りて入れていたが、
CONFIG_JZ4725B_NS3K=y
とかした上で、board-ns3k.c board-ns3k.h なども作って入れることにした。

追加した config は、
CONFIG_JZ4725B_NS3K
CONFIG_JZ4725B_A41
CONFIG_JZ4725B_A33
CONFIG_JZ4725B_P55
の 4つで、board は、board-ns3k , board-a41 だけ作った。
(一応将来の変更も考えて、JZ4750L_NS3K ではなく、JZ4725B_NS3K とした。使わないが、SOC_JZ4725B も作ってある。)

あと デバッグ用に jz_backlight() というのを作ったが、apus , lyra にはないのでビルドできなかったので、スタブを入れてビルドだけはできるようにした。

board-ns3k.h をチェック

    JZ_EXTAL : 水晶の周波数を入れる。

    APUS は、24MHz , LYRA(4740) は 12MHz 。-- では JZ4725B は? ... とりあえず USBBOOT で 12MHz の設定で動作しているので、12MHz で良いだろう。( 動かし出したら時刻のずれから正確な値が分かるはず。)

    GPIO_XX : 各種 GPIO の定義

    GPIO_SD1_VCC_EN_N
    GPIO_SD1_CD_N (MSC1_HOTPLUG_PIN)
    GPIO_SD1_WP (MSC1_WP_PIN)
    GPIO_DC_DETE_N
    GPIO_CHARG_STAT_N
    GPIO_DISP_OFF_N (LDC_REV ?)
    GPIO_USB_DETE (GPIO_UDC_HOTPLUG)
    GPIO_LCD_PWM

    MMC/SD に 電源を供給する スイッチがあるらしい。-- 考慮してなかった。Write Protect も。充電IC の STAT にも普通つながているものらしい。DC デテクトも USB の専用機能でできるものだとばかり思っていた。LCDの OFF 機能だけは、LCD の線から選ぶはずだとは思っていた。どうも 思っていたより 4-5 本余計に必要なようだ。 --- JZ4725B では、とても厳しいはずだ。

    ちなみに LCD 関係は、drivers/video/jz4750_lcd.h で定義する。

    それ以外にオーディオ関係(スピーカ ON/OFF)があるはずだが .. どこでるのだろう?


追記:NAND のパーティション

NAND の パーティションは、drivers/mtd/nand/jz4750_nand.c で定義している。

機種情報を定義したので パーティションも一応定義しておこうと思う。

まず、最初の問題は、オリジナルファームウェアと 共存するか否かを決めないといけない。

今まで調べてきた限りでは、無理という結論で。好きなように使おうと思う。

APUS を見てみると、2GB を

    4MB ブート用 (代替ブロック 2)
    4MB カーネル用 (代替ブロック 2)
    504MB rootfs 用 (代替ブロック 10)
    512MB DATA 用 (代替ブロック 10)
    1024MB VFAT用 (代替ブロック 10)

としている。

こうやって細かく分けてしまうと、ウェアレベリングをそのパーティション内でやらざるを得ないという問題が出る。スワップは領域が小さい上に書き換え頻度が多くなることになり、持つこと自体が厳しくなる。そのため、大きな領域にして UBI パーティションとして、その後の分割は後で考えることにしたい。

UBI 以外は、ブート用と カーネル用のパーティションに分ける。
ただし、使うのは先頭だけで、隙間をたっぷり取っておく。(
隙間の使い道はあとで考える。)

    4MB ブート用 (代替ブロック 2)
    60MB カーネル用 (代替ブロック 2)
    残り UBI 用 (代替ブロック 10)

こんなところでどうだろう。

ところで、カーネルは、zImage を カーネル用パーティションの 先頭から 置く ことにして、ブートローダをどうするか?

実をいうと U-BOOT は使うのをやめることにした。

開発用は USBBOOT でいける。NAND からのブートも stage1/stage2 をベースにすれば自分で作れる。

U-BOOT が持っている高度な機能は使わない/使えない。

  • ファイルシステムからの読み込み
    UBI の上に構築された 、ファイルシステムを読めないといけないので無理と判断。その機能を使わないなら ベタイメージのロードなので、stage2 でもできる。
  • シリアルのオペレーション
    普通は開発用に シリアルを使うのだが、使わずに USBBOOT でなんとかすると決めた。USBBOOT を使うのであれば NAND に プログラムを置く必要はなく、U-BOOT の出番はない。


ちなみに、stage1 は、メモリの初期化など最低限度のハードウェアの初期化をする。それ以降なら メモリを使える。

stage1 の先頭は、ハードウェアの config 情報が入っている。これをバイナリに埋めておけば、ロード→実行 で 最低限度のハードウェアの初期化が終わるわけだ。

現在のサイズは 6KB 。stage2 をロードするコードを入れないといけないが 8KB 以内にできそうだ。

stage2 といっても 最低必要なのは、カーネルとカーネルパラメータをロードして 制御を渡すだけのもの。

とは言っても多少の機能は付けるつもり。

  • USB-BOOT に使うボタン(A-41/33 なら MENU) と ソフトウェア電源ボタン (A-41/33 なら PLAY/PAUSE) だけは 全部の機種で使えるので、多少のオペレーションもできるだろう。

  • LCDを扱うのは面倒だが、バックライトだけは使える。点滅させたりして、エラーを知らせることは出来る。


ところで、Nand からの ブートについて。

Jz4725 を使う SAKC のページに 0x80000004 から開始するということが書いてあったのだが ...

Neo Slim 3000 の先頭は

00: ff 55 55 55 55 55 55 55 ff ff ff ff 01 00 11 04
01: 00 00 00 00 21 e0 e0 03 00 00 e9 8f 21 e0 20 01
02: 00 80 1d 3c 00 40 bd 37 00 80 19 3c b8 06 39 27

となっていて、命令が入っているとは思えない。不思議に思っていたのだが ... u-boot のコードを見たら理解できた。

u-boot の cpu/mips/start.S を説明すると...

    オフセット
    0-3 : NAND が 8bit バスの場合 0xff,0x55,0x55,0x55
    4-7 : 常に 0x55,0x55,0x55,0x55
    8 : NAND_ROW_CYCLE==3 の場合 0xff
    9 : NAND_PAGE_SIZE!=512 の場合 0xff
    10 : NAND_PAGE_SIZE==2048 の場合 0xff
    11 : 不明
    12-15 : 最初の命令

ということらしい。上記 は、Neo Slim 3000 の例だが、A-41, A-33 ともに全く同じだった。

オフセット 8-11 は all 0xff なので、上記とは少し意味が違うようだが、とにかく 元の機種と同じもの -- all 0xff にすれば良いのだろう。

逆に 0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55 で始まっていないものは、Jz4750系の ROM イメージではない。

    実をいうと、各機種の ROM イメージのバックアップを取ってあるのだが、P5-5 だけ全然違う。... どうも失敗したようだ。

    追記:何回やっても違う。
    先頭はこんなパターン。

    00: 80 80 1f 3c 00 00 ff 27 00 90 80 40 00 98 80 40
    01: 80 00 09 3c 00 68 89 40 40 00 08 3c 00 fc 08 35
    02: 00 60 88 40 03 00 08 24 00 80 88 40 00 80 08 3c
    03: 00 40 09 35 00 e0 80 40 00 e8 80 40 00 00 08 bd

    256MB を 2 回 ダンプして cmp をかけ 不一致が起きるのは、107950 MB のところ。(USBBOOT で電源を入れるだけでなぜ不一致が起きるのか分からないが 他のマシンでも起きる ... それはともかく 頭の方はいつも同じ )
    だからと言ってこれでブートできるとは思えないのだ。... うーん困った。(バックアップが確定しないとイジる気が起きない)

ここまで分れば、nandbootの head.S などを参考に自作したほうが、見通しが良く便利。

jz_ubcomm-002 パッチ

まだまだ整理途中。動かそうともしていないし、ubcomm も無変更。


linux-jz4725b-r237-base をいれた上でこのパッチを当てる。

  • 常に base からの差分でパッチを作る予定 。
  • もし shrink 版で足りないファイルが出てきても、パッチは存在するものとして作成する予定で、エラーになったらオリジナルから取ってくる必要がある。
posted by すz at 23:12| Comment(0) | TrackBack(0) | Jz47xx(Linux)
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス: [必須入力]

ホームページアドレス: [必須入力]

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/40723446
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック