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

📄 init.asm

📁 WinCE5.0部分核心源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
; Copyright (c) Microsoft Corporation.  All rights reserved.
;
;
; This source code is licensed under Microsoft Shared Source License
; Version 1.0 for Windows CE.
; For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
;
;-------------------------------------------------------------------------------
;
;
;-------------------------------------------------------------------------------
.486p


PAGE_SIZE               EQU 1000h
PAGE_ATTRIB_RW          EQU 000001100011b
PAGE_ATTRIB_RW_NOCACHE  EQU 000001111011b
PAGE_ATTRIB_RO_USER     EQU 000000100101b
PAGE_ATTRIB_RW_USER     EQU 000001100111b
PDE_PS                  EQU 080H
PDE_G                   EQU 100h

CPUID_PSE               EQU   0008H
CPUID_PGE               EQU   2000H

SYSTEM_PAGES            EQU 4000h               ; 4 system pages:

; offset within SYSTEM_PAGES
SYSPAGE_PAGEDIR         EQU 0                   ; Page Directory:       1 page
SYSPAGE_ADDRTABLE       EQU 1000h               ; space to save OEMAddressTable:      1 page
SYSPAGE_SYSCALL         EQU 2000h               ; Syscall Page:         1 page
SYSPAGE_SYSCALLDIR      EQU 3000h               ; Syscall Page Dir:     1 page

ZERO_BLOCK_SIZE         EQU 2000h               ; page needs to be zero'd (page directory and shadwo)

KGDT_R0_CODE            EQU 8h
KGDT_R0_DATA            EQU 10h

PG_MASK                 EQU 80000000h
WP_MASK                 EQU 00010000h

LIN_TO_PHYS_OFFSET      EQU 80000000h

OFFSET32                EQU <OFFSET FLAT:>

OFFSET_MEM_FOR_PT       EQU 02a8h               ; offset into _KDATA for nMemForPT field
OFFSET_CPU_CAP          EQU 02ach               ; offset into _KDATA for dwCpuCap field
                                                ;        -- must match nkx86.h
                                                
OFFSET_ULRAMFREE        EQU 24                  ; offset into pTOC for ulRamFree field

EFLAGS_IF_BIT           EQU 9                   ; bit 9 of EFLAGS is IF bit

;-------------------------------------------------------------------------------
; Kernel Data Segment ; KStack, Page Directory, KPage, Page Table pool
;-------------------------------------------------------------------------------
.KDATA segment para public 'STACK'

        public _KDBase
        public _KStack
        public _KData
        public _CurMSec, _DiffMSec
        
                        db 1000h dup (?)        ; reserve an extra page for the debugger
_KDBase                 db 07fch dup (?)        ; 2k Kernel Stack
_KStack                 dd ?
_KData                  db 0088h dup (?)        ; 2k KData
_CurMSec                dd ?
_DiffMSec               dd ?
                        db (800h - ($ - _KData)) dup (?)
.KDATA ends


;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_TEXT segment para public 'TEXT'

extrn _SystemInitialization:near
extrn _KernelInit:near
extrn _Reschedule:near
extrn _SafeIdentifyCpu:near
extrn _pTOC:near

        public  _NullSection
        align   4
_NullSection dd 512 dup (0)

;-------------------------------------------------------------------------------
; Figure out Virtual Address of a Physical Address
;
; uses ecx, edx (uses registers per calling convention allowed)
;
; (esi) = ptr to OEMAddressTable
; (eax) = PA
;
; On return
; (eax) = VA
;-------------------------------------------------------------------------------
VaFromPa PROC NEAR 
        mov     edx, esi                ; (edx) = &OEMAddressTable[0]

TestNextPa:
        cmp     dword ptr [edx+8], 0    ; last entry?
        je      short PaNotFound        ; entry not found
        mov     ecx, dword ptr [edx+4]  ; (ecx) = OEMAddressTable[i].paddr
        cmp     eax, ecx                ; Is (PA >= OEMAddressTable[i].paddr)?
        jb      short NextPa            ; go to next entry if not
        add     ecx, dword ptr [edx+8]  ; (ecx) = OEMAddressTable[i].paddr + OEMAddressTable[i].size
        cmp     eax, ecx                ; Is (PA < OEMAddressTable[i].paddr + OEMAddressTable[i].size)?
        jb      short PaFound           ; Found if it's true

