Raspberry Pi Zero 2 WにBookworm(64-bit) Desktopをインストール

## 1.はじめに
　Raspberry Pi Zero 2 W（以下、Zero 2 W）は、2015年に初登場したRaspberry Pi Zeroシリーズの第2世代モデルで、2021年に英国、2022年に日本で発表されました。Zero 2 Wは、従来のシングルコアから4コアのCPUに強化され、大幅に性能が向上しています。Zeroシリーズは、従来の高性能なRaspberry Pi シリーズ（Pi 5，Pi 4B）とは以下の点で差別化されています。
* Wi-Fi(2.4GHz)の通信機能がありながら基板サイズが従来シリーズの約半分で、小型化が求められるIoT機器の組み込みに適しています。
* 低消費電力で動作するため、バッテリー駆動のモバイルデバイスに最適です。
* 1GHzのCPUと512MBのRAMを備え、スペックは控えめですが、価格はPi 5の約3分の1です。

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/95387b69-543c-c257-cdfe-66011f85ef27.jpeg">

写真：左側　Zero 2 W、右側　Raspberry Pi 5。写真のZero 2 Wには、GPIO信号の入出力のためにピンヘッダをはんだ付けしています。

　通常、Zeroシリーズはリモートからターミナルにログインして操作するのが一般的だと思いますが、Zero 2 WではGUIベースのデスクトップ(Desktop)も利用可能です。2024年7月4日に新しいOSであるBookworm（64-bit）版のデスクトップがリリースされたため、インストールしてみました。インストール後にスワップメモリの拡張、使用しないプロセスの停止、オーバークロックの設定を行って、システムのパフォーマンスの改善を目指します。
 　しかし、先に結論をべると、Raspberry Piシリーズ（Pi 5、Pi 4B）のようにサクサク動作するわけではなく、Webブラウザなどの負荷が大きいアプリの動作は厳しいです。それでも、初心者や学生を対象としたプログラミング学習やホビーユースなど、使用できる用途はあるかもしれません。
  
#### 1.1 使用したもの
* Rasberry Pi Zero 2 W
* OS：Bookworm(64-bit) Release 5.3 July 2024
* microSDカード：KIOXIA microSDHC EXCERIA 32GB 100MB/s
* PC、ディスプレイ、キーボード、マウス、カードリーダー
* Wi-Fi環境

## 2. microSDカードにOSイメージの書き込み
　PCでRaspberry Pi Imagerを利用して、microSDカードにOSイメージを書き込みます。ImagerはRaspberry Piの公式ウェブサイトからダウンロードして、PCにインストールできます。
 https://www.raspberrypi.com/software/
 Imagerの各項目を以下のように選択し、「次へ」をクリックします。
|項　目 | 選　択|
|:----------------------------:|:--------------:|
|Raspberry Piデバイス | RASBERRY PI ZERO 2 W |
|OS | Raspberry Pi OS (64-bit) A port of Debian Bookworm with the Raspberry Pi Desktop(Recommended)|
|ストレージ　|　microSDカード|

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/1256d45f-812d-d8a8-941e-df9a267d8643.png">

　「Would you like to apply OS customization settings?」というダイアログで「いいえ」をクリックします。次に、「SDHC Cardに存在するすべてのデータは完全に削除されます。本当に続けますか？」というダイアログで「はい」をクリックします。これで、microSDカードにOSイメージの書き込みが始まります。しばらくすると「Raspberry Pi OS(64-bit)はSDHC Cardに書き込まれました。」というダイアログが表示されますので、「続ける」をクリックします。最後に、microSDカードを取り出して、Raspberry Pi Imagerを終了します。
## 3. OSのセットアップ
　OSのイメージを書き込んだmicroSDカードをZero 2 Wにセットし、電源を入れます。
* しばらくすると、ディスプレイに「Welcome to the Raspberry Pi Desktop!」というダイアログが表示されるので、「Next」をクリックします。以降の画面切り替えでは、特に指示がない限り「Next」をクリックして進めてください。キャプチャは省略しますが、流れに従って設定を進めてください。

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/30ee887e-3e0b-b0dd-feed-18932eac3850.png">

