%include "pm.inc" org 1000h jmp start sectnum dw 19 sectnum1 db 1 init_kernel_ofs dw 0000h init_kernel_seg dw 8000h FATOFS dw 0000h FATSEG dw 9000h fatnum dw 9 fatnumcount dw 1 fatentry dw 200h filename db 'KERNEL BIN' kernel_msg: db "Loading kernel" nofound_msg: db "No kernel." ready: db "Ready." ;descriptor limitl basel basem attrib baseh ; dw dw db dw db gdt: null_des: descriptor 0,0,0,0,0 code_des: descriptor 0ffffh,0,0,attrib_ce+attrib_32+atrrib_limit_4k,0 data_des: descriptor 0ffffh,0h,0h,attrib_drw+attrib_32+atrrib_limit_4k,0 video_des: descriptor 0ffffh,8000h,0bh,attrib_drw+attrib_32,0 page_dir_des: descriptor 4095,0000h,20h,attrib_drw,0 page_tbl_des: descriptor 1023,1000h,20h,attrib_drw+atrrib_limit_4k ,0h gdt_len equ $-gdt code_sel equ code_des-gdt data_sel equ data_des-gdt video_sel equ video_des-gdt page_dir_sel equ page_dir_des-gdt page_tbl_sel equ page_tbl_des-gdt page_dir_base equ 200000h ; 页目录开始地址: 2M page_tbl_base equ 201000h ; 页表开始地址: 2M + 4K base_setup_phyaddr equ 90000h ;INITSEG 9000h INITOFS 1000h base_kernel_phyaddr equ 80000h ;kernel offset kernel_entry_phyaddr equ 000400h ;kernel entry vgdtr: pdescriptor gdt_len-1,gdt+base_setup_phyaddr stack: times 1024 db 0 top_stack equ $+base_setup_phyaddr count dw 0 mem_size dd 0 mem_buffer times 512 db 0 msg db "In protect mode!",0 page_msg db "After paging!",0 check_msg db "Checked ok!",0 check1_msg db "Checked fail!",0 finish_msg db "Checked finish!",0 ram_size_msg db "Ram size:" ards: ;address range descriptor struture dd 0 ;base addr low dd 0 ;base addr high dd 0 ;length low dd 0 ;length high dd 0 ;type offset_msg equ msg+base_setup_phyaddr offset_page_msg equ page_msg+base_setup_phyaddr offset_count equ count+base_setup_phyaddr offset_mem_buffer equ mem_buffer+base_setup_phyaddr offset_check_msg equ check_msg+base_setup_phyaddr offset_check1_msg equ check1_msg+base_setup_phyaddr offset_finish_msg equ finish_msg+base_setup_phyaddr offset_ards equ ards+base_setup_phyaddr offset_mem_size equ mem_size+base_setup_phyaddr offset_ram_size_msg equ ram_size_msg+base_setup_phyaddr start: mov ax, cs mov ds, ax mov es, ax mov ss, ax mov sp, ax xor ax,ax call read_mem_info ;放前面,奇怪放后面就不行了 xor ah, ah xor dl, dl int 13h call load_kernel call kill_motor lgdt [vgdtr] cli call enable_a20 mov eax,cr0 or eax,1 mov cr0,eax jmp dword code_sel:base_setup_phyaddr+virtual enable_a20: push ax in al,92h or al,2 out 92h,al pop ax ret disable_a20: push ax in al,92h and al,0fdh out 92h,al pop ax ret read_mem_info: mov di,mem_buffer mov ebx,0 rl: mov eax,0E820h mov ecx,20 mov edx,534D4150h int 15h jc faile add di,20 inc word [count] cmp ebx,0 jne rl jmp ok faile: mov word [mem_size],0 jmp finish ok: finish: ret load_kernel: push ax push bx push cx push si push di mov cx,14 mov si,kernel_msg call print16_string nof: mov ax,[sectnum] ;mov ax,21 cmp ax,32 ja fail mov di,[FATOFS] push ax mov ax,[FATSEG] mov es,ax pop ax call read_sect call search_file inc word [sectnum] cmp ax,-1 je nof ;ax=file first sector fatread: push ax mov es,[init_kernel_seg] mov di,[init_kernel_ofs] add ax,31 call read_sect pop ax add word[init_kernel_ofs],200h mov bx,[init_kernel_ofs] push ax mov al,'.' call print16_char pop ax call get_entry cmp ax,0ff8h jae fatreadend jmp fatread fatreadend: call print16_newline push si mov cx,6 mov si,ready call print16_string pop si jmp o fail: call print16_newline mov cx,10 mov si,nofound_msg call print16_string o: pop di pop si pop cx pop bx pop ax ret kill_motor: push ax push dx mov dx,03f2h mov al,0 out dx,al pop dx pop ax ret ;es: di=地址 ds: si=filename ax->起始扇区号 ax=-1 没找到 search_file: push bx push cx push si cld mov bx,di goon: mov di,bx and di,0ffe0h mov si,filename mov cx,11 repz cmpsb cmp cx,0 jz find add bx,32 cmp bx,200h ;FATOFS+512byte one sector jae nofind jmp goon find: ;print add di,15 mov ax,[es:di] ;add ax,31 jmp endserch nofind: mov ax,-1 endserch: pop si pop cx pop bx ret ;sectornum/18 ch=Q>>1 cl=R+1 dh=Q&1 ;ax=扇区号,sectnum1=扇区数 es:di=mem addr read_sect: push ax push bx push cx push dx push di mov bh,18 div bh mov ch,al shr ch,1 and al,1 mov dh,al inc ah mov cl,ah mov dl,00h mov bx,di readagine: ;mov bx,[init_kernel_ofs] ;mov es,[init_kernel_seg] mov ah,02h mov al,1 int 13h jc readagine pop di pop dx pop cx pop bx pop ax ret ;ax=sector es:di=fat men addr get_entry: push bx push cx push dx push es push di mov bx,3 mul bx mov bx,2 div bx a: cmp ax,[fatentry] ;first time=200h jbe next mov es,[FATSEG] mov di,[FATOFS] push ax mov ax,[fatnumcount] cmp ax,9 ja endread ;fat 9 项 call read_sect pop ax inc word[fatnumcount] add word[fatentry],200h ;200h jmp a next: push ax mov es,[FATSEG] mov di,[FATOFS] mov ax,[fatnumcount] call read_sect pop ax add ax,200h sub ax,[fatentry] add di,ax mov ax,[es:di] cmp dx,0 je even1 mov cl,4 shr ax,cl jmp endread even1: and ax,0fffh endread: ;int 3h pop di pop es pop dx pop cx pop bx ret print16_newline: push ax mov al,0dh call print16_char mov al,0ah call print16_char pop ax ret ;al char print16_char: push ax push bx mov ah, 0eh ;mov al, '.' mov bx,000ch int 10h pop bx pop ax ret ;si addr ,cx count ,dh row ,dl col print16_string: push ax ps16: mov al,[si] call print16_char inc si loop ps16 pend16: pop ax ret ;-----------------------------------protect bits 32 virtual: mov ax,data_sel mov ds,ax mov ss,ax mov es,ax mov fs,ax mov ax,video_sel mov gs, ax mov esp,0ff00h xor esi,esi mov dx,0400h mov cx,16 mov esi,offset_msg call print_string call print_newline mov cx,14 mov esi,offset_finish_msg call print_string call print_newline mov cx,14 mov esi,offset_check_msg call print_string call print_newline mov bx,[offset_count] call print_bx call print_newline ;call init8259a call dump_mem call print_newline call setup_paging mov cx,13 mov esi,offset_page_msg call print_string call mov_kernel jmp code_sel:kernel_entry_phyaddr mov_kernel: push eax push ecx push edx push esi xor eax,eax mov ax,[80000h+2ch] ;elf_heder ->e_phnum mov esi,[80000h+1ch] ;elf_header->e_phoff add esi,80000h coniue: mov edx,[esi] ;p_type cmp edx,0 jz noload push eax push esi mov ecx,[esi+16] ;p_filesz size mov edi,[esi+8] ;p_vaddr des mov esi,[esi+4] ;p_offset src add esi,base_kernel_phyaddr ;call mem_cpy cpy2: cmp ecx,0 jle cpy1 mov eax,[esi] mov [edi],eax add edi,4 add esi,4 sub ecx,4 jmp cpy2 cpy1: pop esi pop eax noload: add esi,020h dec eax jnz coniue pop esi pop edx pop ecx pop eax ret ;es:edi des ,ds:esi src ,ecx size mem_cpy: cpy12: cmp ecx,0 jle cpy11 mov eax,[esi] mov [edi],eax add edi,4 add esi,4 sub ecx,4 jmp cpy12 cpy11: ret setup_paging: push edx xor edx,edx mov eax,[offset_mem_size] mov ebx,1024*4096 div ebx ;edx remainder eax test edx,edx jz no_remainder inc eax no_remainder: mov ecx,eax push eax mov ax,page_dir_sel mov es,ax mov ecx,1024 xor edi,edi xor eax,eax mov eax,page_tbl_base|page_p|page_usu|page_rww s1: stosd add eax,4096 loop s1 mov ax,page_tbl_sel mov es,ax pop eax ;mov ecx,1024*1024 mov ebx,1024 mul ebx mov ecx,eax xor edi,edi xor eax,eax mov eax,page_p|page_usu|page_rww s2: stosd add eax,4096 loop s2 mov eax,page_dir_base mov cr3,eax mov eax,cr0 or eax,80000000h mov cr0,eax jmp short .3 .3: nop pop edx ret init8259a: mov al,011h ;master icw1 out 20h,al call io_delay out 0a0h,al ;slaver icw1 call io_delay mov al,020h ;irq0 0x20 out 21h,al ;master icw2 call io_delay mov al,028h ;irq8 0x28 out 0a1h,al ;slaver icw2 call io_delay mov al,004h ;ir2 out 021h,al ;master icw3 call io_delay mov al,002h ;ir2 out 0a1h,al call io_delay mov al,01h out 021h,al ;master icw4 call io_delay ;mov al, 11111110b ; 仅仅开启定时器中断 mov al,0ffh ;ocw1 out 021h,al call io_delay mov al,0ffh ;owc1 out 0a1h,al call io_delay ret io_delay: nop nop nop nop nop nop ret ;bx print_bx: rol bx,8 call print_bl rol bx,8 call print_bl ret print_ebx: push cx mov cl,4 ee: rol ebx,8 call print_bl add dl,2 loop ee pop cx ret ;bl print_bl: push ax push cx push dx mov ax,dx mov ch,2 l22: mov cl,4 rol bl,cl mov dl,bl and dl,0fh add dl,30h cmp dl,39h jbe l11 add dl,7 l11: push ax mov ah,al mov al,dl mov dl,ah call print_char pop ax inc al dec ch jnz l22 mov dx,ax pop dx pop cx pop ax ret ;dh,dl row,col print_newline: xor dl,dl inc dh ret ;al char ,gs video_sel ,dh row,dl col print_char: push eax push ebx push ecx push edi xor ebx,ebx xor ecx,ecx mov bl,dh mov cl,dh shl ebx,6 shl ecx,4 add ebx,ecx xor ecx,ecx mov cl,dl add ebx,ecx shl ebx,1 mov edi,ebx mov ah, 07h mov [gs:edi],ax pop edi pop ecx pop ebx pop eax ret ;esi addr ,cx count ,dh row ,dl col print_string: push ax ps: mov al,[esi] call print_char inc dl inc esi loop ps pend: pop ax ret dump_mem: ;display mem info push esi push ebx push ecx mov esi,offset_mem_buffer mov cx,[offset_count] du: mov ebx,[esi+4] call print_ebx inc dl mov ebx,[esi] call print_ebx inc dl mov ebx,[esi+12] call print_ebx inc dl mov ebx,[esi+8] call print_ebx inc dl mov ebx,[esi+16] call print_ebx call print_newline cmp ebx,1 jne du1 push edx mov edx,[esi] add edx,[esi+8] cmp edx,[offset_mem_size] jb ld mov [offset_mem_size],edx mov edx,[esi] mov [offset_ards],edx mov edx,[esi+4] mov [offset_ards+4],edx mov edx,[esi+8] mov [offset_ards+8],edx mov edx,[esi+12] mov [offset_ards+12],edx mov edx,[esi+16] mov [offset_ards+16],edx ld: pop edx du1: add esi,20 dec cx jnz du call print_newline mov cx,5 mov esi,offset_ards du2: mov ebx,[esi] call print_ebx inc dl add esi,4 loop du2 inc dl call print_newline mov cx,9 mov esi,offset_ram_size_msg call print_string mov ebx,[offset_mem_size] call print_ebx pop ecx pop ebx pop esi ret ;初始化进入保护模式,检测内存,并分页,加载内核,跳转到kernel.bin执行kernel是elf格式的。