[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)