Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Vhex - Une plateforme de développement
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Vhex - Une plateforme de développement

Posté le 09/03/2020 10:54

Vhex est le nom donné à un regroupement de projet permettant de facilité à la création de jeux vidéo et d'utilitaire bas-niveau pouvant aller jusqu'à la conception de noyau sur des plateformes embarquées.

L'objectif derrière ces fonctionnalités est d'aider à la compréhension et à l’apprentissage de la programmation dite bas-niveau au néophyte, car ce domaine permet d’avoir une bonne vision du monde qui nous entoure et de démystifier le fonctionnement des machines ainsi que certains concepts assez abstraits dans la programmation.


Présentation rapide du projet

Le projet est assez gros et est en réalité composé de plusieurs petits projets. Contrairement à Gint qui est spécifique aux calculatrices Casio et qui est orienté "efficacité" pour créer des jeux extrêmement performants. Vhex n'a pas exactement la même vision.

En effet, je ne vise pas uniquement les calculatrices Casio, mais bien la création de ma propre console portable. Seulement, je ne dispose pas encore des connaissances nécessaires pour arriver à concevoir des machines. C'est pourquoi, (et pour plein d'autres raisons qui seront évoqués dans le premier chapitre du topic), le "proof of concept" du projet est fait sur la calculatrice Casio et plus précisément les calculatrices couleurs.



La vidéo au-dessus montre une démo du projet. Ce qu'il faut retenir de cette vidéo, c'est que le noyau fonctionne et que les API (les fonctions que les utilisateurs pourront utiliser pour construire des choses) de base (dessin, clavier, timer) sont fonctionnels. Cependant, et comme vous allez le voir en lisant le chapitre concernant le noyau, le résultat est globalement extrêmement lent (d'où l'image de fin qui dit "envie d'overclocking") et c'est parfaitement normal. Le projet est jeune* et la gestion des performances ne sont pas à l'ordre du jour.

À l'heure actuelle où j'écris ces lignes, je suis en train de poser toutes les APIs sur papier afin de "geler" toutes les fonctionnalités le plus rapidement possible. Une fois que ce sera fait, je pourrais commencer à faire des optimisations. Je m'attarderai beaucoup plus en détaille sur la planification du projet sur le chapitre d'introduction.

Le projet Vhex regroupe actuellement tous ces projets :

  • plateforme agnostique (indépendante d'une machine)

    • vxKernel : l'unikernel, une des pièces maitresse du projet
    • vxSDK : le SDK pour aider au développement, une des pièces maitresse du projet aussi
    • vxOS : le système d'exploitation qui fournit une interface utilisateur
    • vxGDuck : un projet de démo qui est une adaptation du code de PierrotLL
    • vxControl : un "OS" de contrôle du kernel (comme gintctl pour les connaisseurs)
    • vxOpenLibM : un fork d'openlibm supportant la compilation PIC (pour faire simple : c'est très technique)
    • fxlibc : la librairie standard C

  • calculatrices Casio:

    • sh-elf-vhex : un GCC modifié permettant la création de librairie dynamique (c'est très technique aussi)
    • vxBoot : le bootloader permettant de charger des noyaux en mémoire (et pas que Vhex !)


Pour l'instant, peu de ces projets sont publics, car je manipule pas mal de chose qui flirtent avec la légalité et la stabilité des calculatrices. Je publierai les projets petits à petit après être certains que tout soit en ordre avant d'être rendue public.

Néanmoins, vous pouvez vous balader sur l'instance Gitea de Vhex, afin de voir tous les projets qui y ont été ajouté.

Groupe Gitea : Vhex-Kernel-Core


Structure du topic

Pour des questions de lisibilité et pour ne pas surcharger cette page d'information et de mot technique inutile. Je vais fragmenter mes informations et mes notes dans les commentaires de ce topic et y ajouter des liens pour aller les lires, ça sera beaucoup plus simple pour tout le monde. Cette page fait donc office de "hub" pour le projet.

Ça me permettra de poster les informations au fur et à mesure sans me décourager en voyant la montagne de truc à écrire et ça animera beaucoup plus ce projet plutôt que de le faire dans mon coin.

Je vais aussi essayer de mettre en place une newsletter tous les dimanches pour expliquer mes avancées et mes prévisions pour la semaine suivante. Ça évitera de faire le mort pendant des années alors que beaucoup de choses avancent dans l'ombre.

Aussi, la tête du topic évoluera avec le temps. C'est alors normal que pour l'instant, il n'y ait rien de fou visuellement. Vhex est un projet extrêmement technique qui demande du temps avant d'avoir quelque chose de visuel à montrer.


Sommaire
Le sommaire sera mis à jour avec le temps.





Newsletter


Fichier joint


1, 2 Suivante
Kikoodx Hors ligne Labélisateur Points: 2979 Défis: 11 Message

Citer : Posté le 09/03/2020 14:18 | #


Le projet m'intéresse en tant que spectateur (j'y comprend pas grand chose )
Je suivrai les avancées, le topic est compréhensible
mi lape ala.

J'suis un méga chômeur
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 10/03/2020 15:50 | #


En voilà une affaire intéressante ! Plus besoin d'être un ninja pour savoir ce que tu fais maintenant

J'ai envie de dire plein de trucs mais je vais te laisser continuer à présenter pour l'instant
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 15/03/2020 23:21 | #


Le deuxième jour est arrivé

J'ai envie de dire plein de trucs mais je vais te laisser continuer à présenter pour l'instant

Non dit moi. Je suis vraiment nul pour faire de la communication sur un projet (surtout aussi technique que ça) alors je pense que sans aucun retour je ne pourrais jamais être compris par qui que ce sois à part moi x)

Ajouté le 21/03/2020 à 21:58 :
Le troisième jour est arrivé
Rader Hors ligne Membre Points: 234 Défis: 0 Message

Citer : Posté le 21/03/2020 22:00 | #


Ah, le lien vers wikipedia pour PIE renvoie vers PIC
Oh nvm j'ai pas bien lu la page wikipedia xD
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 21/03/2020 22:10 | #


Ah, le lien vers wikipedia pour PIE renvoie vers PIC

Oui c'est normal mais du coup je l'ai changé pour un lien sur stackoverflow ou quelqu'un explique l'intérêt du PIE

Ajouté le 25/03/2020 à 13:23 :
Le quatrième jour est arrivé
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 01/06/2020 10:15 | #


Salut ! Donc quelques questions pour situer un peu où tu es et où tu vas maintenant.

Le bug de loader il est corrigé depuis la dernière fois ?
Le multi-processus ça se passe bien du coup ? L'ordonnanceur est-il dans un état suffisant pour l'instant ?
Est-ce que tu as pu régler le problème de performances lié au TTY ?
Pour l'implémentation du tas, tu as une idée particulière de la taille ou la méthode que tu vas utiliser ?
Comme drivers matériels du coup, tu as le T6K11, le KEYSC, le TMU, l'UBC... est-ce que veux/envisages/planifies d'utiliser les ETMU, le DMA, ou les ports séries/USB ?
En parlant d'USB, à quel point est-ce tu penses que la recherche que tu as faite jusqu'à présent s'approche de ce qui est nécessaire pour attaquer un driver ? Est-ce que tu as juste une poignée de registres et c'est loin d'être tout ? Ou à l'inverse, est-ce que tu as la plupart des infos nécessaires ?

Je me doute bien que tu as pas fait tout ça en même temps, c'est surtout pour essayer de suivre !
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 01/06/2020 15:29 | #


C'est gentil de demander des nouvelles du projet
Avant toute chose je tiens à m'excuser du manque de nouvelles / infos à propos de ce projet (pratiquement 3 mois, honte à moi) mais le manque de motivation ainsi que la fin d'année on fait que j'ai avancé le projet en sous-marin.

Si ça peut vous "rassurer" le projet n'est pas à l'abandon car une chose est entrée en jeu entre mon dernier poste sur le topic et aujourd'hui : j'ai proposé Vhex comme projet HUB (projet annexe) à Epitech (je suis étudiant là-bas) pour essayer de valider une partie de mon année avec ( ) et pour me forcer à avoir une deadline. Et comme il a été accepté, je dois rendre quelque chose de correcte, propre et montrable (ce que j'estime n'être absolument pas le cas pour l'instant).
Bref, passons aux questions

Le bug de loader il est corrigé depuis la dernière fois ?

Bien sûr ! Je l'ai corrigé quelques jours après. Le problème venait de ma primitive de lecture pour la SMEM qui faisait n'importe quoi quand j'essayais de lire un fragment de données autre que le premier. Parce qu'il faut savoir que les données d'un fichier sont divisé en blocs éparpillés un peu partout dans la ROM donc il faut faire attention quand on change de fragments si on ne veut pas lire n'importe quoi dans la ROM (l'erreur était vraiment toute simple, j'avais une variable que je mettais à 0 en pleins milieux du code pour aucune raison >_> ).

Le multi-processus ça se passe bien du coup ? L'ordonnanceur est-il dans un état suffisant pour l'instant ?

Le multi-processus ce passe bien pour le moment. Actuellement je suis en train de mettre en place un système pour que les processus puissent supporter plusieurs contextes d'exécution à la fois. Ce mécanisme est indispensable pour que la gestion des signaux puisse être accessible à l'utilisateur (via les syscall signal() et sigaction() (autre que les signaux, il y a atexit() et on exit() qui ont besoin de ce mécanisme)).

En parlant de signaux, une partie y est implémentés est fonctionnels. On peut peut mettre en pause, interrompre et quitter un processus via le TTY (CTRL+Z, CTRL+C, CTRL+D). Aussi, un signal peut être envoyé si une erreur est détectée par le kernel.

Pour ce qui est de l'ordonnanceur, il n'est toujours pas préemptif mais est stable pour l'instant.

D'ailleurs, voila la liste des signaux ainsi que les syscalls implémentées (certains sont en cours d'implémentations):
Cliquez pour découvrir
Cliquez pour recouvrir

Signaux
-= ISO C99 =-
SIGINT (Interactive attention signal)
SIGILL (Illegal instruction)
SIGABRT (Abnormal termination (no core dump generated yet))
SIGSEGV (Invalid access to storage)
SIGTERM (Termination request)

-= Historical signals specified by POSIX =-
SIGTRAP (Trace/breakpoint trap)
SIGKILL (Killed)
SIGBUS (Bus error)
SIGSYS (Bad system call)

-= New(er) POSIX signals =-
SIGSTOP (Stop, unblockable)
SIGTSTP (Keyboard stop)
SIGCONT (Continue)
SIGCHLD (Child terminated or stopped)

Appel système
Manipulation de fichier 
open()
close()
read()
write()
pread()
pwrite()
lseek()
opendir() (not implemented correctly)
readdir() (not implemented correctly)
closedir() (not implemented correctly)

Processus
_exit()
fork_execve() (custom, fork() + execve())
wait()
waitpid()
getpid()
getppid()
setpgid()
getpgid()
chdir() (not implemented correctly)
fchdir() (not implemented correctly)
atexit() (not implemented correctly)
onexit() (not implemented correctly)

Signaux UNIX
signal()
sigaction() (not implemented correctly)
kill() (not implemented correctly)
sigprocmask()
sigreturn()