NextPa:
        add     edx, 12                 ; i ++
        jmp     short TestNextPa        ; test next entry

PaNotFound:
        jmp     short PaNotFound        ; not much we can do if can't find the mapping
                                        ; spin forever

PaFound:
        sub     eax, dword ptr [edx+4]  ; PA -= PAStart
        add     eax, dword ptr [edx]    ; PA += VAStart
        ret

VaFromPa ENDP

;-------------------------------------------------------------------------------
; Figure out Physical Address of a Virtual Address
;
; uses ecx, edx (uses registers per calling convention allowed)
;
; (esi) = ptr to OEMAddressTable
; (eax) = VA
;
; On return
; (eax) = PA
;-------------------------------------------------------------------------------
PaFromVa PROC NEAR 
        mov     edx, esi                ; (edx) = &OEMAddressTable[0]

TestNextVa:
        mov     ecx, dword ptr [edx]    ; (ecx) = OEMAddressTable[i].vaddr
        test    ecx, ecx                ; last entry?
        jz      short VaNotFound        ; entry not found
        cmp     eax, ecx                ; Is (VA >= OEMAddressTable[i].vaddr)?
        jb      short NextVa            ; go to next entry if not
        add     ecx, dword ptr [edx+8]  ; (ecx) = OEMAddressTable[i].vaddr + OEMAddressTable[i].size
        cmp     eax, ecx                ; Is (VA < OEMAddressTable[i].vaddr + OEMAddressTable[i].size)?
        jb      short VaFound           ; Found if it's true

NextVa:
        add     edx, 12                 ; i ++
        jmp     short TestNextVa        ; test next entry

VaNotFound:
        jmp     short VaNotFound        ; not much we can do if can't find the mapping
                                        ; spin forever

VaFound:
        sub     eax, dword ptr [edx]    ; VA -= VAStart
        add     eax, dword ptr [edx+4]  ; VA += PAStart
        ret

PaFromVa ENDP



;
; Fill PageDirectory of an OEMAddressTable entry using 4M pages
; On Entry
; (eax) = PA of an OEMAddressTable Entry
; (ebx) = PA of Page Directory
; (edx) = PDE capability bits (PDE_PS and PDE_G)
; 
;
; !!! All Reigsters preserved !!!
;
FillPD4M PROC NEAR
        pushad

        mov     esi, dword ptr[eax]     ; (esi) = VA of region
        shr     esi, 20                 ; (esi) = offset into the Page Directory
        add     esi, ebx                ; (esi) = ptr to Page Directory cached entry

        mov     edi, esi
        add     edi, 0200h              ; (edi) = ptr to Page Directory uncached entry

        mov     ecx, dword ptr [eax+8]  ; (ecx) = size of the region
        
        add     ecx, 0003fffffh         ; round up to multiple of 4M
        and     ecx, 0ffc00000h         ; 
        ; DEBUGCHK (ecx != 0)

        or      edx, dword ptr [eax+4]  ; (edx) = PA | Capability BITs
        mov     eax, edx

        or      edx, PAGE_ATTRIB_RW             ; (edx) = PDE entry for 1st 4M (cached)
        or      eax, PAGE_ATTRIB_RW_NOCACHE     ; (eax) = PDE entry value for 1st 4M (uncached)

Next4M:
        mov     dword ptr [esi], edx    ; setup one cached entry
        mov     dword ptr [edi], eax    ; setup one uncached entry

        add     esi, 4                  ; (esi) = ptr to next PDE (cached)
        add     edi, 4                  ; (edi) = ptr to next PDE (uncached)

        add     edx, 0400000h           ; (edx) = PDE entry value for next 4M (cached)
        add     eax, 0400000h           ; (eax) = PDE entry value for next 4M (uncached)
        
        sub     ecx, 0400000h           ; decrement size by 4M
        jg      short Next4M

        popad

        ret
FillPD4M ENDP