* 「Set Country」のダイアログで、[Country]リストから[Japan] を選択すると、自動的に[Language]⇒[Japanese]、[Timezone]⇒[Tokyo]に設定されます。
* 「Create User」のダイアログで、ユーザー名とパスワードを設定します。
* 「Set Up Screen」では、デスクトップ画面がディスプレイより大きい場合にスイッチをオンにします。
* 「Select WiFi Network」のダイアログで、アクセスポイントを選択します。
* 「Enter WiFi Password」ダイアログで、パスワードを入力します。
* 「Choose Browser」のダイアログでは、デフォルトのまま「Next」をクリックします。
* 「Enable Raspberry Pi Connect」のダイアログも、デフォルトのまま「Next」をクリックします。必要であれば、インストールした後でも「Raspberry Piの設定」から有効にできます。
* 「Update Software」のダイアログで「Next」をクリックします。
* 最後の「Setup Complete」ダイアログで［Restart］をクリックして再起動します。<br>
2024-07-04付けのイメージでは、日本語IMEにMOZCが自動的にインストールされます。ターミナルから下記のコマンドにウィンドシステムの種別を確認できます。「X11」と表示されて、従来使用されていたX Window Systemと判明しました。なお、Raspberry Pi 5やPi 4Bの場合、新しいシステム名「Wayland」が表示されます。
```
$ echo $XDG_SESSION_TYPE
X11
```

## 4. スワップ領域を拡張する
　Raspberry Piシリーズ（Pi 5、Pi 4B）の物理メモリ(RAM)が2GB,4GB,8GBに対して、Zero 2Wの物理メモリは512MBと少なめです。システムでは、スワップ領域（ファイル）をストレージ（ここではmicroSDカード）に確保し、物理メモリがひっぱくした際に、直近に使われていないメモリ領域の内容をスワップ領域に退避させ、物理メモリに空き領域を作り出します[1]。スワップ領域を拡張することで、システムのパフォーマンスを改善します[2]。
#### 4.1. 物理メモリとスワップ容量の確認
　free -mコマンドは、システムのメモリ使用状況をMB（メガバイト）単位で表示します。このコマンドを実行すると、以下のような出力が表示されます。Memが物理メモリ、Swapがスワップ領域を示します。スワップ領域の総容量（MB）は199と表示されますが、実際には200MBが/var/swapに確保されています。180MBが使用中でほとんど余裕がありません。この状態でコマンドやアプリを実行するとメモリ不足が発生して、システムがフリーズする可能性があります。なお、物理メモリで完全に未使用のfreeメモリは145MBで、バッファやキャッシュから融通できるメモリと合わせると、実際には183MB(available)が使用可能です。

```
$ free -m
               total        used        free      shared  buff/cache   available
Mem:             417         233         145           0         100         183
Swap:            199         180          19
```
#### 4.2. ターミナル起動に切り替えて作業する
　スワップサイズを変更する際に、システムが一時的にスワップ領域を使用しないようにします。これにより、物理メモリがさらに不足する状況になるため、軽量なターミナル（CLI：Command Line Interface）での起動に切り替えて作業し、その後デスクトップ起動に戻します。
* [Menu]⇒[設定]⇒[Raspberry Piの設定]を開きます。
* [システム]タブの[ブート]項目の[CLI]にチェックを入れ、「OK」を押して再起動します。
※ [CLI]にチェックを入れると、自動的に「スプラッシュ画面」のスイッチがオフになります。スプラッシュ画面とは、デスクトップが表示される前に「Welcome to the Raspberry Pi Desktop」と表示される画面のことです。<br>
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/c01438cf-3f72-6360-4e86-e9daa937742c.png">

　再起動すると、ターミナルが表示されます。free -mコマンドを実行するとSwapの使用量は0と表示されて、ターミナルがメモリに対して軽量であることが確認できます。まず、システムがスワップ領域を使用しないようにします。
```
$ sudo dphys-swapfile swapoff
```
　dphys-swapfileのCONF_SWAPSIZEを物理メモリの2倍にあたる1024MB(1GB)に変更します[3]。nanoエディタではマウスは使用できませんが、キーボードの矢印キーでカーソルを移動できます。CONF_SWAPSIZEまで移動して、backspaceで200を削除してから、1024と入力します。
```
$ sudo nano /etc/dphys-swapfile
```
【変更前】CONF_SWAPSIZE=200
【変更後】CONF_SWAPSIZE=<b>1024</b>

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/3ad4ae04-bd61-ea21-66f0-f780c4ff3e30.png">

　nanoで編集したら、ファイルを保存して終了します。ショートカットキーを使って操作します。まず、CTRL+xを押し、次にｙを押して、最後にENTERを押します。catコマンドで変更した内容を確認します。
```
$ cat /etc/dphys-swapfile
```
　次に、スワップ領域を再初期化します。1024MBに変更されたメッセージが表示されれば、問題ありません。そして、OSがスワップ領域を使用できるようにします。
```
$ sudo dphys-swapfile setup
want /var/swap=1024MByte, checking existing: deleting wrong size file (209715200), generating swapfile ... of 1024MBytes
$ sudo dphys-swapfile swapon
```
#### 3\. デスクトップから起動できるようにする
デスクトップから起動できるようにraspi-configコマンドで設定を変更します。
```
$ sudo raspi-config
```
* raspi-configのダイアログの「1 System Options」を選択してENTERを押します。
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/c9e31729-5697-56d8-748c-203dae2ab1e5.jpeg">

* キーボードの矢印キーでカーソルを移動させて「S5 Boot/Auto Login・・・」を選択してENTERを押します。
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/21497c4b-5da6-b0b8-414d-97e21d052195.jpeg">

* 「B4 Desktop Autologin Desktop GUI,・・・」に移動してENTERを押します。
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/dc2cc5ad-3767-a633-2f0f-3d399ac04fe2.jpeg">

* しばらくすると、最初のダイアログに戻るので、TABを押して「Finish」に移動してENTERを押します。
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/173e1427-5ec4-32bd-68f1-9a0ff8dbe6d9.jpeg">

* 再起動のダイアログに切り替わり、「はい」が字化けしていますがENTERを押します。
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/0d360fa3-9155-6744-a260-19f966f13243.jpeg">

　システムが再起動したら、デスクトップのターミナルからスワップ領域が拡張されたことを確認します。なお、スプラッシュ画面を再表示したい場合は、「Raspberry Piの設定」でスプラッシュ画面」のスイッチがオンにします。
```
$ free -m
               total        used        free      shared  buff/cache   available
Mem:             417         218         136           0         124         198
Swap:           1023         202         821
```
## 5. 使用しないサービスを停止する
　システムの起動時に自動的に実行されるものの、実際には使用しないサービスやデーモンがあります。これらを停止することで、CPUやメモリの消費を減らし、システム全体のパフォーマンスを向上させることができます。ここでは、いくつかのサービスやデーモンを停止しますが、必要に応じて選択してください。サービスを停止しない場合は、本章をスキップしてください。
　systemctlコマンドで起動しているサービスを確認します。UNIT FILEはサービスユニットのフルネームです。STATEはサービスユニットがブート時に自動的に起動するかどうかの情報を示しています。
 ```
$ sudo systemctl list-unit-files -t service|grep -e UNIT -e enabled
UNIT FILE                                  STATE           PRESET
accounts-daemon.service                    enabled         enabled
alsa-utils.service                         masked          enabled
apparmor.service                           enabled         enabled
avahi-daemon.service                       enabled         enabled
bluetooth.service                          enabled         enabled
console-setup.service                      enabled         enabled
cron.service                               enabled         enabled
cryptdisks-early.service                   masked          enabled
cryptdisks.service                         masked          enabled
cups-browsed.service                       enabled         enabled
cups.service                               enabled         enabled
dphys-swapfile.service                     enabled         enabled
e2scrub_reap.service                       enabled         enabled
fake-hwclock.service                       enabled         enabled
fio.service                                disabled        enabled
getty@.service                             enabled         enabled
glamor-test.service                        enabled         enabled
hciuart.service                            enabled         enabled
hwclock.service                            masked          enabled
ifupdown-wait-online.service               disabled        enabled
keyboard-setup.service                     enabled         enabled
lightdm.service                            enabled         enabled
ModemManager.service                       enabled         enabled
/*　　　　　　　　　　　　　　中　略                               */
wpa_supplicant@.service                    disabled        enabled
x11-common.service                         masked          enabled
 ```
 ここでは、下記のサービスを停止して、自動起動しないように設定します。
