Je n’ai pas encore trouvé de solution pour la résolution de
l’absence de /dev/mem dans le container 64 bits. De plus je n’ai pas réussi à
installer le périphérique pour lire les compteurs relatifs à la mesure de
performance. En effet il faut créer un module kernel en utilisant un package
contenant les headers linux et il n’existe pas pour la version 64 bits !!.
Donc nous allons voir l’utilisation de X11 pour générer des
fenêtres graphiques. Pour cela nous reprenons la démarche utilisée pour le 32
bits : installation sur le raspberry du package X11 , installation d’un serveur X11 sur le PC
(par exemple Xming), création d’une connexion au raspberry avec le top X11 dans
putty. Pour plus de précisions je vous renvoie au chapitre 30 de ce blog.
J’effectue un premier test en 32 bits avec un des programmes
anciens pour vérifier si la fenêtre s’affiche bien sur le PC : ok pas de
problème.
Je reprends le programme de création d’une simple fenêtre creafen641.s.
Il faut déjà recalculer les positions des données dans les structures car les définitions des zones doivent avoir une longueur de 8 octets. Enfin pas
toutes !! Il faut donc reprendre chaque structure, passer tous les
pointeurs et les entiers longs en 8 octets et laisser les entiers en 4 octets.
Mais il y a des réalignements à faire s’il y a un nombre d’entiers impairs, il
faut ajouter une zone de 4 octets pour que la zone pointeur suivante soit
toujours bien alignée.
En conclusion, les structures du fichier defstruct64.inc
sont toutes à revoir de très prés avant toute utilisation sérieuse.
Ensuite le passage des paramètres à la fonction XCreateSimpleWindow
doit être revu. Nous pouvons passer les 8 premiers paramètres dans les
registres x0 à x7 et le dernier est à passer par la pile. Celle çi doit
toujours être alignée, c’est la raison de l’instruction str x8,[sp,-16]! Avant
l’appel et de l’instruction add sp,sp,16 après l’appel.
Après modification du script de compil pour intégrer les
librairies X11, exécution de la compilation et correction des erreurs !!
lancement du programme.
Et bing erreur : PuTTY X11 proxy: Unsupported
authorisation protocol
Longues recherches sur internet pour trouver l’origine de
l’erreur, sans succès mais une piste apparait en explorant les logs : une
ligne indique que le port 22 est déjà utilisé par un autre service !! Et
en effet à la réflexion j’ai déjà une connexion entre Raspberry et Putty en 32
bits !! Donc il faut modifier le fichier /etc/ssh/sshd_config dans le
container 64 bits pour mettre un autre
port par exemple 3222 au lieu de 22. Et cela fonctionne !
Maintenant, nous allons passer à un programme plus complet.
En 32 bits, j’avais écrit au chapitre 62 un programme qui affichait des images
jpeg et donc suivant le même principe je décide d’écrire un afficheur 64 bits
des images png !! source du programme afficheurPNG.s
Pour cela il faut charger les packages X11 (X11-common,X11-apps
etc.) et le package libpng-dev qui permet d’avoir accès à la librairie libpng
dont on va se servir pour convertir les images PNG. En effet comme pour le
jpeg, il n’est pas question de réécrire toutes les fonctions nécessaires en
assembleur.
La documentation de la libpng peut se trouver ici :
Dans un premier temps, je repars du programme d’affichage
jpeg 32 bits que je transforme en 64 bits à l’aide des consignes du chapitre
précédent. J’effectue aussi les modifications des appels des fonctions X11 et
je crée la même image des 3 cercles colorés utilisée pour jpeg au format png
avec myPaint.
A l’aide de la documentation de la librairie, j’écris la
partie de chargement de l’image jpeg, ouverture du fichier, lecture des 8
premiers octets pour vérifier la signature du fichier ( la fonction à appeler est
différente de celle de la doc car il y a un paramètre supplémentaire qui est
masqué par la redéfinition de la fonction dans png.h). Ensuite création des
structures nécessaires, puis liaison entre ces structures et le FD du fichier à
lire, puis lecture des données.
Ensuite le décodage de l’image est un peu plus complexe car
il faut créer une table de pointeurs qui pointe chaque début de ligne de l’image
en mémoire. Un exemple m’indique que l’image png est inversée, donc les pointeurs
doivent être initialisés en ordre inverse (mais mes tests montrent que cela n’est
pas exact ou alors j’ai fait une erreur lors des affichages X11).
Puis j’adapte le programme pour prendre l’image convertie en
mémoire et l’afficher dans une fenêtre X11.
Après quelques tests et corrections des erreurs, je tombe
sur l’erreur classique dans la fonction de lecture png_read_image que je n’arrive
pas à résoudre. Quelques jours après, je me rappelle que le mélange des
fonctions d’ouverture de fichier en assembleur ne fait pas bon ménage avec les
fonctions de lecture du C utilisées par les librairies. Je récris donc les
ouvertures/ fermetures pour appeler les fonctions du C et le programme
fonctionne correctement.
Enfin presque, car les couleurs de l’image sont inversées
dont j’ajoute une fonction d’inversion pour chaque pixel de l’image.
En lisant la documentation, je découvre qu’il est possible
de convertir des images png à partir d’un buffer en mémoire.
Dans le deuxième programme afficheurPNG2.s, je remets l’ouverture
et la lecture du fichier par des appels system en assembleur et je passe l’adresse
du buffer à la fonction de décodage. Il faut la modifier pour prendre en compte
la lecture depuis le buffer en créant une sous fonction de recopie png_read_from_memPNG.
J’en profite pour modifier les zones réceptrices (pointeurs et pixels images) en
allouant leurs places nécessaires sur le tas.
La lecture et le décodage se passe bien mais l’affichage de
l’image entraine une erreur X11. Si je remets la zone des pixels de l’image en
mémoire et pas sur le tas, l’affichage se passe bien !! L’allocation de la
table des pointeurs elle ne génère pas d’erreurs.
Donc quelques jours après (la réflexion est lente !!)
il me vient que le mélange de l’allocation de place entre ma fonction allocPlace
et les fonctions de la libraire pour créer les structures doivent être
incompatibles surtout que dans l’enchainement je libère la place des structures
par png_destroy_read_struct avant d’afficher l’image X11.
Donc je déporte l’allocation de place de la zone des pixels
de l’image dans la fonction de lecture du fichier car nous pouvons trouver au
début du buffer lu les dimensions en pixel de l’image puis je passe l’adresse
de la zone crée à la fonction de conversion par l’intermédiaire du registre x23 :
c’est pas terrible comme programmation !! c’est à améliorer mais pour les
tests, cela fonctionne bien : voir le programme afficheurPNG3.s
Que reste-il à faire ?
améliorer la programmation entre les différentes fonctions !!
regarder d’un peu plus prés certaines fonctions annexes de conversion d’images
png particulières (niveau de gris) et vérifier le bon fonctionnement de
plusieurs lectures successives d’images différentes.
Il faudrait aussi vérifier la libération de la place du
buffer de lecture, des zones des pointeurs et des pixels dans le cas ou il
faudrait charger un grand nombre d’images. Çà me fait penser que j’avais écrit
un programme de jeu qui se passait dans un labyrinthe et où les murs et le
personnage étaient plus que succincts. Il faudrait que je le réécrive en
utilisant des textures et des images png : du boulot pour l’année 2020 !!!