{"id":4405,"date":"2015-12-08T09:00:12","date_gmt":"2015-12-08T08:00:12","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=4405"},"modified":"2019-03-06T14:26:40","modified_gmt":"2019-03-06T13:26:40","slug":"creation-dun-systeme-complet-avec-buildroot","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2015\/12\/08\/creation-dun-systeme-complet-avec-buildroot\/","title":{"rendered":"Cr\u00e9ation d&rsquo;un syst\u00e8me complet avec Buildroot"},"content":{"rendered":"<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2015\/12\/Buildroot-Rpi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-4468\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2015\/12\/Buildroot-Rpi.png\" alt=\"Cr\u00e9ation d'un syst\u00e8me complet avec Buildroot 2015-11\" width=\"250\" height=\"200\" \/><\/a><\/p>\n<p>[Une version plus r\u00e9cente de cet article est <a href=\"https:\/\/www.blaess.fr\/christophe\/articles\/creer-un-systeme-complet-avec-buildroot\/\">disponible ici<\/a>]<\/p>\n<p style=\"text-align: justify;\">Le projet <a href=\"http:\/\/buildroot.uclibc.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Buildroot<\/a> nous fournit d\u00e9sormais une version de travail trimestrielle et une version annuelle maintenue sur le long terme. Buildroot permet de construire un syst\u00e8me embarqu\u00e9 plus traditionnel qu&rsquo;en utilisant une distribution pr\u00e9-compil\u00e9e, et d&rsquo;ajuster plus finement son contenu. Nous allons l&rsquo;utiliser pour construire un syst\u00e8me personnalis\u00e9 pour Raspberry Pi.<\/p>\n<p>\n<!--more-->\n<\/p>\n<p style=\"text-align: justify;\">[5 Novembre 2018: cet article a \u00e9t\u00e9 mis \u00e0 jour pour prendre en compte la version \u00ab\u00a0long terme\u00a0\u00bb actuelle de Buildroot. L&rsquo;ancien article qui parlait de Buildroot 2015.11 est archiv\u00e9 <a href=\"https:\/\/www.blaess.fr\/christophe\/2015\/12\/08\/creation-dun-systeme-avec-buildroot-2015-11\/\">ici<\/a>.]<\/p>\n<p style=\"text-align: justify;\">Nous allons successivement pr\u00e9parer une cha\u00eene de <em>cross-compilation<\/em>, construire un syst\u00e8me minimal pour v\u00e9rifier le bon fonctionnement de celle-ci puis g\u00e9n\u00e9rer un syst\u00e8me configur\u00e9 de fa\u00e7on plus personnalis\u00e9e.<\/p>\n<h1>Environnement de travail<\/h1>\n<p style=\"text-align: justify;\">Commen\u00e7ons par cr\u00e9er une arborescence de travail qui contiendra tous nos fichiers personnalis\u00e9s, les r\u00e9pertoires de construction, la cha\u00eene de compilation, etc.<\/p>\n<pre>[~]$ <strong>mkdir br-tree<\/strong>\n[~]$ <strong>cd br-tree<\/strong>\n[br-tree]$<\/pre>\n<p style=\"text-align: justify;\">Au sein de cet environnement, nous allons essayer de respecter <a href=\"http:\/\/www.buildroot.org\/downloads\/manual\/manual.html#customize-dir-structure\" target=\"_blank\" rel=\"noopener noreferrer\">l&rsquo;organisation des fichiers<\/a> propos\u00e9e par le projet Buildroot&nbsp;: une arborescence <code>board\/<\/code> contenant un sous-r\u00e9pertoire pour chaque carte que nous supporterons (ici le Raspberry Pi 3 uniquement). Tous nos fichiers personnalis\u00e9s se trouveront dans cette sous-arborescence.<\/p>\n<pre>[br-tree]$ <strong>mkdir -p board\/rpi-3\/<\/strong><\/pre>\n<p style=\"text-align: justify;\">Nous t\u00e9l\u00e9chargeons les sources de la derni\u00e8re version de Buildroot, les d\u00e9compressons et entrons dans ce r\u00e9pertoire&nbsp;:<\/p>\n<pre>[br-tree]$ <strong>wget <a href=\"http:\/\/www.buildroot.org\/downloads\/buildroot-2018.02.7.tar.bz2\">http:\/\/www.buildroot.org\/downloads\/buildroot-2018.02.7.tar.bz2<\/a><\/strong>\n[br-tree]$ <strong>tar xf buildroot-2018.02.7.tar.bz2<\/strong>\n[br-tree]$ <strong>cd buildroot-2018.02.7\/<\/strong><\/pre>\n<h1>Toolchain<\/h1>\n<p style=\"text-align: justify;\">J&rsquo;ai l&rsquo;habitude de commencer mes projets embarqu\u00e9s par la construction d&rsquo;une <em>toolchain<\/em> de <em>cross-compilation<\/em>. Il s&rsquo;agit d&rsquo;obtenir un compilateur &#8211; et tous les outils associ\u00e9s &#8211; fonctionnant sur la machine de d\u00e9veloppement (un PC par exemple) et produisant du code pour la plate-forme cible (ici le Raspberry Pi 3).<\/p>\n<p style=\"text-align: justify;\">Il est tout \u00e0 fait possible de se procurer une <em>toolchain<\/em> pr\u00e9-compil\u00e9e, mais je trouve qu&rsquo;il est dommage de se priver de cette \u00e9tape de construction, d&rsquo;autant que cela nous permet de ma\u00eetriser exactement les versions de la biblioth\u00e8que C, du noyau, des outils, etc. que nous souhaitons.<\/p>\n<p style=\"text-align: justify;\">Si j&rsquo;isole cette \u00e9tape de la production du syst\u00e8me complet, c&rsquo;est qu&rsquo;elle prend un temps significatif (une vingtaine de minutes sur un petit processeur i7 avec une connexion Internet fibre). La <em>toolchain<\/em> est donc compil\u00e9e et install\u00e9e une fois pour toutes, et ne sera plus modifi\u00e9e m\u00eame si nous r\u00e9it\u00e9rons autant de g\u00e9n\u00e9ration du syst\u00e8me que nous le d\u00e9sirons.<\/p>\n<p style=\"text-align: justify;\">J&rsquo;ai l&rsquo;habitude de placer la <em>toolchain<\/em> dans le r\u00e9pertoire <code>board\/<em>&lt;target&gt;<\/em>\/cross<\/code>.<\/p>\n<p style=\"text-align: justify;\">Pour produire la <em>toolchain<\/em>, nous demandons une configuration de Buildroot par d\u00e9faut pour la cible choisie, et l&rsquo;\u00e9laguons pour ne laisser que la production du compilateur et de ses outils. Les configurations par d\u00e9faut disponibles sont visibles dans le sous-r\u00e9pertoire <code>configs\/<\/code>. Nous choisissons celle pour Raspberry Pi 3.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>make raspberrypi3_defconfig\n<\/strong>[buildroot-2018.02.7]$ <strong>make menuconfig<\/strong><\/pre>\n<p style=\"text-align: justify;\">Voici la liste des modifications apport\u00e9es&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Target options<\/code><\/strong> : pas de changement, mais on peut en profiter pour observer et v\u00e9rifier le support du processeur cible.<\/li>\n<li>Menu <strong><code>Build options<\/code><\/strong> :\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Download dir<\/code> : nous extrayons de l&rsquo;arborescence de Buildroot ce r\u00e9pertoire dans lequel il stocke les fichiers t\u00e9l\u00e9charg\u00e9s. Ainsi les compilations successives ne n\u00e9cessiterons pas de nouveaux t\u00e9l\u00e9chargements. Nouvelle valeur&nbsp;: <code>$(TOPDIR)\/..\/dl<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\"><code>Host dir<\/code> : l&#8217;emplacement o\u00f9 se trouvera la <em>toolchain<\/em> compil\u00e9e. Comme indiqu\u00e9 plus haut, j&rsquo;ai pour habitude de la placer dans le r\u00e9pertoire <code>board\/&lt;target&gt;\/cross<\/code> de notre arborescence de travail. Nouveau chemin&nbsp;: <code>$(TOPDIR)\/..\/board\/rpi-3\/cross<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Toolchain<\/code><\/strong> :\n<ul>\n<li><code>C library<\/code> : c&rsquo;est un choix qui d\u00e9pend beaucoup du code m\u00e9tier. La biblioth\u00e8que C est un point-cl\u00e9 du syst\u00e8me&nbsp;; c&rsquo;est elle qui permet d&rsquo;entrer dans le noyau pour b\u00e9n\u00e9ficier de ses services (appels-syst\u00e8me). Pour \u00eatre le plus g\u00e9n\u00e9rique possible, nous choisissons la <em>Gnu C library<\/em>, un peu plus volumineuse que les autres, mais plus riche \u00e9galement. Nouvelle valeur&nbsp;: <code>glibc<\/code><\/li>\n<li><code>Kernel Headers<\/code> : la compilation de la biblioth\u00e8que C n\u00e9cessite de charger les fichiers <em>headers<\/em> du noyau afin de conna\u00eetre ses points d&rsquo;entr\u00e9e (voir <a href=\"https:\/\/www.blaess.fr\/christophe\/2014\/04\/05\/utiliser-un-appel-systeme-inconnu-de-la-libc\/\">cet article<\/a> pour plus de d\u00e9tails). Par d\u00e9faut Buildroot utilise la m\u00eame version de noyau que celui qui sera construit pour le syst\u00e8me (Linux 4.9.x). Toutefois nous n&rsquo;allons pas compiler tout de suite de noyau aussi se rabat-il sur la version la plus r\u00e9cente qu&rsquo;il conna\u00eet (Linux 4.15.x) pour produire la libC. Si nous laissons en l&rsquo;\u00e9tat, une fois que nous aurons compil\u00e9 tout le syst\u00e8me et <em>booterons<\/em> le Raspberry Pi 3, la GlibC compil\u00e9e pour un 4.15 refusera de s&rsquo;initialiser sur un 4.9. et affichera le message \u00ab\u00a0<em>Kernel too old<\/em>\u00a0\u00bb avant qu&rsquo;un <em>Kernel Panic<\/em> se produise puisque le processus <em>init<\/em> ne peut d\u00e9marrer. Nouvelle valeur&nbsp;: <code>Linux 4.9.x kernel headers<\/code>. Le menu <code>Custom kernel headers series<\/code> dispara\u00eet alors.<\/li>\n<li><code>Build cross gdb for the host<\/code> : en pr\u00e9vision des \u00e9ventuelles s\u00e9ances de d\u00e9bogage distant du code applicatif, j&rsquo;ajoute dans la <em>toolchain<\/em> un d\u00e9bogueur qui fonctionne sur PC mais peut analyser du code au format de la cible. Nouvelle valeur&nbsp;: <code>[*]<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>System configuration<\/code><\/strong> :\n<ul>\n<li><code>Init system<\/code> : cette option contient au pr\u00e9alable <code>BusyBox<\/code> mais nous la d\u00e9sactivons pour pouvoir \u00e9liminer ce package. Nouvelle valeur&nbsp;: <code>None<\/code><\/li>\n<li><code>Custom scripts to run before creating filesystem images<\/code> : nous n&rsquo;allons pas produire de syst\u00e8me complet, il ne faut donc pas lancer le script qui finalise l&rsquo;arborescence avant de cr\u00e9er les images des syst\u00e8mes de fichiers. Nouvelle valeur&nbsp;: <code>()<\/code>.<\/li>\n<li><code>Custom scripts to run after creating filesystem images<\/code> : pour la m\u00eame raison nous ne lan\u00e7ons pas le script qui assemble les images des syst\u00e8mes de fichiers pour cr\u00e9er une image compl\u00e8te de la carte microSD pour Raspberry Pi. Nouvelle valeur&nbsp;: <code>()<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Kernel<\/code><\/strong> :\n<ul>\n<li><code>Linux Kernel<\/code> : nous ne voulons, dans un premier temps, produire que la <em>toolchain<\/em> et rien d&rsquo;autre. Nous d\u00e9sactivons cette option. Nouvelle valeur&nbsp;: <code>[ ]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Target packages<\/code><\/strong> :\n<ul>\n<li><code>BusyBox<\/code> : c&rsquo;est le seul package initialement pr\u00e9sent. Nous le d\u00e9sactivons. Nouvelle valeur&nbsp;: <code>[ ]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Filesystem images<\/code><\/strong> :\n<ul>\n<li><code>ext2\/3\/4 root filesystem<\/code> : inutile, nous ne voulons pas de <em>filesystem<\/em> pour le moment. Nouvelle valeur&nbsp;: <code>[ ]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\">Menu <strong><code>Legacy config options<\/code><\/strong> : Je jette toujours un \u0153il \u00e0 ce menu lorsque j&rsquo;utilise une nouvelle version de Buildroot avec un fichier de configuration pr\u00e9-existant car il nous indique les fonctionnalit\u00e9s incompatibles (modifi\u00e9es, disparues, etc.) entre deux versions.<br \/>\nComme nous avons g\u00e9n\u00e9r\u00e9 un fichier de configuration \u00ab\u00a0<em>from scratch<\/em>\u00ab\u00a0, ce n&rsquo;est pas n\u00e9cessaire ici.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Sauvegardons la configuration et lan\u00e7ons la compilation. Une nouvelle cible de compilation \u00ab\u00a0<code>toolchain<\/code>\u00a0\u00bb est disponible depuis quelques versions de Buildroot. Je suppose que certaines de nos modifications dans les menus \u00ab\u00a0<code>System configuration<\/code>\u00ab\u00a0, \u00ab\u00a0<code>Kernel<\/code>\u00a0\u00bb et \u00ab\u00a0<code>Target Packages<\/code>\u00a0\u00bb sont redondantes avec cette nouvelle cible mais je pr\u00e9f\u00e8re les appliquer quand m\u00eame.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>cp .config ..\/board\/rpi-3\/buildroot-2018.02-toolchain.config<\/strong>\n[buildroot-2018.02.7]$ <strong>make toolchain<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s quelques minutes, la compilation se termine avec ces lignes&nbsp;:<\/p>\n<pre>\t-e 's#@@STAGING_SUBDIR@@#arm-buildroot-linux-gnueabihf\/sysroot#' \\\n\t-e 's#@@TARGET_CFLAGS@@#-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os#' \\\n\t-e 's#@@TARGET_CXXFLAGS@@#-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os#' \\\n\t-e 's#@@TARGET_FCFLAGS@@#-Os#' \\\n\t-e 's#@@TARGET_LDFLAGS@@##' \\\n\t-e 's#@@TARGET_CC@@#bin\/arm-buildroot-linux-gnueabihf-gcc#' \\\n\t-e 's#@@TARGET_CXX@@#bin\/arm-buildroot-linux-gnueabihf-g++#' \\\n\t-e 's#@@TARGET_FC@@#bin\/arm-buildroot-linux-gnueabihf-gfortran#' \\\n\t-e 's#@@CMAKE_SYSTEM_PROCESSOR@@#armv6l#' \\\n\t-e 's#@@TOOLCHAIN_HAS_FORTRAN@@#0#' \\\n\t-e 's#@@CMAKE_BUILD_TYPE@@#Release#' \\\n\t\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/support\/misc\/toolchainfile.cmake.in \\\n\t&gt; \/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross\/share\/buildroot\/toolchainfile.cmake\n\n<\/pre>\n<p style=\"text-align: justify;\">V\u00e9rifions la <em>toolchain<\/em> produite&nbsp;:<\/p>\n<pre>[buildroot-2018.02]$ <strong>cd ..<\/strong>\n[br-tree]$ <strong>ls board\/rpi-3\/cross\/usr\/bin\/<\/strong>\narm-buildroot-linux-gnueabihf-addr2line          arm-linux-as\narm-buildroot-linux-gnueabihf-ar                 arm-linux-c++\narm-buildroot-linux-gnueabihf-as                 arm-linux-c++.br_real\narm-buildroot-linux-gnueabihf-c++                arm-linux-cc\narm-buildroot-linux-gnueabihf-c++.br_real        arm-linux-cc.br_real\narm-buildroot-linux-gnueabihf-cc                 arm-linux-c++filt\narm-buildroot-linux-gnueabihf-cc.br_real         arm-linux-cpp\narm-buildroot-linux-gnueabihf-c++filt            arm-linux-cpp.br_real\narm-buildroot-linux-gnueabihf-cpp                arm-linux-elfedit\narm-buildroot-linux-gnueabihf-cpp.br_real        arm-linux-g++\narm-buildroot-linux-gnueabihf-elfedit            arm-linux-g++.br_real\narm-buildroot-linux-gnueabihf-g++                arm-linux-gcc\narm-buildroot-linux-gnueabihf-g++.br_real        arm-linux-gcc-6.4.0\narm-buildroot-linux-gnueabihf-gcc                arm-linux-gcc-6.4.0.br_real\narm-buildroot-linux-gnueabihf-gcc-6.4.0          arm-linux-gcc-ar\narm-buildroot-linux-gnueabihf-gcc-6.4.0.br_real  arm-linux-gcc.br_real\narm-buildroot-linux-gnueabihf-gcc-ar             arm-linux-gcc-nm\narm-buildroot-linux-gnueabihf-gcc.br_real        arm-linux-gcc-ranlib\narm-buildroot-linux-gnueabihf-gcc-nm             arm-linux-gcov\narm-buildroot-linux-gnueabihf-gcc-ranlib         arm-linux-gcov-dump\narm-buildroot-linux-gnueabihf-gcov               arm-linux-gcov-tool\narm-buildroot-linux-gnueabihf-gcov-dump          arm-linux-gprof\narm-buildroot-linux-gnueabihf-gcov-tool          arm-linux-ld\narm-buildroot-linux-gnueabihf-gprof              arm-linux-ld.bfd\narm-buildroot-linux-gnueabihf-ld                 arm-linux-nm\narm-buildroot-linux-gnueabihf-ld.bfd             arm-linux-objcopy\narm-buildroot-linux-gnueabihf-nm                 arm-linux-objdump\narm-buildroot-linux-gnueabihf-objcopy            arm-linux-ranlib\narm-buildroot-linux-gnueabihf-objdump            arm-linux-readelf\narm-buildroot-linux-gnueabihf-ranlib             arm-linux-size\narm-buildroot-linux-gnueabihf-readelf            arm-linux-strings\narm-buildroot-linux-gnueabihf-size               arm-linux-strip\narm-buildroot-linux-gnueabihf-strings            gawk\narm-buildroot-linux-gnueabihf-strip              igawk\narm-linux-addr2line                              m4\narm-linux-ar                                     toolchain-wrapper\n[br-tree]$<\/pre>\n<p style=\"text-align: justify;\">La <em>toolchain<\/em> de cross-compilation regroupe tous les outils dont les noms sont pr\u00e9fix\u00e9s par l&rsquo;architecture (<code>arm<\/code>), l&rsquo;outil de production (<code>buildroot<\/code>), le syst\u00e8me d&rsquo;exploitation de la cible (<code>linux<\/code>) et les conventions d&rsquo;interfa\u00e7age binaire entre applications et syst\u00e8me (<code>gnueabi<\/code>). Pour simplifier l&rsquo;appel des outils, des liens symboliques existent raccourcissant le pr\u00e9fixe pour ne garder que l&rsquo;architecture et le syst\u00e8me d&rsquo;exploitation. On invoquera donc <code>arm-linux-gcc<\/code> ou <code>arm-linux-g++<\/code> par exemple.<\/p>\n<pre>[br-tree]$ <strong>board\/rpi-3\/cross\/usr\/bin\/arm-linux-gcc -v<\/strong>\nUtilisation des specs internes.\nCOLLECT_GCC=\/home\/testing\/Build\/br-tree\/board\/rpi-3\/cross\/bin\/arm-linux-gcc.br_real\nCOLLECT_LTO_WRAPPER=\/home\/testing\/Build\/br-tree\/board\/rpi-3\/cross\/bin\/..\/libexec\/gcc\/arm-buildroot-linux-gnueabihf\/6.4.0\/lto-wrapper\nCible : arm-buildroot-linux-gnueabihf\nConfigur\u00e9 avec: .\/configure --prefix=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross --sysconfdir=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross\/etc --enable-static --target=arm-buildroot-linux-gnueabihf --with-sysroot=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross\/arm-buildroot-linux-gnueabihf\/sysroot --disable-__cxa_atexit --with-gnu-ld --disable-libssp --disable-multilib --with-gmp=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross --with-mpc=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross --with-mpfr=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross --with-pkgversion='Buildroot 2018.02.7' --with-bugurl=http:\/\/bugs.buildroot.net\/ --disable-libquadmath --enable-tls --disable-libmudflap --enable-threads --without-isl --without-cloog --disable-decimal-float --with-abi=aapcs-linux --with-cpu=cortex-a53 --with-fpu=neon-vfpv4 --with-float=hard --with-mode=arm --enable-languages=c,c++ --with-build-time-tools=\/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/..\/board\/rpi-3\/cross\/arm-buildroot-linux-gnueabihf\/bin --enable-shared --disable-libgomp\nMod\u00e8le de thread: posix\ngcc version 6.4.0 (Buildroot 2018.02.7)<\/pre>\n<p style=\"text-align: justify;\">Si l&rsquo;on souhaite pouvoir invoquer directement le <em>cross-compiler<\/em> depuis la ligne de commande sans pr\u00e9ciser tout le chemin (par exemple pendant une phase de d\u00e9veloppement de code m\u00e9tier hors Buildroot), on peut \u00e9diter le fichier <code>~\/.bashrc<\/code> afin d&rsquo;y ajouter \u00e0 la fin la ligne suivante&nbsp;:<\/p>\n<pre>PATH=$PATH:~\/br-tree\/board\/rpi-3\/cross\/usr\/bin\/<\/pre>\n<p>On peut aussi adopter une autre approche qui consiste \u00e0 cr\u00e9er un script qui modifie dynamiquement le <code>PATH<\/code>, script que l&rsquo;on <em>sourcera<\/em> (que l&rsquo;on invoquera en le pr\u00e9c\u00e9dant d&rsquo;un point) avant chaque session de travail sur le code applicatif.<\/p>\n<h1>Syst\u00e8me complet<\/h1>\n<p style=\"text-align: justify;\">Nous allons construire \u00e0 pr\u00e9sent une image d&rsquo;un syst\u00e8me complet, y compris le noyau, en utilisant la toolchain obtenue pr\u00e9c\u00e9demment. Il nous faut effacer les fichiers objets, fichiers temporaires, etc. produits auparavant et l&rsquo;on serait tent\u00e9 de faire un <code>make clean<\/code>. Abstenons-nous en n\u00e9anmoins car cela aurait pour effet d&rsquo;effacer la <em>toolchain<\/em> compil\u00e9e. La solution la plus simple pour \u00e9viter les erreurs de manipulation est de supprimer le r\u00e9pertoire de compilation de Buildroot et de d\u00e9compresser \u00e0 nouveau l&rsquo;archive t\u00e9l\u00e9charg\u00e9e.<\/p>\n<pre>[br-tree]$ <strong>rm -rf buildroot-2018.02.7<\/strong>\n[br-tree]$ <strong>tar xf buildroot-2018.02.7.tar.bz2<\/strong> \n[br-tree]$ <strong>cd buildroot-2018.02.7\/<\/strong>\n[buildroot-2018.02.7]$<\/pre>\n<p style=\"text-align: justify;\">Puis nous pr\u00e9parons une nouvelle configuration, toujours, en partant de celle par d\u00e9faut.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>make raspberrypi3_defconfig<\/strong>\n[buildroot-2018.02.7]$ <strong>make menuconfig<\/strong><\/pre>\n<p style=\"text-align: justify;\">Passons en revue les menus pour observer ce qu&rsquo;il faut modifier&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Target options<\/code> : rien \u00e0 changer<\/li>\n<li><code>Build options<\/code> :\n<ul>\n<li style=\"text-align: justify;\"><code>Download dir<\/code> : configurons le r\u00e9pertoire de t\u00e9l\u00e9chargement pour retrouver le pr\u00e9c\u00e9dent. Nouvelle valeur&nbsp;: <code>$(TOPDIR)\/..\/dl<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Toolchain<\/code> : plusieurs modifications sont n\u00e9cessaires pour retrouver la <em>toolchain<\/em> pr\u00e9c\u00e9dente.\n<ul>\n<li><code>Toolchain type<\/code> : nous souhaitons que Buildroot consid\u00e8re la <em>toolchain<\/em> comme pr\u00e9existante, m\u00eame si c&rsquo;est lui qui l&rsquo;a cr\u00e9\u00e9e auparavant. Nouvelle valeur&nbsp;: <code>External toolchain<\/code><\/li>\n<li><code>Toolchain<\/code> : elle a \u00e9t\u00e9 compil\u00e9e sp\u00e9cifiquement. Nouvelle valeur&nbsp;: <code>Custom toolchain<\/code><\/li>\n<li><code>Toolchain origin<\/code> : il n&rsquo;est pas n\u00e9cessaire de la t\u00e9l\u00e9charger. Valeur conserv\u00e9e&nbsp;: <code>Pre-installed toolchain<\/code><\/li>\n<li><code>Toolchain path<\/code> : le r\u00e9pertoire dans lequel se trouve le sous-r\u00e9pertoire <code>bin<\/code> de la cha\u00eene de compilation. Nouvelle valeur&nbsp;: <code>$(TOPDIR)\/..\/board\/RPI-3\/cross\/usr<\/code><\/li>\n<li><code>External toolchain gcc version<\/code> : si vous n&rsquo;avez pas not\u00e9 ce num\u00e9ro de version lors de la configuration de la <em>toolchain<\/em>, vous pouvez l&rsquo;obtenir en appelant <code>arm-linux-gcc -v<\/code> comme ci-dessus. Nouvelle valeur&nbsp;: <code>6.x<\/code><\/li>\n<li><code>External toolchain kernel headers series<\/code> : on peut retrouver le num\u00e9ro de version si on ne l&rsquo;a pas not\u00e9, mais c&rsquo;est plus compliqu\u00e9. Il faut regarder le contenu du fichier <code>..\/board\/rpi-3\/cross\/usr\/arm-buildroot-linux-gnueabihf\/sysroot\/usr\/include\/linux\/version.h<\/code>. On y trouve une valeur <code>LINUX_VERSION_CODE 264581<\/code>. Il faut convertir ce nombre en hexad\u00e9cimal, par exemple en saisissant sur la ligne de commande du shell <code>printf '%x\\n' 264581<\/code>. Ceci nous affiche <code>40985<\/code> qui repr\u00e9sente chiffre par chiffre le num\u00e9ro de noyau 4.9.133. Ce sont les deux premiers chiffres qui comptent, le troisi\u00e8me n&rsquo;est pas n\u00e9cessairement le m\u00eame que celui qui sera effectivement s\u00e9lectionn\u00e9 pour compiler le syst\u00e8me complet. Nouvelle valeur&nbsp;: <code>4.9.x<\/code><\/li>\n<li><code>External toolchain C library<\/code> : en tant que biblioth\u00e8que C, nous avons choisi de compiler une GlibC. Nouvelle valeur&nbsp;: <code>glibc\/eglibc<\/code><\/li>\n<li><code>Toolchain has SSP support?<\/code> : l&rsquo;option <em>Stack Smashing Protection<\/em> (qui limite les d\u00e9g\u00e2ts en cas de d\u00e9bordement de buffer dans la pile) est active par d\u00e9faut dans la GCC. Nouvelle valeur&nbsp;: <code>[*]<\/code>.<\/li>\n<li><code>Toolchain has RPC support?<\/code> : le support pour les <em>Remote Procedure Call<\/em> est activ\u00e9 dans la cha\u00eene de compilation produite. Nous pouvons l&rsquo;ajouter ici. Nouvelle valeur&nbsp;: <code>[*]<\/code>.<\/li>\n<li><code>Toolchain has C++ support<\/code> : l&rsquo;int\u00e9gration d&rsquo;un compilateur C++ dans la <em>toolchain<\/em> \u00e9tait activ\u00e9e par d\u00e9faut lors de la compilation pr\u00e9c\u00e9dente. Nouvelle valeur&nbsp;: <code>[*]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\"><code>System Configuration<\/code> : rien \u00e0 changer dans ce menu, mais nous l&rsquo;ajusterons un peu plus tard.<\/li>\n<li><code>Kernel<\/code> : rien \u00e0 changer<\/li>\n<li><code>Target packages<\/code> : rien \u00e0 changer<\/li>\n<li><code>Filesystem images<\/code> : rien \u00e0 changer<\/li>\n<li><code>Bootloaders<\/code> : rien \u00e0 changer<\/li>\n<li><code>Host utilities<\/code> : rien \u00e0 changer<\/li>\n<li><code>Legacy config options<\/code> : rien \u00e0 changer<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">\u00c0 nouveau, sauvegardons notre configuration pour pouvoir la r\u00e9utiliser directement si besoin et lan\u00e7ons la compilation.<\/p>\n<pre>[buildroot-2015.11]$ <strong>cp .config ..\/board\/rpi-3\/buildroot-2018.02-system-01.config<\/strong>\n[buildroot-2015.11]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">La compilation se termine au bout de quelques minutes avec en haut de la page de message une ligne plut\u00f4t surprenante&nbsp;:<\/p>\n<pre>\/usr\/bin\/install -m 0644 support\/misc\/target-dir-warning.txt \/home\/testing\/Build\/br-tree\/buildroot-2018.02.7\/output\/target\/<strong>THIS_IS_NOT_YOUR_ROOT_FILESYSTEM<\/strong>\n[...]\nvfat(boot.vfat): adding file 'rpi-firmware\/fixup.dat' as 'rpi-firmware\/fixup.dat' ...\nvfat(boot.vfat): adding file 'rpi-firmware\/start.elf' as 'rpi-firmware\/start.elf' ...\nvfat(boot.vfat): adding file 'rpi-firmware\/overlays' as 'rpi-firmware\/overlays' ...\nvfat(boot.vfat): adding file 'zImage' as 'zImage' ...\nhdimage(sdcard.img): adding partition 'boot' (in MBR) from 'boot.vfat' ...\nhdimage(sdcard.img): adding partition 'rootfs' (in MBR) from 'rootfs.ext4' ...\nhdimage(sdcard.img): writing MBR\n[buildroot-2018.02.7]<\/pre>\n<p>Mais que signifie donc ce <code>THIS_IS_NOT_YOUR_ROOT_FILESYSTEM<\/code> ?<\/p>\n<p style=\"text-align: justify;\">Il s&rsquo;agit en fait d&rsquo;un nom de fichier, tr\u00e8s anodin. Lorsque Buildroot pr\u00e9pare l&rsquo;arborescence de la cible, il construit une repr\u00e9sentation de son syst\u00e8me de fichiers, qui se trouve dans <code>output\/target<\/code>. Ces fichiers sont cr\u00e9\u00e9s en appartenant \u00e0 l&rsquo;utilisateur courant. Or les fichiers syst\u00e8mes (ceux se trouvant dans les r\u00e9pertoires <code>\/bin<\/code>, <code>\/etc<\/code>, <code>\/usr<\/code>&#8230; de la cible) doivent appartenir \u00e0 <em>root<\/em>. Pour pouvoir produire une image (une archive <code>tar<\/code> par exemple) avec les bonnes appartenances, on fait appel \u00e0 un utilitaire nomm\u00e9 <code>fakeroot<\/code> qui modifie les droits au moment de la cr\u00e9ation de l&rsquo;archive. Pas d&rsquo;inqui\u00e9tude, il n&rsquo;y a rien de malicieux l\u00e0-dessous, aucun probl\u00e8me de s\u00e9curit\u00e9.<\/p>\n<p style=\"text-align: justify;\">Comme le r\u00e9pertoire <code>output\/target<\/code> contient des fichiers n&rsquo;ayant pas la bonne appartenance, il ne faut pas l&rsquo;utiliser aveugl\u00e9ment, ne pas le copier directement sur une cible o\u00f9 l&rsquo;exporter pour un montage NFS <em>root<\/em>. C&rsquo;est ce que Buildroot nous rappelle en cr\u00e9ant ce fameux fichier&nbsp;:<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>ls output\/target\/<\/strong>\nbin  lib      media  proc  sbin                              tmp\ndev  lib32    mnt    root  sys                               usr\netc  linuxrc  opt    run   <strong>THIS_IS_NOT_YOUR_ROOT_FILESYSTEM<\/strong>  var\n[buildroot-2015.11]$<\/pre>\n<h1>Installation et boot<\/h1>\n<p style=\"text-align: justify;\">Depuis quelques versions, l&rsquo;installation de l&rsquo;image sur un Raspberry Pi est devenue beaucoup plus simple puisqu&rsquo;il suffit de copier un simple fichier sur l&rsquo;ensemble de la carte micro-SD.<\/p>\n<p style=\"text-align: justify;\">Avant de faire quoique ce soit, lancez la commande <code>lsblk<\/code> afin de voir la liste des p\u00e9riph\u00e9riques blocs et partitions pr\u00e9sents. En voici un exemple&nbsp;:<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>lsblk<\/strong>\nNAME           MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT\nsda              8:0    0 465,8G  0 disk  \n\u251c\u2500sda1           8:1    0   400G  0 part  \/home\/testing\n\u2514\u2500sda2           8:2    0     8G  0 part  [SWAP]\nnvme0n1        259:0    0 232,9G  0 disk\n\u251c\u2500nvme0n1p1    259:1    0   512M  0 part  \/boot\/efi\n\u251c\u2500nvme0n1p2    259:2    0 224,6G  0 part  \/\n\u2514\u2500nvme0n1p3    259:3    0   7,8G  0 part\n  \u2514\u2500cryptswap1 253:0    0   7,8G  0 crypt\n[buildroot-2018.02.7]$<\/pre>\n<p style=\"text-align: justify;\">Ins\u00e9rons une carte micro-SD sur le poste de d\u00e9veloppement (par exemple avec un adaptateur USB), puis relan\u00e7ons la m\u00eame commande pour voir ce qui est apparu.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>lsblk<\/strong>\nNAME           MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT\nsda              8:0    0 465,8G  0 disk\n\u251c\u2500sda1           8:1    0   400G  0 part  \/home\/testing\n\u2514\u2500sda2           8:2    0     8G  0 part  [SWAP]\n<strong>sdb              8:16   1  14,4G  0 disk\n\u251c\u2500sdb1           8:17   1    32M  0 part  \/media\/cpb\/86B1-7E7E\n\u2514\u2500sdb2           8:18   1   400M  0 part  \/media\/cpb\/68346014-8add-4d95-84f1-1dad224<\/strong>\nnvme0n1        259:0    0 232,9G  0 disk\n\u251c\u2500nvme0n1p1    259:1    0   512M  0 part  \/boot\/efi\n\u251c\u2500nvme0n1p2    259:2    0 224,6G  0 part  \/\n\u2514\u2500nvme0n1p3    259:3    0   7,8G  0 part\n  \u2514\u2500cryptswap1 253:0    0   7,8G  0 crypt\n[buildroot-2018.02.7]$<\/pre>\n<p style=\"text-align: justify;\">Dans cet exemple, il s&rsquo;agit du p\u00e9riph\u00e9rique <code>sdb<\/code>, c&rsquo;est ce que nous utiliserons ci-dessous.<\/p>\n<p style=\"padding-left: 30px; text-align: justify;\"><strong> Attention \u00e0 ne pas vous tromper d&rsquo;identifiant de p\u00e9riph\u00e9rique&nbsp;!<\/strong> cela pourrait \u00eatre dangereux pour votre syst\u00e8me si vous confondez avec votre disque dur par exemple.<\/p>\n<p style=\"text-align: justify;\">Je d\u00e9monte les partitions auto-mont\u00e9es de la carte micro-SD (<code>sdb1<\/code> et <code>sdb2<\/code> dans mon cas). Ceci est indispensable pour s&rsquo;assurer qu&rsquo;il n&rsquo;y aura plus d&rsquo;acc\u00e8s \u00e0 ces emplacements de la carte.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>umount \/dev\/sdb?<\/strong><\/pre>\n<p style=\"text-align: justify;\">Tous les \u00e9l\u00e9ments produits par Buildroot se trouvent dans son arborescence <code>output\/<\/code>. Je m&rsquo;int\u00e9resse \u00e0 <code>output\/images\/<\/code> qui contient les \u00e9l\u00e9ments \u00e0 installer sur le syst\u00e8me cible et plus particuli\u00e8rement \u00e0 <code>output\/images\/sdcard.img<\/code> qui repr\u00e9sente le contenu complet de l&rsquo;image \u00e0 inscrire sur la carte SD.<\/p>\n<p style=\"text-align: justify;\">Il est important de comprendre que ce fichier doit venir \u00e9craser l&rsquo;ensemble des donn\u00e9es de la carte SD, y compris les premiers secteurs contenant la table des partitions. Nous devons donc \u00e9crire <u>sur<\/u> le p\u00e9riph\u00e9rique bloc lui-m\u00eame <code>\/dev\/sdb<\/code> et pas <u>dans<\/u> le syst\u00e8me de fichiers qu&rsquo;il peut contenir.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>sudo cp output\/images\/sdcard.img \/dev\/sdb<\/strong><\/pre>\n<p style=\"text-align: justify;\">La copie dure un petit moment, c&rsquo;est normal, il faut remplir quelques centaines de m\u00e9ga-octets. Pas d&rsquo;inqui\u00e9tude sur la taille de la carte SD, Buildroot n&rsquo;utilise que le minimum vital.<\/p>\n<p style=\"text-align: justify;\">Une fois la copie termin\u00e9e, j&rsquo;ins\u00e8re la carte micro-SD sur un Raspberry Pi 3 auquel je suis reli\u00e9 par une liaison s\u00e9rie avec un c\u00e2ble USB-S\u00e9rie de ce genre (lien Amazon&nbsp;: <a href=\"https:\/\/amzn.to\/2AHKbaH\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/amzn.to\/2AHKbaH<\/a>).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5402\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2018\/11\/usb-serial.jpeg\" alt=\"\" width=\"291\" height=\"128\" \/><\/p>\n<p style=\"text-align: justify;\">J&rsquo;observe les messages suivants \u00e0 la mise sous tension.<\/p>\n<pre>[    0.000000] Booting Linux on physical CPU 0x0\n[    0.000000] Linux version 4.9.79-v7 (cpb@why-cpb) (gcc version 6.4.0 (Buildroot 2018.02.7) ) #1 SMP Sat Nov 3 08:18:16 CET 2018\n[    0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d\n[    0.000000] CPU: div instructions available: patching division code\n[    0.000000] CPU: PIPT \/ VIPT nonaliasing data cache, VIPT aliasing instruction cache\n[    0.000000] OF: fdt:Machine model: Raspberry Pi 3 Model B Rev 1.2\n[    0.000000] cma: Reserved 8 MiB at 0x39400000\n[    0.000000] Memory policy: Data cache writealloc                                                             \n[    0.000000] percpu: Embedded 14 pages\/cpu @b8b91000 s25548 r8192 d23604 u57344                               \n[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 234465                      \n[    0.000000] Kernel command line: 8250.nr_uarts=1 bcm2708_fb.fbwidth=720 bcm2708_fb.fbheight=480 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  root=\/de\nv\/mmcblk0p2 rootwait console=tty1 console=ttyAMA0,115200                                                        \n[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)\n[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)\n[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)\n[    0.000000] Memory: 916004K\/946176K available (7168K kernel code, 485K rwdata, 2012K rodata, 1024K init, 769K bss, 21980K reserved, 8192K cma-reserved)\n[    0.000000] Virtual kernel memory layout:\n[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)\n[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)\n[    0.000000]     vmalloc : 0xba000000 - 0xff800000   (1112 MB)\n[    0.000000]     lowmem  : 0x80000000 - 0xb9c00000   ( 924 MB)\n[    0.000000]     modules : 0x7f000000 - 0x80000000   (  16 MB)\n[    0.000000]       .text : 0x80008000 - 0x80800000   (8160 kB)\n[    0.000000]       .init : 0x80b00000 - 0x80c00000   (1024 kB)\n[    0.000000]       .data : 0x80c00000 - 0x80c797ec   ( 486 kB)\n[    0.000000]        .bss : 0x80c7b000 - 0x80d3b7d4   ( 770 kB)\n[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1\n[    0.000000] Hierarchical RCU implementation.\n[    0.000000]  Build-time adjustment of leaf fanout to 32.\n[    0.000000] NR_IRQS:16 nr_irqs:16 16\n[    0.000000] arm_arch_timer: Architected cp15 timer(s) running at 19.20MHz (phys).\n[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns\n[    0.000006] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns\n[    0.000022] Switching to timer-based delay loop, resolution 52ns\n[    0.000288] Console: colour dummy device 80x30\n[    0.001122] console [tty1] enabled\n[    0.001169] Calibrating delay loop (skipped), value calculated using timer frequency.. 38.40 BogoMIPS (lpj=192000)\n[    0.001235] pid_max: default: 32768 minimum: 301\n[    0.001566] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)\n[    0.001607] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 bytes)\n[    0.002630] Disabling memory control group subsystem\n[    0.002731] CPU: Testing write buffer coherency: ok\n[    0.002793] ftrace: allocating 22277 entries in 66 pages\n[    0.050948] CPU0: update cpu_capacity 1024\n[    0.050998] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000\n[    0.051059] Setting up static identity map for 0x100000 - 0x100034\n[    0.052879] CPU1: update cpu_capacity 1024\n[    0.052886] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001\n[    0.053516] CPU2: update cpu_capacity 1024\n[    0.053523] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002\n[    0.054137] CPU3: update cpu_capacity 1024\n[    0.054144] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003\n[    0.054228] Brought up 4 CPUs\n[    0.054401] SMP: Total of 4 processors activated (153.60 BogoMIPS).\n[    0.054430] CPU: All CPU(s) started in HYP mode.\n[    0.054456] CPU: Virtualization extensions available.\n[    0.055261] devtmpfs: initialized\n[    0.066042] VFP support v0.3: implementor 41 architecture 3 part 40 variant 3 rev 4\n[    0.066355] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns\n[    0.066416] futex hash table entries: 1024 (order: 4, 65536 bytes)\n[    0.066992] pinctrl core: initialized pinctrl subsystem\n[    0.067917] NET: Registered protocol family 16\n[    0.069940] DMA: preallocated 1024 KiB pool for atomic coherent allocations\n[    0.078576] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.\n[    0.078625] hw-breakpoint: maximum watchpoint size is 8 bytes.\n[    0.078800] Serial: AMBA PL011 UART driver\n[    0.080640] bcm2835-mbox 3f00b880.mailbox: mailbox enabled\n[    0.081178] uart-pl011 3f201000.serial: could not find pctldev for node \/soc\/gpio@7e200000\/uart0_pins, deferring probe\n[    0.081525] irq: no irq domain found for \/soc\/aux@0x7e215000 !\n[    0.151767] bcm2835-dma 3f007000.dma: DMA legacy API manager at ba00d000, dmachans=0x1\n[    0.153600] SCSI subsystem initialized\n[    0.153781] usbcore: registered new interface driver usbfs\n[    0.153882] usbcore: registered new interface driver hub\n[    0.153996] usbcore: registered new device driver usb\n[    0.160765] raspberrypi-firmware soc:firmware: Attached to firmware from 2017-09-12 15:21\n[    0.162013] clocksource: Switched to clocksource arch_sys_counter\n[    0.208294] VFS: Disk quotas dquot_6.6.0\n[    0.208404] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)\n[    0.208625] FS-Cache: Loaded\n[    0.208897] CacheFiles: Loaded\n[    0.220915] NET: Registered protocol family 2\n[    0.221805] TCP established hash table entries: 8192 (order: 3, 32768 bytes)\n[    0.221944] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)\n[    0.222202] TCP: Hash tables configured (established 8192 bind 8192)\n[    0.222320] UDP hash table entries: 512 (order: 2, 16384 bytes)\n[    0.222388] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)\n[    0.222616] NET: Registered protocol family 1\n[    0.223044] RPC: Registered named UNIX socket transport module.\n[    0.223076] RPC: Registered udp transport module.\n[    0.223103] RPC: Registered tcp transport module.\n[    0.223130] RPC: Registered tcp NFSv4.1 backchannel transport module.\n[    0.223945] hw perfevents: enabled with armv7_cortex_a7 PMU driver, 7 counters available\n[    0.226226] workingset: timestamp_bits=14 max_order=18 bucket_order=4\n[    0.241938] FS-Cache: Netfs 'nfs' registered for caching\n[    0.242945] NFS: Registering the id_resolver key type\n[    0.242998] Key type id_resolver registered\n[    0.243026] Key type id_legacy registered\n[    0.245378] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)\n[    0.245522] io scheduler noop registered\n[    0.245552] io scheduler deadline registered\n[    0.245851] io scheduler cfq registered (default)\n[    0.251351] BCM2708FB: allocated DMA memory f9510000\n[    0.251402] BCM2708FB: allocated DMA channel 0 @ ba00d000\n[    0.261057] Console: switching to colour frame buffer device 90x30\n[    0.268860] Serial: 8250\/16550 driver, 1 ports, IRQ sharing enabled\n[    0.273794] bcm2835-rng 3f104000.rng: hwrng registered\n[    0.276205] vc-mem: phys_addr:0x00000000 mem_base=0x3ec00000 mem_size:0x40000000(1024 MiB)\n[    0.281384] vc-sm: Videocore shared memory driver\n[    0.298369] brd: module loaded\n[    0.309375] loop: module loaded\n[    0.311728] Loading iSCSI transport class v2.0-870.\n[    0.314688] usbcore: registered new interface driver smsc95xx\n[    0.317156] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)\n[    0.547616] Core Release: 2.80a\n[    0.549961] Setting default values for core params\n[    0.552324] Finished setting default values for core params\n[    0.755025] Using Buffer DMA mode\n[    0.757306] Periodic Transfer Interrupt Enhancement - disabled\n[    0.759652] Multiprocessor Interrupt Enhancement - disabled\n[    0.762061] OTG VER PARAM: 0, OTG VER FLAG: 0\n[    0.764412] Dedicated Tx FIFOs mode\n[    0.766998] WARN::dwc_otg_hcd_init:1032: FIQ DMA bounce buffers: virt = 0xb9504000 dma = 0xf9504000 len=9024\n[    0.771814] FIQ FSM acceleration enabled for :\n[    0.771814] Non-periodic Split Transactions\n[    0.771814] Periodic Split Transactions\n[    0.771814] High-Speed Isochronous Endpoints\n[    0.771814] Interrupt\/Control Split Transaction hack enabled\n[    0.784099] WARN::hcd_init_fiq:459: FIQ on core 1 at 0x80592a54\n[    0.786554] WARN::hcd_init_fiq:460: FIQ ASM at 0x80592db4 length 36\n[    0.788930] WARN::hcd_init_fiq:486: MPHI regs_base at 0xba078000\n[    0.791258] dwc_otg 3f980000.usb: DWC OTG Controller\n[    0.793584] dwc_otg 3f980000.usb: new USB bus registered, assigned bus number 1\n[    0.795944] dwc_otg 3f980000.usb: irq 62, io mem 0x00000000\n[    0.798321] Init: Port Power? op_state=1\n[    0.800631] Init: Power Port (0)\n[    0.803093] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002\n[    0.805451] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1\n[    0.807798] usb usb1: Product: DWC OTG Controller\n[    0.810121] usb usb1: Manufacturer: Linux 4.9.79-v7 dwc_otg_hcd\n[    0.812479] usb usb1: SerialNumber: 3f980000.usb\n[    0.815599] hub 1-0:1.0: USB hub found\n[    0.817889] hub 1-0:1.0: 1 port detected\n[    0.821017] usbcore: registered new interface driver usb-storage\n[    0.823507] mousedev: PS\/2 mouse device common for all mice\n[    0.826695] bcm2835-wdt 3f100000.watchdog: Broadcom BCM2835 watchdog timer\n[    0.829251] bcm2835-cpufreq: min=600000 max=1200000\n[    0.831824] sdhci: Secure Digital Host Controller Interface driver\n[    0.834077] sdhci: Copyright(c) Pierre Ossman\n[    0.836569] sdhost-bcm2835 3f202000.sdhost: could not get clk, deferring probe\n[    0.841075] mmc-bcm2835 3f300000.mmc: could not get clk, deferring probe\n[    0.843585] sdhci-pltfm: SDHCI platform and OF driver helper\n[    0.848605] ledtrig-cpu: registered to indicate activity on CPUs\n[    0.851200] hidraw: raw HID events driver (C) Jiri Kosina\n[    0.853865] usbcore: registered new interface driver usbhid\n[    0.856320] usbhid: USB HID core driver\n[    0.859498] vchiq: vchiq_init_state: slot_zero = 0xb9580000, is_master = 0\n[    0.863318] [vc_sm_connected_init]: start\n[    0.872078] [vc_sm_connected_init]: end - returning 0\n[    0.874879] Initializing XFRM netlink socket\n[    0.877353] NET: Registered protocol family 17\n[    0.879868] Key type dns_resolver registered\n[    0.882529] Registering SWP\/SWPB emulation handler\n[    0.885600] registered taskstats version 1\n[    0.893181] uart-pl011 3f201000.serial: cts_event_workaround enabled\n[    0.895688] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 87, base_baud = 0) is a PL011 rev2\n[    1.842544] console [ttyAMA0] enabled\n[    1.851380] 3f215040.serial: ttyS0 at MMIO 0x0 (irq = 220, base_baud = 50000000) is a 16550\n[    1.865602] sdhost: log_buf @ b9507000 (f9507000)\n[    1.952041] mmc0: sdhost-bcm2835 loaded - DMA enabled (&gt;1)\n[    1.962323] mmc-bcm2835 3f300000.mmc: mmc_debug:0 mmc_debug2:0\n[    1.970764] mmc-bcm2835 3f300000.mmc: DMA channel allocated\n[    1.999575] Indeed it is in host mode hprt0 = 00021501\n[    2.092140] of_cfs_init\n[    2.094394] random: fast init done\n[    2.102985] of_cfs_init: OK\n[    2.108505] uart-pl011 3f201000.serial: no DMA platform data\n[    2.109314] mmc0: host does not support reading read-only switch, assuming write-enable\n[    2.111307] mmc0: new high speed SDHC card at address 0007\n[    2.112173] mmcblk0: mmc0:0007 SD16G 14.4 GiB\n[    2.114015] mmc1: queuing unknown CIS tuple 0x80 (2 bytes)\n[    2.115580] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)\n[    2.117148] mmc1: queuing unknown CIS tuple 0x80 (3 bytes)\n[    2.119952] mmc1: queuing unknown CIS tuple 0x80 (7 bytes)\n[    2.150795]  mmcblk0: p1 p2\n[    2.179804] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities\n[    2.193546] EXT4-fs (mmcblk0p2): couldn't mount as ext2 due to feature incompatibilities\n[    2.210593] mmc1: new high speed SDIO card at address 0001\n[    2.218664] usb 1-1: new high-speed USB device number 2 using dwc_otg\n[    2.228171] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)\n[    2.228226] Indeed it is in host mode hprt0 = 00001101\n[    2.248801] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.\n[    2.259641] devtmpfs: mounted\n[    2.289627] Freeing unused kernel memory: 1024K\n[    2.421684] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered\n[    2.452413] usb 1-1: New USB device found, idVendor=0424, idProduct=9514\n[    2.462164] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0\n[    2.473227] hub 1-1:1.0: USB hub found\nStarting logging: [    2.480116] hub 1-1:1.0: 5 ports detected\nOK\nInitializing random number generator... done.\nStarting network: Waiting for interface eth0 to appear[    2.802056] usb 1-1.1: new high-speed USB device number 3 using dwc_otg\n[    2.932300] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00\n[    2.941753] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0\n[    2.954518] smsc95xx v1.0.5\n[    3.045558] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-3f980000.usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:fa:03:50\n.\n[    3.684451] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup\nudhcpc: started, v1.27.2\nudhcpc: sending discover\nudhcpc: sending discover\nudhcpc: sending discover\nudhcpc: no lease, failing\nFAIL\n\nWelcome to Buildroot\nbuildroot login:<\/pre>\n<p style=\"text-align: justify;\">Il ne faut pas s&rsquo;\u00e9tonner, lorsqu&rsquo;aucun c\u00e2ble n&rsquo;est branch\u00e9 dans la prise Ethernet du Raspberry Pi, la fin du boot est un peu longue. Le service <code>udhcpc<\/code> r\u00e9p\u00e8te ses <code>sending discover<\/code> toutes les trois secondes jusqu&rsquo;\u00e0 renoncer \u00e0 joindre un serveur DHCP et affiche alors le message <code>no lease, failing<\/code>. Le script d&rsquo;initialisation du r\u00e9seau nous indique s\u00e8chement son \u00e9chec d&rsquo;un <code>FAIL<\/code> abrupt.<\/p>\n<p style=\"text-align: justify;\">Nous disposons bien d&rsquo;une invite de login, et pouvons nous connecter&nbsp;:<\/p>\n<pre>buildroot login: <strong>root<\/strong>\n# <strong>uname -a<\/strong>\nLinux buildroot 4.9.79-v7 #1 SMP Sat Nov 3 08:18:16 CET 2018 armv7l GNU\/Linux<\/pre>\n<p style=\"text-align: justify;\">Le noyau correspondant bien \u00e0 la version indiqu\u00e9e plus haut. V\u00e9rifions le processeur du Raspberry Pi 3.<\/p>\n<pre># <strong>cat \/proc\/cpuinfo<\/strong>\nprocessor       : 0\nmodel name      : ARMv7 Processor rev 4 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xd03\nCPU revision    : 4\n\nprocessor       : 1\nmodel name      : ARMv7 Processor rev 4 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xd03\nCPU revision    : 4\n\nprocessor       : 2\nmodel name      : ARMv7 Processor rev 4 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xd03\nCPU revision    : 4\n\nprocessor       : 3\nmodel name      : ARMv7 Processor rev 4 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xd03\nCPU revision    : 4\n\nHardware        : BCM2835\nRevision        : a02082\nSerial          : 000000003efa0350\n#<\/pre>\n<p style=\"text-align: justify;\">Nous avons bien observ\u00e9 les quatre c\u0153urs de processeur du Raspberry Pi 3. Examinons l&rsquo;\u00e9tat de la m\u00e9moire&nbsp;:<\/p>\n<pre># <strong>free<\/strong>\n             total       used       free     shared    buffers     cached\nMem:        925220      15908     909312         40        180       2192\n-\/+ buffers\/cache:      13536     911684\nSwap:            0          0          0\n<\/pre>\n<p style=\"text-align: justify;\">Le syst\u00e8me compte au total un Go (dont une partie est r\u00e9serv\u00e9e pour le contr\u00f4leur graphique) et dispose de 890 Mo de m\u00e9moire libre. En pressant deux fois la touche <em>tabulation<\/em>, nous pouvons voir la liste des commandes disponibles&nbsp;:<\/p>\n<pre># <strong><em>(tab) (tab)<\/em><\/strong>\n[                  fsck               mdev               sha3sum\n[[                 fsfreeze           mesg               sha512sum\naddgroup           fstrim             microcom           shred\nadduser            fuser              mkdir              sleep\nar                 getopt             mkdosfs            sort\narp                getty              mke2fs             start-stop-daemon\narping             grep               mkfifo             strings\nash                gunzip             mknod              stty\nawk                gzip               mkpasswd           su\nbasename           halt               mkswap             sulogin\nblkid              hdparm             mktemp             svc\nbunzip2            head               modprobe           swapoff\nbusybox            hexdump            more               swapon\nbzcat              hostid             mount              switch_root\ncat                hostname           mountpoint         sync\nchattr             hwclock            mt                 sysctl\nchgrp              i2cdetect          mv                 syslogd\nchmod              i2cdump            nameif             tail\nchown              i2cget             netstat            tar\nchroot             i2cset             nice               tee\nchrt               id                 nl                 telnet\nchvt               ifconfig           nohup              test\ncksum              ifdown             nproc              tftp\nclear              ifup               nslookup           time\ncmp                inetd              od                 top\ncp                 init               openvt             touch\ncpio               insmod             partprobe          tr\ncrond              install            passwd             traceroute\ncrontab            ip                 paste              true\ncut                ipaddr             patch              truncate\ndate               ipcrm              pidof              tty\ndc                 ipcs               ping               ubirename\ndd                 iplink             pipe_progress      udhcpc\ndeallocvt          ipneigh            pivot_root         uevent\ndelgroup           iproute            poweroff           umount\ndeluser            iprule             printenv           uname\ndevmem             iptunnel           printf             uniq\ndf                 kill               ps                 unix2dos\ndiff               killall            pwd                unlink\ndirname            killall5           rdate              unlzma\ndmesg              klogd              readlink           unlzop\ndnsd               last               readprofile        unxz\ndnsdomainname      less               realpath           unzip\ndos2unix           link               reboot             uptime\ndu                 linux32            renice             usleep\ndumpkmap           linux64            reset              uudecode\necho               ln                 resize             uuencode\negrep              loadfont           rm                 vconfig\neject              loadkmap           rmdir              vi\nenv                logger             rmmod              vlock\nether-wake         login              route              w\nexpr               logname            run-parts          watch\nfactor             losetup            runlevel           watchdog\nfallocate          ls                 sed                wc\nfalse              lsattr             seq                wget\nfbset              lsmod              setarch            which\nfdflush            lsof               setconsole         who\nfdformat           lspci              setkeycodes        whoami\nfdisk              lsscsi             setlogcons         xargs\nfgrep              lsusb              setpriv            xxd\nfind               lzcat              setserial          xz\nflock              lzma               setsid             xzcat\nfold               lzopcat            sh                 yes\nfree               makedevs           sha1sum            zcat\nfreeramdisk        md5sum             sha256sum\n#<\/pre>\n<p style=\"text-align: justify;\">La commande <code>ps<\/code> nous affiche la liste des processus pr\u00e9sents&nbsp;:<\/p>\n<pre># <strong>ps<\/strong>\nPID   USER     COMMAND\n    1 root     init\n    2 root     [kthreadd]\n    3 root     [ksoftirqd\/0]\n    4 root     [kworker\/0:0]\n    5 root     [kworker\/0:0H]\n    6 root     [kworker\/u8:0]\n    7 root     [rcu_sched]\n    8 root     [rcu_bh]\n    9 root     [migration\/0]\n   10 root     [lru-add-drain]\n   11 root     [cpuhp\/0]\n   12 root     [cpuhp\/1]\n   13 root     [migration\/1]\n   14 root     [ksoftirqd\/1]\n   15 root     [kworker\/1:0]\n   16 root     [kworker\/1:0H]\n   17 root     [cpuhp\/2]\n   18 root     [migration\/2]\n   19 root     [ksoftirqd\/2]\n   21 root     [kworker\/2:0H]\n   22 root     [cpuhp\/3]\n   23 root     [migration\/3]\n   24 root     [ksoftirqd\/3]\n   25 root     [kworker\/3:0]\n   26 root     [kworker\/3:0H]\n   27 root     [kdevtmpfs]\n   28 root     [netns]\n   29 root     [khungtaskd]\n   30 root     [oom_reaper]\n   31 root     [writeback]\n   32 root     [kcompactd0]\n   33 root     [crypto]\n   34 root     [bioset]\n   35 root     [kblockd]\n   36 root     [watchdogd]\n   37 root     [kworker\/0:1]\n   38 root     [rpciod]\n   39 root     [xprtiod]\n   40 root     [kswapd0]\n   41 root     [vmstat]\n   42 root     [nfsiod]\n   52 root     [kthrotld]\n   53 root     [bioset]\n   54 root     [bioset]\n   55 root     [bioset]\n   56 root     [bioset]\n   57 root     [bioset]\n   58 root     [bioset]\n   59 root     [bioset]\n   60 root     [bioset]\n   61 root     [bioset]\n   62 root     [bioset]\n   63 root     [bioset]\n   64 root     [bioset]\n   65 root     [bioset]\n   66 root     [bioset]\n   67 root     [bioset]\n   68 root     [bioset]\n   69 root     [bioset]\n   70 root     [bioset]\n   71 root     [bioset]\n   72 root     [bioset]\n   73 root     [bioset]\n   74 root     [bioset]\n   75 root     [bioset]\n   76 root     [bioset]\n   77 root     [iscsi_eh]\n   78 root     [dwc_otg]\n   79 root     [kworker\/2:1]\n   80 root     [DWC Notificatio]\n   81 root     [VCHIQ-0]\n   82 root     [VCHIQr-0]\n   83 root     [VCHIQs-0]\n   84 root     [VCHIQka-0]\n   85 root     [SMIO]\n   87 root     [kworker\/2:2]\n   88 root     [kworker\/1:1]\n   89 root     [kworker\/3:2]\n   90 root     [irq\/92-mmc1]\n   92 root     [bioset]\n   93 root     [mmcqd\/0]\n   94 root     [kworker\/0:1H]\n   95 root     [jbd2\/mmcblk0p2-]\n   96 root     [ext4-rsv-conver]\n  112 root     \/sbin\/syslogd -n\n  115 root     \/sbin\/klogd -n\n  117 root     [kworker\/2:1H]\n  152 root     [kworker\/u8:1]\n  154 root     -sh\n  155 root     \/sbin\/getty -L tty1 0 vt100\n  160 root     [kworker\/2:0]\n  161 root     ps\n#<\/pre>\n<p style=\"text-align: justify;\">Hormis les threads du noyau (toutes les t\u00e2ches avec des noms entre crochets), nous observons la pr\u00e9sence de seulement six processus&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>init<\/code> : le premier processus qui est charg\u00e9 d&rsquo;abord de l&rsquo;initialisation du syst\u00e8me depuis l&rsquo;espace utilisateur et par la suite de \u00ab\u00a0l&rsquo;adoption\u00a0\u00bb des processus dont le parent se termine&nbsp;;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>syslogd<\/code> et <code>klogd<\/code> : d\u00e9mons charg\u00e9s de l&rsquo;enregistrement des messages du syst\u00e8me&nbsp;;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>getty<\/code> : l&rsquo;outil qui attend les connexions sur le terminal <code>tty1<\/code> (\u00e9cran HDMI + clavier USB), je suis connect\u00e9 sur la console s\u00e9rie et le <code>getty<\/code> correspondant a laiss\u00e9 sa place au shell&nbsp;;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\"><code>sh<\/code> le shell sur lequel nous sommes connect\u00e9s et la commande <code>ps<\/code> elle-m\u00eame.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Voil\u00e0 un syst\u00e8me dont le contenu est bien sous contr\u00f4le&nbsp;!<\/p>\n<h1>Affinement de la configuration<\/h1>\n<p style=\"text-align: justify;\">Nous pouvons faire une premi\u00e8re s\u00e9rie d&rsquo;am\u00e9liorations, afin d&rsquo;obtenir un syst\u00e8me un peu plus convivial, accueillant un autre utilisateur que <em>root<\/em> par exemple ou renfor\u00e7ant la partition principale contre les risques de coupures d&rsquo;alimentation intempestives.<\/p>\n<h2>Configuration de Buildroot<\/h2>\n<pre>[buildroot-2018.02.7]$ <strong>make menuconfig<\/strong><\/pre>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Menu <code>System configuration<\/code> :\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>System hostname<\/code>: Choisissons un nom plus repr\u00e9sentatif pour notre carte. Il appara\u00eetra par exemple dans l&rsquo;invite de connexion, et nous l&rsquo;afficherons \u00e9galement dans le <em>prompt<\/em> du shell. Nouvelle valeur&nbsp;: <code>R-Pi<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>System banner<\/code> : Cette petite phrase s&rsquo;affichera au d\u00e9marrage avant la proposition de connexion&nbsp;; on peut la personnaliser \u00e0 volont\u00e9. Nouvelle valeur&nbsp;: <code>Welcome on board!<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Enable root login with password<\/code> : Si le syst\u00e8me a la moindre chance de se retrouver connect\u00e9 \u00e0 Internet, il est pr\u00e9f\u00e9rable de d\u00e9sactiver cette option. En effet le compte <em>root<\/em> sera le premier vis\u00e9 par les attaques automatiques par force brute. Si cette option est d\u00e9sactiv\u00e9e, il faudra int\u00e9grer la commande <code>sudo<\/code> afin de pouvoir r\u00e9aliser les op\u00e9rations d&rsquo;administration. Sur un syst\u00e8me exp\u00e9rimental, nous laissons la valeur originale&nbsp;: <code>[*]<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Root password<\/code> : De m\u00eame, il est conseill\u00e9 de choisir pour tous les comptes des mots de passe solides (<a href=\"https:\/\/xkcd.com\/936\/\" target=\"_blank\" rel=\"noopener noreferrer\">longs, assez faciles \u00e0 retenir mais difficiles \u00e0 deviner<\/a>). Pour cette d\u00e9monstration prenons un mot de passe ridiculement simple. Nouvelle valeur <code>root<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>remount root filesystem read-write during boot<\/code> : Sur un syst\u00e8me embarqu\u00e9 o\u00f9 l&rsquo;alimentation peut \u00eatre coup\u00e9e \u00e0 tout moment, il est conseill\u00e9 de conserver le syst\u00e8me de fichiers principal en lecture-seule. On le basculera en lecture-\u00e9criture temporairement pour des modifications de configuration par exemple. Nouvelle valeur&nbsp;: <code>[ ]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Network interface to configure through DHCP<\/code> : Suivant la configuration, on utilisera ou non une configuration r\u00e9seau par DHCP. Si tel est le cas, on indique ici le nom de l&rsquo;interface Ethernet, laissant donc la valeur&nbsp;: <code>eth0<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><code>Path to the users tables<\/code> : On indique ici le chemin d&rsquo;acc\u00e8s pour un fichier contenant la liste des utilisateurs (voir plus loin). Nouvelle valeur&nbsp;: <code>$(TOPDIR)\/..\/board\/rpi-3\/users.tbl<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\"><code>Root filesystem overlay directories<\/code> : Le r\u00e9pertoire indiqu\u00e9 ici est l&rsquo;origine d&rsquo;une arborescence qui sera appliqu\u00e9e \u00ab\u00a0par-dessus\u00a0\u00bb le syst\u00e8me de fichiers obtenu \u00e0 l&rsquo;issue des compilations et installations, avant de pr\u00e9parer l&rsquo;image de sortie. Autrement dit notre arborescence va venir se superposer (rempla\u00e7ant \u00e9ventuellement des fichiers) \u00e0 celle se trouvant dans <code>output\/target<\/code> avant de la stocker dans <code>output\/image\/rootfs.tar<\/code>. Nous d\u00e9taillerons plus loin ce qu&rsquo;il faut ajouter dans cet overlay. Nouvelle valeur&nbsp;: <code>$(TOPDIR)\/..\/board\/rpi-3\/ovl<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Table des utilisateurs<\/h2>\n<p style=\"text-align: justify;\">Nous avons rempli l&rsquo;option <code>Path to the users tables<\/code> avec le nom d&rsquo;un fichier qui contient la liste des utilisateurs. Il doit y avoir un compte par ligne. Les champs, s\u00e9par\u00e9s par un espace, sont les suivants&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>login<\/em> : identifiant de connexion du compte (sauf <em>root<\/em>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>uid<\/em> : num\u00e9ro d&rsquo;utilisateur. On peut indiquer <code>-1<\/code> pour que l&rsquo;attribution soit automatique, mais nous aurons besoin un peu plus loin d&rsquo;une UID connue, je pr\u00e9cise donc <code>1000<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>group<\/em> : groupe principal de l&rsquo;utilisateur. G\u00e9n\u00e9ralement le m\u00eame nom que le <em>login<\/em>, ou alors un groupe global pour tous les comptes, comme <code>users<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>gid<\/em> : num\u00e9ro du groupe. Comme pour le champ <em>uid<\/em>, je pr\u00e9cise <code>1000<\/code> pour conna\u00eetre \u00e0 l&rsquo;avance le num\u00e9ro de groupe.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>password<\/em> : le mot de passe, en clair si pr\u00e9c\u00e9d\u00e9 d&rsquo;un &lsquo;<code>=<\/code>&lsquo;, crypt\u00e9 sinon. Si le mot de passe est &lsquo;<code>!<\/code>&lsquo;, pas de connexion possible (compte utilis\u00e9 pour un d\u00e9mon syst\u00e8me par exemple).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>home<\/em> : r\u00e9pertoire personnel (aucun si &lsquo;<code>-<\/code>&lsquo;).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>shell<\/em> : le shell de connexion. Sur notre syst\u00e8me minimal, <code>\/bin\/sh<\/code> est un shell <em>ash<\/em> inclus dans Busybox.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\"><em>groups<\/em> : ce champ contient la liste des groupes suppl\u00e9mentaires auxquels appartient l&rsquo;utilisateur (<code>-1<\/code> si aucun).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\"><em>gecos<\/em> : des informations sur le compte, comme le nom en clair de l&rsquo;utilisateur. Ce dernier champ peut contenir \u00e9ventuellement des espaces.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Voici notre fichier <code>..\/board\/rpi-3\/users.tbl<\/code> :<\/p>\n<pre>rpi 1000 rpi 1000 =rpi \/home\/rpi \/bin\/sh - Raspberry Pi User<\/pre>\n<h2>Overlay<\/h2>\n<p style=\"text-align: justify;\">Comme indiqu\u00e9 plus haut nous nous cr\u00e9ons une arborescence sp\u00e9cifique, contenant des fichiers qui viendront s&rsquo;ajouter \u00e0 ceux produits par Buildroot.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>mkdir -p ..\/board\/rpi-3\/ovl\/usr\/bin\/<\/strong><\/pre>\n<h3>Scripts suppl\u00e9mentaires<\/h3>\n<p style=\"text-align: justify;\">Le syst\u00e8me de fichiers principal est mont\u00e9 en lecture seule. Mais il est parfois n\u00e9cessaire de repasser temporairement en lecture-\u00e9criture. Pour cela j&rsquo;ai l&rsquo;habitude de cr\u00e9er deux petits scripts <code>rw<\/code> et <code>ro<\/code> qui remontent la racine du syst\u00e8me de fichiers respectivement en lecture-\u00e9criture ou lecture seule. Pour que Buildroot puisse les int\u00e9grer automatiquement dans l&rsquo;image qu&rsquo;il produit, nous les pla\u00e7ons dans l&rsquo;arborescence <em>overlay<\/em> :<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>nano ..\/board\/rpi-3\/ovl\/usr\/bin\/rw<\/strong><\/pre>\n<p style=\"text-align: justify;\">Contenu du script <code>rw<\/code><\/p>\n<pre>#! \/bin\/sh\n\nmount \/ -o rw,remount<\/pre>\n<pre>[buildroot-2018.02.7]$ <strong>cp ..\/board\/rpi-3\/ovl\/usr\/bin\/rw ..\/board\/rpi-3\/ovl\/usr\/bin\/ro<\/strong>\n[buildroot-2018.02.7]$ <strong>nano ..\/board\/rpi-3\/ovl\/usr\/local\/bin\/ro<\/strong><\/pre>\n<p style=\"text-align: justify;\">Contenu du script <code>ro<\/code><\/p>\n<pre>#! \/bin\/sh\n\nmount \/ -o ro,remount<\/pre>\n<pre>[buildroot-2018.02.7]$ <strong>chmod +x ..\/board\/rpi-3\/ovl\/usr\/bin\/*<\/strong><\/pre>\n<p style=\"text-align: justify;\">Lan\u00e7ons la nouvelle compilation<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">Nous r\u00e9-ins\u00e9rons la carte micro-SD dans le PC de d\u00e9veloppement et re-flashons l&rsquo;image.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>umount \/dev\/sdb?<\/strong>\n[buildroot-2018.02.7]$ <strong>sudo cp output\/images\/sdcard.img \/dev\/sdb<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s red\u00e9marrage du Raspberry Pi, v\u00e9rifions la connexion avec l&rsquo;identit\u00e9 <em>root<\/em> :<\/p>\n<pre>Welcome on board!\nR-Pi login: <strong>root<\/strong>\nPassword: <strong>(root)<\/strong>\n#<\/pre>\n<p style=\"text-align: justify;\">V\u00e9rifions tout de suite si le syst\u00e8me de fichiers est bien mont\u00e9 en lecture seulement.<\/p>\n<pre># <strong>ls \/<\/strong>\nbin         lib         media       root        tmp\ndev         lib32       mnt         run         usr\netc         linuxrc     opt         sbin        var\nhome        lost+found  proc        sys\n# <strong>echo hello &gt; \/test-file<\/strong>\n-sh: can't create \/test-file: Read-only file system<\/pre>\n<p style=\"text-align: justify;\">Tr\u00e8s bien. V\u00e9rifions qu&rsquo;il soit possible de passer temporairement en lecture-\u00e9criture.<\/p>\n<pre># <strong>rw<\/strong>\n[   86.847490] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered\n# <strong>echo hello &gt; \/test-file<\/strong>\n# <strong>ls \/<\/strong>\nbin         lib         media       root        <strong>test-file<\/strong>\ndev         lib32       mnt         run         tmp\netc         linuxrc     opt         sbin        usr\nhome        lost+found  proc        sys         var\n# <strong>ro<\/strong>\n[  116.742951] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered\n# <strong>rm \/test-file<\/strong>\nrm: remove '\/test-file'? <strong>y<\/strong>\nrm: can't remove '\/test-file': Read-only file system\n# <strong>exit<\/strong><\/pre>\n<p style=\"text-align: justify;\">La protection du syst\u00e8me est donc correcte. V\u00e9rifions l&rsquo;acc\u00e8s en tant qu&rsquo;utilisateur normal.<\/p>\n<pre>Welcome on board!\nR-Pi login: <strong>rpi<\/strong>\nPassword: <strong>(rpi)<\/strong>\n$ <strong>pwd<\/strong>\n\/home\/rpi\n$ <strong>ls<\/strong>\n$ <strong>echo hello &gt; my-file<\/strong>\n-sh: can't create my-file: Read-only file system\n$<\/pre>\n<p style=\"text-align: justify;\">Ici, un petit probl\u00e8me se pose. La partition \u00ab\u00a0syst\u00e8me\u00a0\u00bb de notre Raspberry Pi est bien prot\u00e9g\u00e9e contre les \u00e9critures, mais nous aimerions peut-\u00eatre disposer de possibilit\u00e9s de stockage de donn\u00e9es utilisateur. Pour cela il va falloir envisager l&rsquo;ajout d&rsquo;une partition suppl\u00e9mentaire mont\u00e9e en lecture-\u00e9criture<\/p>\n<h1>Nouvelles am\u00e9liorations<\/h1>\n<p style=\"text-align: justify;\">Nous allons donc ajouter une nouvelle partition, format\u00e9e en <code>vfat<\/code>, afin de contenir les donn\u00e9es utilisateur. Comme j&rsquo;en ai parl\u00e9 dans <a href=\"http:\/\/www.blaess.fr\/christophe\/2015\/10\/19\/renforcer-une-distribution-raspbian-jessie\/#vfat\">cet article<\/a>, le format <code>vfat<\/code> est beaucoup plus simple que les traditionnels <code>ext4<\/code> et consorts, mais il r\u00e9siste bien \u00e0 des coupures d&rsquo;alimentations pendant une \u00e9criture.<\/p>\n<p style=\"text-align: justify;\">Il faut indiquer la pr\u00e9sence de cette partition dans le fichier <code>\/etc\/fstab<\/code>. Nous allons copier le fichier original produit par Buildroot dans notre <em>overlay<\/em> et lui ajouter une derni\u00e8re ligne.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>mkdir  -p  ..\/board\/rpi-3\/ovl\/etc<\/strong>\n[buildroot-2018.02.7]$ <strong>cp output\/target\/etc\/fstab ..\/board\/rpi-3\/ovl\/etc\/<\/strong>\n[buildroot-2018.02.7]$ <strong>nano ..\/board\/rpi-3\/ovl\/etc\/fstab<\/strong><\/pre>\n<p>Le fichier est modifi\u00e9 ainsi (derni\u00e8re ligne ajout\u00e9e)<\/p>\n<pre>\/dev\/root       \/               ext2    rw,noauto       0       1\nproc            \/proc           proc    defaults        0       0\ndevpts          \/dev\/pts        devpts  defaults,gid=5,mode=620 0       0\ntmpfs           \/dev\/shm        tmpfs   mode=0777       0       0\ntmpfs           \/tmp            tmpfs   mode=1777       0       0\ntmpfs           \/run            tmpfs   mode=0755,nosuid,nodev  0       0\nsysfs           \/sys            sysfs   defaults        0       0\n<strong>\/dev\/mmcblk0p3  \/home       vfat    defaults,uid=1000,gid=1000  0 0<\/strong><\/pre>\n<p style=\"text-align: justify;\">Pour cr\u00e9er les partitions et l&rsquo;image <code>sdcard.img<\/code> finale, Buildroot appelle le script <code>board\/raspberrypi3\/post-image.sh<\/code> (indiqu\u00e9 dans l&rsquo;option \u00ab\u00a0<em>Custom scripts to run after creating filesystem images<\/em>\u00a0\u00bb du menu \u00ab\u00a0<em>System configuration<\/em>\u00ab\u00a0). Ce script fait appel \u00e0 un utilitaire nomm\u00e9 <code>genimage<\/code> en lui passant le fichier de configuration <code>board\/raspberrypi3\/genimage-raspberrypi3.cfg<\/code>.<\/p>\n<p style=\"text-align: justify;\">Pour \u00e9viter de modifier un fichier fourni par Buildroot, nous pourrions copier le script et le fichier de configuration dans notre r\u00e9pertoire, les modifier \u00e0 cet endroit, et fournir notre version dans l&rsquo;option \u00ab\u00a0<em>Custom scripts to run after creating filesystem images<\/em>\u00ab\u00a0. Pour garder cet article relativement simple, je vais modifier directement le fichier de configuration <code>genimage-raspberrypi3.cfg<\/code>.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>nano board\/raspberrypi3\/genimage-raspberrypi3.cfg<\/strong><\/pre>\n<p>Le fichier est modifi\u00e9 (lignes ajout\u00e9es en gras) pour devenir&nbsp;:<\/p>\n<pre>image boot.vfat {\n  vfat {\n    files = {\n      \"bcm2710-rpi-3-b.dtb\",\n      \"bcm2710-rpi-cm3.dtb\",\n      \"rpi-firmware\/bootcode.bin\",\n      \"rpi-firmware\/cmdline.txt\",\n      \"rpi-firmware\/config.txt\",\n      \"rpi-firmware\/fixup.dat\",\n      \"rpi-firmware\/start.elf\",\n      \"rpi-firmware\/overlays\",\n      \"zImage\"\n    }\n  }\n  size = 32M\n}\n\n<strong>image home.vfat {\n  name = \"home.vfat\"\n  vfat { \n    files = { }\n  }\n  size = 128M\n  mountpoint = \"\/home\"\n}<\/strong>\n\nimage sdcard.img {\n  hdimage {\n  }\n\n  partition boot {\n    partition-type = 0xC\n    bootable = \"true\"\n    image = \"boot.vfat\"\n  }\n\n  partition rootfs {\n    partition-type = 0x83\n    image = \"rootfs.ext4\"\n  }\n\n  <strong>partition home {\n    partition-type = 0xC\n    image  = \"home.vfat\"\n  }<\/strong>\n}\n<\/pre>\n<p style=\"text-align: justify;\">Recompilons notre syst\u00e8me, et r\u00e9inscrivons-le sur la carte SD.<\/p>\n<pre>[buildroot-2018.02.7]$ <strong>make<\/strong>\n[buildroot-2018.02.7]$ <strong>umount \/dev\/sdb?<\/strong>\n[buildroot-2018.02.7]$ <strong>sudo cp output\/images\/sdcard.img \/dev\/sdb<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s d\u00e9marrage du Raspberry Pi, nous pouvons v\u00e9rifier que l&rsquo;utilisateur <code>rpi<\/code> a bien acc\u00e8s \u00e0 son r\u00e9pertoire personnel en lecture et \u00e9criture.<\/p>\n<pre>Welcome on board!\nR-Pi login: <strong>rpi<\/strong>\nPassword: <strong>(<em>rpi<\/em>)<\/strong>\n$ <strong>echo 1 &gt; my-file<\/strong>\n$ <strong>ls -l<\/strong>\ntotal 2\n-rwxr-xr-x    1 rpi      rpi              2 Jan  1 00:00 my-file\n$ <strong>exit<\/strong><\/pre>\n<p style=\"text-align: justify;\">V\u00e9rifions aussi que la partition syst\u00e8me est bien en lecture seulement, m\u00eame pour l&rsquo;utilisateur <code>root<\/code>.<\/p>\n<pre>Welcome on board!\nR-Pi login: <strong>root<\/strong>\nPassword: <strong>(<em>root<\/em>)<\/strong>\n# <strong>echo 1 &gt; my-file<\/strong>\n-sh: can't create my-file: Read-only file system\n#<\/pre>\n<p style=\"text-align: justify;\">Bien entendu, <code>root<\/code> peut appeler notre commande <code>rw<\/code> s&rsquo;il souhaite vraiment modifier un fichier de l&rsquo;arborescence syst\u00e8me.<\/p>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">Nous disposons ainsi d&rsquo;un syst\u00e8me Linux embarqu\u00e9 minimal assez personnalis\u00e9. Bien s\u00fbr il faudra ajouter de nombreux outils pour avoir un v\u00e9ritable environnement de travail complet, citons par exemple le serveur SSH Dropbear, un serveur web comme celui de Busybox ou Lighttp, un client NTP, etc. Nous verrons cela dans de prochains articles.<\/p>","protected":false},"excerpt":{"rendered":"<p>[Une version plus r&eacute;cente de cet article est disponible ici] Le projet Buildroot nous fournit d&eacute;sormais une version de travail trimestrielle et une version annuelle maintenue sur le long terme. Buildroot permet de construire un syst&egrave;me embarqu&eacute; plus traditionnel qu&rsquo;en utilisant une distribution pr&eacute;-compil&eacute;e, et d&rsquo;ajuster plus finement son contenu. Nous allons l&rsquo;utiliser pour construire [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,5,8,11],"tags":[],"class_list":["post-4405","post","type-post","status-publish","format-standard","hentry","category-actualite","category-embarque","category-linux-2","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4405","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=4405"}],"version-history":[{"count":65,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4405\/revisions"}],"predecessor-version":[{"id":5626,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4405\/revisions\/5626"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=4405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=4405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=4405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}