Forum Linux.embarqué Linux from scratch pour Raspeberry: préparation depuis un PC

Posté par . Licence CC by-sa
Tags : aucun
1
17
juin
2015

Bonjour à tous,

Ce matine je me suis dit "Tiens, si je retentais l'aventure LFS comme y a 10 ans, mais sur Raspberry".
Rapidement j'ai trouvé le site qui s'occupe de la chose:
http://www.intestinate.com/pilfs/guide.html

Problème: si j'ai bien compris leur tuto, tout est compilé sur le Raspberry même et cela prend des heures.

Question: Est il possible de préparer son image à déployer depuis un PC standard (compilation depuis le PC (kernel, binaires, OS), génération d'image ISO, mise en place de l'image sur une carte SD pour utilisation dans le Raspberry) ? Peux ton utiliser une machine virtuelle émulant un raspberry sur un PC standard ? Avez vous des pistes ou tuto pour cela, ou peut être même des retours de vos expérience ?

  • # Processeur ARM

    Posté par . Évalué à 2.

    Bonjour,

    Etant donné que le Raspberry est équipé d'un processeur ARM, je pense que c'est à cause de cela que tout doit être compilé depuis le Raspberry lui même et non de ton PC équipé d'un processeur x86.
    Peut-être voir du côté de QEMU s'il peut émuler un processeur ARM voir un Raspberry complet ;)

  • # lmgtfy

    Posté par (page perso) . Évalué à 1.

    • [^] # Re: lmgtfy

      Posté par . Évalué à 2.

      Outre que je n'étais pas certains que le terme cross compilation s'applique ici, je ne connaissais pas lmgtfy

      Merci :*)

      • [^] # Re: lmgtfy

        Posté par (page perso) . Évalué à 3.

        :*)

        Wow ! tu fais des bisous à quelqu'un qui se moque de toi, j'aime ton humilité.

        Allez,
        :*)

        « Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »

  • # CLFS

    Posté par . Évalué à 1.

    Il faut utiliser CLFS pour avoir une version cross-compilable de LFS.

  • # Réponse : oui

    Posté par . Évalué à 4.

    Voici mes notes. Elles datent d’environ un an, donc il y aura peut-être des mises à jour à faire. C’est très synthétique (ce n’était pas destiné à publication) : il faut donc avoir un très bon niveau pour pouvoir s’en servir.

    Ça utilise Gentoo par contre, si tu connais pas, peut-être vaut-il mieux l’utiliser avant sur un poste ordinaire : de toute façon mes notes utilisent Gentoo comme système de build, avec une partition btrfs (un subvolume faisant office d’image virtuelle du système : on versionne le système et on met à jour le diff seulement sur la carte, c’est vraiment le top pour travailler).

    C’est un gros boulot. J’avais fini par abandonner mon but initial. Mais il y a déjà de quoi faire avec mes notes. À toi d’adapter en fonction de tes besoins. Je livre tel quel, j’espère que cela te sera utile ou à d’autres même si ça n’utilise pas LFS. Bon courage !

    Je crois savoir que sous Debian il existe aussi un système de compilation croisée.

    Introduction
    ============
    
          Il  s’agit  d’utiliser  la  carte  comme  un serveur pour de
          l’auto‐hébergement. On exploitera  les  fonctionnalités  les
          plus   avancées   des   systèmes   Linux  et  les  dernières
          innovations  (btrfs,  systemd,  kexec,  gentoo,  etc.).  Par
          exemple btrfs conjugué à kexec autoriseront des mises à jour
          fiables du système sur la carte  SD.   Gentoo  permettra  de
          configurer  le  système  afin  de veiller à des performances
          optimales, avec la mise en place d’une  compilation  croisée
          et d’une distribution binaire des paquets.
    
          Le  serveur web sera léger (lighttpd à priori) et fera appel
          à FCGI/C++, via une technologie “semi‐statique” : les  pages
          html  seront  servies statiquement, mais il sera possible de
          les  modifier  via  l’exposition  d’une  API  HTTP  get/post
          adéquate. La modification des pages html fera appel au *copy‐
          on‐write* et au renommage atomique. En guise de démonstration
          technologique,  on  créera  un  blog simple. On pourra aussi
          réutiliser,  moyennant  quelques  menues  adaptations,   les
          scripts  dash/make  qui  me  permettent  de  tenir à jour ma
          galerie d’images & vidéos.
    
    
    Pré-requis
    ----------
    
          Achat pour ~50 €, livraison comprise, sur [materiel.net](http://materiel.net) :
          — Raspberry Pi B+ ;
          — alimentation 1,2 A (dont ~700 mA pour la carte) ;
          — carte microSDHC classe 4 Kingston 4 GB ;
          — cable ethernet court, sans blindage.
    
          On  peut  vérifier  avec une raspbian que le tout fonctionne
          correctement, et on peut récupérer les options du noyau dans
          `/proc/config.gz`, utiles si l’on ne les a pas déjà.
    
          Connaissances requises :
          — administration d’une gentoo, niveau intermédiaire ;
          — administration de serveurs, web & mail essentiellement.
          — systemd, niveau débutant ;
          — base en développement C ;
          — chaîne de compilation (config/econf, make/emake, install).
    
          Documentation :
          — [guide](http://wiki.gentoo.org/wiki/Raspberry_Pi) gentoo sur la raspberry ;
          — [guide](https://www.gentoo.org/proj/en/base/embedded/handbook/?part=1) gentoo sur les systèmes embarqués ;
          — page `man ebuild` de gentoo ;
          — pages `man systemd`.
    
    
    Compilation croisée
    ===================
    
          On utilisera une variable de confort
          `ARM="armv6j-hardfloat-linux-gnueabi"`
          à  placer  dans  son  `~/.$(basename  $SHELL)rc`.
    
          Faire :
          `sudo emerge sys-devel/crossdev
          sudo crossdev -S -P \-j2 -oO /usr/local/portage \
            --target $ARM`
          Si  on  vous  le  demande, il vous faudra convertir certains
          fichiers de `/etc/portage` en répertoire. Toutes  les  options
          du type `‐jN` peuvent être adaptées, ici et par la suite, avec
          N  le  nombre de cœurs de vos processeurs — c’est la célèbre
          option de make, passée telle quelle. On va combler un manque
          de crossdev :
          `sudo cp /usr/bin/$ARM-emerge /usr/bin/$ARM-ebuild`
          puis éditer le fichier nouvellement créé en remplaçant toute
          référence à emerge par ebuild et  en  supprimant  l’argument
          `--root-deps=rdeps`.
    
          Il est temps de configurer & compiler un système de base :
          `sudo ln -nsf \
            /usr/portage/profiles/default/linux/arm/13.0/armv6j \
            /usr/$ARM/etc/portage/make.profile`
          puis éditer le fichier `/usr/$ARM/etc/portage/make.conf` :
          `CFLAGS="-O2 -pipe -fomit-frame-pointer
            -march=armv6j -mfpu=vfp -mfloat-abi=hard"
          USE_PYTHON="2.7"
          PYTHON_TARGETS="python2_7"
          MAKEOPTS="-j2"
          PORTAGE_NICENESS=19
          PORTAGE_TMPDIR=/tmp/
          USE="${ARCH} -pam
               systemd python2 minimal
               -acl -kmod -firmware-loader -cracklib
               -nls -cramfs"`
          Notez  bien  que  si  je  prends l’option d’un répertoire de
          travail dans `/tmp`, c’est pour que la compilation se  déroule
          dans  un  tmpfs  — c’est le cas de `/tmp` chez moi — sans pour
          autant interférer avec le répertoire de travail  du  portage
          principal — dans `/var/tmp` chez moi. Enfin :
          `sudo $ARM-emerge systemd btrfs-progs dash`
          Cela  devrait  nous mener à quelques erreurs de compilation.
          Voyons comment les résoudre.
    
    
    À propos des problèmes de compilation
    -------------------------------------
    
          Il  faut  commencer  par  consulter  les  logs  laissés  par
          portage. Par exemple à partir de
          `/tmp/portage/sys-apps/shadow-4.2.1/temp/build.log`
          on atteint
          `[..]/sys-apps/shadow-4.2.1/work/shadow-4.2.1/config.log`
          et  ce  dernier  mène au script `configure:14778` dans le même
          répertoire.
    
          Il  faut  donc  débrayer emerge et passer en manuel pour que
          portage puisse compiler les  paquets  qui  posent  problème.
          Pour  ce  faire  on  utilisera  ebuild :  je  renvoie  à  sa
          documentation. Pour toute la section nous  supposerons  être
          root.  En utilisant le fichier `.ebuild`, dans `/usr/portage` et
          correspondant au paquet à installer (attention à la  version
          du paquet!), les commandes utiles sont :
          `$ARM-ebuild xxx.ebuild prepare
          $ARM-ebuild xxx.ebuild configure
          $ARM-ebuild xxx.ebuild compile
          $ARM-ebuild xxx.ebuild install
          $ARM-ebuild xxx.ebuild qmerge
          $ARM-ebuild xxx.ebuild package
          $ARM-ebuild xxx.ebuild clean`
    
          Par  exemple  avec  shadow,  on  prépare  le  répertoire  de
          travail, et ensuite  on  modifie  le  script  configure  aux
          alentours  de  la  ligne  14 778. En effet on réalise que le
          problème vient de ce que le script a besoin de  compiler  et
          d’exécuter  un  petit  programme à la volée pour vérifier si
          certaines données sont  en  32 bits.  Dans  un  contexte  de
          compilation  croisée, c’est pas cool ! Ceci dit, on sait que
          la raspberry est 32 bits. Il nous suffit donc de modifier le
          script en conséquence pour qu’il n’ait pas à faire son test,
          mais qu’il exécute les actions nécessaires en  admettant  un
          résultat de type 32 bits.
    
          En ce qui concerne btrfs, il sera probablement nécessaire de
          compiler le paquet acl avant, puis de  suivre  la  procédure
          manuelle,  pour faire un petit tour vers le Makefile afin de
          désactiver la compilation de  l’inutile  documentation,  qui
          nécessite asciidoc, dont les dépendances sont trop lourdes.
    
          Parfois  les  problèmes  sont plus profonds, et il peut être
          nécessaire de bloquer la version la plus récente d’un paquet
          se  trouvant  la  plupart  du temps dans `~arm`. Ce fut le cas
          pour `libgpg‐error‐1.13`.
    
          Pour  clucene, réclamé plus tard par dovecot compilé avec la
          recherche  plein  texte,  il  faut  désactiver  le  test  de
          `snprintf`, après vérification manuelle sur la raspberry. Mais
          c’est insuffisant : une  erreur  de  programmation  subsiste
          lorsque  les  espaces de nom C++ ne sont pas disponibles. En
          effet le dévelopeur a bêtement  utilisé  un  espace  de  nom
          directement  plutôt qu’une macro ad‐hoc correspondante. Ceci
          dit, finalement, j’ai activé les espaces de nom directement,
          après  vérification  manuelle du test CMake sur la raspberry
          bien sûr, en  modifiant  directement  le  fichier  cache  de
          CMake.  Ce  fut  nécessaire pour ne pas avoir de conflits au
          moment du lien.
    
          Rebelotte  pour  Dovecot.  Toujours  la même chose : l’étape
          configure  réclame  la   compilation   et   l’exécution   de
          programmes  à la volée. Il faut modifier le script `configure`
          pour court‐circuiter les tests de epoll et inotify  dont  on
          veillera  à  l’activation  dans  le noyau. Il en est de même
          pour `fallocate` de posix, et des  `size_t`  non  signés,  après
          vérification  manuelle.  Le  nombre  de  bits  supportés par
          `gmtime` est 32, les `time_t`  sont  signés,  `mmap`  accepte  les
          `write`,  un obscur truc à propos de `fd` passe le test (premier
          de  la  boucle)  sans  problème,  idem  pour  `vsnprintf`,  et
          quelques test sur les listes à taille variable d’arguments.
    
    
    Noyau
    =====
    
          `USE="-symlink" sudo emerge \
            sys-kernel/raspberrypi-sources \
            sys-boot/raspberrypi-mkimage`
          J’ai  installé la version des sources noyau qui correspond à
          mon système principal, suffisament récente  pour  btrfs  — à
          l’heure  où  j’écris  ce  texte, c’est 3.14 —, et j’ai rendu
          permanent la suppression du USE symlink dans un  fichier  de
          `/etc/portage/package.use`.   Puis dans le dossier des sources
          du noyau :
          `sudo make ARCH=arm CROSS_COMPILE=$ARM- make -j2
          sudo mkdir /usr/$ARM/boot
          sudo imagetool-uncompressed.py --force
            arch/arm/boot/Image /usr/$ARM/boot/kernel.img`
          J’utilise un noyau  monolitique avec un [.config](http://TODO|le `.config` de mon noyau actuel) issu d’une
          raspbian  (`/proc/config.gz`)  et  modifié  pour  être le plus
          minimaliste possible. Il faut veiller à certaines [options](Doivent être activées les deux options menuconfig qui concernent kexec ainsi que CONFIG_ATGS, pour plus tard, et les dépendances systemd pour le noyau : AUTOFS4_FS ok, BLK_DEV_BSG ok, CGROUPS ok, DEVTMPFS ok, DMIID n/a, EPOLL ok, FANOTIFY ok, FHANDLE ok, INOTIFY_USER ok, IPV6 ok, NET ok, NET_NS ok, PROC_FS ok, SECCOMP ok, SIGNALFD ok, SYSFS ok, TIMERFD ok, TMPFS_XATTR ok, !IDE ok, !SYSFS_DEPRECATED ok, !SYSFS_DEPRECATED_V2 ok, !GRKERNSEC_PROC ok, !FW_LOADER_USER_HELPER ok).
    
    
    Système
    =======
    
          Rechercher dans les [dépots](http://distfiles.gentoo.org/releases/arm/autobuilds/current-stage3-armv6j_hardfp/) gentoo l’archive stage3 la plus
          récente, et noter son `url` :
          `wget $url
          wget \
          http://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2
          sudo btrfs subvolume create root-work
          sudo tar xjpf stage3-armv6j_hardfp-xxx.tar.bz2 -C root-work/
          sudo tar xjpf portage-latest.tar.bz2 -C root-work/usr/       `<- TODO image miroir de /usr/$ARM/usr/bla
                                                                          Tenter un mount --bind`
          sudo $ARM-emerge --root root-work --unmerge udev
          PKGDIR=/usr/$ARM/packages sudo $ARM-emerge \
            systemd btrfs-progs dash --root root-work --usepkgonly`
          Il  faut  utiliser  les fichiers fournis sur la partition de
          boot de la raspbian, car ceux du  paquet  gentoo  ad‐hoc  ne
          sont pas bons. La procédure consiste à lancer :
          `sudo parted bla-raspbian.img unit b print`
          Regarder  le  début  de  la  partition fat16, et s’en servir
          comme `offset` :
          `mkdir boot
          sudo mount -o offset=$offset bla-raspbian.img boot
          sudo cp boot/* /usr/$ARM/boot
          sudo umount boot
          rmdir boot`
          Puis  éditer  le fichier `/usr/$ARM/boot/cmdline.txt`, sur une
          seule ligne :
          `console=tty1
          root=/dev/mmcblk0p2
          rootfstype=btrfs
          elevator=noop
          rootwait
          init=/usr/lib/systemd/systemd
          quiet
          ro
          rootflags=compress=lzo`
          puis le fichier `/usr/$ARM/boot/config.txt` pour les options :
          `hdmi_safe=1
          gpu_mem=16`
          Enfin, `root-work/etc/fstab` doit contenir :
          `/dev/mmcblk0p1 /boot vfat noauto,noatime 1 2
          /dev/mmcblk0p2 / btrfs noatime,compress=lzo 0 1
          /dev/mmcblk0p2 /mnt btrfs noatime,subvol=/,compress=lzo 0 0`
          Ne pas oublier de créer le lien :
          `sudo ln -s /proc/self/mounts root‐work/etc/mtab`
          Puis éditer le fichier `root-work/etc/systemd/journald.conf` :
          `Storage=volatile
          RuntimeMaxUse=10M`
          Activer le synchronisation de temps :                        <- TODO: ne fonctionne pas à cause d’une entrée /dev absente
          `sudo systemctl enable --root root-work \
            systemd-timesyncd.service`
          Bien  noter qu’il faut copier l’unité correspondante du côté
          de `/etc` et y supprimer la ligne `PrivateTmp=yes`, et penser  à
          créer   le   fichier   `/var/lib/systemd/clock`  avec  le  bon
          propriétaire (voir la section sur la création  d’un  système
          de fichier mixte ro‐rw). Pour localiser la zone horaire :
          `sudo ln -sf \
            /usr/share/zoneinfo/Europe/Paris root-work/etc/localtime`
    
          Le système d’init se contentera d’un démarrage simplifié :
          `sudo systemctl set-default basic.target --root root-work`
    
    
    Réseau & OpenSSH
    ----------------
    
          L’interface   réseau   est  reconnue  comme  étant  le  très
          classique eth0. Il faut  créer  l’unité  `static‐eth0.service`
          dans `root‐work/etc/systemd/system/network.target.wants` :
          `[Unit]
          Description=Static ethernet connection
          Before=network.target
          BindsTo=sys-subsystem-net-devices-eth0.device
          After=sys-subsystem-net-devices-eth0.device
          [Service]
          Type=oneshot
          RemainAfterExit=yes
          KillMode=none
          ExecStart=/bin/ifconfig eth0 192.168.0.2 \
            broadcast 192.168.0.255 netmask 255.255.255.0 up
          ExecStart=/bin/route add default gw 192.168.0.254`
          On n’oublie pas les DNS :
          `sudo cp -L /etc/resolv.conf root-work/etc/`
          On doit mettre en place le serveur ssh. Pour cela ajouter un
          lien :
          `sudo systemctl --root root-work enable sshd.socket`
          Editer le fichier de configuration
          `root-work/etc/ssh/sshd_config`
          pour supprimer, ou commenter, la ligne :
          `UsePAM yes
          AcceptEnv LANG LC_*`
          Puis faire (première commande le cas échéant) :
          `sudo ssh-keygen                                            <- TODO: doit être fait pour chaque image fournie/téléchargée
          sudo mkdir root-work/root/.ssh
          sudo chmod 700 root-work/root/.ssh
          sudo cp \
            /root/.ssh/id_rsa.pub root-work/root/.ssh/authorized_keys
          sudo mount --bind root-work/root/etc/ssh /etc/ssh
          sudo ssh-keygen -A
          sudo umount /etc/ssh`
    
    
    Préparation de la carte SD
    --------------------------
    
          Pour  finir on prépare le snapshot à placer sur la carte SD,
          pour cela, créer une partition FAT16 commençant à 4096kB  et
          ayant l’étiquette lba, et une seconde pour le fichier racine
          en btrfs. Attention à bien spécifier les bons fichiers  bloc
          pour  les  deux  première  commandes,  car  elles  sont tout
          particulièrement dangereuses :
          `sudo mkfs.fat -F16 /dev/sdX1
          sudo mkfs.btrfs /dev/sdX2
          sudo mount /dev/sdX1 /mnt
          sudo cp /usr/$ARM/boot/* /mnt
          sudo umount /mnt
          sudo btrfs subvolume snapshot -r root-work root-xxx
          sudo mount /dev/sdX2 /mnt
          sudo btrfs send raspberry/root-xxx | sudo btrfs receive /mnt
          sudo btrfs subvolume set-default \
            $(sudo btrfs inspect-internal rootid /mnt/root-xxx) /mnt
          sudo umount /mnt`
    
    
    Finaliser l’installation
    ========================
    
          Si  tout se passe bien, les étapes précédentes auront permis
          de créer un système fonctionnel  avec  lequel  la  raspberry
          peut  démarrer,  se  connecter au réseau local, et ouvrir un
          serveur ssh. Une connection ssh depuis le compte root permet
          de valider l’opération.
    
          On pourra continuer le travail en supposant que la raspberry
          est allumée et accessible via le nom d’hôte éponyme. Pour ce
          faire, écrire dans le fichier /etc/hosts :
          `192.168.0.2 raspberry`
    
    
    Kexec & mise-à-jour à distance
    ------------------------------
    
          Nous  allons  installer  kexec  pour montrer comment on peut
          faire évoluer le système :
          `sudo $ARM-emerge kexec-tools
          PKGDIR=/usr/$ARM/packages sudo $ARM-emerge kexec-tools \
            --root root-work --usepkgonly
          sudo btrfs subvolume snapshot -r root-work root-xxx-r1
          sudo btrfs send -p root-xxx root-xxx-r1 -f incr.img
          sudo scp incr.img raspberry:/tmp
          sudo ssh raspberry
          mount -o subvol=/ /dev/mmcblk0p2 /mnt
          btrfs receive -f /tmp/incr.img /mnt
          btrfs subvolume set-default \
            $(btrfs inspect-internal rootid /mnt/root-xxx-r1) /mnt
          umount /mnt
          systemctl reboot`
          Ce qui devrait logiquement fermer la connexion ssh. Attendre
          quelques secondes, puis relancer :
          `sudo ssh raspberry
          mount -o subvol=/ /dev/mmcblk0p2 /mnt
          btrfs subvolume delete /mnt/root-xxx
          umount /mnt
          kexec -v`
          La dernière commande devrait être ok : on a réalisé une mise
          à jour à distance de notre raspberry !
    
          Pourquoi  kexec ? Et bien, si un nouveau noyau tombe dans un
          `kernel panic` et que l’option
          `menuconfig->kernel hacking->panic timeout`
          est  réglée  à  10 (par exemple), alors qu’il est lancé avec
          kexec, la carte  redémarrera  automatiquement  sur  l’ancien
          noyau. Elle est pas belle la vie ? Voyons voir, compilons un
          nouveau noyau,  selon  la  procédure  décrite  précédemment.
          Puis :
          `sudo scp arch/arm/boot/zImage raspberry:/tmp
          sudo ssh raspberry
          kexec -l /tmp/zImage --atags --command-line="$(cat /proc/cmdline)"
          kexec -e`                                                     <- TODO c’est pas du propre !
    
    
    Rendre fonctionnel l’ensemble
    -----------------------------
    
          Pour corriger les erreurs qui subsistent, il suffit d’ouvrir
          le journal systemd. Par exemple, mon installation montre que
          des  groupes et des utilisateurs qui sont nécessaires au bon
          fonctionnement de systemd, etc. n’ont pas  été  créés.  J’ai
          corrigé cela en ajoutant les lignes nécessaires aux fichiers
          `/etc/passwd` & `/etc/group`, directement piquées de mon système
          principal.
    
          C’est   aussi   le  journal  qui  permet  de  connaître  les
          répertoires qui doivent être accessibles en écriture pour la
          section suivante.
    
    
    Système de fichier mixte ro–rw
    ------------------------------
    
          Btrfs  permet  d’obtenir  un  système de fichier qui utilise
          deux blocs mémoire sources, dont un est en lecture seule. On
          va  donc  procéder  à  la  création  d’un  fichier image qui
          contiendra un système de fichiers en lecture seule, et  d’un
          bloc  situé  en  mémoire vive accessible en écriture, et qui
          sera le *copy‐on‐write* du  fichier  image.  On  pourra  ainsi
          limiter les écritures sur la carte SD, afin de la préserver.
    
          Pour  initier  la procédure, toujours sur la raspberry, avec
          la variable shell `rep` l’ensemble des répertoires qui doivent
          être  en  écriture,  en  suivant la convention de nommage de
          systemd :
          `dd if=/dev/zero of=/mnt/live bs=128M count=1
          mkfs.btrfs /mnt/live
          mount -o loop /mnt/live /media
          btrfs subvolume create /media/0
          for r in $rep;do mkdir /media/0/$r;done
          btrfs property set /media/0 ro true
          ln -s 0 /media/cur
          umount /media`
          Et  sur  l’ordinateur principal, toujours dans le répertoire
          où se trouve `root‐work`  le  répertoire  destiné  à  être  la
          racine du système de fichier de la raspberry :
          `sudo mkdir root-work/live`
          Éditer les fichiers `root-work/etc/fstab` :
          `/mnt/live /mnt btrfs loop,noatime 0 0`
          ensuite `root-work/usr/local/sbin/live.start` :
          `#!/bin/dash
          current=$(readlink /live/cur)
          other=$((1 - ${current}))
          if [ -d /live/${other} ]
          then
            /bin/umount /live
            /sbin/btrfstune -fS0 /mnt/live
            /bin/mount /live
            /sbin/btrfs subvolume delete /live/${other}
            /bin/umount /live
            /sbin/btrfstune -S1 /mnt/live
            /bin/mount /live
          fi
          btrfs device add -Kf /dev/ram0 /live
          mount -o rw,remount /live
          btrfs subvolume snapshot /live/${current} /live/${other}
          ln -snf ${other} /live/cur`
          et enfin `root-work/usr/local/sbin/live.stop` :
          `#!/bin/dash
          [ -f /live/volatile ] && exit 0
          current=$(readlink /live/cur)
          other=$((1 - ${current}))
          btrfs property set /live/${current} ro true
          btrfs send -p /live/${other} /live/${current} -f /tmp/live.incr
          umount /live
          btrfstune -fS0 /mnt/live
          mount /live
          btrfs receive -f /tmp/live.incr /live \
          && ln -nsf ${current} /live/cur.tmp \
          && mv -T /live/cur.tmp /live/cur \
          && btrfs subvolume delete /live/${other}
          umount /live \
          && btrfstune -S1 /mnt/live \
          && btrfs filesystem sync /mnt`
          Puis rendre les deux scripts exécutables :
          `chmod u+x root-work/usr/local/sbin/live.st*`
          Ils seront appelés par une unité systemd chargée de gérer ce
          montage d’un type un peu particulier dans  `/live`,  on  écrit
          donc `root-work/etc/systemd/system/live.service` :
          `[Unit]
          DefaultDependencies=false
          RequiresMountsFor=/mnt /tmp /live
          [Service]
          Type=oneshot
          RemainAfterExit=true
          ExecStart=/usr/local/sbin/live.start
          ExecStop=/usr/local/sbin/live.stop`
          ainsi que `root-work/etc/systemd/system/live-pre.service` :
          `[Unit]
          DefaultDependencies=false
          RequiresMountsFor=/mnt
          Before=live.mount
          [Service]
          Type=oneshot
          SuccessExitStatus=1
          ExecStart=/sbin/btrfstune -S1 /mnt/live`
          et pour finir `root-work/etc/systemd/system/live.mount` :
          `[Unit]
          DefaultDependencies=false
          RequiresMountsFor=/mnt
          Requires=live-pre.service
          After=live-pre.service
          [Mount]
          What=/mnt/live
          Where=/live
          Options=loop,noatime`
          Il faut noter une fonctionnalité qui permet de désactiver le
          script d’arrêt,  qui  est  particulièrement  long  lorsqu’on 
          teste, en plaçant un fichier vide `/live/volatile`, auquel cas
          on perd la persistance des données.
    
          On  va  ensuite créer des unités systemd de type `.mount` afin
          de gérer tous les répertoires qui doivent  être  accessibles
          en  écriture.  Elles  devront  dépendre du service qui vient
          d’être écrit. Il  faut  rendre  accessible  en  écriture  un
          certain  nombre  de  répertoires,  par  exemple  `/var/log`  &
          `/var/lib/systemd`.  Ce  qui  donne,  par  exemple,  une unité
          dans  `/etc/systemd/system/local‐fs.target.wants`  de nom fixé
          `var‐log.mount` :
          `[Unit]
          DefaultDependencies=false
          Requires=live.service
          After=live.service
          Before=systemd-tmpfiles-setup.service
          [Mount]
          What=/live/cur/var-log
          Where=/var/log
          Options=bind`
          Et  ainsi  de suite, en veillant à bien respecter le nommage
          des unités comme systemd le réclame (voir la documentation).
          Il  faut  aussi créer les dossiers voulus sur la raspberry :
          si cela  n’est  pas  déjà  fait,  enlever  momentanément  la
          propriété  `ro` du volume concerné par `/live/cur`, puis y créer
          les dossiers tout en respectant, encore une fois, le  schéma
          de nommage.
    
    
    Logiciels tiers
    ===============
    
    Serveurs
    --------
    
          Pour  installer  le serveur, on ajoute les USE nécessaires :
          `sieve managesieve lucene
          -threads
          -mysql -sqlite -gdbm`
          dans `/usr/$ARM/etc/portage/make.conf`, puis :
          `sudo $ARM-emerge \
            fetchmail ssmtp dovecot lighttpd`
          Pour  les  erreurs  de compilation, se reporter à la section
          correspondante. Pour l’installation :
          `PKGDIR=/usr/$ARM/packages sudo $ARM-emerge \
            fetchmail ssmtp dovecot lighttpd \
            --root root-work --usepkgonly`
    
          Il faut là encore mettre en place les bons utilisateurs dans
          `/etc/passwd` & `/etc/group`. Il faut aussi  les  bons  dossiers
          accessibles en écriture. Par exemple, sur la raspberry :
          `mkdir /var/log/lighttpd
          chown lighttpd:lighttpd /var/log/lighttpd
          rm /live/volatile
          systemctl stop live.mount`
          Ainsi  le  script  d’arrêt  est  bien appelé dans sa version
          complète, comme cela peut  prendre  un  moment  on  peut  se
          renseigner sur son avancement :
          `systemctl status live.mount`
          puis remonter le tout :
          `systemctl start live.service
          systemctl start var-log.mount
          systemctl start var-lib-systemd.mount`
          avec  l’avantage  d’être toujours en volatile, si c’était le
          cas, car le fichier ad‐hoc  a  uniquement  été  supprimé  du
          système de fichier en ram.
    
          Le   cache   de  compression  de  lighttpd  se  trouve  dans
          `/var/cache/lighttpd`,   mis   en   tmpfs   (`size=512M`)   dans
          `/etc/fstab`  en  oubliant  pas de placer un `RequiresMountsFor`
          adéquat  pour  l’unité  lighttpd, ce qui aurait déjà dû être
          fait pour le `/var/log/lighttpd`.
    
    
    Outils
    ------
    
          Gnuplot  et  Imagemagick  sont de la partie. Le premier sans
          readline mais avec gd (png), le second avec cxx et jpeg.
    
          TODO :   Des   erreurs  de  compilation  apparaissent,  sans
          surprise. Pour Gnuplot, c’est la création de fichiers d’aide
          qui  bloque.  Ce  ne  devrait  pas  être  un  problème. Pour
          Imagemagick, il faut creuser du côté de la libtool.
    
    
    Perspectives
    ============
    
          Penser  à  la  possibilité  d’ajouter  une  petite batterie,
          typiquement  ce  que  j’ai  sur  mon  XZ‐1.  Il  existe  des
          convertisseurs 3,7 à 5 V DC. Cela permettrait une extinction
          propre de la machine  au  débranchement  de  l’alimentation,
          avec  un  peu  de  travail  sur  l’électronique. On pourrait
          relâcher ainsi la contrainte d’écriture sur la carte SD.
    
    
    
    TODO: redémarrer en cas de fail du net ou du ssh.
    TODO: faire du kexec et améliorer le noyau (unité systemd nécessaire, notamment pour veiller à la bonne gestion du live.service).
    TODO: kexec en changeant la cmdline pour démarrer sur un nouveau snapshot !!! pb avec fstab pas à jour?
    TODO: Documentation/cmdline-partition, pour indiquer la table de partitions sur la ligne de commande, sans compter l’utilisation d’un device static.
    TODO: utile de compléter le fichier /etc/shadow ?
    TODO: comment se passe la gestion des fichiers /var/log et/ou /var/lib/systemd
    TODO: voir si le premier umount avec -f dans live.stop accélère la vitesse du démontage (qui peut être forcé sans problème)
    TODO: SIGSTOP&SIGCONT pour pouvoir garder lighttpd sur le fil lorsqu’on doit effectuer un live.stop&live.start pour les dossiers du serveur.
    TODO: check pagesize of the raspberry
    TODO: ssh-keygen doit pouvoir être relancé pour chaque image.
    
  • # buildroot

    Posté par . Évalué à 1.

    Salut snurpsss,

    Si tu veux préparer ton image et ton root-fs en lançant la compilation depuis ton pc je te conseil d'utiliser un outil comme buildroot ! Il comporte d’ailleurs des configurations prédéfinis pour cible Raspberry (Cross-compile…). C'est un outil vraiment puissant qui te permettra de tailler un environnement sur mesure !

    Tu trouvera des tutos sur buildroot sans problème !

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.