⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 startup.asm

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 ASM
字号:
;
;THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
;ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
;THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
;PARTICULAR PURPOSE.
;Copyright (c) 1995-2000  Microsoft Corporation
;
;Module Name: startup.asm
;
;Abstract: Boot loader startup code.
;
;Functions:
;
;    Startup
;    InPMode
;
;Notes:
;
; Romimage has been modified to support the RESETVECTOR feature for x86 (it's
; usually a PPC-only option).  The startup routine and associated GDT need to
; be located in the highest 64KB sector (FFFF.0000 -> FFFF.FFFF) so the reset
; vector only need do a near jump.  If we far jump from the reset vector, the
; selector is reloaded and we can't get > 1MB.  The RESETVECTOR feature means
; we can build our image for the start of flash (FFFC.0000 for a 256KB part,
; for example), but romimage will *copy* part of this code to the specified
; address.  
;
; To use RESETVECTOR, the bib file needs to RESERVE the section and the 
; RESETVECTOR= value is assigned there.  In the code, three tags, ResetVector,
; ResetVectorAddr, and ResetVectorEnd are use to define the code/data of 
; interest.  Until the CPU is in protected mode, all addresses need be greater
; than or relative to FFFF.0000.  As such, the following need be correctly
; defined:
;
; X86BOOT -> reset jump address
; mov eax, OFFSET GDTPtr
;
; The RESETVECTOR= feature locates StartUp() and the GDT to FFFF.0000.  The 
; reset vector jumps to FFFF.0000 + GDT + GDTPtr (relative 0x2D).  The offset
; to GDTPtr is relative to FFFF.0000 and is FFFF.001A.
;
; If the StartUp routine grows, the GDT changes, or the BIB/RESETVECTOR build
; the StartUp routine to a different location (from FFFF.0000), other changes
; may be required.


.486p
.model FLAT

INCLUDE		macro.inc

.code

PUBLIC ResetVectorAddr
PUBLIC ResetVector
PUBLIC ResetVectorEnd

align 4
ResetVectorAddr LABEL DWORD 
	dd 090000H	; Weird value so 090000H + FFF6.0000H = FFFF.0000H
                ; and our startup code will be in the upper 64KB.
                ; FFF6.0000H is ROM_OFFSET/ROMOFFSET.

ResetVector:	; *** Start of code located in upper 64KB ***

align 4
;
; Static GDT mapping:
;  - flat 0-4GB code address space
;  - flat 0-4GB data address space
;
GDT_Data LABEL DWORD
        db         0,    0,   0,   0,   0,         0,         0,   0 ; Unused
        CS_FLAT_SEL EQU ($-GDT_Data)
        db      0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00h ; Code
        DS_FLAT_SEL EQU ($-GDT_Data)
        db      0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00h ; Data
GDT_TABLE_SIZE = $ - OFFSET GDT_Data

align 4
;
; GDTR contents (size and GDT pointer)
;
        dw 0000h			; Odd word boundary to avoid faults
GDTPtr LABEL FWORD
        dw      GDT_TABLE_SIZE - 1
        dd      OFFSET GDT_Data + ROM_OFFSET	; ROM_OFFSET because we're
						; pushing RAM image into ROM.
align 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ROM Loader startup routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
StartUp PROC NEAR C PUBLIC

    ;
    ; Initialize Debug Serial (must inline because we have no stack)
    ;
    mov     dh, 003h
    mov     dl, 0FBh
    mov     al, 080h            ; Access Baud Divisor
    out     dx, al

    mov     dl, 0F8h
    mov     al, 003h            ; 38400 Baud
    out     dx, al

    mov     dl, 0F9h
    mov     al, 000h
    out     dx, al

    mov     dl, 0FAh
    mov     al, 007h            ; Enable FIFO if present
    out     dx, al

    mov     dl, 0FBh
    mov     al, 003h            ; DLAB = 0, 8 bit, no parity
    out     dx, al

    mov     dl, 0F9h
    xor     al, al              ; No interrupts, polled
    out     dx, al

    mov     dl, 0FCh
    mov     al, 003h            ; Assert DTR, RTS
    out     dx, al

IF 0
    WriteChar 'B'		; Write status to serial
    WriteChar '0'
    WriteChar 0dh
    WriteChar 0ah
ENDIF

 
    ;
    ; General setup stuff
    ;
    cli                                 ; disable interrupts
    cld                                 ; clear direction flag


    ;
    ; Configure CPU to use static GDT
    ;
    OpPrefix
    ;mov     eax, OFFSET GDTPtr          ; EAX -> Flat GDT Ptr address
; TODO - compute offset - don't hard-code.
    mov     eax, 0FFFF001AH          ; EAX -> Flat GDT Ptr address

    ; Since the above calculation is assuming a flat address space, we only want
    ; the offset for the segmented address.
    OpPrefix
    and     eax, 0FFFFh         ; Make it relative to funky 0FFFF0000h CS base

    AddrPrefix
    OpPrefix
    lgdt    FWORD PTR cs:[eax]          ; load the GDTR

    ;
    ; Set the PE bit in CR0 (switch to protected mode)
    ;
    ; Don't need OpPrefix on mov to/from CR0 - always 32-bit
    mov     eax, cr0                    ; get the current CR0
    OpPrefix
    or      eax, 000000001h
    mov     cr0, eax                    ; NOW WE'RE IN PMODE!

    OpPrefix
    db      0EAh
    dd      OFFSET InPMode + ROM_OFFSET
    dw      CS_FLAT_SEL

StartUp ENDP



align 4

;
; The first Protected Mode routine
;
InPMode PROC NEAR

    ;
    ; Init the segment registers
    ;
    xor     eax, eax
    mov     al, DS_FLAT_SEL
    mov     ds, ax
    mov     es, ax
    mov     fs, ax
    mov     gs, ax
    mov     ss, ax
    mov     esp, FLAT_STACK_START

    ;
    ; Boot progress message
    ;
IF 0
    WriteChar 'B'
    WriteChar '1'
    WriteChar 0dh
    WriteChar 0ah
ENDIF

    ;
    ; Configure northbridge
    ;
; TODO - if we're running in a BIOS environment, we needn't do this.  Code can
; be conditionally included.
    EXTRN   _BridgeConfig:NEAR
    EXTRN   _BridgePrintConfig:NEAR
    NoMemCall _BridgeConfig
IF 0
    NoMemCall _BridgePrintConfig
ENDIF

    ;
    ; Boot progress message
    ;
IF 0
    WriteChar 'B'
    WriteChar '2'
    WriteChar 0dh
    WriteChar 0ah
ENDIF

    ;
    ; Configure cache (enable and set write-through mode)
    ;
    mov     ebx, OFFSET CacheEnabled + ROM_OFFSET
    mov     eax, cr0
    and     eax, not 060000000h         ; clear cache disable and write-through
    mov     cr0, eax
    jmp     ebx                         ; jump to clear prefetch queue

align   4

CacheEnabled:
    wbinvd                              ; clear out the cache

    ;
    ; Boot progress message
    ;
IF 0
    WriteChar 'B'
    WriteChar '3'
    WriteChar 0dh
    WriteChar 0ah
ENDIF

    ;
    ; Copy ourselves into RAM
    ;
    EXTRN   _CopyToRAM:NEAR
    call    _CopyToRAM

    ;
    ; Jump to C main routine...
    ;
    EXTRN   _blMain:FAR
    mov     eax, OFFSET _blMain
    jmp     eax

ResetVectorEnd:

    nop     ; Should never get here.
    
InPMode ENDP


END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -