Publié le 26 Septembre 2013

Rédigé par keru

Repost0

Publié le 26 Septembre 2013

Repost0

Publié le 26 Septembre 2013

Rédigé par keru

Repost0

Publié le 25 Septembre 2013

Rédigé par keru

Repost0

Publié le 19 Septembre 2013

Cet article est reposté depuis une source devenue inaccessible.

Voir les commentaires

Rédigé par r00t_me

Publié dans #Lego, #Arduino, #microscope

Repost0

Publié le 17 Septembre 2013

Rédigé par keru

Repost0

Publié le 8 Septembre 2013

Avant de continuer sur le kernel, on est bien obligé de parler de matériel puisqu'un des rôles d'un kernel est de causer avec le matos.

Pour cet article, on parlera des interruptions.

Une interruptions porte bien bien son nom, pour les interruptions matérielles c'est une façon pour les périphérique de se signaler au CPU (et donc indirectement au kernel) pour lui dire qu'il s'est passé quelque chose.

Ça ressemble à quelque chose du genre :

  • clavier : Ho merde merde merde putain ! CPU ! Arrête tout !
  • CPU (qui arrête ce qu'il faisait) : huh ? quoi ? y'a le feu ?
  • clavier : Quelqu'un a appuyé sur une de mes touches !!!!!!!!!!!!!!!!!
  • CPU : Wow ! Dingue ... C'est bon j'ai prévenu le kernel, retourne dormir.
  • clavier : kthxbye!

Bon, c'est pas tout a fait exactement comme ca, mais pas loin. ;)

Il y a 3 grands type d'interruptions :

  • Les exceptions : qui permet au CPU de se signaler au kernel (ex : division par zero)
  • Les interruptions materielles (IRQ) : qui permet au matériel de se signaler au CPU (ex: clavier)
  • Les interruptions logicielles : qui permet au logiciel de se signaler au kernel (ex : un appel système)

Les interruptions logicielles, c'est pas pour maintenant. J'ai présenté au dernier article la méthode principale du kernel (start), mais pour l'instant il n'a encore rien fait. (et je ne présente pas les interruptions maintenant pour rien, puisque cela va être une des premières chose dont il va devoir s'occuper pour démarrer)

Manière que le matériel ne soit pas connecté directement au CPU, parce que ca serait vraiment moche, il existe un controlleur qui s'appelle le PIC (Programmable Interrupt Controller). Sur nos PC modernes c'est l'APIC (pour Advanced) mais il est capable de fonctionner comme un PIC et Cosmos ne gère par encore l'APIC, et puis c'est plus compliqué à comprendre.

Le role du PIC est de gérer les interruptions matérielle pour le CPU.

Le clavier envoi une impulsion électrique au PIC, le pic transforme ça en quelque chose que le CPU comprend, interromps le CPU, envoie le message au CPU qui fera passer ca au kernel qui fera ce qu'il veut avec, le kernel dit au cpu qu'il a fini qui dit au PIC qu'il a fini. Pendant ce temps il ne peut rien se passer d'autre, il faut donc que cela aille très vite.

Sur les plus anciennes architectures IBM PC et PC/XT il y a un seul PIC (le 8259).

Sur les PC/AT il y en a 2 qui sont chaînés.

Chaque PIC 8259 a 8 entrées qui peuvent être connectés à 8 périphériques.

Avec 2 PIC ca fait 15 périphériques et non 16 car une entrée sert au chaînage des 2 PICs. Le premier PIC est appelé "maître" et le 2ème "esclave".

Chaque entrée est numérotée et on dit généralement : IRQ0 pour la première entrée, IRQ1 pour la 2ème, etc jusqu’à IRQ15. Ceux qui ont fait du DOS doivent se souvenir :)

Le standard ISA (wow, ca date) definit les réservations IRQ suivantes :

  • IRQ 0 : Programmable Interval Timer (le PIT, un oscillateur avec des diviseurs et autres joyeuseté)
  • IRQ 1 : Clavier
  • IRQ 2 : Cascade (pour le chainage des 2 PIC)
  • IRQ 3 : COM 2 (port série 2)
  • IRQ 4 : COM 1 (port série 1)
  • IRQ 5 : LTP 2 (port parallèle 2)
  • IRQ 6 : Lecteur de disquette
  • IRQ 7 : LPT 1 (port parallèle 1)
  • IRQ 8 : Horloge CMOS
  • IRQ 9, 10, 11 : libre
  • IRQ 12 : Souris
  • IRQ 13 : FPU/Coprocesseur/Inter-processeur
  • IRQ 14 : ATA 1 (Disque dur 1)
  • IRQ 15 : ATA 2 (Disque dur 2)

Les IRQ 0 à 7 sont gerées par le 1er PIC, les IRQ 8 à 15 par le 2ème.

Quand le 2ème pic recoit une interruption il appelle l'IRQ 2 (du premier PIC pour qu'on s'occupe de lui. Car le 2ème PIC ne peut pas interrompre le CPU directement il faut que le 1er le fasse a sa place)

Sans aller jusqu'à une démonstration d'assembleur x86, il faut quand même en parler un tout petit peu. Les cpu intel ont une instruction OUT et des "ports". Sans rentrer dans les details :

  • pour causer au PIC master il faut utiliser les ports 20h et 21h,
  • Et pour le PIC slave c'est A0 et A1h.

Quand le CPU est interrompu par une interruption(!) materielle, il doit savoir quoi en faire. Pour cela il y a l'interrupt vector table (je sais pas comment traduire ça en français). Cette table peut contenir l'instruction a exécuter, mais en général elle contient plutôt l'instruction "JMP adresse" qui dit au cpu que la fonction a exécuter est ailleurs (comprendre : une fonction du kernel).

La joyeuseté est qu'il y a eu un gros foirage (merci IBM) et que la table pour les interruption matérielle et la table pour les exceptions CPU se marchent dessus. Heureusement on peut redéfinir l'endroit ou se trouve la table pour gérer les interruptions matérielle. C'est une des premières chose que fera le Kernel COSMOS. Il s'occupera par la même occasion des "masques" d'interruptions qui sert a dire au PIC d'ignorer certaines interruptions matérielles. (par ex : ignorer les IRQ 7)

Pour resumer :

  1. Un peripherique envoi une impulsion au PIC
  2. Le PIC recoit une impulsion sur une de ses lignes
  3. Le PIC set un bit en interne pour se souvenir qu'une interruption est demandée
  4. Le PIC vérifie si l'interruption n'est pas masquée
  5. Le PIC vérifie si cette interruption n'est pas déjà en cours de traitement par le CPU.
  6. si 4 et 5 sont ok, le PIC interromps le CPU
  7. Quand le CPU est interrompu, il interroge les 2 PICs (via les ports dont on a parlé plus haut) pour savoir lequel est responsable (les 2 sont chainés et seul le master peu interrompre le CPU)
  8. Le PIC responsable repond en indiquant l'adresse de l'interrupt vector table qui contient l'instruction a executer par le CPU (donc en general, un JMP)
  9. En regle general la fonction qui est appelé par le CPU (on est dans le kernel là) interroge le peripherique qui a demandé une interruption (par exemple si c'est l'IRQ 1, il demande au clavier quelle touche est pressée)
  10. Quand le kernel a fini de gerer l'interruption il previent le PIC que la gestion de cette instruction est terminée.
  11. Tout le monde reprend une activité normale jusqu'a la prochaine exception

Pour les exceptions : C'est le CPU qui s'interromps lui même, il regarde dans la table (fournie par le kernel) ce qu'il doit executer quand, par exemple, on tente de lui faire faire une division par zero.

Pour le prochain article, j'approfondirai ça, où bien j'indiquerai comment le kernel Cosmos gere ce joyeux bazar.

Voir les commentaires

Rédigé par keru

Repost0

Publié le 7 Septembre 2013

Quand le PC démarre :

  1. le BIOS fait sa sauce
  2. puis passe la main au bootloader qui fait sa sauce
  3. puis appelle un point d'entrée pour passer la main au système d'exploitation.

Cosmos commence au point d'entrée appelé par le bootloader.

Soit "Kernel_Start", ce qui, coté C# est : Cosmos.System.Kernel.Start()

Cosmos.System.Kernel est une classe abstraite car une partie de la classe est laissée a l'initiative de l'utilisateur du userkit.

Seules les fonctions Start(), Stop() et PrintDebug() sont implémentées.

BeforeRun(), Run() et AfterRun() sont a implémenter par le userkit, sachant que BeforeRun() et AfterRun() sont virtual, seul Run() est (obligatoirement) à implémenter par le userkit.

BeforeRun() et AfterRun() par défaut ne font rien.

Start() effectue (dans les grandes lignes et hors debug) les taches suivantes :

  1. Hardware.Bootstrap.Init();
  2. Global.Init();
  3. BeforeRun(); (soit rien par defaut)
  4. while (!mStopped) { Network.NetworkStack.Update(); Run(); }
  5. AfterRun(); (soit rien par défaut)

La méthode Stop() se contentant de set mStopped à true pour arrêter la boucle.

Start() hormis quelques messages de debug ne fait que ça.

On ne peut pas dire que ça soit compliqué.

Si dessous en lien le diagramme de séquence du point d'entrée du kernel (hors debug)

Voir les commentaires

Rédigé par keru

Repost0

Publié le 7 Septembre 2013

J'ai commencé à participer au projet Cosmos, parce que c'est trop fou furieux pour que je passe à coté.

Le projet est composé de 3 grandes partie :

  1. Le système de build/compilation. Parce que le compilo C# génère de l'IL et le CPU ne comprend pas l'IL. Alors il y a un truc que je ne veux même pas chercher à comprendre qui génère du code Intel a partir du code IL.
  2. La partie kernel, du moins un bout de kernel, c'est en fait une librairie qui va du bootstrap jusqu'aux driver. La boucle principale est laissée aux bons soins du user kit.
  3. Le userkit permet a un utilisateur qui veut créer son propre système d'exploitation en utilisant les libs (point 2) et outils (point 1).

C'est la partie 2 qui m’intéresse, le kernel. J'écrirai de la doc a ce sujet, dans le code du projet, et sur ce blog. Un kernel simple n'est pas si compliqué que ca. Par contre l'architecture PC hérite de foirages particulièrement velus.

PS : Le projet utilise Syslinux comme bootloader, on s'épargne donc un bout de l’héritage "velu" de l'architecture PC. Mais juste un bout :)

Voir les commentaires

Rédigé par keru

Repost0

Publié le 3 Septembre 2013

Rédigé par keru

Repost0