Tvùrce webu je i pro tebe! Postav tøeba web. Bez grafika. Bez kodéra. Hned.
wz

INIT_32.ASM

Initialization, Protected Mode


; =============================================================================
;
;                    Litos - Initialization, protected mode
;
; =============================================================================

		CODE_SECTION	32

; -----------------------------------------------------------------------------
;               Initialization 2 (jump here from INIT\INIT.ASM)
; -----------------------------------------------------------------------------

; ------------- Initialize data selectors

Start32:	mov	eax,SYSTEM_DS	; EAX <- data selector
		mov	ds,eax		; DS <- data selector
		mov	es,eax		; ES <- data selector
		mov	fs,eax		; FS <- data selector
		mov	gs,eax		; GS <- data selector

; ------------- Initialize stack (setting SS temporary disables interrupts)

		mov	ss,eax		; SS <- data selector (disables int.)
		mov	esp,BootSystemStack-SYSTEM_ADDR ; ESP <- end of stack

; ------------- One more check A20 gate (now in protected mode)

		mov	esi,CheckA20Addr-SYSTEM_ADDR ; ESI <- 0 MB
		mov	edi,CheckA20Addr-SYSTEM_ADDR+100000h ; EDI <- 1 MB
		mov	eax,0fa5025afh	; EAX <- test value 1
		mov	ebx,eax		; EBX <- test value 1
		not	ebx		; EBX <- test value 2
CheckA20:	mov	[esi],eax	; store test value 1 into 0 MB
		mov	[edi],ebx	; store test value 2 into 1 MB
		cmp	eax,[esi]	; check test value 1
		jne	CheckA20	; invalid check value 1
		cmp	ebx,[edi]	; check test value 2
		jne	CheckA20	; wait for A20 is enabled

; ------------- Initialize flags

		xor	eax,eax		; EAX <- 0
		push	eax		; push EAX (=0)
		popf			; clear all flags

; ------------- Initialize page tables

		call	InitPDE		; initialize page tables

; ------------- Enable paging

		mov	edx,PageDir-SYSTEM_ADDR ; EDX <- page directory
		mov	cr3,edx		; CR3 <- set page directory register
		mov	eax,cr0		; EAX <- CR0 (control register)
		or	eax,B31		; set PG (Paging Enable) bit on
		mov	cr0,eax		; CR0 <- enable paging

; ------------- Flush instruction queue and jump to kernel copy at high RAM

		jmp	SYSTEM_CS:FlushInsPage ; flush instruction queue

; ------------- Reinitialize stack into copy of the kernel in high RAM

FlushInsPage:	mov	eax,SYSTEM_DS	; EAX <- data selector
		mov	ss,eax		; SS <- data selector (disables int.)
		mov	esp,BootSystemStack ; ESP <- end of stack

; ------------- Load system global descriptor table

		mov	esi,BootGDTTab	; ESI <- pattern of SystemGDTTab
		mov	edi,SystemGDTTab ; EDI <- system GDT table
		mov	ecx,BOOT_GDT_NUM*GLDT_size/4 ; size of GDT pattern
		rep	movsd		; copy pattern of GDT table
		lgdt	[SystemGDT]	; load system global descriptor table

; ------------- Flush instruction queue and load new CS

		jmp	SYSTEM_CS:FlushInsCS ; flush instruction queue

; ------------- Reload all selectors

FlushInsCS:	mov	eax,SYSTEM_DS	; EAX <- system data selector
		mov	ss,eax		; SS <- data selector
		mov	eax,USER_DS	; EAX <- user data selector
		mov	ds,eax		; DS <- user data selector
		mov	es,eax		; ES <- user data selector
		xor	eax,eax		; EAX <- 0
		mov	fs,eax		; FS <- NULL selector
		mov	gs,eax		; GS <- NULL selector
		lldt	ax		; clear local descriptor

; ------------- Uninitialize bottom part of memory

		mov	edi,PageDir	; EDI <- page directory
		mov	eax,(PageEmpty-SYSTEM_ADDR)+PE_PRESENT; EAX <- invalid
		mov	ecx,SYSTEM_ADDR/4096/1024 ; number of pages
		rep	stosd		; uninitialize bottom part of directory
		mov	edx,PageDir-SYSTEM_ADDR ; EDX <- page directory
		mov	cr3,edx		; CR3 <- reload page directory register

; ------------- Detect and init CPU

		call	InitCPU		; detect and init CPU

; ------------- Initialize math coprocessor

		call	InitFPU		; initialize math coprocessor

; ------------- Initialize CPU frequency

		call	InitCPUFreq	; initialize CPU frequency

; ------------- Initialize system interrupt table (KERNEL\TRAPS.ASM)

		call	InitIDT		; initialize system interrupt table

; ------------- Start kernel (-> INIT\INIT_SYS.ASM)

		jmp	StartKernel	; start kernel

; -----------------------------------------------------------------------------
;                         Initialize page tables
; -----------------------------------------------------------------------------

; ------------- Prepare registers

InitPDE:	mov	eax,PE_INIT	; EAX <- address 0 + flags (P+R/W+U/S)
		mov	bl,B0		; page mask
		mov	edx,PageDir-SYSTEM_ADDR ; page directory
		mov	esi,PageMemMap-SYSTEM_ADDR+SYSTEM_SIZE/PAGE_SIZE/8
		mov	edi,SYSTEM_SIZE	; end of memory

; ------------- Index of page for correction of Intel Pentium F00F bug
; Instructions F0 0F C7 C8 .. F0 0F C7 CF (=LOCK CMPXCHG8B EAX..) should
; generate exception as ilegal instruction, LOCK prefix not used on memory
; operand should generate exception too, in such case CPU freezes.
;
; Solution: Align IDT table such that it spans a 4 KB page boundary
; by placing first entry starting 56 bytes from the end of the first 4 KB
; page. This places the first seven entries (0-6) on the first 4 KB
; page and the reamining entries on the second page. Mark the first 4 KB
; page as non-cacheable (PTE.PCD=1 or PTE.PWT=1).

		mov	ebp,SystemIDTTab-SYSTEM_ADDR ; EBP <- system IDT table
		and	ebp,PAGE_MASK	; EBP <- page address with IDT table
		or	ebp,eax		; EBP <- PTE entry

; ------------- Get next page entry

InitPDE2:	sub	edi,PAGE_SIZE	; shift address of page
		shr	bl,1		; shift bit mask
		jnc	InitPDE6	; no overflow
		dec	esi		; shift address in bit map
		mov	bl,B7		; new bit mask
InitPDE6:	test	[esi],bl	; is this page available?
		jz	InitPDE2	; this page is not available
		xor	[esi],bl	; clear page flag

; ------------- Store address of PTE into page directory

		lea	ecx,[edi+PE_INIT] ; ECX <- PTE + flags
		mov	[edx],ecx	; store address of page + flags
		mov	[edx+SYSTEM_ADDR/PAGE_SIZE/1024*PDE_size],ecx
		add	edx,byte PDE_size ; address of next page directory

; ------------- Initialize PTE

		mov	ecx,PAGE_SIZE/PTE_size ; ECX <- number of entries
		push	edi		; push EDI
InitPDE8:	stosd			; store address of memory
                cmp	eax,ebp		; is it first page with IDT table?
		jne	InitPDE9	; it is not page with IDT table
		or	byte [edi-4],PE_PCD ; disable page cache
InitPDE9:	add	eax,PAGE_SIZE	; address of next page
		loop	InitPDE8	; next page entry
		pop	edi		; pop EDI

; ------------- Check page address

		cmp	eax,[MemoryMax-SYSTEM_ADDR] ; check end of memory
		jb	InitPDE2	; init next page
		ret

; -----------------------------------------------------------------------------
;                                   Data
; -----------------------------------------------------------------------------

		DATA_SECTION

; ------------- System global descriptor table

		align	4, db 0
		dw	0		; align
SystemGDT:	dw	SystemGDTTabEnd-SystemGDTTab-1 ; GDT size limit
		dd	SystemGDTTab	; GDT base address

; -----------------------------------------------------------------------------
;                            Uninitialized data
; -----------------------------------------------------------------------------

		BSS_SECTION

		align	4, resb 1
CheckA20Addr:	resd	1		; checked A20 address

Back to source browser