# Raspberry Pi OS

## Table of contents <!-- omit in toc -->

1. [First boot](#first-boot)
1. [Boot from USB](#boot-from-usb)
   1. [Raspberry Pi 4B](#raspberry-pi-4b)
1. [Repositories](#repositories)
1. [Privilege escalation](#privilege-escalation)
1. [Disable WiFi and Bluetooth](#disable-wifi-and-bluetooth)
   1. [Through boot configuration](#through-boot-configuration)
   1. [Through rfkill](#through-rfkill)
   1. [Disable the related services](#disable-the-related-services)
   1. [Disable the stacks completely uninstalling the packages](#disable-the-stacks-completely-uninstalling-the-packages)
1. [Disable swap](#disable-swap)
1. [Disable automatic upgrades](#disable-automatic-upgrades)
1. [Overlay filesystem mode](#overlay-filesystem-mode)
   1. [Store files on the SD when the overlay file system is active](#store-files-on-the-sd-when-the-overlay-file-system-is-active)
1. [Checks](#checks)
   1. [Frequencies](#frequencies)
   1. [CPU throttling](#cpu-throttling)
   1. [Board temperature](#board-temperature)
1. [Apply CPU governors](#apply-cpu-governors)
1. [Tuning](#tuning)
1. [Headless boot](#headless-boot)
    1. [The `wpa_supplicant` file](#the-wpa_supplicant-file)
       1. [Compute the password's hash](#compute-the-passwords-hash)
1. [Run containers](#run-containers)
    1. [Kernel containerization features](#kernel-containerization-features)
    1. [Firewall settings](#firewall-settings)
1. [Troubleshooting](#troubleshooting)
    1. [LED warning flash codes](#led-warning-flash-codes)
    1. [Issues connecting to WiFi network using roaming features or WPA3](#issues-connecting-to-wifi-network-using-roaming-features-or-wpa3)
1. [Further readings](#further-readings)
    1. [Sources](#sources)

## First boot

Unless manually set from the Imager, on first boot the system will ask to create a new initial user.

## Boot from USB

Available on Raspberry Pi 2B v1.2, 3A+, 3B, 3B+, 4B, 400, Compute Module 3, Compute Module 3+ and Compute Module 4 only.

### Raspberry Pi 4B

The bootloader EEPROM may need to be updated to enable booting from USB mass storage devices.

To check this, power the Pi up with no SD card inserted and a display attached to one of the HDMI ports.<br/>
It will display a diagnostic screen which includes the bootloader EEPROM version at the top.

The bootloader must be dated **_Sep 3 2020_** or later to support USB mass storage boot.<br/>
If the diagnostic screen reports a date earlier than _Sep 3 2020_, or there is no diagnostic screen shown, one will need
to update the bootloader EEPROM first to enable USB mass storage boot.

To update it:

1. use the _Misc Utility Images_ option in Raspberry Pi Imager to create an SD card with the latest
   _Raspberry Pi 4 EEPROM boot recovery_ image
1. boot the Pi using this SD card
1. the bootloader EEPROM will be updated to the latest factory version
1. the Pi will flash its green ACT light rapidly and display green on the HDMI outputs to indicate success

USB mass storage boot on the Pi 4B requires Raspberry Pi OS 2020-08-20 or later.

## Repositories

[Repositories], [Mirrors].

```sh
curl -fsSL https://raspbian.mirror.garr.it/mirrors/raspbian/raspbian.public.key | sudo gpg --dearmor -o /etc/apt/keyrings/raspbian.mirror.garr.it
curl -fsSL https://mirror.nl.leaseweb.net/raspbian/raspbian.public.key | sudo gpg --dearmor -o /etc/apt/keyrings/mirror.nl.leaseweb.net.gpg
cat <<EOF | sudo tee /etc/apt/sources.list.d/mirrors.list > /dev/null
deb [arch=armhf signed-by=/etc/apt/keyrings/raspbian.mirror.garr.it] https://raspbian.mirror.garr.it/mirrors/raspbian/raspbian/ bullseye main contrib non-free rpi firmware
deb [arch=armhf signed-by=/etc/apt/keyrings/mirror.nl.leaseweb.net.gpg] http://mirror.nl.leaseweb.net/raspbian/raspbian bullseye main contrib non-free rpi firmware
deb [arch=armhf signed-by=/etc/apt/keyrings/mirror.nl.leaseweb.net.gpg] https://raspbian.mirror.liteserver.nl/ bullseye main contrib non-free rpi firmware
EOF
sudo apt update
```

## Privilege escalation

- Users in the `sudo` group can `sudo`.
- The initial user can `sudo` without being asked for a password by default.

## Disable WiFi and Bluetooth

### Through boot configuration

Disable one or both in the `all` section of `/boot/config.txt`:

```ini
[all]
dtoverlay=disable-wifi
dtoverlay=disable-bt
```

### Through rfkill

1. block one or both:

   ```sh
   rfkill block 'wifi'
   rfkill block 'bluetooth'
   ```

1. check they are correctly soft-blocked:

   ```sh
   rfkill list
   ```

### Disable the related services

- `hciuart.service` and `bluetooth.service` for Bluetooth
- `wpa_supplicant.service` for WiFi

### Disable the stacks completely uninstalling the packages

```sh
sudo apt --assume-yes purge 'bluez'
sudo apt --assume-yes autoremove --purge
```

## Disable swap

Disable the swap file:

```sh
sudo systemctl disable --now 'dphys-swapfile'
```

## Disable automatic upgrades

Raspberry Pi OS has daily upgrades enabled by default. Check the second line of this command's output:

```sh
systemctl status 'apt-daily-upgrade.timer'
```

Check the time it was last run with the following:

```sh
stat -c '%z' '/var/lib/apt/daily-lock'
```

If the service is enabled, there should be a record of that in `/var/log/dpkg.log`.

To disable this, execute the following:

```sh
sudo systemctl mask 'apt-daily-upgrade'
sudo systemctl mask 'apt-daily'
sudo systemctl disable 'apt-daily-upgrade.timer'
sudo systemctl disable 'apt-daily.timer'
```

Using **_mask_** to prevent the above services from being re-enabled by some dependency.

Notice those are two separate services; they both run `/usr/lib/apt/apt.systemd.daily`, a shell script, with parameters install and update.

## Overlay filesystem mode

This enhances the performances, but all changes will be kept in RAM and lost after a reboot unless it is saved elsewhere.

Enable it using `raspi-config`. While enabled, `/root` is in RO and no data will be written to the card.

### Store files on the SD when the overlay file system is active

The files just need to be stored on a different file system from `/`. You can partition the SD and use that, or create a file and mount it as a virtual file system:

```sh
truncate -s '6G' 'file'
mkfs.ext4 'file'
mkdir 'mount/point'
sudo mount -t 'ext4' -o 'loop' 'file' 'mount/point'
sudo chown 'user':'group' 'mount/point'
touch 'mount/point/new-file'
```

## Checks

See [vcgencmd] for more information.

### Frequencies

```sh
# Current CPU frequency.
vcgencmd measure_clock arm

# Current GPU frequency.
vcgencmd measure_clock core

# Min set frequency per CPU core.
cat '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq'
cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_min_freq

# Max set frequency per CPU core.
cat '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq'
cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_max_freq

# Current set frequency per CPU core.
cat '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq'
cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq
```

### CPU throttling

See also [Re: How to make sure the rpi cpu is not throttled down?].

```sh
$ vcgencmd get_throttled
throttled=0x0
```

The bits in this number represent the following:

| Bit | Hex value | Meaning                                                                            |
| --- | --------- | ---------------------------------------------------------------------------------- |
| 0   | 0x1       | Under-voltage detected; occurs when voltage drops below 4.63V; the Pi is throttled |
| 1   | 0x2       | Arm frequency capped; occurs with temp > 80˚C                                      |
| 2   | 0x4       | Currently throttled                                                                |
| 3   | 0x8       | Soft temperature limit active                                                      |
| 16  | 0x10000   | Under-voltage has occurred                                                         |
| 17  | 0x20000   | Arm frequency capping has occurred                                                 |
| 18  | 0x40000   | Throttling has occurred                                                            |
| 19  | 0x80000   | Soft temperature limit has occurred                                                |

`over-temperature` occurs with temp > 85˚C. The Pi is throttled.

Throttling removes turbo mode, which reduces core voltage and sets arm and gpu frequencies to a non-turbo value.

Capping just limits the CPU frequency (somewhere between 600MHz and 1200MHz) to try to avoid throttling.

If the board throttled but is not under-voltage, you can assume over-temperature; confirm this with `vcgencmd measure_temp`.

Sums of error codes mean multiple events occurred.<br/>
E.g., `0x50005` means you are currently under-voltage and throttled. If you want to be able to support this use case without throttling you will need a better power supply.

If you never see a non-zero `get_throttled` value in normal usage, then you may not need to do anything.

### Board temperature

```sh
$ vcgencmd measure_temp
temp=73.1'C
```

## Apply CPU governors

Until next boot:

```sh
echo 'ondemand' | sudo tee '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'
echo 'performance' | sudo tee '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'
echo 'powersave' | sudo tee '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor'
```

Permanently:

```sh
sudo nano '/etc/init.d/raspi-config'
```

## Tuning

See [Timely tips for speeding up your Raspberry Pi].

```sh
# Run benchmarks.
curl -L https://raw.githubusercontent.com/aikoncwd/rpi-benchmark/master/rpi-benchmark.sh | sudo bash
```

## Headless boot

Manual procedure:

1. Image the SD card

   ```sh
   sudo dd bs='4M' if='/tmp/2019-09-26-raspbian-buster-lite.img' of='/dev/mmcblk0' status='progress' oflag='sync'
   ```

1. Mount the `boot` partition.
1. Create an empty `ssh` file in that partition.<br/>
   This will enable the `ssh` service at boot.
1. Create the `wpa_supplicant.conf` file in the same partition.<br/>
   This will be used to overwrite the same file in `/etc` on the OS.

   1. Follow the template below.
   1. \[Optionally] fill the template with the password's hash for improved security

### The `wpa_supplicant` file

`wpa_supplicant.conf` template:

```ini
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=«your_ISO-3166-1_two-letter_country_code»

network={
    ssid="«your_SSID»"
    psk="«your_PSK»"
    key_mgmt=WPA-PSK
}
```

Replace `«your_ISO-3166-1_two-letter_country_code»` with your [ISO Country Code](https://www.iso.org/obp/ui/#search/code/) (such as CA for Canada), `«your_SSID»` with your wireless access point name and `«your_PSK»` with your wifi password.

Note that the `country`, `ctrl_interface` and `update_config` lines are required in file as created in `/boot`: if they are missing the system will not connect to the network. The above process can be repeated to correct the omissions.

`wpa_supplicant.conf` example:

```ini
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=IE

network={
    ssid="VM6371722"
    psk=77475166938e2ddc18bcde2a59d4b63810c0a05ddf9b931e4b0223b74e94e389  # psk="qqqqqqqqq"
    key_mgmt=WPA-PSK
}
```

#### Compute the password's hash

Use `wpa_passphrase`:

```plaintext
usage: wpa_passphrase <ssid> [passphrase]
If passphrase is left out, it will be read from stdin
```

The utility will prompt for the password, and will return the hexadecimal hash value. This hashed password is to be stored **without quotes** in the `/boot/wpa_supplicant.conf` file.

```sh
$ wpa_passphrase "ssid"
# reading passphrase from stdin
password
network={
    ssid="ssid"
    #psk="password"
    psk=77475166938e2ddc18bcde2a59d4b63810c0a05ddf9b931e4b0223b74e94e389
}
```

## Run containers

1. enable the kernel's containerization feature
1. disable swap
1. if kubernetes is involved, set up the firewall to use the legacy configuration

### Kernel containerization features

Enable containerization features in the kernel to be able to run containers as intended.

Add the following properties at the end of the line in `/boot/cmdline.txt`:

```sh
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1
```

```sh
sed -i '/cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1/!s/\s*$/ cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1&/' /boot/cmdline.txt
```

### Firewall settings

Switch Debian firewall to use the legacy configuration:

```sh
update-alternatives --set 'iptables'  '/usr/sbin/iptables-legacy'
update-alternatives --set 'ip6tables' '/usr/sbin/ip6tables-legacy'
```

## Troubleshooting

### LED warning flash codes

If a Raspberry Pi fails to boot or has to shut down for some reason, in most cases it will flash a LED a specific number of times to indicate what happened.<br/>
The LED will blink for a number of long flashes (0 or more), then short flashes, to indicate the exact status. In most cases, the pattern will repeat after a 2 second gap.

See the [configuration] page for updated information.

| Long flashes | Short flashes | Status                                 | Notes     |
| ------------ | ------------- | -------------------------------------- | --------- |
| 0            | 3             | Generic failure on boot                |           |
| 0            | 4             | `start*.elf` not found                 |           |
| 0            | 7             | Kernel image not found                 |           |
| 0            | 8             | SDRAM failure                          |           |
| 0            | 9             | Insufficient SDRAM                     |           |
| 0            | 10            | In HALT state                          |           |
| 2            | 1             | Partition not FAT                      |           |
| 2            | 2             | Failed to read from partition          |           |
| 2            | 3             | Extended partition not FAT             |           |
| 2            | 4             | File signature/hash mismatch           | Pi 4 only |
| 3            | 1             | SPI EEPROM error                       | Pi 4 only |
| 3            | 2             | SPI EEPROM is write protected          | Pi 4 only |
| 3            | 3             | I2C error                              | Pi 4 only |
| 3            | 4             | Secure-boot configuration is not valid |           |
| 4            | 4             | Unsupported board type                 |           |
| 4            | 5             | Fatal firmware error                   |           |
| 4            | 6             | Power failure type A                   |           |
| 4            | 7             | Power failure type B                   |           |

### Issues connecting to WiFi network using roaming features or WPA3

Check [raspbian's bug 1929746][raspbian bug 1929746] for more information.

Quick solutions:

- (quick 'n' dirty) disable roaming options and WPA3 in your router;
- (preferable) disable SAE (WPA3) and SWSUP (offload authentication to the firmware), and fast roaming:

  ```sh
  rmmod 'brcmfmac'
  modprobe 'brcmfmac' roamoff=1 feature_disable=0x82000
  ```

  Make it permanent in a `.conf` file in `/etc/modprobe.d/`:

  ```sh
  # /etc/modprobe.d/wifi_workaround.conf
  options brcmfmac roamoff=1 feature_disable=0x82000
  ```

Long term solution: none currently known.

## Further readings

- [`/boot/config.txt`][/boot/config.txt]
- [Overclocking]
- [`rfkill`][rfkill]
- [Country code search]
- [`k3s`][k3s]
- [Configuration]
- [os documentation]

### Sources

- [Prepare SD card for WiFi on headless Pi]
- [Run Kubernetes on a Raspberry Pi with k3s]
- Project's [issue 2067]
- [Re: How to make sure the rpi CPU is not throttled down?]
- [Timely tips for speeding up your Raspberry Pi]
- [Repositories]
- [Mirrors]
- [disabling bluetooth on raspberry pi]
- [ghollingworth/overlayfs]
- [how to disable onboard wifi and bluetooth on raspberry pi 3]
- [how to disable wi-fi on raspberry pi]
- [how to disable your raspberry pi's wi-fi]
- [how to make your raspberry pi 4 faster with a 64 bit kernel]
- [re: raspbian jessie linux 4.4.9 severe performance degradati]
- [rp automatic updates]
- [sd card power failure resilience ideas]
- [alpine linux headless installation]
- [alpine linux]
- [benchmark]
- [preventing filesystem corruption in embedded linux]
- [usb mass storage boot]

<!--
  Reference
  ═╬═Time══
  -->

<!-- Upstream -->
[/boot/config.txt]: https://www.raspberrypi.org/documentation/configuration/config-txt/README.md
[configuration]: https://www.raspberrypi.com/documentation/computers/configuration.html
[mirrors]: https://www.raspbian.org/RaspbianMirrors
[os documentation]: https://www.raspberrypi.org/documentation/computers/os.html
[overclocking]: https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md
[repositories]: https://www.raspbian.org/RaspbianRepository
[vcgencmd]: https://www.raspberrypi.com/documentation/computers/os.html#vcgencmd

<!-- Knowledge base -->
[k3s]: kubernetes/k3s.md
[rfkill]: rfkill.md

<!-- Others -->
[alpine linux headless installation]: https://wiki.alpinelinux.org/wiki/Raspberry_Pi_-_Headless_Installation
[alpine linux]: https://wiki.alpinelinux.org/wiki/Raspberry_Pi
[benchmark]: https://github.com/aikoncwd/rpi-benchmark
[country code search]: https://www.iso.org/obp/ui/#search/code/
[disabling bluetooth on raspberry pi]: https://di-marco.net/blog/it/2020-04-18-tips-disabling_bluetooth_on_raspberry_pi/
[ghollingworth/overlayfs]: https://github.com/ghollingworth/overlayfs
[how to disable onboard wifi and bluetooth on raspberry pi 3]: https://sleeplessbeastie.eu/2018/12/31/how-to-disable-onboard-wifi-and-bluetooth-on-raspberry-pi-3/
[how to disable wi-fi on raspberry pi]: https://raspberrytips.com/disable-wifi-raspberry-pi/
[how to disable your raspberry pi's wi-fi]: https://pimylifeup.com/raspberry-pi-disable-wifi/
[how to make your raspberry pi 4 faster with a 64 bit kernel]: https://medium.com/for-linux-users/how-to-make-your-raspberry-pi-4-faster-with-a-64-bit-kernel-77028c47d653
[issue 2067]: https://github.com/k3s-io/k3s/issues/2067#issuecomment-664052806
[prepare sd card for wifi on headless pi]: https://raspberrypi.stackexchange.com/questions/10251/prepare-sd-card-for-wifi-on-headless-pi
[preventing filesystem corruption in embedded linux]: https://www.embeddedarm.com/assets/preventing-filesystem-corruption-in-embedded-linux
[raspbian bug 1929746]: https://bugs.launchpad.net/raspbian/+bug/1929746
[re: how to make sure the rpi cpu is not throttled down?]: https://www.raspberrypi.org/forums/viewtopic.php?t=152549#p999931
[re: raspbian jessie linux 4.4.9 severe performance degradati]: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=147781&start=50#p972790
[rp automatic updates]: https://raspberrypi.stackexchange.com/questions/102377/rp-automatic-updates#102379
[run kubernetes on a raspberry pi with k3s]: https://opensource.com/article/20/3/kubernetes-raspberry-pi-k3s
[sd card power failure resilience ideas]: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=253104&p=1549229#p1549117
[timely tips for speeding up your raspberry pi]: https://www.raspberry-pi-geek.com/Archive/2013/01/Timely-tips-for-speeding-up-your-Raspberry-Pi
[usb mass storage boot]: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md