Thread (en pause pour l'instant)
thread_create()
thread_cancel()
thread_atexit()
thread_on_exit()

Gestion de la mémoire
process_heap_alloc()
process_heap_free()
process_heap_realloc()



Est-ce que tu as pu régler le problème de performances lié au TTY ?

Yep. J'ai pu remplacer une bonne partie des opérations atomiques par des mutex et j'ai pu mettre en place un système qui permet d'afficher le TTY en "parallèle", ce qui permet de sortir du syscall "en avance" et surtout de permettre à l'ordonnanceur d'effectuer son travail en même temps que l'utilisation du TTY.

Pour faire simple, les données à afficher est mis dans un buffer (interne au TTY) qui est vidé / affiché de manière monotone. (16 hz pour être précis donc l'affichage est plus lent MAIS il a l'avantage de fluidifier l'exécution des processus en parallèle).


Pour l'implémentation du tas, tu as une idée particulière de la taille ou la méthode que tu vas utiliser ?

Je me rends vraiment compte que je n'ai plus donné de nouvelles depuis longtemps
Le tas est implémenté et pour être honnête je n'ai aucune idée du nom de l'algorithme que j'ai utilisé même si au départ je voulais implementer les arbres AVL. Mais comme j'avais déjà une gestion du tas dans GladOS j'ai repris mes travaux et refactor le code. Je fais donc ma propre tambouille a ce niveau. Ça va être complexe de résumer car il y a plein de subtilité et surtout 2 niveaux de gestion : L'allocation de page et l'allocation du tas.

Pour l'allocation des pages c'est simple: en premier je regarde combien de RAM je dispose puis, je la sépare en deux parties ("cache" et zone libre). Ensuite c'est simple : J'ai une liste chainée (basé sur le "cache") qui indique les "zones" de pages utilisées. Chaque "nœud" de la liste contient juste le numéro de la première page ainsi que le numéro de la dernière. Donc pour trouver un emplacement libre, je calcule le gap entre deux "nœud" et je prends le premier emplacement libre ("first-fit" donc).

Pour ce qui est de l'allocation du tas c'est un peu plus complexe car je ne peux pas avoir un tas linéaire. Donc chaque processus contient une liste de "zone de mémoire" qui font office de "mini-tas". Une zone peut être de n'importe quelle taille et n'est jamais libérée sauf lorsque le processus en question meurt. À chaque appelle de malloc() (par exemple) je parcours la liste des zones en regardant s'il y a de la place dans l'une d'elles. Si aucune place est trouvée dans la liste, je demande au kernel une zone de la taille indiquée par l'utilisateur (et comme le kernel se base sur la taille des pages, une zone allouée sera probablement un peu plus grande, ce qui permet de stocker potentiellement des choses a la fin d'une zone fraichement allouée).

Ce n'est pas la meilleure façon de faire mais il est complexe de mettre en place quelque chose de propre (surtout impossible de fournir sbrk et brk() proprement) d'où les syscall process_heap_*() dans la liste des syscalls. Je referai cette partie quand j'estimerai que le projet est suffisamment mature pour passer à un stade d'optimisation

Je suis très mauvais en explication, si tu as des questions, n'hésite pas

Comme drivers matériels du coup, tu as le T6K11, le KEYSC, le TMU, l'UBC... est-ce que veux/envisages/planifies d'utiliser les ETMU, le DMA, ou les ports séries/USB

La gestion des drivers a totalement été refait depuis la dernière fois et tout est chargé "à-la volée" en fonction des spécificités hardware et de la version de l'OS de Casio. Je pense effectivement implémenter un driver pour le port séries (qui sera utilisable via les sockets ou par un device dans /dev/scif, je ne sais pas encore) et un driver pour l'USB (un device pour le coup, qui transformera la calculatrice en modem). Pour ce qui est des autres drivers, bien sûr ! Je compte gérer le plus de module hardware possible


En parlant d'USB, à quel point est-ce tu penses que la recherche que tu as faite jusqu'à présent s'approche de ce qui est nécessaire pour attaquer un driver ? Est-ce que tu as juste une poignée de registres et c'est loin d'être tout ? Ou à l'inverse, est-ce que tu as la plupart des infos nécessaires ?

Pour l'USB, j'ai quelques registres documentés et j'arrive à signaler à l'hôte que j'existe sur le bus, ce qui me génère une interruption (0xa20)...et je n'arrive pas à la clear. Les registres ne correspondent (de ce que j'ai pu tester) pas au SH7724. Par exemple, le module ne peut pas jouer le rôle d'hôte (on s'en fout mais ça explique pourquoi certains bits disparaissent).

J'ai fait des tentatives (en décembre dernier) de désassemblage du syscall Comme_open(), des menus "cachés" ainsi que les handlers de Casio mais je n'ai vraiment pas trouvé grand-chose :
* Casio utilise le même buffer de 256 octets utilisé par le SCIF (on ne peut pas utiliser le port 3pins et l'USB en même temps).
* Casio utilise le channel 5 du DMA
* Casio semble faire de l'attente active en scannant fréquemment le VBUS pour savoir si l'utilisateur a branché un câble.
* Le clavier ainsi que la RTC sont utilisés dans USB_open() pour des raisons que j'ignore encore.

De cet échec, j'ai fait un prototype d'auto-débogueur pour tracer le syscall mais je ne pouvais pas allez bien loin (car je déboguais l'OS de Casio....avec l'OS de Casio donc à un moment ça a ses limites ) et du coup je suis reparti de 0, ce qui a donné l'origine de Vhex.

Mais récemment j'ai voulu porter Vhex sur Graph35+II E et Graph90+E mais Casio ayant changé le système de fichiers, il était impossible de loader un exécutable depuis la SMEM sans provoquer de crash et pourtant j'utilisais Bfile_*() (cependant, grâce aux découvertes de Lephe je devrai pouvoir utiliser Bfile de manière stable). Lephe a donc décidé de chercher comment être compatible avec Bfile, moi j'ai faits le choix de déassembler les syscalls de Casio pour faire une primitive de lecture propre. Mais comme c'est INCROYABLEMENT long, il me fallait un traceur rapidement. J'ai donc fait un fork de Vhex et retiré beaucoup de choses (mutli-processus, device, ...) histoire de faire un traceur "simple" (...spoiler: je me suis retrouvé à débuguer du multi-threading qui plantaient).

Ceci dit, j'ai réussi à avoir quelque chose d'assez poussé : je pouvais tracer plusieurs syscall en parallèle, poser des breakpoints ou je voulais, ignorer des instructions, des notes s'affichaient si je détectais une adresse connue (syscall, registre, etc.) et je disposais de plusieurs outils :
* [F1] - désassembleur
* [F2] - analyseur de contexte
* [F3] - hexdump
* [F4] - callgraph
* [F5] - rien
* [F6] - kernel log
Et j'ai pu désassembler avec une grande rapidité 80% du syscall Bfile_OpenFile() de la Graph35+II E (qui est encore PIRE que celui de la Graph35+). Mais malheureusement, non seulement je n'ai pas réussi à comprendre le system de fichier mais en plus je suis tombé sur un bug (venant des threads) assez compliquer à trouver et au bout de quelques jours de recherche, j'ai abandonné le projet pour retourner sur Vhex car le temps commence à me manquer.

Mais cette expérience m'a permis de prendre dû recule sur le projet et voila ce que j'ai en tête: j'aimerais pouvoir faire plusieurs projets autour de Vhex:
* un unikernel: juste pour développer des programmes UNIX avec du multiprocessus et faire un peu de RE trainquiloubilou (ce que je suis en train dev d'actuellement)
* un OS: qui aura pour but de remplacer Casio complètement (GaldOS)
* un débogueur: ce dont j'ai parlé plus haut, un débogueur/traceur pour analyser finement le fonctionnement de l'OS de Casio.

Tout ça, j'aimerais que ce sois basé sur le noyau que je développe actuellement, il faut donc quelque chose d'extrêmement propre, souple et bien architecturer pour pouvoir dev sans se soucier du noyau (exactement comme Gint). Je compte donc détacher le shell ainsi que les programmes de tests de Vhex histoire d'avoir le noyau à poil et pouvoir lui faire lire un fichier de configuration (utilisation du MMU, choix du premier exécutable à lancer, log level, ...). Les projets autours seront comme les différentes distributions de Linux.

On en est pas là et ma confiance en moi est foireuse au possible mais c'est carrément faisable avec mes connaissances actuelles. Reste à savoir comment mettre à jour proprement le noyau en restant indépendant vis-à-vis des projets (en gros j'aimerait que les dev n'ai pas à avoir le code du noyau avec eux dans leurs repos, juste des libs (dynamique si possible))
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 02/06/2020 11:41 | #


Le problème venait de ma primitive de lecture pour la SMEM qui faisait n'importe quoi quand j'essayais de lire un fragment de données autre que le premier.

Mais du coup quelle partie du filesystem est-ce que tu maîtrises jusqu'ici ? Ton driver permet de lire les fichiers dans la version homebrew du filesystem qui était dans l'OS 2, c'est ça ? Par opposition à Fugue qui est utilisé sur la Prizm et dans l'OS 3.

Actuellement je suis en train de mettre en place un système pour que les processus puissent supporter plusieurs contextes d'exécution à la fois. Ce mécanisme est indispensable pour que la gestion des signaux puisse être accessible à l'utilisateur (via les syscall signal() et sigaction() (autre que les signaux, il y a atexit() et on exit() qui ont besoin de ce mécanisme)).

Tu ne peux pas juste sauvegarder l'état du processus sur la pile quand tu rentres dans un gestionnaire de signal, pareil que pour le traitement d'une interruption ? Ça n'a pas l'air si différent en termes de fonctionnalités. Ou est-ce qu'il y a des particularités aux signaux qui t'empêchent de faire ça ?

D'ailleurs, voila la liste des signaux ainsi que les syscalls implémentées (certains sont en cours d'implémentations):

Impressionnant ! On peut déjà en écrire des applis sympa avec ça.

Pour faire simple, les données à afficher est mis dans un buffer (interne au TTY) qui est vidé / affiché de manière monotone. (16 hz pour être précis donc l'affichage est plus lent MAIS il a l'avantage de fluidifier l'exécution des processus en parallèle).

Ah, parfait ! Une sorte de synchronisation avec le framerate de l'écran (qu'on suppose être 16 Hz vu que plus vite ça ne se voit pas). Parfait donc, bien joué.

Pour l'allocation des pages c'est simple: en premier je regarde combien de RAM je dispose puis, je la sépare en deux parties ("cache" et zone libre). Ensuite c'est simple : J'ai une liste chainée (basé sur le "cache") qui indique les "zones" de pages utilisées. Chaque "nœud" de la liste contient juste le numéro de la première page ainsi que le numéro de la dernière. Donc pour trouver un emplacement libre, je calcule le gap entre deux "nœud" et je prends le premier emplacement libre ("first-fit" donc).

Hmm un first fit pour un allocateur de pages, surprenant mais pourquoi pas. Donc là sauf erreur de ma part les pages que tu alloues sont en accès direct (sans MMU), c'est pour ça que tu dois trouver des zones aussi grandes que ce qu'on demande ? Parce que si tu alloues qu'une seule page à la fois, ou disposes du MMU pour donner à volonté une illusion de continuité, c'est plus courant de juste garder l'ensemble des pages libres et donner la première à chaque fois.

Pour ce qui est de l'allocation du tas c'est un peu plus complexe car je ne peux pas avoir un tas linéaire.

Ça c'est vraiment la dèche ha ha. Pourquoi est-ce que tu ne libères pas les zones si tout ce qui est dedans est free() ? Ça me paraît être une mauvaise idée de les garder parce que ça monopolise de la mémoire pour rien (et les arguments plus élaborés comme la fragmentation que tu as si tu libères et réalloues trop souvent les zones ont besoin de chiffres pour être crédibles).

Quelle est la taille typique d'une zone et comment cherches-tu un espace libre dans une zone ? C'est un first-fit aussi ?

Je pense effectivement implémenter un driver pour le port séries (qui sera utilisable via les sockets ou par un device dans /dev/scif, je ne sais pas encore) et un driver pour l'USB (un device pour le coup, qui transformera la calculatrice en modem). Pour ce qui est des autres drivers, bien sûr ! Je compte gérer le plus de module hardware possible

Ah ouais, pas mal ! Si j'implémente un driver USB dans gint ce sera très certainement sur ta doc/ton code donc j'attends avec impatience de voir ce qui va se passer sur ce front. En attendant, je ferai sans doute un add-in de transfert avec fxlib parce que la Graph 35+E II et la Graph 90+E ont un workflow assez lent avec le SCSI. On verra ce qui se présente...

Pour l'USB, j'ai quelques registres documentés et j'arrive à signaler à l'hôte que j'existe sur le bus, ce qui me génère une interruption (0xa20)...et je n'arrive pas à la clear. Les registres ne correspondent (de ce que j'ai pu tester) pas au SH7724. Par exemple, le module ne peut pas jouer le rôle d'hôte (on s'en fout mais ça explique pourquoi certains bits disparaissent).

Hmm, ok, je vois un peu l'idée. Il doit y avoir pas mal d'exploration à faire. J'envisage d'écrire un "détecteur de registres" même si c'est un peu risqué.

* Casio utilise le même buffer de 256 octets utilisé par le SCIF (on ne peut pas utiliser le port 3pins et l'USB en même temps).
* Casio utilise le channel 5 du DMA
* Casio semble faire de l'attente active en scannant fréquemment le VBUS pour savoir si l'utilisateur a branché un câble.
* Le clavier ainsi que la RTC sont utilisés dans USB_open() pour des raisons que j'ignore encore.

Hmm, oui ok, rien de totalement inattendu, mais c'est bon à savoir. Merci pour tout ça ! Les bouts désassemblés sont documentés/uploadés sur la bible ?

(cependant, grâce aux découvertes de Lephe je devrai pouvoir utiliser Bfile de manière stable).

Attention, moi je le fais pendant que le matériel es contrôlé par fxlib, et je me suis occupé uniquement de comment reprendre proprement le contrôle après coup sans interrompre BFile. C'est un début, mais ça ne suffit probablement pas (?)

Lephe a donc décidé de chercher comment être compatible avec Bfile, moi j'ai faits le choix de déassembler les syscalls de Casio pour faire une primitive de lecture propre.

En vrai BFile c'est surtout un truc pour remplir les trous à défaut de mieux. Dans la mesure où il y a deux FS différents et pas encore de primitives d'écriture, je suis obligé de faire des compromis si je veux que les jeux développés avec gint puissent avoir ne serait-ce que des sauvegardes. x_x

Ceci dit, j'ai réussi à avoir quelque chose d'assez poussé : je pouvais tracer plusieurs syscall en parallèle, poser des breakpoints ou je voulais, ignorer des instructions, des notes s'affichaient si je détectais une adresse connue (syscall, registre, etc.) et je disposais de plusieurs outils :
* [F1] - désassembleur
* [F2] - analyseur de contexte
* [F3] - hexdump
* [F4] - callgraph
* [F5] - rien
* [F6] - kernel log

Impressionnant ! Le g1a est quelque part ? Des instructions d'utilisation ?

* un unikernel: juste pour développer des programmes UNIX avec du multiprocessus et faire un peu de RE trainquiloubilou (ce que je suis en train dev d'actuellement)
* un OS: qui aura pour but de remplacer Casio complètement (GaldOS)
* un débogueur: ce dont j'ai parlé plus haut, un débogueur/traceur pour analyser finement le fonctionnement de l'OS de Casio.

Bien résumé ! Donc si je suis bien, le débogueur c'est un programme qui embarque l'unikernel un peu comme gintctl embarque gint ?

On en est pas là et ma confiance en moi est foireuse au possible mais c'est carrément faisable avec mes connaissances actuelles.

En attendant t'es encore là et ça avance toujours donc tout ça n'est pas perdu !
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 02/06/2020 17:41 | # | Fichier joint


Mais du coup quelle partie du filesystem est-ce que tu maîtrises jusqu'ici ? Ton driver permet de lire les fichiers dans la version homebrew du filesystem qui était dans l'OS 2, c'est ça ? Par opposition à Fugue qui est utilisé sur la Prizm et dans l'OS 3.

J'arrive à lire des fichiers de la SMEM avec mes propres primitifs, à aucun moment j'utilise Bfile. Pour ce qui est de Fugue (Graph35+II et Graph90), j'ai fait de gros wrappers autour des Bfile_*(). Seulement je crash pour aucune raison au bout de la deuxième lecture de fichier (donc le shell se charge mais pas les exécutables pour l'instant).

J'ai donc tracé le syscall Bfile_OpenFile() dans l'espoir de me passer de Fugue et d'avoir quelque chose de "propre" pour accéder a la SMEM. C'est toujours en cours de RE et c'est loin d'être finis car Fugue est exclusivement en RAM, ce qui n'était pas le cas avant. Donc je dois me taper des fonctions immenses (vraiment) sur des structures non documentées en RAM. C'est long. Ceci-dit, je pensais tracer une des primitives d'écriture en ROM, ce qui forcera Fugue à se "recharger en RAM" et me permettra de desceller le fonctionnement de ce truc.

D'ailleurs, je viens de checker les messages d'erreur "cachés" dans l'OS de la Graph35+ et il se trouve que ce sont exactement les mêmes que Fugue donc il n’est pas impossible que depuis le début Casio utilise Fugue. Ça expliquerait pourquoi je suis tombé plusieurs fois sur des adresses connues comme 0xa0270000 quand je recherchais des endroits de l'OS ou Caiso écrits en EEPROM sur la Graph35+IIE.

Tu ne peux pas juste sauvegarder l'état du processus sur la pile quand tu rentres dans un gestionnaire de signal, pareil que pour le traitement d'une interruption ? Ça n'a pas l'air si différent en termes de fonctionnalités. Ou est-ce qu'il y a des particularités aux signaux qui t'empêchent de faire ça ?

Eh bien figures-toi que je me suis fait la même réflexion dans la journée et oui tu as raison. Je ne sais pas pourquoi j'ai voulu faire autrement xD Au passage, j'en profite pour dire que j'ai implémenté correctement signal() et sigreturn() et j'ai refait l'ordonnanceur (il n’est pas toujours pas préemptif mais bien plus "propre" en termes d'architecture).

Hmm un first fit pour un allocateur de pages, surprenant mais pourquoi pas. Donc là sauf erreur de ma part les pages que tu alloues sont en accès direct (sans MMU), c'est pour ça que tu dois trouver des zones aussi grandes que ce qu'on demande ? Parce que si tu alloues qu'une seule page à la fois, ou disposes du MMU pour donner à volonté une illusion de continuité, c'est plus courant de juste garder l'ensemble des pages libres et donner la première à chaque fois.

C'est ce que je faisais avec GladOS mais dans Vhex je ne touche pas au MMU parce qu'a la base, je voulais faire de ce noyau un environnement de développement et de RE sur l'OS de Casio donc ça implique de ne pas toucher au MMU. Donc oui, je suis obligé d'allouer des zones entières.

Pourquoi est-ce que tu ne libères pas les zones si tout ce qui est dedans est free() ? Ça me paraît être une mauvaise idée de les garder parce que ça monopolise de la mémoire pour rien (et les arguments plus élaborés comme la fragmentation que tu as si tu libères et réalloues trop souvent les zones ont besoin de chiffres pour être crédibles).

Je pars du principe que si l'utilisateur a demandé une grosse taille et qu'il la libère, il risque de la redemander. Donc pour éviter de grosse opérations pour la gestion de la mémoire et de bloquer le processus, je préfère ne pas relacher les zones allouées (pour rappel aucun signal n'est pris en compte tant que l'utilisateur est dans un appel système).

Quelle est la taille typique d'une zone et comment cherches-tu un espace libre dans une zone ? C'est un first-fit aussi ?

Toutes les recherches sont en first fit pour l'instant car ce n'est pas ma priorité d'avoir une gestion de la mémoire ultra sophistiquer. Mais le jour ou le noyau devient mature, je referai cette partie.

Ah ouais, pas mal ! Si j'implémente un driver USB dans gint ce sera très certainement sur ta doc/ton code donc j'attends avec impatience de voir ce qui va se passer sur ce front.

J'ai peur qu'il se passe encore quelque temps avant que je me penche dessus. Voilà en gros ma "TODO list" :
* 1) Réorganiser le projet (car certaines parties ne me plaisent pas)
* 2) Implémentation correcte des signaux.
* 3) Portage sur Graph35+IIE (en partie faite, il manque plus qu'à tester le Bfile)
* 4) Portage sur Graph90 (Il faut revoir beaucoup de choses, notamment le dessin et l'organisation du repo)
* 5) Isoler complètement le noyau des librairies.
* 5) Reprendre le prototype de traceur que j'ai commencé (et qui est cassé actuellement)
* 6) Faire des primitives propres pour Fugue.
* 7) Faire un driver USB.
* 8) Faire un driver pour l'écriture en EEPROM (Bfile ?)
Donc il reste encore beaucoup de choses à faire. Je pense pouvoir atteindre le point 3 cette semaine mais le reste risque de prendre beaucoup plus de temps.

J'envisage d'écrire un "détecteur de registres" même si c'est un peu risqué.

Comment ça ? (si c'est ce que je pense, c'est plus que risqué xD)

Les bouts désassemblés sont documentés/uploadés sur la bible ?

J'ai la mauvaise habitude de ne rien documenter nulle part d'autre que dans le fichier ou je désassemble. Donc si je peux mettre sur la Bible les OS que j'ai commencé à désassembler, en accès libre je suis partant mais il y aura potentiellement des zones "sensibles". À voir si c'est vraiment gênant.

Attention, moi je le fais pendant que le matériel es contrôlé par fxlib, et je me suis occupé uniquement de comment reprendre proprement le contrôle après coup sans interrompre BFile.

C'est exactement ce que je fais de mon côté aussi. Quand je monte le système de fichiers de Casio (que j'ai appelé smemfs), j'utilise Bfile_Find*() pour faire un dump complet de stockage (probablement ce que fait Fugue d'ailleurs). Le reste des primitives (open, read et close) sont des wrappers autour des Bfile_*().

