Warning: Cannot modify header information - headers already sent by (output started at /home/gillesbld/www/weblog/inc/config.php:41) in /home/gillesbld/www/weblog/inc/clearbricks/common/lib.http.php on line 222

Warning: Cannot modify header information - headers already sent by (output started at /home/gillesbld/www/weblog/inc/config.php:41) in /home/gillesbld/www/weblog/inc/clearbricks/common/lib.http.php on line 224

Warning: Cannot modify header information - headers already sent by (output started at /home/gillesbld/www/weblog/inc/config.php:41) in /home/gillesbld/www/weblog/inc/public/lib.urlhandlers.php on line 65

Warning: Cannot modify header information - headers already sent by (output started at /home/gillesbld/www/weblog/inc/config.php:41) in /home/gillesbld/www/weblog/inc/clearbricks/common/lib.http.php on line 247
Embedded weblog - page 4

Embedded weblog

Aller au contenu | Aller au menu | Aller à la recherche

lundi, décembre 15 2008

le libre contre-attaque

Ouch, coup sur coup, une attaque de trois développeurs (avec la FSF France en sous-main, n'en doutons pas trop) contre Free, ce qui leur pendait au nez depuis un bon bout de temps, suivi juste ensuite d'un attaque de la FSF (tout court) contre Cisco (via Linksys) : mêmes raisons, mêmes effets et même milieu. Celui de l'embarqué, bien sûr. Deux box, l'une de type modem/Set Top Box (Freebox), l'autre de type routeur évolué de maison (WRT54), comprenant de manière certaine des Linux (avec Netfilter), des busybox, des libC, et que sait-on d'autre, mais pas de code redistribué en contre-partie. Pour l'instant, les deux parties sont présumées innocentes (je précise, parce qu'à 6h30, je dors, et que je tiens à mon intimité -- et mon bon PDG, responsable de ma publication même s'il ne doit me lire que bien peu, certainement aussi, d'ailleurs je précise au cas où un Capital aurait été raté qu'il est pilier au rugby !), mais que se passera-t-il en cas de condamnation ?

Eh bien c'est simple : outre les dommages et intérêts à déterminer (pour Free, on demande 10 millions d'Euros, soit grosso modo pour chacun des trois 1€ par box, ce qui est fort peu : certaines royalties tapent dans les 5$, pour des softs franchement bidons que nous ne citerons pas pour des raisons évidentes), il faut faire cesser le litige (sous peine d'astreinte) : deux choix s'offrent alors. Soit on écoute la bonne licence et on libère le code, c'est-à-dire que l'on fait disposer à tout un chacun le demandant (et pouvant s'en prévaloir : il faut avoir acheté l'appareil concerné) un CDrom les contenant, ou alors on ne s'embête pas et l'on tient un ftp public (regardez comme ils sont sympas chez Sony : Linux, busybox, uClibc, cross-gcc, et p'têtre deux ou trois autres trucs, pour chaque appareil, tout simplement, d'ailleurs ils devraient mettre en toute rigueur les scripts de compil, mais ils ne le font même pas). Soit, deuxième solution, on rapatrie les box et on change tout le logiciel, mais je crois que ça risque de coûter assez cher (c'est mon petit doigt qui me le souffle), et que ça ne vaut pas vraiment le coup (sinon, Linagora se propose de tout vous faire migrer sous BSD, on peut vous faire un prix d'ami je pense, c'est bientôt les soldes).

Ou alors on paie l'astreinte, mais tout le monde n'est pas Microsoft (heu, c'est de notoriété commune, c'est pas de la diffamation, hein chef ?). On ne badine pas avec la GPL, à bon entendeur... Pour ma part, j'ai vécu aussi des choses assez ubuesques, comme des demandes explicites de ne surtout pas changer une seule ligne de code d'un programme libre (même pour quelque chose de très bête, qu'il a fallu contourner à grands coups de scotch et de ficèle), pour ne pas avoir à la redistribuer ensuite (on ne parle même pas de faire l'effort de la réintégrer auprès de la communauté, comme s'engage Linagora à le faire plusieurs fois par jour !). Ce n'est pas pour rien que j'insiste toujours sur le côté juridique de mon cours, partie qui assomme régulièrement mes étudiants, pressés de brancher leur premier câble RS232 (pour avoir... un prompt, c'est qu'on est heureux avec peu, lorsqu'on est jeune).

Et Linagora dans tout ça ? Eh bien... notre projet de logiciel embarqué, qui nous occupe depuis un bon bout de temps, est sous BSD (OpenBSD). Forcément, ça fait moins de problèmes juridiques à l'arrivée (mais juste juridiques... Et à vrai dire, ce n'était pas pour une question de licence que cela a été choisi ainsi : embarqué ne veut pas dire accessible à tout un chacun ! Seul le client peut se prévaloir de la licence et réclamer les sources couvertes par la GPL). Sinon, nous dispensons aussi des cours en Droit Individuel à la Formation, par Benjamin Jean, une pointure vous dis-je, et si ce n'est certes pas donné, il faut bien se dire que des conférences pleines au salon RTS il n'y en a qu'une par an (et... il n'y avait pas vraiment de juriste présent, d'après mes souvenirs), et puis que ça peut faire économiser potentiellement un procès et 10 millions d'Euros pour couvrir à tout prix (c'est le cas de le dire) des NDAs ou une sécurité foireuse que l'on n'avait pas pas bien considérés avant, en fait...

mercredi, décembre 10 2008

les comportements erratiques de syslog-ng

* un fichier sans ligne "destination remote" implique une impossibilité de démarrer syslog-ng (avec une erreur franchement pas belle, ça râle)
* un fichier avec un "destination remote { };" garde les logs uniquement en local
* un kill -HUP envoyé sur un syslog-ng relit le fichier de conf et le prend en compte (sans changer le PID, mais un changement de filtre en plus permissif montre bien que ça été pris en compte)

Soit un fichier avec un "destination remote" avec ou sans IP à l'intérieur permet de démarrer le syslog-ng sans problème. On enlève la ligne "destination remote". On envoie un -HUP. Question : que se passe-t-il ? Eh bien rien du tout. Encore un bug non détecté... (pour le cas où l'on démarre le démon à la main, ce qui en l'occurrence n'arrivait qu'au démarrage, et pour un fichier sans adresse IP de serveur distant : il fallait deviner que ça ne voulait pas démarrer sans !)

jeudi, décembre 4 2008

quid des lutins ?

La QOTD :

libcurl is completely agnostic about the underlying transport layer being
ethernet, gprs or carrier pigeons!

(Daniel Stenberg, libcurl development)

comment inline changea le monde

Enfin, je pense. Inline, ce n'est pas dans le C, à la base, ai-je appris ce matin ; manifestement, ça n'a été standardisé qu'en 99, alors que GCC le gérait déjà depuis belle lurette (j'ai déjà dit à quel point gcc était génial ? Ah, oui...). Alors comment faisait-on avant ?

Eh bien manifestement, c'est horrible, mais on n'utilisait que les macros. Retenez votre respiration, cher lecteur (de plus de 16 ans, en dessous, fermez votre navigateur immédiatement !), et allez voir par ici...

mardi, novembre 25 2008

ARM European Technical Conference

J'ai pu assister toute la journée de jeudi 20 novembre à la conférence européenne de ARM, qui se tenait à Paris, tout prêt de la tour Eiffel. Le programme était lourd et a priori fort intéressant et les partenaires nombreux et de qualité. Je ne connaissais absolument pas ce rendez-vous de l'informatique embarqué, dont je me demande même s'il a lieu toutes les années en France (j'aurais dû demander, certains étaient manifestement des habitués de l'événement) ; en fait, c'est par le biais d'OK-Labs que j'ai appris l'existence de cette manifestation. La rencontre s'est déroulée depuis le matin, vers 9h00 (je suis arrivé à peine plus tard) et a duré jusqu'à 18h45 environ ; j'ai pu assister à cinq conférences techniques.

A mon arrivée, je me vois offrir, outre un porte-badge plein de poches pratiques, un sac en tissu simple contenant déjà quelques tracts et un programme de la matinée (les sessions sont nombreuses, quatre à chaque fois, et on rappelle sur le badge quelles sont celles pour lesquelles on s'est inscrit), mais surtout, un sac pour PC portable à deux grandes poches, très pratique et de fort bonne qualité : on ne se moque pas du monde, chez ARM ! L'organisation sera parfaite de bout en bout, enfin si j'avais pu savoir où rendre ma feuille de sondage d'opinion à temps j'aurais pu participer au tirage au sort, dommage (de manière fort amusante, je remarque que près de deux goodies sur trois à gagner tourne sur du Linux embarqué !). Parlons donc rapidement, puisqu'on y est, du repas : asiatique ou crustacés (même... des huitres !), j'aurais été subjugué par la fontaine à chocolat : il faut absolument penser à donner une prime à la dame qui a impulsé l'idée !  :)

Je fais un premier tour rapide sur les stands avant d'arriver enfin aux premières conférences communes (outre les cinq techniques, donc) : je n'avais pas imaginé que le nombre de participants serait si grand ! D'ailleurs, comme il y a finalement assez peu de temps libre pour y passer -- trois fois quarante minutes, grosso modo -- je n'ai malheureusement pas pu aller sur tous les stands, dommage. Je commence donc véritablement avec une première intervention de NXP (Geoff Lees, lis-je sur mon programme, je n'ai malheureusement pas eu de slides des interventions -- en fait je me demande même s'il y avait un moyen de les récupérer, peut-être ai-je rêvé --, mais j'ai envoyé un mail au contact ARM pour savoir s'il était possible de les obtenir : on devrait me les envoyer par CD ! :)  ), "The ARM Microcontroller (R)evolution" ; NXP vise à obtenir une rétrocompatibilité binaire parfaite entre ses MCU sur base ARM, je ne sais pas si c'est une si bonne idée (les casseroles du x86 ?), mais en tout cas ça révèle quelque chose que l'on reverra souvent : moins on fait appel au développeur software (même pour une recompilation simple !), et mieux on se porte.

Il me semble d'ailleurs que c'est Semir Hadda, le manager du marketting de STMicroelectronics, qui a traumatisé l'assistance en affirmant qu'il fallait commencer le développement logiciel le plus tôt possible, car c'était là où tout se jouait, à l'heure du hardware peu cher et plus facile qu'avant à obtenir ; penser d'ailleurs à la phase d'optimisation software avant d'augmenter la puissance hardware. Le message est dans la même ligne que celui de Reinhard Keil, le directeur des outils MCU chez ARM, avec sa conférence "ARM Microcontroller: Strategic view". Il ressort de tout cela que les acteurs en ingénierie embarqué sont par exemple intéressé à 70% par des outils de débuggage performants, et ce avant même la considération des performances et de la robustesse des produits : on sent le time to market et la solidité des développements softwares devenus de plus en plus complexes au coeur des attentes -- et des craintes ? -- des différents acteurs.

D'économie de marché, il en a été fortement question avec l'intervention de Malcolm Penn, le CEO de Future Horizons, qui avec "Vision 20:20... Designing Tomorrow's Systems Today", nous a expliqué qu'il a déjà vu des crises, que c'est cyclique, et que l'on est effectivement en train de plonger -- ça coupe avec l'optimisme affiché des précédents intervenants, avec leurs graphiques tous exponentiels !  Il n'y a pourtant pas de quoi s'inquiéter, apparemment : si des gros ont déjà disparu par le passé, cela peut toujours arriver maintenant (j'apprendrai plus tard que Atmel a eu chaud, récemment : pourtant leurs produits sont réputés excellents !), mais le marché survit et se restructure (on dirait presque du Friedman avec une touche de pragmatisme, mais on n'en sort pas bien rassuré tout de même). Il nous entretient ensuite de l'importance capitale, à ce niveau, de la R&D : celui qui ne suit pas meurt, c'est aussi simple que cela, et il faut à l'heure actuelle deux à trois ans pour sortir quelque chose de viable. C'est-à-dire que si une société s'avise de couper dans le budget de l'innovation sur ses MCU, à la nouvelle génération, soit deux à trois ans plus tard (durée qui tend à s'allonger, ce qui représente un problème pour l'arrivée de nouveaux concurrents), cette société disparaîtra brutalement, alors que jusque là tout pouvait aller fort bien. Voilà un avertissement qui a le mérite d'être clair. Cependant il parle très vite (ça part dans tous les sens, d'ailleurs) et ses slides sont plein à ras bord, il saute beaucoup de choses, bref j'espère que l'on pourra retrouver quelque part son analyse et se pencher dessus.

