[BITS 16]
[ORG 0x7c00] ;Chargement du bootloader en 0x00007c00
%define NbSecteur 40 ;Nombre de secteur du kernel (1secteur = 512o)
%define AdresseBase 0x100 ;Adresse mémoire où notre kernel sera chargé
start:
;On recupere l'id du peripherique du boot
mov [bootPeriphId], dl
;Remise à 0 des registres utilisés
xor ax, ax
xor sp, sp
xor si, si
xor bp, bp
;Segment de données
mov ds, ax
;Segment de pile
mov ax, 0x8000
mov ss, ax
;| |Adresses Hautes
;...........
;|_________| 0x8F000 = SP -> Adressage en mode reel = SS*0x10+SP = 0x80000+f000 = 0x8F000
;|Stack \/ |
;| \/ |
;|_________| 0x80000
;| |
;...........
;| |0x0
;Pointeur du haut de la stack
mov sp, 0xf000
;Pointeur du bas de la stack
mov bp, 0xf000
mov si, chargementBootloaderMsg
call printf
;Chargeons notre noyau à présent
push es
mov ax, AdresseBase
mov es, ax ;ES:BX Pointe sur la zone où le kernel va être copié
mov bx, 0
mov ah, 2 ;Read Sectors From Drive
mov al, NbSecteur ;Nombre de secteur à lire
mov ch, 0 ;
mov cl, 2 ;
mov dh, 0 ;
mov dl, [bootPeriphId]
int 0x13
pop es
;Actualisons le registre GDTR (2octets => taille de la gdt, 4octet => base de la gdt) contenant l'adresse/taille de la gdt
mov ax, debutGDT
mov bx, finGDT
sub bx, ax
mov word [gdtr], bx ;On place la taille de la gdt dans les deux premiers octets
mov eax, debutGDT
mov dword [gdtr+2], eax ;On place l'adresse de base de la gdt
lgdt [gdtr] ;On met à jour le registre gdtr
cli ;On desactive les interuptions, le systeme d'adressage va changer donc les routines appelé par les ints seront mauvaises
mov eax, cr0
or ax, 1 ;AX=XXXX OU 0001 => AX=XXX1 nous mettons à 1 le premier bits (LSB) cr0.PE
mov cr0, eax
;Initialisons nos segments selectors
mov ax, 0000000000010000b ;Segment de donnée, indice 2 dans la GDT, RPL=0
mov ds, ax
mov fs, ax
mov gs, ax
mov es, ax
mov ss, ax
mov esp, 0x8f00
mov ebp, 0x8000
; saut vers le kernel, reinitialisation du segment selectors de code (ds)
jmp dword 0000000000001000b:0 ;Segment de code, indice 1 dans la GDT, RPL=0
;------------------[V-a-r-i-a-b-l-e-s]------------------------------
chargementBootloaderMsg: db "Bootloader [OK]", 0xA, 0xD, 0
bootPeriphId: db 0
gdtr : dw 0 ;Taille
dd 0 ;Base
ldtr : dw 0
debutGDT:
segmentDescriptorNull: dd 0, 0
segmentDescriptorCodeSegmentR0: db 0x00, 0xA0, 0x00, 0x10, 0x00, 10011010b, 01010000b, 0x00
segmentDescriptorDataSegmentR0: db 0xff, 0xff, 0x00, 0x00, 0x00, 10010010b, 11011111b, 0x00
segmentDescriptorCodeSegmentR3 : db 0x00, 0x04, 0x00, 0x0A, 0x00, 11111010b, 11000000b, 0x40
;Pour test le page fault, si nous gardons le même segment descriptor nous auront une #GP(0) car nous sortons de la limit du segment
;il faut rester ds la limite du segment et en même temps avoir un "trou" de pagination
;segmentDescriptorStackSegmentR3: db 0xff, 0xff, 0x00, 0x00, 0x00, 11110010b, 01001111b, 0x40
segmentDescriptorStackSegmentR3: db 0xff, 0x09, 0x00, 0x00, 0x00, 11110010b, 01000000b, 0x40
segmentDescriptorTSS : db 0x67, 0x00, 0x00, 0x09, 0x00, 11101001b, 0x00, 0x00
segmentDescriptorTSS2 : db 0x67, 0x00, 0x00, 0x08, 0x00, 11101001b, 0x00, 0x00
segmentDescriptorSystem : db 0x00, 0x00, 0x33, 0x00, 0x00, 11100101b, 0x00, 0x00
segmentDescriptorSystem2 : db 0xff, 0xff, 0x00, 0x00, 0x00, 11111010b, 11001111b, 0x00
finGDT:
;-----------------[I-n-c-l-u-s-i-o-n-s]-----------------------------
%include "C:\Hydropon-1K\sources\fonctions.inc"
times (510-($-start)) db 0 ;Notre binaire doit faire 512 octet, on bourre en consequence
dw 0xAA55 ;Boot signature (55AA)