📄 init-cpu.asm
字号:
; ============================================================
; File: INIT-CPU.ASM
;
; Copyright (C) 2001, Daniel W. Lewis and Prentice-Hall
;
; Purpose: Switches the processor from real to protected mode,
; establishes a flat memory model with all segments starting
; at address zero and set to a size of 4GB.
;
; Interrupts: Already disabled; remain disabled.
;
; Designed for use with the NASM protected mode 386 assembler.
;
; Modification History:
;
%define BUG_FEB_20_2002
; Found by Wayne Gibson (wgibson@speakeasy.net).
; Execution of LGDT instruction in real mode still had
; default size of 64KB for DS. If data segment contained
; more than 64KB, the LGDT instruction would cause an
; exception. Solution was to create a new "SECTION .init"
; and place Init_CPU and Check_CPU code, as well as the
; the gdt and gdt_info data structures. Also required
; change to LDSCRIPT and resulting LINK.CMD file.
;
; ============================================================
%ifdef BUG_FEB_20_2002
SECTION .init
%else
SECTION .data
%endif
;----------------------------------------------------------------------------
; Global Descriptor Table (GDT)
;----------------------------------------------------------------------------
gdt_info: DW (3*8)-1 ; 16-bit GDT limit
DD gdt ; 32-bit GDT address
gdt:
null_descriptor:
DW 0 ; seg length <0..15>
DW 0 ; base address <0..15>
DB 0 ; base address <16..23>
DB 0 ; seg type and misc flags
DB 0 ; seg length <16..19> & access flags
DB 0 ; base address <24..31>
code_descriptor:
DW 0FFFFh ; seg length <0..15>
DW 0 ; base address <0..15>
DB 0 ; base address <16..23>
DB 09Ah ; seg type and misc flags
DB 0CFh ; seg length <16..19> & access flags
DB 0 ; base address <24..31>
data_descriptor:
DW 0FFFFh ; seg length <0..15>
DW 0 ; base address <0..15>
DB 0 ; base address <16..23>
DB 092h ; seg type and misc flags
DB 0CFh ; seg length <16..19> & access flags
DB 0 ; base address <24..31>
CODE_SELECTOR EQU code_descriptor - gdt
DATA_SELECTOR EQU data_descriptor - gdt
GLOBAL code_selector ; (Needed in init-idt.c)
code_selector: DW CODE_SELECTOR
SECTION .start
BITS 32
GLOBAL start
;============================================================================
; Start at phys adrs 0, real mode, A20-Gate Open, IF=0, CS=0, & IP=0 ...
;============================================================================
start: CLI ; no interrupts during initialization
DB 66h ; (JMP assembled with 32-bit offset)
JMP Check_CPU
%ifdef BUG_FEB_20_2002
SECTION .init
%else
SECTION .text
%endif
BITS 32
GLOBAL Init_CPU
EXTERN Check_CPU
EXTERN stack_last
EXTERN Init8259
EXTERN Init8253
EXTERN Init_IDT
EXTERN Init_CRT
EXTERN _main
Init_CPU: XOR EAX,EAX ; Still in Real Mode, so
MOV DS,EAX ; this is really AX
DB 66h ; Need 32-bit operand size.
DB 67h ; (LGDT assembled with 32-bit offset)
LGDT [gdt_info] ; load GDT register
MOV EAX,CR0 ; get CR0 into EAX
OR AL,1 ; set Protected Mode bit
MOV CR0,EAX ; go to Protected Mode!
DB 66h
DB 0EAh ; far jump (to set CS)
DD ProtMode
DW CODE_SELECTOR
;============================================================================
; Execution continues here in protected mode ...
;============================================================================
ProtMode: MOV AL,DATA_SELECTOR; load all other selectors
XOR AH,AH
MOV DS,EAX
MOV ES,EAX
MOV FS,EAX
MOV GS,EAX
MOV SS,EAX
LEA ESP,[stack_last + 1]
CALL Init_CRT ; C Run-Time Environment
CALL Init8259 ; Programmable Interrupt Controller
CALL Init8253 ; Programmable Interrupt Timer
CALL Init_IDT ; Interrupt Descriptor Table
CALL _main ; User's Embedded Application
JMP $
HLT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -