< Réaliser un secteur de boot qui affiche un message | TutoOS | Réaliser un secteur de boot qui passe en mode protégé >
Le package contenant les sources est téléchargeable ici : bootsect.tgz.
Pour naviguer dans l'arborescence : BootSector
La partie précedente explique par l'exemple les principes de fonctionnement d'un programme de boot. Dans cette partie, nous allons voir un programme de boot plus raffiné qui, après avoir affiché un message, charge en mémoire un noyau très rudimentaire et lui passe la main. Là encore, nous allons faire au plus simple et le noyau se contentera seulement d'afficher un message.
Ce programme ressemble beaucoup à celui du chapitre précédent. En fait, c'est le même avec juste quelques lignes de code en plus qui copient une partie de la disquette, contenant le noyau, en mémoire :
Le programme commence par un saut à l'adresse start
. La directive include
ajoute au code du noyau le contenu du fichier UTIL.INC
qui contient le code de la fonction afficher
vue précedement.
Cette instruction met dans une variable un nombre servant à identifier le périphérique de boot (ici le lecteur de disquettes). Cette variable sera réutilisée plus tard pour indiquer à partir de quel périphérique doit être chargé le noyau.
Le bout de code ci-dessus charge le noyau en mémoire en faisant appel à l'interruption 0x13 du BIOS qui permet de copier un ou plusieurs secteurs d'une disquette en mémoire. Dans notre cas, le noyau se situe au début du second secteur de la disquette et le programme recopie ce secteur à l'adresse 0x1000
en RAM. Notez que le choix de cette adresse est arbitraire et on aurait très bien pu choisir une autre valeur.
L'adresse physique 0x1000
est adressée ici en mettant le sélecteur à 0x0100
. Mais on aurait très bien pu procéder autrement, en utilisant un sélecteur à 0
et un offset de 0x1000
, ça aurait aussi fonctionné !
La variable KSIZE
définit le nombre de secteurs à charger pour que tout le noyau soit bien recopié en mémoire. Ce premier noyau, qui est décrit dans la partie suivante, est très court (pas plus de 100 octets). On peut donc se contenter de mettre la valeur de KSIZE
à 1 pour copier un seul secteur.
Ensuite, une instruction de saut donne la main au code du noyau.
Programmer un secteur de boot et un noyau, cela signifie entre autres organiser l'occupation en mémoire des différents composants. Pour ne pas vous y perdre, je vous conseille d'utiliser des petits schémas. Les 5 minutes passées à crayonner sur un bout de papier vous ferons parfois économiser des heures de débogage ! Dans notre cas, la mémoire est occupée de la façon suivante après le chargement du noyau :
Voici le programme du noyau :
Ce programme initialise le registre de code et les registres de données afin qu'ils pointent sur la bonne zone mémoire, en 0x1000
. Ensuite, un message est affiché pour attester de la réussite des opérations. A la ligne suivante, le noyau ne fait vraiment pas grand chose : il boucle indéfiniment.
Le package contenant les sources est téléchargeable ici : bootsect.tgz.
Le code se décompose en :
UTIL.INC
, qui contient la fonction afficher
$ ls UTIL.INC bootsect.asm kernel.asm
On compile le boot loader et le noyau séparement :
$ nasm -f bin -o bootsect bootsect.asm $ nasm -f bin -o kernel kernel.asm
On remarque que le binaire du secteur de boot fait comme prévu 512 octets :
$ ls -l total 14 -rw-r--r-- 1 am users 492 Jan 17 17:20 UTIL.INC -rw-r--r-- 1 am users 512 Jan 19 18:16 bootsect -rw-r--r-- 1 am users 715 Jan 17 17:22 bootsect.asm -rw-r--r-- 1 am users 297 Jan 17 17:50 kernel.asm -rw-r--r-- 1 am users 69 Jan 19 18:16 kernel
On remarque aussi que le kernel fait seulement 69 octets, soit moins d'un secteur de disquette (512 octets), ce qui permet d'utiliser une valeur très basse pour KSIZE
. Au cas où le kernel occupe davantage de place, il faut augmenter cette valeur. Malheureusement, celà fonctionne dans une certaine limite car la lecture de données sur disque est complexe. Pour en savoir plus :
0x13
du BIOS
La disquette que nous allons faire aura le noyau placé sur le deuxieme secteur. On réalise une image de la disquette avec la commande suivante :
$ cat bootsect kernel /dev/zero | dd of=floppyA bs=512 count=2880 $ ls -l floppyA -rw-r--r-- 1 am users 1474117 Jan 19 18:27 floppyA
< Réaliser un secteur de boot qui affiche un message | TutoOS | Réaliser un secteur de boot qui passe en mode protégé >