Impressionnant ! Le g1a est quelque part ? Des instructions d'utilisation ?

Malheureusement non, j'ai la fâcheuse tendance à commit uniquement quand quelque chose est stable. Du coup, j'ai cassé le repo sans le vouloir. Mais j'ai un proto (fichier joint, il est compatible avec toutes les graph mono) qui est vaguement fonctionnelle sauf que le retour menu provoque une corruption de mémoire et certaine opcodes sont mal traduitent (malin). D'ailleurs, j'ai appris que récemment (par toi) que Casio a eu l'idée du siècle en mappant l'adresse 0 (NULL pour les intimes) vers le début de la ROM. Du coup je peux faire un truc du style:

uint32_t tab = NULL;
uint32_t a = tab[3];

Sans aucune exception. C'est qui est honteux et très fourbe car je me suis rendu compte que certaine variable n'était pas initialisée correctement durant le boot du noyau. Bref c'est d'une tristesse absolue cette OS de Casio.
Utilisation / notes pour le traceur
Cliquer pour enrouler

Le tracer à un seul but ici, tracer le syscall Bfile_OpenFile().
Pour revenir au menu c'est la touche [MENU] mais il y a de forte chances pour que ça provoque de la corruption de mémoire on reste bloqué dans le traceur (malin) du coup il faut mieux reset pour sortir du truc >_<

[F1] - menu désassembleur
* [UP] / [DOWN] scrolle.
* [-] - déplace le prochain break point vers le haut.
* [+] - déplace le prochain break point vers le bas.
* [EXE] continuer l'exécution du programme jusqu'au prochain break point.
* [OTN] force le programme à reprendre la ou le prochain break point a lieu (indispensable pour skip les instructions qui bloquent les interruptions ! Si SR.BL est mis à 1, les breaks ne point seront ignorés !)

[F2] - menu contexte et [F3] - hexdump
* [UP] / [DOWN] scrolle
* [LEFT/RIGHT] scrolle


Donc si je suis bien, le débogueur c'est un programme qui embarque l'unikernel un peu comme gintctl embarque gint ?

Ouais mais sur le long terme, les développeurs auront des libraires dynamiques pour communiquer avec le noyau et ils pourront créer un fichier de configuration (*.vhex?) pour choisir :
I] l'architecture du noyau:
* unikernel: Il s'installe en RAM et ne rentre en aucun cas en conflit avec Casio.
* kernel: Il prend le contrôle complet de la machine (donc pas de retour menu possible).
* OS-receiver (par défaut(?), si aucun fichier de config n'est trouvé): permettant de flasher (via l'USB) l'OS de Casio ou GladOS quand il sera disponible.
II] Les différents modules du kernel à charger au démarrage (ordonnanceur, thread, processus, VFS, ...)
III] Le nom du projet
IV] Le log level
V] Le choix du device pour écrire les logs du kernel (TTY, USB, series?)

Et je pense offrir la possibilité d'avoir du multi-boot (une sorte de Grub) pour pouvoir choisir quoi lancer avec le noyau *-*

Bref, on en est vraiment pas à ce point là d'avancement mais ça me semble faisable (il y a beaucoup de choses à prendre en compte encore mais voila l'idée que je me fais du noyau), à voir à l'avenir
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 02/06/2020 19:26 | #


Donc je dois me taper des fonctions immenses (vraiment) sur des structures non documentées en RAM. C'est long.

Mais on sait que c'est du FAT 12/16/32 ou du VFAT. Pourquoi ne pas simplement commencer par là ? Ça m'étonnerait que tu puisses pas chercher dans la RAM des entrées de la table des fichiers.

Ceci-dit, je pensais tracer une des primitives d'écriture en ROM, ce qui forcera Fugue à se "recharger en RAM" et me permettra de desceller le fonctionnement de ce truc.

On en a déjà parlé, mais je vois pas pourquoi tu veux absolument que tout se passe en ROM. Tu as de toute façon besoin de deux implémentations du système de fichier pour l'ancien FS et le nouveau, alors si la table des fichiers est en RAM pourquoi s'emmerder avec des acrobaties qui ne servent à rien ? :x

C'est ce que je faisais avec GladOS mais dans Vhex je ne touche pas au MMU parce qu'a la base, je voulais faire de ce noyau un environnement de développement et de RE sur l'OS de Casio donc ça implique de ne pas toucher au MMU.

Et comment tu conçois ton interaction avec l'OS ? Parce qu'autant dans gint je peux juste prendre le contrôle du matériel et le rendre quand ça m'arrange, autant là avec le débogueur tu as besoin d'exécuter du code de l'OS en même temps que le kernel. Quel est le modèle ?

Je pars du principe que si l'utilisateur a demandé une grosse taille et qu'il la libère, il risque de la redemander. Donc pour éviter de grosse opérations pour la gestion de la mémoire et de bloquer le processus, je préfère ne pas relacher la mémoire (pour rappel aucun signal n'est pris en compte tant que l'utilisateur est dans un appel système).

Je te laisserai faire les expérimentations si l'envie t'en prend, mais tu vas surtout perdre beaucoup de mémoire ! Perso j'y crois pas trop. Je pense que c'est plus intelligent de rendre la zone, et le processus pourra décider tout seul de ne pas free() s'il considère qu'il en aura besoin de nouveau plus tard. Comme ça il peut agir en connaissance de cause selon la taille de la zone, etc. Imagine un vecteur qui ne fait que grandir, chaque zone libérée serait inutilisable donc conservée pour rien.

Toutes les recherches sont en first fit pour l'instant car ce n'est pas ma priorité d'avoir une gestion de la mémoire ultra sophistiquer. Mais le jour ou le noyau devient mature, je referai cette partie.

C'est honnête. Et du coup c'est quoi la taille moyenne d'une zone ? :3

* 4) Portage sur Graph90 (Il faut revoir beaucoup de choses, notamment le dessin et l'organisation du repo)

Bon courage, moi j'ai repris gint de quasiment zéro et ça m'a pris trèès longtemps, sans doute plus que nécessaire. Je te conseille pas de faire pareil.

C'est une sacrée liste, hésite pas à poster des updates ici. Y'a deux points 5 aussi.

Comment ça ? (si c'est ce que je pense, c'est plus que risqué xD)

Première passe, tu cherches des adresses qui ne renvoient pas la même valeur selon la taille de l'accès. Ça détectera tous les registres dont au moins un des bits est égal à 1 à ce moment-là (parce que s'il n'y a pas de registre ça renvoie 0 en général), donc... probablement la majorité. Deuxième passe, tu cherches dans les trous, tu cherches des modules SH7*** qui ont un agencement relatif similaire, des occurrences dans le code de l'OS, etc. Troisième passe, si tu as un match avec un module, on peut tenter d'écrire dans les registres pour faire des tests préliminaires pour un driver.

J'ai la mauvaise habitude de ne rien documenter nulle part d'autre que dans le fichier ou je désassemble. Donc si je peux mettre sur la Bible les OS que j'ai commencé à désassembler, en accès libre je suis partant mais il y aura potentiellement des zones "sensibles". À voir si c'est vraiment gênant.

J'ai uploadé un petit nombre de fichiers désassemblés déjà. Assure-toi juste qu'il n'y a rien d'explicitement sensible (ou tu fais semblant de pas savoir ce que c'est).

C'est exactement ce que je fais de mon côté aussi. Quand je monte le système de fichiers de Casio (que j'ai appelé smemfs), j'utilise Bfile_Find*() pour faire un dump complet de stockage (probablement ce que fait Fugue d'ailleurs). Le reste des primitives (open, read et close) sont des wrappers autour des Bfile_*().

