# Installation on RaspberryPi Trixie (64)
This documents steps to running a prebuilt Exercise 306 binary on a Raspberry Pi 4B or Pi Zero 2W. You will need a second instance to hand shake with, which can be another ARM64 Pi, an AMD64 Linux host, or a T-Beam (ESP32-S).

![](../../img/DSC_5347_v1.jpg)
## New SD Card (Optional)
This section is optional if you already have Trixie running on a Raspberry Pi 4B or Raspberry Pi Zero 2W.  This install guide has not been tested on other model.

This assume you know where your SD Card is exposed as a device and in this example, the card is available as /dev/sdf.

     sudo dd if=/home/jlpoole/Downloads/RaspberryPi/2026-04-21-raspios-trixie-arm64-lite.img of=/dev/sdf bs=4M status=progress conv=fsync

Example:
```bash
jlpoole@jp ~ $ date; time sudo dd if=/home/jlpoole/Downloads/RaspberryPi/2026-04-21-raspios-trixie-arm64-lite.img of=/dev/sdf bs=4M status=progress conv=fsync
Fri May 22 09:32:34 PDT 2026
2738880512 bytes (2.7 GB, 2.6 GiB) copied, 105 s, 26.1 MB/s3229614080 bytes (3.2 GB, 3.0 GiB) copied, 105.792 s, 30.5 MB/s
 
770+0 records in
770+0 records out
3229614080 bytes (3.2 GB, 3.0 GiB) copied, 140.443 s, 23.0 MB/s
 
real    2m20.497s
user    0m0.008s
sys     0m0.009s
jlpoole@jp ~ $ 
```

## 1. Confirm the target image is 64-bit ARM
Your binary is:
```bash
ELF 64-bit LSB pie executable, ARM aarch64
interpreter /lib/ld-linux-aarch64.so.1
```
So your receiving Pi image must be 64-bit Raspberry Pi OS / Debian Trixie, not 32-bit.

```bash
uname -m
getconf LONG_BIT
```
Expected:
```bash
aarch64
64
```
## 2. Install runtime packages
BlueZ is the official Linux Bluetooth protocol stack and supplies Bluetooth daemons/tools on Debian Trixie.  The rfkill package is useful because blocked Bluetooth is a common fresh-image problem.  For Raspberry Pi Bluetooth firmware, Debian’s bluez-firmware package specifically notes Broadcom BCM203x and Raspberry Pi chipset support.
```bash
sudo apt update

sudo apt install -y \
  bluez \
  bluez-firmware \
  rfkill \
  bluetooth \
  libglib2.0-0t64 \
  libstdc++6 \
  libc6 \
  zlib1g \
  libmount1 \
  libselinux1 \
  libffi8 \
  libatomic1 \
  libpcre2-8-0 \
  util-linux
```
## 3. Enable and start Bluetooth

Raspberry Pi OS uses systemd.
```bash
sudo systemctl enable bluetooth
sudo systemctl start bluetooth
sudo systemctl status bluetooth --no-pager
```
Then unblock the radio:
```bash
sudo rfkill unblock bluetooth
rfkill list
```
You want Bluetooth to show:
```bash
Soft blocked: no
Hard blocked: no
```
## 4. Verify BlueZ sees the adapter
```bash 
bluetoothctl list
bluetoothctl show
```
A quick noninteractive check:

```bash
bluetoothctl show | egrep 'Controller|Powered|Discoverable|Discovering'
```
If Powered: no, run:

```bash
bluetoothctl power on
```
The bluetoothctl tool works with both classic Bluetooth and BLE controllers, and is the standard CLI check for BlueZ state.
## 5. Copy the binary

For Pi-to-Pi exchange, prefer the dual-role binaries. The filename should identify the platform, role mode, and poem compiled into the executable:

```text
microreticulum_306_rpi_arm64_dual_little_boy_blue
microreticulum_306_rpi_arm64_dual_children
```

Dual binaries default to `--ble-dual-policy=first-path-wins`: both BlueZ roles start, but the first working peer path stops the opposite role. Normal runs leave frame tracing off. To reproduce the verbose diagnostic trace, add `--ble-frame-log`. To reproduce the older experimental dual-path behavior, run with `--ble-dual-policy=both`.

