require("../global.php"); entete(); ?>
Pour reconnaitre ce programme, le BIOS va aller regarder les 2 derniers octets du secteur, si ils sont égaux à 55h et 0AAh c'est bon. Dans ce cas, il charge le secteur en 0000:7C00h et donne la main au programme. Sinon il affiche un message d'erreur et attend une disquette de boot.
C'est à ce moment là que l'on distingue une disquette d'un disque dur. Dans le cas d'une disquette, le programme de boot va charger directement le système, par exemple IO.SYS et MSDOS.SYS pour le DOS, et lui passer la main. Dans le cas d'un disque dur, c'est un peu plus compliqué car ce secteur est en fait le secteur de partition. Comme c'est celui qui nous intéresse plus particulièrement je lui ai réservé le chapitre suivant...
Pour savoir quel secteur charger, il regarde la fameuse table de partition située providentiellement à la fin du secteur de partition juste avant le 55h,AAh. Comme le BIOS vient de charger ce secteur, la table se trouve en mémoire à l'adresse 07C0h:1BEh et occupe 64 octets.
Cette table permet de diviser un disque dur en morçeaux de taille variable appelés partitions. Ces morceaux sont indépendants et cela permet donc d'avoir plusieurs systèmes d'exploitation sur un même disque dur. Comme la place est limitée dans le secteur de partition, on n'a que quatre entrées dans la table (à mon avis, on avait de la place pour un peu plus mais bon c'est comme ca, il faut faire avec). Chaque entrée contient les informations suivantes :
| Adresse | Taille | Fonction |
| 0 | 1 | Etat de la partition (80h bootable sinon 00h) |
| 1 | 1 | Tête où commence la partition |
| 2 | 2 | Secteur et cylindre où commence la partition |
| 4 | 1 | Type de partition (ex 04h DOS avec FAT 16 bits) |
| 5 | 1 | Tête de fin de partition |
| 6 | 2 | Secteur et cylindre de fin de partition |
| 8 | 4 | Position du secteur de boot de la partition en secteur par rapport au secteur de partition |
| 12 | 4 | Nombre de secteur de la partition |
Avant de vous donner la source accompagnant cet article, je vais vous parler des partition étendues. Les partitions étendues prennent la place d'une des quatre partitions principales avec 5 comme code de type de partition. Le secteur de boot de cette partition est alors spécial et comprend uniquement une table de partition à deux entrées (quelle gâchis : on n'utilise même pas 5% du secteur !). La première entrée donne le secteur de boot de la première partition étendue. La seconde entrée donne la position du secteur de partition étendue suivant. Ainsi il se forme une liste chainée de secteur de partition étendue jusqu'à ce que le type de la deuxième entrée de ces tables de partition soit nulle.
C'est un programme un peu spécial car il est chargé par le BIOS en 0:7C00h et se déplace en 0:600h (vous pouvez changer l'adresse). Le problème étant de faire avaler cela à l'assembleur puis au linker, personnellement j'ai utilisé TASM, ce qui à mon avis n'est pas le meilleur choix. Mais on y arrive en compilant le programme à l'adresse 0 et en rajoutant à toutes les adresses l'offset de début du programme. Puis on linke cela en tant qu'exécutable et on peut alors récupérer le code avec EXE2BIN. Ce programme existe dans le DOS 5 mais pour les nouveaux, j'en ai refait un qui fait le même boulot et normalement il accompagnera l'article.
De plus pour pouvoir changer facilement le secteur de partition de votre propre disque, je vous ai fait un petit programme nommé WRMBOOT qui fait cela très bien. Attention, avant de l'utiliser, lisez attentivement la documentation car il peut vous faire perdre toutes les données de votre disque dur si vous faites n'importe quoi.
Il ne devrait pas y avoir de problème, mais c'est quand même une manipulation un peu délicate donc c'est peut être pas la peine de vous lancer dedans, si vous débutez. Lors des tests, j'ai rencontré un problème car ma table de partition contenait deux partitions exécutables (surement dû à des tests précédents) et comme vous le verrez dans le programme, dans ce cas, le boot s'arrête. Il n'y a pas de raison de paniquer vous avez juste à changer le programme de boot ou la table de partition.
Allez amusez vous bien mais faites quand même attention à votre disque dur.....
;****************************************************************************
;* Programme du secteur de partition de mon disque dur
;*
;* (C) 1990 American Megatrends Inc
IDEAL
STRUC PART_ENTRY ; Structure d'une entrée de la table
State DB 0 ; de partition
StartHead DB 0
StartSector DW 0
Type DB 0
EndHead DB 0
EndSector DW 0
FirstSector DD 0
NbSector DD 0
ENDS
BIOS_BOOT_OFF EQU 7C00h ; adresse où le BIOS charge le boot
NEW_BOOT_OFF EQU 600h ; adresse où l'on déplace le boot
BOOT_SIZE EQU 512 ; taille du boot secteur
NB_PART EQU 4 ; nombre d'entrée dans la table de partition
NB_READ_TRY EQU 5 ; nombre maximum de lecture du secteur de boot
PART_OFF EQU 1BEh ; offset de la table de partition dans le
; secteur de partition
MAGIC_OFF EQU 7DFEh ; offset du nombre magic 0AA55h
SEGMENT BOOT public 'CODE'
ASSUME cs:BOOT ; Au début on est en 7C00h mais
; ca va pas durer
start_boot:
cli
xor ax,ax
mov ss,ax
ASSUME ss:BOOT
mov sp,BIOS_BOOT_OFF ; On place la pile dans un coin
; Pour l'instant il n'y a que
; le BIOS en mémoire alors on
; a de la place
mov si,sp
push ax
pop es
push ax
pop ds
ASSUME es:BOOT,ds:BOOT
; Voilà tous les registres de segment
; sont chargé
sti ; et hop on se recopie en 600h
cld
mov di, NEW_BOOT_OFF
mov cx, BOOT_SIZE/2
repne movsw
jmp FAR 0:NEW_BOOT_OFF+1Dh ; C'est pas cool les assembleurs qui
; se croient malin....:-(
ORG 1Dh ; évitez d'écraser le début du
; du programme
start: ; Là on commence les choses sérieuses
mov si, offset Partition_Tab+NEW_BOOT_OFF
mov bl, NB_PART
Search_bootable: ; recherche une partition bootable
; l'etat de la partition peut être
; 80h bootable ou 00h non bootable
; sinon il y a une erreur
cmp [(PART_ENTRY PTR si).State], 80h
jz Find_Bootable
cmp [(PART_ENTRY PTR si).State], 0
jnz Part_error
add si, SIZE PART_ENTRY
dec bl
jnz Search_bootable
int 18h ; Aucune partition bootable
; Appel du basic en ROM !!!
Find_Bootable: ; Ouf on a trouvé une partition
; bootable
; Pour dx il y a une ruse car 80h
; correspond aussi au premier disque
; dur
mov dx, [word ptr ((PART_ENTRY si).State)]
mov cx, [(PART_ENTRY si).StartSector]
mov bp, si
Test_part: ; On verifie qu'il y a qu'une partition
; bootable
add si, SIZE PART_ENTRY
dec bl
jz Only_one_boot
cmp [byte ptr si], 0
jz Test_part
Part_error:
; Aih, il y a eut un problème
mov si, offset No_Part_msg+NEW_BOOT_OFF
Print_error: ; Affiche un message d'erreur
lodsb
cmp al, 0
jz Endless_loop
push si ; Affiche un caratère
mov bx, 7
mov ah, 0Eh
int 10h
pop si
jmp Print_error
Endless_loop: ; Quand on a affiché tous le message
; d'erreur, attend la fin du monde
jmp Endless_loop
Only_one_boot: ; Ouf, on a trouvé une et une seule
; partition bootable
mov di, NB_READ_TRY
Retry:
mov bx,BIOS_BOOT_OFF ; Essaye de lire le secteur de boot
mov ax,201h ; de la partition choisie
push di
int 13h
pop di
jnb Load_ok
xor ax, ax ; Problème, reset et reessaye
int 13h
dec di
jnz Retry
mov si, offset Disk_error_msg+NEW_BOOT_OFF
jmp Print_error ; Impossible de lire le disque
Load_ok: ; Ouf, on est arrivé à lire
; le secteur de boot
mov si, offset No_system_msg+NEW_BOOT_OFF
mov di, MAGIC_OFF
cmp [word ptr di], 0AA55h
jnz Print_error ; damned, il n'est pas executable
mov si, bp
jmp far ptr 0:7C00h ; C'est fini, on peut aller
; executer le boot
No_Part_msg DB 'Table de partition non valide',0
Disk_error_msg DB 'Erreur au cours du chargement du système d''exploitation',0
No_system_msg DB 'Système d''exploitation absent'
ORG PART_OFF
Partition_Tab PART_ENTRY NB_PART DUP (?)
dw 0AA55h
ENDS
END start_boot
PiedDePage();
?>