ジャンル不定の日記です。

PITファイルの解析とパーティションのリサイズ

中古で買ったGALAXY S II SC-02Cをメインスマホとして使っているが、
古くてもストレージ16GBと十分な容量の機種だが、仮想SD領域が11.5GBもあってdata領域が2GBしかない。
既にアプリ入れるのに不足しちゃってるので、パーティションのリサイズやった。

Samsungスマホのパーティション情報はpitファイルというので更新でき、
調べたところPIT Magicというツールでpitファイルを改造してる情報は出てきたのだが、このPIT MagicはWindows用アプリ。
Windows使うのはめんどくさいのでPITファイル解析してLinuxのバイナリエディタでやった。

まずfdiskでパーティション情報を確認した。
# fdisk /dev/block/mmcblk0
Found valid GPT with protective MBR; using GPT


Command (m for help): p
Disk /dev/block/mmcblk0: 30777344 sectors, 2740M
Logical sector size: 512
Disk identifier (GUID): 52444e41-494f-2044-4d4d-43204449534b
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 30775262

Number  Start (sector)    End (sector)  Size       Code  Name
   1            8192           49151       20.0M   0700  EFS
   2           49152           51711       1280K   0700  SBL1
   3           53248           55807       1280K   0700  SBL2
   4           57344           73727       8192K   0700  PARAM
   5           73728           90111       8192K   0700  KERNEL
   6           90112          106495       8192K   0700  RECOVERY
   7          106496          311295        100M   0700  CACHE
   8          311296          344063       16.0M   0700  MODEM
   9          344064         1597439        612M   0700  FACTORYFS
  10         1597440         5791743       2048M   0700  DATAFS
  11         5791744        29925375       11.5G   0700  UMS
  12        29925376        30769151        412M   0700  HIDDEN

拡大したいdata領域はラベルが"DATAFS"になっているパーティションだが、
容量も少なく先頭に近い"EFS"領域の数値とバイナリエディタのデータを照らし合わせた。

↑バイナリエディタの画面だが、パーティション名である"EFS"の手前に8byteが空っぽで、
その前の8byteに4byteずつ2つの値があるような気配。
というわけで16進→10進変換してみたが、
リトルエンディアンで逆読みすると 2000 と A000 になる。10進だと 8192 と 40960 になる。
先にfdiskでパーティション情報を確認していたが、EFSの開始セクタと最初の4byteの値が完全一致。
それと次の4byteを足すと 49152 になるが、終了セクタ+1の値になる。開始セクタが1セクタ目になることを考えるとサイズに完全一致する。
DATAFSと後ろにあるUMSでも同じように計算してみたが、同様にfdiskの値と一致する。
これ変えれば開始位置とサイズ変えれそう。

PITファイルには他にもデータがあるが、変えるのはdataと後ろのfat領域だけなので失敗しても復旧可能と考え、改造を実施した。

元のPITは、
DATAFSの開始が 00601800 で サイズが 00004000 となっている。
サイズは10進で 4194304セクタ なので3倍して 12582912 にすることにしたが、16進だと C00000 となる。
つまり、
00004000 → 0000C000

UMSの開始セクタは 5791744 → 14180352 となるが、16進だと 00605800 → 0060D800 となる。
サイズは次のHIDDEN領域の開始セクタからUMSの開始セクタを引いて 15745024 なので、00407001 → 0040F000 となる。


↑変更箇所に赤枠をつけたが、
40 → C0
58 → D8
7001 → F000
に変更。


dataと仮想SD領域は壊れるのでPITをflashする前にバックアップだが、追加SDを使ってバックアップした。

# mkdir /sdcard/sd0
# cp -a /sdcard0/* /sdcard1/sd0
仮想SDのバックアップはFATなので単にコピーするだけでOKと判断。

dataのバックアップは方法考えたが、resize2fsコマンドが入ってたので失敗した場合にTWRPで復元することも考え、
TWRPでバックアップしてflashしたあとでresize2fsで拡大することにした。
だが、TWRPバックアップ&リストアはディスクイメージ焼く感じじゃなくてコピーする感じぽい。
単にTWRPバックアップ&リストアするだけで目的のサイズになった。


$ sudo heimdall download-pit --output official.pit
解析に使ったPITと実機のPITが違ってたら困るので、PITをダウンロードしてmd5sumで確認した。
同一だったので焼いた。
$ sudo heimdall flash --repartition --pit custom.pit --KERNEL zImage
どうも --repartition する場合は、どこかのパーティションをついでに焼かないとできないらしい。
でKERNEL領域にCWMを入れる際に使ったzImageを焼いたのだが、何も変わらないつもりだったのだがTWRPがCWMに変わっちゃってた。
この機種のリカバリは仕様がわかりにくい。
KERNEL領域にCWMではなくRECOVERY領域にTWRPを焼いたほうが良かった。
CWMからカスROM導入手順で元に戻した。


TWRPを起動してadb shellして、
# fdisk /dev/block/mmcblk0
Found valid GPT with protective MBR; using GPT


Command (m for help): p
Disk /dev/block/mmcblk0: 30777344 sectors, 2740M
Logical sector size: 512
Disk identifier (GUID): 52444e41-494f-2044-4d4d-43204449534b
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 30777310

Number  Start (sector)    End (sector)  Size       Code  Name
   1            8192           49151       20.0M   0700  EFS
   2           49152           51711       1280K   0700  SBL1
   3           53248           55807       1280K   0700  SBL2
   4           57344           73727       8192K   0700  PARAM
   5           73728           90111       8192K   0700  KERNEL
   6           90112          106495       8192K   0700  RECOVERY
   7          106496          311295        100M   0700  CACHE
   8          311296          344063       16.0M   0700  MODEM
   9          344064         1597439        612M   0700  FACTORYFS
  10         1597440        14180351       6144M   0700  DATAFS
  11        14180352        29925375       7688M   0700  UMS
  12        29925376        30769151        412M   0700  HIDDEN
パーティションは目論見通りDATAFSのサイズが増え、UMSの終了位置とHIDDENの開始位置も問題なし。

TWRPのWipeでAdvanced Internal-Storageで仮想SDを初期化して、
# cp -a /sdcard1/sd0/* /sdcard0
で復元。
dataの方はリストアしただけで目的サイズになってた。
dataの方はリストアでリサイズされてたんで仮想SDの方も普通にバックアップ&リストアでいいのかも。

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
tmpfs                   405084        20    405064   0% /dev
tmpfs                   405084      2044    403040   1% /tmp
/dev/block/mmcblk0p7    100784      4528     96256   4% /cache
/dev/block/mmcblk1p1   7712768   2409472   5303296  31% /sdcard1
/dev/block/mmcblk0p10
                       6192688   1654332   4538356  27% /data
/dev/block/mmcblk0p11
                       7857148    495872   7361276   6% /sdcard0
/dev/block/mmcblk0p11
                       7857148    495872   7361276   6% /and-sec
こんな感じになった。

リブートして問題なし。
Android上でも目的のサイズになってた。