Example scp command to a new server named "trixie1":
```bash
scp microreticulum_306_rpi_arm64_dual_children trixie1:~
```
## 6. Verify shared libraries before first run
```bash
ldd ./microreticulum_306_rpi_arm64_dual_children | tee ldd_$(date +%Y%m%d_%H%M).txt
```
Example:
```bash
jlpoole@trixie1:~ $ ldd ./microreticulum_306_rpi_arm64_dual_children | tee ldd_$(date +%Y%m%d_%H%M).txt
        linux-vdso.so.1 (0x0000007f9cb5c000)
        libgio-2.0.so.0 => /lib/aarch64-linux-gnu/libgio-2.0.so.0 (0x0000007f9c830000)
        libgobject-2.0.so.0 => /lib/aarch64-linux-gnu/libgobject-2.0.so.0 (0x0000007f9c7a0000)
        libglib-2.0.so.0 => /lib/aarch64-linux-gnu/libglib-2.0.so.0 (0x0000007f9c610000)
        libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f9c3a0000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f9c2f0000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f9c2b0000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f9c0f0000)
        libgmodule-2.0.so.0 => /lib/aarch64-linux-gnu/libgmodule-2.0.so.0 (0x0000007f9c0c0000)
        libz.so.1 => /lib/aarch64-linux-gnu/libz.so.1 (0x0000007f9c080000)
        libmount.so.1 => /lib/aarch64-linux-gnu/libmount.so.1 (0x0000007f9bfe0000)
        libselinux.so.1 => /lib/aarch64-linux-gnu/libselinux.so.1 (0x0000007f9bf80000)
        /lib/ld-linux-aarch64.so.1 (0x0000007f9cb20000)
        libffi.so.8 => /lib/aarch64-linux-gnu/libffi.so.8 (0x0000007f9bf50000)
        libatomic.so.1 => /lib/aarch64-linux-gnu/libatomic.so.1 (0x0000007f9bf20000)
        libpcre2-8.so.0 => /lib/aarch64-linux-gnu/libpcre2-8.so.0 (0x0000007f9be60000)
        libblkid.so.1 => /lib/aarch64-linux-gnu/libblkid.so.1 (0x0000007f9bde0000)
jlpoole@trixie1:~ $ 
```
The pass/fail test is simple:

    ldd ./microreticulum_306_rpi_arm64_dual_children | grep 'not found'

No output is good.

Also document:

    file ./microreticulum_306_rpi_arm64_dual_children

Expected:

    ELF 64-bit LSB pie executable, ARM aarch64, dynamically linked ... stripped

## 7. Run a smoke test

First run in foreground:



Expected healthy startup:

```bash
jlpoole@trixie1:~ $ ./microreticulum_306_rpi_arm64_dual_children
Exercise 306 native BLE file transfer console
Node=Node-PIZERO2-DUAL
BLE dual policy=first-path-wins
BLE frame log=off
Selected file=children.txt bytes=1422 chunk=32 interval_ms=500 repeat_rest_ms=10000
[ustore] Initializing PosixFileSystem
[ustore] WARNING: FlashFSFileSystem check failed, reformatting!
BLE linux-central: adapter=/org/bluez/hci0 label=Node-PIZERO2-DUAL
BLE linux-central: scanning for Reticulum service
BLE linux-peripheral: adapter=/org/bluez/hci0 label=Node-PIZERO2-DUAL service=37145b00-442d-4a94-917f-8f42c5da28e3
BLE linux-peripheral: advertising Reticulum service; waiting for central
Local SINGLE destination: dcf5338564d2cf21bfa86f1f2a9a89a3
microReticulum ready; OLED skipped on host native build
BLE linux-dual waiting for peer
BLE linux-dual waiting for peer

```

When one role wins, expect a line like:

```text
BLE dual policy first-path-wins: peripheral path won peer=:1.42; stopping central role
```

or:

```text
BLE dual policy first-path-wins: central path won peer=/org/bluez/hci0/dev_D8_3A_DD_1D_CF_B5; stopping peripheral role
```