|サービス名 | 概　要|
|:----------------------------:|:--------------:|
|bluetooth |Bluetoothデバイスの管理を行うサービスです。|
|avahi-daemon|ネットワーク内のデバイスを自動的に検出します。|
|cups-browsed, cups|プリンタの検出や印刷ジョブの管理を行うサービスです。|
|ModemManager|WWAN (2G/3G/4G/5G)デバイスと接続を制御するシステム デーモンです。|

* サービスを停止(stop)し、自動起動しないように無効化(disable)します。なお、avahi-daemonを停止(stop)した際に警告が表示されますが、そのまま作業を継続してください。
```
sudo systemctl stop [サービス名]
sudo systemctl disable [サービス名]

例 ModemManager.serviceの停止と無効化
sudo systemctl stop ModemManager
sudo systemctl disable ModemManager
```
* サービスを再有効化する場合の手続きは下記になります。
```
sudo systemctl enable [サービス名]
sudo systemctl start [サービス名]
```
　システムを再起動させて、有効な物理メモリの量(available)を確認します。誤差が含まれるかもしれませんが、前回の結果と比較して約9%の余裕ができました。
```
$ free -m
               total        used        free      shared  buff/cache   available
Mem:             417         200         185           0          94         216
Swap:           1023         190         833
```
 　なお、bluetoothのサービスをsysytemctlコマンドで停止・無効化しても、デスクトップのタスクバーのbluetoothアプリは有効な状態です。bluetoothアイコンのメニューの「Bluetoothをオフにする」をクリックして無効にします。
  
## 6. オーバークロックの設定
　CPUのクロック速度を上げることで、システムの処理速度を向上させることができます。ただし、オーバークロックの設定によっては、システムが起動しなくなったり、Zero 2 W本体の故障の原因になるため、慎重に行う必要があります。
 　config.txtファイルの設定を変更する前に、システムが起動しない場合に備えて、SDカードのコピーを作成することをお勧めします。コピーの作成には、[menu]⇒[アクセサリ]⇒[SD Card Copier]のアプリを使用します。Zero 2 Wの個体差によって、1.3GHzで動作しない場合があるようです[4]。まずは、1.2GHzから試すと良いでしょう。設定項目の詳細については、参考文献[5]を参照してください。GPUの周波数が上がることで、グラフィック処理も向上します。

|オプション名| 概　要 |1GHz<br>(デフォルト) | 1.2GHz | 1.3GHz |
|:----:|:---:|:---------:|:-----:|:---:|
|over_voltage|CPU/GPUの電圧を25mV単位で増減|0| 2 | 4 |
|arm_freq|CPUの周波数|1000|1200|1300|
|core_freq|GPUの周波数|400|400|500|

mousepadでconfig.txtを開きます。
```
$ sudo mousepad /boot/firmware/config.txt
```
ファイルの一番最後の[all]の下にカーソルを移動させて設定を追記します。
```
[all]
over_voltage=2
arm_freq=1200
```
config.txtを保存して終了し、再起動します。vdgencmdコマンドで変更を確認します。

    $ vcgencmd get_config [オプション名]
    例
    $ vcgencmd get_config arm_freq
    arm_freq=1200
　動作を確認できたら、1.3GHzでのオーバークロックにも挑戦してみてください。config.txtに「core_freq=500」も追記してください。

　ベンチマークツールsysbenchをインストールして、オーバークロックする前と後で、CPUとメモリのスピードを測定しました。

     $ sudo apt update && sudo apt upgrade -y
     $ sudo apt install sysbench

     $ sysbench --test=cpu --cpu-max-prime=20000 run
	 // --cpu-max-prime=20000 は、計算する素数の上限を指定しています。
     $ sysbench --test=memory run
	 // メモリの読み書き速度の結果を記録します。
　誤差は含まれますが、CPUスピードは約30%、メモリスピードは約34%向上しました。
        |測定項目| 1GHz<br>(デフォルト)  | 1.3GHz<br>(オーバークロック後) |
|:----:|:------:|:---:|
|CPU speed: events per second:|194.58|252.97|
|memory speed test Total operations:|923722.80 per second|1239680.55 per second|

 　CPUの電圧や周波数を上げることで発熱が増加するため、SoCにヒートシンクを取り付けるなどの対策が有効です。
 
