Intel架构实模式,保护模式,64位模式,64位兼容模式 来回切换

Intel架构实模式,保护模式,64位模式,64位兼容模式 来回切换_第1张图片

# we can boot from BOOTLOADER function logic_boot_emmc_init()
# please make sure paging is disabled
# before enter into sbft_call

.text
.section REALMODE_CODE, "ax"

.code32

##########################################
#
# Save original BOOTLOADER execution environment
#
##########################################
.globl sbft_call
sbft_call:
	cld
	push   %fs
	push   %es
	push   %ds
	push   %eax
	push   %ebp
	push   %edi
	push   %esi
	push   %edx
	push   %ecx
	push   %ebx

	# backup BOOTLOADER stack point
	movl   %esp, (psi_esp)

	# fill up SBFT return address(64bit address)
	movl   $x64_mode, (0x1F08)
	movl   $0, (0x1F0C)

	# ebp is IRAM data base
	movl    44(%esp), %ebp
	# esi:edi is set to SBFT RM entry address
	movl    48(%esp), %esi
	movl    52(%esp), %edi
	movw    %di, (sbft_addr)
	movw    %si, (sbft_addr+4)

	# ready to switch to real mode
	cli
	# disable paging
	movl   %cr0, %eax
	andl   $(0x7FFFFFFF), %eax
	movl   %eax, %cr0
	# flush TLB
	xorl   %eax, %eax
	movl   %eax, %cr3

	# load real mode IDT
	lidtl  real_mode_idt

	# load real mode GDT
	lgdtl  real_mode_gdt

	# load segment
	movw   $0x10, %ax
	movw   %ax, %ds
	movw   %ax, %ss
	movw   %ax, %es

	# jump 16bit protected mode
	ljmpw  $8, $real_mode
	nop

#############################################
#
# Recovery original BOOTLOADER execution environment
#
#############################################

psi_recovery:
	pop    %ebx
	pop    %ecx
	pop    %edx
	pop    %esi
	pop    %edi
	pop    %ebp
	pop    %eax
	pop    %ds
	pop    %es
	pop    %fs

	# fetch SBFT result
	movl   (0x1F04), %eax

	ret
	nop
##########################################
#
# 16 bit Real mode
#
##########################################
.code16
.balign 16
real_mode:
	# switch to real mode
	movl   %cr0, %eax
	andl   $(0xFFFFFFFE), %eax
	movl   %eax, %cr0
	# far jump
	.byte 0xEA
	.word 5f, 0

5:
	# setup real mode segment
	movw   %cs, %ax
	movw   %ax, %ds
	movw   %ax, %es
	movw   %ax, %ss

	# jump to SBFT entry
	# ljmpw $0x0000, $0x2700
	ljmpw *(sbft_addr)
	nop
##########################################
#
#  switch 64 bit IA32-e mode
#    to compatibility mode
#
##########################################
.code32
.balign 16
x64_mode:
	nop
	nop
	# switch to 32-bit data segment
	movl $0x8, %eax
	movl %eax, %ds
	movl $x64_gdt_table, %edi
	lgdtl (%edi)
	movl $0x10, %eax
	movl %eax, %ds
	movl %eax, %ss
	movl %eax, %es
	movl %eax, %fs
	movl %eax, %gs

	# 64 bit far jump simulation
	# xorq %rax, %rax (needs 64bit compiler)
	.byte 0x48
	xorl %eax, %eax
	movl $0x10, %eax
	pushl %eax
	movl %esp, %eax
	pushl %eax
	pushf
	movl $0x8, %eax
	pushl %eax
	movl $x64_compat, %eax
	pushl %eax
	# iretq (needs 64bit compiler)
	.byte 0x48
	iretl
	nop
##########################################
#
#    compatibility mode
#
##########################################
x64_compat:
	# NOW! we are in 64bit compatibility mode (32bit code)
	# disable paging, will set IA32_EFER.LMA = 0
	movl   %cr0, %eax
	andl   $0x7FFFFFFF, %eax
	movl   %eax, %cr0
	# flush TLB
	xorl   %eax, %eax
	movl   %eax, %cr3

	# set IA32_EFER.LMA = 0
	xorl %eax, %eax
	xorl %edx, %edx
	movl $0xC0000080, %ecx
	wrmsr
##########################################
#
#    32 bit protected mode
#
##########################################
x32_prot:
	# disable MTRR
	# return EDX:EAX
	movl   $0x2FF, %ecx
	rdmsr
	andl   $0xFFFFF7FF, %eax
	wrmsr
	# cache clean all
	wbinvd

	# recovery BOOTLOADER CPU mode
	# setup GDT
	call gdt_init
	# setup IDT
	call idt_init
	# setup MTRR
	call mmu_bootcore_mtrr_setup
	# enable paging
	call mmu_bootcore_paging_enable
	# recovery BOOTLOADER
	movl (psi_esp), %esp
	jmp psi_recovery
	nop

	.balign 16
sbft_addr:
	.word 0
	.word 0
	.balign 16
real_mode_idt:
	.word 0xFFFF
	.long 0

	.balign 16
real_mode_gdt:
	# GDT0
	.word 0xFFFF
	.long real_mode_gdt
	.word 0

	# GDT1 16bit code segment
	.word 0xFFFF
	.long 0x9B000000 + 0
	.word 0

	# GDT2 16bit data segment
	.word 0xFFFF
	.long 0x93000000 + 0
	.word 0

	.balign 16
x64_gdt:
	# GDT0 dummy 0x0
	.quad 0x0
	# GDT2 32bit code segment 0x8
	.quad 0x00CF9B000000FFFF
	# GDT1 32bit data segment 0x10
	.quad 0x00CF93000000FFFF
x64_gdt_end:

	.balign 16
x64_gdt_table:
	# 64 bit GDT
	.short x64_gdt_end - x64_gdt - 1
	.long x64_gdt
	.long 0

psi_esp: .long 0

 

你可能感兴趣的:(自己的操作系统)