Ainsi s'achève la première session de mini-conférences communes, vers 11h20 ou 11h30. Je peux donc commencer la visite des stands, et en fait le temps passe fort vite en compagnie des intervenants de Virtual Logix ; il faut dire que la paravirtualisation est toujours mon sujet favori, ce qui donne donc lieu à des échanges intéressants (nous parlons notamment d'une fonctionnalité avancée de redistribution à chaud de mémoire vive entre les différentes VM). Qui plus est, le positionnement de Linagora sur le marché peut tout à fait intéresser de manière complémentaire des sociétés proposant du logiciel très embarqué (l'hyperviseur est sous le noyau, avec des impacts au niveau drivers, on est loin du userland !), dont la spécialisation ne peut proposer aux clients souhaitant un système complet (j'ai déjà travaillé sur des projets avec des pages web CGI, par exemple : on peut aller jusqu'à un niveau assez élevé, en embarqué !), ce à quoi Linagora peut tout à fait répondre avec notre équipe d'experts en Linux embarqué. Il est 11h50 : l'heure de rejoindre le rez-de-chaussé (le principal du forum se passe au niveau -1 de CAP15) pour assister à la première conférence technique, menée par Nick Sampay : "Using trace to optimize system performance".

On aurait pu croire à une présentation du debug software en utilisant sondes J-TAG ou autres moyens, mais en fait c'est du hardware dont il va être question, plus exactement de l'organisation des bus et buffers pour dumper registres et pipeline, jusqu'à une éventuelle sortie sur port J-TAG. On est très enfoui, et même si c'est intéressant, un certains nombre de personnes quittent prématurément l'assemblée en se rendant compte que ce n'est pas pour eux ; ce n'est pas vraiment pour moi non plus, mais l'aspect de culture générale n'est pas inutile. Dommage cependant que ce n'étais absolument software, peut-être aurais-je dû aller à "Optimizing Software using ARM tools - profile driven compilation", mais je pense que ça aurait été essentiellement de la publicité pour RVDS, et j'en aurai de toute façon eu pendant encore les deux sessions suivantes...

Durant la pause déjeuner, je rencontre un ingénieur de Trango Virtual Processors, et malédiction, comme un certain nombre d'intervenants, il n'avait pas ou plus de carte de visite, je ne me souviens donc déjà plus de son nom -- nous avons commencé à travailler en même temps pour la société, mais on avait dû se croiser que très rapidement, d'ailleurs j'ai appris que j'avais été le premier "extérieur" à travailler sur Trango, et le premier à expérimenter le développement à distance. C'est l'occasion d'évoquer le rachat récent par VMware : il m'est confirmé que l'entreprise est à présent entièrement la possession du leader américain de la virtualisation (propriétaire), et n'entretient donc plus aucun rapport (déjà très symboliques) avec le groupe Elsys. La société voit cela comme une reconnaissance d'un très grand acteur du marché (c'est plus de 1600 personnes, VMware !) de sa solution, qui rappelons-le est codée à partir de zéro, contrairement aux autres compétiteurs du secteur (VLX et OKLabs se sont basés respectivement sur les microkernels ChorusOS et L4, quant à Sysgo ils ont récupéré leur kernel pour aéronautique PikeOS), lui assurant la plus petite empreinte mémoire (15~20Ko). C'est l'analyse que j'ai aussi faite ici-même.

Je rencontre aussi durant cette pause, et pour la première fois, l'équipe d'OK-Labs. Du moins la fort charmante Brenna Walters, venue tout droit du bureau de Chicago (mais elle est originaire de LA, pas tout le monde n'est australien chez OK-Labs, manifestement !), qui s'occupe justement de la communauté Open Source. Et distribue les T-shirts "I run in privileged mode", phrase d'un humour hautement geekesque... inspirée par elle-même ! Evidemment, nous parlons boutique, puisque mon ancien stagiaire a travaillé durant six mois sur leur produit OKL4, un hyperviseur de paravirtualisation que l'on aura pu tester, comprendre, et pour lequel Linagora aura montré son intérêt et son investissement actif dans la communauté (ML, wiki d'aide, etc). Et puis Abi Nourai, qui prend la direction technique en Europe, à Vélizy (avenue de l'Europe, justement, côté Auchan pour situer), mais qui avait quelques rendez-vous toute la journée : je n'ai donc pu le croiser que fort rapidement à ce moment-là, et ce n'est que plus tard que nous aurons eu la possibilité de faire plus ample connaissance.

En attendant, l'après-midi débutant, c'est à la conférence "Moving to 32 bit MCUs and High Level Programming" que je me suis rendu, la présentation étant toujours assurée par Nick Sampays de ARM.Nous parlons en réalité uniquement de ce que propose Keil pour ce faire. En fait, cette compagnie rachetée en 2005 concentre à présent les outils de développement pour ARM, et on passe donc en revue MDK (Microcontroller Development Kit), avec son compilateur RealView (que je connais fort bien : j'ai eu l'occasion de travailler dessus, pour Trango justement -- et NXP indirectement --, et j'ai entièrement lu les centaines de pages de documentation autant de armcc que de armlink et leurs autres logiciels de la suite), son IDE µVision (qui de base n'a rien de bien original, mais présente des aspects très intéressants : chargement de code sur cible via J-TAG ou simulation du device en deux clics -- avec débuggage facilité --, options de compilations en clickodrome, couverture de code avec statistiques d'exécution, ou encore un analyseur logique qui présente des graphes dans l'idée d'un oscilloscope), sa bibliothèque C avec son pendant très allégé Microlib (on est dans l'idée de la µClibc, mais on annonce 92% de réduction d'utilisation mémoire !), et enfin le câble J-TAG ULINK2. Une grosse page de publicité qui dure 40 minutes, comme toutes les conférences techniques (et non commerciales :)  ).

Problème : il semblerait que au moins µVision (et peut-être les autres logiciels ? Pour RVDS, je sais qu'une version Linux existe, puisque je l'avais) ne soit disponible que sous Windows, en fait on ne parle même pas de l'OS d'accueil, et très généralement tout le monde présente des outils sous Windows dans les stands et les communications (à noter que OKLabs n'utilise que MacOS X, et que Trango est sous Ubuntu). Aussi, Reinhard Keil (mince, de la société Keil, je comprends mieux pourquoi c'est le directeur !) lorsqu'il nous présente la conférence suivante est aussi Windows-centré (on aura même droit à un soft pour éclairer/éteindre des LED d'une carte de dev, compilé en Visual C++... Berk). "ARM Real-Time Library: Facing Embedded Technology Challenges" était alléchant pour la même raison qu'un peu tous les acteurs en R&D embarquée recherchent des outils déjà existants pour réduire le fameux TTM (c'est après les outils de debug l'une des plus importantes attentes). En fait, on va nous parler de RTX, le mini-noyau temps réel de ARM/Keil. Libre de toute royalty, et pesant entre 1,5 et 5ko tout dépend de ce que l'on y met dedans, c'est l'occasion de renouer avec un monde industriel où le hardware est toujours roi : explication de ce que sont UDP et TCP (avec différences), d'Ethernet (avec connexion par PPP, SLIP et dial-up), on évoque aussi les serveurs http avec CGI (quand je disais que c'est à la mode...), le telnet ou le TFTP, le SMTP ou DNS, bref des choses bizarres pour l'électronicien (raté, c'est bien connu), mais tellement standard pour l'ingénieur informatique je pouffe intérieurement de rire lorsque l'on présente cette révolution : "TCP network provides easy solution to connect to the world". Ca remet les idées en place. RTX fournit un file system pour flash (RL-Flash), un support des différentes piles USB par RL-USB (HID/MSD/Audio, l'occasion de présenter rapidement cette grande avanceé qu'est l'USB...), et même un support du bus CAN (RL-CAN, on l'aura deviné). Possibilité d'obtenir les sources dans la version deluxe que l'on imagine plus chère, à l'exception de la pile TCP/IP (toujours la partie sensible...). Je rêve d'une comparaison de tout cela avec RTEMS.

45 minutes de pause, je passe par NXP qui présente sa série LPC (IDE sous Windows) avec un anglais néerlandais qui n'invite pas trop à s'attarder, puis je vois Texas Instrument, et c'est la révélation. Car TI (France, à Villeneuve-Loubet, près de Nice, mais ma première interlocutrice Marie-Claire Desjardins, dénuée de carte de visite, m'a bien dit venir de la banlieue parisienne) n'est pas seulement très intéressé par Linux embarqué -- et sur leur stand, une télé diffuse justement les applications graphiques lancées sur une carte : ce qui les attire, c'est le communautaire ! Aussi peut-on lire en cinq pages un document "TI Linux and Open Source Initiative Backgrounder", et pour bien montrer leur engagement, une carte de développement à base de ARM Cortex-A8 est présentée : cette carte n'est pas banale puisque ses spécifications sont entièrement ouvertes, dans un projet communautaire, pour un mini-prix de 149$. En revanche, pas de port Ethernet et un seul USB OTG (on-the-go, c'est-à-dire qu'il peut tout faire, host, target ou audio), mais en échange une sortie HDMI/DVI et une autre S-Video : c'est que l'on peut faire de la 3D avec ce genre de MCU. En effet, les OMAP font partie des choses fabuleuses que l'on peut rencontrer dans l'embarqué (j'ai travaillé moi-même sur le Sagem MO300e, toute la partie système Linux "distribution maison" vient de moi, sur un OMAP730, d'après la photo de famille) : à présent la série des OMAP35x est considérée comme quatre fois plus puissante que la génération précédente des ARM9 (cadencés jusqu'à 450Mhz, mais chez OMAP, on est passé directement aux ARM11 à 330Mhz), et quand on pense qu'avec les 200Mhz de mon processeur je faisais booter en dix secondes un Linux 2.6.19 virtualisé avec un nucleus, noyau Linux qui démarrait dans sa séquence d'initialisation un serveur http (lighttpd) et un autre ssh (dropbear), on imagine alors les possibilités de ce Cortex ! (il va certainement conquérir le monde) Je repars avec beaucoup de documentation (disponible à mon bureau).

L'échange avec TI fut des plus enrichissants, et partageant des visions communes, j'espère très fortement que nous pourrons travailler ensemble. D'ailleurs, ce type de partenariat entre fournisseur hardware et développeurs software pouvait se rencontrer à peine plus loin, sur le stand d'Antycip, qui ne faisait pas que montrer ses belles cartes de développement professionnelles (prévoir de la place pour en stocker une !), mais faisait aussi la publicité de Montavista, dont on ne distribuait pas seulement des yoyos lumineux (avec un système de dynamo : ça c'est goody !) : la plus célèbre des sociétés en Linux temps-réel est en effet recommandé et présentée sur les stands d'Anticyp comme leur intégrateur de Linux embarqué/RT de préférence, et vice-versa. Leur solution de développement et d'intégration sous Eclipse (qui reste un "must-see" : en quelques clics, on se construit un file system complet !) bénéficie par ailleurs d'une diffusion sur écran plasma géant. Cela me donne l'occasion de parler de stratégies (d'alliances, de partenariats), de perspectives (on me confie qu'en réalité le gros du chiffre d'affaire est effectué par la vente massive à des clients très nombreux de microcontrolleurs de faibles performances, et qu'en fait le nombre d'acteurs sur des secteurs tels celui concernant l'ARM Cortex-A8 est très petit, mais cela est compensé par la diffusion massive en millions d'exemplaires des solutions obtenues, eu égard au type d'applications visées), d'état du marché (certains ont eu très chaud cette année, comme je disais plus haut). Malheureusement, encore un qui n'avait plus de cartes de visite, mais il aura eu la mienne (très... artisanale, c'est vraiment la crise pour tout le monde :)  ). Je me précipite alors, avec un peu de retard, à la conférence sur "Software driven low power optimization for ARM mobile architectures/Multimedia processors power management".

Le premier intervenant est de la société Synopsys (intéressant comme nom !), mais je n'ai pas pu noter son nom (en revanche son prénom est Markus) ; il nous préconise de démarrer le développement logiciel as soon as possible (on continuera tout le temps à parler anglais, même lorsque les intervenants sont francophones : il y a toujours quelques personnes dans la salle qui ne le sont pas, tandis que tout le monde parle anglais ; on y repensera très fort la prochaine fois que l'on médira sur notre système scolaire), ce qui ne va pas sans traumatiser les décideurs hardware, mais c'est ainsi : il nous montre avec une courbe que si l'on démarre tôt, on aura le temps, après avoir ajouter des fonctionnalités demandées qui vont charger la mule (soit le CPU), d'optimiser cette partie software, et ainsi de ne pas avoir ni à augmenter la puissance du hard, ni à perdre en puissance disponible (tant en terme de calcul que de durée de batterie). Je ne peux qu'approuver, et il ajoute même que "Software rules power consumption", voilà qui a le mérite d'être clair. Il vante en outre les mérites de la simulation, et donc du profiling. Marie-Claire Desjardins, de Texas Instrument (Engineer, pas commerciale), nous parle ensuite de "the flexible dynamics of power management in multimedia processors", et nous démontre encore en deux coups de cuiller à pot que TI est très impressionnant dans son domaine. On nous présente le système TI SmartReflex, qui permet de diminuer à la volée le voltage pour diminuer les pertes (dynamic voltage and frequency scaling -- DVFS -- et l'adaptive voltage scaling -- AVS), et dispose de deux systèmes complémentaires : le Dynamic Power Switching (DPS, on arrête ou réduit des parties lorsqu'elles sont inutilisées, avec une détermination à chaud) et le Static Leakage Management (SLM, on met le processeur dans un état de veille prolongée en un clin d'oeil, afin de prolonger pendant plusieurs jours la durée de vie de la batterie : c'est ce que l'on trouve par exemple, à mon avis, sur le N770 dès lors que l'on referme le clapet). Ces technologies avancées sont disponibles sur l'OMAP35x, ce qui prouve que je ne disais pas des bêtises en le qualifiant de merveille de l'embarqué. On trouvera sur le sujet (avec des graphes identiques) des papiers sur powermanagementdesignline ou son équivalent pdf sur ti.com.

Il est alors l'heure de passer à la dernière conférence, sur la paravirtualisation. La première partie est assurée par le fraichement nommé European Technical Director d'OK-Labs Abi Nourai : "design a better feature phone with paravirtualization". Son propos est simple, et c'est celui que je soutiens depuis de années pour ma part : l'augmentation des fonctionalités attendues par les appareils est en constante augmentation, à tel point que l'on en arrive à des OS de type "desktop-like", tels MacOS (iPhone), Windows (Mobile/CE) ou Linux. Et aussi à une attente d'ouverture (possibilité de configurer/rajouter des fonctionalités propres à l'utilisateur), qui ne va pas sans impact au niveau de la conception software (il serait facheux, par exemple, puis-je préciser, qu'un utilisateur lambda de téléphone puisse transformer son appareil en brouilleur). Aussi, nous sommes partis de systèmes d'exploitation simples, et à présent ils sont très sofistiqués. Cependant, les piles de communications représentent de gros investissements, et le re-engineering augmenterait de facto le Time to Market, ce que l'on ne peut jamais se permettre. La solution est alors de faire appel à la paravirtualisation (ou comment ménager la chèvre et le chou dans deux espaces mémoires séparés). OKL4 est alors rapidement présenté -- on évoque rapidement sur les slides le trop peu connu FASS (Fast Adress-Space Switching : je ne trouve pas de lien probant sur le net, c'est toujours une galère sans nom de trouver des informations dessus !), mais on n'ira pas aussi bas dans le discours. Ce qui est certain, c'est que OpenKernel Labs attaque fort niveau stratégie : plus de 200 millions d'appareils (devices) contenant leur solution actuellement distribués, ils tablent sur 250 millions à la fin de l'année, notamment grâce au HTC Dream (G1) qui fait tourner un Linux Android ! Ils ont de plus une "agressive roadmap" (je me mets à parler franglais, c'est pour ma future carrière de commercial) pour la preuve formelle de sûreté de fonctionnement ("correctness", c'est moins fort que la sûreté peut-être, mais comme rien de précis n'a été indiqué... On peut penser à EAL 5 ou 6). OKLabs se définit actuellement comme le leader du marché.

C'est alors au tour de Jean-François Roy de Trango (déjà rencontré sur le salon RTS 08, il est entré après moi chez Trango, je n'ai donc jamais travaillé avec lui, contrairement à Pierre Coulombeau ou Bruno Zoppis, qui s'occupaient avant des salons français, et sont manifestement devenus globe trotters hors France à présent : Trango a d'ailleurs une entité d'une vingtaine de personnes aux USA, soit une bonne partie des salariés de la société !) : si avant la dernière conférence de la journée chacun disait expédier sa présentation en largement moins de 20 minutes, finalement ils mirent chacun une bonne demi-heure. Pourtant, "achieving drivers portability through platform virtualization" (hhmm, driverS ?) ne parla pas technique, du moins on a juste évoqué les possibles répercussions à la fois sur le code -- le plus petit du marché, 20 à 30 Ko -- de Trango ou sur celui du noyau qui doit utiliser la mémoire partagée par ledit driver pour récupérer des piles ou autres, sans énumérer lesquelles. En fait, on a plutôt parlé du pourquoi d'une idée aussi saugrenue (GPL, ABI d'un pilote fermé qui n'est plus en adéquation avec celui d'un nouveau kernel), et de ses mérites logiciels, comme l'indépendance à l'OS ou l'invulnérabilité de celui-ci à un crash éventuel du driver, porté hors noyau (on évitera ainsi un panic/Oops sous Linux). On insiste en tout cas surtout par le rachat récent par VMware, datant du 14 octobre (et rendu public le 10 novembre), d'ailleurs toutes les slides ont migré sur le modèle bleu ciel VMware !

C'est ainsi que s'achève cette journée du ARM European Tecnhnical Conference. Enfin, je fais tout de même un dernier tour des stands, et comme je discute avec un ingénieur d'Adeneo, qui serait notre concurrent direct en terme de développement et intégration spécifique de Linux embarqué (mais dans une optique SSII forfait/prestation à 70%/30%, proche de l'industrie lourde, essentiellement basé à Lyon et un peu à Massy, pour ce que j'ai compris), je rate le tirage au sort. Je termine ma soirée en compagnie d'Abi et Brenna d'OKLabs, qui aurait bien bu une bière avec moi (ou plutôt un lait-fraise pour ma part), mais j'avais malheureusement quelqu'obligation : ce n'est que partie remise ! En tout cas, nous avons fait deux photos que j'espère pouvoir récupérer et publier ici-même. Très, très bon contact avec nos amis d'OKLabs, ce qui confirme la fort bonne impression des précédents entretiens téléphoniques et par mail que nous avions pu avoir ; j'espère que nous pourrons un jour proche travailler sur des projets communs.

En conclusion on peut remercier amplement (ce que j'ai déjà fait là-bas et pas mail) l'équipe organisatrice de ARM, et j'ai pour ma part gardé le ARM bag (mieux qu'un handbag ! :)  ). J'ai été surpris par le très bon format de l'événement, finalement on aurait fort bien pu y emmener notre PDG, mais je ne pouvais pas le savoir avant ; peut-être pourrions-nous y exposer l'année prochaine, les stands concentrés sur le logiciel pur étaient peu nombreux mais tout de même présent, c'est à voir, donc (dans tous les cas, je ne pense pas qu'une exposition à RTS soit souhaitable, par exemple : l'événement aura lieu strictement en même temps que solution Linux, à quelques mètres de là ; en revanche je vais relancer le responsable des conférences). Il est seulement regrettable de n'avoir pas eu assez de temps, avec les conférences, pour faire le tour de tous les stands (comme le montre la dernière photo prise juste à la sortie d'une conférence, les rangées étaient plutôt vides durant celles-ci, alors qu'il était difficile de se déplacer pendant les pauses avec l'assistance très nombreuse). La documentation rapportée a déjà pu être redistribuée à ceux qui ont montré un vif intérêt (celle de TI pour l'instant remporte le plus de succès ; je pourrai en outre mettre à disposition le CD avec les slides dès sa réception), et certains contacts pris (ou repris) mèneront je l'espère à des relations privilégiées. Si l'on ajoute que les conférences et la prise de température générale du secteur ont pu enrichir mon point de vue sur la situation actuelle, je pense que cette journée de visite fut une expérience des plus réussies.

mercredi, novembre 19 2008

GCC everywhere

Hier soir, Basile Starynkevitch (j'arrive à écrire son nom d'une seule traite maintenant ! :)  ) nous a présenté GCC, ou du moins sa partie propre à la compilation (nous n'avons donc pas abordé (ld, objcopy ou gdb, par exemple : nous n'avions qu'une heure trente !), dans le cadre d'une conférence libre pour Parinux (et l'APRIL aussi, si l'on veut). L'organisation, tant sociale que technique du projet, a été au coeur de cette descente dans les entrailles du compilateur libre le plus célèbre. Et ce qui tombe bien, c'est que Basile est passionné par la même chose que nous : l'embarqué !

J'insiste souvent dans mes slides de cours ou de conférence sur le fait que GCC est le pendant sous-estimé de "Linux Embarqué" : non seulement ce logiciel libre sous copyright de la FSF et de facto sous GPLv3 est utilisé dans tous les projets Linux existant (je ne vois pas quel projet ne le ferait pas, on peut supposer que ça existe, mais j'attends de voir...), mais en plus il fait partie intégrante depuis des années des SDK d'OS temps réels bien propriétaires, tel celui de VxWorks ! De fait, GCC n'étant soumis à aucune licence restrictive, on l'utilise partout au moins pour faire des tests. Aussi, si l'on a un compilateur propriétaire sur un projet (RVDS, ObjectAda, Intel Compiler, etc), la licence étant restrictive à un certain nombre d'utilisateurs, on voit les développeurs utiliser GCC en temps de développement, et n'utiliser que le compilateur propriétaire pour le logiciel à réellement embarqué.

Et encore : le compilateur propriétaire est une espèce en voie d'extinction. Qui a entendu récemment parler des compilos de Thomson ou de ST ? Avant, la mode était de créer un CPU et son compilateur associé ; avec le resserrement de l'offre des architectures (certaines puces Thomson ont disparu depuis quelques années, et le CNES fait appel à ses réserves pour équiper ses satellites !), et l'omni-présence de GCC grâce à son organisation permettant d'attaquer toutes sortes de matériels, il n'est plus rentable d'investir dans des compilateurs fermés. Pis encore : il est absolument évident qu'un "méta"-compilateur tel que GCC, capable d'avaler bien des langages, de compiler ou cross-compiler pour bien des architectures, avec une modularité, des options et des extensions de langage à un niveau jamais atteint ne sera jamais plus dépassé. Microsoft est encore le seul à lutter (et pourquoi pas Borland ?), mais il n'y a qu'à compiler du C++ un peu complexe pour se rendre compte que l'on est loin du niveau de GCC.

De fait, les équipes d'Intel ou AMD sont investies dans le projet, à présent. La collaboration de ces entreprises pourtant  concurrentes par nature est même exemplaire. Mais le succès de GCC serait encore bien supérieur à ce que j'imaginais. On m'a parlé de versions certifiées, en DO-178B, que ça, et un membre du public (ingénieur en informatique embarquée dans une grande société concernée) m'a même assuré que du code sur la ligne 13 était compilé par GCC (cependant, est-ce le navigateur ou les freins, ou est-ce l'éclairage clignotant de la loupiotte à l'approche d'une station ? Ce n'est pas pareil ! Dans l'absolu, il y a du code compilé par GCC dans les avions, il y a même du Linux dans les derniers, mais c'est pour du multimédia : quid du navigateur de bord ? Je doute toujours). J'essaierai de faire parler des contacts, mais ce n'est pas facile : la complexité des solutions actuelles, de leur organisation logistique, et le mutisme du milieu industriel, empêchent d'avoir une visibilité fiable et globale des utilisations des logiciels libres en général, et la question du compilateur employé reste définitivement délicate.

J'espère que les slides seront bientôt disponibles, la conférence était très intéressantes, et il semblerait qu'elle peut-être eu plus de succès que la mienne (cependant, je doute un peu, on va dire ex-aequo :)   ). Le sujet était pourtant fortement technique a priori, et les digressions dans les HIR et MIR internes à GCC en ont perdu quelques uns, qui ont tout de même été ravis d'en apprendre autant. Pour ma part, j'étais ravi de retrouver une application de mes vieux cours de compil (on sait qu'à l'EPITA le sujet majeur de première année est la conception d'un compilateur Tiger). A ce propos, j'ai partagé ma consternation avec Basile d'apprendre que les 4 millions de lignes de code de GCC sont écrites en C majoritairement (un peu de C++, ou de langages qui en génère comme celui de notre conférencier), et pas en Caml, ce qui aurait pu au moins diviser le nombre de lignes nécessaires par 100, sans compter la visibilité ; s'il est vrai que l'auto-compilation de GCC par lui-même est l'un des meilleurs tests qui soit, se serait en réalité une question de culture américaine de formation universitaire à la base de ce (non-)choix technique : dommage.

Terminons sur un mot très positif : GDB dans sa prochaine version aura la possibilité d'intégrer des scripts Python, de telle sorte que ce ne sera plus la peine de lutter avec des copies de lignes de commande pour mettre en place des registres, ou de mettre ses breaks à la main avant de les retirer pour les décaler etc (on se rappelle qu'avec un J-TAG, on n'a droit qu'à deux breakpoints/watchpoints hardware !), ou encore d'arrêter le code, dumper les registres et la pile, faire un step, etc, à la main, ce qui est très fastidieux pour le moment. On peut même rêver dès à présent à un équivalent de Time Machine de Greenhills, c'est-à-dire d'avoir la possibilité de jouer un retour en arrière dans l'exécution du code. Et ça, se serait une très grande nouvelle ! (qui ferait économiser 20.000€, hum... Mais il va falloir du temps)

Remercions encore une fois Basile Starynkevitch pour sa fort bonne prestation, et sa bonne humeur naturelle.

VMware rachète Trango-vp

Le choc : j'apprends ce matin via OKLabs que VMware a racheté Trango Virtual Processors ! Depuis le temps que je répète que la paravirtualisation est l'avenir des systèmes embarqués, voilà que cette nouvelle tendrait à me donner clairement raison. J'essaierai de me renseigner sur les raisons et les modalités de cette acquisition dès que possible, mais pour la petite histoire Trango Virtual Processors faisait jusqu'alors partie du groupe Elsys Design (qui ne serait pas à jour ?) ; qui sont mes anciens employeurs, et j'ai fait mes premières armes il y a un peu plus de deux ans sur... Trango. En effet, la société basée à Grenoble est tout à fait française, enfin, un peu moins à présent manifestement. Il sera intéressant de voir l'intéraction d'un géant de la virtualisation desktop et server dans le monde particulier du logiciel embarqué/temps-réel, car le code de Trango n'a certainement pas beaucoup de rapport avec celui de VMware !

lundi, novembre 17 2008

ville européenne des sciences, certes, mais sans Linux ?

Je fus bien triste, ce dimanche, devant ce constat : dans la nef du Grand Palais, où se tenait Paris, ville européenne des sciences, il y avait beaucoup d'ordinateurs sur les stands (des universitaires ou écoles d'ingénieurs jusqu'à des industriels majeurs), et je n'en ai dénombré strictement aucun sous Linux. Rien, que du Windows, du XP très largement, et très peu de Vista. Ah, et deux Mac, sous MacOS X.

J'y étais allé dans le but de revoir les amis de chez Aldebaran, avec qui Linagora entretient de bonnes relations, et chez qui j'ai eu le plaisir de travailler l'an dernier, en décembre et janvier, le temps de leur coder un nouveau bus logiciel de transmission et partage de données entre applications, en C++ très orienté objet, mais très performant en terme de ressources mémoires et temporelles. Malheureusement, ils n'étaient pas sur le stand promis par une plaquette que j'avais reçu : dommage, au moins j'étais à peu près certains que eux au moins seraient sous Linux (ils ont cependant quelques Windows pour des logiciels pro particuliers de modélisation, et quelques MacOS aussi).

Quelle déception que de voir tous ces chercheurs ou ingénieurs montrer leurs démos dans des consoles DOS ! Comment se fait-il, sans compter les raisons budgétaires (on râle sur les finances difficiles, mais on achète des licences à Microsoft !), que l'on s'embête à utiliser un système d'exploitation opaque, aux accès aux périphériques difficiles, dans des carcans de SDK sur lesquels il est difficile de savoir ce que l'on fait réellement ? Quelle image cela donne-t-il ? Pour moi, ingénieur, je pense que j'ai affaire à des personnes qui vont développer en Visual Basic® des choses qui devraient être rigoureuses : quelle claque !

La sensibilisation de cette catégorie bac+5/bac+8 à une informatique précise et ouverte est un vrai challenge. On voit souvent revenir sur la mailing list de l'APRIL ce thème, et la bataille que livrent certains chercheurs pour faire évoluer les mentalités. Car il s'agit bien de cela, que l'on ne viennent pas nous parler d'une quelconque difficulté d'installation de Linux (surtout à ce niveau d'études !), le mythe erroné d'une mauvaise foi sans fin. Décevant que tout cela, vraiment. Peut-être que Linagora devrait proposer ses services pour les DIF des chercheurs, tiens.

vendredi, novembre 14 2008

pourquoi le "GNU/" de GNU/Linux revêt toute son importance dans l'embarqué