;       Fill a secondary page table (2 actually, cached and uncached) + the page directory entry
;       (ebx) = PA to map to
;       (edx & ~0xfff) = PA of Page table (2 consective pages, one for cached, one for uncached)
;               NOTE: Low bit of edx might be set, MUST clear it before using it
;
;       !!! ALL REGITSTERS PRESERVED !!!
;
FillPTE PROc NEAR
        pushad

        mov     eax, ebx
        or      eax, PAGE_ATTRIB_RW             ; (eax) = page entry value (cached)
        or      ebx, PAGE_ATTRIB_RW_NOCACHE     ; (ebx) = page entry value (uncached)

        and     edx, 0fffff000h                 ; (edx) = Page table for cached mapping
                                                ; the low bits might contain gargage when passed in
        mov     esi, edx                        ; (esi) = Page table
        add     esi, PAGE_SIZE                  ; (esi) = Page Table for uncached mapping

        mov     ecx, 1024                       ; (ecx) = counter (1024 entries)

NextPTE:
        mov     dword ptr [edx], eax
        mov     dword ptr [esi], ebx

        add     edx, 4
        add     esi, 4

        add     eax, PAGE_SIZE
        add     ebx, PAGE_SIZE

        dec     ecx
        jne     short NextPTE
        
        popad
        ret
FillPTE ENDP


;
; Fill PageDirectory/PageTable of an OEMAddressTable entry using 4K pages
; On Entry
; (eax) = PA of an OEMAddressTable Entry
; (ebx) = PA of Page Directory
; (edx) = PageTables enough to map this region
;
; !!! All Reigsters preserved !!!
;
FillPD4K PROC NEAR
        pushad

        mov     ecx, dword ptr [eax+8]  ; (ecx) = size of the region

        add     ecx, 0003fffffh         ; round up to multiple of 4M
        and     ecx, 0ffc00000h         ; 
        ; DEBUGCHK (ecx != 0)

        mov     esi, dword ptr [eax]    ; (esi) = VA of region
        shr     esi, 20                 ; (esi) = offset into the Page Directory
        add     esi, ebx                ; (esi) = ptr to Page Directory cached entry

        mov     edi, esi
        add     edi, 0200h              ; (edi) = ptr to Page Directory uncached entry

        mov     ebx, dword ptr [eax+4]  ; (ebx) = PA of the region

        or      edx, PAGE_ATTRIB_RW     ; (edx) = PDE entry for 1st 4M (cached)
        mov     eax, edx
        add     eax, PAGE_SIZE          ; (edx, eax) are PT for (cached, uncached) addresses

Next4MPT:
        ; arguments to FillPTE:
        ;       (edx & ~0xfff) == Page Table address for 2 consective pages
        ;       (ebx) == PA to map to
        call    FillPTE                 ; fill the page tables
                                        ; NOTE: FillPTE perserves all registers 

        mov     dword ptr [esi], edx    ; setup one cached entry
        mov     dword ptr [edi], eax    ; setup one uncached entry

        add     esi, 4                  ; (esi) = ptr to next PDE (cached)
        add     edi, 4                  ; (edi) = ptr to next PDE (uncached)

        add     ebx, 0400000h           ; (ebx) = PA of the next 4M
        
        add     edx, PAGE_SIZE*2        ; (edx) = PDE entry value for next 4M (cached)
        add     eax, PAGe_SIZE*2        ; (eax) = PDE entry value for next 4M (uncached)
        
        sub     ecx, 0400000h           ; decrement size by 4M
        jg      short Next4MPT

        popad
        ret
FillPD4K ENDP


;-------------------------------------------------------------------------------
; (esi) = PA of OEMAddressTable
;       o each entry is of the format ( VA, PA, cbSize )
;       o cbSize must be multiple of 4M
;       o last entry must be (0, 0, 0)
;       o must have at least one non-zero entry
; (edi) = CPU capability bits
;
; throughout this function
; (ebx) = PA of Page Directory
; (esi) = PA of OEMAddressTable
;-------------------------------------------------------------------------------
_KernelInitialize PROC NEAR PUBLIC

;        xor     edi, edi               ; uncomment this line to force 4K page, useful for debugging

        ; set KData.nMemForPT to 0 first

⌨️ 快捷键说明

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