www.pudn.com > ucos+net.zip > Entry.asm


; Entry.asm 
; Copyright (C) 1998, Exposé Corp. All rights reserved. 
; 
; Description: 
;	This code switches the CPU into the protected mode and initializes  
;	the registers to a flat 4GB address space, where linear addresses 
;	equal physical addresses. 
; 
;	It then calls main() to run any linked C program that has been compiled  
;	to run in a 32-bit flat environment with a base address of 0. 
; 
;	This code is part of the port of uCOS (C) to the Intel 80x86 running 
;	in Protected Mode. A full description of the port can be found in  
;	Port86pm.doc 
; 
; Build Commands: 
;	This program requires Microsoft Assembler 6.11. 
; 
;	1. Execute the makefile by typing: 
;		nmake 
; 
;	- or - 
; 
;	2. Type the following command: 
;		ml /c /Fl /coff Entry 
; 
; Questions, comments and suggestions: 
;	Please send e-mail to jean.gareau@exposecorp.com 
 
		.386P				; Use 386+ privileged instructions 
 
;-----------------------------------------------------------------------------; 
; Macros (to use 32-bit instructions while in real mode)		      ; 
;-----------------------------------------------------------------------------; 
 
LGDT32		MACRO	Addr			; 32-bit LGDT Macro in 16-bit 
		DB	66h			; 32-bit operand override 
		DB	8Dh			; lea (e)bx,Addr 
		DB	1Eh 
		DD	Addr 
		DB	0Fh			; lgdt fword ptr [bx] 
		DB	01h 
		DB	17h 
ENDM 
 
LIDT32		MACRO	Addr			; 32-bit LIDT Macro in 16-bit 
		DB	66h			; 32-bit operand override 
		DB	8Dh			; lea (e)bx,Addr 
		DB	1Eh 
		DD	Addr 
		DB	0Fh			; lidt fword ptr [bx] 
		DB	01h 
		DB	1Fh 
ENDM 
 
FJMP32		MACRO	Selector,Offset		; 32-bit Far Jump Macro in 16-bit 
		DB	66h			; 32-bit operand override 
		DB	0EAh			; far jump 
		DD	Offset			; 32-bit offset 
		DW	Selector		; 16-bit selector 
ENDM 
 
		PUBLIC	EntryPoint		; The linker needs it. 
		PUBLIC	_Idt 
		PUBLIC	_Gdt 
		EXTERN	_main:NEAR 
 
_TEXT		SEGMENT PARA USE32 PUBLIC 'CODE' 
		ASSUME	CS:_TEXT, DS:_TEXT, ES:_TEXT, SS:_TEXT 
 
;		ORG	1000h			; => Depends on loader. <= 
 
;-----------------------------------------------------------------------------; 
; Entry Point. The CPU is executing in 16-bit real mode.		      ; 
;-----------------------------------------------------------------------------; 
 
EntryPoint	PROC	NEAR 
 
		LGDT32	GdtDesc			; Load GDT descriptor 
		LIDT32	IdtDesc			; Load IDT descriptor 
 
		mov	eax,cr0			; Get control register 0 
		or	ax,1			; Set PE bit (bit #0) in (e)ax 
		mov	cr0,eax			; Activate protected mode! 
		jmp	$+2			; To flush the instruction queue. 
 
; The CPU is now executing in 16-bit protected mode. Make a far jump in order to 
; load CS with a selector to a 32-bit executable code descriptor. 
 
		FJMP32	08h,EntryPoint32	; Jump to EntryPoint32 
 
; This point is never reached. 
 
EntryPoint	ENDP 
 
;-----------------------------------------------------------------------------; 
; The CPU is now executing in 32-bit protected mode.			      ; 
;-----------------------------------------------------------------------------; 
 
EntryPoint32	PROC	NEAR 
 
; Initialize all segment registers to 10h (entry #2 in the GDT) 
 
		mov	ax,10h			; entry #2 in GDT 
 		mov	ds,ax			; ds = 10h 
 		mov	es,ax			; es = 10h 
 		mov	fs,ax			; fs = 10h 
 		mov	gs,ax			; gs = 10h 
 		mov	ss,ax			; ss = 10h 
  
; Set the top of stack to allow stack operations. 
   
 		mov	esp,8000h		; arbitrary top of stack 
  
; Call main(), which is not expected to return. 
 
		call	_main 
 
; In case main() returns, enter an infinite loop. 
 
IdleLoop: 
		hlt 
		jmp	IdleLoop 
 
; This point is never reached. 
 
EntryPoint32	ENDP 
 
;-------------------------------------------------------------------------------; 
; Tables Descriptors (to use with LGDT32 & LIDT32)				; 
;-------------------------------------------------------------------------------; 
 
		ALIGN	4 
 
GdtDesc:					; GDT descriptor 
		DW	GDT_SIZE - 1		; GDT limit 
 		DD	_Gdt			; GDT base address (below) 
 
		ALIGN	4 
 
IdtDesc:					; IDT descriptor 
		DW	IDT_SIZE - 1		; IDT limit 
 		DD	_Idt			; IDT base address (below) 
 
;-------------------------------------------------------------------------------; 
; GDT										;	 
;-------------------------------------------------------------------------------; 
 
		ALIGN	4 
 
; Global Descriptor Table (GDT) 
 
_Gdt: 
  
; GDT[0]: Null entry, never used. 
      
 		DD	0 
 		DD	0 
  
; GDT[1]: Executable, read-only code, base address of 0, limit of FFFFFh,  
;	  granularity bit (G) set (making the limit 4GB) 
  
 		DW	0FFFFh			; Limit[15..0] 
 		DW	0000h			; Base[15..0] 
 		DB	00h			; Base[23..16] 
 		DB	10011010b		; P(1) DPL(00) S(1) 1 C(0) R(1) A(0) 
 		DB	11001111b		; G(1) D(1) 0 0 Limit[19..16] 
 		DB	00h			; Base[31..24] 
 		 
; GDT[2]: Writable data segment, covering the save address space than GDT[1]. 
  
 		DW	0FFFFh			; Limit[15..0] 
 		DW	0000h			; Base[15..0] 
 		DB	00h			; Base[23..16] 
 		DB	10010010b		; P(1) DPL(00) S(1) 0 E(0) W(1) A(0) 
 		DB	11001111b		; G(1) B(1) 0 0 Limit[19..16] 
 		DB	00h			; Base[31..24] 
  
GDT_SIZE	EQU	$ - _Gdt		; Size, in bytes 
 
;-------------------------------------------------------------------------------; 
; IDT										;	 
;-------------------------------------------------------------------------------; 
 
		ALIGN	4 
 
; Interrupt Descriptor Table (IDT) 
 
GATE		STRUCT 
		DD	? 
		DD	? 
GATE		ENDS 
 
_Idt: 
		GATE	32 dup (<0>)		; (00h-19h) Reserved for CPU interrupts 
		GATE	16 dup (<0>)		; (20h-2Fh) Reserved for IRQ interrupts 
		GATE	16 dup (<0>)		; (30h-3Fh) Reserved for OS interrupts 
 
IDT_SIZE	EQU	$ - _Idt		; Size, in bytes 
 
_TEXT		ENDS 
		END