Note to Self by notekunst

ただの備忘録です

Unihertz Atom L への LineageOS のインストール

Unihertz Atom L に LineageOS を入れてみました。

私の場合、最初は、フラッシュした Lineage リカバリがうまく起動しませんでした(画面上部に緑色の線が表示されて、Atom L がフリーズしました)。試しに、Atom L の Stock Rom を初期のものにダウングレードしてから Lineage リカバリをフラッシュしたら、Lineage リカバリがうまく動作しました。XDA の投稿をみると、緑線フリーズが発生する場合と発生しない場合とがあるようです。初期の Stock Rom をフラッシュしなくても、設定の工夫によって、Lineage リカバリが動作するのかもしれません。

また、自分で LineageOS をビルドしてみました。ビルドした LineageOS を Atom L に入れたら、うまく動作しました。

本記事は、これらの作業のメモです。

Stock Rom のフラッシュ

Stock Rom の URL を、Unihertz の公式ウェブサイトのフォーラムの投稿の中に見つけました。
https://www.unihertz.com/unihertz-form.html/rom--development/firmware-for-atom
この投稿の「unihertz's google drive」のリンク先から、Stock Romをダウンロードできました。
このURLが公式なのか否かは未確認なので、ご利用は自己責任で・・・

私は、Software_firmware/Atom_L/None_EEAから、最も古いと思われる "2020052615_g63v71c2k_dfl_tee.zip" をダウンロードしました。そして、SP Flash Tool を使って Atom L に Stock Rom をフラッシュしました。
SP Flash Tool を、XDA の記事等々を参考にして、入手しました。
https://forum.xda-developers.com/t/tut-mtk-android-sp-flash-tool-tutorial.1982587/
このツールはMediatek社の公式ツールではなさそうなので、普段使いの PC 上ではなく、仮想マシンVirtualBoxUbuntu)で SP Flash Tool を動かしました。

LineageOSのビルド

参考にした記事

以下の3つの記事を参考にしました。

・PeterCxy氏の記事(Atom L 用のデバイスツリーを公開しています)
https://forum.xda-developers.com/t/rom-unofficial-lineageos-17-1-for-unihertz-atom-l-20200828.4139423/

・a-dead-trousers氏の記事(Atom XL 用のデバイスツリーとビルドの手順などをまとめています)
https://forum.xda-developers.com/t/rom-10-0-unofficial-lineageos-17-1-for-unihertz-atom-xl-alpha-2021-01-24.4171407/

・dirtylimerick0氏のリポジトリAtom L 用のデバイスツリーとビルドの手順などをまとめています)
https://github.com/dirtylimerick0/Atom_L

私は、LineageOS 17.1のリポジトリにdirtylimerick0氏のデバイスツリーを追加してLineageOSをビルドしました。

lineageOSリポジトリの初期化

ディレクトリを作って、リポジトリを初期化します。

mkdir -p ~/android/lineage_atoml
cd ~/android/lineage_atoml
repo init -u https://github.com/LineageOS/android.git -b lineage-17.1
local_manifestsの作成

dirtylimerick0氏のデバイスツリーを用いるためのmanifestを作成します。

mkdir -p .repo/local_manifests
vi .repo/local_manifests/unihertzatoml.xml

ファイル名は、任意です。内容を、以下のように書いてみました。

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <project name="dirtylimerick0/Atom_L" path="device/Unihertz/Atom_L" remote="github" revision="master" />
</manifest>
ソースコードの同期

manifestを作成したら、ソースコードを同期します。

cd ~/android/lineage_atoml
repo sync --force-sync
blobの準備

私は、現時点で最新と思われる Stock Rom のzipデータ "2020110318_g63v71c2k_dfl_tee.zip"から blob を抽出しました。
まず、このzipファイルから「super.img」を取り出します(例えば、~/blobにコピーします)。
super.imgからイメージデータを抽出します。抽出方法については、 a-dead-trousers氏の以下の記事が参考になります。
https://github.com/ADeadTrousers/android_device_Unihertz_Atom_XL/blob/master/docs/HOW-TO-EXTRACT_FILES.md

ツール「imjtool」を用いて product.img、system.img、vendor.img を抽出します。

cd ~/blob
imjtool super.img extract (image.imgが抽出され、ディレクトリextractedの下の保存されます)
imjtool extracted/image.img extract (product.img、system.img、vendor.imgが抽出され、ディレクトリextractedの下の保存されます)

抽出したイメージをマウントします。

mkdir system
sudo mount extracted/system.img system/
sudo mount extracted/vendor.img system/vendor/
sudo mount extracted/product.img system/product/

Atom L のデバイスツリー(ここでは、device/Unihertz/Atom_L)に移動して、blob 抽出コマンドを実行します。

./extract-files.sh ~/blob

blob の抽出が終了したら、img ファイルをアンマウントします。

