OPPO/realme/OnePlusのシステムイメージの中身を取り出す方法のメモです。
目次
HUAWEIが開発したEROFSに変更されている
OPPO/realme/OnePlus (と一部のXiaomiスマホ) のシステムイメージでは、最近ではext4ではなくEnhanced Read-Only File System、EROFSと呼ばれるファイルシステムが使われるようになりました。
EROFSはHUAWEIによって開発された読み取り専用のファイルシステムで、Androidなどのスマートフォンでの利用を前提に開発されています。
Linux 5.4でメインラインカーネルにマージされたため、OPPOも利用するようになったのでしょう。
GSIビルドにもEROFSが使われるようになるなど、GoogleもEROFSの採用を進めています。
ext4であればLinux Readerなどを使えばWindows環境でも簡単に中身を取り出せたのですが、EROFSには非対応なので取り出せません。
対応をお願いしたものの優先度は低そうなので、ひとまずWSL環境で取り出せるようにしました。
1. WSLのカスタムカーネルビルドを準備
EROFSは残念ながらWSLのデフォルトのカーネルでは有効化されていません。
そこで、EROFSを有効にしたカスタムカーネルをビルドします。
まずCドライブ直下などにWSL2-Linux-Kernelなどとフォルダを作成します。
Linux環境だとそのままソースをクローンしてこれば良いのですが、Windows環境では大文字小文字の区別をつけるよう設定しておかないといけません。
管理者権限のPowerShellにて、下記コマンドを実行して大文字小文字の区別を有効化してください。
fsutil file setcasesensitiveinfo C:\WSL2-Linux-Kernel enable
有効化できたら、
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
でカーネルソースをクローンします。
2. ビルドツールのインストール
WSLにて
sudo apt install build-essential flex bison libssl-dev libelf-dev dwarves
を実行し、ビルドに必要なツールをインストールします。
dwarvesを入れていない場合、ビルドしたときにBTF: .tmp_vmlinux.btf: pahole (pahole) is not available
などとエラーが出てしまいます。
3. EROFSの有効化
WSL2-Linux-Kernel/Microsoft/config-wslにカーネル設定があります。
# CONFIG_EROFS_FS is not setと書かれているところを探して、
CONFIG_EROFS_FS=y
# CONFIG_EROFS_FS_DEBUG is not set
CONFIG_EROFS_FS_XATTR=y
CONFIG_EROFS_FS_POSIX_ACL=y
CONFIG_EROFS_FS_SECURITY=y
CONFIG_EROFS_FS_ZIP=y
CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1
というように変更してください。
4. ビルドする
make KCONFIG_CONFIG=./Microsoft/config-wsl
でビルドできます。
ビルドが正常に完了すれば、WSL2-Linux-Kernelフォルダにvmlinuxファイルが作られます。
vmlinuxファイルがカーネル本体なので、消さないようにしてください。
5. 利用できる状態にする
ビルドできたら、インストールします。
sudo make modules_install
でカーネルモジュールをインストールした後、%USERPROFILE%\.wslconfig
にあるWSLの設定ファイルを開きます。
[wsl2]
kernel=C:\\WSL2-Linux-Kernel\\vmlinux
というように書いて保存してください。
6. WSLを起動する
初回起動時は、すでに起動しているWSLを再起動しないといけません。
wsl.exe --shutdown
でシャットダウンし、
wsl.exe
で起動します。
これでEROFSがWSL上で利用できるようになります。
7. マウントする
フォルダ名などは何でも良いですが、例えばsystem_a.imgからファイルを取り出したい場合は
mkdir mount data
sudo mount -t erofs -o loop system_a.img mount
sudo rsync -zarvhP mount/ data
といったようなコマンドを実行することで、system_a.imgと同じディレクトリに作ったdataフォルダにファイルがコピーされます。
コピーが終わったら
sudo umount mount
でマウントを解除できます。
こちらのシェルスクリプトを使うと自動化できます。
ビルドが面倒なのでデフォルトで有効化されれば良いのですが、今のところ有効化する予定はなさそうです。