{"id":5368,"date":"2015-12-08T06:09:16","date_gmt":"2015-12-08T05:09:16","guid":{"rendered":"https:\/\/www.blaess.fr\/christophe\/?p=5368"},"modified":"2019-03-06T00:57:48","modified_gmt":"2019-03-05T23:57:48","slug":"creation-dun-systeme-avec-buildroot-2015-11","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2015\/12\/08\/creation-dun-systeme-avec-buildroot-2015-11\/","title":{"rendered":"Cr\u00e9ation d&rsquo;un syst\u00e8me avec Buildroot 2015.11"},"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>Cette copie d&rsquo;un ancien article est ici \u00e0 titre de r\u00e9f\u00e9rence. Je vous conseille de lire plut\u00f4t <a href=\"https:\/\/www.blaess.fr\/christophe\/2015\/12\/08\/creation-dun-systeme-complet-avec-buildroot\/\">la version mise \u00e0 jour<\/a>.]<\/p>\n<p style=\"text-align: justify;\">Il y a quelques jours, la livraison trimestrielle de <a href=\"http:\/\/buildroot.uclibc.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Buildroot<\/a> a rendu disponible une version <a href=\"http:\/\/buildroot.uclibc.org\/downloads\/buildroot-2015.11.tar.bz2\" target=\"_blank\" rel=\"noopener noreferrer\">2015.11<\/a>. J&rsquo;ai voulu l&rsquo;essayer en construisant un petit syst\u00e8me pour Raspberry Pi 2. et partager cette exp\u00e9rience qui viendra ainsi en compl\u00e9ment de <a href=\"http:\/\/www.blaess.fr\/christophe\/2015\/10\/19\/renforcer-une-distribution-raspbian-jessie\/\">mon article pr\u00e9c\u00e9dent<\/a>. 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.<\/p>\n<p>\n<!--more-->\n<\/p>\n<p style=\"text-align: justify;\">Nous allons successivement pr\u00e9parer une cha\u00eene de compilation crois\u00e9e, 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\u00e9es 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 2 uniquement). Tous nos fichiers personnalis\u00e9s se trouveront dans cette sous-arborescence.<\/p>\n<pre>[br-tree]$ <strong>mkdir -p board\/raspberrypi2\/<\/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-2015.11.tar.bz2\">http:\/\/www.buildroot.org\/downloads\/buildroot-2015.11.tar.bz2<\/a><\/strong>\n[br-tree]$ <strong>tar xjf buildroot-2015.11.tar.bz2<\/strong>\n[br-tree]$ <strong>cd buildroot-2015.11\/<\/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 compilation crois\u00e9e. 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 2).<\/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 (environ vingt minutes sur un PC portable moyen avec une connexion Internet ADSL correcte). 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\/&lt;target&gt;\/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&nbsp;:<\/p>\n<pre>[buildroot-2015.11]$ <strong>make raspberrypi2_defconfig<\/strong>\n[buildroot-2015.11]$ <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\/raspberrypi2\/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<\/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<\/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=\"text-align: justify;\">Menu <strong><code>Filesystem images<\/code><\/strong> :\n<ul>\n<li><code>tar the 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<p style=\"text-align: justify;\">Sauvegardons la configuration et lan\u00e7ons la compilation&nbsp;:<\/p>\n<pre>[buildroot-2015.11]$ <strong>cp .config ..\/board\/raspberrypi2\/buildroot-01.cfg<\/strong>\n[buildroot-2015.11]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s quelques minutes, la compilation se termine avec ces lignes&nbsp;:<\/p>\n<pre>( \\\n\t\techo \"NAME=Buildroot\"; \\\n\t\techo \"VERSION=2015.11\"; \\\n\t\techo \"ID=buildroot\"; \\\n\t\techo \"VERSION_ID=2015.11\"; \\\n\t\techo \"PRETTY_NAME=\\\"Buildroot 2015.11\\\"\" \\\n\t) &gt;  \/home\/cpb\/br-tree\/buildroot-2015.11\/output\/target\/etc\/os-release<\/pre>\n<p style=\"text-align: justify;\">Attention, des messages alarmants apparaissent auparavant (des fichiers inexistants, un octet magique incorrect, etc.), c&rsquo;est parfaitement normal puisque nous n&rsquo;avons pas cr\u00e9\u00e9 de syst\u00e8me de fichiers.<\/p>\n<p style=\"text-align: justify;\">V\u00e9rifions la <em>toolchain<\/em> produite&nbsp;:<\/p>\n<pre>[buildroot-2015.11]$ <strong>cd ..<\/strong>\n[br-tree]$ <strong>ls board\/raspberrypi2\/cross\/usr\/bin\/<\/strong>\narm-buildroot-linux-gnueabihf-addr2line          arm-linux-c++\narm-buildroot-linux-gnueabihf-ar                 arm-linux-c++.br_real\narm-buildroot-linux-gnueabihf-as                 arm-linux-cc\narm-buildroot-linux-gnueabihf-c++                arm-linux-cc.br_real\narm-buildroot-linux-gnueabihf-c++.br_real        arm-linux-c++filt\narm-buildroot-linux-gnueabihf-cc                 arm-linux-cpp\narm-buildroot-linux-gnueabihf-cc.br_real         arm-linux-cpp.br_real\narm-buildroot-linux-gnueabihf-c++filt            arm-linux-elfedit\narm-buildroot-linux-gnueabihf-cpp                arm-linux-g++\narm-buildroot-linux-gnueabihf-cpp.br_real        arm-linux-g++.br_real\narm-buildroot-linux-gnueabihf-elfedit            arm-linux-gcc\narm-buildroot-linux-gnueabihf-g++                arm-linux-gcc-4.9.3\narm-buildroot-linux-gnueabihf-g++.br_real        arm-linux-gcc-4.9.3.br_real\narm-buildroot-linux-gnueabihf-gcc                arm-linux-gcc-ar\narm-buildroot-linux-gnueabihf-gcc-4.9.3          arm-linux-gcc.br_real\narm-buildroot-linux-gnueabihf-gcc-4.9.3.br_real  arm-linux-gcc-nm\narm-buildroot-linux-gnueabihf-gcc-ar             arm-linux-gcc-ranlib\narm-buildroot-linux-gnueabihf-gcc.br_real        arm-linux-gcov\narm-buildroot-linux-gnueabihf-gcc-nm             arm-linux-gprof\narm-buildroot-linux-gnueabihf-gcc-ranlib         arm-linux-ld\narm-buildroot-linux-gnueabihf-gcov               arm-linux-ld.bfd\narm-buildroot-linux-gnueabihf-gprof              arm-linux-nm\narm-buildroot-linux-gnueabihf-ld                 arm-linux-objcopy\narm-buildroot-linux-gnueabihf-ld.bfd             arm-linux-objdump\narm-buildroot-linux-gnueabihf-nm                 arm-linux-ranlib\narm-buildroot-linux-gnueabihf-objcopy            arm-linux-readelf\narm-buildroot-linux-gnueabihf-objdump            arm-linux-size\narm-buildroot-linux-gnueabihf-ranlib             arm-linux-strings\narm-buildroot-linux-gnueabihf-readelf            arm-linux-strip\narm-buildroot-linux-gnueabihf-size               gawk\narm-buildroot-linux-gnueabihf-strings            igawk\narm-buildroot-linux-gnueabihf-strip              m4\narm-linux-addr2line                              mkknlimg\narm-linux-ar                                     toolchain-wrapper\narm-linux-as\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 \u00e0 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\/raspberrypi2\/cross\/usr\/bin\/arm-linux-gcc -v<\/strong>\nUtilisation des specs internes.\nCOLLECT_GCC=\/home\/cpb\/br-tree\/board\/raspberrypi2\/cross\/usr\/bin\/arm-linux-gcc.br_real\nCOLLECT_LTO_WRAPPER=\/home\/cpb\/br-tree\/board\/raspberrypi2\/cross\/usr\/bin\/..\/libexec\/gcc\/arm-buildroot-linux-gnueabihf\/4.9.3\/lto-wrapper\nTarget: arm-buildroot-linux-gnueabihf\nConfigur\u00e9 avec: .\/configure --prefix=\/home\/cpb\/br-tree\/buildroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/usr --sysconfdir=\/home\/cpb\/br-\ntree\/buildroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/etc --enable-static --target=arm-buildroot-linux-gnueabihf --with-sysroot=\/home\/\ncpb\/br-tree\/buildroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/usr\/arm-buildroot-linux-gnueabihf\/sysroot --disable-__cxa_atexit --with-g\nnu-ld --disable-libssp --disable-multilib --with-gmp=\/home\/cpb\/br-tree\/buildroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/usr --with-mpf\nr=\/home\/cpb\/br-tree\/buildroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/usr --with-pkgversion='Buildroot 2015.11' --with-bugurl=http:\/\/bu\ngs.buildroot.net\/ --disable-libquadmath --enable-tls --disable-libmudflap --enable-threads --with-mpc=\/home\/cpb\/br-tree\/buildroot-20\n15.11\/..\/board\/raspberrypi2\/cross\/\/usr --without-isl --without-cloog --disable-decimal-float --with-abi=aapcs-linux --with-cpu=corte\nx-a7 --with-fpu=neon-vfpv4 --with-float=hard --with-mode=arm --enable-languages=c,c++ --with-build-time-tools=\/home\/cpb\/br-tree\/buil\ndroot-2015.11\/..\/board\/raspberrypi2\/cross\/\/usr\/arm-buildroot-linux-gnueabihf\/bin --enable-shared --disable-libgomp\nMod\u00e8le de thread: posix\ngcc version 4.9.3 (Buildroot 2015.11)<\/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\/raspberrypi2\/cross\/usr\/bin\/<\/pre>\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>[buildroot-2015.11]$ <strong>cd ..<\/strong>\n[br-tree]$ <strong>rm -rf buildroot-2015.11<\/strong>\n[br-tree]$ <strong>tar xjf buildroot-2015.11.tar.bz2<\/strong>\n[br-tree]$ <strong>cd buildroot-2015.11<\/strong><\/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-2015.11]$ <strong>make raspberrypi2_defconfig<\/strong>\n[buildroot-2015.11]$ <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\/rapsberrypi2\/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>4.9.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\/raspberrypi2\/cross\/usr\/arm-buildroot-linux-gnueabihf\/sysroot\/usr\/include\/linux\/version.h<\/code>. On y trouve une valeur <code>LINUX_VERSION_CODE 262405<\/code>. Il faut convertir ce nombre en hexad\u00e9cimal, par exemple en saisissant sur la ligne de commande du shell <code>printf '%x\\n' 262405<\/code>. Ceci nous affiche <code>40105<\/code> qui repr\u00e9sente le num\u00e9ro de noyau 4.1.5. Nouvelle valeur&nbsp;: <code>4.1.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 C++ support<\/code> : cette option \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> : pour l&rsquo;instant nous ne changeons pratiquement rien dans ce menu, mais nous l&rsquo;ajusterons un peu plus tard.\n<ul>\n<li><code>[*] Run a getty (login prompt) after boot ---&gt;<\/code> : Je pr\u00e9f\u00e8re me connecter au Raspberry Pi 2 en utilisant la console s\u00e9rie (comme sur la plupart des syst\u00e8mes embarqu\u00e9s que je configure) plut\u00f4t que l&rsquo;\u00e9cran HDMI et le clavier USB. Je modifie en cons\u00e9quence le param\u00e8tre suivant&nbsp;:\n<ul>\n<li><code>TTY port<\/code> : j&rsquo;indique le port s\u00e9rie du Raspberry Pi 2. Nouvelle valeur&nbsp;: <code>ttyAMA0<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/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\/raspberrypi2\/buildroot-02.cfg<\/strong>\n[buildroot-2015.11]$ <strong>make<\/strong><\/pre>\n<p style=\"text-align: justify;\">La compilation se termine au bout de quelques minutes sur un message plut\u00f4t surprenant&#8230;<\/p>\n<pre>\/br-tree\/buildroot-2015.11\/output\/build\/_fakeroot.fs\nrootdir=\/home\/cpb\/br-tree\/buildroot-2015.11\/output\/target\ntable='\/home\/cpb\/br-tree\/buildroot-2015.11\/output\/build\/_device_table.txt'\n\/usr\/bin\/install -m 0644 support\/misc\/target-dir-warning.txt \/home\/cpb\/br-tree\/buildroot-2015.11\/output\/ta\nrget\/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM\n[buildroot-2015.11]<\/pre>\n<p>Mais que signifie donc ce THIS_IS_NOT_YOUR_ROOT_FILESYSTEM&nbsp;?<\/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-2015.11]$ <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;\">Ins\u00e9rons une carte micro-SD sur le poste de d\u00e9veloppement (par exemple avec un adaptateur USB). On recherche alors le nom du p\u00e9riph\u00e9rique bloc qu&rsquo;elle repr\u00e9sente.<\/p>\n<pre>[buildroot-2015.11]$ <strong>dmesg | tail<\/strong>\n[21924.805390] sd 5:0:0:0: [sdc] No Caching mode page found\n[21924.805395] sd 5:0:0:0: [sdc] Assuming drive cache: write through\n[21924.805400] sd 5:0:0:0: [sdc] Attached SCSI removable disk\n[21926.017065] EXT4-fs (sdc2): recovery complete\n[21926.020278] EXT4-fs (sdc2): mounted filesystem with ordered data mode. Opts: (null)<\/pre>\n<p style=\"text-align: justify;\">Dans cet exemple, il s&rsquo;agit du p\u00e9riph\u00e9rique <code>sdc<\/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 et j&rsquo;efface compl\u00e8tement ses premiers secteurs.<\/p>\n<pre>[buildroot-2015.11]$ <strong>umount \/dev\/sdc?<\/strong>\n[buildroot-2015.11]$ <strong>sudo dd if=\/dev\/zero of=\/dev\/sdc bs=1M count=16<\/strong>\n16+0 enregistrements lus\n16+0 enregistrements \u00e9crits\n16777216 octets (17 MB) copi\u00e9s, 3,82191 s, 4,4 MB\/s<\/pre>\n<p style=\"text-align: justify;\">Partitionnons la carte pour obtenir&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">Une premi\u00e8re partition bootable au format <em>Dos Vfat<\/em> : ici j&rsquo;ai choisi une taille de 128 Mo pour pouvoir faire des exp\u00e9riences avec des noyaux suppl\u00e9mentaires, U-boot, etc. En r\u00e9alit\u00e9 une partition de 16 Mo suffira largement.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\">Une seconde partition au format Linux s&rsquo;\u00e9tendant sur le reste de la carte micro-SD.<\/li>\n<\/ul>\n<pre>[buildroot-2015.11]$ <strong>sudo fdisk \/dev\/sdc<\/strong>\n  [...]\nCommande (m pour l'aide) : <strong>n<\/strong>\nPartition type:\n   p   primary (0 primary, 0 extended, 4 free)\n   e   extended\nSelect (default p):<strong><em>(Entr\u00e9e)<\/em><\/strong>\nNum\u00e9ro de partition (1-4, 1 par d\u00e9faut) : <strong><em>(Entr\u00e9e)<\/em><\/strong>\nPremier secteur (2048-7741439, 2048 par d\u00e9faut) : <strong><em>(Entr\u00e9e)<\/em><\/strong>\nDernier secteur, +secteurs ou +taille{K,M,G} (2048-7741439, 7741439 par d\u00e9faut) : <strong>+128M<\/strong>\nCommande (m pour l'aide) : <strong>t<\/strong>\nPartition s\u00e9lectionn\u00e9e 1\nCode Hexa (taper L pour lister les codes): <strong>c<\/strong>\nType syst\u00e8me de partition modifi\u00e9 de 1 \u00e0 c (W95 FAT32 (LBA))\nCommande (m pour l'aide) : <strong>n<\/strong>\nPartition type:\n   p   primary (1 primary, 0 extended, 3 free)\n   e   extended\nSelect (default p): <strong><em>(Entr\u00e9e)<\/em><\/strong>\nNum\u00e9ro de partition (1-4, 2 par d\u00e9faut) : <strong><em>(Entr\u00e9e)<\/em><\/strong>\nPremier secteur (264192-7741439, 264192 par d\u00e9faut) : <strong><em>(Entr\u00e9e)<\/em><\/strong>\nDernier secteur, +secteurs ou +taille{K,M,G} (264192-7741439, 7741439 par d\u00e9faut) : <strong><em>(Entr\u00e9e)<\/em><\/strong>\nCommande (m pour l'aide) : <strong>a<\/strong>\nNum\u00e9ro de partition (1-4): <strong>1<\/strong>\nCommande (m pour l'aide) : <strong>p<\/strong>\n[...]\nP\u00e9riph\u00e9rique Amor\u00e7age  D\u00e9but         Fin      Blocs    Id. Syst\u00e8me\n\/dev\/sdc1   *        2048      264191      131072    c  W95 FAT32 (LBA)\n\/dev\/sdc2          264192     7741439     3738624   83  Linux\nCommande (m pour l'aide) : <strong>w<\/strong>\n  [...]\n[buildroot-2015.11]$<\/pre>\n<p style=\"text-align: justify;\">Nous formatons les deux partitions, l&rsquo;une au format <code>vfat<\/code> (le seul format connu par le <em>firmware<\/em> du Raspberry Pi 2 qui doit charger en m\u00e9moire le <em>bootloader<\/em>), la seconde au format classique Linux <code>ext2<\/code>. L&rsquo;absence de journalisation des donn\u00e9es dans ce format permet de limiter l&rsquo;usure des cartes flash en \u00e9vitant les \u00e9critures suppl\u00e9mentaires. Je nomme classiquement mes partitions <code>BOOT<\/code> et <code>ROOT<\/code> afin de les identifier ais\u00e9ment.<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo mkfs.vfat -n BOOT \/dev\/sdc1<\/strong>\n[buildroot-2015.11]$ <strong>sudo mkfs.ext2 -L ROOT \/dev\/sdc2<\/strong><\/pre>\n<p style=\"text-align: justify;\">Extrayons \u00e0 pr\u00e9sent la carte micro-SD et r\u00e9ins\u00e9rons-la afin que l&rsquo;auto-monteur nous donne un acc\u00e8s imm\u00e9diat aux partitions.<\/p>\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 en particulier \u00e0 <code>output\/images\/<\/code> qui contient les \u00e9l\u00e9ments \u00e0 installer sur le syst\u00e8me cible.<\/p>\n<p style=\"text-align: justify;\">Nous allons copier sur la premi\u00e8re partition&nbsp;:<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"text-align: justify;\">les fichiers du <em>bootloader<\/em> du Raspberry Pi 2, pr\u00e9compil\u00e9s et propri\u00e9taires, que Buildroot \u00e0 t\u00e9l\u00e9charg\u00e9s et copi\u00e9s dans <code>output\/images\/rpi-firmware<\/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;\">le fichier <code>dtb<\/code> (<em>Device Tree Blob<\/em>) qui contient la description du mat\u00e9riel permettant l&rsquo;utilisation d&rsquo;un noyau g\u00e9n\u00e9rique.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"text-align: justify;\">le noyau <code>zImage<\/code>, que nous ne copions pas directement mais installons par l&rsquo;interm\u00e9diaire de l&rsquo;utilitaire <code>mkknlimg<\/code> qui lui ajoute un suffixe indiquant qu&rsquo;il contient le support du <em>Device Tree<\/em>.<\/li>\n<\/ul>\n<pre>[buildroot-2015.11]$ <strong>ls output\/images\/<\/strong>\nbcm2709-rpi-2-b.dtb  rootfs.tar  rpi-firmware  zImage\n[buildroot-2015.11]$ <strong>sudo cp output\/images\/bcm2709-rpi-2-b.dtb  \/media\/cpb\/BOOT\/<\/strong>\n[buildroot-2015.11]$ <strong>sudo cp output\/images\/rpi-firmware\/*  \/media\/cpb\/BOOT\/<\/strong>\n[buildroot-2015.11]$ <strong>sudo .\/output\/host\/usr\/bin\/mkknlimg  output\/images\/zImage  \/media\/cpb\/BOOT\/zImage<\/strong>\nVersion: Linux version 4.1.5-v7 (cpb@Logilin) (gcc version 4.9.3 (Buildroot 2015.11) ) #1 SMP PREEMPT Wed Dec 2 13:38:15 CET 2015\nDT: y\nDDT: n\n283x: n<\/pre>\n<p>Pour voir les traces de boot du noyau sur le port s\u00e9rie du Raspberry Pi 2, nous \u00e9ditons le fichier <code>cmdline.txt<\/code> se trouvant dans la partition BOOT, et ajoutons sur la premi\u00e8re ligne (attention, il ne doit y avoir qu&rsquo;une seule ligne dans ce fichier) la cha\u00eene de caract\u00e8res suivante <code>console=ttyAMA0,115200<\/code>.<\/p>\n<p>Sur la seconde partition, nous d\u00e9compressons toute l&rsquo;archive <code>tar<\/code> produite par Buildroot. Pour que les appartenances des fichiers soient correctement respect\u00e9es, il est n\u00e9cessaire de le faire avec les droits <em>root<\/em>. Ensuite nous d\u00e9montons proprement les deux partitions.<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo tar xf output\/images\/rootfs.tar  -C \/media\/cpb\/ROOT\/<\/strong>\n[buildroot-2015.11]$ <strong>umount \/media\/cpb\/*<\/strong><\/pre>\n<p>J&rsquo;ins\u00e8re la carte micro-SD sur un Raspberry Pi 2 auquel je suis reli\u00e9 par une liaison s\u00e9rie, et j&rsquo;observe les messages suivants \u00e0 la mise sous tension.<\/p>\n<pre>Uncompressing Linux... done, booting the kernel.                                                                                                         \n[    0.832142] Switched to clocksource arch_sys_counter                                                                                                   \n[    0.888108] FS-Cache: Loaded                                                                                                                           \n[    0.891365] CacheFiles: Loaded\n[    0.906112] NET: Registered protocol family 2\n[    0.911787] TCP established hash table entries: 8192 (order: 3, 32768 bytes)\n[    0.919008] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)\n[    0.925674] TCP: Hash tables configured (established 8192 bind 8192)\n[    0.932165] UDP hash table entries: 512 (order: 2, 16384 bytes)\n[    0.938130] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)\n[    0.944853] NET: Registered protocol family 1\n[    0.949645] RPC: Registered named UNIX socket transport module.\n[    0.955646] RPC: Registered udp transport module.\n[    0.960346] RPC: Registered tcp transport module.\n[    0.965063] RPC: Registered tcp NFSv4.1 backchannel transport module.\n[    0.972612] hw perfevents: enabled with armv7_cortex_a7 PMU driver, 5 counters available\n[    0.982104] futex hash table entries: 1024 (order: 4, 65536 bytes)\n[    1.004416] VFS: Disk quotas dquot_6.6.0\n[    1.008720] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)\n[    1.018425] FS-Cache: Netfs 'nfs' registered for caching\n[    1.024905] NFS: Registering the id_resolver key type\n[    1.030011] Key type id_resolver registered\n[    1.034264] Key type id_legacy registered\n[    1.041110] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)\n[    1.048794] io scheduler noop registered\n[    1.052810] io scheduler deadline registered\n[    1.057414] io scheduler cfq registered (default)\n[    1.064669] BCM2708FB: allocated DMA memory f8800000\n[    1.069667] BCM2708FB: allocated DMA channel 0 @ f3007000\n[    1.081887] Console: switching to colour frame buffer device 90x30\n[    1.092405] Serial: 8250\/16550 driver, 0 ports, IRQ sharing disabled\n[    1.099985] vc-cma: Videocore CMA driver\n[    1.103939] vc-cma: vc_cma_base      = 0x00000000\n[    1.108636] vc-cma: vc_cma_size      = 0x00000000 (0 MiB)\n[    1.114048] vc-cma: vc_cma_initial   = 0x00000000 (0 MiB)\n[    1.119688] vc-mem: phys_addr:0x00000000 mem_base=0x3dc00000 mem_size:0x3f000000(1008 MiB)\n[    1.143850] brd: module loaded\n[    1.156001] loop: module loaded\n[    1.160180] vchiq: vchiq_init_state: slot_zero = 0xb8880000, is_master = 0\n[    1.168931] Loading iSCSI transport class v2.0-870.\n[    1.174819] usbcore: registered new interface driver smsc95xx\n[    1.180646] dwc_otg: version 3.00a 10-AUG-2012 (platform bus)\n[    1.386775] Core Release: 2.80a\n[    1.389922] Setting default values for core params\n[    1.394786] Finished setting default values for core params\n[    1.600754] Using Buffer DMA mode\n[    1.604091] Periodic Transfer Interrupt Enhancement - disabled\n[    1.609915] Multiprocessor Interrupt Enhancement - disabled\n[    1.615500] OTG VER PARAM: 0, OTG VER FLAG: 0\n[    1.619856] Dedicated Tx FIFOs mode\n[    1.623734] WARN::dwc_otg_hcd_init:1047: FIQ DMA bounce buffers: virt = 0xb8814000 dma = 0xf8814000 len=9024\n[    1.633612] FIQ FSM acceleration enabled for :\n[    1.633612] Non-periodic Split Transactions\n[    1.633612] Periodic Split Transactions\n[    1.633612] High-Speed Isochronous Endpoints\n[    1.650386] WARN::hcd_init_fiq:412: FIQ on core 1 at 0x80413218\n[    1.656305] WARN::hcd_init_fiq:413: FIQ ASM at 0x80413588 length 36\n[    1.662569] WARN::hcd_init_fiq:438: MPHI regs_base at 0xb909a000\n[    1.668603] dwc_otg 3f980000.usb: DWC OTG Controller\n[    1.673680] dwc_otg 3f980000.usb: new USB bus registered, assigned bus number 1\n[    1.681016] dwc_otg 3f980000.usb: irq 32, io mem 0x00000000\n[    1.686653] Init: Port Power? op_state=1\n[    1.690569] Init: Power Port (0)\n[    1.694101] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002\n[    1.700890] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1\n[    1.708137] usb usb1: Product: DWC OTG Controller\n[    1.712863] usb usb1: Manufacturer: Linux 4.1.5-v7 dwc_otg_hcd\n[    1.718692] usb usb1: SerialNumber: 3f980000.usb\n[    1.724204] hub 1-0:1.0: USB hub found\n[    1.728005] hub 1-0:1.0: 1 port detected\n[    1.732954] usbcore: registered new interface driver usb-storage\n[    1.739227] mousedev: PS\/2 mouse device common for all mice\n[    1.745700] bcm2835-cpufreq: min=600000 max=900000\n[    1.750865] sdhci: Secure Digital Host Controller Interface driver\n[    1.757068] sdhci: Copyright(c) Pierre Ossman\n[    1.761869] mmc-bcm2835 3f300000.mmc: mmc_debug:0 mmc_debug2:0\n[    1.767728] mmc-bcm2835 3f300000.mmc: DMA channels allocated\n[    1.812493] sdhci-pltfm: SDHCI platform and OF driver helper\n[    1.824209] ledtrig-cpu: registered to indicate activity on CPUs\n[    1.830499] hidraw: raw HID events driver (C) Jiri Kosina\n[    1.837286] usbcore: registered new interface driver usbhid\n[    1.843977] usbhid: USB HID core driver\n[    1.849291] Initializing XFRM netlink socket\n[    1.853703] NET: Registered protocol family 17\n[    1.861673] Key type dns_resolver registered\n[    1.866448] Registering SWP\/SWPB emulation handler\n[    1.872248] registered taskstats version 1\n[    1.876594] vc-sm: Videocore shared memory driver\n[    1.881301] [vc_sm_connected_init]: start\n[    1.886168] [vc_sm_connected_init]: end - returning 0\n[    1.892592] uart-pl011 3f201000.uart: no DMA platform data\n[    1.898409] Waiting for root device \/dev\/mmcblk0p2...\n[    1.903640] mmc0: host does not support reading read-only switch, assuming write-enable\n[    1.913753] mmc0: new high speed SDHC card at address b368\n[    1.919832] mmcblk0: mmc0:b368 SMI   3.69 GiB \n[    1.924456] Indeed it is in host mode hprt0 = 00021501\n[    1.942943]  mmcblk0: p1 p2\n[    2.013559] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities\n[    2.022462] EXT4-fs (mmcblk0p2): mounting ext2 file system using the ext4 subsystem\n[    2.042841] EXT4-fs (mmcblk0p2): mounted filesystem without journal. Opts: (null)\n[    2.050390] VFS: Mounted root (ext2 filesystem) readonly on device 179:2.\n[    2.065487] devtmpfs: mounted\n[    2.069355] Freeing unused kernel memory: 424K (80788000 - 807f2000)\n[    2.102224] usb 1-1: new high-speed USB device number 2 using dwc_otg\n[    2.108947] Indeed it is in host mode hprt0 = 00001101\n[    2.297336] EXT4-fs (mmcblk0p2): warning: mounting unchecked fs, running e2fsck is recommended\n[    2.312601] usb 1-1: New USB device found, idVendor=0424, idProduct=9514\n[    2.319306] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0\n[    2.327381] hub 1-1:1.0: USB hub found\n[    2.331252] hub 1-1:1.0: 5 ports detected\n[    2.368084] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)\nStarting logging: OK\nInitializing random number generator... [    2.505165] random: dd urandom read with 59 bits of entropy available\ndone.\nStarting network...\n[    2.612233] usb 1-1.1: new high-speed USB device number 3 using dwc_otg\nWelcome to Buildroot\nbuildroot login: [    2.732562] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00\n[    2.739446] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0\n[    2.750075] smsc95xx v1.0.4\n[    2.816413] smsc95xx 1-1.1:1.0 eth0: register 'smsc95xx' at usb-3f980000.usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:ff:aa:a8<\/pre>\n<p style=\"text-align: justify;\">En fait, le boot du noyau est bien termin\u00e9. Il a d\u00e9j\u00e0 affich\u00e9 un message de bienvenue et une invite de connexion. N\u00e9anmoins le contr\u00f4leur USB a mis du temps \u00e0 d\u00e9marrer et de nouvelles traces ont \u00e9t\u00e9 affich\u00e9es, masquant la r\u00e9ussite du d\u00e9marrage. Il faut appuyer sur <em>Entr\u00e9e<\/em> pour que le syst\u00e8me nous r\u00e9-affiche son <em>prompt<\/em> de connexion.<\/p>\n<pre>Welcome to Buildroot\nbuildroot login: <strong>root<\/strong>\n# <strong>uname -a<\/strong>\nLinux buildroot 4.1.5-v7 #1 SMP PREEMPT Wed Dec 2 13:38:15 CET 2015 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 Pi2.<\/p>\n<pre># <strong>cat \/proc\/cpuinfo<\/strong>\nprocessor       : 0\nmodel name      : ARMv7 Processor rev 5 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xc07\nCPU revision    : 5\n\nprocessor       : 1\nmodel name      : ARMv7 Processor rev 5 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xc07\nCPU revision    : 5\n\nprocessor       : 2\nmodel name      : ARMv7 Processor rev 5 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xc07\nCPU revision    : 5\n\nprocessor       : 3\nmodel name      : ARMv7 Processor rev 5 (v7l)\nBogoMIPS        : 38.40\nFeatures        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm \nCPU implementer : 0x41\nCPU architecture: 7\nCPU variant     : 0x0\nCPU part        : 0xc07\nCPU revision    : 5\n\nHardware        : BCM2709\nRevision        : a01041\nSerial          : 00000000f0ff000\n#<\/pre>\n<p style=\"text-align: justify;\">Nous avons bien observ\u00e9 les quatre c\u0153urs de processeur du Raspberry Pi 2. Examinons l&rsquo;\u00e9tat de la m\u00e9moire&nbsp;:<\/p>\n<pre># <strong>free<\/strong>\n             total       used       free     shared    buffers     cached\nMem:        911512      18156     893356         40       1948       2128\n-\/+ buffers\/cache:      14080     897432\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 897 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[                  flock              lzcat              sha256sum\n[[                 fold               lzma               sha3sum\naddgroup           free               makedevs           sha512sum\nadduser            freeramdisk        md5sum             sleep\nar                 fsck               mdev               sort\narp                fstrim             mesg               start-stop-daemon\narping             fuser              microcom           strings\nash                getopt             mkdir              stty\nawk                getty              mkfifo             su\nbasename           grep               mknod              sulogin\nblkid              gunzip             mkswap             swapoff\nbunzip2            gzip               mktemp             swapon\nbusybox            halt               modprobe           switch_root\nbzcat              hdparm             more               sync\ncat                head               mount              sysctl\ncatv               hexdump            mountpoint         syslogd\nchattr             hostid             mt                 tail\nchgrp              hostname           mv                 tar\nchmod              hwclock            nameif             tee\nchown              i2cdetect          netstat            telnet\nchroot             i2cdump            nice               test\nchrt               i2cget             nohup              tftp\nchvt               i2cset             nslookup           time\ncksum              id                 od                 top\nclear              ifconfig           openvt             touch\ncmp                ifdown             passwd             tr\ncp                 ifup               patch              traceroute\ncpio               inetd              pidof              true\ncrond              init               ping               truncate\ncrontab            insmod             pipe_progress      tty\ncut                install            pivot_root         udhcpc\ndate               ip                 poweroff           uevent\ndc                 ipaddr             printenv           umount\ndd                 ipcrm              printf             uname\ndeallocvt          ipcs               ps                 uniq\ndelgroup           iplink             pwd                unix2dos\ndeluser            iproute            rdate              unlink\ndevmem             iprule             readlink           unlzma\ndf                 iptunnel           readprofile        unxz\ndiff               kill               realpath           unzip\ndirname            killall            reboot             uptime\ndmesg              killall5           renice             usleep\ndnsd               klogd              reset              uudecode\ndnsdomainname      last               resize             uuencode\ndos2unix           less               rm                 vconfig\ndu                 linux32            rmdir              vi\ndumpkmap           linux64            rmmod              vlock\necho               ln                 route              watch\negrep              loadfont           run-parts          watchdog\neject              loadkmap           runlevel           wc\nenv                logger             sed                wget\nether-wake         login              seq                which\nexpr               logname            setarch            who\nfalse              losetup            setconsole         whoami\nfbset              ls                 setkeycodes        xargs\nfdflush            lsattr             setlogcons         xz\nfdformat           lsmod              setserial          xzcat\nfdisk              lsof               setsid             yes\nfgrep              lspci              sh                 zcat\nfind               lsusb              sha1sum\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_preempt]\n    8 root     [rcu_sched]\n    9 root     [rcu_bh]\n   10 root     [migration\/0]\n   11 root     [migration\/1]\n   12 root     [ksoftirqd\/1]\n   14 root     [kworker\/1:0H]\n   15 root     [migration\/2]\n   16 root     [ksoftirqd\/2]\n   17 root     [kworker\/2:0]\n   18 root     [kworker\/2:0H]\n   19 root     [migration\/3]\n   20 root     [ksoftirqd\/3]\n   21 root     [kworker\/3:0]\n   22 root     [kworker\/3:0H]\n   23 root     [khelper]\n   24 root     [kdevtmpfs]\n   25 root     [netns]\n   26 root     [perf]\n   27 root     [khungtaskd]\n   28 root     [writeback]\n   29 root     [crypto]\n   30 root     [bioset]\n   31 root     [kblockd]\n   32 root     [kworker\/1:1]\n   33 root     [rpciod]\n   34 root     [kswapd0]\n   35 root     [fsnotify_mark]\n   36 root     [nfsiod]\n   42 root     [kthrotld]\n   43 root     [kworker\/0:1]\n   44 root     [VCHIQ-0]\n   45 root     [VCHIQr-0]\n   46 root     [VCHIQs-0]\n   47 root     [iscsi_eh]\n   48 root     [dwc_otg]\n   49 root     [DWC Notificatio]\n   51 root     [VCHIQka-0]\n   52 root     [SMIO]\n   53 root     [deferwq]\n   54 root     [kworker\/u8:2]\n   55 root     [mmcqd\/0]\n   56 root     [kworker\/0:1H]\n   57 root     [ext4-rsv-conver]\n   58 root     [kworker\/1:1H]\n   59 root     [kworker\/1:2]\n   60 root     [kworker\/2:1]\n   69 root     [kworker\/2:1H]\n   71 root     \/sbin\/syslogd -n\n   74 root     \/sbin\/klogd -n\n   93 root     [kworker\/3:1]\n  145 root     [kworker\/0:2]\n  149 root     -sh\n  153 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 cinq 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 les parents se terminent&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=\"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-2015.11]$ <strong>make menuconfig<\/strong><\/pre>\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. Nouvelle 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\/raspberrypi2\/users.cfg<\/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\/raspberrypi2\/ovl<\/code>.<\/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=\"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. <code>-1<\/code> pour que l&rsquo;attribution soit automatique.<\/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. <code>-1<\/code> pour une attribution automatique.<\/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<p style=\"text-align: justify;\">Voici notre fichier <code>..\/board\/raspberrypi2\/users.cfg<\/code> :<\/p>\n<pre>rpi -1 rpi -1 =rpi \/home\/rpi \/bin\/sh - Raspberry Pi 2 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-2015.11]$ <strong>mkdir -p ..\/board\/raspberrypi2\/ovl\/usr\/local\/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-2015.11]$ <strong>nano ..\/board\/raspberrypi2\/ovl\/usr\/local\/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-2015.11]$ <strong>cp ..\/board\/raspberrypi2\/ovl\/usr\/local\/bin\/rw ..\/board\/raspberrypi2\/ovl\/usr\/local\/bin\/ro<\/strong>\n[buildroot-2015.11]$ <strong>nano ..\/board\/raspberrypi2\/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-2015.11]$ <strong>chmod +x ..\/board\/raspberrypi2\/ovl\/usr\/local\/bin\/*<\/strong><\/pre>\n<p style=\"text-align: justify;\">Lan\u00e7ons la nouvelle compilation<\/p>\n<pre>[buildroot-2015.11]$ <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.Seule la partition <em>ROOT<\/em> doit \u00eatre modifi\u00e9e.<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo rm -rf \/media\/cpb\/ROOT\/*<\/strong>\n[buildroot-2015.11]$ <strong>sudo tar xf output\/images\/rootfs.tar -C \/media\/cpb\/ROOT\/<\/strong>\n[buildroot-2015.11]$ <strong>sudo umount \/media\/cpb\/*<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s red\u00e9marrage du Raspberry Pi 2, 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      etc      lib      linuxrc  mnt      proc     run      sys      usr\ndev      home     lib32    media    opt      root     sbin     tmp      var\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-sh: rw: not found\n# <strong>\/usr\/local\/bin\/rw<\/strong>\n[  287.714995] EXT4-fs (mmcblk0p2): warning: mounting unchecked fs, running e2fsck is recommended\n[  287.725877] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)\n# <strong>echo hello &gt; \/test-file<\/strong>\n# <strong>ls \/<\/strong>\nbin        home       linuxrc    opt        run        <strong>test-file<\/strong>  var\ndev        lib        media      proc       sbin       tmp\netc        lib32      mnt        root       sys        usr\n# <strong>rm \/test-file<\/strong>\n# <strong>\/usr\/local\/bin\/ro<\/strong>\n[  302.623095] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)\n# <strong>echo hello &gt; \/test-file<\/strong>\n-sh: can't create \/test-file: Read-only file system\n# exit<\/pre>\n<p style=\"text-align: justify;\">Malgr\u00e9 un petit souci de <code>PATH<\/code> qui ne permet pas d&rsquo;invoquer directement <code>rw<\/code> ou <code>ro<\/code>, 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-2015.11]$ <strong>mkdir  -p  ..\/board\/raspberrypi2\/ovl\/etc<\/strong>\n[buildroot-2015.11]$ <strong>cp output\/target\/etc\/fstab ..\/board\/raspberrypi2\/ovl\/etc\/<\/strong>\n[buildroot-2015.11]$ <strong>nano ..\/board\/raspberrypi2\/ovl\/etc\/fstab<\/strong><\/pre>\n<p>Le fichier est modifi\u00e9 ainsi (derni\u00e8re ligne ajout\u00e9e)<\/p>\n<pre>#                 \n\/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\/rpi       vfat    defaults,uid=1000,gid=1000  0 0<\/strong><\/pre>\n<p style=\"text-align: justify;\">Nous pouvons \u00e9galement ajouter dans l&rsquo;<em>overlay<\/em> un fichier <code>..\/board\/raspberrypi2\/etc\/profile.d\/custom.sh<\/code> ajustant la configuration du <code>PATH<\/code> et du <em>prompt<\/em> du shell.<\/p>\n<pre>[buildroot-2015.11]$ <strong>mkdir  -p  ..\/board\/raspberrypi2\/ovl\/etc\/profile.d\/<\/strong>\n[buildroot-2015.11]$ <strong>nano ..\/board\/raspberrypi2\/ovl\/etc\/profile.d\/custom.sh<\/strong><\/pre>\n<p>Contenu du fichier <code>custom.sh<\/code><\/p>\n<pre># <em>Acces aux scripts personnels et code metier.<\/em>\nPATH=$PATH:\/usr\/local\/bin\n\n# <em>Prompt indiquant nom d'hote et repertoire courant.<\/em>\nPS1='\\h[\\W]\\$ '<\/pre>\n<p style=\"text-align: justify;\">Recompilons notre syst\u00e8me, et r\u00e9inscrivons-le sur la carte SD en ajoutant une partition <em>vfat<\/em> de 1Go, destin\u00e9e \u00e0 recevoir les donn\u00e9es utilisateur (applicatives).<\/p>\n<pre>[buildroot-2015.11]$ <strong>cp .config ..\/board\/raspberrypi2\/buildroot-03.cfg<\/strong>\n[buildroot-2015.11]$ <strong>make<\/strong>\n [...]<\/pre>\n<p style=\"text-align: justify;\">Lors du partitionnement, nous pouvons placer la partition 3 (celle des donn\u00e9es utilisateur) avant la partition 2 (celle du syst\u00e8me). Ceci permet de donner une taille fixe \u00e0 la partition 3, tout en laissant la partition 2 occuper tout l&rsquo;espace disque disponible.<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo fdisk \/dev\/sdc<\/strong>\nCommande (m pour l'aide) : <strong>n<\/strong>\nPartition type:\n   p   primary (0 primary, 0 extended, 4 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 1 par d\u00e9faut) : <strong>1<\/strong>\nPremier secteur (2048-7741439, 2048 par d\u00e9faut) : <strong>(Entr\u00e9e)<\/strong>\nDernier secteur, +secteurs ou +taille{K,M,G} (2048-7741439, 7741439 par d\u00e9faut) : <strong>+128M<\/strong>\n\nCommande (m pour l'aide) : <strong>t<\/strong>\nNum\u00e9ro de partition (1-4): <strong>1<\/strong>\nCode Hexa (taper L pour lister les codes): <strong>C<\/strong>\n\nCommande (m pour l'aide) : <strong>n<\/strong>\nPartition type:\n   p   primary (1 primary, 0 extended, 3 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 2 par d\u00e9faut) : <strong>3<\/strong>\nPremier secteur (264192-7741439, 264192 par d\u00e9faut) : <strong>(Entr\u00e9e)<\/strong>\nDernier secteur, +secteurs ou +taille{K,M,G} (264192-7741439, 7741439 par d\u00e9faut) : <strong>+1G<\/strong>\n\nCommande (m pour l'aide) : <strong>t<\/strong>\nNum\u00e9ro de partition (1-4): <strong>3<\/strong>\nCode Hexa (taper L pour lister les codes): <strong>C<\/strong>\n\nCommande (m pour l'aide) : <strong>n<\/strong>\nPartition type:\n   p   primary (2 primary, 0 extended, 2 free)\n   e   extended\nSelect (default p): <strong>p<\/strong>\nNum\u00e9ro de partition (1-4, 2 par d\u00e9faut) : <strong>2<\/strong>\nPremier secteur (2361344-7741439, 2361344 par d\u00e9faut) : <strong>(Entr\u00e9e)<\/strong>\nDernier secteur, +secteurs ou +taille{K,M,G} (2361344-7741439, 7741439 par d\u00e9faut) : <strong>(Entr\u00e9e)<\/strong>\n\nCommande (m pour l'aide) : <strong>a<\/strong>\nNum\u00e9ro de partition (1-4): <strong>1<\/strong>\n\nCommande (m pour l'aide) : <strong>p<\/strong>\nP\u00e9riph\u00e9rique Amor\u00e7age  D\u00e9but         Fin      Blocs    Id. Syst\u00e8me\n\/dev\/sdc1   *        2048      264191      131072    c  W95 FAT32 (LBA)\n\/dev\/sdc2         2361344     7741439     2690048   83  Linux\n\/dev\/sdc3          264192     2361343     1048576    c  W95 FAT32 (LBA)\n\nLes entr\u00e9es de la table de partitions ne sont pas dans l'ordre du disque\nCommande (m pour l'aide) : <strong>w<\/strong><\/pre>\n<p style=\"text-align: justify;\">Formatage de toutes les partitions&nbsp;:<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo mkfs.vfat -n BOOT \/dev\/sdc1<\/strong>\n[buildroot-2015.11]$ <strong>sudo mkfs.vfat -n DATA \/dev\/sdc3<\/strong>\n[buildroot-2015.11]$ <strong>sudo mkfs.ext2 -L ROOT \/dev\/sdc2<\/strong><\/pre>\n<p style=\"text-align: justify;\">Apr\u00e8s retrait et r\u00e9insertion de la carte SD&nbsp;:<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo cp output\/images\/bcm2709-rpi-2-b.dtb  \/media\/cpb\/BOOT\/<\/strong>\n[buildroot-2015.11]$ <strong>sudo cp output\/images\/rpi-firmware\/*  \/media\/cpb\/BOOT\/<\/strong>\n[buildroot-2015.11]$ <strong>sudo .\/output\/host\/usr\/bin\/mkknlimg  output\/images\/zImage  \/media\/cpb\/BOOT\/zImage<\/strong>\n[buildroot-2015.11]$ <strong>sudo tar xf output\/images\/rootfs.tar  -C \/media\/cpb\/ROOT\/<\/strong><\/pre>\n<p style=\"text-align: justify;\">Nous devons toujours \u00e9diter le fichier <code>cmdline.txt<\/code> de la partition <code>BOOT<\/code> pour ajouter <code>console=ttyAMA,115200<\/code> sur la premi\u00e8re ligne. Nous verrons ult\u00e9rieurement comment int\u00e9grer cela dans la configuration du noyau. J&rsquo;ajoute \u00e9galement au passage un petit fichier sur la partition <code>DATA<\/code> afin de v\u00e9rifier que tout soit bien mont\u00e9 au d\u00e9marrage.<\/p>\n<pre>[buildroot-2015.11]$ <strong>sudo nano \/media\/cpb\/BOOT\/cmdline.txt<\/strong>\n    [...]\n[buildroot-2015.11]$ <strong>echo \"Hello User !\" &gt; \/media\/cpb\/DATA\/file.txt<\/strong>\n[buildroot-2015.11]$ <strong>sudo umount \/media\/cpb\/*<\/strong><\/pre>\n<p style=\"text-align: justify;\">Au d\u00e9marrage du Raspberry Pi 2, nous observons&nbsp;:<\/p>\n<pre>Welcome on board!\nR-Pi login: <strong>rpi<\/strong>\nPassword: <strong>(rpi)<\/strong>\nR-Pi[~]$ <strong>ls<\/strong>\nfile.txt\nR-Pi[~]$ <strong>cat file.txt<\/strong>\nHello User !\nR-Pi[~]$ <strong>echo $PATH<\/strong>\n\/bin:\/sbin:\/usr\/bin:\/usr\/sbin:\/usr\/local\/bin\nR-Pi[~]$ <strong>echo Modification &gt; file.txt<\/strong>\nR-Pi[~]$ <strong>cat file.txt<\/strong>\nModification\nR-Pi[~]$ <strong>rm file.txt<\/strong>\nR-Pi[~]$ <strong>ls<\/strong>\nR-Pi[~]$<\/pre>\n<p style=\"text-align: justify;\">Nos modifications concernant le <em>prompt<\/em> du shell, le <code>PATH<\/code> et le r\u00e9pertoire utilisateur en lecture-\u00e9criture ont bien \u00e9t\u00e9 prises en compte.<\/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 nous sommes tr\u00e8s loin d&rsquo;un environnement de travail complet comme on peut l&rsquo;obtenir avec une distribution pr\u00e9compil\u00e9e comme <em>Raspbian<\/em>. Mais cela nous permet justement de ma\u00eetriser parfaitement le contenu de notre syst\u00e8me.<\/p>\n<p style=\"text-align: justify;\">La configuration ainsi \u00e9tablie (dont on peut <a href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2015-12-08\/config-buildroot-2015-11-raspberry-pi-2-01.tar.bz2\">t\u00e9l\u00e9charger ici<\/a> les fichiers utilis\u00e9s) nous permettra, dans de prochains articles, d&rsquo;ajouter des applications et services standards (SSH, HTTP, NTP, etc.), d&rsquo;ajuster le contenu du noyau, d&rsquo;installer le bootloader <em>U-Boot<\/em> pour programmer des scripts de d\u00e9marrage (et mise \u00e0 jour) robustes, d&rsquo;ajouter une application personnalis\u00e9e (code m\u00e9tier) et m\u00eame des modules kernel \u00ab\u00a0maison\u00a0\u00bb.<\/p>","protected":false},"excerpt":{"rendered":"<p>[Cette copie d&rsquo;un ancien article est ici &agrave; titre de r&eacute;f&eacute;rence. Je vous conseille de lire plut&ocirc;t la version mise &agrave; jour.] Il y a quelques jours, la livraison trimestrielle de Buildroot a rendu disponible une version 2015.11. J&rsquo;ai voulu l&rsquo;essayer en construisant un petit syst&egrave;me pour Raspberry Pi 2. et partager cette exp&eacute;rience qui [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,10,11],"tags":[],"class_list":["post-5368","post","type-post","status-publish","format-standard","hentry","category-embarque","category-linux-2","category-microprocesseur","category-raspberry-pi"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5368","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=5368"}],"version-history":[{"count":6,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5368\/revisions"}],"predecessor-version":[{"id":5602,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5368\/revisions\/5602"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=5368"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=5368"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=5368"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}