LE SECTEUR DE PARTITION

 

Introduction

Comme vous devez le savoir, au démarrage de votre ordinateur, le BIOS recherche sur A: ou C: un petit programme dans le premier secteur de la disquette ou du disque dur qui lui permettra de charger la suite des réjouissances... pardon, je veux dire le système d'exploitation.

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...

 

Le secteur de partition

J'en étais où ? Ah oui au secteur de partition, qu'en passant, on appelle aussi master boot ou primary boot en anglais. Contrairement au programme du boot d'une disquette, le programme du secteur de partition ne va pas charger directement le système mais va charger un autre secteur qui lui est le vrai secteur de boot.

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 :

AdresseTailleFonction
01Etat de la partition (80h bootable sinon 00h)
11Tête où commence la partition
22Secteur et cylindre où commence la partition
41Type de partition (ex 04h DOS avec FAT 16 bits)
51Tête de fin de partition
62Secteur et cylindre de fin de partition
84Position du secteur de boot de la partition en secteur par rapport au secteur de partition
124Nombre de secteur de la partition

Le programme du secteur de partition va donc chercher une partition bootable et charger le premier secteur en 07C0:0000h après s'être déplacé ailleurs. Il vérifie qu'il contient bien un programme utilisable en regardant si il se termine bien par 55h,0AAh. Puis il passe la main à ce programme qui est le véritable programme de boot, équivalent à celui qui se trouve sur le premier secteur d'une disquette.

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.

 

Une source pour finir

Le programme du secteur de partition est donc quelque chose de très simple. Pour éviter de rester dans une discussion théorique, je vais maintenant vous donner un listing désassemblé et commenté du programme de boot d'un disque dur.

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.....

 

Le source du boot

;****************************************************************************
;*    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