sudo umount -R ~/blob/system/

以上で、blob の抽出作業は終了です。

ビルド

ビルドの準備の行います。

cd ~/android/lineage_atoml
source build/envsetup.sh
breakfast Atom_L

準備が整ったら、ビルドを開始します。

croot
brunch Atom_L > brunch.log 2>&1 &

ビルドに成功した場合、出力用のディレクトリ(~/android/lineage_atoml/out/target/product/Atom_L/)に、インストールパッケージファイル等が生成されます。

lineage-17.1-2021XXXX-UNOFFICIAL-Atom_L.zip
recovery.img
vbmeta.img

LineageOSのインストール

以下の順に作業を進めます。
ブートローダのアンロック
・AVB (Android Verified Boot)の無効化
Lineage recovery のインストール
・LineageOS のインストール

以下の記事を参考にしました。

・PeterCxy氏の記事
https://forum.xda-developers.com/t/rom-unofficial-lineageos-17-1-for-unihertz-atom-l-20200828.4139423/

・a-dead-trousers氏の記事
https://github.com/ADeadTrousers/android_device_Unihertz_Atom_XL/blob/master/docs/HOW-TO-INSTALL.md

a-dead-trousers氏の記事は Atom XL 用のものですが、インストールの手順は、Atom L でも同様です。

ブートローダのアンロック

自分がどのようにアンロックしたのか忘れましたが、PeterCxy氏の記事によると、アンロックの手順は以下の通りです。なお、アンロックを行うと、メーカー保証を受けられない可能性があります。試したい人は、自己責任で・・・

・Settings(設定)->About phone(端末情報)->Build number(ビルド番号)を複数回タップして、Developer options(開発者向けオプション)を有効化します。
・Settings(設定)->System(システム)->Developer options(開発者向けオプション)->OEM unlocking(OEM ロック解除)を有効化します。
・Atom L を PC に繋ぎ、PC 上で adb reboot bootloader を実行して、bootloader を起動します。
「Volume down を押しながら電源をオン」を行っても、bootloader は起動しません(代わりに、テストモードが起動します)
・PC 上で、fastboot flashing unlock を実行します。
AVB (Android Verified Boot)の無効化

bootloader を起動し、vbmetaのイメージをフラッシュします。

fastboot flash --disable-verification --disable-verity vbmeta vbmeta.img
fastboot flash --disable-verification --disable-verity vbmeta_system vbmeta_system.img
fastboot flash --disable-verification --disable-verity vbmeta_vendor vbmeta_vendor.img

私は、最初、PeterCxy氏の記事の vbmeta.img、vbmeta_system.img、vbmeta_vendor.img を用いました。その後、LineageOS のビルドで生成された vbmeta.img を3つの領域にフラッシュしてみました。この後も、 LineageOS と Lineage リカバリは、うまく動作しました。

Lineage recovery のインストール

vbmetaのイメージのフラッシュに続いて、Lineage recovery をフラッシュします。

fastboot flash recovery recovery.img

私は、最初、PeterCxy氏の記事の recovery.img を用いました。その後、LineageOS のビルドで生成された recovery.img をフラッシュしてみましたが、このリカバリもうまく動作しました。

LineageOS のインストール

リカバリを起動して、LineageOS を sideload します。
リカバリを起動すると、ボリュームボタンにより選択肢を変更でき、電源ボタンにより選択(確定)できます。
なお、メニューの一番上の「戻る」の選択肢が表示されませんが、見えないだけで選択可能です。

Atom L を PC に繋き、リカバリを起動します。PC 上で「adb reboot recovery」を実行してもよく、Volume Up を押しながら電源ONでもよいです。
・初めて LineageOS をインストールする場合、データを消去するとよいと思います (Factory reset, Format data/factory reset)
・「Apply update」を選択し、「Apply from ADB」を選択します。
・PC 上で「adb sideload lineage-17.1-2021XXXX-UNOFFICIAL-Atom_L.zip」を実行します。

sideload が完了したら、リブートします (Reboot system now)。これで、LineageOS が起動しました。

Hotspot & tethering の設定メニューについて

上記のデバイスツリーを利用する場合、「Setting(設定)」の「Network & internet」のメニューに「Hotspot & tethering」が表示されません。
a-dead-trousers氏は、Atom XL 用に、この設定メニューのためのコードを書いてます。
https://github.com/ADeadTrousers/android_device_Unihertz_Atom_XL/commit/24ad9ff230a7a50213128b589405a421a663c65d
私はコードに詳しくありませんが、「 overlay/frameworks/base/core/res/res/values/config.xml」の修正部分と、「 sepolicy/private/hal_graphics_allocator.te」とを、デバイスツリーに適用してみました。すると、「Hotspot & tethering」 の設定メニューが表示されました。
なお、「 app/Intercom/Android.mk」は、トランシーバのためのコードと思われるので省略しました。

F(x)tec Pro1 用の LineageOS のビルド

F(x)tec Pro1 用に LineageOS をビルドしてみました。Pro1 は lineage によって公式にサポートされています。Lineage の Pro1 の記事に従ってビルドを行うと、大きな問題は生じずに、ビルドは成功しました。
wiki.lineageos.org

本記事は、ビルドのための設定などのメモです。ご自身でビルドを行う場合には、本記事ではなく、Lineage の上記の一次情報を参照するといいです。

下準備

ビルド用のPC

Lineage の記事には、8GB以上のRAMと100GB の空きストレージ (ccache を有効にするならそれ以上) を備える 64-bit コンピュータが必要である、とあります。SSD を用いれば HDD よりもビルドの時間が大幅に短縮される、ともあります。

私が用いたPCは古いものであり、CPU は Core i3-3220、 RAM は 8GB、SSD の空き容量は 300GB 以上、OS は Ubuntu 20.04 です。

Pro1 用のビルドを始めた当初には、ソースコードの内容に関するエラーやビルド環境に関するエラーなど、いろいろなエラーが発生しました。しかし、リポジトリの更新が進むにつれて、ソースコードの内容に関するエラーは無くなりました。結局、エラーが解消するようにビルド環境を整えることによって、ビルドは成功しました。

PC のスペックが低いので、ビルド開始からエラーによる停止まで12時間以上かかる場合がありました。最初からエラー無くビルドが進行する場合、ビルドに1日以上かかりそうです。高スペック PC を用いれば、数時間でビルドできるようです。

RAMについて

ネットで調べると、システムのビルドのためには、RAM の容量が 16GBや32GB ほどあるとよいようです。そこで、RAM不足にならないように、swap を 32GB に増やしました。swap がファイル形式でしたので、以下のように容量を変更しました。

free -h    スワップのサイズを確認
swapon -s    swapがファイル(/swapfile)であることを確認
swapoff /swapfile    スワップを解除
rm /swapfile    スワップファイルを削除
fallocate -l 32G /swapfile    スワップ用に32GBの新ファイル (/swapfile) を作成
chmod go= /swapfile    新ファイルの余計な権限を削除
mkswap /swapfile    新ファイルをスワップファイルに変換
swapon /swapfile    スワップファイルを有効化
free -h    スワップのサイズを確認 

なお、ビルドの最中に、時々にメモリの使用状況をチェックしましたが、swap は使用されていませんでした。swap の拡張は不要だったかもしれません。

ストレージについて

ビルドが完了した状態で、du コマンドで主要なディレクトリのデータサイズを見てみました。ビルドしたデバイスは、Pro1 だけです。

du -s ~/android/lineage
78035784 (約78GB)
du -s ~/android/lineage/out
118869912 (約118GB)
du -s ~/.ccache
4743872 (約4.7GB)

ccache 分を除いても、合わせて 200GB ほど使用しています。200GB 以上の空き容量を準備するのが良さそうです。なお、出力データ用のディレクトリ (~/android/lineage/out) を別のドライブに割り当てたので、このディレクトリのデータサイズは、lineage ディレクトリのものとは別になっています。

adb と fastboot

android developer の以下のウェブページで公開されている SDK Platform-Tools は便利です。
https://developer.android.com/studio/releases/platform-tools?hl=ja
自分の OS に対応したパッケージをダウンロードして展開するだけで、なにかをインストールしたりせずに、コマンドライン ツールを利用できます。

他のツール

Lineage の記事によれば、以下のツールが必要です。

bc bison build-essential ccache curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5 libncurses5-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev

未インストールのツールを sudo apt install でインストールしました。

OpenJDK

Lineage の記事によれば、LineageOS 16.0-17.1 のビルドには OpenJDK 1.9 (included by default) が必要とあります。「included by default」という注意書きがありますが、この意味は私にはよくわかりませんでした(LineageOS 16.0-17.1 のソースコードjdk が含まれてるという意味でしょうか?)。私の PC には、すでに、openjdk-14-jdk がインストール済です。OpenJDK については、ビルドでエラーが生じたら、そのときに考えることにしました。ビルドを始めた当初には、Java 関連のエラーが発生しましたが、その後にリポジトリを更新するだけで、Java 関連のエラーは発生しなくなりました。

ビルド

Lineage の記事に従って、ビルドを進めます。

ディレクトリの作成

ビルドに必要なディレクトリを以下のように作成します。1つ目は、後述のコマンド repo をインストールするためのディレクトリです。2つ目は、ソースコードを展開するためのディレクトリです。

mkdir -p ~/bin
mkdir -p ~/android/lineage

repo コマンドのインストール

以下の手順で repo をインストールできます。

curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

さらに、必要ならば、~/bin をパスに追加します。私は、~/.profile に以下の設定を追加しました。

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

gitの設定

repo が Android を同期するために身元確認を必要とするので、git の識別情報を設定します。普段に git を使用している人は、この作業は不要です。

git config --global user.email "you@example.com"   (you@example.comは、実際には自分のメールアドレス)
git config --global user.name "Your Name"   (Your Nameは、実際には自分の名前)

普段に git を使用していない場合、ダミーデータでも問題なさそうです。

LineageOS ソースリポジトリの初期化と、ソースコードのダウンロード

F(x)tec Pro1 に関しては、lineage-16.0 が公式にサポートされています。このブランチのリポジトリを初期化します。

cd ~/android/lineage
repo init -u https://github.com/LineageOS/android.git -b lineage-16.0

次に、ソースコードをダウンロードします。

repo sync

通信回線にもよりますが、ダウンロードには長い時間がかかります。私の場合、2時間以上かかりました(2時間待っても終わらなかったので外出し、数時間後に戻ったら終わってました)。

なお、repo sync は、ソースコードの更新にも利用されます。Lineage の記事には、数日おきに repo sync を行うよい、とあります。実際に再び repo sync を行ってビルドすると、Android の新しいセキュリティパッチがビルド結果に反映されたりします。

装置固有のコードのダウンロード

ソースコードのダウンロードが完了したら、装置に固有なコード(カーネルなど)をダウンロードします。

cd ~/android/lineage
source build/envsetup.sh
breakfast pro1

ここで、"vendor/fxtec/pro1/pro1-vendor.mk" does not exist. というエラーが生じました。以下に説明する blob (バイナリデータ) を準備する処理によって、このエラーは解消しました。

装置独自の blob (バイナリデータ) の準備

