From 2765cd73312ef7e3df003600bbee217170633da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Hord=C3=A9?= Date: Mon, 2 Apr 2007 14:30:51 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20r=C3=A9alise=20la=20chargement=20du=20f?= =?UTF-8?q?ichier=20system.sys=20au=20format=20PE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boot/echs.h | 20 +- boot/loader.asm | 694 +++++++++++++++++++++++++++++++++++++++++------- boot/pe.h | 162 +++++------ 3 files changed, 690 insertions(+), 186 deletions(-) diff --git a/boot/echs.h b/boot/echs.h index fc1bba9..7309f47 100644 --- a/boot/echs.h +++ b/boot/echs.h @@ -1,10 +1,10 @@ -struc echs -Sizes resb 1 -Reserve resb 1 -NumSectors resw 1 -Adressoff resw 1 -Adressseg resw 1 -SectorLow resw 1 -SectorHigh resw 1 -Dummy resq 1 -endstuc +struc echs +Sizes resb 1 +Reserve resb 1 +NumSectors resw 1 +Adressoff resw 1 +Adressseg resw 1 +SectorLow resw 1 +SectorHigh resw 1 +Dummy resq 1 +endstuc diff --git a/boot/loader.asm b/boot/loader.asm index 7b9deef..9808d5c 100644 --- a/boot/loader.asm +++ b/boot/loader.asm @@ -6,85 +6,423 @@ push cs pop ds pop es - call EnableA20 - mov si,msgpmode + mov si,msg0 call showstr - mov ax,cs - mov [RealCS],ax - lea ax,[Real] - mov [RealIP],ax + + mov si,msg1 + call showstr + call initfat +call ok - xor eax,eax - mov ax,cs + 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 mov [GDT.Entry1+2],ax mov [GDT.Entry2+2],ax - mov [GDT.Entry4+2],ax - mov [GDT.Entry5+2],ax shr eax,16 mov [GDT.Entry1+4],al mov [GDT.Entry2+4],al - mov [GDT.Entry4+4],al - mov [GDT.Entry5+4],al - - xor eax,eax - mov ax,cs + mov eax,cs shl eax,4 add eax,gdt0 mov [GDTR.Address],eax - lgdt [GDTR] - + lgdt [GDTR] +call ok + + mov si,msg5 + call showstr + cli + mov eax,cr0 + or al,1 + 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,0xFF - ;out 0x21,al mov al,0x80 out 0x70,al - mov eax,cr0 or al,1 mov cr0,eax - jmp SYS_CODE_SEL:GoPMode32 + + +Boot_Error: + mov si,error + call showstr + xor ax,ax + int 16h + jmp 0xFFFF:0x0 + +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 [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 -GoPMode32: -[BITS 32] - mov ax,SYS_DATA_SEL - mov ds,ax - mov ecx,50000/4 - cld - mov esi,kernel - mov edi,0x100000 - mov ax,ALL_DATA_SEL - mov es,ax - mov gs,ax - mov fs,ax - mov ss,ax - rep movsd - mov ds,ax - mov esp,0x3fffff - call KERNEL_SEL:0x100000 - jmp REAL_CODE_SEL:GoReal +;==========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' -GoReal: -[BITS 16] - mov ax,REAL_DATA_SEL - mov ds,ax - mov es,ax - mov ss,ax - mov gs,ax - mov fs,ax - mov esp,0xffff +;======================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 - mov eax,cr0 - and al,0xFE - mov cr0,eax - jmp far [RealIP] +;======================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 si,The_Dot + 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 -Real: - jmp Real +;======================INITFAT======================== +;Initialise les variables de la fat +;-> +;<- Flag Carry si erreur +;===================================================== +initfat: + pusha + push ds + xor ax,ax + mov ds,ax + mov si,0x7C0B + mov di,bootsector + 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 + +;======================SEARCH======================== +;Recherche le groupe d'un fichier +;-> si nom du fichier +;<- Flag Carry si erreur CX +;===================================================== +search: + push bx + push dx + 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 + -msgpmode db 'Pmode loader is loading',0 ;======================SHOWSTR======================== ;Affiche la chaine de caractère pointé par ds:si à l'écran @@ -92,19 +430,144 @@ msgpmode db 'Pmode loader is loading',0 ;<- Flag Carry si erreur ;===================================================== showstr: - pusha -Next_Char: + pusha + xor bh,bh + xor cx,cx + inc cx +nextchar: lodsb or al,al - jz End_Show - mov ah,0x0E - mov bx,0x07 + jz endshow + cmp al,' ' + 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 - jmp Next_Char -End_Show: +justchar: + mov ah,0x0E + int 0x10 + jmp nextchar +endshow: popa + 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******************************* ;-> @@ -137,19 +600,60 @@ ReadKeyb: jmp ClearKeybBuffer A20Enabled: 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 -RealIP: dw 0 -RealCS: dw 0 +thecolor db 0x07 +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,' ',0 +The_Dot db '.',0 +System_File db "SYSTEM SYS" +entries dw 0 +data dw 0 +xy dw 0 GDTR: .Size: dw GDT_END .Address: dd 0 - - gdt0 equ $ ; null entry GDT: .Entry0: dw 0 ; limit 15:0 @@ -166,7 +670,7 @@ SYS_CODE_SEL equ $-gdt0 ; code segment descriptor dw 0x0 ; base db 0x0 ; base db 0x9A ; present, ring 0, code, non-conforming, readable - db 0x40 ; 32 bit + db 0xCF ; 32 bit db 0 @@ -176,52 +680,52 @@ SYS_DATA_SEL equ $-gdt0 ; data segment descriptor dw 0x0 ; base db 0x0 ; base db 0x92 ; present, ring 0, data, expand-up, writable - db 0x40 ; 32 bit + db 0xCF ; 32 bit db 0 ALL_DATA_SEL equ $-gdt0 ; 4meg data segment descriptor -.Entry3: dw 0x03ff +.Entry3: dw 0xFFFF dw 0x0 ; base db 0x0 ; base db 0x92 ; present, ring 0, data, expand-up, writable - db 0xcf ; 4k pages, 32 bit + db 0xCF ; 4k pages, 32 bit 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 - dw 0x0 ; base - db 0x0 ; base - db 0x9A ; present, ring 0, code, non-conforming, readable - db 0x00 ; 16 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 +.Entry4: dw 0xffff dw 0x0 ; base db 0x0 ; base db 0x9A ; present, ring 0, code, non-conforming, readable - db 0xcf ; 4k pages, 32 bit + db 0xCF ; 4k pages, 32 bit db 0 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 +%include "pe.h" + diff --git a/boot/pe.h b/boot/pe.h index a44cf1b..9d68f4f 100644 --- a/boot/pe.h +++ b/boot/pe.h @@ -1,81 +1,81 @@ -struc mzheader -.magic resb 2;"MZ" -.cblp resw 1 -.cp resw 1 -.crlc resw 1 -.cparhdr resw 1 -.minalloc resw 1 -.maxalloc resw 1 -.ss resw 1 -.sp resw 1 -.csum resw 1 -.ip resw 1 -.cs resw 1 -.lfarlc resw 1 -.ovno resw 1 -.res resw 4 -.oemid resw 1 -.oeminfo resw 1 -.res2 resw 10 -.lfanew resd 1 -.end equ $ -endstruc - -struc peheader -.Signature resd 1 -.Machine resw 1 -.NumberOfSections resw 1 -.TimeDateStamp resd 1 -.PointerToSymbolTable resd 1 -.NumberOfSymbols resd 1 -.SizeOfOptionalHeader resw 1 -.Characteristics resw 1 -.Magic resw 1 -.MajorLinkerVersion resb 1 -.MinorLinkerVersion resb 1 -.SizeOfCode resd 1 -.SizeOfInitializedData resd 1 -.SizeOfUninitialzedData resd 1 -.AddressOfEntryPoint resd 1 -.BaseOfCode resd 1 -.BaseOfData resd 1 -.ImageBase resd 1 -.SectionAlignment resd 1 -.FileAlignment resd 1 -.MajorOperSystemVersion resw 1 -.MinorOperSystemVersion resw 1 -.MajorImageVersion resw 1 -.MinorImageVersion resw 1 -.MajorSubsystemVersion resw 1 -.MinorSubsystemVersion resw 1 -.Reserved1 resd 1 -.SizeOfImage resd 1 -.SizeOfHeaders resd 1 -.CheckSum resd 1 -.Subsystem resw 1 -.DllCharacteristics resw 1 -.SizeOfStackReserve resd 1 -.SizeOfStackCommit resd 1 -.SizeOfHeapReserve resd 1 -.SizeOfHeapCommit resd 1 -.LoaderFlags resd 1 -.NumberOfRvaAndSizes resd 1 -.export resd 2 -.import resd 2 -.misc_sectionz resd 28 -.end equ $ -endstruc - -struc sections -.SectionName resb 8 -.VirtualSize resd 1 -.VirtualAddress resd 1 -.SizeOfRawData resd 1 -.PointerToRawData resd 1 -.PointerToRelocations resd 1 -.PointerToLinenumbers resd 1 -.NumberOfRelocations resw 1 -.NumberOfLinenumbers resw 1 -.Characteristics resd 1 -.end equ $ -endstruc +struc mzheader +.magic resb 2;"MZ" +.cblp resw 1 +.cp resw 1 +.crlc resw 1 +.cparhdr resw 1 +.minalloc resw 1 +.maxalloc resw 1 +.ss resw 1 +.sp resw 1 +.csum resw 1 +.ip resw 1 +.cs resw 1 +.lfarlc resw 1 +.ovno resw 1 +.res resw 4 +.oemid resw 1 +.oeminfo resw 1 +.res2 resw 10 +.lfanew resd 1 +.end equ $ +endstruc + +struc peheader +.Signature resd 1 +.Machine resw 1 +.NumberOfSections resw 1 +.TimeDateStamp resd 1 +.PointerToSymbolTable resd 1 +.NumberOfSymbols resd 1 +.SizeOfOptionalHeader resw 1 +.Characteristics resw 1 +.Magic resw 1 +.MajorLinkerVersion resb 1 +.MinorLinkerVersion resb 1 +.SizeOfCode resd 1 +.SizeOfInitializedData resd 1 +.SizeOfUninitialzedData resd 1 +.AddressOfEntryPoint resd 1 +.BaseOfCode resd 1 +.BaseOfData resd 1 +.ImageBase resd 1 +.SectionAlignment resd 1 +.FileAlignment resd 1 +.MajorOperSystemVersion resw 1 +.MinorOperSystemVersion resw 1 +.MajorImageVersion resw 1 +.MinorImageVersion resw 1 +.MajorSubsystemVersion resw 1 +.MinorSubsystemVersion resw 1 +.Reserved1 resd 1 +.SizeOfImage resd 1 +.SizeOfHeaders resd 1 +.CheckSum resd 1 +.Subsystem resw 1 +.DllCharacteristics resw 1 +.SizeOfStackReserve resd 1 +.SizeOfStackCommit resd 1 +.SizeOfHeapReserve resd 1 +.SizeOfHeapCommit resd 1 +.LoaderFlags resd 1 +.NumberOfRvaAndSizes resd 1 +.export resd 2 +.import resd 2 +.misc_sectionz resd 28 +.end equ $ +endstruc + +struc sections +.SectionName resb 8 +.VirtualSize resd 1 +.VirtualAddress resd 1 +.SizeOfRawData resd 1 +.PointerToRawData resd 1 +.PointerToRelocations resd 1 +.PointerToLinenumbers resd 1 +.NumberOfRelocations resw 1 +.NumberOfLinenumbers resw 1 +.Characteristics resd 1 +.end equ $ +endstruc