With `--ble-frame-log`, the native BLE interfaces emit `BLE-FRAME` lines for Reticulum frame tracing. Those lines include timestamp, node label, BLE role, peer path/address, BlueZ object path, interface pointer, packet length, and the first packet byte.
When you have a second unit running, your console will show something like:
```bash
[Startup stuff]
...
BLE linux-dual waiting for peer
BLE linux-dual waiting for peer
BLE linux-central: peer candidate path=/org/bluez/hci0/dev_B8_27_EB_82_B2_4C name=RNS-Node-PIZERO1-DUAL
BLE linux-central: connected to /org/bluez/hci0/dev_B8_27_EB_82_B2_4C
BLE linux-central: notifications active; identity handshake sent
2026-05-22 18:24:37 [ERR] Failed to add destination 5aec1dc0939292aa8113cb8661bf06c3 to path table!
RX ANNOUNCE: label=Node-PIZERO1-DUAL hash=5aec1dc0939292aa8113cb8661bf06c3
TX ANNOUNCE: Node-PIZERO2-DUAL
LINK ACTIVE: inbound peer=Node-PIZERO1-DUAL link_id=7993e8fb37845c2f9d1e54ad3d5e2457

RX FILE BEGIN: from=Node-PIZERO1-DUAL file=little_boy_blue.txt bytes=942 chunks=30 crc=8FFFB95D
TX FILE BEGIN: round=1 file=children.txt bytes=1422 chunks=45 crc=C9E80D8B
The little toy dog is covered with dust,
   But sturdy and staunch he stands;
 And the little toy soldier is red with rust,
   And his musket molds in his hands.
Time was when the little toy dog was new,
   And the soldier was passing fair;
And that was the time when our Little Boy Blue
   Kissed them and put them there.

...
What has become of our Little Boy Blue,
   Since he kissed them and put them there. 
RX FILE END: from=Node-PIZERO1-DUAL file=little_boy_blue.txt received=942/942 chunks=30/30 crc=8FFFB95D status=OK
TX FILE END: round=1 file=children.txt bytes=1422 chunks=45 crc=C9E80D8B next_round_in_ms=10000

RX FILE BEGIN: from=Node-PIZERO1-DUAL file=little_boy_blue.txt bytes=942 chunks=30 crc=8FFFB95D
The little toy dog is covered with dust,
   But sturdy and staunch he stands;
 And the little toy soldier is red with rust,
   And his musket molds in his hands.
Time was when the little toy dog was new,
   And the soldier w^CBLE linux-central: disconnected; local stop

Stopped
jlpoole@trixie1:~ $ # 

```

The [ustore] WARNING: FlashFSFileSystem check failed, reformatting! line is not necessarily fatal in the native build, but the program must be run from a writable directory, because it appears to initialize local storage.

## 9. Permission troubleshooting

If the program cannot talk to BlueZ over D-Bus or cannot power/scan the adapter, test once with sudo:

```bash
sudo ./microreticulum_306_rpi_arm64_dual_children
```

If sudo works but the normal user fails, document that this is a BlueZ/D-Bus permission issue, not a missing-library issue. The clean fix may be a D-Bus policy rule for your program’s BlueZ access, but for the first howto I would keep the instruction conservative:

```bash
sudo usermod -aG bluetooth,netdev "$USER"
newgrp bluetooth
```

Then log out and back in.

## 10. Common failure checks
### Is the adapter present?
    hciconfig -a 2>/dev/null || bluetoothctl list

### Is Bluetooth blocked?
    rfkill list

### Is the daemon running?
    systemctl status bluetooth --no-pager

### Does BlueZ respond?
    bluetoothctl show

### Are libraries missing?
    ldd ./microreticulum_306_rpi_arm64_dual_children | grep 'not found'

### Is the binary executable?
    ls -l ./microreticulum_306_rpi_arm64_dual_children


*Note:* on an initial run, the binary will create a local Reticulum credential file `transport_identity` in the directory where you run the binary from.
Example:

```bash
jlpoole@trixie1:~ $ ls -la transport_identity 
-rw-r--r-- 1 jlpoole jlpoole 64 May 22 18:21 transport_identity
jlpoole@trixie1:~ $ 
```
