Un kernel tout neuf pour l’Odroid-C1 !

Pour ceux qui ne le savent pas, je suis l’heureux possesseur d’une carte ARM nommée Odroid-C1. Cette carte a été fabriquée autour de 2014/2015 par Hardkernel.

La version du noyau fourni avec la carte est 3.10, avec énormément de patchs "made by hardkernel" pour que tout fonctionne bien. Seulement, depuis bientôt deux ans, il n’y a plus de mise à jour et déjà les mises à jour à l’époque n’étaient pas fréquentes et ne suivaient pas vraiment les patchs de sécurité.

Bref, j’ai donc décidé qu’il était temps d’essayer d’avoir une nouvelle version du kernel pour cette carte.

Le support de cette carte par la version principale de Linux (mainline) existe grace au projet communautaire Linux for Amlogic Meson (http://linux-meson.com/doku.php). Il a débuté fin 2015 avec ce patch (https://github.com/torvalds/linux/commit/4a69fcd3a10803854852481ab16031563d2d5381) qui a atterri dans la version 4.4 de Linux.

Avant de commencer

Je n’ai pas fait un test complet de la carte, il est donc possible que certaines choses ne fonctionnent pas correctement ou moins bien qu’avec le kernel d’origine.

Ce billet s’adresse à des personnes qui ont des bonnes connaissances de Linux et de son fonctionnement, il ne s’agit pas d’un tutoriel à appliquer tel que mais il doit être adapté pour votre cas (et carte).

Support matériel

La puce principale du C1 est un Amlogic S805, comme indiquée ici : https://wiki.odroid.com/odroid-c1/hardware/hardware.

Le tableau de la page http://linux-meson.com/doku.php nous donne le support de cette puce.

Attention, lors de l'écriture de ce billet, la sortie HDMI n'est pas supportée ! Ce nouveau noyau ne vous sera donc utile que si vous avez un usage sans écran (headless).

Solution rapide

Récupérer les fichiers sur le dépôt git suivant et sauter directement à la partie "installation".

Dans cette archive, vous trouverez le fichier uImage (le kernel) et les modules.

Préparation - Compilation

Avant tout, il faut préparer l’environnement de compilation, car on ne va pas compiler sur la carte ARM, ça serait bien trop long et ça risque de cramer la carte SD (même si on peut utiliser un disque usb pour éviter ça).

On va donc réaliser une cross-compilation depuis un PC, pour ce cas, je pars du principe que vous êtes avec une Debian Stretch, si ce n’est pas le cas, désolé :)

D’abord, il faut installer les paquets requis pour les différentes étapes

apt install gcc-arm-linux-gnueabihf build-essential flex bison libssl-dev bc u-boot-tools ccache fakeroot ncurses-devel libncurses-dev lzop gcc-arm-none-eabi git

Ensuite, on récupère la version stable de Linux (actuellement la version 5)

mkdir $HOME/compile
cd $HOME/compile
git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git -b linux-5.0.y linux
cd linux

La version 5.0 n’est pas une version avec un support à long terme, il faudra donc suivre les évolutions jusqu’à "tomber" sur une version dite LTS.

Avant tout, quelques variables d'environnement sont à définir

export PATH=/usr/lib/ccache:$PATH
export CROSS_COMPILE=arm-linux-gnueabihf-
export LOADADDR=0x00208000
export ARCH=arm
export INSTALL_MOD_PATH=$HOME/compile/linux-modules/

La liste des options à activer pour avoir un kernel fonctionnel, voici le fichier « config » à placer dans le dossier à la racine des sources, il faut le nommer ".config".

Vous pouvez sélectionner et modifier les options en faisant make menuconfig. Dans la config proposée ici, la plupart des options du kernel sont configurées en mode "module" afin de faire une image assez petite tout en proposant une configuration qui permettrait de brancher une clef tv en usb ou une carte wifi sans problème sur la carte odroid.

Une fois les options définies, il faut générer l’image ainsi que les fichiers dit "device tree" et bien sûr, les modules.

make -j4 uImage dtbs modules

Je passe l’option j4 car j’ai un PC avec 4 cœurs ce qui permet d’accélerer le temps de compilation.

Une fois la compilation effectuée, on va faire

make modules_install

Et maintenant il ne reste plus qu’à copier les fichiers sur la carte odroid.

Les fichiers dont on va avoir besoin dans la compilation qu'on a effectuée sont :

  • Le fichier « DTB », située ici : arch/arm/boot/dts/meson8b-odroidc1.dtb 
  • L’image du noyaux, située ici : arch/arm/boot/uImage
  • les modules dans, située dans : arch/arm/lib/modules (ainsi que dans $INSTALL_MOD_PATH)

Installation

Si vous prenez les fichiers présents sur le git ou ceux de la compilation, l’installation est identique.

