Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5

Discussion: boot + mode protégé

  1. #1
    Membre expérimenté Avatar de edfed
    être humain
    Inscrit en
    décembre 2007
    Messages
    471
    Détails du profil
    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : décembre 2007
    Messages : 471
    Points : 563
    Points
    563

    Par défaut boot + mode protégé

    bon, voici un exemple simple pour démarrer le PC en mode protégé.
    évidement, ce code ci n'est pas optimisé pour la taille, le record à ma connaissance étant de même pas 40 octets.
    non, ici, il s'agit du code minimal compréhensible par le plus de codeurs possible.
    avec les commentaires (en french please) et tout ce qu'il faut pour montrer comment que ça marche ce truc là.

    regardez bien, le petit oiseau va sortir

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;demarrage et mode protégé      ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            org 7c00h               ; l'emplacement où sera chargé et exécuté ce programme
    boot:                           ; amorçage = 7c00h (org)
            cli                     ; désactiver les interruptions
            lgdt fword[cs:gdt.r]     ; charger la gdt depuis [cs:gdt.taille], pseudo descripteur de 6 octets
            mov eax,cr0             ; équivalent à "or cr0,1"
            or al,1                  ;   commuter le CPU en mode protégé
            mov cr0,eax             ;   mode protégé activé
            jmp gdt.code:activé     ; équivalent à "mov cs,gdt.code" + "mov eip,activé"
    activé:                         ;   la première instruction à exécuter après l'activation du mode protégé
            use32                   ; le code ci dessous est encodé pour le mode 32 bits
            mov ax,gdt.données      ; le registre "ax" pointe vers le contenu de gdt.data
            mov ds,ax               ; le sélecteur "ds" charge le descripteur de segment gdt.data
            mov ah,74h              ; couleur du texte
            mov esi,bonjour         ; pointer vers le message à afficher
            mov ecx,0b8000h         ; pointer vers la mémoire vidéo mode texte
            mov edi,0               ; pointer sur la première cellule de la mémoire vidéo, en haut à gauche
    @@:                             ;boucle d'affichage du texte
            mov al,[cs:esi]         ;  charger un caractère dans al
            or al,al                ;  caractère null, al=0?
            je @f                   ;  si oui, sortie
            mov [ecx+edi*2],ax      ; afficher le caractère en rouge sur fond gris, en haut à gauche
            inc esi                 ;  incrémenter les pointeurs
            inc edi                 ;  ...
            jmp @b                  ;goto boucle d'affichage du texte
    @@:                             ;  sortie
            hlt                     ; mettre le CPU en pause, comme cela, il consomme peu d'énergie
            jmp $                   ; reboucler infiniment
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    bonjour:                        ; message à afficher
            db 'bonjour',0          ;  bonjour
            align 8                 ; aligner la prochaine instruction sur une adresse multiple de 8 octets.
    gdt:    dw 0                    ; aligner la partie 32 bits du pseudo descripteur sur une adresse
    .r      dw @f-gdt-1             ; partie 16 bits du pseudo descripteur, taille de la gdt en octets
    .linear dd gdt                  ; partie 32 bits du pseudo descripteur, adresse de base linéaire
    .code=$-gdt                     ; première entrée dans la gdt (8*1)
    dw 0ffffh,0                     ;   4 giga octets, base à l'adresse linéaire 0
    db 0,10011010b,11001111b,0      ;   granularité = 4 kilo octets, segment de code, privilège 0, exécutable
    .données=$-gdt                  ; second entry in gdt (8*2)
    dw 0ffffh,0                     ;   4Gbytes, start at linear 0
    db 0,10010010b,11001111b,0      ;   granularity = 4Kbytes, data segment, ring 0, read/write, present,etc...
    @@:                             ; used for gdt.size calculation
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    libre =  510-(remplissage-$$)   ; define "free" bytes count
    remplissage rb libre            ; reserve "free" bytes to make line below at offset 510
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            dw 0aa55h               ; magic number boot mark, used by bios to test if valid boot sector
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    d1='0'+libre shr 8 and 0fh       ;
    d2='0'+libre shr 4 and 0fh       ;
    d3='0'+libre and 0fh             ;
    if d1>'9'                       ;
            d1=d1+7                 ;
    end if                          ;
                                    ;
    if d2>'9'                       ;
            d2=d2+7                 ;
    end if                          ;
                                    ;
    if d3>'9'                       ;
            d3=d3+7                 ;
    end if                          ;
                                    ;
    display d1,d2,d3,'h '           ;
    display 'libre bytes',13,10      ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    d1='0'+(510-libre)shr 8 and 0fh  ;
    d2='0'+(510-libre)shr 4 and 0fh  ;
    d3='0'+(510-libre)and 0fh        ;
    if d1>'9'                       ;
            d1=d1+7                 ;
    end if                          ;
                                    ;
    if d2>'9'                       ;
            d2=d2+7                 ;
    end if                          ;
                                    ;
    if d3>'9'                       ;
            d3=d3+7                 ;
    end if                          ;
                                    ;
    display d1,d2,d3,'h '           ;
    display 'used bytes',13,10      ;
     
    ;segment_descriptor:
    ;.limitl =0
    ;.basel  =2
    ;.basem  =4
    ;.field1 =5
    ;.type   =0fh
    ;.s      =10h
    ;.dpl    =60h
    ;.p      =80h
    ;.field2 =6
    ;.limith =0fh
    ;.avl    =10h
    ;.db     =40h
    ;.g      =80h
    ;.baseh  =7
    donc, comme déjà indiqué dans les commentaires, ce code, il se contente de vraiment très peu de choses.
    il désactive les interruptions, comme ça, pas de problème, pas besoin de définir la mystérieuse table de descripteurs d'interruptions (IDT).

    suite à ça, le registre GDTR est chargé avec la valeur du pseudo descripteur défini plus loin en tant que gdt.r. notez que ce pseudo descripteur (c'est le nom officiel donné par intel) mesure 48 bits, et est aligné sur 8 octets + 2, car la première partie mesure 16 bits, et la seconde 32 bits. c'est comme ça, ne cherchez pas, intel à dit de faire comme ça, il faut faire comme ça. sauf si on veut ralentir l'instruction LGDT de 2 cycles. ce qui est acceptable mais non désiré, surtout quand on code en assembleur.

    bon, la suite:

    une fois le registre GDTR chargé avec le pseudo descripteur 48 bits gdt.r, il faut activer le mode protégé.
    chose faite en positionnant le bit PE (bit 0) du registre CR0, à 1.
    pour ça, on lit une première fois le registre, en le copiant dans eax, ou ailleurs, peu importe.
    puis hop, or eax,1, et le bit est mis à 1. magique!!!! et on copie le contenu de eax dans cr0.
    le tour est joué, le CPU est en mode protégé, mais il reste une chose primordiale à faire.

    charger la partie invisible de CS avec le bon descripteur.
    pour ça, un jmp far (saut éloigné en français) vers l'adresse désirée, ici, gdt.cs:activé, et nous voilà enfin en mode protégé, pour de vrai.
    le reste, c'est de l'initialisation de registres, on charge le segment de données avec le bon descripteur.
    on pointe vers la mémoire vidéo en mode texte.
    puis on écrit "bonjour", parce qu'on est polit.

    et voilà.
    si vous voulez tester ce code, de multiples moyens s'offrent à vous.
    vous devez copier le fichier compilé sur le premier secteur du disque de démarrage (disquette, disque dur, clé usb, émulation sur cdrom, image de disque, peu importe) et lancer la machine (virtuelle ou réelle, peu importe).
    magique, il s'affiche le message bonjour en haut à gauche de l'écran. c'est joli, ça marche.

    et on va passer à la suite, car on s'arrête pas à ça.
    au passage, notez que je n'ai pas traduit les commentaires à la fin, j'estime que vous étant mis à l'assembleur, vous n'avez pas peur de trois mots en anglais, en plus, c'est de l'anglais fastoche, écrit pas un français (moi).

    pour la macro à la fin, il ne s'agit que d'un message que le compilateur FASM fourni à la compilation, pour dire combien il reste d'octets, et combien d'octets sont utilisés. donc, normalement, avec ce code, vous voyez ça:

    19Eh libre bytes
    060h used bytes

    ce qui veut dire que le code n'utilise que 96 octets (c'est énorme) et que vous avez encore 414 octets dans le secteur de boot pour vous amuser. vérification:
    un secteur = 512 octets.
    le dernier word (offset 510) est utilisé pour le mot magique. 0AA55h
    il reste bien 510 octets pour travailler.
    bien évidement, il n'y à pas de table de partition, ça sert à rien ce genre de chose, surtout quand on n'aime pas windows et linux.


    to be continued

  2. #2
    Membre confirmé
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 29

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 176
    Points : 224
    Points
    224

    Par défaut

    bravo! encore 2 sujets dans cette section et vous aurez initié plus de la moitié des sujets

    par contre je déconseillerait aux créateur d'os de mettre le passage en mode protégé directement dans le premier secteur car on ne peut plus bénéficier des fonction du dos après avoir passer en mode protégé, ce qui est utile si on veut charger d'autre secteurs en mémoire

    sauf si bien sur on veut faire du flat real mode, c'est a dire repasser en mode réel après avoir chargé les selecteurs de segment avec un segment de donnée de 4Go, ce qui permet d'avoir un mode avec les fonction du dos et l'accès total a la mémoire

  3. #3
    Membre expérimenté Avatar de edfed
    être humain
    Inscrit en
    décembre 2007
    Messages
    471
    Détails du profil
    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : décembre 2007
    Messages : 471
    Points : 563
    Points
    563

    Par défaut

    Ce n'est qu'un début cher ami.

    Effectivement, je ne l'ai pas précisé, mais ce petit code n'a qu'un seul but, montrer que c'est très simple de passer au mode protégé.

    Evidement, pour exploiter ce mode à fond, c'est tout autre chose, et nécessite plusieurs milliers de lignes de code... ce qui sort littéralement du cadre de la section contribuez, et passe dans la section projets limite commerciaux ou professionnels.

    Pour ce qui est du chargement de secteurs en mode protégé, si le lecteur est en IDE, il est tout à fait possible d'utiliser le mode PIO pour charger un nombre limité de secteurs, en atendant d'avoir le pilote DMA requis pour des chargements plus rapides et performants.

    Sinon sachez toutefois que sur les PC récents (après 2005) il y a la présence quasi systématique de l'extension de l'interruption bios INT 13H, qui permet de faire une lecture de disque en ... LBA64 (et non pas seulement 28).

  4. #4
    Membre confirmé
    passe le balais et l'aspirateur
    Inscrit en
    mars 2008
    Messages
    176
    Détails du profil
    Informations personnelles :
    Âge : 29

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : mars 2008
    Messages : 176
    Points : 224
    Points
    224

    Par défaut

    tient je ne savait pas que les bios font le LBA64! bonne nouvelle, faut que je me documente la dessus

    la doc que je possède ne me permet d'adresser que du LBA48 (ce qui fait des disque de 130 000To tout de même) faut que j'avoue que je me sui contenté de réaliser la programmation d'un mode PIO LBA28

    pour finir ue petite question:
    - j'avait comprit que le mode ultra DMA des controlleurs ATA n'uttilisait pas le puce DMA qui était uttilisé jadis par le controlleur disquette, est ce que j'aurait mal comprit?

  5. #5
    Membre expérimenté Avatar de edfed
    être humain
    Inscrit en
    décembre 2007
    Messages
    471
    Détails du profil
    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : décembre 2007
    Messages : 471
    Points : 563
    Points
    563

    Par défaut

    je ne me suis jamais penché sur du DMA.

    ce que je sais, c'est que le contrôleur UDMA existe et est une version améliorée du contrôleur DMA.

    le contrôleur DMA est un des casses tête du PC.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •