0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

続フォトフレームHack

Last updated at Posted at 2022-07-04

以前あきらめたmipsなフォトフレームをまたいじってみました。

以前にページに調べた情報も追記してあります。

このターゲットはmips4Kでmipsとしては後期のアーキテクチャです。またメモリも8Mバイトと結構大きいのも魅力です。

SOCの中にプリプートローダーのROMがあって、そのコードでSPI Flashの先頭の64KをSDRAMの0x80000000から貼り付けて、実行を移している。

おそらくブートローダーもコマンドオペレーションが可能なのではないかと思われますが、入り方がわかりません。

そして、SDRAM上のブートローダーがSPI Flashの中のlzo圧縮されたThreadXをメモリに貼り付けて起動していることがわかりました。

ThreadXはExpress Logic社のクローズドソースのRTOSで2019年にMSに買収されていました。

lzo圧縮は圧縮サイズと圧縮データがいくつか並ぶような構造のようです。このターゲットの場合は一つのブロックだけで圧縮されているようです。lzoのオープンソース(GPL)使ってるような気がします。

lzoはライブラリのlzoとコマンドのlzopにソースに分かれています。しかしlzoの方のexamplesディレクトリの下に簡単な圧縮解凍プログラムのlzopack.cというソースがあります。

このコードを改造してこのブートローダーが使用できる圧縮データを作れるようにしてみました。

オリジナルのブートローダーに無限ループのプロクラムを実行されせてみます。

無限ループのコードはこれです。

ビルドできたファイルを元のブートローダーとcatしてflashのザイズの2Mにしてflashromでspi flashに焼いてみます。

BOOT SPI
.B(128)P(1)D(1)M(0)
..
------------ [SPMF28XX Boot Loader] ------------
1 memProfile.pheapStart=8000D9A0
=========>new buddy system<============
new buddy system start_addr=0xA06FF000, size=0x100000
IOTRAp=200

[loadLzoFW] run,807FF000
[loadLzoFW] run,807FF000
[loadLzoFW] run,807FF000
[loadLzoFW] run,807FF000
[loadLzoFW] run,807FF000
[loadLzoFW] run,807FF000
[serialFlashDetect] run,dmaMode=0
. buf=A06FF010,size=256
EXEC round=16
   0 | 53;50;49;46;20;52;53;56;EF;BE;00;00;F1;0E;0F;F1;
   1 | 00;00;00;00;7F;00;00;00;00;00;00;00;00;00;00;00;
   2 | 00;00;00;00;00;05;00;07;7F;00;00;00;19;00;00;00;
   3 | 71;02;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
   4 | 8C;20;15;00;01;00;80;00;00;01;00;00;00;02;00;A0;
   5 | 7F;00;00;00;04;00;00;00;01;00;1C;00;20;71;00;B0;
   6 | 00;00;00;00;40;70;00;B0;00;00;00;00;50;70;00;B0;
   7 | 02;00;00;00;02;00;0C;00;54;70;00;B0;00;02;00;00;
   8 | 01;00;24;00;5B;70;00;B0;02;00;00;00;73;70;00;B0;
   9 | 28;00;00;00;80;70;00;B0;02;00;00;00;E6;70;00;B0;
   A | 02;00;00;00;01;00;0C;00;23;40;00;B0;00;00;00;00;
   B | 00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
   C | 00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
   D | 00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
   E | 00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
   F | 00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;
[loadLzoFW] run,lzoSrc = 0xA06B0000,lzoSize = 0x4E200
[loadLzoFW] run prsvHeader->realFwBlks=19,prsvHeader->nrRealFW=271
.Using LZO firmware
..........[loadLzoFW] run,dstLen = 88
[loadLzoFW] run , _exceptVect = 0x80010000;80000280
 buf=B0001000,size=16
EXEC round=1
   0 | 00;00;00;00;00;00;06;00;00;00;00;00;00;00;01;00;

run,dstLen = 88となっていて、圧縮前のバイナリファイルと同じサイズなのでlzoはうまくいってると思われます。

uartを探してみたのですが、見つからなかったので、ブートローダーのprintルーチンを探り当てて、Hello Worldしてみました。

EXEC round=1
   0 | 00;00;00;00;00;00;06;00;00;00;00;00;00;00;01;00;
Hello World!!
MORIMORI 1234

0x2cのブロック数のところからのイメージを読み込むようです。ThreadXでは0x19(25)になっていました。ここを1にしてbootの直後にイメージを置くことができました。

printルーチンは例外の中にあるのではないかと思います。 mips16の部分があり見つけるのに手間取りました。

コードはgithubに上げてあります。

