für alle die einen eignen Kernel bauen wollen auf ihrem Einplatinenrechner. Hier eine Kurzanleitung und noch einige Tipps.
Vorbereitung
sudo pacman -Syu
sudo reboot
sudo pacman -S git wget
Kernel bauen
aktuellen Kernel herunterladen und entpacken
https://www.kernel.org/
oder
cd /usr/src
sudo wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.3.tar.xz
sudo tar -xJf linux-4.9.3.tar.xz
Kernel patchen
cd /usr/src
herunterladen der Patches
sudo git clone https://github.com/GBert/sunxi-can-driver
sudo cp /usr/src/sunxi-can-driver/800-dt-sun7i-add-can.patch /usr/src/linux-4.9.3/800-dt-sun7i-add-can.patch
sudo cp /usr/src/sunxi-can-driver/801-dt-sun7i-add-can-bananapi.patch /usr/src/linux-4.9.3/801-dt-sun7i-add-can-bananapi.patch
cd /usr/src/linux-4.9.3
Patch 1
sudo patch -p1 < /usr/src/linux-4.8.12/800-dt-sun7i-add-can.patch
Rückmeldung :
patching file arch/arm/boot/dts/sun7i-a20.dtsi
Hunk #1 succeeded at 1142 (offset 252 lines).
Hunk #2 succeeded at 1655 with fuzz 2 (offset 314 lines).
Patch 2
sudo patch -p1 < /usr/src/linux-4.8.12/801-dt-sun7i-add-can-bananapi.patch
Rückmeldung:
patching file arch/arm/boot/dts/sun7i-a20-bananapi.dts
Hunk #1 succeeded at 96 (offset 4 lines).
Kernelconfigurieren
cd /usr/src/linux-4.9.3
sudo make menuconfig
Konfiguration schliessen ohne zu speichern mit < Exit > und dann < NO >
mit su zum root Benutzer wechseln
su
zcat /proc/config.gz > .config
Überprüfen und anpassen der .config Datei
make menuconfig
"["*"]" Networking support --->
<M> CAN bus subsystem support --->
--- CAN bus subsystem support
<M> Raw CAN Protocol (raw access with CAN-ID filtering)
<M> Broadcast Manager CAN Protocol (with content filtering)
<M> CAN Gateway/Router (with netlink configuration)
CAN Device Drivers --->
...
"["*"]" CAN bit-timing calculation
...
<M> Allwinner A10 CAN controller
meine persönlichen Einstellungen. Sie sind kein MUSS ;-)
General setup --->
(-CAN) Local version - append to kernel release
Device Drivers --->
Generic Driver Options --->
"[ ]" Include in-kernel firmware blobs in kernel binary
() External firmware blobs to build into the kernel binary
Kernel bauen
make -j2
make modules_install
cp arch/arm/boot/*zImage /boot/*zImage
device tree blob kopieren. Hier zu gibt es einpaar mehr Infos am Ende.
cp arch/arm/boot/dts/sun7i-a20-bananapi.dtb /boot/dtbs/sun7i-a20-bananapi.dtb
reboot
Funktionsprüfung
Nach dem Neustart sollte die Schnittstell zur Verfügung stehen. Überprüfen kann man dies wie folgt.
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
oder
$ ip -details link show can0
2: can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state STOPPED (berr-counter tx 0 rx 0) restart-ms 0
sun4i_can: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
clock 24000000numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
gestartet werden (bzw. aktiviert und konfiguriert), kann die CAN Schnittstelle mit folgenden Befehlen. Dies ist aber nur ein Beispiel.
sudo ip link set can0 type can bitrate 500000
sudo ifconfig can0 up
sudo modprobe can-raw
Wenn man mit lsmod die geladen Module sich ansieht, sollte folgendes zusehen sein.
$ lsmod
Module Size Used by
can_raw 7030 0
can 29785 1 can_raw
rpcsec_gss_krb5 22495 0
evdev 12667 2
realtek 2863 0
dwmac_sunxi 2702 0
stmmac_platform 6502 1 dwmac_sunxi
sun4i_codec 12683 3
stmmac 83365 3 stmmac_platform,dwmac_sunxi
sun4i_can 6846 0
ir_lirc_codec 5379 0
lirc_dev 10251 1 ir_lirc_codec
snd_soc_core 151796 1 sun4i_codec
can_dev 14592 1 sun4i_can
snd_pcm_dmaengine 5600 1 snd_soc_core
ac97_bus 1838 1 snd_soc_core
axp20x_pek 3651 0
snd_pcm 95517 2 snd_pcm_dmaengine,snd_soc_core
sun4i_ts 4456 0
snd_timer 22701 1 snd_pcm
sunxi_cir 4337 0
sunxi_wdt 3769 0
sun4i_ss 16342 0
spi_sun4i 4571 0
uio_pdrv_genirq 3591 0
uio 9341 1 uio_pdrv_genirq
sch_fq_codel 9160 3
ip_tables 13001 0
x_tables 18965 1 ip_tables
Erläuterung zum device tree blob
Hierzu möchte ich sagen, das ich nur einen begrenzten Einblick bekommen habe in die Architektur der Einplatinenrechner. Von meinem bisherigen Verständnis her, brauchte man nur den Treiber im Kernel aktivieren und die Schnittstelle funktionierte. 🙂 Die Schwierigkeit beim Banana Pi ist (dies gilt wahrscheinlich auch für andere Einplatinenrechner) , das das GPIO doppelte Funktionen auf den PINs hat. Die Pins können als digitales Bit oder als CAN Schnittstelle genutzt werden. Im Standardkernel sind die PINs als Digitales Bit konfiguriert. Leider gibt keine Konfigurationsdatei, in der man die Funktion nach Bedarf umschalten kann.
Für die Einplatinerechner gibt es den sogenannten Device Tree. Hier findet man für eine vielzahl von Rechnern (chips;) die entsprechende Konfigurationsdateien.
In diesem Fall sind es ../arch/arm/boot/dts/sun7i-a20-bananapi.dts und ../arch/arm/boot/dts/sun7i-a20.dtsi. Dies Dateien beschreiben welche Komponeten des Chips aktiviert und wie sie konfiguriert werden. Man findet zum Beispiel die CPU Geschwindigkeit sowie andere Schnittstellen(z.B. i2c, ohci ...) und ihre Einstellungen.
Die Patches konfigurieren diese Dateien nun so, das beim Kernelbau eine "Konfigurationsdatei" (sun7i-a20-bananapi.dtb) entsteht mit der aktivierten CAN Schnittstelle.
Das ich die Datei sun7i-a20-bananapi.dtb als Konfigurationsdatei beschrieben habe, ist sicher nicht korrekt, da sie etwas mehr macht aber es ist einfacher für das Verständnis.
Die Datei wird dann in den "device tree" des Bootverzeichnisses kopiert, damit sie dann beim Bootvorgang auch genutzt werden kann.
Ich hoffe es hilft allen, die sich mit die Hardware auseinander setzen möchten. Falls ich etwas nicht korrekt beschrieben habe, fühlt euch eingeladen dies richtig zustellen. 🙂
euer Nordländer