Mais du coup ton kernel contrôle le matériel donc c'est pas ce que je fais du tout... right? Ou alors tu décharges posément les drivers pendant que tu montes le fs et tu n'en as jamais parlé ?

Ouais mais sur le long terme, les développeurs auront des libraires dynamiques pour communiquer avec le noyau

Et le noyau il est chargé quand ? Parce que c'est bien malin d'avoir une interface mais il faut que le truc soit lancé. Et en quoi est-ce que ça diffère des syscalls, qui sont la méthode canonique de communication userspace/noyau ?

* unikernel: Il s'installe en RAM et ne rentre en aucun cas en conflit avec Casio.

Soit dit en passant la notion d'unikernel englobe tous les noyaux qui sont sous formes de libs et intégrés directement dans l'exécutable, donc selon les libs partagées que tu auras le terme sera pas forcément approprié.

Et je pense offrir la possibilité d'avoir du multi-boot (une sorte de Grub) pour pouvoir choisir quoi lancer avec le noyau *-*

Euh si c'est le noyau qui lance des exécutables c'est juste un userspace. Un multiboot ce serait si t'as plusieurs noyaux !
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 02/06/2020 23:24 | #


Mais on sait que c'est du FAT 12/16/32 ou du VFAT. Pourquoi ne pas simplement commencer par là ? Ça m'étonnerait que tu puisses pas chercher dans la RAM des entrées de la table des fichiers.
[...]
On en a déjà parlé, mais je vois pas pourquoi tu veux absolument que tout se passe en ROM. Tu as de toute façon besoin de deux implémentations du système de fichier pour l'ancien FS et le nouveau, alors si la table des fichiers est en RAM pourquoi s'emmerder avec des acrobaties qui ne servent à rien ? :x

J'ai déjà fait des recherches en RAM et je n'ai absolument rien trouvé. C'est vraiment frustrant x)

Je ne veux pas forcément que tout se passe en ROM. Je veux juste comprendre ou et comment le FS est organisé en ROM pour pouvoir y accéder proprement. Parce que, crois-moi, Fugue + Bfile c'est d'une lenteur affolante en plus d'être incroyablement lourd et dangereux avec tous les buffers utilisés par Casio. Et on ne peut pas utiliser l'API de Fugue car justement il est en RAM donc pas à une adresse fixe donc impossible de communiquer avec lui "proprement". Encore une fois, mon objectif est de me débarrasser définitivement de Fugue. Et je pense avoir quelque piste sur l'organisation du nouveau FS mais je n'ai pas vraiment le temps de faire des recherches plus avancé maintenant.

Mais du coup ton kernel contrôle le matériel donc c'est pas ce que je fais du tout... right? Ou alors tu décharges posément les drivers pendant que tu montes le fs et tu n'en as jamais parlé ?

Ah ! Oui j'ai oublié de dire que je décharge les drivers et restaure tout l'environnement de Casio avant d'utiliser quoique ce sois qui a un lien avec l'OS

Et le noyau il est chargé quand ? Parce que c'est bien malin d'avoir une interface mais il faut que le truc soit lancé. Et en quoi est-ce que ça diffère des syscalls, qui sont la méthode canonique de communication userspace/noyau ?
[...]
Euh si c'est le noyau qui lance des exécutables c'est juste un userspace. Un multiboot ce serait si t'as plusieurs noyaux !

Actuellement, le noyau est un addin g1a / g3a. Lorsqu'il démarre il charge tous les drivers possibles en fonction de l'OS et du MPU (clavier, power, cpg, intc, vbr, ubc, tmu, ecran, keysc) ainsi que ses "modules" (mémoire, ordonnanceur, VFS, devices, processus). Ensuite il essaie de créer le premier processus (qui n'est pas init() mais directement le shell (qui se trouve dans /mnt/casio/VHEX/shell.elf)). Puis roulez jeunesse.

Mais par la suite j'aimerais que le g1a/g3a devienne un BIOS. Et là j'hésite. Sois il se base sur les syscalls de Casio (le plus simple) ou alors il chargera le noyau avec le strict minimum (vbr + driver clavier/écran) et disposera de ses propres primitifs de lecture pour la SMEM. Ensuite il cherchera dans la SMEM tous les fichiers de configuration avec une extension bien précise (*.vhex par exemple) qui lui dicteront comment charger le reste du noyau. Si plusieurs fichiers sont détectés, alors il y aura un menu pour choisir quelle configuration on veut (comme un Grub. Les deux programmes seront au sein du même addin).

Mais du coup j'ai le même problème qu'avec GladOS: ça implique que le noyau doit pouvoir être relocalisé (je commence à comprendre l'intérêt de GNU/Hurd, je me tâte à partir sur un truc comme ça ). Le plus simple serait d'avoir un addin qui fait office de BIOS/Grub et le noyau (un fichier ELF certainement) dans la SMEM qui sera chargée dynamiquement en RAM en fonction de la config choisie. Mais comme je suis têtu, j'aimerais avoir qu'un seul g1a (pour des raisons pratiques). Donc ça impliquerait de pouvoir relocaliser ou on veut (ASLR?) du code venant d'un addin vers la RAM, il faudra faire des tests pour voir comment faire ça proprement car je ne suis pas sûr que ce sois faisable facilement (x_x)

Et comment tu conçois ton interaction avec l'OS ? Parce qu'autant dans gint je peux juste prendre le contrôle du matériel et le rendre quand ça m'arrange, autant là avec le débogueur tu as besoin d'exécuter du code de l'OS en même temps que le kernel. Quel est le modèle ?

En fait pour être plus précis, quand je trace un syscall, deux threads sont créés : un qui se contente d'exécuter le syscall et un autre qui exécute uniquement l'handler de l'UBC donc tout est isolé. (@note: il n'y a pas d'ordonnanceur dans le débogueur, pour changer de contexte j'utilise un syscall dédié. C'est d'ailleurs pour ça que j'aimerais pouvoir spécifier les modules du noyau à charger)

Une fois le premier break point posé, je décharge mes drivers et je change de contexte pour passer sur le thread qui va exécuter le syscall de Casio. Lorsqu'un break point est atteint une interruption à lieu SAUF où'au lieu d'utiliser la VBR, l'UBC utilise le registre DBR (qui joue le même rôle que la VBR. On peu choisir entre VBR/DBR en configurant l'UBC correctement). Ce qui me permet de brancher dans mon kernel uniquement avec un Break Point Après il me reste juste à sauvegarder le contexte actuel (thread syscall), charger le contexte du thread qui exécute l'handler (thread UBC) puis je recharge les drivers et PAF ça fonctionne.

Bon courage, moi j'ai repris gint de quasiment zéro et ça m'a pris trèès longtemps, sans doute plus que nécessaire. Je te conseille pas de faire pareil.

En théorie je n'ai aucun problème à porter le noyau sur la Graph90 (bon, il faut que fasse le driver DMA, quelque ajustement pour le TTY (pour la couleur) et il faut que je revois l'organisation générale du projet pour générer un g1a et un g3a) mais en matière de code je ne devrai pas avoir de problème d'architecture.

Et du coup c'est quoi la taille moyenne d'une zone ? :3

Une page fait 1ko et le malloc() demande des zones qui sont tronquées "((size + 1023) / 1024) * 1024 " histoire de pouvoir demander au kernel un nombre précis de pages "qui se suivent". Ensuite je les ajoute au processus (elles sont cachées). Quand il meure toutes les pages sont relâché "manuellement" par le noyau. Comme ça je suis sûr que la mémoire est complément libéré.

Soit dit en passant la notion d'unikernel englobe tous les noyaux qui sont sous formes de libs et intégrés directement dans l'exécutable, donc selon les libs partagées que tu auras le terme sera pas forcément approprié.

Sérieux ? Moi je pensais vraiment qu'un unikernel désignait un noyau qui partage le même espace mémoire que les processus (donc pas de gestion de mémoire virtuelle). Mince. Mais du coup ça s'appelle comment ce que je suis en train de faire ? xD
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 03/06/2020 08:54 | #


Je veux juste comprendre ou et comment le FS est organisé en ROM pour pouvoir y accéder proprement. Parce que, crois-moi, Fugue + Bfile c'est d'une lenteur affolante en plus d'être incroyablement lourd et dangereux avec tous les buffers utilisés par Casio.

Ça d'accord, mais la lenteur c'est pas parce qu'il y a une partie en RAM. Déjà c'était déjà lent avant. Et en plus parcourir une table dans la RAM ça va sensiblement plus vite que faire pareil dans la ROM (à mitiger avec l'effet du cache). Personnellement je n'ai encore vu aucune explication crédible de la lenteur de BFile, donc il me paraît être bien trop tôt pour décider comment il faut faire pour aller vite.

Et on ne peut pas utiliser l'API de Fugue car justement il est en RAM donc pas à une adresse fixe donc impossible de communiquer avec lui "proprement".

Qui a dit que le code de Fugue était dans la RAM ? Y'a pas la moindre raison, et t'as jamais mentionné ça avant.

Encore une fois, mon objectif est de me débarrasser définitivement de Fugue. Et je pense avoir quelque piste sur l'organisation du nouveau FS mais je n'ai pas vraiment le temps de faire des recherches plus avancé maintenant.

Ça peut pas être aussi simple que "se débarrasser définitivement du fs en place". Soit tu te moques de préserver fs codé par Casio et alors t'as aucune raison de le rétro-analyser puisqu'il te suffit de mettre de l'ext à la place dans la ROM. Soit tu veux le préserver et alors tu pourras pas éviter de travailler avec/pour Fugue parce que la cohérence de ce fs dépend de structures de données de Fugue. Même si c'est du FAT standard, si Fugue maintient la table des fichiers dans la RAM, tu seras bien obligé de faire pareil. L'histoire de "Fugue relit peut-être la table dans la ROM" c'est une idée complètement infondée et non vérifiée que j'ai émise pour voir si charger la table des fichiers en RAM restait viable même en présence de crash/reset. Y'a zéro garantie que ça se fait, et surtout il y aura d'autres problèmes ailleurs. Tu peux pas cohabiter avec le code existant et l'ignorer complètement.

Ah ! Oui j'ai oublié de dire que je décharge les drivers et restaure tout l'environnement de Casio avant d'utiliser quoique ce sois qui a un lien avec l'OS

Ah c'est donc bien le truc que j'ai galéré à faire marcher à trois reprises. Attention aux ETMU, au DMA et aux TLB, même si maintenant tu le sais...

Mais par la suite j'aimerais que le g1a/g3a devienne un BIOS.

Donc plus l approche unikernel. Quel est l'avantage de ça ? Qu'est-ce qu'on y gagne par rapport à juste intégrer le noyau dans les add-ins ?

Mais comme je suis têtu, j'aimerais avoir qu'un seul g1a (pour des raisons pratiques).

Tu peux intégrer l'ELF du noyau dans le g1a du bootloader mais ça casse tout l'intérêt de séparer les deux.

(ASLR?)

Ça a pas besoin d'être aléatoire, l'ASLR est un patch pour des failles de sécurité dans lesquelles tu peux modifier/tricher avec le code des programmes si tu sais à quelle adresse ils sont chargés. Vois Return-to-libc par exemple.

Une fois le premier break point posé, je décharge mes drivers et je change de contexte pour passer sur le thread qui va exécuter le syscall de Casio.

Donc tu changes le contrôle de tout le matériel (UBC exclus) en permanence. Jolie acrobatie ! J'ai tellement galéré à rendre ça stable dans gint que je me demande comment ça peut paraître si facile quand c'est toi qui le racontes.

Une page fait 1ko et le malloc() demande des zones qui sont tronquées "((size + 1023) / 1024) * 1024 " histoire de pouvoir demander au kernel un nombre précis de pages "qui se suivent".

Ok, ça a l'air raisonnable. Au passage ça s'écrit aussi (size + 1023) & ~1023 cette chose (mais tu le sais certainement déjà >_>).

Ajouté le 03/06/2020 à 08:55 :
Sérieux ? Moi je pensais vraiment qu'un unikernel désignait un noyau qui partage le même espace mémoire que les processus (donc pas de gestion de mémoire virtuelle). Mince. Mais du coup ça s'appelle comment ce que je suis en train de faire ? xD

C'est plus un kernel monolithique du coup. Que tu te fasses chain-load de façon compliquée par un bootloader caché dans un g1a lancé par CasioWin n'y change pas grand-chose.
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 03/06/2020 12:04 | #


Ça d'accord, mais la lenteur c'est pas parce qu'il y a une partie en RAM. Déjà c'était déjà lent avant. Et en plus parcourir une table dans la RAM ça va sensiblement plus vite que faire pareil dans la ROM (à mitiger avec l'effet du cache). Personnellement je n'ai encore vu aucune explication crédible de la lenteur de BFile, donc il me paraît être bien trop tôt pour décider comment il faut faire pour aller vite.

Hoo non la lenteur vient du fait que Fugue ne se base pas sur des caractères étendu (uint16_t) pour stocker le path mais sur des chars classiques (uint8_t). Donc le path qu'on envoie au Bfile et traité une première fois par Casio puis envoyer à Fugue qui le check à son tour (au passage il "s'auto-check lui-même"). Ensuite Fugue vérifie que le path contient de caractère valide (ASCII et SHIFT-JIS) et le converti comme ça : "\\fls0\vhex.g1a" -> "\vhex.g1a". Casio repend la main et reconvertit le path de Fugue en uint16_t, vérifie si l'OS accepte les caractères étendu (en fonction de l'OS qu'on utilise), check si le path est valide (taille des noms fichiers + type de caractère + taille de l'extension (s’il en détecte une) + noms spéciaux, genre . et .., etc, etc, ...). Il finit par compter combien de niveau il y a dans le path (ex: "\VHEX\shell.elf" = 2 niveaux).

Ensuite il récupère le dernier fichier du path ("\VHEX\shell.elf" -> "shell.elf"), retire les espaces (uniquement ceux qui se trouvent devant le nom) et regarde s’il y a une extension (si oui, il regarde si l'extension est connue) puis demande à Fugue de trouver le fichier. Une fois trouvé il regarde si le fichier a un parent. Si oui alors Fugue + Casio réanalysent le path, récupère le nom du fichier parent ("\VHEX\shell.elf" -> "VHEX") et font une recherche avec Fugue, s’il est trouvé il regarde s’il est lié avec le premier fichier et s'il y a encore un parent, ils recommencent à analyser le path.

Les manipulations avec le path sont extrêmement lentes car Casio reconvertie le path super souvent et (Fugue/Casio) vérifient la validité *complète* du path à chaque fois. Et là, tu as seulement 60% de ce qu'il se passe avec Bfile_OpenFile() car il y a des parties que je ne n'ai pas encore réussie à déchiffrer.

Qui a dit que le code de Fugue était dans la RAM ? Y'a pas la moindre raison, et t'as jamais mentionné ça avant.

Une grosse partie de Fugue est en RAM et aucun syscall n'est appelé dans Bfile_OpenFile() faisant référence à ce truc. Donc on ne peut pas l'utiliser via des syscalls et les structures en RAM ne sont pas fixes.

Soit tu veux le préserver et alors tu pourras pas éviter de travailler avec/pour Fugue parce que la cohérence de ce fs dépend de structures de données de Fugue.
[...]
Tu peux pas cohabiter avec le code existant et l'ignorer complètement.

Je veux seulement pouvoir y accéder en lecture donc si, je peux largement me passer de Fugue. Le jour où je fais de l'écriture, oui, il faudra que je trouve un moyen pour être compatible avec Fugue (ou simplement trouver le moyen de le forcer à se régénérer en RAM, si c'est possible).

Donc plus l approche unikernel. Quel est l'avantage de ça ? Qu'est-ce qu'on y gagne par rapport à juste intégrer le noyau dans les add-ins ?

Ça permettrait de supporter et choisir entre plusieurs configurations du noyau et de le charger dynamiquement en RAM par "modules" au lieu de le charger complètement à chaque fois. (Le noyau serait un peu comme une librairie dynamique en gros). De plus, si le BIOS/Gurb (je ne suis pas sûr du nom) devient assez élaborer, on peut imaginer pouvoir en faire une interface pour des transferts de fichiers et / ou un moyen de flasher des OS customs.

Donc si je résume mon idée, il y aura 3 projets distincts : le BIOS/Grub (pas sûr que ce sois les meilleurs termes pour ce truc), le noyau (reste encore à définir la forme qu'il prendra) et les librairies (dynamique si possible)

Tu peux intégrer l'ELF du noyau dans le g1a du bootloader mais ça casse tout l'intérêt de séparer les deux

Oui tu as raison. C'est très con comme idée dit comme ça xD (Je pensais plus à l'aspect pratique d'avoir qu'un seul addin à installer au lieu d'un g1a et d'un ELF. Mais ça casse l'intérêt du projet, malin )

je me demande comment ça peut paraître si facile quand c'est toi qui le racontes.

Il suffit d'être parano et de partir du principe que le code peut être exécuté par plusieurs entités en même temps et être interrompue en plein milieu d'une opération. Comme ça, ça force à sécuriser le code. Mais je suis surpris de voir à quel point c'est stable alors que je ne gère pas la DMA et les ETMU.
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 03/06/2020 13:21 | #


Hoo non la lenteur vient du fait que Fugue ne se base pas sur des caractères étendu (uint16_t) pour stocker le path mais sur des chars classiques (uint8_t).

C'est pas lent, ça. Je viens de mesurer avec libprof que convertir 100 fois "\\fls0\vhex.g1a" dans les deux sens prend 359 µs (oui le cache aide beaucoup et les variables locales sur la pile sont couvertes par le cache !). En plus ça n'a rien à voir avec la lenteur d'écriture dans un fichier, celle qui fait que sauvegarder 1 Mo de la ROM prend pas loin d'une minute. À la limite ça peut être un problème pour les fonctions de recherche et le fait que MEMORY est de plus en plus lent quand le nombre de fichiers augmente, mais encore faut-il s'assurer que ce n'est ni la fragmentation ni la GUI ni whatever.

Donc autant je suis persuadé aussi qu'on peut faire plus vite que BFile, autant pour l'instant je suis pas du tout convaincu qu'on sait où est le bottleneck dans l'histoire. En plus si le problème était vraiment là tu pourrais utiliser directement Fugue avec des u8 classiques dans Vhex (avec utf8 derrière si l'envie t'en prend) et les performances seraient très bien, donc je suis presque sûr que tu d'autres raisons de vouloir le contourner.

Les manipulations avec le path sont extrêmement lentes car Casio reconvertie le path super souvent et (Fugue/Casio) vérifient la validité *complète* du path à chaque fois.

Si la validité c'est juste que ça commence "\\fls0\", on s'en remettra. Si ça parcourait la table de fichiers en RAM, alors tu saurais certainement la trouver (^^"), et en tous cas c'est pas si long parce que RAM+cache encore une fois.

Oublions pas que le CPU tourne à 0.12 GHz (c'est beaucoup écrit comme ça hein ?) donc il faut un peu plus que de l'overhead mondain pour expliquer des lenteurs caractéristiques. Moi je serais plus intéressé de regarder les specs de la puce de ROM (qu'on a d'ailleurs), la config du BSC et l'utilisation du DMA dans l'affaire. Le reste tu n'auras pas de difficultés à le faire suffisamment rapide, et je pense que même si la version Casio est moche, ce n'est sans doute pas le coeur du problème.

Une grosse partie de Fugue est en RAM et aucun syscall n'est appelé dans Bfile_OpenFile() faisant référence à ce truc. Donc on ne peut pas l'utiliser via des syscalls et les structures en RAM ne sont pas fixes.

Qu'il n'y a pas de syscalls dédiés, pas de problème, mais le code est quand même presque toujours dans la ROM ? Le seul code en RAM actuellement connu c'est les syscalls flash dans la mémoire RS. Je vois pas de raison que ce soit fait autrement que r2=0x80machin et jsr @r2, et comme tu n'as pas encore dit explicitement le contraire (eg. r2=0x88machin et jmp @r2) ni publié d'extraits désassemblés je sais toujours pas. x_x

Mais qu'on ne puisse pas l'appeler directement, ok, et que les structures soient pas fixes, ok. Après tu peux toujours essayer de les trouver en détectant les structures par une recherche dans la RAM (comme les tables ACPI sur x86), ou en faisant des acrobaties pétées comme analyser dynamiquement le code pour trouver les adresses, un peu comme dans GetGetKeyToMainMenuReturnFlag() ici où le code donné par SimLo désassemble une instruction pour trouver un flag dans la RAM. J'ai aucune idée de si ces machins sont viables, mais je m'attends pas à ce que tu puisses l'éviter. Si la table des fichiers est en cache en RAM t'auras pas trop le choix parce que la ROM sera probablement pas à jour tout le temps. Imagine que tu transfères un add-in et que le nouveaux fichier g1a est listé que dans la table en RAM jusqu'à ce que tu éteignes la calculatrice. Ça pourrait arriver ça.

Je veux seulement pouvoir y accéder en lecture donc si, je peux largement me passer de Fugue. Le jour où je fais de l'écriture, oui, il faudra que je trouve un moyen pour être compatible avec Fugue (ou simplement trouver le moyen de le forcer à se régénérer en RAM, si c'est possible).

Ah mais c'est pas la même affaire tout de suite, il fallait le dire avaaaaant. (Je sais même pas quel smiley mettre là, c'est te dire le désarroi.)

Ça permettrait de supporter et choisir entre plusieurs configurations du noyau et de le charger dynamiquement en RAM par "modules" au lieu de le charger complètement à chaque fois.

Euh, comme une lib statique donc ? gint ne contient que les drivers que ton add-in utilise et ce dès la compilation. Je vois moyennement l'intérêt de vouloir charger différents modules d'une fois sur l'autre si c'est le même add-in qui tourne.

De plus, si le BIOS/Gurb (je ne suis pas sûr du nom) devient assez élaborer, on peut imaginer pouvoir en faire une interface pour des transferts de fichiers et / ou un moyen de flasher des OS customs.

Et pourquoi mettre ça dans le bootloader au lieu de juste avoir une appli normale qui importe sa version du noyau ?

Il suffit d'être parano et de partir du principe que le code peut être exécuté par plusieurs entités en même temps et être interrompue en plein milieu d'une opération. Comme ça, ça force à sécuriser le code. Mais je suis surpris de voir à quel point c'est stable alors que je ne gère pas la DMA et les ETMU.

Le problème c'est que tu ne peux pas te permettre d'être interrompu en plein milieu d'une opération sur le DMA parce que (par exemple) l'écran attend les données. Il ne s'agit pas d'interrompre que le code mais aussi le matériel, ce qui change pas mal de trucs. Bon, pour les ETMU je pense que maintenant que j'ai trouvé le trick des écritures lentes ça ira mieux. Pour le DMA, j'attends de voir si ça te pose des problèmes. Et pour le TLB c'est pareil, en général quand tu exécutes ton code tu fais l'hypothèse qu'il est mappé, et changer ça est très chiant parce que si le code pour recharger le TLB est démappé... tu vois le truc. Mais t'as beaucoup plus de trucs en RAM que moi donc ça aide je suppose.
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 23/06/2020 13:09 | #


Donc autant je suis persuadé aussi qu'on peut faire plus vite que BFile, autant pour l'instant je suis pas du tout convaincu qu'on sait où est le bottleneck dans l'histoire.

Tu as raison pour le bottleneck mais il n'empêche que le code derrière les Bfile est horrible et il y a plein d'opérations répétées mille fois pour pas grand-chose, ce qui rend la RE du truc compliqué.

En plus si le problème était vraiment là tu pourrais utiliser directement Fugue avec des u8 classiques dans Vhex (avec utf8 derrière si l'envie t'en prend) et les performances seraient très bien, donc je suis presque sûr que tu as d'autres raisons de vouloir le contourner.

Oui j'ai plusieurs raisons de vouloir contourner le BFile(). Premièrement parce que ce n'est pas un FS "open source" donc d'un point de vue "morale" je ne suis pas super chaud d'utiliser ce truc sans l'avoir documenté un minimum. Secondement, Bfile utilise (pour certaines primitives telles que Bfile_WriteFile()) le DMA avec (possiblement) des callbacks et il me semble aussi qu'a chaque écriture dans la ROM, Casio flush le TLB (pour des raisons de synchronisation). Il faut donc, pour éviter tout problème avec Bfile restaurer TOUT l'environnement de Casio pour qu'ils puissent reprendre la main ; ce qui implique, par conséquent, un blocage complet du noyau le temps que la primitive se finisse correctement (blocage, qui pourrait être beaucoup moins important si j'ai des primitives customs).

Je vois pas de raison que ce soit fait autrement que r2=0x80machin et jsr @r2, et comme tu n'as pas encore dit explicitement le contraire (eg. r2=0x88machin et jmp @r2) ni publié d'extraits désassemblés je sais toujours pas. x_x

En fait je m'attendais tellement à ce que Casio utilise le syscall 0x01C8 flash read() (comme pour l'ancien FS) que je n'ai pas cherché à comprendre les différentes structures de données de Fuge. Je retracerai les primitives Bfile correctement une fois le driver USB sera fait (je m'explique plus bas).

Euh, comme une lib statique donc ? gint ne contient que les drivers que ton add-in utilise et ce dès la compilation. Je vois moyennement l'intérêt de vouloir charger différents modules d'une fois sur l'autre si c'est le même add-in qui tourne.
[...]
Et pourquoi mettre ça dans le bootloader au lieu de juste avoir une appli normale qui importe sa version du noyau ?

Le fait d'avoir un bootloader à part me permettrait de passer d'un noyau monolithique non modulaire à un noyau monolithique modulaire. Ça permet de faire beaucoup de choses mais voila en gros ce qu'il m'intéresse avec cette nouvelle architecture :
* le noyau sera directement compatible avec toutes les machines (il faudra juste choisir le bon bootloader pour la calto)
* le noyau pourra être entièrement en RAM (ce qui va permettre d'éviter des problèmes avec le démappage des pages de la TLB)
* ça permettra de choisir le module qu'on souhaite utiliser (donc les modules pourront être dev à part).
* ça permettra de charger uniquement les driver appropriés (donc les drivers pourront être dev à part).
* le noyau pourra être porté sur d'autres architectures hardwares (AVR, ARM, Z80, ...) sans trop de difficulté(?).
* les différentes parties (drivers, module, ...(?)) pourront être ajoutés / créer facilement car totalement indépendant du noyau.
* ça permettra d'isoler correctement toutes les parties du noyau comme ça si quelqu'un veut ajouter un driver, un module ou une lib il pourra le faire sans avoir à se taper toute le doc du noyau (qui n'existe pas d'ailleurs, malin <_< ).

D'ailleurs j'ai des news du projet.
Il y a quelques semaines j'ai commencé à refactor beaucoup de choses car l'architecture "visuel" du projet (dossiers, nom de fichier, ...) me plaisait pas. De plus, j'ai corrigé / amélioré certaines parties (notamment l'ordonnanceur, qui est presque prêt à être préemptif ) malheureusement, j'ai un problème de deadlock quelque part (probablement le TTY qui fait encore des siennes). Mais comme je compte refaire l'architecture "logique" du noyau pour passer à un kernel monolithique modulaire, je ne vais pas chercher à corriger les problèmes qui trainent car les modifications seront beaucoup trop importantes et risquent fortement de changer le fonctionnement de pas mal de chose.

J'aimerais avoir votre avis pour l'organisation du projet car finalement il y aura (au moins) 3 parties distinctes :
* le bootloader (basé uniquement sur les syscall de Casio pour fonctionner, ce qui assurera une portabilité à toute épreuve).
* le noyau (est-ce que je sépare les différents modules ? est-ce que je sépare les différents drivers ?)
* les librairies (glibc / newlib, bopti, topti, Revolution-FX, MonochromLib, ...)
Est-ce que je fais un repos avec tout dedans ? Est-ce que je fais 3 dépôts différents ? Est-ce qu'on peut faire des "groupe de dépôts" sur Gitea ? Est-ce que vous pensez qu'il serait préférable de passer sur une licence autre que CC0 (car je crois qu'elle n'est pas applicable à 100% en France(?))?
(@note: "est-ce que je sépare les différents [...]" -> est-ce que je fais un dépôt à part ?)

Actuellement je ne suis pas sur le projet, je fais une pause.
Je suis actuellement à la recherche d'info sur le module hardware USB car je pense en avoir besoin pour envoyer des logs de debug sur mon laptop (en implémentant la classe CDC/ADC)...et j'ai envie de m'amuser aussi

Mais c'est vraiment compliqué car le module semble ne pas correspondre a la doc du SH7724 (d'après mes tests) mais il est curieusement proche du SH7724 en matière d'adresse. Donc en ce moment, j'essaie de tracer les syscall Comm_*() pour avoir au moins le protocole d'initialisation / power-on du module mais c'est vraiment complexe car Casio initialise l'USB via un timer ainsi que les interruptions hardwares du module donc c'est tendu à réunir toutes les infos.

Ceci-dit ça avance, j'ai le protocole pour "allumer" le module USB, détecter quand un câble est branché et dire à l'hôte "Hey je suis un device USB :D". Mais je n'arrive pas à configurer la suite, les registres semblent différents et je suis bloqué dans mon gestionnaire d'interruption de l'USB (et je ne sais pas si c'est parce que je ne réponds pas à l'hôte ou si c'est parce que j'oublie d'effacer un flag). Bref je tâtonne mais ça avance un petit peu plus chaque jour

Pour ce qui est de la suite, je compte finir le driver USB et retourner sur le projet en attaquant avec la conception du bootloader (donc probablement après les "vacances")
Lephenixnoir Hors ligne Administrateur Points: 22771 Défis: 149 Message

Citer : Posté le 23/06/2020 21:14 | #


Secondement, Bfile utilise (pour certaines primitives telles que Bfile_WriteFile()) le DMA avec (possiblement) des callbacks et il me semble aussi qu'a chaque écriture dans la ROM, Casio flush le TLB (pour des raisons de synchronisation). Il faut donc, pour éviter tout problème avec Bfile restaurer TOUT l'environnement de Casio pour qu'ils puissent reprendre la main ; ce qui implique, par conséquent, un blocage complet du noyau le temps que la primitive se finisse correctement (blocage, qui pourrait être beaucoup moins important si j'ai des primitives customs).

C'est exact, il utilise bien le DMA et il flushe bien le TLB, ce que je peux d'ailleurs voir dans gintctl... avec les mêmes inconvénients que tu décris.

En fait je m'attendais tellement à ce que Casio utilise le syscall 0x01C8 flash read() (comme pour l'ancien FS)

