ospre 0.1.6

这是一个用于开发64位操作系统的前置工具,用于做boot、loader等工作。它需要你安装nasm编译器才能使用,使用方式请看文档
Documentation
;
; 功能:清除屏幕,检测处理器是否支持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"