Les opérations de copie de fichiers (modules, kernel et DTB) peuvent être faite en branchant la carte SD sur un PC, ou depuis le C1 via le réseau ou une clef usb. La génération de l'initramfs doit elle être faite dans l'environnement cible, c'est-à-dire sur le C1. Elle nécessite un OS Debian ou Ubuntu sur le C1.

Dans le doute, faites les opérations depuis le C1, afin que les chemins correspondent à ceux de ce billet.

Les modules

On copie les fichiers des modules dans /lib/modules/ (si vous avez fait une compilation vous-mêmes ils sont dans : $INSTALL_MOD_PATH, sinon ils sont dans le répertoire lib/modules sur le git).

Le kernel, l’initramfs et le DTB

Le kernel est le fichier nommé uImage et le DTB meson8b-odroidc1.dtb, ces deux fichiers sont à copier dans le répertoire de boot de votre carte (en général /boot ou /media/boot).

Par souci de version, j’ajoute au fichier uImage le numéro de version (exemple uImage-3.10.148)

Génération de l’initramfs

Important, cette opération doit être faite depuis le C1 !

Pour générer l’initramfs, on utilise les commandes suivantes :

VERSION=5.0.10
update-initramfs -c -k $VERSION
mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n uInitrd -d /boot/initrd.img-$VERSION /boot/uInitrd-$VERSION

Le boot.ini

Il reste ensuite à modifier le fichier boot.ini pour démarrer sur notre nouveau noyau.

Les seules modifications absolument nécessaires au boot.ini par rapport au boot.ini fourni par la version ubuntu-minimal de hardkernel sont les 3 lignes fatload.

Si vous avez des doutes, vous pouvez prendre celui-là comme exemple.

Pour utiliser le boot.ini qui est en exemple, il faut récupérer l’UUID de votre partition système (rootdev plus loin), pour ça on peut utiliser la commande suivante :

blkid $(mount | awk '/ \/ /{print$1}')

Il faut modifier les deux variables suivante pour correspondre aux informations de votre carte.

ethaddr
rootdev

Il faut aussi changer vers la fin du fichier les noms des fichiers uImage et uInitrd.

fatload mmc 0:1 0x21000000 uImage-5.0.10
fatload mmc 0:1 0x22000000 uInitrd-5.0.10
#fatload mmc 0:1 0x21800000 meson8b_odroidc.dtb
fatload mmc 0:1 0x21800000 meson8b-odroidc1.dtb

Post-conf (network)

Pour une raison inconnue, définir l’adresse MAC de la carte réseau dans le boot.ini ne suffit pas, il faut aussi la définir dans le fichier de configuration /etc/network/interfaces.

Il y a aussi un problème de stabilité si on laisse la carte réseau en gigabit, je force donc la carte en 100Mbit full duplex (merci Adventures with Linux).

iface eth0 inet dhcp
  hwaddress ether 00:1e:06:cb:e2:4d
  up ethtool -s $IFACE speed 100 duplex full autoneg off 

Si vous utiliser NetworkManager il faudra faire les modifications dans NetworkManager.

Sur Ubuntu, NetworkManager est installé, et remplace ifupdown.
Cependant, en héritant de la conf dans /etc/network/interfaces.d/eth0 en lecture seule, il n'est pas capable de positionner l'adressse Mac de l'interface.

De plus, une fois l'interface active, il n'est pas possible de changer son adresse... or vous êtes connecté à l'odroid via le réseau en ssh ! La solution consiste a ajouter le paquet ifupdown : apt install ifupdown.

Après le redémarrage, la commande ifup sera lancée par le service networking, et l'adresse Mac sera positionnée en accord avec le fichier /etc/network/interfaces.d/eth0.

L'autre solution (non testée) aurait été une gestion complète via NetworkManager, en supprimant le fichier /etc/network/interfaces.d/eth0 et en une ligne mac-address dans la section [Ethernet] du fichier /etc/NetworkManager/system-connections/ethernet-eth0.

Il manque un module pour chez moi !

Si vous avez besoin de modules ou d’option pour le noyaux qui ne sont pas disponible dans le binaire mis à disposition, merci d’ouvrir un ticket sur le gitlab.

Ressources complémentaires

Remerciement

Merci à Id2ndR pour les remarques et amélioration de l’article.

Merci à Meriem pour les relectures :)

Les problèmes d'alimentation ou d'affichage du raspberry-pi

Problème d'interférence Ici on est dans un cas fréquent, référencé ici (capture d'écran avec les pixels verts). Ma solution a été de réduire la bande passante nécessaire sur le cable HDMI. Je suis passé à une résolution FullHD (1080p) mais à une fréquence de 30Hz au lieu des 60Hz par défaut, et le  […]

Lire la suite

Haut de page