ADIN1110-Linux-Kernel-Modul auf dem Raspberry Pi bauen

ADIN1110-Linux-Kernel-Modul auf dem Raspberry Pi bauen
Dieser Artikel zeigt, wie der Linux-Treiber für den ADIN1110 10BASE-T1L Ethernet MAC-PHY als externes Kernel-Modul auf einem Raspberry Pi gebaut wird.
Das Ziel ist einfach:
- Raspberry Pi OS 64-Bit verwenden
- Den aktuell laufenden Raspberry-Pi-Kernel verwenden
- Den passenden ADIN1110-Treiberquelltext herunterladen
adin1110.kobauen- Das Modul unter
/lib/modulesinstallieren - Das Modul mit
modprobeladen
Dies ist hilfreich, wenn der Treiber im installierten Raspberry-Pi-Kernel nicht als einsatzbereites Modul verfügbar ist.
1. Warum nur das Modul bauen?
Viele Anleitungen beschreiben, wie der vollständige Raspberry-Pi-Kernel neu gebaut wird.
Das ist zum Lernen hilfreich, für die Inbetriebnahme jedoch nicht immer praktikabel.
Für viele Anwendungsfälle ist es sinnvoller, nur das benötigte Kernel-Modul zu bauen:
Manuelle Einrichtung zum Verstehen.
Installer-basierte Einrichtung für den Einsatz.
Dieser Ansatz vermeidet einen vollständigen Kernel-Neubau und hält das System nahe am installierten Raspberry-Pi-OS-Kernel.
2. Hintergrund
Der ADIN1110 ist ein 10BASE-T1L-Ethernet-MAC-PHY von Analog Devices.
Unter Linux befindet sich der ADIN1110-Treiber im Kernel-Quellbaum unter:
drivers/net/ethernet/adi/adin1110.c
Statt den vollständigen Raspberry-Pi-Kernel neu zu bauen, kann der Treiber als externes Kernel-Modul kompiliert werden.
Dies ist hilfreich für:
- Entwicklung
- Tests
- Installer-basierte Inbetriebnahme
- Raspberry-Pi-basierte Industrial-Ethernet-Gateways
3. Verwandte Arbeiten
Es gibt bereits einen guten Artikel, der die ADIN1110-Kernel-Konfiguration und die Overlay-Einrichtung für den Raspberry Pi erklärt:
https://www.hackster.io/pier8283/adin1110-linux-kernel-configuration-for-raspberry-pi-2f4a26
Dieser Artikel konzentriert sich auf die Konfiguration und den Neubau des Raspberry-Pi-Kernels.
Der vorliegende Artikel beschreibt einen anderen Ansatz:
Nur den ADIN1110-Treiber als externes Kernel-Modul bauen.
Dies ist hilfreich, wenn der Raspberry-Pi-Kernel selbst unverändert bleiben soll.
4. Voraussetzungen
Dieser Aufbau ist vorgesehen für:
Raspberry Pi OS 64-Bit
Raspberry Pi OS 64-Bit ist erforderlich, weil die benötigte Netzwerk-Kernel-Konfiguration dort bereits verfügbar ist.
Das Skript benötigt außerdem:
Linux-Kernel >= 6.12
Erforderliche Werkzeuge:
uname
wget
make
gcc
sudo
Das passende Kernel-Build-Verzeichnis muss vorhanden sein:
/lib/modules/$(uname -r)/build
Unter Raspberry Pi OS wird dieses normalerweise durch die installierten Kernel-Header bereitgestellt.
5. Benötigte Pakete installieren
Installieren Sie die benötigten Build-Werkzeuge:
sudo apt update
sudo apt install -y raspberrypi-kernel-headers build-essential wget
Prüfen Sie, ob das Kernel-Build-Verzeichnis vorhanden ist:
ls -l /lib/modules/$(uname -r)/build
Erwartetes Ergebnis:
/lib/modules/.../build -> /usr/src/...
6. Build-Skript
Erstellen Sie eine Datei:
mkdir -p scripts/adin1110
vim scripts/adin1110/build_adin1110_module.sh
Fügen Sie das folgende Skript ein:
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
die() {
echo "Fehler: $1" >&2
exit 1
}
say() {
step="$1"
msg="$2"
printf "%s: %s\n" "$step" "$msg"
}
require_command() {
cmd="$1"
command -v "$cmd" >/dev/null 2>&1 || die "Required command not found: $cmd"
}
STEP="STEP0"
say "$STEP" "Checking required tools"
require_command uname
require_command wget
require_command make
require_command gcc
require_command sudo
KVER="$(uname -r)"
KDIR="/lib/modules/$KVER/build"
say "$STEP" "Running kernel: $KVER"
say "$STEP" "Kernel build directory: $KDIR"
STEP="STEP1"
say "$STEP" "Checking kernel compatibility"
case "$KVER" in
6.1[2-9].*|6.[2-9]*)
;;
*)
die "Unsupported kernel version: $KVER (requires >= 6.12)"
;;
esac
[ -d "$KDIR" ] || die "Kernel build directory not found: $KDIR"
[ -f "$KDIR/include/generated/autoconf.h" ] || die "Missing autoconf.h in $KDIR"
[ -f "$KDIR/Makefile" ] || die "Missing kernel Makefile in $KDIR"
STEP="STEP2"
say "$STEP" "Preparing build directory"
BUILD_DIR="${REPO_ROOT}/build/adin1110"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
STEP="STEP3"
say "$STEP" "Downloading sources"
KMAJOR="$(echo "$KVER" | cut -d. -f1)"
KMINOR="$(echo "$KVER" | cut -d. -f2)"
KBRANCH="rpi-${KMAJOR}.${KMINOR}.y"
BASE_URL="https://raw.githubusercontent.com/raspberrypi/linux/${KBRANCH}/drivers/net/ethernet/adi"
say "$STEP" "Using Raspberry Pi kernel branch: $KBRANCH"
wget -nv -O "$BUILD_DIR/adin1110.c" "$BASE_URL/adin1110.c"
STEP="STEP4"
say "$STEP" "Creating Makefile"
printf 'obj-m := adin1110.o\n\nall:\n\t$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules\n\nclean:\n\t$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean\n' > "$BUILD_DIR/Makefile"
STEP="STEP5"
say "$STEP" "Building module"
make -C "$KDIR" M="$BUILD_DIR" modules
[ -f "$BUILD_DIR/adin1110.ko" ] || die "adin1110.ko was not created"
STEP="STEP6"
say "$STEP" "Installing module"
sudo install -D -m 644 "$BUILD_DIR/adin1110.ko" "/lib/modules/$KVER/updates/adin1110.ko"
sudo depmod "$KVER"
STEP="STEP7"
say "$STEP" "Done"
say "$STEP" "Try loading with:"
say "$STEP" "sudo modprobe adin1110"
Machen Sie das Skript ausführbar:
chmod +x scripts/adin1110/build_adin1110_module.sh
Führen Sie es aus:
./scripts/adin1110/build_adin1110_module.sh
7. Was das Skript macht
Das Skript führt folgende Schritte aus:
- Benötigte Build-Werkzeuge prüfen
- Laufende Kernel-Version ermitteln
- Kernel-Build-Verzeichnis prüfen
- Passenden ADIN1110-Treiberquelltext herunterladen
- Minimales Modul-Makefile erstellen
adin1110.kobauen- Modul installieren
depmodausführen
8. STEP0: Benötigte Werkzeuge prüfen
Das Skript prüft zunächst, ob die benötigten Kommandozeilenwerkzeuge verfügbar sind:
require_command uname
require_command wget
require_command make
require_command gcc
require_command sudo
Zusätzlich liest es die aktuell laufende Kernel-Version aus:
KVER="$(uname -r)"
KDIR="/lib/modules/$KVER/build"
Das Modul wird immer gegen den aktuell laufenden Kernel gebaut.
Das ist wichtig, weil Linux-Kernel-Module zu dem Kernel passen müssen, in den sie geladen werden.
9. STEP1: Kernel-Kompatibilität prüfen
Das Skript benötigt Linux-Kernel-Version 6.12 oder neuer:
case "$KVER" in
6.1[2-9].*|6.[2-9]*)
;;
*)
die "Unsupported kernel version: $KVER (requires >= 6.12)"
;;
esac
Außerdem prüft es, ob die Kernel-Build-Dateien vorhanden sind:
[ -d "$KDIR" ] || die "Kernel build directory not found: $KDIR"
[ -f "$KDIR/include/generated/autoconf.h" ] || die "Missing autoconf.h in $KDIR"
[ -f "$KDIR/Makefile" ] || die "Missing kernel Makefile in $KDIR"
Ohne diese Dateien können keine externen Kernel-Module gebaut werden.
10. STEP2: Build-Verzeichnis vorbereiten
Das Modul wird in folgendem Verzeichnis gebaut:
build/adin1110
Das Verzeichnis wird bei jedem Durchlauf gelöscht und neu angelegt:
BUILD_DIR="${REPO_ROOT}/build/adin1110"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
Dadurch werden Probleme mit alten Objektdateien aus früheren Builds vermieden.
11. STEP3: ADIN1110-Treiberquelltext herunterladen
Das Skript ermittelt Haupt- und Nebenversion des Kernels:
KMAJOR="$(echo "$KVER" | cut -d. -f1)"
KMINOR="$(echo "$KVER" | cut -d. -f2)"
KBRANCH="rpi-${KMAJOR}.${KMINOR}.y"
Zum Beispiel:
6.12.x -> rpi-6.12.y
6.13.x -> rpi-6.13.y
Anschließend lädt es den ADIN1110-Treiber aus dem passenden Raspberry-Pi-Kernel-Branch herunter:
BASE_URL="https://raw.githubusercontent.com/raspberrypi/linux/${KBRANCH}/drivers/net/ethernet/adi"
wget -nv -O "$BUILD_DIR/adin1110.c" "$BASE_URL/adin1110.c"
Dadurch bleibt der Treiberquelltext nahe an der Version des laufenden Raspberry-Pi-Kernels.
12. STEP4: Modul-Makefile erstellen
Das Skript erstellt ein minimales Makefile für ein externes Kernel-Modul:
obj-m := adin1110.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Damit wird das Kernel-Build-System angewiesen, folgende Datei zu bauen:
adin1110.ko
aus:
adin1110.c
13. STEP5: Kernel-Modul bauen
Das Modul wird mit folgendem Befehl gebaut:
make -C "$KDIR" M="$BUILD_DIR" modules
Das bedeutet:
-C "$KDIR"
Das Build-Verzeichnis des laufenden Kernels verwenden.
M="$BUILD_DIR"
Das externe Modul aus dem ADIN1110-Build-Verzeichnis bauen.
Nach dem Build prüft das Skript, ob das Modul vorhanden ist:
[ -f "$BUILD_DIR/adin1110.ko" ] || die "adin1110.ko was not created"
Die erwartete Ausgabedatei ist:
build/adin1110/adin1110.ko
14. STEP6: Modul installieren
Das Modul wird installiert unter:
/lib/modules/$(uname -r)/updates/adin1110.ko
Das Skript verwendet:
sudo install -D -m 644 "$BUILD_DIR/adin1110.ko" "/lib/modules/$KVER/updates/adin1110.ko"
sudo depmod "$KVER"
depmod aktualisiert die Abhängigkeitsdatenbank der Kernel-Module.
Nach diesem Schritt kann das Modul über seinen Namen geladen werden.
15. STEP7: Modul laden
Laden Sie das Modul mit:
sudo modprobe adin1110
Prüfen Sie, ob es geladen wurde:
lsmod | grep adin1110
Prüfen Sie die Kernel-Meldungen:
dmesg | tail -n 100
16. Device-Tree-Overlay
Das Kernel-Modul allein reicht nicht aus.
Der Raspberry Pi benötigt außerdem ein passendes Device-Tree-Overlay, das das ADIN1110-SPI-Gerät beschreibt.
Typische Angaben, die im Overlay benötigt werden:
- SPI-Bus
- Chip-Select
- Interrupt-GPIO
- Reset-GPIO, sofern verwendet
- Compatible-String für den ADIN1110
- SPI-Frequenz
- MAC-Adresse
Die MAC-Adresse muss im Device Tree angegeben werden.
Ist keine gültige MAC-Adresse konfiguriert, kann die Initialisierung des Treibers fehlschlagen oder es können Fehler in dmesg erscheinen.
Beispielstruktur:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
status = "okay";
adin1110: ethernet@0 {
compatible = "adi,adin1110";
reg = <0>;
spi-max-frequency = <25000000>;
interrupt-parent = <&gpio>;
interrupts = <25 8>;
local-mac-address = [ 02 00 00 00 00 01 ];
status = "okay";
};
};
};
};
Die genauen GPIO-Nummern hängen vom Hardwaredesign ab.
Die oben angegebene MAC-Adresse ist nur ein Beispiel. Bei realen Produkten sollte jedes Gerät eine eindeutige und gültige MAC-Adresse verwenden.
Device-Tree-Overlays können auch direkt auf dem Raspberry-Pi-Zielsystem gebaut werden.
Bei Interesse kann ein eigener Artikel zum Bauen und Installieren von Raspberry-Pi-Device-Tree-Overlays direkt auf dem Zielsystem folgen.
17. Netzwerkschnittstelle testen
Nach dem Laden des Moduls und dem Aktivieren des Overlays wird das System neu gestartet:
sudo reboot
Prüfen Sie nach dem Neustart die Netzwerkschnittstellen:
ip link
Es sollte eine neue Ethernet-Schnittstelle erscheinen.
Beispiel:
eth1
oder:
end0
Aktivieren Sie die Schnittstelle:
sudo ip link set eth1 up
Prüfen Sie den Link-Status:
ip addr show eth1
dmesg | grep -i adin
18. Fehlersuche
Kernel-Header fehlen
Fehler:
Kernel build directory not found
Lösung:
sudo apt install -y raspberrypi-kernel-headers
Modul lässt sich nicht laden
Prüfen:
sudo modprobe adin1110
dmesg | tail -n 100
Mögliche Ursachen:
- Falsche Kernel-Version
- Modul wurde für einen anderen Kernel gebaut
- Fehlende Abhängigkeit
- Inkompatible Kernel-Quellversion
SPI-Gerät wird nicht erkannt
Prüfen Sie, ob SPI aktiviert ist:
ls /dev/spidev*
Aktivieren Sie SPI:
sudo raspi-config
Aktivieren Sie anschließend:
Interface Options -> SPI
Starten Sie das System danach neu.
Device-Tree-Overlay fehlt oder ist fehlerhaft
Wenn das Modul geladen wird, aber keine Netzwerkschnittstelle erscheint, fehlt normalerweise das Device-Tree-Overlay oder es ist fehlerhaft.
Prüfen:
dmesg | grep -i spi
dmesg | grep -i adin
MAC-Adresse fehlt
Der ADIN1110 benötigt eine gültige MAC-Adresse.
Wenn der Device Tree keine MAC-Adresse bereitstellt, kann der Treiber fehlschlagen oder Fehler melden.
Prüfen Sie die Kernel-Meldungen:
dmesg | grep -i mac
dmesg | grep -i adin
Korrigieren Sie das Device-Tree-Overlay und ergänzen Sie eine gültige local-mac-address.
19. Build bereinigen
So entfernen Sie das lokale Build-Verzeichnis:
rm -rf build/adin1110
So entfernen Sie das installierte Modul:
sudo rm -f /lib/modules/$(uname -r)/updates/adin1110.ko
sudo depmod "$(uname -r)"
20. Quelle des Build-Skripts
Das in diesem Artikel verwendete Build-Skript basiert auf dem offenen BE-IIS Installer-Projekt:
https://github.com/be-iis/be-iis-installer/
Der Installer übernimmt mehr als nur den Bau des ADIN1110-Moduls.
Er dient zur Einrichtung von BE-IIS HAT++ Boards auf Raspberry-Pi-Systemen und kann die erforderlichen Module, Overlays und Konfigurationsdateien für unterstützte HATs installieren.
Ziel ist, dass Anwender diese manuellen Schritte bei der normalen Inbetriebnahme nicht selbst durchführen müssen.
Der manuelle Ablauf in diesem Artikel dient hauptsächlich dazu, die internen Vorgänge nachvollziehen zu können.
Alles ist offen und nachvollziehbar.
21. BE-IIS HAT++ Installer
BE-IIS bietet Raspberry-Pi-HAT++-Boards für industrielle Schnittstellen an, darunter auch Single-Pair-Ethernet-Boards.
Für die Inbetriebnahme stellt BE-IIS einen Installer bereit, der die unterstützten HATs automatisch einrichtet.
Der Installer ist dafür ausgelegt:
- Erforderliche Kernel-Module zu installieren
- Erforderliche Device-Tree-Overlays zu installieren
- Unterstützte BE-IIS HAT++ Boards einzurichten
- Unterstützte HATs automatisch zu erkennen
- Den manuellen Konfigurationsaufwand zu reduzieren
Anwender unterstützter BE-IIS HAT++ Boards müssen das Modul daher normalerweise nicht manuell bauen.
Die manuellen Schritte in diesem Artikel bleiben hilfreich, wenn die Linux-Integration im Detail nachvollzogen werden soll.
22. Zusammenfassung
Mit dieser Methode wird der ADIN1110-Treiber als externes Raspberry-Pi-Kernel-Modul gebaut.
Sie vermeidet den Neubau des vollständigen Kernels und hält den Ablauf einfach:
./scripts/adin1110/build_adin1110_module.sh
sudo modprobe adin1110
Für den Modul-Build werden benötigt:
- Raspberry Pi OS 64-Bit
- Passende Raspberry-Pi-Kernel-Header
- Linux-Kernel 6.12 oder neuer
- ADIN1110-Treiberquelltext aus dem passenden Raspberry-Pi-Kernel-Branch
- Ein korrektes Device-Tree-Overlay
- Eine gültige MAC-Adresse im Device Tree
Dieser Ansatz eignet sich für manuelle Einrichtung, Fehlersuche und zum Verständnis der Treiberintegration.
Für die Inbetriebnahme ist dieselbe Logik in den offenen BE-IIS Installer integriert.
Referenzen
-
ADIN1110 10BASE-T1L Ethernet MAC-PHY, Analog Devices / DigiKey https://www.digikey.de/de/product-highlight/a/analog-devices/adin1110-10base-t1l-ethernet-mac-phy
-
ADIN1110-Linux-Kernel-Konfiguration für Raspberry Pi, Hackster.io https://www.hackster.io/pier8283/adin1110-linux-kernel-configuration-for-raspberry-pi-2f4a26
-
BE-IIS Installer https://github.com/be-iis/be-iis-installer/