## 7. Lチカで学習環境の確認
　Zero 2 Wのデスクトップのインストールとチューンアップは以上で完了です。次に、プログラミングの学習環境の確認するために、GPIO23に390Ωの抵抗とLEDを接続して、１Hzの周波数でLチカ（LEDの点滅）を実行してみましょう[6]。

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631966/0c51810d-2315-f936-3f4d-155ec1d8aa2e.jpeg">

 
joan2937氏がフリーで公開しているGPIO制御ライブラリ「<b>lgpio</b>」をインストールして使用します。
 
    $ wget http://abyz.me.uk/lg/lg.zip
    $ unzip lg.zip
    $ cd lg
    $ make
    $ sudo make install

* C言語の場合
テキストエディタGeanyで下記のソースコードを入力して、ビルドして実行します。Geanyの「ビルドコマンドを設定」の[Build]に「gcc -Wall -o "%e" "%f" -llgpio -lpthread -g -O0」を設定します。o（オー）の小文字と大文字の違いに注意。
```c:4-Led01.c
#include <stdio.h>
#include <stdlib.h>     //EXIT_SUCCESS
#include <lgpio.h>      //lgGpiochipOpen,lgGpioWrite,etc
#define LED0    23      //GPIO23をLED0と定義

int main(void) {
    int hnd;
    int lFlgOut=0;
    hnd = lgGpiochipOpen(0);    //GPIOチップをオープン
    lgGpioClaimOutput(hnd,lFlgOut,LED0,LG_LOW); //GPIOピンを出力に設定
    for(;;){
        lgGpioWrite(hnd,LED0,LG_HIGH);
        lguSleep(0.5);      //0.5秒時間待ち
        lgGpioWrite(hnd,LED0,LG_LOW);
        lguSleep(0.5);      //0.5秒時間待ち
    }
    lgGpiochipClose(hnd);   //GPIOチップをクローズ
    return EXIT_SUCCESS;
}
```

* Pythonの場合
エディタThonnyで下記のpythonコードを入力して実行します。

```python:LED.py
import lgpio
import time

# 使用するGPIOピンの番号（BCM番号）
LED_PIN = 23

# GPIOチップをオープン
chip = lgpio.gpiochip_open(0)

# GPIOピンを出力に設定
lgpio.gpio_claim_output(chip, LED_PIN)

try:
    while True:
        # LEDを点灯
        lgpio.gpio_write(chip, LED_PIN, 1)
        time.sleep(0.5)

        # LEDを消灯
        lgpio.gpio_write(chip, LED_PIN, 0)
        time.sleep(0.5) 

except KeyboardInterrupt:
    # プログラム終了時にGPIOをクローズ
    pass

finally:
    lgpio.gpiochip_close(chip)
```

## 8. おわりに
　スワップ領域の拡張、使用しないプロセスの停止、オーバークロックの設定を行って、メモリリソースを増加させたり、処理速度が向上したことをコマンドやツールを使用して確認しました。しかし、Raspberry Piシリーズ（Pi 5、Pi 4B）のようにサクサク動作するわけではなく、Webブラウザなどの負荷が大きいアプリの動作は厳しい状況です。それでも、初心者のプログラミング学習やホビーユースなど、使用できる用途はあるかもしれません。最終的には、読者の判断に委ねる部分もありますが、本稿が限られた予算とリソースに奮闘されて、プログラミングやデジタルメイキングを学ぶ方および携わる方への情報提供になれば幸いです。

## Reference
[1] スワップ 【swap】, "https://e-words.jp/w/スワップ.html"
[2] Raspberry PIにてSWAPファイルのリサイズ, "https://qiita.com/neomi/items/9212885b7c08a17f1572"
[3] swapは容量によってメモリ x 2 では無いみたい, "https://qiita.com/akagane99/items/581afdbe827c050ce461"
[4] Raspberry Pi Zero 2 Wのすべて, "https://picockpit.com/raspberry-pi/ja/ラズベリー・パイ・ゼロのすべてとは？/#Overclocking"
[5] What is config.txt?, "https://www.raspberrypi.com/documentation/computers/config_txt.html"
[6] 菊池達也,"C言語ではじめるRaspberry Pi徹底入門",技術評論社,pp.68-72,(Apr.2020)