newlibを引っ付けてみたのですが、うまく動きません。。。 bootのprintルーチンはgpレジスタを使っていて、newlibでもgpレジスタを使うためにコンフリクトしていたようです。

オリジナルのバイナリを逆アセンブルしてみてluiがブートには0xb000しかなく、ThreadXには0xb001もあるので、IOはブートに必要なIOは前半の32Kにあり、それ以外が後半32Kにあるものと推測されます。

 % grep ",0xb000" boot.txt | awk '{print $4}' | sort | uniq -c
   3 a0,0xb000
   5 a1,0xb000
   1 a2,0xb000
   5 a3,0xb000
   7 s0,0xb000
   3 s1,0xb000
   4 t0,0xb000
  26 v0,0xb000
  19 v1,0xb000

ブートにUSBのメッセージが含まれるのでUSBは前半32Kにあると思われる。ThreadX部分のアップデートがブートで出来るようにしているものと思われます。

メモリマップ

アドレス 機能
0x80000000-0x807fffff RAM
0xb0000000-0xb000ffff IO
0xd0000000- ?

bootのIOの初期化

80000410:       00b0083c        lui     t0,0xb000
80000414:       01000924        li      t1,1
80000418:       a22009a1        sb      t1,0x20a2(t0)
8000041c:       a12009a1        sb      t1,0x20a1(t0)
80000420:       10000924        li      t1,16
80000424:       384009a1        sb      t1,0x4038(t0)
80000428:       304009a1        sb      t1,0x4030(t0)
8000042c:       0f000924        li      t1,15
80000430:       600009a1        sb      t1,0x0060(t0)
80000434:       8b00093c        lui     t1,0x8b
80000438:       45022935        ori     t1,t1,0x245
8000043c:       640009ad        sw      t1,0x0064(t0)
80000440:       01000924        li      t1,1
80000444:       890009a1        sb      t1,0x0089(t0)
80000448:       040000a1        sb      zero,0x0004(t0)
8000044c:       081000ad        sw      zero,0x1008(t0)
80000450:       0c1000ad        sw      zero,0x100c(t0)
80000454:       ffff0924        li      t1,-1
80000458:       000009a1        sb      t1,0x0000(t0)
8000045c:       001009a5        sh      t1,0x1000(t0)
80000460:       041009ad        sw      t1,0x1004(t0)
80000464:       01580924        li      t1,22529
80000468:       081009a5        sh      t1,0x1008(t0)
8000046c:       701000a1        sb      zero,0x1070(t0)
80000470:       00d0093c        lui     t1,0xd000
80000474:       601009ad        sw      t1,0x1060(t0)
80000478:       00d0093c        lui     t1,0xd000
8000047c:       ff1f2935        ori     t1,t1,0x1fff
80000480:       641009ad        sw      t1,0x1064(t0)
80000484:       58000985        lh      t1,0x0058(t0)
80000488:       000100a5        sh      zero,0x0100(t0)
8000048c:       020100a5        sh      zero,0x0102(t0)

objdumpはオフセットを10進数で表示するのを16進数に変えてあります。

一文字出力は以下のようです。

80007d58:       ff00a530        andi    a1,a1,0xff
80007d5c:       01118290        lbu     v0,4353(a0)
80007d60:       00000000        nop
80007d64:       42110200        srl     v0,v0,0x5
80007d68:       01004230        andi    v0,v0,0x1
80007d6c:       fbff4010        beqz    v0,0x80007d5c
80007d70:       00000000        nop
80007d74:       0800e003        jr      ra
80007d78:       081185a0        sb      a1,4360(a0)

printは

0x800025cc(mips16)->0x80003948(mips)->0x80007d58(mips)

で処理されているようです。出力先を代えることが出来るようにするためか、関数ポインターをつかってるようで、追うのが骨でした。

ステータスレジスタがデータポートより前にありuart互換ではないようです。

0xb0000000-0xb0007fffにありそうなIO

  • 割り込み
  • タイマー
  • GPIO
  • シリアル
  • IR
  • SPI
  • USB
  • SD ?

0xb0008000-0xb000ffffにありそうなIO

  • LCD (MIPI DSI?)

LCDはRDB入力なので、メモリにフレームバッファを設定して、クロックを作ってその領域をDMAしてくれるエンジンが入っているのではないかと思われます。

threadxは97d84(+10000)までがコードのようです。

  97c0f ?Dio
  97c22         h"l
  97c4f ?#J{
  97c85  1'A-
  97cb1 n#q`s
  97d84 empty
  97d94 image
  97da4 audio
  97db4 video
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?