Introduction à u-boot

Transcription

Introduction à u-boot
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
INTRODUCTION À U-BOOT
NOVEMBRE 2010
OPEN WIDE
- 1/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
TABLE DES MATIÈRES
1. INTRODUCTION.................................................................................................. 3
1.1. QU'EST CE QU'UN BOOTLOADER.....................................................................................................3
1.2. LES BOOTLOADERS DANS L'EMBARQUÉ............................................................................................3
1.3. HISTOIRE DE U-BOOT..................................................................................................................3
2. U-BOOT.................................................................................................................. 5
2.1. GÉNÉRALITÉS..............................................................................................................................5
2.2. ARCHITECTURE DU CODE SOURCE...................................................................................................5
2.3. COMPILATION DE U-BOOT............................................................................................................6
2.4. UTILISATION DE U-BOOT.............................................................................................................6
2.4.1. Configuration de U-Boot..................................................................................................6
2.4.2. La console U-Boot............................................................................................................7
2.4.3. Les commandes internes U-Boot......................................................................................7
2.4.4. Exemple de commandes....................................................................................................9
2.5. CODER DANS U-BOOT................................................................................................................10
2.5.1. Les fichiers d'include et de configuration.......................................................................10
2.5.2. Ajout d'un CPU...............................................................................................................11
2.5.3. Ajout d'une carte ............................................................................................................11
2.5.4. Ajout d'un périphérique...................................................................................................12
2.5.5. Ajout d'une commande....................................................................................................12
3. CONCLUSION..................................................................................................... 13
3.1. U-BOOT....................................................................................................................................13
3.2. AUTRES BOOTLOADERS...............................................................................................................13
- 2/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
1.
1.1.
INTRODUCTION
QU'EST CE QU'UN BOOTLOADER
U-Boot fait partie de la famille des bootloaders. Les bootloaders sont des logiciels, en général mal
connus du grand public, présents sur la grande majorité des équipements informatique. Leur tâche
principale est le chargement du système d'exploitation lors du démarrage de la machine. Les
bootloaders sont très spécialisés et souvent silencieux.
Voici quelques bootloaders utilisés sur les OS grand public.
•
NTLDR: pour les OS Windows avant Vista
•
WINLOAD: pour les OS Windows Vista et Seven
•
Bootcamp: pour charger un système Windows sur une machine Apple
•
Darwin: bootloader Apple
•
Grub/Grub2: bootloader très répandu pour les systèmes Linux
•
Lilo: LInux Loader, anciennement très utilisé sous Linux mais maintenant supplanté par
Grub
1.2.
LES BOOTLOADERS DANS L'EMBARQUÉ
Le monde de l'embarqué utilise ses propres bootloaders. En effet, les architectures sont très variées :
différentes familles de processeurs (ARM / POWERPC / X86 / MIPS / ...) présentant chacune de
nombreuses versions de microprocesseur pouvant être implantées sur plusieurs versions de cartes
mères. U-Boot est un bootloader très répandu dans ce domaine. Il permet de démarrer un OS Linux
(mais pas seulement) sur plusieurs centaines de type de cartes cibles.
La tâche du bootloader est de gérer les initialisations de base du processeur ainsi que de certains
composants, puis de charger le noyau du système d'exploitation. Certains bootloaders offrent des
options supplémentaires :
•
Affichages des actions en cours sur une console (série, USB, écran)
•
Sélection de l'OS à charger et modification des options de démarrage
•
Récupération des composants de l'OS (noyau + système de fichiers de base) depuis
différents média: ROM interne, support USB, réseau...
•
Flashage d'OS
U-Boot permet de réaliser toute ces actions grâce à un interpréteur de commande interne.
1.3.
HISTOIRE DE U-BOOT
Le nom U-Boot vient de la contraction de l'allemand Das Unterseeboot (qui désigne les sous-marins
allemand des deux guerres mondiales) mais pourrait aussi correspondre à la contraction de
- 3/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
universal bootloader.
Le projet est apparut en 1999.
Il est disponible sous licence GPL v2, les sources sont en téléchargement depuis le git à l'adresse
git://git.denx.de/U-Boot.git
U-Boot fut créé par l'allemand Magnus Damm tout d'abord pour l'architecture PPC et fut nommé
PPCBoot.
Le nom U-Boot est apparu en novembre 2002 lorsque le support de nouvelles architectures arriva
suite à la fusion avec le projet ARMBoot.
U-Boot est distribué par l'entreprise Denx Software Engineering, qui est connue également pour
ELDK (Embedded Linux Development Kit).
- 4/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
2.
2.1.
U-BOOT
GÉNÉRALITÉS
Le code de U-Boot est majoritairement écrit en C. Les seules parties devant être décrites en
assembleur sont les codes bas niveau spécifiques.
Les évolutions sont faites par soumission de patchs sur la mailing list puis intégration par les
responsable de modules (les custodians).
La politique de sortie de version se décompose en deux parties. Tout d'abord, 2 semaines sont
dédiées à la soumission des évolutions suivies de 6 semaines de stabilisation. Cela correspond à un
cycle d'environ 2 mois.
2.2.
ARCHITECTURE DU CODE SOURCE
U-Boot devant supporter de nombreux matériels différents, son architectures est modulaire. Les
fonctionnalités sont réparties dans divers dossiers. Ainsi, le dossier arch/ contient les portages de
tous les processeurs supportés, classés par familles. Le dossier board/ contient le code spécifique de
chaque carte supportée. Afin d'assurer une modularité maximum, les drivers de périphériques sont
présents dans un dossier drivers/ et classés par catégories. Le dossier common/ contient toutes les
fonctionnalités indépendantes des processeurs : le cœur de U-Boot. C'est la que se retrouve
l'interpréteur de commande interne. Enfin, le dossier include/configs/ contient la liste des
descriptions de chaque carte cible. Ceci permet de paramétrer une carte utilisant des composants
génériques comme l'adresse des registres, des composants, l'association d'une broche d'un
composant à une fonction, l'activation de fonctionnalité, déclaration des spécificités processeur,
sans avoir a réécrire de ligne de code.
Des scripts permettent ensuite de compiler U-Boot pour une cible particulière en créant des liens
symboliques.
Le fichier boards.cfg contient la liste des cibles supportées ainsi que leur description :
•
nom
•
architecture
•
type de CPU
•
nom de la carte
•
vendeur
•
systeme on chip
•
options
A la rédaction de cet article, plus de 700 cartes différentes sont décrites.
- 5/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
2.3.
COMPILATION DE U-BOOT
En pratique, si le CPU et la carte sont supportés par U-Boot en natif (sans faire de modification du
code source), alors il est assez simple de recompiler depuis les sources. Pour cela, il suffit de
configurer l'arborescence pour la carte cible en faisant :
$> make <board_name>_config
Le script mkconfig va alors créer les liens symboliques nécessaires afin de faire de la carte cible, la
carte par défaut.
$> make
va alors permettre de construire l'exécutable U-Boot.bin.
Bien entendu, dans la grande majorité des cas, la compilation de U-Boot se fait sur une machine
hôte (HOST) ayant une architecture CPU différente de la machine cible (TARGET). Il faut donc
utiliser le principe de la compilation croisée avec une chaine de compilation définie en définissant
la variable d'environnement.
PATH=$PATH:<chemin vers la toolchain>
Il est possible d'utiliser le script MAKEALL qui va construire tour à tour toutes les cibles possibles.
En général, ce script n'est utilisé qu'à des fins de test.
Lors de la compilation, le makefile va compiler tous les modules sous forme de librairies statiques
puis lier le tout dans un exécutable lui aussi statique nommé U-Boot.bin. Ce binaire présente une
faible taille, typiquement inférieur à 128Ko pour assurer une compatibilité avec un maximum de
cible. Le binaire devra ensuite être flashé sur la ROM de la carte cible.
La technique de flashage dépend grandement de la cible. En général, une sonde JTAG est
nécessaire, mais dans certains cas il est possible de s'en passer. Si un système est déjà présent sur la
cible, alors, il est peut être possible de flasher la ROM depuis celui ci, s'il possède les drivers
permettant d'écrire sur la ROM en question. Un simple accès en série/telnet/ssh suffira. Certaines
cible propose aussi un micro bootloader qui sert à démarrer/flasher un bootloader plus complet.
Dans ce cas la, il est possible d'utiliser une simple liaison série pour dialoguer avec ce bootloader
initial et lui envoyer le binaire U-Boot par un protocole spécialisé (du genre x-modem/y-modem/zmodem/kermit/ascii).
2.4.
UTILISATION DE U-BOOT
Une fois U-Boot flashé dans la cible, il est possible, d'interrompre le processus de démarrage
standard en pressant une touche (si l'option CONFIG_BOOTDELAY est définie et supérieure à 0
dans le fichier de configuration de la carte). U-Boot va alors afficher un prompt et l'utilisateur
pourra, à l'aide de quelques commandes simples, paramétrer la cible, flasher un nouveau noyau, un
nouveau système de fichier.
2.4.1.
Configuration de U-Boot
Le comportement de U-Boot peut être complètement modifié en utilisant le principe des variables
d'environnement. Celles ci peuvent avoir trois types d'utilisation différents :
•
Paramètres de configuration précis définis pour un module : par exemple la variables
bootfile définie le fichier qui sera téléchargé par la commande tftp. De même, l'interface
- 6/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
réseau peut être entièrement configurée en plaçant les bonnes valeurs dans les variables
ipaddr, netmask et gatewayip.
•
Variable intermédiaire à usage de l'utilisateur : toute valeur voulue peut être stockée sous
forme de chaine de caractères, par exemple, les arguments de démarrage du noyau peuvent
être décomposés dans plusieurs variables intermédiaires afin de pouvoir les modifier
facilement sans changer les autres.
•
Macros permettant d'exécuter rapidement des fonctions plus complexes : une variable peut
contenir une suite de commande séparée par des point virgule. Par exemple, un appel à la
commande run $<nom macro> va exécuter la macro en question.
2.4.2.
La console U-Boot
La console est la principale interaction entre U-Boot et l'utilisateur. Habituellement, une liaison
série permet de recevoir un prompt, d'émettre des commandes et d'en recevoir les réponses. Ceci est
très utile en phase de développement, cependant, cela nécessite d'avoir un accès physique sur le port
série. Très souvent le port série n'est pas accessible facilement : il faut ouvrir le boitier, parfois
souder des fils, bricoler un adaptateur de niveau RS323/TTL.
U-Boot permet en option l'utilisation d'une console réseau : la netconsole. Celle ci est activée en
paramétrant des variables internes :
•
stdin : serial pour une console série ou nc pour la netconsole
•
stdout : serial pour une console série ou nc pour la netconsole
•
stderr : serial pour une console série ou nc pour la netconsole
•
ncip : addresse IP de la machine distante qui recevra la netconsole (port 6666)
Il faut aussi ajouter le #define CONFIG_NETCONSOLE dans le fichier de configuration de la carte
afin de rendre disponible la fonctionnalité lors de la compilation.
Lors de l'activation de la netconsole, U-Boot n'affichera plus rien sur la sortie standard série. La
machine distante devra alors utiliser un logiciel afin de récupérer les informations et renvoyer les
commandes. Dans le répertoire tools/ l'utilitaire netconsole permet de se connecter sur la carte
depuis la machine distante.
$> ./tools/netconsole <board ip>
U­Boot> 2.4.3.
Les commandes internes U-Boot
Le langage de script interne offre des commandes basiques:
•
get/set de variable d'environnement
•
exécution d'un script (défini en variable d'environnement ou dans une image script U-Boot)
•
lecture/écriture de la mémoire
•
attribution d'adresse IP par DHCP
•
téléchargement d'images par TFTP
- 7/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
•
exécution de binaires au format SREC ou de noyaux au format uImage
Par contre, U-Boot ne permet pas de faire des opérations sur les variables (addition, soustraction,
multiplication, division), ni de faire des tests conditionnels, ni des boucles.
Les commandes permettant de manipuler les variables d'environnements sont :
•
printenv : affiche les variables d'environnement existantes.
•
setenv [var name] [var value] : ajoute ou modifie une variable d'environnement.
•
setenv [var name] : supprime une variable d'environnement.
•
Saveenv : sauvegarde l'environement dans la flash
•
run [var name] : exécute un script écrit dans une variable d'environement.
Les commande permettant de manipuler une flash NOR sont :
•
cp [source] [dest] [count] : copie depuis la RAM vers la flash
•
erase [start] [end] : efface les données de la flash
•
protect [on|off] [start] [end] : protège les données de la flash
Les commandes permettant de manipuler une mémoire NAND sont :
•
nand read [dest] [source] [count] : lit les données de la NAND et les écrit dans [dest]
•
nand write [source] [dest] [count] : lit des données de [source] et les écrit dans la NAND
•
nand erase [addr] [len] : efface les données dans la NAND
Les commandes permettant d'interagir avec le système sont :
•
reset : effectue un reset du CPU
•
help : affiche la liste des commandes connues.
•
help [commande] : affiche une aide sur la commande en question
•
bdinfo : affiche des informations sur la carte
•
flinfo : affiche des informations sur la flash
•
iminfo :listes les images stockées (noyau, binaire, scripts)
•
md [addr] : affiche le contenu de la mémoire à une adresse précise
Beaucoup d'autre commandes sont disponibles. Pour plus d'informations à ce sujet, il est possible de
se référer directement à la documentation U-Boot.
Il est à noter pour ceux qui aiment optimiser leur temps que toutes les commandes U-Boot peuvent
être abrégées. Seules les lettres servant à valider qu'aucune ambiguïté n'est possible sont nécessaires
dans la commande. Ainsi les deux séquences :
printenv
setenv ipaddr 192.168.0.2
saveenv
et
- 8/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
pri
se ipaddr 192.168.0.2
sa
Auront exactement le même résultat.
2.4.4.
Exemple de commandes
Quelques exemples de commandes utiles et leur résultat illustrant le processus de démarrage lors de
la phase de développement :
•
demander d' une adresse en dhcp va renseigner les champs suivant :
▪ l'adresse IP est assignée à la variable ipaddr
▪ le masque de sous réseau est assigné à la variable netmask
▪ l'adresse du serveur est assigné à la variable serverip
▪ l'adresse de la passerelle est assigné à la variable gatewayip
$> dhcp
BOOTP broadcast 1
DHCP client bound to address 192.168.0.101
•
télécharger le fichier dont le nom est contenu dans la variable bootfile depuis le serveur tftp
serverip et renseigne les variables suivantes :
▪ la variable fileaddr contient l'adresse du fichier en RAM
▪ la variable filesize contient la taille du fichier
$> tftp
Using AT91RM9200_EMAC device
TFTP from server 192.168.0.1; our IP address is 192.168.0.101
Filename 'uImage'.
Load address: 0x20d00000
Loading: ##############################################################
##############################################################
##############################################################
###############################################
done
Bytes transferred = 1295848 (13c5e8 hex)
•
positionner la variable mtdparts pour décrire les partitions de la flash NOR
▪ descriptif des partitions de la flash nommée AT45DB321B.spi0
▪ la première partition (de 0x00000000 à 0x00042000) contient U-Boot
▪ la deuxième partition (reste de la flash) contient le noyau
$> setenv mtdparts=AT45DB321B.spi0:0x42000(U­Boot)ro,­(Kernel)
•
positionner les arguments du noyau pour démarrer en NFS avec une console série
$> setenv bootargs console=ttyS0,115200 root=/dev/nfs rw nfsroot=$
{serverip}:/nfsroots/rootfs_arm/ ip=${ipaddr}:${serverip}:${gatewayip}:$
{netmask}:${hostname}:eth0:off mtdparts=${mtdparts}
•
démarrer le noyau téléchargé (par défaut, si aucun argument n'est fournit a la commande
bootm, la variable fileaddr sera utilisée
- 9/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
$> bootm 0x20d00000
## Booting kernel from Legacy Image at 20d00000 ...
Image Name: Linux­2.6.24.7
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1295784 Bytes = 1.2 MiB
Load Address: 00108000
Entry Point: 00108000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
U-Boot supporte plusieurs types d'images en téléchargement:
•
Scripts U-Boot: permettant de faire des actions particulière en utilisant l'interpréteur de
commande interne
•
Noyau Linux: démarrer un système Linux dont le noyau est au format uImage
•
Binaire statique: U-Boot permet d'exécuter un binaire au format SREC
Une fois téléchargées, ces images peuvent être écrite en flash afin de persister lors d'un
redémarrage.
Par défaut, lorsque la cible est mise sous tension, U-Boot démarre et exécute :
run ${bootcmd}
C'est donc cette commande qui doit initier le processus de démarrage de votre cible en mode
nominal.
2.5.
CODER DANS U-BOOT
L'ajout de code dans un projet demande le plus souvent le respect des conventions utilisées. U-Boot
ne déroge pas à cette règle et suit globalement les normes de codage du noyau. Les principales sont:
•
Indentation par tabulation
•
Ajout d'un espace avant la parenthèse ouvrante
•
Limite d'une ligne à 80 caractères
Pour plus d'information sur ces règles, voir http://www.denx.de/wiki/U-Boot/CodingStyle ou bien
dans le fichier Documentation/CodingStyle des sources de Linux.
L'arborescence des sources, et plus particulièrement le nom des différents dossiers, n'est pas anodin.
En effet, le fichier descriptif de cible va relier directement les nom de CPU / board aux dossiers
correspondant ainsi que le nom de la cible à son fichier de configuration.
2.5.1.
Les fichiers d'include et de configuration
Chaque cible doit avoir un fichier de configuration global. Ce fichier est situé dans le répertoire
include/configs/ et nommé <nom de la cible>.h. Il permet d'ajouter une cible utilisant du matériel
existant en paramétrant ce qu'il faut par des #define :
•
Activation / désactivation de composants matériels (flash nand présente ou non)
- 10/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
•
Activation / désactivation de fonctionnalités logicielles (support réseau actif ou non)
•
Paramétrage de variable spécifique à chaque cible (adresse de base d'un périphérique,
fréquence de l'horloge)
Ceci permet de décrire plusieurs cible relativement similaire (en terme de matériel) sans avoir à
réécrire de code C
Les différentes cibles peuvent
arch/<ARCH>/include/asm/<CPU>/
définir
des
fichiers
d'includes
dans
le
dossier:
Ces fichiers, lors de la configuration de U-Boot pour une cible particulière, seront rendus
accessibles par des liens symboliques dans le dossier include/asm/arch/
Ces fichiers définissent en général les différents registres et GPIO, nommés par des #defines ou
directement définis par des structures.
2.5.2.
Ajout d'un CPU
Les CPU se trouve dans le dossier arch/ classé par architectures, puis par catégories.
Un CPU est défini par :
•
Start.s : codé en assembleur, démarre et initialise le processeur
•
<fichiers>.c : codé en C, gestion bas niveau du CPU
•
Sous répertoires : communication bas niveau avec composants liés au CPU (SOC): codé en
C, définie les fonctions de base des périphériques associés au CPU (contrôleur mémoire,
timers, bus...)
Ces fonctions définissant un SOC sont appelées par les procédure d'init interne U-Boot lorsque jugé
nécessaire.
Dans le cas de l'USB, lorsqu'un accès à un périphérique USB est demandé (par exemple par la
commande usb info, U-Boot va chercher à initialiser le contrôleur USB en appelant successivement
et au besoin, les fonctions: usb_CPU_init(), usb_board_init().
Seul les fonctions spécifiques au CPU se trouve à cet endroit (accès aux registres internes,
adressage spécifique). Toutes les fonctions ne dépendant que du périphérique en question sont
implémentées dans le dossier driver (voir §2.5.4)
Dans le cas de l'USB, seules les fonctions usb_CPU_init(), usb_CPU_init_fail(), et
usb_CPU_stop() sont présentes. Les autres fonctions de l'API USB (définie dans include/usb.h)
sont implémentées dans drivers/usb/host/usb_ohci.h (entre autres).
2.5.3.
Ajout d'une carte
Les cartes se trouvent dans le dossier board/ classées par constructeurs. Ajouter une carte revient à
créer un dossier et ajouter les fichiers d'initialisation.
Les fonctions suivantes devront être implémentées :
•
board_init()
•
board_reset()
- 11/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
Fonction initialisation des périphériques utilisés: par exemple board_eth_init() dans le cas
de l'utilisation d'un contrôleur réseau.
•
2.5.4.
Ajout d'un périphérique
U-Boot crée des bibliothèques pour chaque fonctionnalité. Chaque librairie suit une API bien
définie (en générale décrite dans include/<device>.h). Par exemple l'implémentation d'un nouveau
contrôleur Ethernet demandera la création d'un fichier <my_eth>.c dans drivers/net/ qui
implémentera à minima, les fonctions définies dans include/net.h dans la structure struct
eth_device :
•
int init(struct eth_device*, bd_t*);
•
int send(struct eth_device*, volatile void* packet, int length);
•
int recv(struct eth_device*);
•
void halt(struct eth_device*);
•
int write_hwaddr(struct eth_device*);
de plus une fonction d'initialisation devra être implémentée. Cette fonction sera appelée par le
module d'initialisation des périphériques spécifiques CPU ou board. Cette fonction aura pour charge
d'allouer et de remplir la structure struct eth_device et de la déclarer (en utilisant dans ce cas la
fonction eth_register()) dans la liste des interfaces réseau disponibles. Par convention, cette
fonction est nommée <device>_register().
La carte ou CPU qui voudra utiliser ce driver, devra donc appeler la fonction register
correspondante et définir si besoin les #define associés dans son fichier de configuration.
2.5.5.
Ajout d'une commande
L'ajout d'une commande dans U-Boot se fera dans le dossier common/. C'est ici que se trouve toutes
les commandes présentes dans l'interpréteur interne. Une macro permet de définir la commande en
question, l'aide associée et la fonction C correspondante :
U_BOOT_CMD(cmdname, maxargs, repeatable, cmdfunction, "short help", "long help")
Les commandes sont regroupées par fonctionnalité, le nommage des fichiers est de la forme :
cmd_<fonction>.c.
L'accès aux variables d'environnement depuis le code d'une commande particulière se fait grâce aux
fonctions getenv() et setenv().
- 12/13 -
Tristan Lelong – OpenWide
INTRODUCTION À U-Boot
3.
3.1.
CONCLUSION
U-BOOT
U-Boot est un bootloader très complet et très polyvalent. Il permet un contrôle maximum de la cible
lors des phases de développement. Il sait aussi se faire très petit lors de la phase de production.
Son architecture modulaire rend l'ajout du support pour de nouveaux matériels assez simple, pourvu
que les documentations existent. Souvent, il sera possible de s'appuyer sur des matériels existants, et
le développement n'en sera que plus aisé.
3.2.
AUTRES BOOTLOADERS
D'autre bootloaders sont utilisés dans le monde de l'embarqué. Nous pouvons citer entre autres les
bien connus :
•
redboot : Red Hat Embedded Debug and Bootstrap firmware
•
barebox : aussi connu sous le nom de U-Boot v2, il associe la souplesse et la légèreté de UBoot avec une architecture similaire au noyau Linux
•
syslinux : plusieurs modules comme ISOLINUX (boot depuis le cdrom), PXELINUX (boot
réseau), EXTLINUX (boot depuis un système de fichier) permettant de démarrer un système
Linux.
•
Etherboot/GPXE : boot réseau supportant de nombreux protocoles
Actuellement, Barebox supporte moins d'architectures que U-Boot (notamment les architectures
plus ancienne). Cependant, les fonctionnalités présentes peuvent être très intéressantes comme
l'accès à un environnement de type système de fichiers ainsi qu'un interpréteur de commande plus
complet.
Le principal concurrent de U-Boot en terme de fonctionnalité est redboot. Celui ci est supporté par
redhat. Tous deux supportent un grand nombre d'architectures CPU, de carte cible, et tous deux
permettent d'accéder à un interpréteur de commande au démarrage.
Le choix d'un des bootloaders sera alors une question de connaissance (de l'un par rapport à l'autre),
et de support de la cible concernée.
- 13/13 -

Documents pareils