blob の準備方法は、Lineage の以下の記事で説明されています。
https://wiki.lineageos.org/devices/pro1/build#extract-proprietary-blobs
この記事によれば、blob は、実機から抽出されます。ビルドしようとしているブランチの最新の LineageOS が走っている実機を用いるとよいようです。実機が手元にない場合、LineageOS の zip ファイル(インストールパッケージ)から blob を抽出可能です。手順は、Lineage の以下の記事で説明されています。
https://wiki.lineageos.org/extracting_blobs_from_zips.html
この記事の"Extracting proprietary blobs from payload-based OTAs"の手順に従って、Lineage の zip ファイルから blob を抽出できます。私は、Lineage 公式ページからダウンロード可能な zip ファイルから blob を取り出しました(https://download.lineageos.org/pro1)。

blob を抽出するためには、まず、zip の中身を展開するディレクトリを作成し、そこに移動します。

mkdir ~/android/system_dump/
cd ~/android/system_dump/

zip ファイルから payload.bin を抽出します。

unzip lineage-16.0-XXX.zip payload.bin   (lineage-16.0-XXX.zip は、実際にはzipファイルのファイル名)

Python のツール python-protobuf をインストールします。

sudo apt install python-protobuf

私の環境では python-protobuf ではなく python3-protobuf が既にインストールされていました。

なお、LineageOS のビルドには、Python2 が必要です。Ubuntu 20.04 では、Python3 が標準であり、Python2 はインストールされていません。Python2 と Python3 との混在を避けるために、私は、conda を用いて Python2 の環境を作成し、この環境下でビルドを進めました。また、この時なのか後のビルドの時なのか忘れましたが、「/usr/bin/pythonが無い」というエラーが生じたので、python2 へのシンボリックリンク /usr/bin/python を作成しました。

先程に抽出した payload.bin から種々の img ファイルを抽出します。

python ~/android/lineage/lineage/scripts/update-payload-extractor/extract.py payload.bin --output_dir ./
(私の場合、"python"の代わりに"python3"を用いました)

抽出した system.img と、もしあれば vendor.img と product.img とを、マウントします。私の場合、system.img と vendor.img とは見つかりましたが、product.img は、ありませんでした。

mkdir system/
sudo mount system.img system/
sudo mount vendor.img system/vendor/

ソースコードの pro1 用のディレクトリに移動して、blob 抽出コマンドを実行します。

cd ~/android/lineage/device/fxtec/pro1
./extract-files.sh ~/android/system_dump/

blob の抽出が終了したら、img ファイルをアンマウントし、データを削除します。

sudo umount -R ~/android/system_dump/system/
rm -rf ~/android/system_dump/

以上で、blob の抽出作業は終了です。
ディレクトリ "~/android/lineage" に戻って "breakfast pro1" を再び実行すると、今度はエラーは発生しませんでした。

ccacheの有効化

ccache を有効にすれば、2回目以降のビルドを高速化できます。私は、~/.profile に以下の設定を追加しました。

export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache
export CCACHE_COMPRESS=1

また、キャッシュのサイズを 50GB に設定しました。

ccache -M 50G

このコマンドは、1回だけ実行すればよいようです。

ビルド開始

以上で準備は整いました。以下のコマンドを実行して、ビルドを開始します。

croot
brunch pro1 > brunch.log 2>&1 &

低スペック PC を用いる場合、初回のビルドは半日以上かかります。私は、ターミナルウィンドウを閉じてもビルドが止まらないように、ログを brunch.log に保存し、バックグラウンドでビルドを実行しました。croot の後、単に brunch pro1 でもビルドできます。

ビルド結果

ビルドに成功した場合、LineageOS のインストールパッケージファイルが生成されます。

~/android/lineage/out/target/product/pro1/lineage-16.0-2020XXXX-UNOFFICIAL-pro1.zip   (XXXXは、ビルドした月日)

これを、実機にフラッシュすれば、セルフビルドシステムスマホのできあがりです。

F(x)tec Pro1 への LineageOS、Magisk のインストール

F(x)tec Pro1 に自分でビルドした LineageOS をインストールしました。また、Magisk もインストールしました。本記事は、インストール作業の忘備録です。なお、この記事はただの記録であり、何の保証もありません(同じ手順で失敗の可能性もあります)。LineageOS のビルドについては、別記事にする予定です。

bootloader のアンロック

LineageOS をインストールするために、bootloader をアンロックします。アンロックは、以下の手順でできました。なお、アンロックを行うと、メーカー保証を受けられない可能性があります。メーカー保証を受けるためには、アンロックをせずに元の Android OS を使い続けるべきでしょう

・Settings(設定)->About phone(端末情報)->Build number(ビルド番号)を複数回タップして、Developer options(開発者向けオプション)を有効化します。
・Settings(設定)->System(システム)->Developer options(開発者向けオプション)->OEM unlocking(OEM ロック解除)を有効化します。
・Pro1 を PC に繋いで bootloader を起動します。
  PC 上で adb reboot bootloader を実行してもよく、Volume down を押しながら電源をオンにしてもよいです。
・PC 上で、fastboot flashing unlock を実行します。

リカバリLineageのフラッシュ

私は、tdm 氏の以下の記事を参考にして LineageOS をインストールしました(tdm 氏は、F(x)tec のフォーラムにいろいろな技術情報を投稿しています)。
http://files.nwwn.com/android/pro1/lineage.html

この記事では、slot A と slot B の違いを意識して作業を進めているので、わかりやすいです。具体的には、リカバリを slot A にフラッシュします。そして、slot A のリカバリを起動し、これを用いて Lineage システム を slot B にフラッシュします。

公式の LineageOS をインストールする場合、Lineage の記事 Install LineageOS on pro1 (https://wiki.lineageos.org/devices/pro1/install)を参考にするとよいと思います。

作業を進めるにあたり、リカバリ、LineageOS、(必要なら)Google apps のデータを準備します。私は、tdm 氏の記事にリンクされていたテストビルド用のリカバリを用いました。今(2020/08/23)は、このリカバリへのリンクはなく、代わりにLineage の記事 LineageOS Downloads (https://download.lineageos.org/pro1)へのリンクがあります。

Google apps のデータは、Lineage の記事 Google apps (https://wiki.lineageos.org/gapps.html) からリンクをたどると入手可能です(私は、MindTheGapps-9.0.0-arm64-20190615_031441.zip を用いました)。なお、Google apps のフラッシュは、Lineage を最初に起動する前に行います。

私は、tdm 氏の記事を参考に、Pro1 を PC に繋ぎ、以下の作業を進めました。

・ブートローダを起動します (adb reboot bootloader または Volume down を押しながら電源オン)
・PC 上で、fastboot flash boot_a lineage-16.0-***.img を実行し、slot A にリカバリをフラッシュします(lineage-16.0-***.img は、実際にはリカバリのファイル名)
・PC 上で、fastboot --set-active=a を実行し、slot A がアクティブであることを確実にします。
・Pro1 のボリュームキーを操作して"Recovery mode"を選択し、電源キーを押します。これで、slot A のリカバリが起動します。
・Pro1 上のリカバリメニュー上で"Factory Reset"を選択し、"Wipe data / factory reset"を選択します。そして、メインメニューに戻ります。
・リカバリのメニュー上で"Apply Update"を選択し、"Apply from ADB"を選択します。これで、sideload が可能になります。
・PC 上で、adb sideload lineage-16.0-***.zip を実行し、システムをフラッシュします(lineage-16.0-***.zipは、実際には LineageOS ファイルのファイル名)
 フラッシュが終了すると、リカバリは、自動的に、アクティブな boot slot を切り替えるそうです。
 ですから、続けて Google Apps をフラッシュする場合、以下のようにリカバリを再起動して作業を進めます。
・Pro1 上のリカバリメニュー上で"Advanced"を選択し、"Reboot to recovery"を選択します。
・再起動したリカバリのメニュー上で"Apply Update"を選択し、"Apply from ADB"を選択します。
・PC 上で、adb sideload MindTheGapps-9.0.0-arm64-20190615_031441.zip を実行し、Gappsをフラッシュします。

これで、LineageOS と Google apps のフラッシュは完了です。Pro1 を再起動すると、LineageOS が立ち上がりました。

LineageOS を更新する場合、"Wipe data / factory reset" をせずに、新しい LineageOS と Gapps をフラッシュすることによって、ユーザデータを維持しつつシステムを更新できました。

Magisk のフラッシュ

Pro1 を PC に繋ぎ、リカバリを起動して以下のように Magisk をフラッシュすると、簡単に Magisk をインストールできました。

・リカバリを起動します (adb reboot recovery または Volume up を押しながら電源オン)
・リカバリのメニュー上で"Apply Update"を選択し、"Apply from ADB"を選択します。
・PC 上で、adb sideload Magisk-v20.4.zip を実行し、Magiskをフラッシュします

Pro1 を再起動すると、Magisk Manager を起動できました。

古いGPUのためのTorchVisionのビルド(Ubuntu 20.04 on MacBookPro 15" Late2013)

PyTorchのビルドに続いて、TorchVisionもビルドします。
まずは、リポジトリを取得します。

$ git clone --recursive https://github.com/pytorch/vision
$ cd vision

以前に書いた記事「古いGPUのためのPyTorchのビルド」と同様に、環境変数を設定します。TORCH_CUDA_ARCH_LISTを"3.0"に設定します。さらに私の場合は、condaでpytorch用の環境も有効にしています。

$ conda activate XXXXX     (XXXXXは環境名です)
$ export USE_CUDA=1 USE_CUDNN=1 TORCH_CUDA_ARCH_LIST="3.0"

通常は、この後に "python setup.py install" を実行すれば TorchVision をインストールできます。しかし、古いGPU用の環境変数を設定しているからか、以下の様に 3.0 の GPU はサポートされていないというエラーが発生します。

$ python setup.py install
...
  File "/home/...(一部省略).../lib/python3.8/site-packages/torch/utils/cpp_extension.py", line 1409, in _get_cuda_arch_flags
    raise ValueError("Unknown CUDA arch ({}) or GPU not supported".format(arch))
ValueError: Unknown CUDA arch (3.0) or GPU not supported

以前に書いた記事「...CUDA...のインストール」の通り、私のマシンの CUDA は 3.0 の GPU をサポートしています。そこで、エラーを出力したファイル "cpp_extension.py" を、以下のように編集します(変数 "supported_arches" に "3.0" を追加します)。

    supported_arches = ['3.0', '3.5', '3.7', '5.0', '5.2', ...
(下線部を追加)

これで、下記コマンドでTorchVisionをインストールできます。

$ python setup.py install

ディレクトリ "test" の下には、テスト用のスクリプトがあります。いろいろ試したところ、うまく実行できました。
"test_models.py"というテストスクリプトは、GPUを用いているようです。これを実行したら、"GPUが古い" というCUDAの警告が表示されましたが、処理は無事に終了しました。GPUもうまく利用できているようです。

古いGPUのためのPyTorchのビルド(Ubuntu 20.04 on MacBookPro 15" Late2013)

通常は、PyTorchの下記ページで得られるコマンドの実行によって、PyTorchをインストールできます。
https://pytorch.org/
しかし、この方法でインストールされるPyTorchは、3.5よりも小さい"Compute Capability"をサポートしていません。"GeForce GT 750M"の"Compute Capability"は"3.0"なので、これはサポート対象外です。仮にこのPyTorchを用いる場合、"torch.cuda.is_available()"の結果は"True"ですが、GPUを使う処理で、以下のように"カーネルが無い"というエラーが発生します。

RuntimeError: CUDA error: no kernel image is available for execution on the device

ネットで調べた情報によると、PyTorchをソースコードからビルドすれば、古いGPU用のカーネルをビルドできるそうです。そこで、PyTorchをソースコードからビルドします。
私はcondaでpythonの環境を切り替えています。今回は、condaでPyTorch用の環境を作成し、その環境下でPyTorchをビルドしました。

ツールのインストール

condaでPyTorch用の環境を有効化し、ツールをインストールします(XXXXXは予め作成しておいた環境の名前を示します)。最初の2つはconda上で見つからなかったので、普通にインストールしました。

$ sudo apt install libgoogle-glog-dev
$ sudo apt install libgflags-dev
$ conda activate XXXXX
$ conda install pyyaml
$ conda install numpy
$ conda install ninja
$ conda install cmake
$ conda install glog

PyTorchのインストール

PyTorchのリポジトリを取得します。

$ git clone --recursive http://github.com/pytorch/pytorch
$ cd pytorch

以下のように、環境変数を設定します。TORCH_CUDA_ARCH_LISTに"GeForce GT 750M"の"Compute Capability"である"3.0"を設定します。

$ export USE_CUDA=1 USE_CUDNN=1 TORCH_CUDA_ARCH_LIST="3.0"

PyTorchのビルド・インストールを行います。

$ python setup.py install

これで、PyTorchのインストールは完了です。

PyTorchのテスト

pythonを起動してPyTorchを試してみます。

$ python
Python 3.8.3 (default, Jul  2 2020, 16:21:59) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> torch.cuda.is_available()
True
>>> torch.cuda.device(0)
<torch.cuda.device object at 0x7f00bddc3a90>
>>> torch.cuda.get_device_name(0)
/...(一部省略).../torch/cuda/__init__.py:102: UserWarning: 
    Found GPU0 GeForce GT 750M which is of cudacapability 3.0.
    PyTorch no longer supports this GPU because it is too old.
    The minimum cuda capability that we support is 3.5.
    
  warnings.warn(old_gpu_warn % (d, name, major, capability[1]))
'GeForce GT 750M'

"GPUが古い"という警告が表示されます。GPUが古いことは分かっているので、警告にある"__init__.py"を、警告を表示しないように編集してもよいと思います。

計算を実行する前に、python上でGPUメモリの使用状況を見てみます。

>>> print('Total:    ', round(torch.cuda.get_device_properties(0).total_memory/(1024**2),1), 'MB')
Total:     1999.7 MB
>>> print('Allocated:', round(torch.cuda.memory_allocated(0)/(1024**2),1), 'MB')
Allocated: 0.0 MB
>>> print('Cached:   ', round(torch.cuda.memory_reserved(0)/(1024**2),1), 'MB') 
Cached:    0.0 MB

python上では、GPUメモリのキャッシュはゼロです。別のターミナルで"nvidia-smi"を実行してみます。

$ nvidia-smi 
...
|===============================+======================+======================|
|   0  GeForce GT 750M     On   | 00000000:01:00.0 N/A |                  N/A |
| N/A   60C    P0    N/A /  N/A |    271MiB /  1999MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

GPUメモリの使用量は、それほど多くはありません。
次に、起動済のpython上で、GPU上に大きなテンソルa,bを生成し、メモリ使用状況を確認してみます。

>>> a = torch.rand(11000,11000,device="cuda:0")
>>> b = torch.rand(11000,11000,device="cuda:0")
>>> print('Allocated:', round(torch.cuda.memory_allocated(0)/(1024**2),1), 'MB')
Allocated: 924.0 MB
>>> print('Cached:   ', round(torch.cuda.memory_reserved(0)/(1024**2),1), 'MB')
Cached:    924.0 MB

GPUメモリのうち924.0 MBが、python用にキャッシュされています。別のターミナル上で"nvidia-smi"を実行してみます。

$ nvidia-smi
...
|===============================+======================+======================|
|   0  GeForce GT 750M     On   | 00000000:01:00.0 N/A |                  N/A |
| N/A   55C    P0    N/A /  N/A |   1378MiB /  1999MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

GPUメモリの使用量が増大しています。
起動済のpython上でテンソルa,bの積を計算し、メモリ使用状況を確認してみます。

>>> c = torch.mm(a,b)
>>> print('Allocated:', round(torch.cuda.memory_allocated(0)/(1024**2),1), 'MB')
Allocated: 1386.0 MB
>>> print('Cached:   ', round(torch.cuda.memory_reserved(0)/(1024**2),1), 'MB')
Cached:    1386.0 MB

テンソルの計算は、数秒で終わります(速い?)。また、演算によりキャッシュが増大しています。別のターミナル上で"nvidia-smi"を実行してみます。

$ nvidia-smi
...
|===============================+======================+======================|
|   0  GeForce GT 750M     On   | 00000000:01:00.0 N/A |                  N/A |
| N/A   60C    P0    N/A /  N/A |   1866MiB /  1999MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

GPUメモリのほぼ全てが使用されています。pythonを終了すると、GPUメモリは解放されます。

$ nvidia-smi
...
|===============================+======================+======================|
|   0  GeForce GT 750M     On   | 00000000:01:00.0 N/A |                  N/A |
| N/A   61C    P0    N/A /  N/A |    269MiB /  1999MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

このように、PyTorchは、GPUを用いて動作できました。

なお、PyTorchには、テスト用のスクリプトもあります。以下のコマンドにより、複数のテストコードが順次に実行されます。

$ python test/run_test.py

MacBookPro (15" Late2013) で実行したところ、複数のテストをパスしましたが、GPUメモリ不足のエラーが生じるテストもありました。

別の記事で"torchvision"のインストールの話を書く予定です。

FacetimeHDカメラを使う(Ubuntu 20.04 on MacBookPro 15" Late2013)

Ubuntu上でMacBookProのFacetimeHDカメラを利用するために、Patrik Jakobsson氏のツールを用います。
github.com
この記事に沿って作業を進めると、MacBookPro (15" Late2013) のFacetimeHDカメラを簡単に使えるようになりました。
手順は、氏の以下の記事"Get Started"に書かれています。
Get Started · patjak/bcwc_pcie Wiki · GitHub

ファームウェアの抽出

$ git clone https://github.com/patjak/facetimehd-firmware.git
$ sudo apt install make curl cpio   (もしインストールしてなければ)
$ cd facetimehd-firmware/
$ make
Found matching hash from OS X, El Capitan 10.11.5
==> Extracting firmware...
 --> Decompressing the firmware using gzip...
 --> Deleting temporary files...
 --> Extracted firmware version 1.43.0
$ sudo make install
Copying firmware into '//usr/lib/firmware/facetimehd'

インストール

以下の記事"Get Started"によれば、Ubuntuでの手順は、Debianでの手順とほぼ同じです(違いは、ファームウェアのコピー先が異なることだけです)。この記事には、Ubuntu用のスクリプトもあります。私は、スクリプトを用いずに、手動で作業を進めました。
Get Started · patjak/bcwc_pcie Wiki · GitHub

自分のシステムのカーネルのバージョンと同じバージョンのヘッダをインストールします。

$ uname -r
5.4.0-40-generic
$ sudo apt install linux-headers-5.4.0-40-generic

続けて、作業を進めます。

$ sudo apt install kmod libssl-dev checkinstall   (もしインストールしてなければ)
$ git clone https://github.com/patjak/bcwc_pcie.git
$ cd bcwc_pcie
$ make
$ sudo checkinstall
パッケージドキュメントを聞かれたら、適当な説明 (例えば "FacetimeHD Linux Driver")を入力

新たに作ったモジュール"facetimehd"をロードする前に、モジュール"bdc_pci"を外します。モジュール"bdc_pci"は、デバイス"/dev/video0"の準備を妨げます。

$ sudo modprobe -r bdc_pci

bdc_pciをロードしないようにブラックリストに登録します。
/etc/modprobe.d/blacklist-bdc_pci.confに以下を記載します

blacklist bdc_pci

モジュール"facetimehd"をロードします。

$ sudo depmod
$ sudo modprobe facetimehd

これで、FacetimeHDカメラが利用できるようになります。gnomeのアプリ"Cheese"を起動すると、緑色のランプが点灯し、撮影画像が表示されます。
Macの起動時に自動的に"facetimehd"をロードするように、/etc/modulesに以下を記載します。

facetimehd

カメラを扱うツール"v4l-utils"は、便利そうです。

$ sudo apt install v4l-utils

カメラの情報を確認できます。

$ v4l2-ctl --list-device
Apple Facetime HD (PCI:0000:04:00.0):
	/dev/video0

画面の明るさを調整する(Ubuntu 20.04 on MacBookPro 15" Late 2013)

画面の明るさを調整するための設定

MacBookPro(15" Late2013)のUbuntu 20.04上でnvidiaドライバを用いる場合、追加の設定が必要です。
ネットで調べると、下記コマンドが見つかります。

$ sudo setpci -v -H1 -s 00:01.00 BRIDGE_CONTROL=0

これで、gnomeの設定画面や、キーボードの輝度調整キー(F1,F2の位置のキー)を用いて、画面の明るさを調整できます。しかし、Macを再起動すると、設定がクリアされてしまいます。
そこで、Macの起動時に上記コマンドを自動的に実行するための設定を行います。ここでは、"rc.local" を自動実行するsystemdのサービスを設定します。

コマンドファイルの準備

"/etc/rc.local"をサービスのコマンドとして準備します。このファイルに、以下を記載します。

#!/bin/sh
setpci -v -H1 -s 00:01.00 BRIDGE_CONTROL=0

このファイルの実行を許可します。

$ sudo chmod u+x /etc/rc.local
ユニットファイルの準備

ユニットファイルは、サービスの制御情報を記載するファイルです。
"man systemd.unit"に詳細があります。
ここでは、"/etc/systemd/system/rc-local.service"を、ユニットファイルとして準備します。このファイルに、以下を記載します。

[Unit]
 Description=Execute /etc/rc.local
 ConditionFileIsExecutable=/etc/rc.local

[Service]
 Type=simple
 ExecStart=/etc/rc.local

[Install]
 WantedBy=multi-user.target
サービスの有効化
$ sudo systemctl enable rc-local
サービスの開始とステータスの確認
$ sudo systemctl start rc-local
$ sudo systemctl status rc-local

この "rc.local" の処理はすぐに終了するので、正常に処理された場合であっても、以下のように、ステータスは "inactive" です。

Active: inactive (dead) since ....

ユニットファイルの "[Service]" に "RemainAfterExit=yes" を記載すれば、以下のように、処理の終了後もステータスは"active"に維持されます。

Active: active (exited) since ...

いずれにせよ、再起動後も、画面の明るさを調整できます。