%include "asm.inc" %define STUB_STAT _stub_stat BITS 32 GLOBAL entry_point GLOBAL __exit GLOBAL __fpu_family GLOBAL __cpu_family GLOBAL __cpu_model GLOBAL __cpu_steppingID GLOBAL __cpu_feature GLOBAL __cpu_vendor GLOBAL __cr4 EXTERN _start EXTERN STUB_STAT EXTERN end_datas EXTERN end_bsss SECTION .data temp dw 0 __fpu_family db 0 __cpu_family db 3 __cpu_model db 0 __cpu_steppingID db 0 __cpu_feature dd 0 __cpu_vendor_ db 'unknown',0,0,0,0,0,0 __cpu_vendor dd __cpu_vendor_ __cr4 dd 0 saved_ss_esp dd 0 dw 0 saved_gdt dw 0 dd 0 SECTION .text ; ; questo e` l'indirizzo che viene chiamato dal loader. ; la paginazione e` gia` attiva, occhio pero` che per risparmiare ; memoria ho messo il pde e i pte nella memoria video :) ; ; secondo il draft del 10/09/197 il kernel dovrebbe essere caricato ; a 512Mb, e la memoria kernel e` riservata fino a 1Gb. ; quindi ci sono 512Mb di spazio per il kernel, dovrebbero essere ; sufficiente per tutti ... [come disse l'amico Bill per i 640K del dos] ; ; la versione 0.6 dello stub comunque mappa solo i primi 4Mb a partire ; dall'indirizzo virtuale base del kernel, e poi mappa il primo Mb 1:1. ; ; ; i selettori sono : ; 30h punta allo stub (256 bytes) ; 38h dati (limite 4G) ; 40h codice (4G) ; 48h TSS _TEMPORANEO_ (non deve essere + richiamato!) ; ; DS = ES = SS = dati [30h] ; FS = stub selector GS = ? ; ; TR=48h, ldt=0, idt=0 ; ; esp = stack dello stub, poco meno di 1K disponibile ... magari usero` ; un po' di memoria video anche per questo :) ; ; tutti i flags sono stati azzerati (DF,IF,..) ; ;----- ; la versione 0.61 dello stub mappa i primi 12Mb di memoria fisica, e 4 kernel ; inoltre l'indirizzo del kernel e` cambiato, ora e` 3Gb, la memoria da ; 1Gb fino a 3Gb e` disponibile. la memoria < 1Gb e` riservata per altri scopi entry_point: ; ; salva lo stack ; mov dword [saved_ss_esp],esp mov word [saved_ss_esp+4],ss ; ; salva gdt ; sgdt [saved_gdt] ; ; azzera bss ; mov edi,end_datas mov ecx,end_bsss xor eax,eax sub ecx,edi rep stosb ; ; copia stub_stat ; xor esi,esi cmp word [fs:esi],'V0' ; confronta magic (versione) mov al,0xff jne __exit mov cx,[fs:esi+2] ; legge dimensione da trasferire add esi,4 mov edi,STUB_STAT .copy mov al,[fs:esi] inc esi mov [edi],al inc edi loop .copy,cx mov fs,cx ; azzera fs e gs mov gs,cx call cpu_info call fpu_info cmp byte [__fpu_family],0 setne al or byte [__cpu_feature],al call set_cr mov bx,0xF8F0 mov cl,3 call pic_setup call _start __exit: ; eax = exit cli mov ebp,eax mov bx,0x7008 mov cl,1 call pic_setup mov bx,KERNEL_DS mov ds,bx ; cmp dword [__cr4],0 ; je .nocr4 ; xor ebx,ebx ; mov cr4,ebx .nocr4 lgdt [saved_gdt] ; DS deve sempre essere 30h !! lss esp, [saved_ss_esp] mov eax,ebp retf ; ; in: copia il bit %1 di edx alla posizione %2 in ebx ; ; %macro testbt 2 xor ecx,ecx bt edx,%1 rcl ecx,%2+1 or ebx,ecx %endm set_cr: ; ; setup per cr4 (registro ebx) ; mov edx,[__cpu_feature] xor ebx,ebx testbt 1,0 ; VM86 Mode Ex testbt 1,1 ; PVI testbt 2,3 ; Debug Extension testbt 3,4 ; Page Size extension testbt 13,7 ; Page Global test ebx,ebx jz .nocr4 mov cr4,ebx mov [__cr4],ebx .nocr4 ; ; setup per cr0 ; mov ebx,0x80000001 testbt 0,1 cmp byte [__cpu_family],4 jb .end je .486 or ebx,50020h ; AM WP NE .486 or ebx,50000h ; AM WP .end mov cr0,ebx ret cpu_info: pushfd pop eax mov eax,ecx xor eax,0x40000 push eax popfd pushfd pop eax xor eax,ecx and eax,0x40000 jz .end mov byte [__cpu_family],4 ; 486 mov eax,ecx xor eax,0x200000 push eax popfd pushfd pop eax xor eax,ecx jz .end push ecx ; 486DX4/Pentium+ popfd xor eax,eax cpuid mov [__cpu_vendor_],ebx mov [__cpu_vendor_+4],edx mov [__cpu_vendor_+8],ecx test eax,eax jz .end mov eax,1 cpuid mov cl,al and cl,0x0f mov [__cpu_steppingID],al shr al,4 mov [__cpu_model],al mov cl,ah and cl,0x0f mov [__cpu_family],cl mov [__cpu_feature],edx .end ret fpu_info: clts fninit mov word [temp],0x5a5a fstsw [temp] mov ax,[temp] cmp al,0 jnz .end mov byte [__fpu_family],2 mov eax,cr0 shr eax,5 jnc .end inc byte [__fpu_family] .end ret ; ; BL = PIC #1 vect ; BH = PIC #2 vect ; CL = 1 -> standard, 3 -> auto EOI %macro delay 0 dw 00ebh dw 00ebh %endm pic_setup: mov al,0x11 ;init command out 0x20,al delay out 0xa0,al mov ax,bx ; set vector out 0x21,al xchg al,ah delay out 0xa1,al mov al,4 out 0x21,al ; irq 2 = cascade mov al,2 delay out 0xa1,al ; irq 9 ->irq2 mov al,cl ; mode control, 1 = standard, 3 auto EOI out 0x21,al delay out 0xa1,al ; ; keyboard reset ; delay in al,60h delay or al,80h out 60h,al delay and al,7fh out 60h,al ret