Ce document rassemble quelques notes sur l'installation de la carte Banana Pi avec U-Boot et Linux. Ces notes sont inspirées par le site linux-sunxi.org qui est sans doute la référence dans ce domaine.
Ce site préconise l'utilisation des branches principales de U-Boot et du kernel Linux et c'est ce que l'on va faire.
A la mise sous tension, Le processeur Allwinner A20 commence par exécuter le code embarqué dans sa rom dans un mode déterminé par la pin BOOTSEL du A20. Cette pin est connectée au bouton K3 de la carte. Il y a donc 2 modes:
Dans le mode eGON, le code cherche un SPL (Secondary Program Loader) dans l'ordre suivant :
Le FEL mode est un mode USB et nécessite un HOST (votre PC) pour charger le SPL puis le u-boot, puis ... C'est un mode qui peut être intéressant pour le développement, mais présente moins d'intérêt pour l'exploitation.
En conséquence, on constate que la carte ne peut booter que sur la carte SD correctement préparée, pour charger u-boot. U-boot étant chargé, il est possible de faire ce que u-boot sait faire : SD, SATA, USB, NFS, PXE, ...
Pour continuer, il nous faudra les binaires u-boot, du noyau Linux et un filesystem root. Sur la machine de développement (mon pc), on dispose d'un compilateur croisé appelé armv7-rpi2-linux-musleabihf- et accessible par le path. Pour éviter de trainer notre préfixe de compilateur partout, on l'exporte par une variable d'environnement:
export CC=armv7-rpi2-linux-musleabihf-
Ne prenez pas forcément les versions que j'indique, prenez les plus récentes...
Téléchargemnt du code source de U-boot et sélection de la version:
git clone git://git.denx.de/u-boot.git cd u-boot git checkout v2016.11
Maintenant on peut configurer u-boot pour le Banana PI:
make CROSS_COMPILE=${CC} Bananapi_defconfig
Vous pouvez personnaliser votre u-boot:
make CROSS_COMPILE=${CC} menuconfig
Compiler u-boot:
make CROSS_COMPILE=${CC}
La compilation du noyau est similaire à celle de u-boot et on commence par télécharger le source :
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.8.13.tar.xz tar Jxvf linux-4.8.13.tar.xz cd linux-4.8.13
On configure le noyau avec la configuration sunxi:
make ARCH=arm CROSS_COMPILE=${CC} sunxi_defconfig
Cette commande permet la personnalisation de la configuration. On va le faire pour configurer CONFIG_CPUSETS. Il faudra revenir ici plus tard, pour créer les modules dont on aura besoin.
make ARCH=arm CROSS_COMPILE=${CC} menuconfig
Le processeur Allwinner A20 a en fait 2 cores, mais un seul est visible avec le sunxi_defconfig. Avec la configuration suivante, on va activer CONFIG_CPUSETS=y:
General setup Control Group support Cpuset controller
On peut maintenant compiler le noyau, le dts et les modules qui seront installés dans le répertoire indiqué. Ces commandes devront être exécutées pour prendre en compte les modifications ultérieures de la configuration
ARCH=arm CROSS_COMPILE=${CC} make zImage dtbs ARCH=arm CROSS_COMPILE=${CC} INSTALL_MOD_PATH=../modules make modules modules_install
Si vous utilisez le noyau 4.8.13, il vous faudra un patch PATCHv4-net.git-1-2-Revert-stmmac-Fix-eth0-No-PHY-found-regression.patch, sinon ethernet ne fonctionnera pas sur le Banana Pi.
Si vous avez l'intention d'installer Asterisk, n'installez pas la version musl mais plutôt la version glibc, les fonctionnalités sont les mêmes, c'est juste un peu plus lent, mais ça fonctionne, ce qui n'est pas le cas avec la première.
A moins de vouloir tout compiler, ce qui prend beaucoup de temps, il semble préférable de prendre les binaires précompilés d'une distributions. Donc arrivé à ce point chacun prendra sa distribution préférée. Les distributions sont en général disponibles sous forme d'images d'une clé USB qu'il suffit de copier sur une carte SD, cela fait à la fois le partionnement, le formatage et l'installation d'un système minimal. Cela ne coute rien d'essayer et si ça ne fonctionne pas il sera toujours temps de revenir à cette page, en conservant votre système et en remplacant u-boot et le noyau.
Personnellement, je me suis dirigé vers la distribution Void Linux qui semble allier simplicité et performance. De plus elle fournit une archive d'un root fs minimal qu'il suffira d'extraire. Ensuite, une fois le système démarré, on pourra utiliser le gestionnaire de paquets pour installer les paquets que l'on souhaite ou même, si nécessaire, les compiler. Mais tout cela est complémentaire à l'objet de cette page.
Le root fs téléchargé sur le site http://repo.voidlinux.eu/live/current s'appelle void-cubieboard2-musl-rootfs-20160316.tar.xz. Il est destiné à la carte cubieboard2 qui utilise le même processeur Allwinner A20.
Pour résumer, après les étapes précédentes, on se retrouve dans un répertoire de travail contenant un répertoire u-boot, un répertoire linux-4.8.13, un répertoire modules. On dispose d'une carte SD de 4 Go minimum et de classe 10 de préférence. La notre fait 16 Go et comportera une partition de 4 Go pour le système et une partition home qui contiendra le volume restant.
Il est conseillé de mettre à zéro le premier Mo de la carte, surtout si la carte a auparavant contenu un iso. La commande suivante copie 1023 blocs de 1024 octets à 0, en commencant après les 1024 premiers octets, donc en sautant le MBR. Remplacer sdX, par le nom du volume que vous utilisez, par exemple sdb.
dd if=/dev/zero of=/dev/sdX bs=1k count=1023 seek=1
On peut ensuite partitionner la carte, si ce n'est déja fait.
La commande fdisk permet de la faire.
La séquence de caractères à taper est la suivante,
fdisk /dev/sdX on +4G n w
Après la séquence précédente, La commande p dans fdisk montre ceci:
Disk /dev/sdb: 14.6 GiB, 15707668480 bytes, 30679040 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xc6a382f1 Device Boot Start End Sectors Size Id Type /dev/sdb1 2048 8390655 8388608 4G 83 Linux /dev/sdb2 8390656 30679039 22288384 10.6G 83 Linux
Pour formatter les partitions linux:
mkfs.ext4 -L BPIROOT /dev/sdb1 mkfs.ext4 -L BPIHOME /dev/sdb2
On peut installer le SPL u-boot en un endroit où le bootloader du micro saura le trouver:
dd if=u-boot/u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8
Si la machine est opérationnelle, la copie de u-boot peut être effectué sur la machine elle-même, pour une mise à jour:
cd /boot dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8
Maintenant, il est temps d'extraire le filesystem root de notre distribution que l'on a préalablement téléchargé qui s'appelle void-cubieboard2-musl-rootfs-20160316.tar.xz.
mount /dev/sdb1 /mnt tar -C /mnt -Jxvf void-cubieboard2-musl-rootfs-20160316.tar.xz
Ce filesystem contient bien un noyau et un u-boot destiné à une autre carte, le cubieboard2. On va donc écraser ces binaires par ceux que l'on a généré pour le Banana Pi. Les autres fichiers sont conservés, car ils sont de la même architecture et ils caractérisent la distribution.
On a besoin d'un fichier binaire boot.scr pour donner des instructions à u-boot. Ce fichier est issu d'un fichier source boot.cmd:
ext4load mmc 0 0x46000000 /boot/zImage ext4load mmc 0 0x49000000 /boot/dtbs/sun7i-a20-bananapi.dtb setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p1 ro rootwait panic=10 ${extra} bootz 0x46000000 - 0x49000000
La commande suivante crée le fichier boot.scr à partir de boot.cmd et la commande mkimage a été généré pour notre host, lorsque l'on acompilé u-boot. Il suffit de la copier dans un endroit accessible par le path.
cp u-boot/tools/mkimage /usr/local mkimage -C none -A arm -T script -d boot.cmd boot.scr
Pour finir, on peut copier nos fichiers vers la carte SD. Notez que les fichiers boot.cmd et u-boot-sunxi-with-spl.bin ne sont pas nécessaires.
cp boot.cmd boot.scr /mnt/boot cp u-boot/u-boot.bin u-boot/u-boot-sunxi-with-spl.bin /mnt/boot cp linux-4.8.13/arch/arm/boot/zImage /mnt/boot mkdir -p /mnt/boot/dtbs cp linux-4.8.13/arch/arm/boot/dts/sun7i-a20-bananapi.dtb /mnt/boot/dtbs mkdir -p /mnt/lib/modules/4.8.13 tar -C modules/lib/modules/4.8.13 -cvf - . | tar -C /mnt/lib/modules/4.8.13 -xf -
Comme on aura à le faire plusieurs fois, lorsque l'on rajoutera des modules, un Makefile peut être utile.
# Void Linux banana pi sd cart generation Makefile # sd card mounted on /mnt VERSION = 4.8.13 LINUX = linux-$(VERSION) LINUXIMG = $(LINUX)/arch/arm/boot LINUXDTB = $(LINUX)/arch/arm/boot/dts DTB = sun7i-a20-bananapi.dtb UBOOT = u-boot BOOT = /mnt/boot MODULES = /mnt/lib/modules/$(VERSION) REMMODULES = /lib/modules/$(VERSION) SMODULES = modules/lib/modules/$(VERSION) bpi: boot.scr tar -C $(SMODULES) -cvf modules.tar . scp boot.scr boot.cmd $(LINUXIMG)/zImage $(UBOOT)/u-boot.bin bpi:/boot scp $(LINUXDTB)/$(DTB) bpi:/boot/dtbs scp modules.tar bpi:/ ssh bpi "tar -C $(REMMODULES) -xf /modules.tar" sd: $(BOOT)/boot.scr $(BOOT)/zImage $(BOOT)/dtbs/$(DTB) \ $(BOOT)/u-boot.bin $(MODULES)/modules.alias boot.scr: boot.cmd mkimage -C none -A arm -T script -d boot.cmd boot.scr $(BOOT)/boot.scr : boot.scr cp boot.scr boot.cmd $(BOOT) $(BOOT)/u-boot.bin : $(UBOOT)/u-boot.bin cp $(UBOOT)/u-boot.bin $(UBOOT)/u-boot-sunxi-with-spl.bin $(BOOT) $(BOOT)/zImage : $(LINUXIMG)/zImage cp $(LINUXIMG)/zImage $(BOOT)/zImage $(BOOT)/dtbs/$(DTB): $(LINUXDTB)/$(DTB) mkdir -p $(BOOT)/dtbs cp $(LINUXDTB)/$(DTB) $(BOOT)/dtbs/$(DTB) $(MODULES)/modules.alias : $(SMODULES)/modules.alias mkdir -p $(MODULES) tar -C $(SMODULES) -cvf - . | tar -C $(MODULES) -xf - touch $@ clean: rm -f *~
Il comporte 2 cibles bpi et sd. La première bpi suppose que la carte SD est opérationnelle sur la carte Banana PI. La seconde sd suppose que la partition root de la carte SD est montée sur /mnt sur la machine de développement.
make bpi
ou
make sd
On n'oubliera pas de démonter la partition root, lorsqu'elle est montée avant de récupérer la carte SD.
umount /mnt
Si on souhaite consulter les messages générés pendant la phase de boot et éventuellemnt intervenir en cas de problème, il est pratiquement nécessaire de connecter son PC à la carte Banana Pi par la liaison série.
Mon PC dispose d'une liaison série (j'avais choisi la carte mère pour cela). Le cable se branche donc sur un connecteur à l'arrière et se termine sur une petite carte d'interface, cablée depuis longtemps et servant pour toute connexion série, son rôle étant l'adaptation des niveaux rs232 <-> 3.3 Volts (Voir Rs232 serial adaptor). Il est alors nécessaire de se faire un cable connectant:
Connexions Uart /dev/ttyS0 | |||||
---|---|---|---|---|---|
carte bpi | carte rsadapt | ||||
J11 Pin1 TXD de l'UART0-TX | TXD | ||||
J11 Pin2 RXD de l'UART0-RX | RXD | ||||
J12 Pin2 3.3V | 5v | ||||
J12 Pin8 GND | gnd |
L'alimentation de l'adaptateur est fournie par la carte BPI et en général par le montage auquel il est connecté afin de fonctionner avec l'alimentation fournie 5V ou 3.3V. Le 5 ième point non connecté sert de détrompeur.
Si votre PC n'a pas de liaison série, un convertisseur USB série 3.3V fera l'affaire. Il faudra cependant raccorder les points TXD, RXD et GND à votre adaptateur.
Sur le PC un programme comme gtkterm permet de piloter la liaison série /dev/ttyS0 ou la liaison par usb /dev/ttyUSB0.
Photo du cable série pour Banana Pi.
Pour pouvoir l'utiliser en point de logging, il faut en activer le démarrage et sous Void Linux, c'est:
cd /var/service ln -s /etc/sv/agetty-console
Cette commande suppose la machine en fonctionnement, ce qui n'est pas toujours le cas. Pour préparer l'opération sur la carte SD montée sur /mnt sur votre machine de développement, exécuter les commandes suivantes:
# cd /mnt/etc/runit/runsvdir/default/ # ln -s /etc/sv/agetty-console
Modifier le fichier /etc/sv/agetty-console/conf, en effet le noyau démarre à 115200 bps alors pourquoi pas continuer, ce qui évite de changer dans le terminal.
BAUD_RATE=115200 TERM_NAME=linux
Le processeur dispose d'un 2 ième uart nommé UART3 dont les accès sont disponibles sur le connecteur CON3.
Connexions Uart /dev/ttyS0 | |||||
---|---|---|---|---|---|
carte bpi | utilisation | ||||
CON3 Pin8 TXD de l'UART3-TX | TXD | ||||
CON3 Pin10 RXD de l'UART3-RX | RXD | ||||
CON3 Pin6 GND | gnd |
L'accès naturel à la machine se fait par ssh. Il faut donc que le réseau soit configuré. Pour cela, une solution simple est d'utiliser dhcpcd et voici son fichier de configuration /etc/dhcpcd.conf qui utilise des ip statiques:
interface eth0 static ip_address=192.168.1.85/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1 interface wlan0 static ip_address=192.168.1.86/24 static routers=192.168.1.1 static domain_name_servers=192.168.1.1
Ce fichier contient déja la configuration pour la wifi que l'on peut commenter ou enlever si on n'a pas l'intention de l'utiliser. La commande suivante permet de démarrer le démon dhcpcd.
# ln -s /etc/sv/dhcpcd /var/service/
ou si la carte sd est montée sur /mnt sur la machine de développement:
# cd /mnt/etc/runit/runsvdir/default/ # ln -s /etc/sv/dhcpcd dhcpcd
Il ne faut pas se priver d'une installation wifi qui demande seulement l'acquisition d'une clé wifi du point de vue matériel. Elle coute moins cher qu'un cordon rj45 (moins de 2 euros)!. Du point de vue logiciel, il faut le paquet wpa_supplicant et bien sûr, le module du noyau corespondant à la clé installée et éventuellemnt un firmware pour cette clé.
L'essai se fait sucessivement sur 2 clés RTL8188ETV puis MT7601U. La commande lsusb donne des indications sur la clé wifi insérée. Une recherche internet indique que la clé RTL8188ETV est gérée par le module rtl8188eu (staging). Il faut donc activer ce module dans la configuration du noyau.
# lsusb ... Bus 002 Device 002: ID 0bda:0179 Realtek Semiconductor Corp. RTL8188ETV Wireless LAN 802.11n Network Adapter ... Bus 002 Device 002: ID 148f:7601 Ralink Technology, Corp. MT7601U Wireless Adapter ...
L'insertion de la RTL8188ETV se passe bien. L'insertion de MT7601U produit les messages suivants qui indique qu' un firmware mt7601u.bin est absent. On va donc l'installer:
[ 367.319719] mt7601u 2-1:1.0: ASIC revision: 76010001 MAC revision: 76010500 [ 367.328253] mt7601u 2-1:1.0: Direct firmware load for mt7601u.bin failed with error -2 [ 367.336918] mt7601u: probe of 2-1:1.0 failed with error -2
Une fois la clé connectée et le module chargé, la commande suivante donne la liste des interfaces net:
# ls /sys/class/net eth0 lo wlan0
Maintenant avec notre interface wifi wlan0, on peut créer le fichier de configuration wpa_supplicant, puis le modifier avec wpa_passphrase. La commande wifi fait "echo <Mon-ssid> <Ma-passphrase>" car c'est juste fatiguant de se rappeler et de taper sans erreur ces infos.
# cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wlan0.conf wpa_passphrase `wifi` >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
Le fichier résultant est à peu près ceci avec des vraies valeurs pour MY-SSID et MY-WPA-KEY :
$ cat /etc/wpa_supplicant/wpa_supplicant-wlan0.conf # Default configuration file for wpa_supplicant.conf(5). ctrl_interface=/run/wpa_supplicant ctrl_interface_group=wheel eapol_version=1 ap_scan=1 fast_reauth=1 update_config=1 # Add here your networks. network={ ssid="MY-SSID" #psk="MY-WPA-KEY" psk=3e187b29ae183052c6900244df85b546dce324902938aa486e9063391fd7c77b }
Il faut ensuite créer un fichier /etc/sv/wpa_supplicant/conf pour donner les paramètres adéquats. Et il arriva ce qui devait arriver: les paramètres de wpa_supplicant sont différents pour chacune des clés. On teste donc si r8188eu est chargé, et si oui on modifie la variable OPTS.
CONF_FILE=/etc/wpa_supplicant/wpa_supplicant-wlan0.conf if ! modprobe -q -n --first-time -v "r8188eu" ; then echo r8188eu is loaded OPTS="-Dwext -s" fi
Il ne reste plus qu'à démarrer wpa_supplicant en tant que service:
# ln -s /etc/sv/wpa_supplicant /var/service/
ou si la carte sd est montée sur /mnt sur la machine de développement:
# cd /mnt/etc/runit/runsvdir/default/ # ln -s /etc/sv/wpa_supplicant
Tout cela est très bien, l'adresse ip est affectée à l'interface mais le modem routeur n'en sait rien. On va donc faire un script /root/bin/netping et activé par /etc/rc.local pour pinguer le routeur.
#!/bin/bash # when bpi start the ip are set up, but the router is not aware, # so send a ping to modem when the interface is up # /etc/hosts must be up to date IP=192.168.1.1 HOST=bpi MODULES="r8188eu mt7601u" for m in $MODULES ; do # echo $m if ! modprobe -q -n --first-time -v $m ; then echo $m is loaded HOST=bpiw fi done #echo $HOST # for lazy net card until $(ping -q -W 1 -c 1 $HOST > /dev/null); do echo "Waiting $HOST interface to be up" sleep 1 done #ping the router ping -q -W 1 -c 1 $IP > /dev/null
Ceci n'est qu'une solution. Si on installe un desktop et NetworkManager les opérations précédentes ne sont plus nécessaires et doivent être désactivées.
A noter que la RTL8188ETV manque un peu de sensibilité, elle fonctionne bien à 6 m + 1 mur, mais très mal à 10 m + un plancher béton, ce qui n'est pas le cas pour l'autre.
On met la carte SD dans son emplacement, on démarre gtkterm et on branche le cordon secteur. Le listing suivant est la capture par gtkterm des messages émis sur l'UART0. On constate un prompt de login au bout de 5 s après le démarrage du noyau. Le réseau est prêt au bout de 10 s
U-Boot SPL 2016.03 (Mar 30 2016 - 18:11:30) DRAM: 1024 MiB CPU: 912000000Hz, AXI/AHB/APB: 3/2/2 Trying to boot from MMC U-Boot 2016.03 (Mar 30 2016 - 18:11:30 +0200) Allwinner Technology CPU: Allwinner A20 (SUN7I) I2C: ready DRAM: 1 GiB MMC: SUNXI SD/MMC: 0 *** Warning - bad CRC, using default environment Setting up a 720x576i composite-pal console (overscan 32x20) In: serial Out: vga Err: vga SCSI: SUNXI SCSI INIT SATA link 0 timeout. AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode flags: ncq stag pm led clo only pmp pio slum part ccc apst Net: eth0: ethernet@01c50000 starting USB... USB0: USB EHCI 1.00 USB1: USB OHCI 1.0 USB2: USB EHCI 0.00 USB3: USB OHCI 0.0 scanning bus 0 for devices... 1 USB Device(s) found scanning bus 2 for devices... 1 USB Device(s) found Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0 is current device Scanning mmc 0:1... Found U-Boot script /boot/boot.scr 288 bytes read in 166 ms (1000 Bytes/s) ## Executing script at 43100000 3164008 bytes read in 346 ms (8.7 MiB/s) 30295 bytes read in 173 ms (170.9 KiB/s) Kernel image @ 0x46000000 [ 0x000000 - 0x304768 ] ## Flattened Device Tree blob at 49000000 Booting using the fdt blob at 0x49000000 EHCI failed to shut down host controller. Loading Device Tree to 49ff5000, end 49fff656 ... OK Starting kernel ... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.8.13 (hq@olix) (gcc version 5.3.0 (crosstool-NG crosstool-ng-1.22.0-134-ge1d494a) ) #5 SMP Wed Apr 6 18:28:44 CEST 2016 [ 0.000000] CPU: ARMv7 Processor [410fc074] revision 4 (ARMv7), cr=10c5387d [ 0.000000] CPU: div instructions available: patching division code [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] Machine model: LeMaker Banana Pi [ 0.000000] Memory policy: Data cache writealloc [ 0.000000] psci: probing for conduit method from DT. [ 0.000000] psci: Using PSCI v0.1 Function IDs from DT [ 0.000000] PERCPU: Embedded 12 pages/cpu @ef7c6000 s17484 r8192 d23476 u49152 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 260202 [ 0.000000] Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p1 ro rootwait panic=10 [ 0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes) [ 0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes) [ 0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Memory: 1031212K/1046952K available (4418K kernel code, 203K rwdata, 1304K rodata, 284K init, 261K bss, 15740K reserved, 0K cma-reserved, 260520K highmem) [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB) [ 0.000000] vmalloc : 0xf0800000 - 0xff800000 ( 240 MB) [ 0.000000] lowmem : 0xc0000000 - 0xf0000000 ( 768 MB) [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB) [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB) [ 0.000000] .text : 0xc0008000 - 0xc059eb48 (5723 kB) [ 0.000000] .init : 0xc059f000 - 0xc05e6000 ( 284 kB) [ 0.000000] .data : 0xc05e6000 - 0xc0618f40 ( 204 kB) [ 0.000000] .bss : 0xc061b000 - 0xc065c484 ( 262 kB) [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1 [ 0.000000] Hierarchical RCU implementation. [ 0.000000] Build-time adjustment of leaf fanout to 32. [ 0.000000] RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=2. [ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2 [ 0.000000] NR_IRQS:16 nr_irqs:16 16 [ 0.000000] Architected cp15 timer(s) running at 24.00MHz (phys). [ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns [ 0.000007] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns [ 0.000019] Switching to timer-based delay loop, resolution 41ns [ 0.000414] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns [ 0.000610] clocksource: hstimer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 12741736309 ns [ 0.000795] Console: colour dummy device 80x30 [ 0.000826] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=240000) [ 0.000841] pid_max: default: 32768 minimum: 301 [ 0.000950] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000962] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes) [ 0.001610] CPU: Testing write buffer coherency: ok [ 0.001941] /cpus/cpu@0 missing clock-frequency property [ 0.001959] /cpus/cpu@1 missing clock-frequency property [ 0.001971] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.002037] Setting up static identity map for 0x40008280 - 0x400082d8 [ 0.003533] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.003619] Brought up 2 CPUs [ 0.003638] SMP: Total of 2 processors activated (96.00 BogoMIPS). [ 0.003644] CPU: All CPU(s) started in HYP mode. [ 0.003649] CPU: Virtualization extensions available. [ 0.004369] devtmpfs: initialized [ 0.012324] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 4 [ 0.012681] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns [ 0.012804] pinctrl core: initialized pinctrl subsystem [ 0.013937] NET: Registered protocol family 16 [ 0.014264] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.021257] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers. [ 0.021273] hw-breakpoint: maximum watchpoint size is 8 bytes. [ 0.028334] reg-fixed-voltage usb0-vbus: could not find pctldev for node /soc@01c00000/pinctrl@01c20800/usb0_vbus_pin@0, deferring probe [ 0.028388] reg-fixed-voltage usb1-vbus: could not find pctldev for node /soc@01c00000/pinctrl@01c20800/usb1_vbus_pin@0, deferring probe [ 0.028419] reg-fixed-voltage usb2-vbus: could not find pctldev for node /soc@01c00000/pinctrl@01c20800/usb2_vbus_pin@0, deferring probe [ 0.029152] reg-fixed-voltage gmac-3v3: could not find pctldev for node /soc@01c00000/pinctrl@01c20800/gmac_power_pin@0, deferring probe [ 0.029642] SCSI subsystem initialized [ 0.030287] usbcore: registered new interface driver usbfs [ 0.030353] usbcore: registered new interface driver hub [ 0.030420] usbcore: registered new device driver usb [ 0.030569] pps_core: LinuxPPS API ver. 1 registered [ 0.030577] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti[ 0.030606] PTP clock support registered [ 0.031675] clocksource: Switched to clocksource arch_sys_counter [ 0.032674] simple-framebuffer 7fe79000.framebuffer: framebuffer at 0x7fe79000, 0x178e00 bytes, mapped to 0xf0900000 [ 0.032692] simple-framebuffer 7fe79000.framebuffer: format=x8r8g8b8, mode=656x536x32, linelength=2880 [ 0.039386] Console: switching to colour frame buffer device 82x33 [ 0.045495] simple-framebuffer 7fe79000.framebuffer: fb0: simplefb registered! [ 0.055124] NET: Registered protocol family 2 [ 0.055698] TCP established hash table entries: 8192 (order: 3, 32768 bytes) [ 0.055788] TCP bind hash table entries: 8192 (order: 4, 65536 bytes) [ 0.055914] TCP: Hash tables configured (established 8192 bind 8192) [ 0.056001] UDP hash table entries: 512 (order: 2, 16384 bytes) [ 0.056061] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes) [ 0.056278] NET: Registered protocol family 1 [ 0.056733] RPC: Registered named UNIX socket transport module. [ 0.056747] RPC: Registered udp transport module. [ 0.056754] RPC: Registered tcp transport module. [ 0.056760] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.057381] hw perfevents: enabled with armv7_cortex_a7 PMU driver, 5 counters available [ 0.058574] futex hash table entries: 512 (order: 3, 32768 bytes) [ 0.069245] NFS: Registering the id_resolver key type [ 0.069335] Key type id_resolver registered [ 0.069342] Key type id_legacy registered [ 0.070493] bounce: pool size: 64 pages [ 0.070768] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250) [ 0.070791] io scheduler noop registered [ 0.070807] io scheduler deadline registered [ 0.070839] io scheduler cfq registered (default) [ 0.071258] sun4i-usb-phy 1c13400.phy: could not find pctldev for node /soc@01c00000/pinctrl@01c20800/usb0_id_detect_pin@0, deferring probe [ 0.074072] sun7i-a20-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver [ 0.138617] Serial: 8250/16550 driver, 8 ports, IRQ sharing disabled [ 0.141844] console [ttyS0] disabled [ 0.162047] 1c28000.serial: ttyS0 at MMIO 0x1c28000 (irq = 44, base_baud = 1500000) is a U6_16550A [ 0.835749] console [ttyS0] enabled [ 0.862742] 1c28c00.serial: ttyS1 at MMIO 0x1c28c00 (irq = 45, base_baud = 1500000) is a U6_16550A [ 0.895147] 1c29c00.serial: ttyS2 at MMIO 0x1c29c00 (irq = 46, base_baud = 1500000) is a U6_16550A [ 0.971719] ahci-sunxi 1c18000.sata: controller can't do PMP, turning off CAP_PMP [ 0.979242] ahci-sunxi 1c18000.sata: SSS flag set, parallel bus scan disabled [ 0.986427] ahci-sunxi 1c18000.sata: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl platform mode [ 0.995397] ahci-sunxi 1c18000.sata: flags: ncq sntf stag pm led clo only pio slum part ccc [ 1.004872] scsi host0: ahci-sunxi [ 1.008624] ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 32 [ 1.018149] CAN device driver interface [ 1.023099] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 1.029631] ehci-platform: EHCI generic platform driver [ 1.035253] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 1.041453] ohci-platform: OHCI generic platform driver [ 1.048525] sunxi-rtc 1c20d00.rtc: rtc core: registered rtc-sunxi as rtc0 [ 1.055378] sunxi-rtc 1c20d00.rtc: RTC enabled [ 1.059946] i2c /dev entries driver [ 1.064599] axp20x 0-0034: AXP20x variant AXP209 found [ 1.083256] input: axp20x-pek as /devices/platform/soc@01c00000/1c2ac00.i2c/i2c-0/0-0034/axp20x-pek/input/input0 [ 1.098709] axp20x 0-0034: AXP20X driver loaded [ 1.122482] sunxi-wdt 1c20c90.watchdog: Watchdog enabled (timeout=16 sec, nowayout=0) [ 1.131555] sunxi-mmc 1c0f000.mmc: Got CD GPIO [ 1.171876] sunxi-mmc 1c0f000.mmc: base:0xf08d6000 irq:27 [ 1.178133] sun4i-ss 1c15000.crypto-engine: no reset control found [ 1.185910] sun4i-ss 1c15000.crypto-engine: Die ID 0 [ 1.192583] usbcore: registered new interface driver usbhid [ 1.198158] usbhid: USB HID core driver [ 1.203565] NET: Registered protocol family 17 [ 1.208037] can: controller area network core (rev 20120528 abi 9) [ 1.214319] NET: Registered protocol family 29 [ 1.218774] can: raw protocol (rev 20120528) [ 1.223064] can: broadcast manager protocol (rev 20120528 t) [ 1.228730] can: netlink gateway (rev 20130117) max_hops=1 [ 1.234586] Key type dns_resolver registered [ 1.249984] Registering SWP/SWPB emulation handler [ 1.288795] mmc0: host does not support reading read-only switch, assuming write-enable [ 1.299304] mmc0: new high speed SDHC card at address 59b4 [ 1.305431] mmcblk0: mmc0:59b4 14.9 GiB [ 1.311166] mmcblk0: p1 p2 [ 1.336089] ata1: SATA link down (SStatus 0 SControl 300) [ 1.361775] sun7i-dwmac 1c50000.ethernet: no reset control found [ 1.367781] Ring mode enabled [ 1.370833] No HW DMA feature register supported [ 1.375392] Normal descriptors [ 1.378713] TX Checksum insertion supported [ 1.383622] sun7i-dwmac 1c50000.ethernet eth0: No MDIO subnode found [ 1.393605] libphy: stmmac: probed [ 1.397014] eth0: PHY ID 001cc915 at 0 IRQ POLL (stmmac-0:00) active [ 1.403386] eth0: PHY ID 001cc915 at 1 IRQ POLL (stmmac-0:01) [ 1.409568] ehci-platform 1c14000.usb: EHCI Host Controller [ 1.415212] ehci-platform 1c14000.usb: new USB bus registered, assigned bus number 1 [ 1.423135] ehci-platform 1c14000.usb: irq 29, io mem 0x01c14000 [ 1.441721] ehci-platform 1c14000.usb: USB 2.0 started, EHCI 1.00 [ 1.448716] hub 1-0:1.0: USB hub found [ 1.452566] hub 1-0:1.0: 1 port detected [ 1.457207] ehci-platform 1c1c000.usb: EHCI Host Controller [ 1.462862] ehci-platform 1c1c000.usb: new USB bus registered, assigned bus number 2 [ 1.470730] ehci-platform 1c1c000.usb: irq 33, io mem 0x01c1c000 [ 1.491668] ehci-platform 1c1c000.usb: USB 2.0 started, EHCI 1.00 [ 1.498636] hub 2-0:1.0: USB hub found [ 1.502476] hub 2-0:1.0: 1 port detected [ 1.507094] ohci-platform 1c14400.usb: Generic Platform OHCI controller [ 1.513776] ohci-platform 1c14400.usb: new USB bus registered, assigned bus number 3 [ 1.521697] ohci-platform 1c14400.usb: irq 30, io mem 0x01c14400 [ 1.586526] hub 3-0:1.0: USB hub found [ 1.590333] hub 3-0:1.0: 1 port detected [ 1.595041] ohci-platform 1c1c400.usb: Generic Platform OHCI controller [ 1.601741] ohci-platform 1c1c400.usb: new USB bus registered, assigned bus number 4 [ 1.609619] ohci-platform 1c1c400.usb: irq 34, io mem 0x01c1c400 [ 1.676537] hub 4-0:1.0: USB hub found [ 1.680331] hub 4-0:1.0: 1 port detected [ 1.684774] sunxi-rtc 1c20d00.rtc: setting system clock to 1970-01-01 00:00:10 UTC (10) [ 1.697901] vcc3v0: disabling [ 1.700896] vcc5v0: disabling [ 1.704410] usb0-vbus: disabling [ 1.709451] EXT4-fs (mmcblk0p1): couldn't mount as ext3 due to feature incompatibilities [ 1.718308] EXT4-fs (mmcblk0p1): couldn't mount as ext2 due to feature incompatibilities [ 1.737369] EXT4-fs (mmcblk0p1): mounted filesystem with ordered data mode. Opts: (null) [ 1.745589] VFS: Mounted root (ext4 filesystem) readonly on device 179:1. [ 1.755366] devtmpfs: mounted [ 1.758661] Freeing unused kernel memory: 284K (c059f000 - c05e6000) - runit: $Id: 25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $: booting. - runit: enter stage: /etc/runit/1 => Welcome to Void! => Mounting pseudo-filesystems... => Setting up keymap to 'fr'... => Setting up RTC to 'UTC'... => Starting udev and waiting for devices to settle... [ 2.206854] udevd[88]: starting version 3.1.5 [ 2.242545] random: udevd urandom read with 11 bits of entropy available [ 2.610610] sun4i-codec 1c22c00.codec: Codec <-> 1c22c00.codec mapping ok => Remounting rootfs read-only... [ 3.061476] EXT4-fs (mmcblk0p1): re-mounted. Opts: (null) => Activating btrfs devices... Scanning for Btrfs filesystems => Activating encrypted devices... => Checking filesystems: VOID_ARM: clean, 25553/262144 files, 239993/1048576 blocks VOID_HOME: clean, 7539/715264 files, 374661/2860544 blocks [ 3.407141] random: nonblocking pool is initialized => Mounting rootfs read-write... [ 3.495844] EXT4-fs (mmcblk0p1): re-mounted. Opts: (null) => Mounting all non-network filesystems... [ 3.551575] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) => Initializing swap... => Initializing random seed... => Setting up loopback interface... => Setting up hostname to 'lemaker'... => Setting up timezone to 'Europe/Paris'... => Loading kernel modules... => Loading sysctl(8) settings... * Applying /usr/lib/sysctl.d/void.conf ... kernel.core_uses_pid = 1 fs.protected_hardlinks = 1 fs.protected_symlinks = 1 * Applying /etc/sysctl.conf ... => Initialization complete, running stage 2... - runit: leave stage: /etc/runit/1 - runit: enter stage: /etc/runit/2 runsvchdir: default: current. [ 4.052390] RX IPC Checksum Offload disabled [ 4.056762] No MAC Management Counters available [ 5.007203] udevd[188]: starting version 3.1.5 Void 4.8.13 (lemaker) (console) lemaker login: [ 8.282578] RX IPC Checksum Offload disabled [ 8.286950] No MAC Management Counters available [ 10.272359] sun7i-dwmac 1c50000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
Les fichiers du root fs ne sont q'un minimum. Void Linux ne se distingue pas des autres distributions et a son installateur de paquets xbps-install et xbps-query pour la recherche. La première chose a faire c'est mettre à jour la distribution. Ensuite chacun installera ses paquets en fonction de son besoin.
xbps-install -Su
Comme nous n'avons pas utilisé l'installatateur officiel, il est nécessaire de finir manuellement.
Pour pouvoir monter les volumes d'une clé USB ou monter un volume de la carte sur la machine host par usb, ou avoir une connexion ethernet par USB, il faut compléter la configuration du noyau soit en créant des modules soit en incluant les fonctionnalités dans le noyau.
Device Drivers USB support Support for Host-side USB Enable USB persist by default OTG support USB Mass Storage support Inventra Highspeed Dual Role Controller (TI, ADI, AW, ...) Allwinner (sunxi) Disable DMA (always use PIO) USB Physical Layer drivers NOP USB Transceiver Driver USB Gadget Support Ethernet Gadget (with CDC Ethernet support) Gadget Filesystem Function Filesystem Mass Storage Gadget CDC Composite Device (Ethernet and ACM) CDC Composite Device (ACM and mass storage) Multifunction Composite Gadget HID Gadget
La commande lsblk montre les partitions sda* disponibles sur le Banana Pi, à la suite de l'insertion d'une clé USB sur une prise USB host de la carte. mmcblk0 correspond à la carte SD.
[root@lemaker ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 1 14.6G 0 disk sda1 8:1 1 1G 0 part sda2 8:2 1 8G 0 part sda3 8:3 1 5.6G 0 part mmcblk0 179:0 0 14.9G 0 disk mmcblk0p1 179:1 0 4G 0 part / mmcblk0p2 179:2 0 10.9G 0 part /home
La prise OTG du Banana Pi est connectée par un cable micro usb sur une prise USB de mon PC. Si c'est juste pour une démo, on peut faire la commande:
modprobe sunxi modprobe g_mass_storage file=/dev/mmcblk0p2
Une fenêtre s'ouvre sur mon desktop avec comme titre VOID_HOME, qui est le label donné à la partition mmcblk0p2. La commande lsblk me montre un disque sdb monté sur /run/media/hq/VOID_HOME. La commande lsusb fait appaitre la ligne suivante.
Bus 002 Device 003: ID 0525:a4a5 Netchip Technology, Inc. Pocketbook Pro 903
Pour monter la partition à chaque démarrage, on crée un fichier de configuration /etc/modprobe.d/masssto.conf contenant:
softdep g_mass_storage pre: sunxi options g_mass_storage file=/dev/mmcblk0p2 install g_mass_storage /sbin/modprobe --ignore-install g_mass_storage
Et on ajoute un fichier /etc/modules-load.d/masssto.conf contenant le nom du module g_mass_storage.
Vous n'avez pas de cable micro usb, vous pouvez avoir à peu près la même fonctionnalité avec sshfs ou avec nfs.
La prise OTG du Banana Pi est connectée par un cable micro usb sur une prise USB de mon PC. Pour voir quelque chose se passer, il faut charger les modules suivants sur le BPI:
modprobe sunxi modprobe g_ether
Sur le BPI, un device usb0 apparait:
root@lemaker ~]# ls /sys/class/net eth0 lo usb0 [root@lemaker ~]# ip link 3: usb0:mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether da:a1:94:c7:ea:59 brd ff:ff:ff:ff:ff:ff
Sur le Host, un device enp0s29f7u5, ainsi qu'un périphérique USB apparaissent:
[hq@olix temp]$ ls /sys/class/net enp0s29f7u5 enp4s0 lo [hq@olix temp]$ ip link 3: enp0s29f7u5:mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 6a:74:0c:0a:9f:b6 brd ff:ff:ff:ff:ff:ff [hq@olix temp]$ lsusb Bus 002 Device 002: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget
Il faut maintenant configurer les interfaces de chaque coté. d'abord du coté BPI:
ip link set dev usb0 up ip addr add 192.168.7.2/24 dev usb0 ip route add default via 192.168.7.1
Puis du coté host:
ip link set dev enp0s29f7u5 up ip addr add 192.168.7.1/24 dev enp0s29f7u5 ip route add 192.168.7.0/24 dev enp0s29f7u5 iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.7.0/24 sysctl -w net.ipv4.ip_forward=1
Les 2 dernières commandes permettent de pinger le routeur à partir du BPI. On peut à ce niveau, se connecter par ssh d'une machine vers l'autre et inversement. Il ne reste plus qu'à lancer dnsmasq comme relai dns
Pour atteindre le Banana Pi d'une autre machine du réseau, il est nécessaire, sur cette machine, de rajouter une route, lui disant quelle machine sert de passerelle.
ip route add 192.168.7.0/24 via 192.168.1.11
La carte Banana Pi possede un récepteur infrarouge, connecté directement au processeur et controllé par le module sunxi-cir du noyau. Avant de le rendre opérationnel, une configuration du noyau est nécessaire.
Device Drivers Input device support Generic input layer Multimedia support Remote Controller support compile Remote Controller keymap modules Remote Controller devices SUNXI IR remote control
Après compilation et installation, on peut charger le module:
modprobe sunxi-cir
Si tout se passe bien, on peut vérifier que sunxi-ir apparait dans le fichier /proc/bus/input/devices et qu'un répertoire /sys/class/rc/rc0 est créé. Le fichier /sys/class/rc/rc0/protocols donne la liste des protocoles compris par le driver. Il faut choisir celui qui correspond à notre télécommande et l'écrire dans ce même fichier
cat /sys/class/rc/rc0/protocols other [unknown] rc-5 nec rc-6 jvc sony rc-5-sz sanyo sharp mce_kbd xmp
echo -n rc-5 > /sys/class/rc/rc0/protocols
Le driver est accessible dans /dev/input/event1. Un fichier /etc/udev/rules.d/10-cir.rules permet de nommer définitivement le point d'accès en /dev/input/cir et éventuellement donner des droits.
SUBSYSTEM=="input", ACTION=="add", KERNEL=="event*", ATTRS{name}=="sunxi-ir", SYMLINK+="input/cir"
Lancer evtest, qui est un outil approprié pour tester et appuyer sur les touches de la télécommande:
[root@lemaker ~]# evtest /dev/input/cir Input driver version is 1.0.1 Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100 Input device name: "sunxi-ir" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 152 (KEY_SCREENLOCK) Event type 4 (EV_MSC) Event code 4 (MSC_SCAN) Key repeat handling: Repeat type 20 (EV_REP) Repeat code 0 (REP_DELAY) Value 500 Repeat code 1 (REP_PERIOD) Value 125 Properties: Testing ... (interrupt to exit) Event: time 9437.411710, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e01 Event: time 9437.411710, -------------- SYN_REPORT ------------ Event: time 9437.525324, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e01 Event: time 9437.525324, -------------- SYN_REPORT ------------ Event: time 9442.491425, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e02 Event: time 9442.491425, -------------- SYN_REPORT ------------ Event: time 9442.605047, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e02 Event: time 9442.605047, -------------- SYN_REPORT ------------ Event: time 9446.978642, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e03 Event: time 9446.978642, -------------- SYN_REPORT ------------ Event: time 9447.092258, type 4 (EV_MSC), code 4 (MSC_SCAN), value 1e03 Event: time 9447.092258, -------------- SYN_REPORT ------------
Le processeur de la carte Banana Pi embarque des codecs audio équivalent à une carte son de PC. la carte contient un microphone, une sortie audio sur un connecteur jack 3.5, une entrée stéréo sur le connecteur 1 pas facilement accessible et des soties par hdmi. La configuration du son dans sunxi_defconfig n'est pas faite par défaut, il faut donc la faire:
Device Drivers Sound card support Advanced Linux Sound Architecture Generic sound devices (NEW) ALSA for SoC audio support Allwinner SoC Audio support Allwinner A10 Codec Support
Après compilation et installation, les modules sont chargés automatiquement:
[root@lemaker ~]# lsmod Module Size Used by sun4i_codec 10367 3 snd_soc_core 105278 1 sun4i_codec snd_pcm_dmaengine 3007 1 snd_soc_core snd_pcm 69800 2 snd_soc_core,snd_pcm_dmaengine snd_timer 18088 1 snd_pcm snd 38886 3 snd_soc_core,snd_timer,snd_pcm soundcore 858 1 snd
Pour utiliser les commandes aplay, arecord du packet alsa-utils, un fichier de configuration /etc/asound.conf est bien utile. Si card = 0, les sorties analogiques sont utilisées. Pour utiliser hdmi, changer la valeur de card à 1.
pcm.!default { type hw card 0 device 0 } ctl.!default { type hw card 0 }
La carte Banana P posède 3 leds + 2 sur le connecteur rj45
La led verte D8, pilotée par le GPIO PH24, est à la disposition de l'utilisateur et est accessible par le sysfs. La commande suivante produit une liste de fonctions disponible pour cette led.
cat /sys/class/leds/bananapi:green:usr/trigger [none] kbd-scrollock kbd-numlock kbd-capslock kbd-kanalock kbd-shiftlock kbd-altgrlock kbd-ctrllock kbd-altlock kbd-shiftllock kbd-shiftrlock kbd-ctrlllock kbd-ctrlrlock axp20x-usb-online mmc0 heartbeat default-on
Pour changer la fonction il faut écrire le nom de cette fonction dans le fichier trigger. Par exemple:
echo -n heartbeat > /sys/class/leds/bananapi:green:usr/trigger
La led rouge D7 est connectée au circuit d'alimentation 3.3V et ne peut être éteinte qu'en coupant l'alimentation.
La led bleue D6 est connectée à la sortie DVDD33 du circuit RTL8211 d'interface ethernet. Il en est de même des 2 leds du connecteur rj45, la jaune sur la pin LED0-AD0 et la verte sur LED1-AD1. Un programme pour les piloter différemment est disponible ici.
Les gpios sont accessibles par l'interface sysfs /sys. Il faut commencer par exporter le gpio par la commande suivante:
echo -n> /sys/class/gpio/export
Le problème qui se pose alors est de trouver le numéro du gpio qui atterris sur le connecteur 3 pin 7 par exemple. Le schéma de la carte indique que cette pin à un nom PWM1. Si on cherche ce nom sur le schéma on s'apercçoit qu'il est connecté au pad B19 du microcontrolleur qui, par multiplexage, peut avoir comme fonctionnalités PWM1/TWI4_SDA/PI3. Sur le processeur Allwinner A20 (voir la datasheet) les ports sont nommés PXn avec X allant de A à I et n étant le numéro de bit (bitnum) dans le port pouvant aller de 0 à 31, mais pouvant être différent pour chaque port. Attention, tous les bits ne sont pas utilisés et ne correspondent pas forcément à un port!. Pour calculer le numéro, le port A-I est converti à portnum 0-8 puis multiplié par 32 et additionné du numéro de bit. Ce qui pour notre exemple donne 259.
numéro = portnum * 32 + bitnum 259 = 9 * 32 + 3
La commande d'export de port devient alors:
echo -n 259 > /sys/class/gpio/export
Ceci fait apparaitre un répertoire /sys/class/gpio/gpio259 contenant les fichiers suivants:
ls gpio259 active_low device direction power subsystem uevent value
Le fichier direction permet de modifier ou lire la direction du port (in/out) et le fichier value l'état logique du port visible à l'extérieur par son état électrique (0 / 3.3V).
cat gpio259/direction out cat gpio259/value 0 echo -n 1 > gpio259/value cat gpio259/value 1 echo -n in > gpio259/direction cat gpio259/direction in cat gpio259/value 0
Pour libérer les ressources:
echo -n 259 > /sys/class/gpio/unexport
Pour en savoir plus voir Documentation/gpio/sysfs.txt.
La méthode de calcul du numéro n'est valable que pour le processeur A20. Pour un autre processeur, il faudra redéfinir la formule en s'inspirant des fichiers de la hiérarchie Linux linux-4.8.13/drivers/pinctrl correspondant à ce processeur.
Le processeur A20 possède 5 TWI controleurs.
La fonctionnalité i2c est intégrée au noyau par défaut et l'interface /sys/class/i2c-dev laisse apparaitre i2c-0 i2c-1. i2c-0 pilote le controleur d'alimentation et i2c-1 les fils TWI2-SDA (pin 3) TWI2-SCK (pin 5) sur le connecteur CON3. La tension est 3.3 V !. Pour les commandes i2cdetect,... le numéro est 1, en effet le bus i2c1 n'est pas déclaré dans le device tree.
Pour tester l'i2c, j'ai voulu utliser un afficheur lcd 2x16 piloté par un processeur at89c2051 réalisant une interface i2c esclave ou interface série, le tout fonctionnant en 5 V. Il faut, pour commencer, réaliser une adaptation de niveau logique 3.3 / 5 V dont voici le schéma :
La fréquence du bus i2c est par défaut 100 kHz, c'est un peu trop rapide pour ma carte dont l'horloge effective est à 7.3728 / 12 Mhz et dont l'interface est faite en logiciel. Une fréquence de 5 ou 10 kHz sera plus approprié. Pour la modifier, il y a 2 moyens, soit modifier le device tree, soit accéder au registre de controle par l'interface /dev/mem. On va donc commencer par modifier le fichier arch/arm/boot/dts/sun7i-a20-bananapi.dts dans les sources Linux et y rajouter la ligne clock-frequency, puis compiler le dts et enfin copier le dtb sur la carte.
... &i2c2 { pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; clock-frequency = <10000>; status = "okay"; }; ...
Pour éviter de perdre du temps... Ne pas confondre l'adresse effective i2c et l'octet d'adresse transmis en ligne.
<Adresse i2c> = <octect d'adresse> >> 1.
On peut maintenamt lancer i2cdetect sur le bus 1. L'afficheur est détecté:
hq@lemaker ~ $ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- 22 -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Un programme minimal permet d'envoyer des messages vers l'afficheur sans empiler des librairies inutiles.
/* * i2ctst.c - HQ i2ctst program. It sends a message to a 2x16 lcd display. * gcc -Wall -g i2ctst.c -o i2ctst */ #include#include #include #include #include #include #include #include #include #include /* * message format: * msg | msg 0A msg | msg 0A msg 0A ... msg * first byte is a command byte * 0x41 left justified line1 * 0x61 left justified line2 * 0x42 right justified line1 * 0x62 right justified line2 * 0x43 center justified line1 * 0x63 center justified line2 * 0x44 set cursor line1 * 0x64 set cursor line2 * 0x45 write one char at cursor line1 * 0x65 write one char at cursor line2 * 0x46 blink char at cursor line1 * 0x66 blink char at cursor line2 * 0x47 lcd clear * 0x48 No blink char at cursor * 0x49 Write cmd */ int i2c_init(char *dev, int addr) { int fd; if ((fd = open(dev, O_RDWR)) < 0) { fprintf(stderr, "Failed to open the bus. %s - %s\n", dev, strerror(errno) ); return fd; } if (ioctl(fd, I2C_SLAVE, addr) < 0){ fprintf(stderr, "Failed to set slave addr 0x%x. - %s\n", addr, strerror(errno) ); return -1; } return fd; } /* * Write a n bytes message */ int i2c_write( int fd, char *msg ) { int n; int nw; n = strlen(msg) ; nw = write(fd, msg, n); if ( nw != n) { fprintf(stderr, "Wrote %d - Error writing %d bytes - %s\n", nw, n, strerror(errno) ); } return nw; } int main(int argc, char **argv) { int fd = i2c_init("/dev/i2c-1", 0x22 ); /* device, slave i2c addr */ int ret = i2c_write( fd, argv[1] ); close(fd); return ret; }
Et voici un exemple. Noter que le premier caractère est une commande de format:
sudo ./i2ctst "ABonjour lcd" sudo ./i2ctst "ble 18 dec"
Le processeur A20 fournit un controleur PWM avec 2 canaux. Le controleur est piloté par une fréquence de 24 MHz. Chaque canal divise la fréquence 24 MHz dans un prescaler. Le diviseur est réglage à 120, 180, 240, 360, 480, 12000, 24000, 36000, 48000, 72000 et fournit la fréquence PWM_CLK dont la période sert de reférence dans le signal de sortie. Une période du signal de sortie est définie par n période d' horloges pour le temps actif et m périodes pour le temps total. Ces valeurs m et n sont à écrire dans le registre channel.
modification du device tree arch/arm/boot/dts/sun7i-a20-bananapi.dts
... &pwm { pinctrl-names = "default"; pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins_a>; status = "okay"; }; ...
Unixbench est un jeu de tests, qui exécuté sur une machine, fournit un nombre pouvant caractériser les capacités de cette machine.
Pour effectuer un test il faut télécharger les sources, compiler ces sources sur la machine que l'on va tester (si possible) et exécuter le test qui dure environ 30 minutes et plus si la machine possède plusieurs processeurs. Vous aurez besoin de gcc, make, perl, libc-devel. Les résultats se trouvent dans le répertoire results.
Cliquer Download Zip sur https://github.com/kdlucas/byte-unixbench unzip byte-unixbench-master.zip cd UnixBench make clean make ./Run
Carte Banana Pi M1 | |||||
---|---|---|---|---|---|
Operating System | result 1 cpu | Result n cpus | Delta | ||
Arch linux | 147.5 | na | 0 | ||
Void Linux musl | 232.6 | 400.1 | +57.7 % | ||
Void Linux glibc | 180.6 | 308.0 | +22.4 % | ||
Bananian Linux | 183.8 | na | +24.6 % | ||
Armbian Ubuntu | 171.4 | 307.0 | +16.2 % | ||
Gentoo arm | 141.5 | na | -4.2 % |
Le delta est le rapport entre le résultat de la distribution et celui de Arch Linux, pour un processeur.
Il semblerait que les kernel 3.* n'exploiterait pas les 2 CPUs !. Pour information, voici les résultats pour un Raspberri Pi B:
Carte Raspberri Pi model B | |||||
---|---|---|---|---|---|
Operating System | Result | Result n cpus | Delta | ||
Arch linux | 75.4 | 0 |
Il faut éviter de tirer des conclusions trop hatives. En effet si toutes vos applications fonctionnent avec libc musl, c'est le chiffre indiqué, mais si seulement une ne fonctionne pas, vous êtes dans l'obligation de la rejeter pour une autre. Aujourd'hui par exemple, Asterisk ne fonctionne pas avec musl.