Pourquoi il utiliserait ça quand on peut aller directement sur la ROM dans P2 ? Plus rapide ?

Le fait d'avoir un bootloader à part me permettrait de passer d'un noyau monolithique non modulaire à un noyau monolithique modulaire. Ça permet de faire beaucoup de choses mais voila en gros ce qu'il m'intéresse avec cette nouvelle architecture :
* le noyau sera directement compatible avec toutes les machines (il faudra juste choisir le bon bootloader pour la calto)
* le noyau pourra être entièrement en RAM (ce qui va permettre d'éviter des problèmes avec le démappage des pages de la TLB)
* ça permettra de choisir le module qu'on souhaite utiliser (donc les modules pourront être dev à part).
* ça permettra de charger uniquement les driver appropriés (donc les drivers pourront être dev à part).
* le noyau pourra être porté sur d'autres architectures hardwares (AVR, ARM, Z80, ...) sans trop de difficulté(?).
* les différentes parties (drivers, module, ...(?)) pourront être ajoutés / créer facilement car totalement indépendant du noyau.
* ça permettra d'isoler correctement toutes les parties du noyau comme ça si quelqu'un veut ajouter un driver, un module ou une lib il pourra le faire sans avoir à se taper toute le doc du noyau (qui n'existe pas d'ailleurs, malin <_< ).

Hmm en fait je crois qu'on n'est surtout pas d'accord sur la terminologie. Mais peu importe, l'idée est sensée donc y'a rien à ajouter.

Pour ton architecture, je pense qu'il est sensé d'avoir le bootloader et tous les modules dans le même dépôt même s'ils sont compilés indépendamment les uns des autres. Les autres trucs comme newlib t'auras pas le choix, newlib est un dépôt à elle toute seule.

Mais c'est vraiment compliqué car le module semble ne pas correspondre a la doc du SH7724 (d'après mes tests) mais il est curieusement proche du SH7724 en matière d'adresse.

Je pense qu'on a résolu cette question à l'oral tout à l'heure du coup !

(Si quelqu'un d'autre lit : on a décompilé des bouts de l'émulateur et trouvé les adresses et bitmasks des registres USB, et ça correspond totalement au SH7724.)

Ceci-dit ça avance, j'ai le protocole pour "allumer" le module USB, détecter quand un câble est branché et dire à l'hôte "Hey je suis un device USB :D". Mais je n'arrive pas à configurer la suite, les registres semblent différents et je suis bloqué dans mon gestionnaire d'interruption de l'USB (et je ne sais pas si c'est parce que je ne réponds pas à l'hôte ou si c'est parce que j'oublie d'effacer un flag). Bref je tâtonne mais ça avance un petit peu plus chaque jour

Excellent ! Je suis impatient d'en voir plus
Kikoodx Hors ligne Labélisateur Points: 2979 Défis: 11 Message

Citer : Posté le 15/03/2021 00:40 | #


Déterrage mérité !

J'ai relu la page du projet, en un an je suis devenu un peu moins ignare et je commence à comprendre ce qu'est Vhex.
C'est hyper impressionnant, ne dis pas que « ça n'intéresse personne », je peux te dire que je suis overhypé maintenant que j'ai compris ce que tes projets secrets impliquent. Je trouve ça plus passionnant que Windmill et C.Basic pour tout te dire, et je ne me suis rendu compte de l'ampleur de ton travail qu'aujourd'hui !

Si t'as des mises à jour à faire depuis le temps je veux ─ nous voulons ! ─ savoir ce qu'il se passe. Vraiment.
Et si tu ne le fais pas, je serais Vhexé. OK je sors me tapez pas.
mi lape ala.

J'suis un méga chômeur
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 15/03/2021 21:02 | #


Ho, je suis surpris de voir que le projet intéresse encore.

Sache que le projet est...en pause ? Du moins a bien changé depuis la dernière fois. Le gros problème du projet Vhex/GladOS s'est montré à l'arrivée de la Graph35+EII et la Graph90+E et quand j'ai voulu porter le projet sur ces machines, environ au même moment que le dernier message de Lephe ici. Puis mes études font que j'ai de moins en moins de temps à y consacrer aussi.

Note: pour rappel, Vhex est un kerne *nix-like qui avait pour but d'aider à la rétro-ingénierie de l'OS de Casio dans le but de porter GladOS sur les calculatrice recentes mais il n'a jamais respecté son rôle, c'est plutôt une deuxième version de GladOS qui, lui, se voulait être un OS qui devrait remplacer Casio de la machine. Partez du principe que GladOS et Vhex sont exactement le même projet.




<> Il y a deux raisons qui font que ce projet n'a pas pu (facilement) voir le jour. La première est simple, tu n'es pas sans savoir que le système de fichiers a changé sur les nouvelles calculatrices. Casio a changé son système de fichiers et utilise Fugue, un système de fichier VFAT12/VFAT16, que j'ai commencé à documenter depuis quelques mois. J'ai pas mal de chose dessus et j'arrive (théoriquement) à faire une liste des fichiers du root (pas encore de lecture des données, mais ça ne saurait tarder).

Malheureusement, une bonne partie du système de fichiers se trouve en RAM, hors ça pose énormément de problèmes avec GladOS parce que j'utilise l'entièreté de la RAM et j'écrase toutes les données qui s'y trouvent. J'ai fait quelque tentative d'écriture dans les données interne de Fugue pour renommer un fichier (le nom des fichiers se trouve en RAM la plupart du temps) et j'ai fait plusieurs fois l'erreur d'écraser des données visiblement très importantes. Ce qui m'a valu de reflasher l'OS de la machine sur la Graph35+EII et reset toute la mémoire de stockage via un menu de debug uniquement accessible sur la Graph90+E. Autant te dire que tu n'as pas envie d'écraser ces données.

Donc je ne peux pas m'installer comme je le faisais avant au risque de briquer les calculatrices (avant ça fonctionnait parce que l'entièreté du système de fichiers étais en ROM, donc ce qui restait dans la RAM étais moins importante (car générée au boot) le tout étant de ne jamais redonner la main à Casio une fois les données écrasées).

Tu me diras que je j'aurais pu utiliser Casio pour la gestion de fichier en faisant appel à Bfile, mais Casio utilise le DMA avec Fugue, ce qui implique de restaurer toute l'état de la machine juste pour lire un fichier ce qui est extremement lourd car on dois attendre que toute les operations soit finis avant de rechanger "d'OS" et ça me demande au passage d'etre capable de cohabiter avec Casio ce qui rend l'OS totallement dependant. Donc tant que je n'arriverai pas à effacer entièrement l'OS de Casio en ROM pour m'y installer *sans passer pas l'USB* pour implémenter mes propres carabistouilles, je n'ai aucun intérêt à continuer le développement de GladOS/Vhex.

Au-delà de ça, et c'est la deuxième raison du pourquoi le projet et en pause, la Graph90+E change pas mal de chose au niveau de l'écran et de quelque périphérique (RAM notamment), ce qui impliquait une refonte complète du noyau pour avoir une gestion des drivers propres + 2/3 bricoles pour gérer certains aspects spécifiques de la machine. C'est le problème qu'avait rencontré Lephenixnoir et qui a valu la v2 de Gint. Mais bon, il suffisait de bien penser l'architecture du projet en amont et cette partie aurait pu être résolus si j'avais vraiment eu envie de continuer le projet, ce qui fut le cas dans un premier temps.




