719 lines
16 KiB
Plaintext
719 lines
16 KiB
Plaintext
// Moved from docs/src/platform-integration/RASPBERRY_PI_BUILD.adoc to docs/working/scratch/src/platform-integration/RASPBERRY_PI_BUILD.adoc on 2026-06-16 (docs reorg Phase 2)
|
||
== StarForth on Raspberry Pi 4 - Build Guide
|
||
:toc: left
|
||
:toc-title: Contents
|
||
:toclevels: 3
|
||
xref:../README.adoc[← Back to Documentation Index]
|
||
|
||
|
||
|
||
=== Overview
|
||
|
||
This guide covers building and optimizing StarForth for Raspberry Pi 4
|
||
with ARM64 assembly optimizations.
|
||
|
||
=== Hardware Specifications
|
||
|
||
[cols=",",options="header",]
|
||
|===
|
||
|Component |Specification
|
||
|CPU |Broadcom BCM2711 (Quad-core Cortex-A72 @ 1.5GHz)
|
||
|Architecture |ARMv8-A (64-bit)
|
||
|L1 Cache |32KB I + 32KB D per core
|
||
|L2 Cache |1MB shared
|
||
|RAM |1GB/2GB/4GB/8GB LPDDR4-3200
|
||
|NEON |Yes (Advanced SIMD)
|
||
|CRC32 |Yes
|
||
|===
|
||
|
||
=== Quick Start
|
||
|
||
==== Option 1: Build Natively on Raspberry Pi
|
||
|
||
[source,bash]
|
||
----
|
||
# Install dependencies
|
||
sudo apt update
|
||
sudo apt install build-essential git
|
||
|
||
# Clone repository
|
||
git clone <your-repo-url> starforth
|
||
cd starforth
|
||
|
||
# Build with ARM64 optimizations
|
||
make clean
|
||
make CFLAGS="-std=c99 -O3 -march=armv8-a+crc+simd -mtune=cortex-a72 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -Iinclude -Isrc/word_source -Isrc/test_runner/include" LDFLAGS=""
|
||
|
||
# Test
|
||
./build/starforth
|
||
----
|
||
|
||
==== Option 2: Cross-Compile from x86_64 Linux
|
||
|
||
[source,bash]
|
||
----
|
||
# Install cross-compiler
|
||
sudo apt install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
|
||
|
||
# Build
|
||
make clean
|
||
make CC=aarch64-linux-gnu-gcc \
|
||
CFLAGS="-std=c99 -O3 -march=armv8-a+crc+simd -mtune=cortex-a72 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -Iinclude -Isrc/word_source -Isrc/test_runner/include" \
|
||
LDFLAGS="-static"
|
||
|
||
# Copy to Raspberry Pi
|
||
scp build/starforth pi@raspberrypi.local:~/
|
||
----
|
||
|
||
=== Makefile Integration
|
||
|
||
Add ARM64-specific targets to your Makefile:
|
||
|
||
[source,makefile]
|
||
----
|
||
# Raspberry Pi 4 native build
|
||
rpi4:
|
||
$(MAKE) CFLAGS="$(BASE_CFLAGS) -O3 -march=armv8-a+crc+simd -mtune=cortex-a72 -DUSE_ASM_OPT=1 -DARCH_ARM64=1" LDFLAGS=""
|
||
|
||
# Cross-compile for Raspberry Pi 4
|
||
rpi4-cross:
|
||
$(MAKE) CC=aarch64-linux-gnu-gcc \
|
||
CFLAGS="$(BASE_CFLAGS) -O3 -march=armv8-a+crc+simd -mtune=cortex-a72 -DUSE_ASM_OPT=1 -DARCH_ARM64=1 -static" \
|
||
LDFLAGS="-static"
|
||
|
||
# Performance build with direct threading
|
||
rpi4-perf:
|
||
$(MAKE) CFLAGS="$(BASE_CFLAGS) -O3 -march=armv8-a+crc+simd -mtune=cortex-a72 -DUSE_ASM_OPT=1 -DUSE_DIRECT_THREADING=1 -DARCH_ARM64=1 -flto" LDFLAGS="-flto"
|
||
----
|
||
|
||
=== Code Integration
|
||
|
||
==== 1. Architecture Detection Header
|
||
|
||
Create `+include/arch_detect.h+`:
|
||
|
||
[source,c]
|
||
----
|
||
#ifndef ARCH_DETECT_H
|
||
#define ARCH_DETECT_H
|
||
|
||
/* Detect architecture at compile time */
|
||
#if defined(__x86_64__) || defined(_M_X64)
|
||
#define ARCH_X86_64 1
|
||
#define ARCH_ARM64 0
|
||
#include "vm_asm_opt.h"
|
||
#include "vm_inner_interp_asm.h"
|
||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||
#define ARCH_X86_64 0
|
||
#define ARCH_ARM64 1
|
||
#include "vm_asm_opt_arm64.h"
|
||
#include "vm_inner_interp_arm64.h"
|
||
#else
|
||
#define ARCH_X86_64 0
|
||
#define ARCH_ARM64 0
|
||
#warning "Unknown architecture, assembly optimizations disabled"
|
||
#endif
|
||
|
||
/* Architecture-agnostic wrapper macros */
|
||
#if ARCH_X86_64
|
||
#define vm_push_opt(vm, val) vm_push_asm(vm, val)
|
||
#define vm_pop_opt(vm) vm_pop_asm(vm)
|
||
#define NEXT_OPT() NEXT_ASM()
|
||
#define PRIM_DUP_OPT() PRIM_DUP()
|
||
#define PRIM_DROP_OPT() PRIM_DROP()
|
||
#define PRIM_SWAP_OPT() PRIM_SWAP()
|
||
#define PRIM_PLUS_OPT() PRIM_PLUS()
|
||
/* ... other primitives ... */
|
||
#elif ARCH_ARM64
|
||
#define vm_push_opt(vm, val) vm_push_asm(vm, val)
|
||
#define vm_pop_opt(vm) vm_pop_asm(vm)
|
||
#define NEXT_OPT() NEXT_ARM64()
|
||
#define PRIM_DUP_OPT() PRIM_DUP_ARM64()
|
||
#define PRIM_DROP_OPT() PRIM_DROP_ARM64()
|
||
#define PRIM_SWAP_OPT() PRIM_SWAP_ARM64()
|
||
#define PRIM_PLUS_OPT() PRIM_PLUS_ARM64()
|
||
/* ... other primitives ... */
|
||
#else
|
||
#define vm_push_opt(vm, val) vm_push(vm, val)
|
||
#define vm_pop_opt(vm) vm_pop(vm)
|
||
#define NEXT_OPT() do {} while(0)
|
||
/* ... fallback to C implementations ... */
|
||
#endif
|
||
|
||
#endif /* ARCH_DETECT_H */
|
||
----
|
||
|
||
==== 2. Update Stack Management
|
||
|
||
In `+src/stack_management.c+`:
|
||
|
||
[source,c]
|
||
----
|
||
#include "../include/vm.h"
|
||
#include "../include/arch_detect.h"
|
||
#include "../include/log.h"
|
||
#include "../include/profiler.h"
|
||
|
||
void vm_push(VM *vm, cell_t value) {
|
||
PROFILE_INC_STACK_OP();
|
||
|
||
#if USE_ASM_OPT
|
||
vm_push_opt(vm, value);
|
||
if (vm->error) {
|
||
log_message(LOG_ERROR, "Stack overflow");
|
||
}
|
||
#else
|
||
if (vm->dsp >= STACK_SIZE - 1) {
|
||
log_message(LOG_ERROR, "Stack overflow");
|
||
vm->error = 1;
|
||
return;
|
||
}
|
||
vm->data_stack[++vm->dsp] = value;
|
||
log_message(LOG_DEBUG, "PUSH: %ld (dsp=%d)", (long)value, vm->dsp);
|
||
#endif
|
||
}
|
||
|
||
cell_t vm_pop(VM *vm) {
|
||
PROFILE_INC_STACK_OP();
|
||
|
||
#if USE_ASM_OPT
|
||
cell_t value = vm_pop_opt(vm);
|
||
if (vm->error) {
|
||
log_message(LOG_ERROR, "Stack underflow");
|
||
}
|
||
return value;
|
||
#else
|
||
if (vm->dsp < 0) {
|
||
log_message(LOG_ERROR, "Stack underflow (dsp=%d)", vm->dsp);
|
||
vm->error = 1;
|
||
return 0;
|
||
}
|
||
cell_t value = vm->data_stack[vm->dsp--];
|
||
log_message(LOG_DEBUG, "POP: %ld (dsp=%d)", (long)value, vm->dsp);
|
||
return value;
|
||
#endif
|
||
}
|
||
----
|
||
|
||
==== 3. Update Arithmetic Words
|
||
|
||
In `+src/word_source/arithmetic_words.c+`:
|
||
|
||
[source,c]
|
||
----
|
||
#include "../../include/arch_detect.h"
|
||
|
||
void arithmetic_word_plus(VM *vm) {
|
||
if (vm->dsp < 1) {
|
||
log_message(LOG_ERROR, "+: Stack underflow");
|
||
vm->error = 1;
|
||
return;
|
||
}
|
||
|
||
#if USE_ASM_OPT
|
||
cell_t n2 = vm_pop_opt(vm);
|
||
cell_t n1 = vm_pop_opt(vm);
|
||
cell_t result;
|
||
|
||
if (vm_add_check_overflow(n1, n2, &result)) {
|
||
log_message(LOG_ERROR, "+: Overflow");
|
||
vm->error = 1;
|
||
return;
|
||
}
|
||
|
||
vm_push_opt(vm, result);
|
||
#else
|
||
cell_t n2 = vm_pop(vm);
|
||
cell_t n1 = vm_pop(vm);
|
||
vm_push(vm, n1 + n2);
|
||
#endif
|
||
log_message(LOG_DEBUG, "+: %ld + %ld = %ld", (long)n1, (long)n2, (long)result);
|
||
}
|
||
|
||
void arithmetic_word_star_slash_mod(VM *vm) {
|
||
// n1 n2 n3 -- rem quot (n1*n2/n3, remainder and quotient)
|
||
if (vm->dsp < 2) {
|
||
vm->error = 1;
|
||
return;
|
||
}
|
||
|
||
#if USE_ASM_OPT
|
||
cell_t n3 = vm_pop_opt(vm);
|
||
cell_t n2 = vm_pop_opt(vm);
|
||
cell_t n1 = vm_pop_opt(vm);
|
||
|
||
if (n3 == 0) {
|
||
vm->error = 1;
|
||
return;
|
||
}
|
||
|
||
// Use double-width multiplication
|
||
cell_t hi, lo;
|
||
vm_mul_double(n1, n2, &hi, &lo);
|
||
|
||
// Divide by n3 (simplified - assumes result fits in 64 bits)
|
||
cell_t quot, rem;
|
||
vm_divmod(lo, n3, ", &rem);
|
||
|
||
vm_push_opt(vm, rem);
|
||
vm_push_opt(vm, quot);
|
||
#else
|
||
cell_t n3 = vm_pop(vm);
|
||
cell_t n2 = vm_pop(vm);
|
||
cell_t n1 = vm_pop(vm);
|
||
// ... C implementation ...
|
||
#endif
|
||
}
|
||
----
|
||
|
||
=== Performance Optimization
|
||
|
||
==== 1. Cache Line Alignment
|
||
|
||
Align VM structure to cache line (64 bytes on Cortex-A72):
|
||
|
||
[source,c]
|
||
----
|
||
typedef struct VM {
|
||
/* Hot data - frequently accessed */
|
||
cell_t data_stack[STACK_SIZE];
|
||
cell_t return_stack[STACK_SIZE];
|
||
int dsp;
|
||
int rsp;
|
||
|
||
/* Align to cache line */
|
||
char _padding[64 - ((sizeof(cell_t) * STACK_SIZE * 2 + sizeof(int) * 2) % 64)];
|
||
|
||
/* Cold data - infrequently accessed */
|
||
int error;
|
||
int halted;
|
||
// ...
|
||
} __attribute__((aligned(64))) VM;
|
||
----
|
||
|
||
==== 2. Prefetching
|
||
|
||
Add prefetch hints in hot loops:
|
||
|
||
[source,c]
|
||
----
|
||
#if ARCH_ARM64
|
||
#include "vm_asm_opt_arm64.h"
|
||
|
||
DictEntry *vm_find_word(VM *vm, const char *name, size_t len) {
|
||
DictEntry *entry = vm->latest;
|
||
|
||
while (entry) {
|
||
// Prefetch next entry while processing current
|
||
if (entry->link) {
|
||
vm_prefetch(entry->link);
|
||
}
|
||
|
||
if (entry->name_len == len) {
|
||
if (vm_strcmp_asm(entry->name, name, len) == 0) {
|
||
return entry;
|
||
}
|
||
}
|
||
entry = entry->link;
|
||
}
|
||
return NULL;
|
||
}
|
||
#endif
|
||
----
|
||
|
||
==== 3. NEON Optimizations
|
||
|
||
For block copy operations:
|
||
|
||
[source,c]
|
||
----
|
||
#if ARCH_ARM64 && defined(__ARM_NEON)
|
||
#include <arm_neon.h>
|
||
|
||
void vm_block_copy_neon(void *dest, const void *src, size_t len) {
|
||
// Copy 64 bytes at a time using NEON
|
||
while (len >= 64) {
|
||
uint8x16_t v0 = vld1q_u8((const uint8_t*)src);
|
||
uint8x16_t v1 = vld1q_u8((const uint8_t*)src + 16);
|
||
uint8x16_t v2 = vld1q_u8((const uint8_t*)src + 32);
|
||
uint8x16_t v3 = vld1q_u8((const uint8_t*)src + 48);
|
||
|
||
vst1q_u8((uint8_t*)dest, v0);
|
||
vst1q_u8((uint8_t*)dest + 16, v1);
|
||
vst1q_u8((uint8_t*)dest + 32, v2);
|
||
vst1q_u8((uint8_t*)dest + 48, v3);
|
||
|
||
src += 64;
|
||
dest += 64;
|
||
len -= 64;
|
||
}
|
||
|
||
// Handle remainder
|
||
vm_memcpy_asm(dest, src, len);
|
||
}
|
||
#endif
|
||
----
|
||
|
||
=== Benchmarking
|
||
|
||
==== 1. CPU Frequency Scaling
|
||
|
||
[source,bash]
|
||
----
|
||
# Check current frequency
|
||
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
|
||
|
||
# Set to performance mode
|
||
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||
|
||
# Or set fixed frequency
|
||
echo 1500000 | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq
|
||
----
|
||
|
||
==== 2. Temperature Monitoring
|
||
|
||
[source,bash]
|
||
----
|
||
# Monitor temperature while benchmarking
|
||
watch -n 1 vcgencmd measure_temp
|
||
|
||
# Check throttling
|
||
vcgencmd get_throttled
|
||
# 0x0 = no throttling
|
||
# Other values indicate thermal throttling occurred
|
||
----
|
||
|
||
==== 3. Benchmark Script
|
||
|
||
Create `+benchmarks/rpi4_bench.sh+`:
|
||
|
||
[source,bash]
|
||
----
|
||
#!/bin/bash
|
||
|
||
echo "StarForth Raspberry Pi 4 Benchmark"
|
||
echo "==================================="
|
||
echo ""
|
||
|
||
# System info
|
||
echo "CPU: $(cat /proc/cpuinfo | grep 'Model' | head -1)"
|
||
echo "Frequency: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq) kHz"
|
||
echo "Temperature: $(vcgencmd measure_temp)"
|
||
echo ""
|
||
|
||
# Set performance mode
|
||
echo "Setting CPU to performance mode..."
|
||
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null
|
||
|
||
# Build baseline
|
||
echo "Building baseline (no optimizations)..."
|
||
make clean > /dev/null 2>&1
|
||
make CFLAGS="-std=c99 -O2 -Iinclude -Isrc/word_source -Isrc/test_runner/include" LDFLAGS="" > /dev/null 2>&1
|
||
cp build/starforth build/starforth_baseline
|
||
|
||
# Build optimized
|
||
echo "Building optimized (ARM64 ASM)..."
|
||
make clean > /dev/null 2>&1
|
||
make rpi4-perf > /dev/null 2>&1
|
||
cp build/starforth build/starforth_opt
|
||
|
||
# Create benchmark
|
||
cat > /tmp/bench.fth <<'EOF'
|
||
: BENCH-STACK 1000000 0 DO 1 2 3 DROP DROP DROP LOOP ;
|
||
: BENCH-MATH 1000000 0 DO 10 20 + 5 * 100 / DROP LOOP ;
|
||
: BENCH-LOGIC 1000000 0 DO 255 DUP AND DUP OR XOR DROP LOOP ;
|
||
|
||
." Running benchmarks..." CR
|
||
." Stack operations: " BENCH-STACK ." Done" CR
|
||
." Math operations: " BENCH-MATH ." Done" CR
|
||
." Logic operations: " BENCH-LOGIC ." Done" CR
|
||
BYE
|
||
EOF
|
||
|
||
# Run benchmarks
|
||
echo ""
|
||
echo "Baseline performance:"
|
||
time build/starforth_baseline /tmp/bench.fth 2>&1 | grep -v "^$"
|
||
|
||
echo ""
|
||
echo "Optimized performance:"
|
||
time build/starforth_opt /tmp/bench.fth 2>&1 | grep -v "^$"
|
||
|
||
echo ""
|
||
echo "Final temperature: $(vcgencmd measure_temp)"
|
||
echo "Throttling status: $(vcgencmd get_throttled)"
|
||
----
|
||
|
||
Run it:
|
||
|
||
[source,bash]
|
||
----
|
||
chmod +x benchmarks/rpi4_bench.sh
|
||
./benchmarks/rpi4_bench.sh
|
||
----
|
||
|
||
==== 4. Detailed Profiling with perf
|
||
|
||
[source,bash]
|
||
----
|
||
# Install perf (if not already installed)
|
||
sudo apt install linux-perf
|
||
|
||
# Profile with perf
|
||
sudo perf record -g ./build/starforth benchmarks/test.fth
|
||
sudo perf report
|
||
|
||
# Cache analysis
|
||
sudo perf stat -e cache-references,cache-misses,instructions,cycles ./build/starforth benchmarks/test.fth
|
||
|
||
# Branch prediction
|
||
sudo perf stat -e branches,branch-misses ./build/starforth benchmarks/test.fth
|
||
----
|
||
|
||
=== Thermal Management
|
||
|
||
==== 1. Passive Cooling
|
||
|
||
Recommended heatsink specs:
|
||
|
||
* Material: Aluminum or copper
|
||
* Size: Covers entire CPU
|
||
* Thermal pad: 1mm thick
|
||
|
||
==== 2. Active Cooling
|
||
|
||
Fan recommendations:
|
||
|
||
* Size: 30mm x 30mm x 7mm
|
||
* Voltage: 5V
|
||
* CFM: 3-5 CFM
|
||
* Connector: 2-pin JST or GPIO
|
||
|
||
GPIO fan control:
|
||
|
||
[source,bash]
|
||
----
|
||
# Install fan control
|
||
sudo apt install fancontrol
|
||
|
||
# Auto-configure
|
||
sudo pwmconfig
|
||
|
||
# Or manual control
|
||
echo 255 > /sys/class/hwmon/hwmon0/pwm1 # Full speed
|
||
echo 128 > /sys/class/hwmon/hwmon0/pwm1 # Half speed
|
||
----
|
||
|
||
==== 3. Overclocking (Optional)
|
||
|
||
⚠️ *Warning*: Requires adequate cooling and may void warranty
|
||
|
||
Add to `+/boot/config.txt+`:
|
||
|
||
....
|
||
# Raspberry Pi 4 overclock
|
||
over_voltage=6
|
||
arm_freq=2000
|
||
gpu_freq=750
|
||
|
||
# Additional cooling required!
|
||
....
|
||
|
||
Reboot and verify:
|
||
|
||
[source,bash]
|
||
----
|
||
sudo reboot
|
||
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
|
||
----
|
||
|
||
=== Power Consumption
|
||
|
||
Typical power usage:
|
||
|
||
* Idle: 2-3W
|
||
* Light load: 4-5W
|
||
* Full load (all cores): 7-8W
|
||
* With peripherals: +2-3W
|
||
|
||
Recommendations:
|
||
|
||
* Use official 5V/3A power supply
|
||
* For battery operation, use 5V/3A+ battery bank
|
||
* Add power meter for monitoring
|
||
|
||
=== SD Card Performance
|
||
|
||
Recommended SD cards:
|
||
|
||
* Class: UHS-I or UHS-II
|
||
* Speed: A2 or higher (Application Performance Class 2)
|
||
* Size: 16GB minimum, 32GB+ recommended
|
||
|
||
Brands with good random I/O:
|
||
|
||
* Samsung EVO Plus
|
||
* SanDisk Extreme
|
||
* Kingston Canvas React
|
||
|
||
Test SD card speed:
|
||
|
||
[source,bash]
|
||
----
|
||
# Write test
|
||
sudo dd if=/dev/zero of=/tmp/test bs=1M count=1024 conv=fdatasync
|
||
|
||
# Read test
|
||
sudo dd if=/tmp/test of=/dev/null bs=1M count=1024
|
||
----
|
||
|
||
=== Troubleshooting
|
||
|
||
==== Build Errors
|
||
|
||
*Problem*: `+Illegal instruction+` when running
|
||
|
||
[source,bash]
|
||
----
|
||
# Check CPU features
|
||
cat /proc/cpuinfo | grep Features
|
||
|
||
# Rebuild with more conservative flags
|
||
make rpi4 CFLAGS="$(BASE_CFLAGS) -O2 -march=armv8-a -DUSE_ASM_OPT=1"
|
||
----
|
||
|
||
*Problem*: Cross-compiled binary doesn’t run
|
||
|
||
[source,bash]
|
||
----
|
||
# Check if binary is static
|
||
file build/starforth
|
||
# Should show "statically linked"
|
||
|
||
# If dynamic, rebuild with -static
|
||
make rpi4-cross LDFLAGS="-static"
|
||
----
|
||
|
||
==== Performance Issues
|
||
|
||
*Problem*: Slower than expected
|
||
|
||
[source,bash]
|
||
----
|
||
# Check CPU governor
|
||
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
|
||
# Should be "performance", not "ondemand"
|
||
|
||
# Check for thermal throttling
|
||
vcgencmd get_throttled
|
||
# 0x0 = no throttling
|
||
|
||
# Monitor while running
|
||
watch -n 1 'vcgencmd measure_clock arm; vcgencmd measure_temp'
|
||
----
|
||
|
||
==== Memory Issues
|
||
|
||
*Problem*: Out of memory
|
||
|
||
[source,bash]
|
||
----
|
||
# Check available memory
|
||
free -h
|
||
|
||
# Reduce VM memory size in vm.h
|
||
#define VM_MEMORY_SIZE (2 * 1024 * 1024) // 2MB instead of 5MB
|
||
|
||
# Or increase swap
|
||
sudo dphys-swapfile swapoff
|
||
sudo nano /etc/dphys-swapfile
|
||
# CONF_SWAPSIZE=2048
|
||
sudo dphys-swapfile setup
|
||
sudo dphys-swapfile swapon
|
||
----
|
||
|
||
=== Production Deployment
|
||
|
||
==== 1. Systemd Service
|
||
|
||
Create `+/etc/systemd/system/starforth.service+`:
|
||
|
||
[source,ini]
|
||
----
|
||
[Unit]
|
||
Description=StarForth VM
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=pi
|
||
WorkingDirectory=/home/pi/starforth
|
||
ExecStart=/home/pi/starforth/build/starforth
|
||
Restart=on-failure
|
||
RestartSec=5s
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
----
|
||
|
||
Enable and start:
|
||
|
||
[source,bash]
|
||
----
|
||
sudo systemctl enable starforth
|
||
sudo systemctl start starforth
|
||
sudo systemctl status starforth
|
||
----
|
||
|
||
==== 2. Boot Optimization
|
||
|
||
Reduce boot time in `+/boot/config.txt+`:
|
||
|
||
....
|
||
# Disable unused features
|
||
dtparam=audio=off
|
||
camera_auto_detect=0
|
||
display_auto_detect=0
|
||
|
||
# Faster boot
|
||
boot_delay=0
|
||
disable_splash=1
|
||
....
|
||
|
||
==== 3. Security Hardening
|
||
|
||
[source,bash]
|
||
----
|
||
# Update system
|
||
sudo apt update && sudo apt upgrade -y
|
||
|
||
# Remove unnecessary packages
|
||
sudo apt autoremove -y
|
||
|
||
# Configure firewall
|
||
sudo apt install ufw
|
||
sudo ufw default deny incoming
|
||
sudo ufw default allow outgoing
|
||
sudo ufw allow ssh
|
||
sudo ufw enable
|
||
|
||
# Disable password auth (use keys)
|
||
sudo nano /etc/ssh/sshd_config
|
||
# PasswordAuthentication no
|
||
sudo systemctl restart sshd
|
||
----
|
||
|
||
=== Further Reading
|
||
|
||
* https://developer.arm.com/documentation/100095/latest[ARM Cortex-A72
|
||
Technical Reference Manual]
|
||
* https://developer.arm.com/architectures/instruction-sets/simd-isas/neon[ARM
|
||
NEON Programmer’s Guide]
|
||
* https://www.raspberrypi.org/documentation/[Raspberry Pi Documentation]
|
||
* https://developer.arm.com/documentation/ddi0487/latest[ARMv8-A
|
||
Architecture Reference Manual]
|
||
|
||
=== License
|
||
|
||
Public domain / CC0. No warranty. Use at your own risk.
|