< Réaliser un secteur de boot qui passe en mode protégé | TutoOS | Un noyau en C qui recharge la GDT >
Le package contenant toutes les sources est téléchargeable ici : bootsect_kernelC.tgz.
Pour naviguer dans l'arborescence : BootSector_kernelC
La programmation en C offre par rapport à l'assembleur des avantages incontournables :
Il est possible d'utiliser à peu prèt n'importe quel langage compilé pour écrire le code d'un noyau et chacun choisira le langage avec lequel il se sent le plus à l'aise (Pascal, C++...), la seule contrainte étant que ce langage doit permettre d'insérer des routines en assembleur et de manipuler directement les adresses en mémoire.
Le fichier screen.c contient des fonctions permettant d'afficher des caractères à l'écran :
kX
et kY
stockent en mémoire l'emplacement du curseur a l'écran. La variable kattr
contient les attributs vidéo des caractères affichés.
scrollup()
prend en argument un entier n et scrolle l'écran de n lignes.
putcar()
affiche un caractère à l'écran
print()
affiche une chaîne de caractères
Notez que certains types ont été définis dans le fichier types.h
:
Le code du noyau ci-dessous fait appel aux fonctions d'affichage définies ci-dessus. Cet exemple est assez intéressant car il montre comment un programme en assembleur fait appel à une fonction écrite en C (ce sujet est développé dans l'annexe sur la compilation séparée en assembleur sous Unix) :
Par rapport aux précédents noyau, on note surtout :
ORG
, qui sert au calcul des adresses en fonction de l'endroit où le code est relogé. Ce calcul est maintenant réalisé par le linker ld
.
_start
, indispensable à ld
.
$ gcc -c screen.c $ nasm -f elf -o kernel.o kernel.asm $ ld --oformat binary -Ttext 1000 kernel.o screen.o -o kernel
L'option -Ttext
indique l'addresse linéaire à partir de laquelle le code commence. Par défaut, ld
suppose que le code commence à l'adresse 0x0
. Ici, ce paramètre est indispensable car le code du noyau est recopié par le secteur de boot en 0x1000
. La même fonctionnalité était implémentée par la directive [ORG 0x1000]
dans les noyaux précédent en assembleur.
L'option -Tdata
, qui sert à indiquer l'offset de début de la section de données, n'est pas utilisée. Par défaut, le linker considère que la zone de données suit la zone de texte (on remarque qu'elle est relogée une page mémoire plus loin).
Le code du noyau en C reprend de façon fidèle le code exprimé plus haut en assembleur.
$ gcc -c screen.c $ gcc -c kernel.c $ ld --oformat binary -Ttext 1000 kernel.o screen.o -o kernel
< Réaliser un secteur de boot qui passe en mode protégé | TutoOS | Un noyau en C qui recharge la GDT >