On connaît la bataille de clochers entre libristes, ou du moins entre fervents libristes de l'église de St-GNU et ceux qui promeuvent le libre uniquement pour supériorité technique -- tels Linus Torvalds : faut-il dire "Linux" ou "GNU/Linux" ? Pour ma part, je me sers de l'expression "GNU/Linux" dans mes interventions afin de bien différencier ce qui relève du noyau "Linux" de ce qui relève du système libre "GNU". Car on peut fort bien utiliser GNU sans Linux, par exemple avec des environnements Cygwin, gcc, gdb, OpenOCD, Eclipse, pour des systèmes propriétaires tels que VxWorks, LynxOS ou QNX (qui ont tous trois des SDK basés sur les logiciels libres précédemment cités ! Et peuvent en partie utiliser des logiciels libres, sans que cela constitue l'intégralité du système hors noyau). La question d'utiliser Linux sans GNU se pose aussi : certains diront que le projet Busybox ou que la uClibc n'en font pas partie, cependant on peut pondérer cette assertion sur le fait que la licence est la GNU/GPLv2, et qu'à vrai dire je ne suis pas convaincu du tout qu'un projet comme la busybox ne soit amusé à recoder les plus de 200 logiciels regroupés qui la composent, notamment des aussi complexes que vi ; quelque part, tout est issu plus ou moins du projet GNU.

Mais peu importe à vrai dire, car le message technique associé pour l'embarqué et la redéfinition des relations associés à l'emploi de (GNU/)Linux est le suivant : le système d'exploitation hors noyau est indépendant dans une large mesure du noyau lui-même. C'est-à-dire qu'il a été conçu certes en utilisant par exemple des IOCTL propres à Linux, d'une manière marginale, mais surtout sur une base POSIX la plus indépendante possible, puisque le projet de noyau de GNU reste avant tout le Hurd. Et que donc même la libC (glibC) est fondé dans cette optique-là. Ceci est une différence fondamentale avec le projet libre OpenBSD, par exemple : ne désignant pas seulement le noyau mais l'ensemble du système d'exploitation complet, même si le noyau /bsd est bien délimité (contrairement à Windows, par exemple, où l'on ne sait jamais très bien où ça commence et où ça finit), le système forme un tout homogène et surtout inséparable dans ses versions. C'est-à-dire que non seulement il est bien spécifié que l'on ne doit pas s'amuser à mélanger les versions de logiciels, car sinon aucun support ne sera assuré par la communauté, mais en plus de cela il y a réellement des problèmes dans la réalité (on aurait pu croire à un simple warning anti-n00bs, comme le découragement de recompiler à partir des sources).

Sur un projet récent j'embarquais de l'OpenBSD 4.2 ; manque de chance, le support de la carte flash était très lent sur cette version, alors que sur la version 4.3 sorti entre temps, cela allait beaucoup mieux. Nul problème quant à une mise en production (le gain est faible sur de petites tailles à écrire, et aucune échéance de temps n'était à respecter absolument), mais gros problème quant à la mise en place usine de master complet sur une mémoire d'un giga octets : la décision fut prise d'utiliser en interne, pour l'opération de flashage, le noyau d'OpenBSD 4.3 sur le système 4.2 longuement mis au point. Et un problème arriva rapidement : le but étant de flasher une image téléchargée sur le réseau via notre ramdisk hybride 4.2/4.3 (opération très classique inspirée par la méthode de gestion de parcs via PXE), une configuration réseau via ifconfig était nécessaire, et autant un ifconfig <interface> <ip> passe très correctement, autant un ifconfig tout court renvoie les pires erreurs imaginables, au lieu de lister les interfaces et leurs propriétés. On ose imaginer ce que cela donnerait pour des programmes plus complexes dont il faudrait retester toutes les options possibles pour s'assurer du bon fonctionnement complet du système : ce n'est pas envisageable !

Fort heureusement, cette éventualité d'impossibilité de pouvoir changer le noyau seul sans le reste du système, ou inversement, avait été évoqué dès le début, et cela ne pose aucun problème à notre projet (il n'est pas impossible de patcher manuellement des logiciels particuliers et d'en assurer la rétrocompatibilité, cependant, mais on ne saurait changer totalement de version). Cependant, ce genre de problématique est à prendre à compte dès lors que l'on souhaite obtenir un système pouvant être mis à jour de manière massive, par exemple lorsque Nokia décide de changer l'interface complète de son système basé sur Maemo (incluant une mise à jour de la libC) ; en l'occurrence, leur choix de reposer sur un ramdisk pour Linux a eu pour avantage la possibilité de mettre à jour le noyau pour activer au passage le support de l'EABI (ce qui impliquait à l'époque du noyau 2.6.16 une recompilation totale du système ; il existe à présent une fonctionalité de rétrocompatibilité avec/sans EABI marquée expérimentale dans le kernel), mais cela ne saurait être toujours le cas (notamment parce que cette solution de ramdisk implique un temps de boot allongé, c'en est même indécent sur le N770) : comme nous le disions la dernière fois, ne serait-ce que pour des questions de sécurité, positionner le noyau en flash au dehors de tout file system est pratique extrêmement courante (on remarquera d'ailleurs l'option "-kernel" de qemu qui permet de faire booter un système de fichier en utilisant un kernel Linux externe). Il est donc souvent inenvisageable de mettre le noyau à jour (on peut toujours faire des dd avec seek pour écrire dans /dev/mem en raw, en calculant de ne pas déborder et en serrant les fesses... Je ne conseille pas !), alors que le système peut être appelé à évoluer (la mode est au reflashage de firmware ajoutant et corrigeant des fonctionnalités, les téléphones proposent cela, toutes les STB des FAI du marché aussi).

On peut élargir cette vision ultra-modulaire des choses au noyau Linux lui-même, qui hérite en sa conception intrinsèque de cette philosophie : alors que le noyau BSD forme un tout dont on déconseille très fortement de toucher à quelque option que ce soit (et il n'y a qu'à voir le fichier de configuration pour s'en convaincre), le mode de compilation de Linux se base sur une interface (en ligne -- make config --, en curses -- make menuconfig --, en Qt -- make xconfig --, ou en GTK -- make gconfig), où l'on coche et décoche ce que l'on souhaite (avec quasiment toujours la possibilité de mettre un support kernel en module chargeable et déchargeable à chaud), et uniquement cela, on peut même penser à activer le support des modules et tout mettre en dur, en prévision du jour où l'on voudra supporter des matériels brachés sur un hypothétique USB, et que l'on voudra alors supporter en ajoutant un driver au système (y compris rajouter le support d'un système de fichier : je suis bien content de pouvoir brancher mon disque dur en XFS sur mon disque dur multimédia, et j'aimerais bien que ce support revienne comme avant sur ma Freebox). La configuration de Linux supporte en outre la gestion des dépendances des modules les uns aux autres, et au final, alors que le projet OpenBSD dont la cible est l'informaticien expérimenté est peu propice au bidouillage, les sites pour utilisateur débutant de Linux proposent des tutoriels de (re)compilation du noyau !

Lorsque l'on voit sur distrowatch l'hétérogénéité des versions logicielles utilisées pour de mêmes kernels Linux (qui eux-mêmes ont un nombre de versions différentes très important, et non une release chaque semestre), ou inversement d'ailleurs (de mêmes versions logicielles pour des kernels différents), on voit bien que le problème ne se pose pas pour GNU/Linux : sa conception modulaire puisqu'agrégative de projets différents (GNU, Linux, autres projets de l'embarqué greffés sans pouvoir préjuger des autres logiciels employés, la Busybox marchant tout aussi bien avec la glibC qu'avec l'uClibc), assure une supériorité technique indéniable. Si l'on considère que les autres projets propriétaires de l'embarqué ont toujours été conçus comme le sont les projets BSD (incompatibles entre eux par ailleurs), on peut donc préjuger là encore d'un avantage majeur de l'emploi du noyau Linux et des projets libres utilisés pour consituer un système d'exploitation complet, dans la droite ligne de ce qui est attendu d'un système embarqué moderne gérant la communication, et donc potentiellement la mise à jour, tout autant que la possibilité de faire "librement" son marché entre les versions logicielles, amenant au problème du packaging (il faut choisir des versions logicielles compatibles entre elles, bref gérer la problématique propre à toute distribution Linux, qu'elle s'appelle Debian, OpenSUSE ou OpenEmbedded), mais aussi à sa puissance incomparable et jamais égalée par aucune autre solution logicielle existante.

jeudi, novembre 13 2008

formats ouverts dans l'embarqué

J'espère m'être bien fait comprendre sur ce point dans ma dernière conférence -- j'ai plus le temps d'insister dessus en cours --, mais Linux embarqué ne fait pas tout, et ouvre même à de nouveaux problèmes afférents à ce genre d'appareils pour lequel on a besoin d'un système si complet : le stockage des données. On peut considérer (c'est plus simple pour se le figurer) une problématique de lecteur audio ou vidéo, qu'il soit portable ou du genre Set Top Box, en passant par l'à présent inévitable smartphone. Lorsque l'on est sous Linux dans l'embarqué, on peut avoir tendance à se laisser emporter, et mettre trop de choses dans la boîte : je veux parler de logiciels pouvant être victimes des brevets américains. Evidemment, tout dépend du marché, mais on sait que sur ce point-là, les étasuniens se sont fait une spécialité d'embêter le monde, mondialisation oblige, justement. Parfois, ça se retourne contre eux : Alcatel assigne en justice Microsoft qui s'arrogeait des droits sur le brevet du MP3 (et donc en retirait fortes sommes d'argent), alors que la société française venant d'acheter Lucent soutenait que c'était cette dernière boîte américaine à qui la redevance revenait de droit ; quelques milliards d'Euros plus tard, nos vaillant concurrents de Linux perdirent cher (mais le procès est toujours en appel, me semble-t-il).

Le MP3 est ainsi la bête noire à ne pas sous-estimer. Certaines distributions européennes (comme la Mandriva) ont même décidé de ne pas supporter MP3 ou autre MPEG2 par défaut, et de laisser le soin aux utilisateurs de prendre leurs responsabilités en fonction du pays où ils habitent (civilisé ou non) afin d'installer les logiciels libres nécessaire au déchiffrement de ces formats. Contrairement aux DVD chiffrés, les MPEG sont pourtant documentés, mais voilà, les lire expose à payer des droits, et des entreprises à l'origine de leur découverte -- comme Philips -- traquent littéralement les contrevenants. On les aura vu s'illustrer sur un stand, lors d'un salon, de Sandisk, où tous les lecteurs furent retirés. Voilà donc qu'à présent, le projet libre OpenMoko serait lui aussi menacé (je ne trouve en revanche rien à ce sujet chez eux, si ce n'est ceci, qui montre à quel point tout cela est ubuesque). Tout support du MP3 (et toute mention aussi) a pour l'instant été retiré.

Il y a une conclusion morale à tout cela, et la chance étant avec nous, grâce au libre. Car il existe un format ouvert pour l'audio particulièrement adapté à l'embarqué, puisqu'il compresse beaucoup, beaucoup mieux que le MP3, tant en terme de taille (compter moitié moins) que de qualité (bien meilleur sur tous les plans !) : c'est le ogg Vorbis.

Tout serait bien alors, mais il existe encore une subtilité pour ces lecteurs : les protocoles de communication, eux aussi dans le même esprit que les formats. Aussi, certains lecteurs Samsung (pas le mien, j'ai fait attention, justement) qui lisent du ogg ne sont pas forcément si ouvert que cela : ils utilisent le MTP, protocole fermé développé par Microsoft (encore et toujours...) qui aura été patiemment reverse-engineeré pour son support sous Linux. Le chemin sera long avant l'ouverture totale des systèmes, Linux Embarqué n'est qu'une pièce du puzzle, l'enjeu est bien plus grand que cela, mais la tendance actuelle visant à embarquer du Linux (et donc du libre, dans une optique d'éviter les royalties ou autres redevances à la limite du racket) ouvre les esprits sur ces problèmes fondamentaux. Avant l'abandon, espérons-le, des brevets logiciels, absurdes au possible, et du non-sens de ces protocoles de communication fermés (c'est un oxymore, n'est-ce pas ?), en n'oubliant aussi les DRM de toutes formes.

En attendant, n'oubliez pas de mettre du ogg pour l'audio, du theora pour la vidéo, et des png pour les images, le tout communicant par direct storage access, ou par FTP.

mercredi, novembre 12 2008

embedded virus

On voit cela comme une grande nouvelle : une boîte déclare qu'il n'y a pas besoin d'antivirus pour Android. Il faut dire qu'une autre entreprise jouait déjà du FUD pour proposer sa propre solution de sécurité. Décidément, on vit dans un monde infecté par le Desktop et l'ignorance qui va avec (surtout pour les utilisateurs windowsiens, formés à l'assainissement régulier d'OS). Tout d'abord, tordons le cou à une assertion débile du second acteur sécuritaire : l'OpenSource impliquerait l'apparition de virus, théorie fort chère à Microsoft (la sécurité est impliquée uniquement par l'obscurantisme du code, il n'y a qu'à considérer leurs produits pour s'en convaincre), dont on peut évidemment vérifier la vérité tous les jours à l'aide de son Linux ou de son BSD. Très sérieusement : c'est n'importe quoi. Et du côté des obscurs, on ira voir RIM (qui ne cache pas certaines failles alarmantes du passé), ou on se penchera sur la réponse d'Apple et de son système de signature d'applications autorisées qui a rapidement été outrepassé.

Analysons objectivement la sécurité des systèmes embarqués : c'est effectivement un soucis qu'il faut prendre au sérieux, j'en parle d'ailleurs dans les cours que je dispense. En informatique, rien n'est magique, il faut donc déjà passer outre les images d'Epinal de "bestioles" rampantes qui s'incrustent dans les appareils et les rendent fou, ou en tirent des informations secrètes (on admet que par "virus" on désigne un peu tout ce qui concerne les failles de sécurité, notamment -- et surtout -- les vers). Déjà, pour les appareils communicants (ce ne sont que ceux-là qui sont concernés, sinon comment s'introduire ?), il faut déjà filtrer les entrées et les sorties : firewall, chiffrage, voire analyse de détection sur des données manifestement mal formattées (les réseaux GSM de SFR limitent par exemple de façon tout à fait arbitraire la taille des URL). Ensuite, il ne faut pas écarter l'apparition de code malveillant, et ici il faut se pencher sur la seule et unique question : comment fait-il pour s'exécuter, et quelle réponse y apporter ?

Plusieurs cas. On peut faire du buffer overflow avec des données corrompues : il suffit de protéger la pile, des solutions comme PaX font cela très bien, en marquant les zones hors piles comme non exécutables. Il y a aussi l'option -fstack-protector-all de GCC, qui met en place des canaris : comme dans les mines où les volatiles jaunes révélaient la présence de gaz en mourant et donc en arrêtant de piailler, la technique consiste à mettre aux extrémités de la pile d'exécution des bouts de données qui, si elles sont écrasées (par un shellcode, au hasard), provoquent l'arrêt immédiat du programme. Et cela sans compter que Android est basé sur du Java, ce qui constitue déjà en soi une boîte à sable pouvant se révéler très efficace (pour avoir programmé en J2ME en 2004 sur téléphone portable, je peux même assurer que l'accès aux données physiques est fortement contrôlé, mais effectivement on peut de plus en plus accéder à des fonctionalités du téléphone, afin d'être plus user-friendly).

On peut ensuite avoir tout simplement un programme tiers téléchargé et exécuté à la main, par l'utilisateur. A ce niveau, il faut évidemment responsabiliser l'utilisateur (ne pas exécuter cette application manifestement malveillante). Notons que l'argument consistant à évoquer la multplicité des OS sur plate-formes mobiles n'est pas recevable, puisqu'accéder au répertoire téléphonique, SMS, ou autres données sensibles de la carte SIM, tout comme le fait de lancer des appels, se fait par commandes AT à un second kernel, très souvent du Nucleus ; et entre Symbian, RIM OS, WinCE/Mobile, Linux et Darwin, on voit mal ce que l'on appelle "grande multiplicité" (surtout que Symbian est toujours majoritaire). Dans tous les cas, éviter de lancer un programme en root, sandboxer (en Java, c'est quasiment natif), filtrer des commandes interdites (ce que fait nativement un BSD avec jail, en somme), et déjà je souhaite une grande chance aux pirates pour s'en sortir.

Il y a en outre la possibilité, pour les appareils communicants, de se mettre à jour. Il faut bien faire attention à la procédure (notamment il faut doubler les OS présents : l'un, très minimal, doit toujours être présent au cas où la mise à jour aurait échoué, afin de pouvoir la reprendre), mais tous les appareils modernes supporte ce genre de fonctionnalité. Cependant, mettre à jour le noyau lui-même peu s'avérer très périlleux, si ce n'est impossible. En effet, pour des raisons pratiques mais aussi de de sécurité, le noyau Linux est placé "en dur", en dehors de tout file system, dans le firmware : c'est une pratique extrêmement courante qui a énormément d'avantages. Le problème est que son remplacement n'est alors pas si aisé, voire inenvisageable. J'ai travaillé, il y a plus d'un an, sur une solution avec un noyau qui s'est avéré six mois plus tard être frappé de la faille sur la mémoire virtuelle qui permet de prendre les droits "kernel" (plus que root, on se retrouve en kernel land) ; pourtant, j'ai continé à bien dormir (sachant que c'est une solution dont le marché prévu recoupait des choses aussi diverses que la gestion de terminaux bancaires).

Car il existe une excellente solution de protection pour Linux : RSBAC. Je vous laisse découvrir la chose, la première fois que l'on se fait jeter d'un "su" alors que l'on est root est une expérience étrange. La faille est donc peut-être présente, mais le mode opératoire pour arriver à en profiter est totalement hors de portée. De même, les solutions de paravirtualisation embarquée sont là pour répondre à cette problématique : un OS se charge de ce qui est sensible, et l'autre de ce qui est pour "le fun" ; l'imperméabilité totale est assurée au niveau électronique, la communication se fait par des canaux très définis, limités et filtrés, et en cas de problème sur le second OS, le premier n'est pas atteint.

Bref, pour peu que l'on réfléchisse avant, des solutions libres pour une parfaite sécurité dans l'embarqué existent, et ne sont pas bien difficile à mettre en oeuvre (l'option de stack protector de GCC n'est pas activée par défaut dans OpenEmbedded, et certains programmes compilent mal avec, mais c'est juste une question de jours pour résoudre les divers problèmes, quant à RSBAC il faut bien le configurer, et une option de démarrage est là pour se mettre en "mode apprentissage automatique"). J'ose croire que les concepteurs de téléphonie mobile (et j'y ai quelque peu travaillé, je peux donc assurer qu'ils ont très paranoïaques) prennent le problème très au sérieux. Et même, que ce que l'on reproche à RIM et son Blackberry, à savoir le manque de transparence sur le trasit des données, ne pourrait être reproché à une solution libre. Les clients de Linagora, qui font le choix de Linux ou BSD pour des opérations très sensibles, pourront sans doute aucun confirmer.

mardi, novembre 11 2008

conférence Paris8

Dans le cadre des conférences menées au sein du département d'informatique de l'Université Paris 8 (Master professionnel Informatique des Métiers et des Applications), j'ai pu mener auprès des étudiants de Master (et notamment les M2 spécialisés en Informatique et Systèmes Embarqués), une conférence sur Linux embarqué. Sujet qui recouvre toujours plus que Linux mais le libre en général, même si notre kernel favori constitue évidemment l'essentiel du sujet. Voici donc les slides sous licence libre FDL, au format OpenOffice.org (3,2mo) et au format pdf (1mo). J'ai aussi effectué une démonstration avec la carte SBC2440, dont on trouvera des détails par là.

Je tiens à chaleureusement remercier Isis Truck pour avoir organisé cette rencontre avec un public nombreux (une quarantaine ou cinquantaine d'étudiants, dirais-je). La séance de questions fut assez brève, mais il est tout à fait possible d'en poser ici-même en commentaire. Mon attention a été attirée sur QNX, microkernel (Neutrino) et système d'exploitation complet certes très connu (de nom du moins) dans le milieu industriel, mais pas si répandu que cela, du moins pas autant qu'il ne devrait l'être si l'on considère ses performances objectives ; après avoir pris connaissance de la licence prise de tête pour une utilisation non-commerciale, je pense qu'il ne faut pas chercher plus loin l'explication du succès de Linux sur QNX, pourtant présent sur le marché depuis le début des années 80, et ayant commencé à s'ouvrir trop tardivement, après la montée en puissance constatée de Linux (virage qu'ont dû aussi prendre WindRiver ou LynuxWorks, ce dernier ayant changé de nom pour l'occasion en ajoutant un "y").

C'est ainsi qu'encore une fois, malgré les incertitudes qui règnent dans les esprits à son sujet, la licence GNU/GPL se montre supérieure : le même constat peut en effet être observé avec le système BSD, longtemps tout à fait meilleur que Linux sur tous les points, mais qui n'arriva jamais à percer, malgré plus de 10 ans (si ce n'est 15) d'avance dans le développement. Aussi, le micronoyau L4, projet universitaire lancé en 99 et dont la version 1.0 date de 2003, a déjà été récupéré plusieurs fois, notamment par l'équipe d'OpenKernel-Labs pour OKL4, le projet de paravirtualisation temps-réel pour l'embarqué courroné de succès. Son secret ? L4, outre qu'il est intelligemment et efficacement conçu, est sous GNU/GPLv2 (additionné d'une licence commerciale, comme Qt) depuis son lancement, tout simplement.

jeudi, novembre 6 2008

à quoi sert typedef ?

A éviter ça ?

snmp_sess_add_ex(netsnmp_session * in_session,
                 netsnmp_transport *transport,
                 int (*fpre_parse) (netsnmp_session *, netsnmp_transport *,
                                    void *, int),
                 int (*fparse) (netsnmp_session *, netsnmp_pdu *, u_char *,
                                size_t),
                 int (*fpost_parse) (netsnmp_session *, netsnmp_pdu *,
                                     int),
                 int (*fbuild) (netsnmp_session *, netsnmp_pdu *, u_char *,
                                size_t *),
                 int (*frbuild) (netsnmp_session *, netsnmp_pdu *,
                                 u_char **, size_t *, size_t *),
                 int (*fcheck) (u_char *, size_t),
                 netsnmp_pdu *(*fcreate_pdu) (netsnmp_transport *, void *,
                                              size_t))

(faut téléphoner au Guiness)

mardi, novembre 4 2008

le diable se cache dans passwd

Celui d'OpenBSD, je précise. C'est qu'il m'en a donné à baver, ce sale bestiaux. Sécurité par l'obscurité bonjour, si je ne peux point relater la malheureuse aventure arrivée, je peux cependant noter toutes les astuces diaboliques qui sont contenus dans si peu de code, et ce qui m'amena à m'y confronter. Code que par ailleurs je n'ai toujours pas entièrement compris, et c'est bien la première fois que ça m'arrive, j'ai même déjà dû maîtriser du code indien, c'est dire (et c'est rusé, un Indien). Tout d'abord, le mode de fonctionnement de passwd : cette commande permet de modifier le mot de passe utilisateur. Ou pas tout à fait. En réalité, l'opération se déroule en deux temps : en premier lieu, changement de /etc/passwd, puis de /etc/master.passwd par le programme passwd lui-même ; ensuite, changement des bases de données /etc/pwd.db et /etc/spwd.db par pwd_mkdb. Ce sont ces bases qui sont utilisées par login pour authentifier les utilisateurs. En toute rigueur, si passwd détecte que le mot de passe est local (il gère aussi les bases kerberos et le système YP), pwd_mkdb est lancé, mais même dans la documentation il n'est pas bien clair qu'il ne faille ajouter l'option "-l" :

     -l      Causes the password to be updated only in the local password
             file.  When changing only the local password, pwd_mkdb(8) is used
             to update the password databases.

Il me sembla avoir expérimenté une fois où la base de donnée ne fut pas mise à jour, c'est même cette fois-là que je découvris l'existence de pwd_mkdb (ce n'est pas très naturel, pour le linuxien). Ce dernier a des options d'appel totalement différentes du premier : on doit notamment spécifier quel est le fichier master.passwd à utiliser, et quel répertoire on doit utiliser. Ainsi, on peut reconstruire une base d'utilisateurs locaux depuis un ramdisk, par exemple (dans le makefile, on parle d'exécution depuis... une disquette). Cette précision a son importance : pwd_mkdb est lié de manière statique, en l'occurrence avec la bibliothèque libutil, non celle du système que l'on compile, mais manifestement celle du système sur lequel on compile (la différence est de taille, surtout lorsqu'on développe dedans) ; de plus, lors d'une modification de la bibliothèque libutil de son arbre de développement, une recompilation depuis la racine n'a pas pour conséquence de gérer la dépendance et de recompiler pwd_mkdb (donc la lier avec la bibliothèque modifiée), ce qui peut avoir de fâcheuses conséquences (tout autant que de sérieuses prises de tête lors d'un développement intensif).

Il faut dire que libutil concentre beaucoup de choses hétérogènes, dont passwd.o, hérité du fichier C du même nom. Dedans se cachent des fonctions que l'on suppose communes à passwd autant qu'à pwd_mkdb ; le premier est ainsi lié dynamiquement avec la bibliothèque -- et en utilise presque toutes ses fonctions (il me semble bien qu'au moins une n'est utilisée par personne). Mais l'on aurait tort de penser cela : la fonction pw_mkdb (remarquez qu'il manque le "d", assez pour devenir fou lorsque l'on fait des recherches) contenue dans cette bibliothèque libutil est ainsi responsable du fork qui appelle pwd_mkdb. A vrai dire, peu de fonctions sont réellement partagées, et elles ne font guère plus de quelques lignes.

Si pwd_mkdb a été prévu dès l'origine, avec son option "-d" pour pouvoir travailler dans des répertoires différents de /etc (ce qui est fort pratique en embarqué pour générer une base à partir des fichiers de mots de passe texte construits à la main, la base étant en binaire), cela est presque de même pour passwd. "Presque" car voilà : il existe une fonction de changement des répertoires à chaud, utilisée par pwd_mkdb, qui fait que lorsque l'on cherche master.passwd dans /toto, on part de la macro /etc/master.passwd pour arriver à /toto/master.passwd. Ces macros sont nombreuses : certaines sont en dur, d'autres dans un fichier d'include ; là encore, problème du build d'OpenBSD : les includes considérés ne sont pas ceux de l'arbre de développement, mais ceux du système d'accueil de la compilation. Autre problème : passwd fait appel dans son code assez souvent aux fonctions de relocalisation, mais il n'y a pas d'option existante comme sur pwd_mkdb : ceci est fâcheux, il faut donc entrer dans le code, et se battre avec des valeurs en dur, qui ont tendance à changer lors de la compilation (réécriture des répertoires rapidement exposés juste avant : il en existe plusieurs mécanismes).

Tout ceci est déjà bien complexe à gérer, mais c'était sans compter sur l'intervention d'un dernier farceur : ptmp. De base, ce fichier est prévu pour être dans /etc. Mais il peut être relocalisé en fonction du code de passwd, ou plutôt celui de la libutil, et ce à chaud, contrairement à ce que laisser penser sa macro (qui est bien "/etc/ptmp" : la changer n'a des impacts que limités). Lorsque /etc n'est pas accessible en écriture (cas courant dans la problématique embarqué), voilà donc ce qui se passe, de base (extrait de man passwd) :

DIAGNOSTICS
     Attempting lock password file, please wait or press ^C to abort

     The password file is currently locked by another process; passwd will
     keep trying to lock the password file until it succeeds or you hit the
     interrupt character (control-C by default).  If passwd is interrupted
     while trying to gain the lock the password changed will be lost.

     If the process holding the lock was prematurely terminated the lock file
     may be stale and passwd will wait forever trying to lock the password
     file.  To determine whether a live process is actually holding the lock,
     the admin may run the following:

           $ fstat /etc/ptmp

     If no process is listed, it is safe to remove the /etc/ptmp file to clear
     the error.

Et en effet, cette erreur apparaît dès que l'on a son / en lecture seule, ce que j'impose toujours dans des systèmes embarqués (par paranoïa naturelle). Malheur à celui qui eu son passwd testé avec un système de fichier monté en lecture-écriture pour cause de développement en cours (en l'occurrence, moi, on l'aura compris), avec de fait un bug non détecté. Et à vrai dire, avant de comprendre tout cela, il fallut pas mal de temps (dont deux remontées du même bug ou presque, avant de se rendre compte de l'erreur dans le test), et bien tâtonner : car il ne m'était pas venu à l'idée qu'un fichier servant de mutex puisse non pas être mis dans /var/run, comme dans tout système civilisé, mais dans /etc/ ; sans compter le fait que l'opération n'est pas atomique, mais on exclura l'idée de deux utilisateurs assez pervers pour lancer deux passwd quasiment en même temps (pourtant ipcs confirme l'existence d'un vrai système de sémaphores). Il y avait en réalité un autre mécanisme, caché : cela aurait été trop simple, sinon. En l'occurrence, passwd lançait tout seul pwd_mkdb, sans que l'option "-l" ne soit spécifié. Grâce à un système de liens, cela n'est pas bien grave, mais voilà : pwd_mkdb ne se lance qu'à condition de pouvoir ouvrir... /etc/ptmp. Car en réalité, passwd appelle le programme de construction de base à l'aide d'option de relocalisation "-d", et l'occurrence une mauvaise, en ce basant sur un autre système, qui au final donnait un "/etc" fatal. Croyant tout d'abord que c'était l'appel manuel de pwd_mkdb (on n'est jamais trop paranoïaque, et puis l'option "-l" n'est pas bien claire) qui échouait, et ayant découvert que la bibliothèque liée n'était pas la bonne, voilà comment on croît résoudre un bug alors qu'en fait on s'attaque à autre chose, et un mélange avec une partition en read-write pour cause de besoin de développement (au hasard, remplacer passwd, libutil.so et pwd_mkdb), puis oubliée dans cet état, amène à un drame (croire que c'est bon, puisque l'on a plus l'erreur d'avant, alors que ça ne l'est pas, puisqu'un bug en cache un autre).

"Errare humanum est, perseverare diabolicum"   (oui mais c'est passwd qui est diabolique, moi j'exorcise, j'le jure !)

J'eus donc l'idée, lors du développement, de retirer le fork de pwd_mkdb appelé depuis le code même de passwd, puisque l'exécutant de toute façon juste ensuite moi-même : le fichier de lock ptmp n'était alors plus supprimé ! De fait, deux exécutions d'affilée ne donnent pas la même erreur, et la seconde exécution donne lieu à une attente sur le fichier de lock présent alors qu'il ne devrait pas (plus) l'être (cf le man ci-dessus ; du coup, on peut croire être retombé dans la première configuration d'erreur, à tort). Ou comment brouiller encore plus les pistes. Et c'est ainsi que je perdis définitivement mon latin... Et pour finir : une erreur du pwd_mkdb forké, même inutilement, entraîne l'abandon de la modification du master.passwd (ce qui n'a pourtant pas grand rapport...), encore un comportement erratique de passwd (la fonction pw_error peut être ainsi appelé si l'édition du fichier échoue : c'est-à-dire si un appel via fork par sh de /bin/vi échoue... Tout dans la simplicité), de telle sorte que l'appel manuel "pour plus de sécurité" de pwd_mkdb travaillait sur un fichier non modifié, et regénérait donc la même base...

Que l'on se rassure, comme dans tous les contes, l'histoire se termine bien : une valeur en dur de répertoire inscriptible pour notre fichier de lock signalé à la main en des endroits stratégiques, et notamment dans le fork de la lib (oui, en dur...) résolut les problèmes. Ce n'est pas beau (euphémisme), mais ça marche. Et à vrai dire, dans une horreur diabolique pareille, cela ne se voit presque pas.

jeudi, octobre 30 2008

portage Linux 2.6.25 et 2.6.27 sur carte Embest 2440, via J-Tag

Suite de nos aventures avec la carte chinoise faisant figurer le S3C2440. Ce fut long et laborieux (surtout à essayer de trouver du temps pour les tests), mais ça boote ! Et avec des logs consoles en ASCII, aussi (la précision a son importance), et un driver de carte réseau qui marche... Il n'y a peut-être pas encore tout de fonctionnel, mais en tout cas on a une console et des programmes qui tournent à la fin, c'est déjà beaucoup quand on sait d'où l'on part à la base (au début, il n'y avait rien...). Notamment une traversée des sites tous chinois, coréens et quelques uns japonais, expliquant plus ou moins comment faire marcher le bestiaux, avec une traduction google très approximative (voire franchement comique), et en réalité, il s'agit plus de la bidouille que de la vraies explications sur les problèmes rencontrés. En ayant eu marre de ramer dans ces sites-là (qu'il faut tout de même remercier, mais c'est dingue, n'y-a-til donc personne parlant Anglais ou Français et pouvant faire le même boulot ?), je me suis finalement attelé tout seul comme un grand au code noyau de A à Z, depuis l'init (problèmes de boot, il faut trouver la bonne config, puis de décompression, trouver la bonne adresse) jusqu'à celui des drivers, en passant par la console qui crachait n'importe quoi. J'ai donc tout d'abord essayé de porter un uClinux, mais ça ne marche pas ; je suis donc reparti avec le même code du 2.6.25 avec MMU, et j'ai vérifié que ce que j'ai écrit dans la suite de ce billet marche bien pour un 2.6.27 (j'ai bidouillé tellement de choses dans le kernel que même les logs font peur à voir  :)   ).

Tout d'abord, la compilation : on ne trouve aucun .config correct sur le Net, voici donc configuration kernel pour carte Embest2440. Comme vous le verrez, j'avais décidé de partir sur un uClinux, mais manifestement l'initialisation de la mémoire se vautre lamentablement (outre un bug impliqué par le numéro de machine écrasé, cf plus tard). Donc retour à l'utilisation normale de la MMU (en réalité, sur ARM, il n'est pas possible de se passer du coproc' P15, d'après une thèse lyonnaise de normal sup' que j'ai trouvée : la MMU est donc initialisée à l'identité, ie  @phys = @log ).

Première étape : compilation du kernel Linux. Avec le .config fourni, le kernel devrait faire à peine plus d'1,3Mo. Les flags de debug sont activés, le kernel avec symboles (environ 50Mo) se trouve à la racine ./S3C2440/linux-2.6.25/vmlinux.

make ARCH=arm xconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage

Notez bien la ligne de commande :

root=/dev/nfs nfsroot=192.168.1.1:/home/gblanc/S3C2440/root_default ip=192.168.1.2:192.168.1.1::255.255.255.0:Linagora_board::none ro init=/linuxrc console=ttySAC0,115200

Ici on boote en NFS en utilisant l'IP 192.168.1.2, le serveur étant à l'IP 192.168.1.1, pour le reste, configuration standard. Avec ceci, vous risquez de voir apparaître beaucoup de garbage sur le minicom, même en réglant bien convenablement les options (qui sont celles par défaut, en fait) : c'est un problème de clock pour la carte SMDK2440 (censée être compatible avec la carte Embest, je commence à penser qu'il vaut peut-être mieux créer une nouvelle archi par copie avec un nouveau numéro... D'ailleurs un "find . -name '*sbc*'" sur le kernel fourni par Embest montre qu'ils ont patché dans tous les sens), il faut la passer en 12Mhz (c'est fait convenablement pour quasiment tous les IDs de machines similaires, mais pas pour la SMDK, or notre carte Embest est en 12Mhz). Dans le fichier arch/arm/mach-s3c2440/mach-smdk2440.c, replacer comme suit :

static void __init smdk2440_map_io(void)
{
        s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
//      s3c24xx_init_clocks(16934400);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}

Ca devrait aller mieux tout à coup (on remarque aussi que s3c24xx_init_clocks appelé avec "0" met l'horloge à la valeur par défaut, qui est... 12*1000*1000). Reste le problème de la carte réseau, la CS8900. Un driver est fourni avec la carte, mais pour le noyau 2.6.13 : depuis, tellement d'eau a coulé sous les ponts qu'il n'est pas aisé de faire un portage. Et une fois fait, le nombre de bugs et autres Oops à débugger est assez scandaleux (je dirais même que l'architecture du chargement des drivers réseau a franchement changé, il faut réécrire l'init, remettre la section privée de la structure device au bon endroit, etc). En réalité, il y a un driver générique pour les cartes Cirrus qui a été écrit, depuis : CS89x0. Sauf qu'il n'est pas activé, et pire, pas activable par défaut. Il faut donc patcher le Kconfig qui va bien, et mettre les bonnes adresses de lecture/écriture de registres (sur ports I/O) et initialiser la MMU pour qu'elle pointe au bon endroit, histoire de ne pas Oopser (@phys sur 0x19000000, c'est fichtrement plus lisible dans u-boot que dans Linux pour retrouver cette adresse ! Evidemment, rien dans les doc, sinon regarder dans./include/asm-arm/arch-s3c2410/sbc2440v3-map.h du kernel 2.6.13 fourni par Embest !). Donc tout d'abord, dans drivers/net/Kconfig, aller à la section "Config CS89x0", et rajouter "|| ARCH_S3C2410" (ne faisons pas dans le détail ! Le but est de bypasser la dépendance sur NET_PCI et les cartes associées). Puis dans le code du driver, il va falloir taper sur une adresse logique qui va bien ; celle du code de la carte QT2410 (en 0xE0000300 -- il faut ajouter "300" aux adresses pour taper dans le réseau, ne me demandez pas d'où ça sort, cékomsa) est bien, mais j'ai finalement opté pour celle du vieux driver CS8900 de Embest, à l'adresse 0xD0000000, ce qui marche sur 2.6.25, mais pas sur 2.6.27, je suis donc retourné à la 0xE0000000. Dans arch/arm/mach-s3c2440/mach-smdk2440.c (puisque l'on décide d'adapter la SMDK2440), ajouter dans le tableau smdk2440_iodesc :

static struct map_desc smdk2440_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */

        {
                .virtual        = (u32)S3C24XX_VA_ISA_WORD,
                .pfn            = __phys_to_pfn(S3C2410_CS2),
                .length         = 0x10000,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
                .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
                .length         = SZ_4M,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (u32)S3C24XX_VA_ISA_BYTE,
                .pfn            = __phys_to_pfn(S3C2410_CS2),
                .length         = 0x10000,
                .type           = MT_DEVICE,
        }, {
                .virtual        = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
                .pfn            = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
                .length         = SZ_4M,
                .type           = MT_DEVICE,
        },
        { 0xE0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
};

Ainsi, l'adresse 0x18000000 + 0x01000000 (soit 0x19000000) sera mappée sur 0xE0000000 (avec une taille de SZ_1M, ce qui me semble un peu grand, mais c'est ce qui est "recommandé", alors...). Petit intermède à propos de ce mapping : dans la 2.6.27, on a la macro VMALLOC_END dans arch/arm/mach-s3c2410/include/mach/vmalloc.h (fichier qui n'existe pour 2.6.25) qui vaut 0xE0000000. Or, dans la mise en place des zones de I/O map, on vérifie que l'on n'écrase pas une zone allouée au mallocage : fonction  de /arch/arm/mm/mmu.c, et message "BUG: mapping for 0x19000000 at 0xd0000000 overlaps vmalloc space" si l'on met 0xD0000000 à la place de 0xE0000000.

Dans le même fichier, il faut "enregistrer" le driver réseau comme faisant partie de la configuration matérielle à activer :

static struct platform_device *smdk2440_devices[] __initdata = {
        &s3c_device_usb,
        &s3c_device_lcd,
        &s3c_device_wdt,
        &s3c_device_i2c,
        &s3c_device_iis,
        &s3c_device_cs89x0,
};

Cette structure est à déclarer dans arch/arm/plat-s3c24xx/devs.c (personnellement, j'ai inséré ce code avant la partie propre au 2440 marquée par "#ifdef CONFIG_CPU_S3C2440" autour de la ligne 500) :

/* CS8900 */

static struct resource s3c_cs89x0_resource[] = {
        [0] = {
                .start  = 0x19000000,
                .end    = 0x19000000 + 16,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
                .start  = IRQ_EINT9,
                .end    = IRQ_EINT9,
                .flags  = IORESOURCE_IRQ,
        },
};

struct platform_device s3c_device_cs89x0 = {
        .name           = "cirrus-cs89x0",
        .num_resources  = ARRAY_SIZE(s3c_cs89x0_resource),
        .resource       = s3c_cs89x0_resource,
};

EXPORT_SYMBOL(s3c_device_cs89x0);

On y trouve l'IRQ qui va bien, l'@ phys à attaquer pour les registres du device aussi (Si vous obtenez en sortie console quelque chose comme "cs89x0: request_region(0xd0000300, 0x10) failed", c'est que votre mapping s'est mal passé, et le driver ne marchera évidemment pas). Pour que l'utilisation du symbole s3c_device_cs89x0 se passe bien, il faut dans include/asm/plat-s3c24xx/devs.h () rajouter une ligne "extern struct platform_device s3c_device_cs89x0;". A présent dans drivers/net/cs89x0.c (le code du driver réseau), ajouter :

#elif defined(CONFIG_ARCH_PNX010X)
// blablabla
#elif defined(CONFIG_ARCH_S3C2410)
#include <asm/arch/irqs.h>  // copie de asm-arm/arch-s3c2410/irqs.h dans 2.6.25 ; attention, dans 2.6.27 se sera <mach/irqs.h> qui pointe vers arch/arm/mach-s3c2410/include/mach/irqs.h ; il faut trouver où est IRQ_EINT9
#include <linux/irq.h>
static unsigned int netcard_portlist [] __initdata = { 0xD0000300, 0 };
static unsigned int cs8900_irq_map[] = { IRQ_EINT9, 0, 0, 0 };
#define NO_EPROM
#else
static unsigned int netcard_portlist[] __used __initdata =
   { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {10,11,12,5};
#endif

On indique donc que le port sera sur l'adresse virtuelle 0xD0000300 (c'est la base, ensuite les additions pour trouver les bons registres de lecture/écriture/contrôle sont toujours les mêmes). On indique aussi l'IRQ (ce sera la 53). Et qu'il n'y a pas d'EEPROM ; sinon il se passera des choses étranges -- de fait, il faudra entrer l'adresse mac à la main (oui, c'est très moche) :

printk(" IRQ %d", dev->irq);

dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0xc0;
dev->dev_addr[3] = 0xff;
dev->dev_addr[4] = 0xee;
dev->dev_addr[5] = 0x08;
set_mac_address(dev, dev->dev_addr);

A mettre dans le driver, dans la fonction cs89x0_probe1  (qui fait l'initialisation du device), vers la ligne 930 sur le 2.6.25 (ou 831 pour un 2.6.27), après la section macroïsé par "#ifndef MONO_IRQ_MAP" et avant celle de "#if ALLOW_DMA". A présent, ça arrêtera de Oopser. On peut aussi juste au dessus (aux environs de la ligne 910, 805 sur 2.6.27) mettre en place la bonne méthode d'enregistrement de l'IRQ dans la structure device :

                if (lp->chip_type == CS8900) {
#if defined(CONFIG_MACH_IXDP2351) || defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X) || defined(CONFIG_ARCH_S3C2410)
                        i = cs8900_irq_map[0];
#else

Mais à l'exécution, ça va merder sur l'IRQ, tout de même :

irq 53: nobody cared (try booting with the "irqpoll" option)
[<c0027d68>] (dump_stack+0x0/0x14) from [<c00602a4>] (__report_bad_irq+0x38/0x88)
[<c006026c>] (__report_bad_irq+0x0/0x88) from [<c00605a4>] (note_interrupt+0x2b0/0x308)
 r4:00000000
[<c00602f4>] (note_interrupt+0x0/0x308) from [<c0061380>] (handle_edge_irq+0x11c/0x1a4)
[<c0061264>] (handle_edge_irq+0x0/0x1a4) from [<c0032cd4>] (s3c_irq_demux_extint8+0x98/0xa8)
 r8:00000000 r7:00000001 r6:00000038 r5:c02c0ee8 r4:00000000
[<c0032c3c>] (s3c_irq_demux_extint8+0x0/0xa8) from [<c0023044>] (asm_do_IRQ+0x44/0x60)
[<c0023000>] (asm_do_IRQ+0x0/0x60) from [<c00235f8>] (__irq_svc+0x38/0xb0)
Exception stack(0xc0345e0c to 0xc0345e54)
5e00:                            00000000 fb000000 00000001 00000000 c02c1a80
5e20: 40000013 00000035 c0d223e0 c016811c c0ccb000 c0ccb000 c0345e70 c0345e30
5e40: c0345e54 c006074c c005fda0 a0000013 ffffffff
 r6:00000020 r5:f4000000 r4:ffffffff
[<c005fc00>] (setup_irq+0x0/0x230) from [<c005fed4>] (request_irq+0xa4/0xd0)
 r7:00000000 r6:00000000 r5:00000035 r4:c0d223e0
[<c005fe30>] (request_irq+0x0/0xd0) from [<c0167af8>] (net_open+0xe4/0x4b8)
[<c0167a14>] (net_open+0x0/0x4b8) from [<c01d7abc>] (dev_open+0x84/0xdc)
 r6:00001002 r5:c0ccb02c r4:c0ccb000
[<c01d7a38>] (dev_open+0x0/0xdc) from [<c01d684c>] (dev_change_flags+0xb0/0x178)
 r5:00001003 r4:c0ccb000
[<c01d679c>] (dev_change_flags+0x0/0x178) from [<c001d0a4>] (ip_auto_config+0x168/0xcb8)
 r7:00001002 r6:00000001 r5:c0ccb000 r4:c02f9ecc
[<c001cf3c>] (ip_auto_config+0x0/0xcb8) from [<c000890c>] (kernel_init+0xb8/0x278)
[<c0008854>] (kernel_init+0x0/0x278) from [<c0040524>] (do_exit+0x0/0x620)
handlers:
[<c016811c>] (net_interrupt+0x0/0x3cc)
Disabling IRQ #53

Oui, ça fait peur. Le résultat, c'est que l'on émet bien des paquets sur l'interface réseau, mais à la réception de la réponse, l'IRQ a été désactivé faute d'avoir trouvé un handler correct, et donc le driver n'est pas notifié de l'arrivée des nouveaux paquets : c'est un dialogue de sourds :

eth0: Attempting TP
eth0: 10Base-T (RJ-45) has no cable
eth0: using half-duplex 10Base-T (RJ-45)
cs89x0: net_open() succeeded
IP-Config: Complete:
     device=eth0, addr=192.168.1.2, mask=255.255.255.0, gw=255.255.255.255,
     host=Linagora_board, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.1
eth0: sent 42 byte packet of type 806
NETDEV WATCHDOG: eth0: transmit timed out
eth0: transmit timed out, IRQ conflict ??
eth0: sent 42 byte packet of type 806
cs89x0: Tx buffer not free!
NETDEV WATCHDOG: eth0: transmit timed out
eth0: transmit timed out, IRQ conflict ??
eth0: sent 42 byte packet of type 806

Il va donc falloir aussi corriger cela. Après avoir bien lutté, il s'avère que c'est la "déclaration" de l'IRQ qui manque, avant son enregistrement comme correspondant au bon handler (via request_irq). Donc dans le fichier ./drivers/net/cs89x0.c, dans la procédure net_open(), on ajoute :

#if !defined(CONFIG_MACH_IXDP2351) && !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X) && !defined(CONFIG_ARCH_S3C2410)
                if (((1 << dev->irq) & lp->irq_map) == 0) {
                        printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x ",
                               dev->name, dev->irq, lp->irq_map);
                        ret = -EAGAIN;
                        goto bad_out;
                }
#endif

                set_irq_type(dev->irq, IRQ_TYPE_EDGE_RISING);   // IRQT_RISING dans les vieux kernels
/* FIXME: Cirrus' release had this: */
                writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
/* And 2.3.47 had this: */
#if 0
                writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
#endif
                write_irq(dev, lp->chip_type, dev->irq);
                ret = request_irq(dev->irq, &net_interrupt, 0, dev->name, dev);

Et voilà le travail !  :)  Si vous obtenez ceci (juste avant "Looking up port of RPC 100003/2 on 192.168.1.1"), c'est que vous vous êtes planté quelque part :

eth0: EEPROM is configured for unavailable media
IP-Config: Failed to open eth0
IP-Config: No network devices available.

Par exemple, sur la 2.6.27, ce n'est pas votre faute : la macro NO_EPROM n'existe plus, résultat, c'est la cata, plus rien ne marche. C'est très bête (euphémisme). Après le commentaire "/* First check to see if an EEPROM is attached. */" (ligne ~730), il faut donc insérer :

#ifdef NO_EPROM
        if (1) {
                printk(KERN_NOTICE "cs89x0: No EEPROM ");
                lp->adapter_cnf = A_CNF_10B_T | A_CNF_MEDIA_10B_T;
                lp->auto_neg_cnf = EE_AUTO_NEG_ENABLE | IMM_BIT;
        } else
#endif

Et tout à coup, ça va beaucoup mieux :

eth0: 10Base-T (RJ-45) has no cable
eth0: using half-duplex 10Base-T (RJ-45)
IP-Config: Complete:
     device=eth0, addr=192.168.1.2, mask=255.255.255.0, gw=255.255.255.255,
     host=Linagora_board, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.1

Il faut bien entendu avoir un serveur NFS correctement configuré, on peut utiliser aussi wireshark pour observer les trames passer (attention au firewall et au contrôle d'accès par wilcard -- ici il n'y en a aucun, c'est la fête, heureusement qu'on est en réseau local entre ami, mais ce sont les joies de l'embarqué, *il faut* ne pas squasher root, et avoir un bon dossier /dev avec devices console, null, zero et random au minimum, en root) :

# cat /etc/exports
/home/gblanc/S3C2440/Linux/rootarm/     (rw,no_root_squash,async,anonuid=0,anongid=0)
/home/gblanc/S3C2440/root_default       (rw,no_root_squash,async,anonuid=0,anongid=0)

Je vous ai fait une archive avec les fichiers modifiés aux bons endroits pour une 2.6.27.4 (pour la 2.6.25, il faudrait trop nettoyer de choses :)   ). Le voici : linux-2.6.27.4-emb2440.tar.gz.

Seconde étape : bien brancher son câble J-TAG Amontec-à-30€, ne pas oublier de monter l'usbfs et d'exécuter openOCD en root (ou de bidouiller son udev), sinon ça démarre mal. Bonne nouvelle : on peut faire ce que l'on veut avec le câble, j'ai même trouvé des gens sur le net qui ont fait marcher le Flash programmer, mais je ne m'en suis pas servi personnellement. En revanche, la limitation pour les breakpoints/watchpoints (qui ne marchent pas super bien, en fait) est de seulement deux, donc dès que l'on veut faire du stepping sous gdb, la limite tombe à un : comment passer son temps à faire des del et des b*0x... pour changer au fur-et-à-mesure de points d'arrêts hardware, dommage. En ce qui concerne le gdb, celui de codesourcery marche convenablement, je n'ai pas compris pourquoi celui de buildroot était buggué (dans l'accès aux registres, ça retourne des erreurs ou fait n'importe quoi), j'ai seulement trouvé que le bug avait été repéré il y a quelques années par... un développeur de codesourcery sur gdb. Bref, démarrons notre OpenOCD avec ce fichier de conf :

interface ft2232
jtag_speed 0
jtag_ntrst_delay 100
jtag_nsrst_delay 100

ft2232_vid_pid 0x0403 0xcff8
ft2232_layout "jtagkey"
ft2232_device_desc "Amontec JTAGkey"

jtag_device 4 0x1 0xf 0xe

#daemon_startup attach
target arm920t little 0 arm920t

reset_config trst_and_srst combined

working_area 0 0x33F00000 0x4000 nobackup

#run_and_halt_time 0 500

#nand device <nand_controller> [controller options]
nand device s3c2440 0

#script
init
reset
halt
#nand probe 0
#arm7_9 sw_bkpts enable
arm7_9 force_hw_bkpts enable

On remarque une partie "script" avec "init", "reset" et "halt" ; "reset" sert à redémarrer la carte automatiquement quand on lance OpenOCD (ça évite d'appuyer sur le bouton), si l'on veut se brancher à chaud sans redémarrer la carte, il suffit de le commenter (ça marche très bien) ; "halt" met le CPU sur "pause", idem on peut s'en passer si l'on ne veut pas avoir à entrer "continue" sous gdb (on retrouvera plus tard cet état de la carte avec la commande "mon poll"). Puis on lance arm-none-linux-gnueabi-gdb :

target remote localhost:3333
load ./S3C2440/linux-2.6.25/arch/arm/boot/compressed/vmlinux 0x33D50000
set $r0=0
set $r1=362
set $r2=0
set $sp=0x33D50000
set $pc=0x33D50000
set $lr=0x33D50000

Le Linux compressé (vmlinux) peut être charger à l'adresse 0x33D50000, c'est calculé à la louche (sur une base d'un kernel ne dépassant pas les 2Mo et quelques) pour ne pas être en problème de réécrasement de mémoire lorsque le kernel va se décompresser à l'adresse 0x30008000, et pour éviter d'écraser aussi le u-boot en mémoire à l'adresse 0x33F80000, sait-on jamais, il pourrait resservir. Attention : ne pas charger en 0x0, ça boote mais crashe au bout d'un court moment : la mémoire mappée en 0x0 est bien de la RAM, mais c'est normalement le SteppingStone (copie des 4 premiers Kb de la flash NAND en RAM pour booter dessus, faute d'avoir de la flash NOR, cf paragraphes 6 et 5 de la documentation du S3C2440), de telle sorte qu'au bout d'un certain temps toute la mémoire après 0x1000 est remise à 0. Donc avec un uClinux, il ne faut pas utiliser load tel quel, mais bien préciser une adresse de chargement (je me suis bien fait avoir, surtout que ça avait l'air de marcher... jusqu'à ce que ça parte n'importe où en mémoire, et que ça reboote cycliquement tout seul).

Il ne faut pas oublier de mettre les trois premiers registres dans un état que normalement le boot loader devrait gérer, et qui seront recupérés plus tard au démarrage du noyau : r0 doit être à 0 ; r1 doit contenir l'ID de la machine (on récupère ça dans arch/arm/tools/mach-types, SMDK2440 est 1008, s3c2440 est 362, a9m2440 est 698, et QT2410 est 1108, etc) ; r2 doit pointer sur la ligne de commande, le mettre à 0 revient à utiliser celle compilée en dur par l'option CMDLINE. Il n'y a plus qu'à mettre sp, pc et lr (normalement seul sp suffit, mais bon...) pour pointer sur l'adresse mémoire de chargement du noyau compressé, lancer évidemment un minicom à côté, et entrer "c" comme "continue" dans gdb : c'est parti ! Attention : parfois l'initialisation de sp/pc/lr échoue silencieusement (et parfois bruyamment : sp peut s'être transformé en r13), si l'on retombe sur le boot loader après avoir entré "c", il faut faire un ctrl-C et réaffecter les six registres ci-dessus ; ça méritera un coup de debugging du débugger un de ces quatre... (apparemment ça arrive surtout quand on appelle gdb avec un argument -- cf en dessous)

Pour débugger votre noyau, il faut lancer gdb comme suit :

arm-none-linux-gnueabi-gdb ./S3C2440/linux-2.6.25/vmlinux

Il ne faut pas utiliser add-symbol file : c'est malheureusement buggué, les symboles sont décalés au bout d'un certain temps (la commande "file" semble en revanche saine). Attention : ça utilisera les bonnes adresses après chargement de la MMU. On peut s'en rendre compte avec

arm-none-linux-gnueabi-objdump -D vmlinux | less

Tout est calé sur 0xC0008000. Pour débugger Linux avant décompression, on peut en revanche faire appel à :

add-symbol-file ./S3C2440/linux-2.6.25-uc/arch/arm/boot/compressed/vmlinux 0x33D50000

Ca chargera les symboles (ils ne sont pas bien nombreux) avec comme référence notre adresse de chargement du dessus (attention aux doublons, notamment en terme d'initialisation d'UART !). On peut ensuite mettre des break sur les symboles, faire des print, et des disassemble ; pour arrêter le kernel on peut toujours faire Ctrl-C n'importe quand, bien entendu. On peut aussi passer directement des commandes à OpenOCD :

(gdb) mon poll
target state: halted
target halted in ARM state due to debug request, current mode: Supervisor
cpsr: 0x40000053 pc: 0x33d50000
MMU: disabled, D-Cache: enabled, I-Cache: enabled
(gdb) mon reg
(0) r0 (/32): 0x00000000 (dirty: 1, valid: 1)
(1) r1 (/32): 0x0000016a (dirty: 1, valid: 1)
(2) r2 (/32): 0x00000000 (dirty: 1, valid: 1)
//etc//

"mon help" permet de toutes les obtenir. On peut ainsi modifier directement les registres ("mon reg r1 0x0", par exemple), et gérer le coprocesseur P15 (mon arm920t cp15), cependant mes tentatives pour désactiver la MMU et rebooter manuellement sans avoir à réinitialiser la carte (et donc passer par un rechargement du noyau compressé, ce qui prend un peu de temps) se sont soldés par des échecs (la carte est en carafe, impossible de la mettre en état halt). Attention aussi : le "step" de gdb en assembleur n'est parfois pas terrible (il n'exécute pas une instruction), auquel cas il vaut mieux faire appel au step de OpenOCD via "mon step" ; à ce moment-là, seul "mon reg" donne un état correct des registres, "info registers" semble connaître des problèmes de cache/synchronisation lorsqu'on n'utilise pas les routines de gdb, de telles sortes que les valeurs communiquées sont obsolètes.

Sur le noyau 2.6.27, ttySAC0 ne donne rien comme affichage (après le message de décompression du kernel, plus rien ne s'affiche sur le minicom), en fait la console n'est pas initialisée. C'est un bon moyen de voir comment on peut débugger avec notre J-TAG. Après le chargement en mémoire, et avant de lancer le kernel, on récupère l'adresse virtuelle de printk :

> grep " printk$" System.map
c003deac T printk

On met alors un breakpoint dessus dans gdb :

(gdb) b *0xc003deac
Breakpoint 1 at 0xc003deac
(gdb)

Je n'utilise pas la commande file pour charger les fichiers ici : on pourrait le faire, mais en l'occurrence un bug m'en empêche, gdb segfaulte ! (il faudra vraiment débugger le débugger à un moment :)  ) Il faut dire qu'on le pousse là dans ses derniers retranchements. Il n'y a plus qu'à lancer le kernel avec "c". Lorsqu'on arrive sur printk, voici ce que l'on peut faire :

(gdb) c
Continuing.

Breakpoint 1, 0xc003deac in ?? ()
(gdb) printf "%s",$r0
Linux version 2.6.27.4linagora (gblanc@deepblue) (gcc version 4.2.0 20070413 (prerelease) (CodeSourcery Sourcery G++ Lite 2007q1-10)) #4 PREEMPT Wed Oct 29 19:33:38 CET 2008
(gdb) c
Continuing.

Breakpoint 1, 0xc003deac in ?? ()
(gdb) printf "%s",$r0
CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx
(gdb) c
Continuing.

Breakpoint 1, 0xc003deac in ?? ()
(gdb) printf "%s",$r0
Machine: %s
(gdb) printf "%s",$r1
SMDK2440(gdb) c
Continuing.

Ceci s'affiche avant même l'initialisation de la console ! (cf la fonction register_console dans printk.c, pour ça) On peut ainsi voir où l'on en est : en l'occurrence, on trouve que les printk sautent ce qui devrait normalement s'afficher,

Console: colour dummy device 80x30
selected clock c02c9bf0 (pclk) quot 26, calc 117187
console [ttySAC0] enabled

Le "selected clock" et le "enabled" sont absents. Voilà qui est gênant. Un breakpoint sur la fonction strcmp utilisée dans register_console pour trouver la bonne console à activer montre que "ttySAC" n'est jamais testé ! On cherche donc dans notre ancien kernel 2.6.25 comment cela marchait avant, ie où était inscrit en dur la châine de caractère "ttySAC" : on trouve une macro dans./drivers/serial/s3c2410.c  et quelque chose dans ./drivers/serial/Kconfig : regardons dans 2.6.27, la macro n'existe plus, mais on a quelque chose dans le Kconfig. On fait un xconfig et on active : SERIAL_SAMSUNG et SERIAL_SAMSUNG_CONSOLE, ainsi que SERIAL_S3C2440, tous marqués comme "(NEW)". Tadam, ça marche !  :)

Uncompressing Linux..............................................................................................
done, booting the kernel.
Linux version 2.6.27.4linagora (gblanc@deepblue) (gcc version 4.2.0 20070413 (prerelease) (CodeSourcery Sourcery G
++ Lite 2007q1-10)) #14 PREEMPT Thu Oct 30 15:14:11 CET 2008
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: SMDK2440
Warning: bad configuration page, trying to continue
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists in Zone order, mobility grouping off.  Total pages: 4064
Kernel command line: root=/dev/nfs nfsroot=192.168.1.1:/home/gblanc/S3C2440/Linux/rootarm ip=192.168.1.2:192.168.1
.1::255.255.255.0:Linagora_board::none rw init=/bin/sh console=ttySAC0,115200
irq: clearing pending ext status 00000200
irq: clearing subpending status 00000002
PID hash table entries: 64 (order: 6, 256 bytes)
timer tcon=00500000, tcnt a4ca, tcfg 00000200,00000000, usec 00001e57
Console: colour dummy device 80x30
console [ttySAC0] enabled
Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 16MB = 16MB total
Memory: 13100KB available (2688K code, 277K data, 112K init)
Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
net_namespace: 288 bytes
NET: Registered protocol family 16
S3C2410 Power Management, (c) 2004 Simtec Electronics
S3C2440: Initialising architecture
S3C2440: IRQ Support
S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics
DMA channel 0 at c1800000, irq 33
DMA channel 1 at c1800040, irq 34
DMA channel 2 at c1800080, irq 35
DMA channel 3 at c18000c0, irq 36
S3C244X: Clock Support, DVS off
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP reno registered
NET: Registered protocol family 1
NetWinder Floating Point Emulator V0.97 (double precision)
JFFS2 version 2.2. (NAND) �© 2001-2006 Red Hat, Inc.
msgmni has been set to 25
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
Console: switching to colour frame buffer device 30x40
fb0: s3c2410fb frame buffer device
Serial: 8250/16550 driver4 ports, IRQ sharing enabled
s3c2440-uart.0: s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2440
s3c2440-uart.1: s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2440
s3c2440-uart.2: s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2440
brd: module loaded
loop: module loaded
nbd: registered device at major 43
cs89x0:cs89x0_probe(0x0)
cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>
eth0: cs8900 rev K found at 0xe0000300
cs89x0: No EEPROM
cs89x0 media RJ-45, IRQ 53eth0: Setting MAC address to c0:ff:ee:08:00:00.
, programmed I/O, MAC c0:ff:ee:08:00:00
cs89x0_probe1() successful
cs89x0:cs89x0_probe(0x0)
cs89x0: request_region(0xe0000300, 0x10) failed
cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP
Uniform Multi-Platform E-IDE driver
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 29ns Twrph0=7 69ns, Twrph1=3 29ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Scanning device for bad blocks
Creating 8 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00004000 : "Boot Agent"
0x00000000-0x00200000 : "S3C2410 flash partition 1"
0x00400000-0x00800000 : "S3C2410 flash partition 2"
0x00800000-0x00a00000 : "S3C2410 flash partition 3"
0x00a00000-0x00e00000 : "S3C2410 flash partition 4"
0x00e00000-0x01800000 : "S3C2410 flash partition 5"
0x01800000-0x03000000 : "S3C2410 flash partition 6"
0x03000000-0x04000000 : "S3C2410 flash partition 7"
aoe: AoE v47 initialised.
usbmon: debugfs is not available
s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
mice: PS/2 mouse device common for all mice
S3C24XX RTC, (c) 2004,2006 Simtec Electronics
i2c /dev entries driver
s3c2440-i2c s3c2440-i2c: slave address 0x10
s3c2440-i2c s3c2440-i2c: bus frequency set to 98 KHz
s3c2440-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
Registered led device: led4
Registered led device: led5
Registered led device: led6
Registered led device: led7
Advanced Linux Sound Architecture Driver Version 1.0.17.
ALSA device list:
  No soundcards found.
TCP cubic registered
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
eth0: using half-duplex 10Base-T (RJ-45)
IP-Config: Complete:
     device=eth0, addr=192.168.1.2, mask=255.255.255.0, gw=255.255.255.255,
     host=Linagora_board, domain=, nis-domain=(none),
     bootserver=192.168.1.1, rootserver=192.168.1.1, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.1
Looking up port of RPC 100005/1 on 192.168.1.1
VFS: Mounted root (nfs filesystem).
Freeing init memory: 112K
sh-3.00#
sh-3.00#
sh-3.00# ls
bin  etc   lib      lost+found  opt   root  tmp  var
dev  home  linuxrc  mnt         proc  sbin  usr
sh-3.00# bin
bin/  bind
sh-3.00# bin/
addgroup   chmod      ed         hostname   mv         sleep      vi
adduser    chown      egrep      kill       netstat    stty       zcat
arch       cp         false      ln         pidof      su         zcmp
ash        date       fgrep      login      ping       sync       zdiff
bash       dd         g++        ls         ps         tar        zegrep
bashbug    delgroup   gcc        mkdir      pwd        touch      zfgrep
busybox    deluser    getopt     mknod      rm         true       zforce
c++        df         grep       mktemp     rmdir      umount     zgrep
cat        dir        gunzip     more       run-parts  uname      zless
cc         dmesg      gzexe      mount      sed        usleep     zmore
chgrp      echo       gzip       mt         sh         vdir       znew
sh-3.00# bin/echo toto
toto
sh-3.00# ps
Error, do this: mount -t proc none /proc
sh-3.00# mount -t proc none /proc
sh-3.00# ps
  PID TTY          TIME CMD
    1 ?        00:00:01 sh
    2 ?        00:00:00 kthreadd
    3 ?        00:00:00 ksoftirqd/0
    4 ?        00:00:00 watchdog/0
    5 ?        00:00:00 events/0
    6 ?        00:00:00 khelper
   64 ?        00:00:00 kblockd/0
   69 ?        00:00:00 ksuspend_usbd
   75 ?        00:00:00 khubd
   78 ?        00:00:00 kseriod
   85 ?        00:00:00 kmmcd
  108 ?        00:00:00 pdflush
  109 ?        00:00:00 pdflush
  110 ?        00:00:00 kswapd0
  111 ?        00:00:00 aio/0
  112 ?        00:00:00 nfsiod
  796 ?        00:00:00 mtdblockd
  852 ?        00:00:00 kpsmoused
  878 ?        00:00:00 rpciod/0
  891 ?        00:00:00 ps
sh-3.00#

Ceci est l'ensemble des logs obtenus avec un noyau 2.6.27. On remarque que certaines choses ne marchent pas encore, comme la carte son (à moins de se planter dans le mapping mémoire, ce qui fait sortir de la carte un son extrêmement strident de ce qui s'avère être un buzzer, mais ça n'a rien à voir avec la carte son), ou la RTC (qui sur un 2.6.27, fait ramer le démarrage, alors que ça se passe sans problème sur le 2.6.25) ; le LCD n'a pas encore été testé. Ici, j'utilise un autre config.emb2440-2.6.27eabi avec l'EABI d'activé : ça marche ! :) Il faudra aussi penser à virer le mapping de la flash en dur (berk), et mettre quelque chose de propre avec mtdparts, par exemple (en réalité, on s'en moque, le but maintenant va être de pouvoir écrire sur la flash où l'on veut quand on veut depuis le réseau et non le J-TAG tout lent ou le u-boot tout imprédictible). A voir dans un prochain épisode, certainement (si j'ai le temps...).

mercredi, octobre 29 2008

Linux Device Driver en ligne

Je ne le savais point jusqu'à hier, c'est ici, et c'est sous GNU/FDL. C'est la seconde édition de Alessandro Rubini et Jonathan Corbet, juin 2001, ça date un peu, mais ça évite toujours de transporter son propre exemplaire (et pour faire des recherches, c'est plus rapide aussi :)  ).

lundi, octobre 27 2008

regrouper pour moins régner

Quelle idée ! Quelle mauvaise idée ! Les salon RTS et le salon Solutions Linux seront aux mêmes dates, les 31 mars, 1er avril et 2 avril. Petite consolation, ils seront au même endroit, de telle sorte qu'il sera possible de s'inscrire aux deux (qui ne marchent pas de concert, RTS est toujours associé à DISPLAY et M2M, mais c'est tout), et naviguer de l'un à l'autre, mais quand on sait que des exposants étaient communs, des conférences recoupaient les mêmes thèmes, de telle sorte que l'on avait une petite vision de l'évolution entre février et avril, l'occasion de voir des personnes différentes, ou encore de pouvoir se rattraper sur l'un ou l'autre en cas d'indisponibilité, voilà qui est à présent impossible, et va concentrer sur une date unique (ne rêvons pas, combien d'entreprises vont permettre à leurs employés de faire deux jours de salon d'affilée, avec parfois des conférences payantes ?) deux visions différentes (et forcément incomplètes de chaque côté, puisque complémentaires entre elles) de Linux embarqué. Aïe ! J'espère que les dates évolueront, mais comme le CNIT est fermé et que la porte de Versaille a des réservations très strictes, je crois que c'est mort.

OKL4 et Android

OKL4 attaque le marché des téléphones portables, et pas qu'un peu : voilà annoncé sur CNBC (étrangement, la page officielle sur OK-labs a disparu) la partitipation à l'élaboration du premier téléphone portable basé sur Android de google, comprendre que le Linux est paravirtualisé par la solution australienne (au côté d'un Nucleus ?), celle-la même sur laquelle mon ancien stagiaire travaillait, et a participé en tant que membre très actif de la communauté (mailing list, wiki d'aide, etc). Sur un marché bien différent de celui de Linagora, mais dont on peut espérer un certain recoupement et même, qui sait, une collaboration dans des domaines de compétences complémentaires, voilà une société du libre (le code est sous double licence, sur un modèle de Qt de Trolltech) qui réussit !

vendredi, octobre 24 2008

le très bon chef de proj'

C'est Yannick ! Après avoir quitté momentanément (heureusement !) mes fonctions embarquées pour celles du réseau sécurisé (no comment), j'ai pu découvrir à quel point sa gestion, appliquée au pôle sécu, était claire, directe, efficace, sans ambigüité, levant les flous, synthétisant les situations, prenant les bonnes décisions, que plaisir ! Après avoir testé bien des chefs de proj', je pense que c'est la première fois que je rencontre cela, il fallait donc bien une note pour saluer cette compétence au sein de notre société (bon, il est toujours un peu obnubilé par la méthode agile, mais personne n'est parfait :)  -- d'un autre côté, c'est peut-être bien grâce à ça qu'il est si bon en fait  ^^').

mardi, octobre 14 2008

berk, berk, berk

int  lm_match(struct lm_softc *);
int  wb_match(struct lm_softc *);
int  def_match(struct lm_softc *);

struct lm_chip {
        int (*chip_match)(struct lm_softc *);
};

struct lm_chip lm_chips[] = {
        { wb_match },
        { lm_match },
        { def_match } /* Must be last */
};

void
lm_attach(struct lm_softc *sc)
{
        u_int i, config;

        for (i = 0; i < sizeof(lm_chips) / sizeof(lm_chips[0]); i++)
                if (lm_chips[i].chip_match(sc))
                        break;

J'ai remis bout à bout les bons morceaux, dans la réalité, c'est bien plus espacé, sinon se serait trop lisible... (on remarquera que j'ai tout de même laissé les commentaires d'origine)

- page 4 de 5 -