feat: réalise la chargement du fichier system.sys au format PE

This commit is contained in:
Nicolas Hordé 2007-04-02 14:30:51 +00:00
parent 1ed65408fc
commit 2765cd7331
3 changed files with 690 additions and 186 deletions

View File

@ -6,85 +6,423 @@
push cs push cs
pop ds pop ds
pop es pop es
call EnableA20 mov si,msg0
mov si,msgpmode
call showstr call showstr
mov ax,cs
mov [RealCS],ax
lea ax,[Real]
mov [RealIP],ax
xor eax,eax mov si,msg1
mov ax,cs call showstr
call initfat
call ok
mov si,msg2
call showstr
mov si,System_File
call search
call ok
mov si,msg3
call showstr
call EnableA20
call ok
mov si,msg4
call showstr
mov eax,cs
shl eax,4 shl eax,4
mov [GDT.Entry1+2],ax mov [GDT.Entry1+2],ax
mov [GDT.Entry2+2],ax mov [GDT.Entry2+2],ax
mov [GDT.Entry4+2],ax
mov [GDT.Entry5+2],ax
shr eax,16 shr eax,16
mov [GDT.Entry1+4],al mov [GDT.Entry1+4],al
mov [GDT.Entry2+4],al mov [GDT.Entry2+4],al
mov [GDT.Entry4+4],al mov eax,cs
mov [GDT.Entry5+4],al
xor eax,eax
mov ax,cs
shl eax,4 shl eax,4
add eax,gdt0 add eax,gdt0
mov [GDTR.Address],eax mov [GDTR.Address],eax
lgdt [GDTR] lgdt [GDTR]
call ok
mov si,msg5
call showstr
cli cli
;mov al,0xFF
;out 0x21,al
mov al,0x80
out 0x70,al
mov eax,cr0 mov eax,cr0
or al,1 or al,1
mov cr0,eax mov cr0,eax
jmp short $+2
mov bx,SYS_DATA_SEL
mov fs,bx
mov ds,bx
mov es,bx
mov gs,bx
and al,0FEh
mov cr0,eax
jmp short $+2
mov bx,cs
mov fs,bx
mov ds,bx
mov es,bx
mov gs,bx
sti
call ok
mov si,msg6
call showstr
mov ebx,0x300000
call load
call ok
mov si,msg7
call showstr
call initpe
call ok
mov si,msg8
call showstr
cli
mov al,0x80
out 0x70,al
mov eax,cr0
or al,1
mov cr0,eax
jmp SYS_CODE_SEL:GoPMode32 jmp SYS_CODE_SEL:GoPMode32
GoPMode32:
[BITS 32] Boot_Error:
mov ax,SYS_DATA_SEL mov si,error
mov ds,ax call showstr
mov ecx,50000/4 xor ax,ax
cld int 16h
mov esi,kernel jmp 0xFFFF:0x0
mov edi,0x100000
mov ax,ALL_DATA_SEL ok:
push si
push cx
mov cl,67
call eol
mov si,okay
call showstr
pop cx
pop si
ret
;======================INITPE========================
;Initialise le PE de l'adresse EBX
;->
;<- Flag Carry si erreur
;=====================================================
initpe:
pusha
push es
xor ax,ax
mov es,ax mov es,ax
mov gs,ax mov [begin],ebx
cmp word [es:ebx+mzheader.magic],"MZ" ; bien l'entete .exe dos ?
jne near errorpe
add ebx,[es:ebx+mzheader.lfanew] ; Pointe vers l'entete PE
cmp word [es:ebx+peheader.Signature],"PE" ; bien l'entete PE ?
jne near errorpe
cmp word [es:ebx+peheader.Signature+2],0 ; bien l'entete PE ?
jne near errorpe
mov [p_pe],ebx
mov esi,[es:ebx+peheader.ImageBase]
mov [base],esi
add esi,[es:ebx+peheader.AddressOfEntryPoint]
mov [entriepoint],esi
mov ax,[es:ebx+peheader.NumberOfSections]
add ebx,peheader.end
mov [p_sections],ebx
mov si,info1
call showstr
readsections:
mov si,info2
call showstr
mov esi,ebx
mov cx,8
call showfixstr
mov cl,17
call eol
mov edx,[es:ebx+sections.VirtualAddress]
add edx,[base]
mov cx,32
call ShowHex
mov cl,30
call eol
mov si,info3
call showstr
mov edx,[es:ebx+sections.VirtualSize]
mov cx,32
call ShowHex
mov si,info4
call showstr
mov edi,[es:ebx+sections.VirtualAddress]
add edi,[base]
cmp edi,0
je noload
push eax
push ecx
mov esi,[es:ebx+sections.PointerToRawData]
add esi,[begin]
mov ecx,[es:ebx+sections.SizeOfRawData]
shr cx,2
cmp cx,0
je zeroize
copietomem:
mov eax,[es:esi]
mov [es:edi],eax
add edi,4
add esi,4
dec cx
jnz copietomem
pop ecx
pop eax
jmp nextsymb
zeroize:
mov ecx,[es:ebx+sections.VirtualSize]
shr cx,2
mov eax,0
zerotomem:
mov [es:edi],eax
add edi,4
dec cx
jnz zerotomem
pop ecx
pop eax
jmp nextsymb
noload:
mov si,info5
call showstr
nextsymb:
mov si,return
call showstr
add ebx,sections.end
dec ax
jnz readsections
mov si,info6
call showstr
mov edx,[entriepoint]
mov cx,32
call ShowHex
clc
pop es
popa
ret
errorpe:
stc
pop es
popa
ret
entriepoint dd 0
begin dd 0
base dd 0
p_pe dd 0
p_sections dd 0
;==========SHOWHEX===========
;Affiche un nombre hexadécimal EDX de taille CX aprés le curseur
;-> AH=10, EDX un entier, CX la taille
;<-
;===========================================
ShowHex:
push ax
push bx
push cx
push edx
mov ax,cx
shr ax,2
sub cx,32
neg cx
shl edx,cl
xor cx,cx
inc cx
Hexaize:
rol edx,4
mov bx,dx
and bx,0fh
push ax
mov al,[cs:bx+Tab]
xor bx,bx
mov ah,0x09
mov bl,[cs:thecolor]
int 0x10
mov ah,0x0E
int 0x10
pop ax
dec al
jnz Hexaize
pop edx
pop cx
pop bx
pop ax
ret
Tab db '0123456789ABCDEF'
;======================EOL========================
;Va en colonne CX
;->
;<- Flag Carry si erreur
;=====================================================
eol:
pusha
mov bp,cx
mov ah,03
xor bx,bx
int 10h
mov ah,02
mov cx,bp
mov dl,cl
int 10h
popa
ret
;======================LOAD========================
;Charge le groupe en mémoire en ebx
;->
;<- Flag Carry si erreur
;=====================================================
load:
push ax
push ebx
push ecx
push edx
push esi
push edi
push fs
xor edx,edx
xor ax,ax
mov fs,ax mov fs,ax
mov ss,ax mov si,The_Dot
rep movsd mov dx,[Sectors_Size]
Resume_Loading:
cmp cx,0x0FF0
jae Finish_Loading
push cx
add cx,word [data]
mov edi,Buffer
call ReadSector
pop cx
jc near Boot_Error
call showstr
push esi
push ebx
push cx
mov esi,Buffer
mov cx,dx
shr cx,2
copie:
mov eax,[ds:esi]
mov [fs:ebx],eax
add ebx,4
add esi,4
dec cx
jnz copie
pop cx
pop ebx
pop esi
add ebx,edx
call NextFatGroup
jc near Boot_Error
jmp Resume_Loading
Finish_Loading:
pop fs
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop ax
ret
;======================INITFAT========================
;Initialise les variables de la fat
;->
;<- Flag Carry si erreur
;=====================================================
initfat:
pusha
push ds
xor ax,ax
mov ds,ax mov ds,ax
mov esp,0x3fffff mov si,0x7C0B
call KERNEL_SEL:0x100000 mov di,bootsector
jmp REAL_CODE_SEL:GoReal mov cx, 512
rep movsb
pop ds
mov cx,[Reserved_Sectors]
add cx,[Sectors_Hidden]
adc cx,[Sectors_Hidden+2]
mov bx,[Sectors_Per_Fat]
mov di,Fat_Buffer
push bx
push cx
readfat:
call ReadSector
jc Boot_Error
inc cx
add di,[Sectors_Size]
dec bx
jnz readfat
pop cx
pop bx
xor ax,ax
mov al,[Fats_Number]
mul bx
add cx,ax
mov [entries],cx
mov ax,32
mul word [Fits_Number]
div word [Sectors_Size]
add cx,ax
sub cx,2
mov word [data],cx
popa
ret
GoReal: ;======================SEARCH========================
[BITS 16] ;Recherche le groupe d'un fichier
mov ax,REAL_DATA_SEL ;-> si nom du fichier
mov ds,ax ;<- Flag Carry si erreur CX
mov es,ax ;=====================================================
mov ss,ax search:
mov gs,ax push bx
mov fs,ax push dx
mov esp,0xffff push di
mov cx,[entries]
mov di,Buffer
call ReadSector
jc Boot_Error
xor bx,bx
Next_Root_Entrie:
cmp byte [di],0
je Boot_Error
push si
push di
push cx
mov cx,11
rep cmpsb
pop cx
pop di
pop si
je Found
add di,32
add bx,32
inc dx
cmp dx,[Fits_Number]
ja Boot_Error
cmp bx,[Sectors_Size]
jb Next_Root_Entrie
inc cx
Found:
mov cx,[di+26]
pop di
pop dx
pop bx
ret
mov eax,cr0
and al,0xFE
mov cr0,eax
jmp far [RealIP]
Real:
jmp Real
msgpmode db 'Pmode loader is loading',0
;======================SHOWSTR======================== ;======================SHOWSTR========================
;Affiche la chaine de caractère pointé par ds:si à l'écran ;Affiche la chaine de caractère pointé par ds:si à l'écran
@ -93,18 +431,143 @@ msgpmode db 'Pmode loader is loading',0
;===================================================== ;=====================================================
showstr: showstr:
pusha pusha
Next_Char: xor bh,bh
xor cx,cx
inc cx
nextchar:
lodsb lodsb
or al,al or al,al
jz End_Show jz endshow
mov ah,0x0E cmp al,' '
mov bx,0x07 jb justchar
cmp al,'#'
jne nocolor
lodsb
sub al,'0'
shl al,3
mov [cs:thecolor],al
shr al,2
add [cs:thecolor],al
lodsb
sub al,'0'
add [cs:thecolor],al
jmp nextchar
nocolor:
xor bx,bx
mov ah,0x09
mov bl,[cs:thecolor]
int 0x10 int 0x10
jmp Next_Char justchar:
End_Show: mov ah,0x0E
int 0x10
jmp nextchar
endshow:
popa popa
ret ret
;======================SHOWFIXEDSTR========================
;Affiche la chaine de caractère pointé par esi à l'écran pour CX caractères
;-> DS, SI
;<- Flag Carry si erreur
;=====================================================
showfixstr:
pusha
push ds
xor ax,ax
mov ds,ax
xor bh,bh
mov dx,cx
xor cx,cx
inc cx
nextchars:
mov al,[ds:esi]
inc esi
or al,al
jz endshows
cmp al,' '
jb justchars
xor bx,bx
mov ah,0x09
mov bl,[cs:thecolor]
int 0x10
justchars:
mov ah,0x0E
int 0x10
dec dx
jnz nextchars
endshows:
pop ds
popa
ret
;====================READSECTOR=======================
;Lit le secteur logique LBA CX et le met en es:di
;-> CX (limité à 65536 secteurs, soit 32 Mo avec secteur 512 octets)
;<- Flag Carry si erreur
;=====================================================
ReadSector:
pusha
mov ax,cx
xor dx,dx
div word [Sectors_Per_Track]
inc dl
mov bl,dl
xor dx,dx
div word [Heads_Number]
mov dh, [Boot_Drive]
xchg dl,dh
mov cx,ax
xchg cl,ch
shl cl,6
or cl, bl
mov bx,di
mov si, 4
mov al, 1
Read_Again:
mov ah, 2
int 0x13
jnc Read_Done
dec si
jnz Read_Again
Read_Done:
popa
ret
;===================NEXTFATGROUP======================
;Renvoie en CX le groupe qui succède dans la FAT le groupe CX
;-> CX
;<-
;=====================================================
NextFatGroup:
push bx
push dx
push di
mov ax,cx
mov bx,ax
and bx,0000000000000001b
shr ax,1
mov cx,3
mul cx
mov di,Fat_Buffer
add di,ax
cmp bx,0
jnz Even_Group
Odd_Group:
mov dx,[di]
and dx,0x0FFF
mov cx,dx
jmp Next_Group_Found
Even_Group:
mov dx,[di+1]
and dx,0xFFF0
shr dx,4
mov cx,dx
Next_Group_Found:
pop di
pop dx
pop bx
ret
;***********************EnableA20******************************* ;***********************EnableA20*******************************
;-> ;->
@ -139,17 +602,58 @@ A20Enabled:
sti sti
ret ret
GoPMode32:
[BITS 32]
mov ax,ALL_DATA_SEL
mov es,ax
mov gs,ax
mov fs,ax
mov ss,ax
mov ds,ax
mov esp,0x3fffff
push KERNEL_SEL
push dword [cs:entriepoint]
retf
; jmp KERNEL_SEL:0x401020
section .data section .data
RealIP: dw 0 thecolor db 0x07
RealCS: dw 0 msg0 db '#12-=< Lancement du Chargeur PE >=-',0x0A,0x0D,0x0A,0x0D,0
msg1 db '#07Initialisation de la FAT',0
msg2 db '#07Recherche du systeme',0
msg3 db '#07Activation adressage 24 bits',0
msg4 db '#07Chargement des descripteurs',0
msg5 db '#07Passage en mode Flat real',0
msg6 db '#07Chargement du systeme',0
msg7 db '#07Mise en place image PE',0
msg8 db '#07Passage en mode protege',0
msg9 db '#07Execution du noyau',0
info1 db 0x0A,0x0D,'#08Sections :',0x0A,0x0D,0
info2 db ' -',0
info3 db ' (',0
info4 db ') ',0
info5 db ' #12Non projete#08',0
info6 db 'Point entree en ',0
return db 0x0A,0x0D,0
okay db ' #15[ #10OK #15]',0x0A,0x0D,0
error db ' #15[#12Erreur#15]',0x0A,0x0D,0x0A,0x0D,' <Appuyez une touche pour redemarrer>',0
The_Dot db '.',0
System_File db "SYSTEM SYS"
entries dw 0
data dw 0
xy dw 0
GDTR: GDTR:
.Size: dw GDT_END .Size: dw GDT_END
.Address: dd 0 .Address: dd 0
gdt0 equ $ ; null entry gdt0 equ $ ; null entry
GDT: GDT:
.Entry0: dw 0 ; limit 15:0 .Entry0: dw 0 ; limit 15:0
@ -166,7 +670,7 @@ SYS_CODE_SEL equ $-gdt0 ; code segment descriptor
dw 0x0 ; base dw 0x0 ; base
db 0x0 ; base db 0x0 ; base
db 0x9A ; present, ring 0, code, non-conforming, readable db 0x9A ; present, ring 0, code, non-conforming, readable
db 0x40 ; 32 bit db 0xCF ; 32 bit
db 0 db 0
@ -176,52 +680,52 @@ SYS_DATA_SEL equ $-gdt0 ; data segment descriptor
dw 0x0 ; base dw 0x0 ; base
db 0x0 ; base db 0x0 ; base
db 0x92 ; present, ring 0, data, expand-up, writable db 0x92 ; present, ring 0, data, expand-up, writable
db 0x40 ; 32 bit db 0xCF ; 32 bit
db 0 db 0
ALL_DATA_SEL equ $-gdt0 ; 4meg data segment descriptor ALL_DATA_SEL equ $-gdt0 ; 4meg data segment descriptor
.Entry3: dw 0x03ff .Entry3: dw 0xFFFF
dw 0x0 ; base dw 0x0 ; base
db 0x0 ; base db 0x0 ; base
db 0x92 ; present, ring 0, data, expand-up, writable db 0x92 ; present, ring 0, data, expand-up, writable
db 0xcf ; 4k pages, 32 bit db 0xCF ; 4k pages, 32 bit
db 0 db 0
REAL_CODE_SEL equ $-gdt0 ; code segment descriptor for 16 bit mode KERNEL_SEL equ $-gdt0 ; 4g code segment descriptor
.Entry4: dw 0xFFFF .Entry4: dw 0xffff
dw 0x0 ; base dw 0x0 ; base
db 0x0 ; base db 0x0 ; base
db 0x9A ; present, ring 0, code, non-conforming, readable db 0x9A ; present, ring 0, code, non-conforming, readable
db 0x00 ; 16 bit db 0xCF ; 4k pages, 32 bit
db 0
REAL_DATA_SEL equ $-gdt0 ; data segment descriptor for 16 bit mode
.Entry5: dw 0xFFFF
dw 0x0 ; base
db 0x0 ; base
db 0x92 ; present, ring 0, data, expand-up, writable
db 0x00 ; 16 bit
db 0
KERNEL_SEL equ $-gdt0 ; 4meg code segment descriptor
.Entry6: dw 0x03ff
dw 0x0 ; base
db 0x0 ; base
db 0x9A ; present, ring 0, code, non-conforming, readable
db 0xcf ; 4k pages, 32 bit
db 0 db 0
GDT_END equ $-gdt0 -1 GDT_END equ $-gdt0 -1
kernel: bootsector equ $
Sectors_Size dw 0 ;Nombre d'octets/secteur
Sectors_Per_Cluster db 0 ;Nombre de secteurs/cluster
Reserved_Sectors dw 0 ;Nombre de secteurs réservé
Fats_Number db 0 ;Nombre de copies de la FAT
Fits_Number dw 0 ;Taille du répertoire racine
Sectors_Per_Disk dw 0 ;Nombre secteurs du volume si < 32 Mo
Media_Descriptor db 0 ;Descripteur de média
Sectors_Per_Fat dw 0 ;Nombre secteurs/FAT
Sectors_Per_Track dw 0 ;Nombre secteurs/piste
Heads_Number dw 0 ;Nombre de tete de lecture/écriture
Sectors_Hidden dd 0 ;Nombre de secteurs cachés
Sectors_Per_Disk2 dd 0 ;Nombre secteurs du volume si > 32 Mo
Boot_Drive db 0 ;Lecteur de démarrage
Reserved db 0 ;NA (pour NT seulement)
Extended_Boot_ID db 0 ;Signature Boot étendu 29h
Buffer equ $
Fat_Buffer equ $+512
SECTION .bss SECTION .bss
%include "pe.h"