<> Au début de m'a troisième année, donc trois mois après le dernier post de Lephe sur le topic, j'ai voulu trouver un projet qui allait m'occuper une bonne partie de l'année "scolaire" car les projets de mon école ne m'intéressent plus. J'ai donc proposé deux projets (que je dois rendre dans quelques jours d'ailleurs): La documentation de Fugue et un boot loader. Car à ce moment-là, je ne m'étais toujours pas rendu compte des dizaines de problèmes qui faisais que GladOS n'avait aucun intérêt à être créé / porté. Et dans ma tête je m'étais dit "Je documente Fugue, HOP je le dégage et PAF je développe le boot loader tranquillement pour charger GladOS sans problème. Trop malin le Yatis ! :D"

C'est seulement quand j'ai commencé sérieusement à me pencher sur le boot loader et que j'ai compris que Fugue ne pouvait pas être ignoré que je me suis rendu compte des problèmes que j'ai cités plus haut et c'est à ce moment-là où j'ai dû faire un choix: Continuer le noyau pour qu'ils puissent être en cohabitation avec Casio *ou* Mettre en pause le projet le temps de documenter Fugue et trouver un moyen d'écrire dans la ROM pour bypass les primitives de Bfile_* et ne plus être dependant de Casio.

Le truc, c'est que, plus je voulais développais Vhex, plus je refaisais ce que Gint faisait déjà a quelque exception près: Userland, appelle système, thread, loader ELF, ... et fallait que je me rende à l'évidence: c'étais contre-productif et je n'avais plus envie de faire ce genre projet. Je l'avais déjà évoqué mais ça fait quoi...3 ans que je fais tout le temps la même chose sans vraiment de résultat "visible" ? Je voulais aller de l'avant et donc j'ai commencé à regarder Gint et à m'amuser avec pour la conception du boot loader (comme je m'étais engagé a rendre un truc donc fallait que je rende un truc. À la base ça allait juste être un loader ELF alakon mais j'ai eu une autre idée, je vous en parle plus bas).

Il faut aussi prendre en compte que dans quelques mois (si tout son passe bien), je pars étudié en Corée pour 1 an et je n'aurais (probablement ?) pas de temps à consacrer pour des projets sur calculatrices. Donc je me suis dit à ce moment-là (en janvier): "le seul kernel qui a fonctionné parce qu'il est exceptionnellement bien foutu et stable, c'est Gint, donc autant le pousser a ses derniers retranchements, déjà pour faire peur à Lephe, mais aussi et surtout pour essayer de montrer peut-être des zones d'évolutions complètement abusées que pourraient avoir Gint si on imagine l'impossible". Et c'est ce que j'ai tenté de faire ces derniers mois (c'est pour ça que j'avais tenté de mettre en place les threads dans Gint).




<> Avant de vous expliquer ce que j'ai prototypé, il faut que je réponde à ta question, où en est Vhex ?

En troisième année à Epitech, commence ce qu'on appelle l'EIP. C'est un projet sur 3 ans qui nous permet de valider notre diplôme. Certaines personnes finissent avec une startup, avec une techno "révolutionnaire" comme Docker (oui, c'est un projet Epitech à la base). Pour ma part, j'ai voulu créer une console de jeux vidéo pour aider à l'apprentissage du bas-niveau, en utilisant GladOS pour l'OS et Vhex comme nom parce que c'est sur ce projet que j'ai pu apprendre / à comprendre énormément de chose...et ça a été accepté et j'ai pu monter une petite équipe de 4 personnes (on est 8 actuellement).

Parce que oui, le vrai but de GladOS a la base, c'étais de l'utilisé pour créer l'OS d'une console de jeux vidéo portable pour aider au développement bas-niveau (C/assembleur). Je n'en avais jamais parlé "ouvertement" (il me semble ?) parce que j'estimais que je n'avais pas les connaissances pour en parler publiquement, maintenant je pense avoir suffisamment confiance sur la viabilité / faisabilité du projet pour l'exposer en entier. Ça doit faire bien 5 ans que j'ai cette idée qui me trotte dans la tête.

Actuellement, je suis chef du projet, mais je vous avoue avoir beaucoup de mal, j'apprends sur le tas et l'équipe n'est pas encore stable (des personnes redoublent, d'autres arrêtent Epitech, d'autre reste, d'autres arrivent, ...) donc rien de concret n'a été commencé de ce côté. Je referai surement ce topic quand on aura quelque chose à montrer, pour l'instant, c'est encore trop tôt.

Mais du coup, ça change beaucoup de choses pour mes projets que j'ai proposé en plus pour validée une partie de mon année a EPitech. Comme nous n'avons pas de console pour avancer (il faut qu'a la conception), j'utilise la calculatrice Graph90+E pour prototyper des choses "visuel" dessus et j'utilise donc Gint pour m'éviter dev d'un noyau et aller vite.

Pour l'OS "final" de la console, j'aimerais avoir le même principe que sur la calculatrice: un menu qui regroupe des jeux et des utilitaires. J'aimerais aussi pouvoir développer des noyaux, des drivers et d'autre chose plus technique, transformant ainsi la machine en "sandbox pour prototyper des choses dangereusement intéressantes". J'aimerais que la console puisse faire tourner plusieurs jeux en parallèle et pouvoir passer de jeu en jeu via un bouton ou une combinaison de touches car ça reste une console de jeux avant d'être un outil de développement.

Le truc, c'est que, dans notre cas, ce ne sont pas véritablement des jeux qui tourneront en parallèle vu que j'aimerais que les développeurs aient accès à l'entièreté de la machine (s'ils veulent réimplémenter un kernel ou un driver, grand bien leur face), donc je ne peux pas simplement considérer les jeux comme de simple programme utilisateur, mais comme des OS à part entière, ce qui change pas mal de chose. Il y a une grosse différence entre un programme et un OS.

Il est possible de faire tourner des OS en simultané sur une même machine (les machines virtuelles le montrent bien), mais ça demande un organisme assez particulier: un hyperviseur. Je ne vais pas vous faire un cours si les hyperviseurs parce que j'en suis incapable, il faut juste comprendre que c'est un vieux concept qui permet de cloisonner des OS sur la machine (j'évite beaucoup de détail technique pour pas vous embêter avec). VMWare a donné l'appellation de "monde" pour les OS qui sont cloisonnés (c'est pour ça qu'on parle de "monde" ces derniers temps avec Lephe).




<> Pour en revenir sur les calculatrices, j'ai donc changé le sujet de mon projet de boot loader pour l'implémentation d'un "hyperviseur" (du type 1 pour les curieux. Ce qui est un choix...ma foi...fort merdique). Le but de base étais de charger deux addins avec leur monde (un utilisant Casio et l'autre utilisant Gint) et de pouvoir changer d'addin via une combinaison de touches. Ce prototype m'a permis de me rendre compte de la "faisabilité" de mes ambitions...et je n'avais pas vu trop haut, j'ai pu surmonter les grosses difficultés techniques, mais je n'ai pas finalisé le projet pour des raisons que je vais expliquer plus bas.

Laissez-moi d'abord vous faire une petite démo de ce que j'ai déjà implémenté parce que je pense que ça pourrait être intéressant et c'est un minimum visuel.



Comme vous pouvez le voir, on peut charger des images (qui sont en réalité des ELF compiler en PIE) qui utilisent deux environnements différents Gint et Casio. Lors du chargement de la deuxième image on peut voir relocalize symbols avec des noms bien connus, c'est parce que le programme de tests utilise Gint...comme une librairie dynamique ! Ce qui signifie que les jeux Gint...n'ont plus besoin d'avoir Gint avec eux pour fonctionner. Ce qui est une grosse évolution et ce qu'allège un peu la taille des programmes en mémoire (je n'ai pas de stats, bravo). Encore une fois, c'est Lephe qui a trouvé comment générer les libraires dynamiques (spoiler: passer par sh-elf-ld et non par sh-elf-gcc) donc un grand merci à lui !

Vers la fin, au moment où vous voyez des lignes d'assembleur, c'est mon deuxième projet: une librairie pour tracer des mondes ! Cela me permet d'exécuter pas à pas, instruction par instruction l'exécution du monde. C'est cet outil qui m’a permis d'éclaircir un plusieurs bugs lors du développement de l'hyperviseur (la convention d'appel pour les arguments variables avec le flag -mrenesas, qui n'est pas la même qui celui utilisé par Gint (qui utilise la convention de GCC), et aussi le fait qu'il y a visiblement une corruption de stack quelque part). C'est aussi un outil que j'utilise pour documenter Fugue, extrêmement pratique.

Du coup, pourquoi je dis que je n'ai pas finalisé le prototype ? Malheureusement, comme je l'ai évoqué, il semble qu'il y ait une corruption de stack quelque part, je n'ai pas eu le temps de l'identifier, mais la relocalisation fonctionne. C'est aussi parce que le projet n'est pas documenté et que je commençais à me perdre dans le code, car ça manipule beaucoup de concepts peu triviaux et que je me suis retrouvé à avoir une librairie de traçage ayant son propre monde ainsi qu'un driver qui ne doit pas être désinstaller par Gint...donc j'avais une version modifiée de Gint pour pouvoir tout mettre en place (c'est pour ça que je dis que l'hyperviseur du type 1 était une idée merdique), sans parler de l'hyperviseur en tant que tels...bref, ça commençait à être un plat de spaghettis donc j'ai arrêté ici.

Mais au moins, ça montre que c'est faisable et pas trop complexe à implémenter si on pose une architecture correcte du système avant et si on intègre l'hyperviseur dans Gint plutôt qu'a coté (ce qui est le cas ici, Gint n'as pas conscience qu'il est cloisonné. J'ai fait ce choix pour éviter de toucher Gint mais c'étais une grosse erreur de ma part parce qu'au final, j'ai du adapter le noyau, malin >_<).

Je vais donc essayer de pondre un document qui schématise et explique tous les concepts que j'ai tentés d'implémenter, dont Gint pourrait intégrer et comment je verrais leur implémentation. Aussi, j'attends de voir ce que va donner le driver USB (on va essayer de donner un bon coup de fouet avec Lephe et DS <3) pour voir à quel point on a besoin de modifier "l'arrière-boutique" du noyau parce que ni moi, ni Lephe a eu l'occasion d'implémenter un tel driver et on ne sait pas trop à quoi s'attendre.




Pour résumer:
<> Vhex est devenue mon sujet de fin d'études, c'est une console portable sandbox pour développer des jeux et des kernels.
<> La conception des différents OS que j'avais commencés (Vhex/GladOS) est arrêté le temps que je trouve un moyen de flasher la ROM sans passer par l'USB.
<> J'essaie de pousser Gint dans ses limites pour voir ce qu'il est possible de faire avec ou non, juste pour embêter Lephe.
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 10/07/2022 17:15 | #


Salut à tous !

Après plus d'un an de silence, je viens vous tenir au courant des avancées du projet, car je commence enfin à avoir des choses palpables et intéressantes à expliquer. J'ai mis à jour le topic afin de repartir sur une bonne base et de donner plus ample explication sur ce qu'est devenue le projet.

Bonne lecture !


[Newsletter] - Refonte du topic Vhex

Cela faisait un moment que je voulais reprendre le topic pour vous tenir au courant des avancées du projet, mais à chaque fois, j'étais découragé par la montagne de chose a expliqué. Il y a eu énormément de changement au cours de ces derniers mois et Vhex commence enfin à avoir un bon cap. Donc fatalement, j'ai beaucoup de choses à vous dire.

J'ai fait le choix d'un compromis. J'ai complètement refait le topic, mais je n'ai pas écrit toutes les parties techniques, ni même donné de quelconque information concernant le projet. Ce topic fait office de "hub" et j'écrirais les informations petit à petit. Ce qui me force à correctement fragmenter et structurer mes informations, a donné des nouvelles régulièrement et ça me laisse le temps de construire le topic petit à petit.

Je mets en place aussi un système de newsletter, qui tombera une fois par semaine le dimanche, où je vous donnerai des informations sur l'avancement du projet et ma planification.

J'espère que le projet intéressera des personnes, j'ai pas mal de choses qui devraient vous intéresser dans les mois qui arrivent.

A+
Yatis Hors ligne Membre Points: 575 Défis: 0 Message

Citer : Posté le 17/07/2022 22:08 | # | Fichier joint


[NewsLetter] - I. Introduction au projet

Ce chapitre ne contiendra pas encore de notes techniques à propos du projet, mais sera en partie une synthèse de mes expériences, mes réflexions et mes échecs que j'ai traversés au cours de la réalisation du projet.


I.1 Historique du projet

Le projet Vhex date de 2018-2019. Au cours de ces trois dernières années, le projet a pris plein de forme différente.

À la base, c'était un outil de rétro-ingénierie dont j'avais besoin pour m'aider dans la documentation du clavier afin de pouvoir continuer GladOS qui est, à mes yeux, l'ancêtre de Vhex. Le projet était vraiment simpliste à l'époque et fonctionnait plutôt bien.

J'ai par la suite découvert le module UBC qui m'a offert un moyen d'écrire un programme me permettant de suivre l'exécution de l'OS de Casio instruction par instruction. Voyant le potentiel du truc que j'avais entre les mains, je me suis empressé de foncer tête baissé pour faire la deuxième version de mon outil... et c'est là que le bât blesse. Et ce n'est que bien plus tard, en lisant "The mythical man mounth" que j'ai compris mon erreur :

Frederick P. Brooks - The Second-System Effect a écrit :

[...]La tendance générale est de sur-concevoir le deuxième système, en utilisant toutes les idées et fioritures qui ont été prudemment détournées sur le premier. Le résultat, comme le dit Ovide, est un "gros tas". [...]


Il faut savoir qu'avant de reprendre Vhex pour faire la 2.0 du projet, j'avais beaucoup avancé sur GladOS en parallèle, mais j'avais mis fin au projet à la suite de beaucoup de problèmes avec le code de ce dernier et à cause de la frustration. Cependant, GladOS m'avait donné énormément de connaissance pour faire des choses extrêmement techniques. J'ai tenté de mettre toutes ces connaissances dans la deuxième version de l'outil.

Après plusieurs semaines de travail, je me suis rendu compte que cette nouvelle version de Vhex...était exactement ce que j'avais déjà fait avec GladOS sauf que cette fois-ci, j'avais réussi à aller un peu plus loin techniquement. Toutefois, le projet (qui était sur ce topic), est tombé à l'eau pour les mêmes raisons que GladOS : j'ai visé trop gros d'un coup et sans vraiment me focaliser sur le but précis du projet. J'avais fini par me retrouver avec des threads, des processus, un ordonnanceur, un début de tests avec des librairies dynamiques, ... ce qui n'était réellement pas nécessaire pour le projet qui est, de base, un désassembleur et non un OS. En conclusion, je me suis retrouvé à nouveau perdu dans mon code et sur des problèmes extrêmement fourbes très proches de ceux que j'avais rencontrés avec GladOS. Sauf que cette fois-ci, le profond sentiment d'avoir perdu mon temps a été très dur à encaisser : j'avais passé plusieurs années (2018 - début 2020) à réécrire le même code, les mêmes lignes pour contrôler la machine, les mêmes logiques, pratiquement la même architecture, ... tout ça sans jamais avoir de résultat visuel et sans jamais réutiliser le code que j'avais precedement fait. J'ai donc simplement abandonné le projet une nouvelle fois, me jurant de passer à autre chose.

Pratiquement 6 mois passèrent sans que je ne touche au projet. On arrive en septembre 2020 et j'avais completement mis de côté le développement sur calculatrices. Je suis resté un peu sur la scène "reverse/documentation", car ce domaine m'intéresse beaucoup, sans rien de vraiment probant.

Cependant, fin 2020, mon école où j'étais à ce moment-là, Epitech, me demande de choisir un sujet de fin d'études sur 2 ans. Dans un premier temps, je rejoins un projet complètement nul (coucou à @Django et @Moule s'ils passent par là) qu'on a appelé Payou : c'était une copie d'Yuka...mais c'était par Yuka. J'ai curieusement quitté le projet rapidement et ai formé, avec tous les étudiants qui n'avaient pas encore trouvé de groupe (dont une quasi-totalité qui on soit disparu, soit redoublé, soit quittés l'école) et j'ai décidé de reprendre Vhex, car j'avais une partie du travail de fait dans un coin et plein de bout de code qui trainait. L'objectif était donc de me la couler douce et de finir le projet en 2 mois au lieu de 2 ans.

Bien sur, ce fus encore une fois un echec, car je devais montré une preuve de concept du projet a toute la promotion, et ce quelque semaine apres la formation officiel du groupe. Et comme je l'ai evoqué plus tot, concevoir un kernel...c'est extremement frustrant au debut, car nous avons aucun resultat visible, ou alors ils sont extremement ridicule. Et surtout, ce n'était pas l'objectif de faire quelque chose de technique, le but était plutôt de nous inciter à faire "une pseudo-startup" et la grille de notation porte en grande majorité sur la stratégie commerciale, le marketing, la communication, les mises en place de CI, ...

Donc, je me suis mis en tête de développer tout le projet avant la présentation du projet..... Ce qui est une erreur absolue, car ce n'etais pas ce qui était demandé, mais j'ai une fois de plus foncé tête baissée sans prendre le temps de réfléchir. J'ai donc redéveloppé en partant zéro, et pour la millième fois de suite, un kernel qui faisait exactement la même chose que Vhex et GladOS, mais cette fois-ci, j'ai échoué bien plus tôt que prévu, car c'était la première fois que je développais sur la Graph90+E, ce qui m'a encore plus affecté psychologiquement, mais c'était trop tard, j'avais signé pour 2 ans.

J'ai complètement délaissé le projet après ça pendant facilement 6 mois, aucune des personnes présentes dans le groupe n'avait envie de faire quoi que ce soit. En même temps, ils n'avaient aucune idée de ce qu'était le projet. J'avais commencé à faire des trucs, mais sans vraiment d'envie, dans mon coin et uniquement parce qu'on devait rendre des choses a Epitech.

Et ça a duré jusqu'à l'arrivée de plusieurs nouvelles personnes dans le projet, beaucoup plus structuré et beaucoup plus sérieux que les précédant, car une année était passée et les enjeux étaient tout de suite plus importants à leurs yeux : la validation du diplôme. Pour ma part, j'avais compris que les diplômes ne servent absolument à rien (surtout celui d'Epitech) et que seules les compétences primes dans le monde professionnel (et l'avenir me donnera raison à de nombreuses reprises). Ceci-dit, on a commencé à reposer les documents correctement, à redéfinir une ligne directrice pour le projet et restructurer le groupe en interne. Toutefois, je n'avais toujours pas spécialement envie de faire le projet. Je le faisais davantage pour ne pas planter les autres.

Cette situation a durée jusqu'en septembre 2021. A ce moment la, je deviens assistant pedagogique dans une ecole de cyber-securité a Paris, l'ecole 2600, ou j'ai aidé a la construction des moulinettes et de l'infra. Comme a Epitech, les etudiants on une "piscine" en debut d'année : deux semaines ultra intenssif sur de l'assembleur et du C tres techniques (vraiment). A savoir que la piscine c'est passé dans une base de loisir autour d'un lac et que ces deux semaine ce terminais par un event "special".

Cet évent a commencé avec de la musique et a mangé. À 22h30 la musique se coupe et on demande à tout le monde de regrouper (assistant et prof compris) : 4 personnes armées sont arrivés sur les lieux et nous ont dit qu'on avait 15 minutes pour faire nos sacs afin de tenir toute la nuit. On apprit plus tard que ces personnes étaient en fais des membres du GIGN. Le but de l'évent était simple : on est divisé en 4 groupes et on devait soulever un brancard avec une personne du groupe dedans et suivre la silouhette d'un des membres du GIGN : s'il passait par-dessus un mur, on devait faire passer le brancard par-dessus le mur. Si on nous disait d'aller dans le lac, on allait dans l'eau (habillé) et le brancard ne doit pas être mouillé, sinon on se faisait tout simplement détruire avec plein d'exercice physique. Pour faire simple : ou que le guide passe, le brancard passe. Et ce, de 22h45 à 7h du matin.

Cette nuit-là, j'ai abandonné vers 6h de matin. Mes échecs depuis ces dernières années me sont revenues en boucle cette nuit et je me suis juste rendu compte que j'étais détruit psychologiquement, perdu et sans objectif. Le lendemain, j'ai décidé de me prendre deux semaines de vacances pour méditer et prendre une décision.

Après cette courte pause, Je me suis totalement repris en main en me fixant des objectifs (que je garde perso pour le coup), je me suis mis à faire des plannings, des listes, des indicateurs, à poser sur papier mes idées de projets, mes envies, ... je voulais absolument avoir une vision sur l'entièreté de ma vie. Et pour gagner en auto-discipline, je me suis interdit de manger le matin jusqu'à la fin de l'année scolaire en cours (~10 mois). Chose que j'ai complètement tenue sans broncher une seule seconde.

Quelques mois plus tard, début 2022, je reprends Vhex de zéro une dernière fois. J'ai reposé les objectifs du projet, fragmenté toutes les étapes en toute petite tache et j'avance petit pas par petit pas avec une vision complète sur le projet sans jamais m'éloigné de mon objectif initial. Si j'ai une idée, je la note quelque part et je l'intègrerai le moment venu. Je rattrape et dépasse toutes mes espérances en quelques semaines. J'ai aussi quitté officiellement (depuis quelques mois maintenant) Epitech, mais je continue le projet comme si ne rien etait, car il est hors de question que je laisse tomber les personnes qui dépendent de ce projet dont je suis le seul à pouvoir faire avancer. Puis je compte bien rattacher Vhex à mon sujet de fin d'études à l'école 2600 (oui, je suis devenue étudiant entre temps).

Je commence vraiment à être extrêmement serein sur l'avancement du projet et c'est pourquoi j'ai décidé de reprendre le topic.



I.2 Le pitch originel du projet

Le pitch de base de mon sujet de fin d'études était "Création d'une console portable pour apprendre à programmer". Et ce qui va suivre et tiré d'un d'un des documents que j'avais écrit pour justifier le projet.

Vhex - document de spec 2019 a écrit :

Il y a peu de solutions qui permettent de visualiser clairement les effets d’un code à bas-niveau et sont souvent trop complexes à aborder et peu fun pour un néophyte. L'une des solutions les plus connues (il me semble) reste Arduino qui est grandement utilisé dans les filiales "techniques" comme la STI2D.



Si je prends l’exemple d’Arduino, comme montre le schéma au-dessus, la ligne directrice "éducative" consiste généralement à comprendre deux notions pratiquement en simultané : l’électronique et l’informatique bas-niveau. Tout ça avant même de pouvoir s’amuser avec leur produit, car généralement la première fois qu'on touche à cette machine, on arrive, après plusieurs heures de cours, à enfin faire clignoter la LED orange de la carte. Ce qui n'est vraiment pas engageant pour les néophytes.

Vous vous doutez bien que seule une faible minorité de personnes arrive à la dernière étape, car on a trop peu de résultats concrets rapidement. Et en plus, de ça, Arduino tente de cacher la partie "technique" avec des abstractions, un IDE et un langage proche du C++. Tout cela permet donc à Arduino de contourner la complexité d’apprentissage de certaines thématiques dont l'une qui est, à mes yeux, primordial : comprendre le fonctionnement de la machine.



Ce n’est pas ma vision, et comme l’illustre le schéma au-dessus, j'aimerais d’abord que les utilisateurs, aussi néophyte soit-il, puissent, dès la sortie de la boîte, s’amuser sur la machine. Puis, par la suite, laisser leurs curiosités prendre le dessus pour comprendre le fonctionnement des jeux, puis potentiellement de la machine. Ils pourront avancer à leur rythme tout en faisant des choses concrètes visuellement et rapidement.




I.3 Compromis

Comme je l'ai évoqué approximativement un peu plus haut, le but de Vhex est de fournir une console portable sur laquelle les utilisateurs peuvent jouer et développer. Je vise dans un premier temps les utilisateurs complètement néophytes, mais aussi les utilisateurs très expérimentés.

Pour faire simple, j'aimerais pouvoir développer un jeu sans avoir m'occuper de comment contrôler la machine et aussi pouvoir prototyper mes propres noyaux sans risque de casser la machine.

Toujours tiré du même document, voilà comment j'imaginais Vhex au début du projet:

Vhex - document de spec 2019 a écrit :




Maintenant, je vais vous expliquer la réalité du projet. Créer une console portable implique de concevoir toute la partie "hardware", sauf que je n'ai pas encore les connaissances nécessaires pour y parvenir. Je devais partir en Corée en 2021 pour ça, mais le Covid modulo mon envie de tout plaquer ont fait que je n'y suis pas allé. J'ai donc dû trouver une alternative à la console et j'ai choisi la Graph90+E, car l'écran est en couleur et je visais plus ou moins mes performances matérielles dans l'idée et je saivais deja programmer dessus. Cependant, je garde en tête que ce médium est temporaire et je compte bien acquérir les connaissances qui me manquent pour concevoir ma propre console, mais chaque chose en son temps.

De plus, il y avait de plus d'en plus de "mini-projet" dont Vhex était dépendant, c'est pourquoi Vhex est bien devenue un regroupement de projet comme cité sur la page principale de ce topic. Je rentrerai en détail sur chaque projet dans les prochains chapitre.

I.3.1 : Pourquoi la G90 ?

L'objectif sur la graph90+E est relativement simple. J'aimerais avoir un noyau qui permet de lancer des applications en parallèle via une interface graphique comme le menu de Casio et de pouvoir "switcher" entre les jeux comme un alt tab sous Windows.

À noter que, secrètement, je voulais créer Vhex (avec la console) comme une sorte "sandbox" pour la conception de noyaux et le prototypage de drivers. C'est pourquoi les "applications" sont considérés comme étant des kernels et non comme des "applications utilisateur". Ce qui signifie que le mécanisme de "switch" entre les applications est fait via réaliser par hyperviseur directement intégré à Vhex.

Aussi, l'entièreté des applications est directement chargée en RAM, je n'ai pas de gestion de mémoire virtuel (du moins pour la graph90+E et aussi pour beaucoup de raison technique).

I.3.2 : Quid de la partie Web ?

Je ne m'occupe pas de la partie Web pour l'instant. Même si j'ai quitté Epitech, quelque personne se charge de créer le site communautaire de Vhex, mais je n'ai aucune vision sur ce qu'ils ont fait jusqu'à présent.

Pour la petite histoire, à Epitech, vers fin 2020, on doit pitcher nos projets à toute la promo, et il me semble qu'on avait même fini premier dans une des catégories d'ailleurs. Lors de notre premier rendu quelques semaines plus tard (on doit rendre des choses tous les mois pratiquement, pour vérifier qu'on avance bien), la personne qui évaluait le rendu nous a clairement dit "ah, mais moi j'y connais rien en électronique, donc toute cette partie ne pourra pas être notée. Et la partie kernel non plus d'ailleurs. Et là, je ne peux pas vous mettre des points parce que vous n'avais pas fait de CI sur Github, ni de tests unitaires...". Bref, ce sont des incapables et cette école reste un des plus gros scams connus à ce jour. Et c'est à ce moment-là que j'ai tordu le projet pour y glisser un site web et j'y mis quasiment toute l'équipe sur sa création.

Donc ce n'est vraiment pas d'actualité pour l'instant.



I.4 : Resumé

Vhex est un regroupement de projets, comme listé sur la page principale du projet, mais a pour but, sur le long terme, d'être une console portable permettant d'apprendre à programmer.

Pour l'instant, je ne peux me concentrer uniquement sur la conception du noyau, et ce, sur la graph90+E, car je n'ai pas encore les compétences requises pour me lancer dans la conception d'une carte mère.
1, 2 Suivante

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 44 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd