IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation d'OS Assembleur Discussion :

Passage en Long mode (64 bits mode) par AMD


Sujet :

Programmation d'OS Assembleur

  1. #1
    Membre actif Avatar de Belegkarnil
    Inscrit en
    Juin 2005
    Messages
    289
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Juin 2005
    Messages : 289
    Points : 205
    Points
    205
    Par défaut Passage en Long mode (64 bits mode) par AMD
    Bonjour, je lis la documentation d'AMD pour les processeurs 64 bits et ils donnent un exemple de code en assembleur pour passer en Long mode. Je ne connais que très peu l'assembleur, donc je ne comprends pas tout le code... Mais je n'arrive pas à le compiler. J'utilise yasm, et j'obtiens plein d'erreurs et quand je test avec nasm j'en obtiens déjà beaucoup moins. Donc je me demande si c'est bien la syntaxe AT&T (parce que yasm utilise celle la je crois). Et si j'ai bien compris, on a la "déclaration" des données dans 'mydata', puis on a le code en 16, 32 et 64 bits. Si vous pouviez donc me dire ce qui ne fonctionne pas, ça serait gentil :-)

    Merci ;-)

    (J'utilise donc yasm sous Linux en 64bits)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    mydata segment para
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ; This generic data-segment holds pseudo-descriptors used
    ; by the LGDT and LIDT instructions.
    ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ; Establish a temporary 32-bit GDT and IDT.
    ;
    pGDT32 label    fword                  ; Used by LGDT.
                    dw      gdt32_limit    ; GDT limit ...
                    dd      gdt32_base     ; and 32-bit GDT base
     
    pIDT32 label    fword                  ; Used by LIDT.
                    dw      idt32_limit    ; IDT limit ...
                    dd      idt32_base     ; and 32-bit IDT base
    ;
    ; Establish a 64-bit GDT and IDT (64-bit linear base-address)
    ;
    pGDT64 label    tbyte                  ; Used by LGDT.
                    dw      gdt64_limit    ; GDT limit ...
                    dq      gdt64_base     ; and 64-bit GDT base
     
    pIDT64 label    tbyte                  ; Used by LIDT.
                    dw       idt64_limit    ; IDT limit ...
                    dq       idt64_base     ; and 64-bit IDT base
     
    mydata ends                 ; end of data segment
     
    code16 segment para use16 ; 16-bit code segment
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; 16-bit code, real mode
    ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;
    ; Initialize DS to point to the data segment containing
    ; pGDT32 and PIDT32. Set up a real-mode stack pointer, SS:SP,
    ; in case of interrupts and exceptions.
    ;
       cli
       mov   ax, seg mydata
       mov   ds, ax
       mov   ax, seg mystack
       mov   ss, ax
       mov   sp, esp0
    ;
    ; Use CPUID to determine if the processor supports long mode. ;
     
       mov   eax, 80000000h ; Extended-function 8000000h.
       cpuid                ; Is largest extended function
       cmp   eax, 80000000h ; any function > 80000000h?
       jbe   no_long_mode   ; If not, no long mode.
       mov   eax, 80000001h ; Extended-function 8000001h.
       cpuid                ; Now EDX = extended-features flag
       bt    edx, 29        ; Test if long mode is supported.
       jnc   no_long_mode   ; Exit if not supported.
    ;
    ; Load the 32-bit GDT before entering protected mode.
    ; This GDT must contain, at a minimum, the following
    ; descriptors:
    ;  1) a CPL=0 16-bit code descriptor for this code segment
    ;  2) a CPL=0 32/64-bit code descriptor for the 64-bit cod
    ;  3) a CPL=0 read/write data segment, usable as a stack
    ;  (referenced by SS).
    ;
    ; Load the 32-bit IDT, in case any interrupts or exception
    ; occur after entering protected mode, but before enabling
    ; long mode).
    ;
    ; Initialize the GDTR and IDTR to point to the temporary
    ; 32-bit GDT and IDT, respectively.
    ;
       lgdt  ds:[pGDT32]
       lidt  ds:[pIDT32]
    ;
    ; Enable protected mode (CR0.PE=1).
     
       mov   eax, 000000011h
       mov   cr0, eax
    ;
    ; Execute a far jump to turn protected mode on.
    ; code16_sel must point to the previously-established 16-bit
    ; code descriptor located in the GDT (for the code currently
    ; being executed).
    ;
       db    0eah              ;Far jump...
       dw    offset now_in_prot;to offset...
       dw    code16_sel        ;in current code segment.
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; At this point we are in 16-bit protected mode, but long
    ; mode is still disabled.
    ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     
    now_in_prot:
    ;
    ; Set up the protected-mode stack pointer, SS:ESP.
    ; Stack_sel must point to the previously-established stack
    ; descriptor (read/write data segment), located in the GDT.
    ; Skip setting DS/ES/FS/GS, because we are jumping right to
    ; 64-bit code.
    ;
       mov   ax, stack_sel
       mov   ss, ax
       mov   esp, esp0
    ;
    ; Enable the 64-bit page-translation-table entries by
    ; setting CR4.PAE=1 (this is _required_ before activating
    ; long mode). Paging is not enabled until after long mode
    ; is enabled.
    ;
       mov   eax, cr4
       bts   eax, 5
       mov   cr4, eax
    ;
    ; Create the long-mode page tables, and initialize the
    ; 64-bit CR3 (page-table base address) to point to the base
    ; of the PML4 page table. The PML4 page table must be located
    ; below 4 Gbytes because only 32 bits of CR3 are loaded when
    ; the processor is not in 64-bit mode.
    ;
       mov   eax, pml4_base ; Pointer to PML4 table (<4GB).
       mov   cr3, eax        ; Initialize CR3 with PML4 base.
    ;
    ; Enable long mode (set EFER.LME=1).
    ;
       mov   ecx, 0c0000080h    ; EFER MSR number.
       rdmsr                    ; Read EFER.
       bts   eax, 8             ; Set LME=1.
     
       wrmsr                   ; Write EFER.
    ;
    ; Enable paging to activate long mode (set CR0.PG=1)
    ;
       mov   eax, cr0          ; Read CR0.
       bts   eax, 31           ; Set PE=1.
       mov   cr0, eax          ; Write CR0.
    ;
    ; At this point, we are in 16-bit compatibility mode
    ; ( LMA=1, CS.L=0, CS.D=0 ).
    ; Now, jump to the 64-bit code segment. The offset must be
    ; equal to the linear address of the 64-bit entry point,
    ; because 64-bit code is in an unsegmented address space.
    ; The selector points to the 32/64-bit code selector in the
    ; current GDT.
    ;
        db    066h
        db    0eah
        dd    start64_linear
        dw    code64_sel
     
    code16ends      ; End of the 16-bit code segment
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;
    ;;;     Start of 64-bit code
    ;;
    ;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    code64 para use64
    start64:        ; At this point, we're using 64-bit code
    ;
    ; Point the 64-bit RSP register to the stack’s _linear_
    ; address. There is no need to set SS here, because the SS
    ; register is not used in 64-bit mode.
    ;
        mov   rsp, stack0_linear
    ;
    ; This LGDT is only needed if the long-mode GDT is to be
    ; located at a linear address above 4 Gbytes. If the long
    ; mode GDT is located at a 32-bit linear address, putting
    ; 64-bit descriptors in the GDT pointed to by [pGDT32] is
    ; just fine. pGDT64_linear is the _linear_ address of the
    ; 10-byte GDT pseudo-descriptor.
    ;
    ; The new GDT should have a valid CPL0 64-bit code segment
    ; descriptor at the entry-point corresponding to the current
    ; CS selector. Alternatively, a far transfer to a valid CPL0
    ; 64-bit code segment descriptor in the new GDT must be done
    ; before enabling interrupts.
    ;
        lgdt [pGDT64_linear]
    ;
     
    ; Load the 64-bit IDT. This is _required_, because the 64-bit
    ; IDT uses 64-bit interrupt descriptors, while the 32-bit
    ; IDT used 32-bit interrupt descriptors. pIDT64_linear is
    ; the _linear_ address of the 10-byte IDT pseudo-descriptor.
    ;
       lidt [pIDT64_linear]
    ;
    ; Set the current TSS. tss_sel should point to a 64-bit TSS
    ; descriptor in the current GDT. The TSS is used for
    ; inner-level stack pointers and the IO bit-map.
    ;
       mov   ax, tss_sel
       ltr   ax
    ;
    ; Set the current LDT. ldt_sel should point to a 64-bit LDT
    ; descriptor in the current GDT.
    ;
     
       mov   ax, ldt_sel
       lldt ax
    ;
    ; Using fs: and gs: prefixes on memory accesses still uses
    ; the 32-bit fs.base and gs.base. Reload these 2 registers
    ; before using the fs: and gs: prefixes. FS and GS can be
    ; loaded from the GDT using a normal “mov fs,foo” type
    ; instructions, which loads a 32-bit base into FS or GS.
    ; Alternatively, use WRMSR to assign 64-bit base values to
    ; MSR_FS_base or MSR_GS_base.
    ;
       mov   ecx, MSR_FS_base
       mov   eax, FsbaseLow
       mov   edx, FsbaseHi
       wrmsr
    ;
    ; Reload CR3 if long-mode page tables are to be located above
    ; 4 Gbytes. Because the original CR3 load was done in 32-bit
    ; legacy mode, it could only load 32 bits into CR3. Thus, the
    ; current page tables are located in the lower 4 Gbytes of
    ; physical memory. This MOV to CR3 is only needed if the
    ; actual long-mode page tables should be located at a linear
    ; address above 4 Gbytes.
    ;
       mov   rax, final_pml4_base ; Point to PML4
       mov   cr3, rax              ; Load 64-bit CR3
    ;
    ; Enable interrupts.
    ;
       sti                         ; Enabled INTR

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 37
    Points : 30
    Points
    30
    Par défaut
    c'est une syntaxe intel(nasm peut donc le compiler).
    Yasm supporte les 2 syntaxe(at&t et intel). Le problème ne vient pas de la syntaxe.
    Je pense qu'il faut que tu spécifie au compilateur l'architecture 64 bit. Par défaut, c'est réglé sur 32bit, et il y a des instructions qui n'existe qu'en 64 bit, ce qui doit être le cas dans ton code.
    Essaye avec :
    yasm -f elf64 -o nomdufichiercompilé fichiersource.s
    ou
    nasm -f elf64 -o nomdufichiercompilé fichiersource.s
    remplace elf64 par win64 si tu es sous windows.

  3. #3
    Membre actif Avatar de Belegkarnil
    Inscrit en
    Juin 2005
    Messages
    289
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations forums :
    Inscription : Juin 2005
    Messages : 289
    Points : 205
    Points
    205
    Par défaut
    Oui, je l'avais normalement compilé en spécifiant le format en 64 bits mais ça n'a donc pas fonctionné.

Discussions similaires

  1. Passer du mode 16 au mode 24 bits
    Par Razblock dans le forum Ubuntu
    Réponses: 1
    Dernier message: 21/07/2009, 14h43
  2. Masquer champs en mode feuille de données par macro
    Par martino_fr dans le forum Access
    Réponses: 1
    Dernier message: 22/09/2006, 09h57
  3. Passage en mode 8 bits (couleurs)
    Par skip78 dans le forum Allegro
    Réponses: 2
    Dernier message: 20/07/2006, 09h22
  4. Compilateur C 16 bits mode réel
    Par jfg31 dans le forum C
    Réponses: 10
    Dernier message: 11/03/2006, 10h40
  5. Passage du mode console au mode graphique
    Par just1980 dans le forum Applications et environnements graphiques
    Réponses: 3
    Dernier message: 23/10/2005, 20h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo