;
; 功能:清除屏幕,检测处理器是否支持64位模式;若支持,加载内核,设置临时4级页表,并开启IA32E模式
; Author:fengchen Xie
; Time:2022-04-20
;
%include "asm/common/boot_loader_equ.asm"
[bits 32]
org 0x7e00
section loader align=4
;清除屏幕
call clear_screen
;获取处理器支持的最大功能号,判断处理器是否支持IA32E模式
mov eax,0x80000000
cpuid
cmp eax,0x80000000
jle not_support_ia32e ;不支持则打印信息
mov eax,0x80000001
cpuid
bt edx,29
jnc not_support_ia32e ;不支持则打印信息
;读取loader64位程序部分,加载到0x100000处
mov ecx,LOADER2_ALL_SECTORS
mov eax,LOADER2_START_SECTOR
mov ebx,LOADER2_CACHE_ADDRESS
read_loader2:
call read_one_sector
add ebx,512
inc eax
loop read_loader2
;设置临时4级头表 、临时页目录指针表、临时页目录表
mov ebx,FOUR_PAGE_ADDRESS
mov ecx,1024*3
mov edi,0x00
.clear_tmp_page_space: ;清理4级头表、临时页目录指针表、临时页目录表所需空间
mov dword [ebx+edi*4],0x00
inc edi
loop .clear_tmp_page_space
mov eax,THRER_PAGE_ADDRESS_FIRST | 3
mov [FOUR_PAGE_ADDRESS+0x00],eax
mov dword [FOUR_PAGE_ADDRESS+0x04],0x00 ;将4级头表第一项指向临时页目录指针表
mov eax,TWO_PAGE_ADDRESS_FIRST | 3
mov [THRER_PAGE_ADDRESS_FIRST+0x00],eax
mov dword [THRER_PAGE_ADDRESS_FIRST+0x04],0x00 ;将临时页目录指针表的第一项指向临时页目录表
xor eax,eax
or eax,0x83
mov ebx,TWO_PAGE_ADDRESS_FIRST
mov ecx,5
shoot_ten_m:
mov dword [ebx+0x00],eax
mov dword [ebx+0x04],0x00 ;映射低端10M内存
add eax,0x200000
add ebx,8
loop shoot_ten_m
;将4级头表物理地址写入cr3
mov eax,FOUR_PAGE_ADDRESS
mov cr3,eax
;开启PAE物理地址扩展功能
mov eax,cr4
bts eax,5
mov cr4,eax
;设置型号专属寄存器IA32_EFER的IA32E模式允许位(第8位)
mov ecx,0xc0000080 ;IA32_EFER寄存器编号
rdmsr
bts eax,8
wrmsr
;开启分页功能,进入IA32E模式的兼容模式
mov eax,cr0
bts eax,31
mov cr0,eax
push dword 0x18
push dword LOADER2_CACHE_ADDRESS
retf ;使用retf进行远跳转,跳转到loader64位代码
;-----------------------------当检测到处理器不支持ia32e模式时,提示not support ia32e ----------------
not_support_ia32e:
mov ebx,0xb8000
mov esi,0x00
mov edi,0x00
mov eax,0x0700
.print_error:
mov al,[not_support_msg+edi]
cmp al,0x00
je .stop_print
mov word [ebx+esi*2],ax
inc edi
inc esi
loop .print_error
.stop_print:
cli
hlt
jmp $
;-----------------------------------------------清除屏幕例程---------------------------------------
clear_screen:
push eax
push ebx
push ecx
push edx
xor esi,esi
mov ebx,0xb8000
mov ecx,80*25
.clear:
mov word [ebx+esi*2],0x00
inc esi
loop .clear
pop edx
pop ecx
pop ebx
pop eax
ret
%include "asm/common/LBA28.asm"
;----------------------------------------------下面是存放数据的区域------------------------------
section data
;不支持ia32e模式提示消息
not_support_msg:
db "cpu does not support IA-32E"