2021年reactos仿windows系统内核源代码研究


    引导序号
    引导程
    引导执行代码位数
    目标文件名称
    1         
    引导代码(Master Boot Record (MBR)code)寻找活动分区然读入引导扇区代码
    16位执行代码
    reactosbootfreeldrbootsectdosmbrasm
    2         
    引导扇区代码寻找根引导程序里寻找freeldrsys
    16位执行代码
    reactosbootfreeldrbootsect fatasm
    reactosbootfreeldrbootsectfat32asm
    3         
    ReactOS加载程序freeldrsys加载haldllntoskrnlexe读取FREELDRINI配置文件
    16位32位代码
    reactosbootfreeldr
    4         
    ntoskrnlexe加载驱动程序初始化核工作
     
    32位代码
    reactosntoskrnl
    normal DOS boot sector
    Ported to nasm from FreeDOS fdisk 120 by
    Casper Hornstrup (chorns@userssourceforgenet)
    global _bootnormal_code
    _bootnormal_code

    ENTRY (copied from freedos bootsector)

    IN DL boot drive
    OUT DL boot drive


    真正启动开中断
    real_start cli
    cld
    xor ax ax
    mov ss ax initialize stack
    mov ds ax
    mov bp 0x7c00
    lea sp [bp0x20]
    sti

    mov ax 0x1FE0
    mov es ax
    mov si bp
    mov di bp
    mov cx 0x0100
    rep movsw

    jmp word 0x1FE00x7c00+ contreal_start

    cont mov ds ax
    mov ss ax
    xor axax
    mov esax


    search for active partition 搜索活动分区
    lea di [bp+0x1be] start of partition table
    test_next_for_active
    test byte [di]0x80
    jne active_partition_found
    add di0x10 next table
    cmp di 07c00h+0x1fe scanned beyond end of table 扫描分区表
    jb test_next_for_active

    *****************************************************************
    call print
    db 'no active partition found'0

    WAIT_FOR_REBOOT
    jmp


    *****************************************************************
    trouble_reading_drive
    call print
    db 'read error while reading drive'0
    jmp WAIT_FOR_REBOOT

    *****************************************************************

    invalid_partition_code
    call print
    db 'partition signature 55AA'0

    jmp WAIT_FOR_REBOOT


    *****************************************************************
    查找分区表
    active_partition_found
    call print
    db 'loading active partition'0

    call read_boot_sector

    jc trouble_reading_drive

    cmp word [es0x7c00+0x1fe]0xaa55
    jne invalid_partition_code

    jmp word 0x00x7c00 and jump to boot sector code


    *****************************
    read_boot_sector

    IN DI> partition info
    OUTCARRY
    *****************************

    read_boot_sector
    * check for LBA support *
    mov bx0x55aa
    mov ah0x41
    int 0x13

    jc StandardBios if (regsbx 0xaa55 || (regsflags & 0x01))
    cmp bx0xaa55 goto StandardBios
    jne StandardBios

    * if DAP cannot be used don't use LBA *
    if ((regscx & 1) 0)
    goto StandardBios
    test cl1
    jz StandardBios

    jmp short LBABios


    _bios_LBA_address_packet
    db 0x10
    db 0
    db 4 read four sectors why not
    db 0
    dw 0x7c00 fixed boot address for DOS sector
    dw 0x0000
    _bios_LBA_low dw 0
    _bios_LBA_high dw 0
    dw 00
    LBABios
    copy start address of partition to DAP
    mov ax[di+8]
    mov [0x7c00+ (_bios_LBA_lowreal_start)]ax
    mov ax[di+8+2]
    mov [0x7c00+ (_bios_LBA_highreal_start)]ax

    mov ax0x4200 regsax LBA_READ
    mov si0x7c00+ (_bios_LBA_address_packetreal_start) regssi FP_OFF(&dap)
    int 0x13
    ret
    *****************************************************************
    read disk using standard BIOS

    StandardBios
    mov ax0x0204 regsax 0x0201
    mov bx0x7c00 regsbx FP_OFF(buffer)
    mov cx[di+2] regscx
    ((chsCylinder & 0xff) << 8) + ((chsCylinder & 0x300) >> 2) +
    chsSector
    that was easy )
    mov dh[di+1] regsdbh chsHead
    regses FP_SEG(buffer)
    int 0x13
    ret
    ****** PRINT
    prints text after call to this function

    print_1char
    xor bx bx video page 0
    mov ah 0x0E else print it
    int 0x10 via TTY mode
    print pop si this is the first character
    print1 lodsb get token
    push si stack up potential return address
    cmp al 0 end of string
    jne print_1char until done
    ret and jump to it



    times 0x1fe+ db 0
    db 0x550xaa
    BIOS 引导 硬盘中MBR 512字节分区表查找分区表 然找 FAT中 Freeldrsys 文件然Freeldrsys 中引导核文件
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    FATASM
    FAT1216 Boot Sector
    Copyright (c) 1998 2001 2002 Brian Palmer
    This is a FAT1216 file system boot sector
    that searches the entire root directory
    for the file freeldrsys and loads it into
    memory 文件系统中查找 freeldrsys 文件

    The stack is set to 00007BF2 so that the first
    WORD pushed will be placed at 00007BF0

    The DWORD at 00007BFC or BP04h is the logical
    sector number of the start of the data area

    The DWORD at 00007BF8 or BP08h is the total
    sector count of the boot drive as reported by
    the computers bios

    The WORD at 00007BF6 or BP0ah is the offset
    of the ReadSectors function in the boot sector

    The WORD at 00007BF4 or BP0ch is the offset
    of the ReadCluster function in the boot sector

    The WORD at 00007BF2 or BP0eh is the offset
    of the PutChars function in the boot sector

    When it locates freeldrsys on the disk it will
    load the first sector of the file to 00008000
    With the help of this sector we should be able
    to load the entire file off the disk no matter
    how fragmented it is

    We load the entire FAT table into memory at
    70000000 This improves the speed of floppy disk
    boots dramatically


    BootSectorStackTop equ 0x7bf2
    DataAreaStartHigh equ 0x2
    DataAreaStartLow equ 0x4
    BiosCHSDriveSizeHigh equ 0x6
    BiosCHSDriveSizeLow equ 0x8
    BiosCHSDriveSize equ 0x8
    ReadSectorsOffset equ 0xa
    ReadClusterOffset equ 0xc
    PutCharsOffset equ 0xe


    org 7c00h

    segment text

    bits 16

    start
    jmp short main
    nop

    OEMName db 'FrLdr10'
    BytesPerSector dw 512
    SectsPerCluster db 1
    ReservedSectors dw 1
    NumberOfFats db 2
    MaxRootEntries dw 224
    TotalSectors dw 2880
    MediaDescriptor db 0f0h
    SectorsPerFat dw 9
    SectorsPerTrack dw 18
    NumberOfHeads dw 2
    HiddenSectors dd 0
    TotalSectorsBig dd 0
    BootDrive db 0xff
    Reserved db 0
    ExtendSig db 29h
    SerialNumber dd 00000000h
    VolumeLabel db 'NO NAME '
    FileSystem db 'FAT12 '

    main
    xor axax
    mov ssax
    mov bp7c00h
    mov spBootSectorStackTop Setup a stack
    mov dsax Make DS correct
    mov esax Make ES correct


    cmp BYTE [BYTE bp+BootDrive]BYTE 0xff If they have specified a boot drive then use it
    jne GetDriveParameters

    mov [BYTE bp+BootDrive]dl Save the boot drive


    GetDriveParameters
    mov ah08h
    mov dl[BYTE bp+BootDrive] Get boot drive in dl
    int 13h Request drive parameters from the bios
    jnc CalcDriveSize If the call succeeded then calculate the drive size

    If we get here then the call to the BIOS failed
    so just set CHS equal to the maximum addressable
    size
    mov cx0ffffh
    mov dhcl

    CalcDriveSize
    Now that we have the drive geometry
    lets calculate the drive size
    mov blch Put the low 8bits of the cylinder count into BL
    mov bhcl Put the high 2bits in BH
    shr bh6 Shift them into position now BX contains the cylinder count
    and cl3fh Mask off cylinder bits from sector count
    CL now contains sectors per track and DH contains head count
    movzx eaxdh Move the heads into EAX
    movzx ebxbx Move the cylinders into EBX
    movzx ecxcl Move the sectors per track into ECX
    inc eax Make it one based because the bios returns it zero based
    inc ebx Make the cylinder count one based also
    mul ecx Multiply heads with the sectors per track result in edxeax
    mul ebx Multiply the cylinders with (heads * sectors) [stored in edxeax already]

    We now have the total number of sectors as reported
    by the bios in eax so store it in our variable
    mov [BYTE bpBiosCHSDriveSize]eax


    Now we must find our way to the first sector of the root directory
    xor axax
    xor cxcx
    mov al[BYTE bp+NumberOfFats] Number of fats
    mul WORD [BYTE bp+SectorsPerFat] Times sectors per fat
    add axWORD [BYTE bp+HiddenSectors]
    adc dxWORD [BYTE bp+HiddenSectors+2] Add the number of hidden sectors
    add axWORD [BYTE bp+ReservedSectors] Add the number of reserved sectors
    adc dxcx Add carry bit
    mov WORD [BYTE bpDataAreaStartLow]ax Save the starting sector of the root directory
    mov WORD [BYTE bpDataAreaStartHigh]dx Save it in the first 4 bytes before the boot sector
    mov siWORD [BYTE bp+MaxRootEntries] Get number of root dir entries in SI
    pusha Save 32bit logical start sector of root dir
    DXAX now has the number of the starting sector of the root directory

    Now calculate the size of the root directory
    xor dxdx
    mov ax0020h Size of dir entry
    mul si Times the number of entries
    mov bx[BYTE bp+BytesPerSector]
    add axbx
    dec ax
    div bx Divided by the size of a sector
    AX now has the number of root directory sectors

    add [BYTE bpDataAreaStartLow]ax Add the number of sectors of the root directory to our other value
    adc [BYTE bpDataAreaStartHigh]cx Now the first 4 bytes before the boot sector contain the starting sector of the data area
    popa Restore root dir logical sector start to DXAX

    LoadRootDirSector
    mov bx7e0h We will load the root directory sector
    mov esbx Right after the boot sector in memory
    xor bxbx We will load it to [00007e00h]
    xor cxcx Zero out CX
    inc cx Now increment it to 1 we are reading one sector
    xor didi Zero out di
    push es Save ES because it will get incremented by 20h
    call ReadSectors Read the first sector of the root directory
    pop es Restore ES (ESDI 07E00000)

    SearchRootDirSector
    cmp [esdi]ch If the first byte of the directory entry is zero then we have
    jz ErrBoot reached the end of the directory and FREELDRSYS is not here so reboot
    pusha Save all registers
    mov cl0xb Put 11 in cl (length of filename in directory entry)
    mov sifilename Put offset of filename string in DSSI
    repe cmpsb Compare this directory entry against 'FREELDR SYS'
    popa Restore all the registers
    jz FoundFreeLoader If we found it then jump
    dec si SI holds MaxRootEntries subtract one
    jz ErrBoot If we are out of root dir entries then reboot
    add diBYTE +0x20 Increment DI by the size of a directory entry
    cmp di0200h Compare DI to 512 (DI has offset to next dir entry make sure we haven't gone over one sector)
    jc SearchRootDirSector If DI is less than 512 loop again
    jmp short LoadRootDirSector Didn't find FREELDRSYS in this directory sector try again

    FoundFreeLoader
    We found freeldrsys on the disk 查找文件
    so we need to load the first 512
    bytes of it to 00008000
    ESDI has dir entry (ESDI 07E0XXXX)
    mov axWORD [esdi+1ah] Get start cluster
    push ax Save start cluster
    push WORD 800h Put 800h on the stack and load it
    pop es Into ES so that we load the cluster at 00008000
    call ReadCluster Read the cluster
    pop ax Restore start cluster of FreeLoader

    Save the addresses of needed functions so
    the helper code will know where to call them
    mov WORD [BYTE bpReadSectorsOffset]ReadSectors Save the address of ReadSectors
    mov WORD [BYTE bpReadClusterOffset]ReadCluster Save the address of ReadCluster
    mov WORD [BYTE bpPutCharsOffset]PutChars Save the address of PutChars

    Now AX has start cluster of FreeLoader and we
    have loaded the helper code in the first 512 bytes
    of FreeLoader to 00008000 Now transfer control
    to the helper code Skip the first three bytes
    because they contain a jump instruction to skip
    over the helper code in the FreeLoader image
    jmp 00008003h
    jmp 8003h
    Displays an error message
    And reboots
    ErrBoot
    mov simsgFreeLdr FreeLdr not found message
    call PutChars Display it

    Reboot
    mov simsgAnyKey Press any key message
    call PutChars Display it
    xor axax
    int 16h Wait for a keypress
    int 19h Reboot

    PutChars
    lodsb
    or alal
    jz short Done
    mov ah0eh
    mov bx07h
    int 10h
    jmp short PutChars
    Done
    retn

    Displays a bad boot message
    And reboots
    BadBoot
    mov simsgDiskError Bad boot disk message
    call PutChars Display it

    jmp short Reboot


    Reads cluster number in AX into [ES0000]
    ReadCluster
    StartSector ((Cluster 2) * SectorsPerCluster) + ReservedSectors + HiddenSectors
    dec ax Adjust start cluster by 2
    dec ax Because the data area starts on cluster 2
    xor chch
    mov clBYTE [BYTE bp+SectsPerCluster]
    mul cx Times sectors per cluster
    add ax[BYTE bpDataAreaStartLow] Add start of data area
    adc dx[BYTE bpDataAreaStartHigh] Now we have DXAX with the logical start sector of OSLOADERSYS
    xor bxbx We will load it to [ES0000] ES loaded before function call
    mov clBYTE [BYTE bp+SectsPerCluster] Sectors per cluster still in CX
    call ReadSectors
    ret
    Reads logical sectors into [ESBX]
    DXAX has logical sector number to read
    CX has number of sectors to read
    ReadSectors
    We can't just check if the start sector is
    in the BIOS CHS range We have to check if
    the start sector + length is in that range
    pusha
    dec cx
    add axcx
    adc dxbyte 0

    cmp dxWORD [BYTE bpBiosCHSDriveSizeHigh] Check if they are reading a sector within CHS range
    ja ReadSectorsLBA No go to the LBA routine
    jb ReadSectorsCHS Yes go to the old CHS routine
    cmp axWORD [BYTE bpBiosCHSDriveSizeLow] Check if they are reading a sector within CHS range
    jbe ReadSectorsCHS Yes go to the old CHS routine

    ReadSectorsLBA
    popa
    ReadSectorsLBALoop
    pusha Save logical sector number & sector count

    o32 push byte 0
    push dx Put 64bit logical
    push ax block address on stack
    push es Put transfer segment on stack
    push bx Put transfer offset on stack
    push byte 1 Set transfer count to 1 sector
    push byte 0x10 Set size of packet to 10h
    mov sisp Setup disk address packet on stack

    We are so totally out of space here that I am forced to
    comment out this very beautifully written piece of code
    It would have been nice to have had this check
    CheckInt13hExtensions Now make sure this computer supports extended reads
    mov ah0x41 AH 41h
    mov bx0x55aa BX 55AAh
    mov dl[BYTE bp+BootDrive] DL drive (80hFFh)
    int 13h IBMMS INT 13 Extensions INSTALLATION CHECK
    jc PrintDiskError CF set on error (extensions not supported)
    cmp bx0xaa55 BX AA55h if installed
    jne PrintDiskError
    test cl1 CX API subset support bitmap
    jz PrintDiskError Bit 0 extended disk access functions (AH42h44h47h48h) supported


    Good we're here so the computer supports LBA disk access
    So finish the extended read
    mov dl[BYTE bp+BootDrive] Drive number
    mov ah42h Int 13h AH 42h Extended Read
    int 13h Call BIOS
    jc BadBoot If the read failed then abort

    add spbyte 0x10 Remove disk address packet from stack

    popa Restore sector count & logical sector number

    inc ax Increment Sector to Read
    adc dxbyte 0

    push bx
    mov bxes
    add bxbyte 20h Increment read buffer for next sector
    mov esbx
    pop bx

    loop ReadSectorsLBALoop Read next sector

    ret


    Reads logical sectors into [ESBX]
    DXAX has logical sector number to read
    CX has number of sectors to read
    CarryFlag set on error
    ReadSectorsCHS
    popa
    ReadSectorsCHSLoop
    pusha
    xchg axcx
    xchg axdx
    xor dxdx
    div WORD [BYTE bp+SectorsPerTrack]
    xchg axcx
    div WORD [BYTE bp+SectorsPerTrack] Divide logical by SectorsPerTrack
    inc dx Sectors numbering starts at 1 not 0
    xchg cxdx
    div WORD [BYTE bp+NumberOfHeads] Number of heads
    mov dhdl Head to DH drive to DL
    mov dl[BYTE bp+BootDrive] Drive number
    mov chal Cylinder in CX
    ror ah2 Low 8 bits of cylinder in CH high 2 bits
    in CL shifted to bits 6 & 7
    or clah Or with sector number
    mov ax0201h
    int 13h DISK READ SECTORS INTO MEMORY
    AL number of sectors to read CH track CL sector
    DH head DL drive ESBX > buffer to fill
    Return CF set on error AH status (see AH01h) AL number of sectors read

    jc BadBoot

    popa
    inc ax Increment Sector to Read
    jnz NoCarryCHS
    inc dx
    NoCarryCHS
    push bx
    mov bxes
    add bxbyte 20h
    mov esbx
    pop bx
    Increment read buffer for next sector
    loop ReadSectorsCHSLoop Read next sector

    ret


    msgDiskError db 'Disk error'0dh0ah0
    msgFreeLdr db 'freeldrsys not found'0dh0ah0
    Sorry need the space
    msgAnyKey db 'Press any key to restart'0dh0ah0
    msgAnyKey db 'Press any key'0dh0ah0
    filename db 'FREELDR SYS'

    times 509() db 0 Pad to 509 bytes

    BootPartition
    db 0

    BootSignature
    dw 0aa55h BootSector signature

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    *
     * FILE            ntoskrnlkei386bootS
     * COPYRIGHT       See COPYING in the top level directory
     * PURPOSE         FreeLDR Wrapper Bootstrap Code and Bootstrap Trampoline
     * PROGRAMMERs     Alex Ionescu (alex@relsoftnet)
     *                  Thomas Weidenmueller 
     *
     第 启动文件 
    * INCLUDES ******************************************************************

    #include 
    intel_syntax noprefix

    * GLOBALS *******************************************************************

    bss        数段 
    align 16   16 位排列

    * Kernel Boot Stack * 核启动 栈变量
    globl _P0BootStack
    space KERNEL_STACK_SIZE  般 4K B 
    _P0BootStack

    * Kernel DoubleFault and Temporary DPC Stack *
    globl _KiDoubleFaultStack  页面二级异常
    space KERNEL_STACK_SIZE
    _KiDoubleFaultStack

    * FUNCTIONS *****************************************************************
         系统启动 Freeldrsys 文件中VOID LoadReactOSSetup2(VOID) 函数中函数指针 
         引导  核基址
         引导跳转  KiSystemStartup 函数中
    text     代码段 
    globl _KiSystemStartup  安装硬盘 核启动函数  直接启动  0x80000000 址
    func KiSystemStartup    Rosxxx  安装时启动函数终 
    _KiSystemStartup
        * NTLDR Boot Call the main kernel initialization *
        test dword ptr [esp+4] 0x80000000 
        jnz _KiSystemStartupReal@4   测试函数 0   传入LoaderBlock 变量  
        * FREELDR Boot Call the FreeLDR wrapper *面函数 freeldr 引导中 外包中
        jmp @KiRosPrepareForSystemStartup@8   否函数中进入  _KiSystemStartupReal 中
    endfunc

    globl _KiSetupStackAndInitializeKernel@24   函数里 初始化线程进程 
    func KiSetupStackAndInitializeKernel@24
    _KiSetupStackAndInitializeKernel@24

        * Save current stack *
        mov esi esp

        * Setup the new stack *
        mov esp [esp+12]
        sub esp NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH
        push CR0_EM + CR0_TS + CR0_MP

        * Copy all parameters to the new stack *
        push [esi+24]
        push [esi+20]
        push [esi+16]
        push [esi+12]
        push [esi+8]
        push [esi+4]
        xor ebp ebp
        进入函数 进入 执行体 函数中 然进入 线程部分 
        call _KiInitializeKernel@24   *****非常关键*   初始化核 容里面

        * Set the priority of this thread to 0 *
        mov ebx PCR[KPCR_CURRENT_THREAD]        获取前线程
        mov byte ptr [ebx+KTHREAD_PRIORITY] 0   设置前线程优先级

        * Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL *
        sti
        mov ecx DISPATCH_LEVEL
        call @KfLowerIrql@4        降低中断级 引起 线程调度

        * Set the right wait IRQL *
        mov byte ptr [ebx+KTHREAD_WAIT_IRQL] DISPATCH_LEVEL

        * Jump into the idle loop *
        jmp @KiIdleLoop@0             Idleexe 系统线程 处理脏 页面
    endfunc
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    系统真正启动函数  直接 硬盘 者 光盘 启动时候 boots 中_KiSystemStartup  先调
    VOID
    NTAPI      
    KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)  LoaderBlockfreeldr中全局变量 已构造
    {          函数 重  关键理解 果构造第线程 现没线程呢  
               面 载入参数块
        ULONG Cpu
        PKTHREAD InitialThread  指针 线程 变量
        ULONG InitialStack
        PKGDTENTRY Gdt          全局描述表
        PKIDTENTRY Idt
        KIDTENTRY NmiEntry DoubleFaultEntry  中断描写表
        PKTSS Tss  务状态段 
        PKIPCR Pcr

        * Save the loader block and get the current CPU *
        KeLoaderBlock  LoaderBlock  保存载入块 构造
        Cpu  KeNumberProcessors
        if (Cpu) 0 启动CPU
        {
            * If this is the boot CPU set FS and the CPU Number*
            Ke386SetFs(KGDT_R0_PCR)
            __writefsdword(KPCR_PROCESSOR_NUMBER Cpu)

            * Set the initial stack and idle thread as well *
            LoaderBlock>KernelStack  (ULONG_PTR)P0BootStack
            LoaderBlock>Thread  (ULONG_PTR)&KiInitialThread 址值 里面没初始化
        }

        * Save the initial thread and stack *
        InitialStack  LoaderBlock>KernelStack 核栈
        InitialThread  (PKTHREAD)LoaderBlock>Thread   启动线程 面赋值 没少值

        * Clean the APC List Head *
        InitializeListHead(&InitialThread>ApcStateApcListHead[KernelMode])

        * Initialize the machine type *
        KiInitializeMachineType()

        * Skip initial setup if this isn't the Boot CPU *
        if (Cpu) goto AppCpuInit

        * Get GDT IDT PCR and TSS pointers *
        KiGetMachineBootPointers(&Gdt &Idt &Pcr &Tss)  初始化寄存器段 

        * Setup the TSS descriptors and entries *
        Ki386InitializeTss(Tss Idt Gdt) 安装 TSS 

        * Initialize the PCR *
        RtlZeroMemory(Pcr PAGE_SIZE) 初始化PCR 结构  里重 4 Kb 
        KiInitializePcr(Cpu           
                        Pcr
                        Idt
                        Gdt
                        Tss
                        InitialThread
                        KiDoubleFaultStack)

        * Set us as the current process *  初始化进程 里初始化啊
        InitialThread>ApcStateProcess  &KiInitialProcessPcb

        * Clear DR67 to cleanup bootloader debugging *
        __writefsdword(KPCR_TEB 0) 清线程环境块
        __writefsdword(KPCR_DR6 0)
        __writefsdword(KPCR_DR7 0)

        * Setup the IDT *
        KeInitExceptions() 安装中断描述表

        * Load Ring 3 selectors for DSES *
        Ke386SetDs(KGDT_R3_DATA | RPL_MASK)  载入户态 选择子
        Ke386SetEs(KGDT_R3_DATA | RPL_MASK)

        * Save NMI and double fault traps *
        RtlCopyMemory(&NmiEntry &Idt[2] sizeof(KIDTENTRY))
        RtlCopyMemory(&DoubleFaultEntry &Idt[8] sizeof(KIDTENTRY))

        * Copy kernel's trap handlers *
        RtlCopyMemory(Idt
                      (PVOID)KiIdtDescriptorBase
                      KiIdtDescriptorLimit + 1)

        * Restore NMI and double fault *
        RtlCopyMemory(&Idt[2] &NmiEntry sizeof(KIDTENTRY))
        RtlCopyMemory(&Idt[8] &DoubleFaultEntry sizeof(KIDTENTRY))

    AppCpuInit
        * Loop until we can release the freeze lock *
        do
        {
            * Loop until execution can continue *
            while (*(volatile PKSPIN_LOCK*)&KiFreezeExecutionLock  (PVOID)1)
        } while(InterlockedBitTestAndSet((PLONG)&KiFreezeExecutionLock 0))

        * Setup CPUrelated fields *
        __writefsdword(KPCR_NUMBER Cpu)
        __writefsdword(KPCR_SET_MEMBER 1 << Cpu)
        __writefsdword(KPCR_SET_MEMBER_COPY 1 << Cpu)
        __writefsdword(KPCR_PRCB_SET_MEMBER 1 << Cpu)

        * Initialize the Processor with HAL *
        HalInitializeProcessor(Cpu KeLoaderBlock)

        * Set active processors *
        KeActiveProcessors | __readfsdword(KPCR_SET_MEMBER)
        KeNumberProcessors++

        * Check if this is the boot CPU *
        if (Cpu)
        {
            * Initialize debugging system *
            KdInitSystem(0 KeLoaderBlock)

            * Check for breakin *
            if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C)
        }

        * Raise to HIGH_LEVEL *
        KfRaiseIrql(HIGH_LEVEL)

        * Align stack and make space for the trap frame and NPX frame *
        InitialStack & ~(KTRAP_FRAME_ALIGN  1)
        
    函数里 初始化线程进程  boots 中然  
        * Switch to new kernel stack and start kernel bootstrapping 启动核引导 * boot中asm代码中
        KiSetupStackAndInitializeKernel(&KiInitialProcessPcb
                                        InitialThread
                                        (PVOID)InitialStack
                                        (PKPRCB)__readfsdword(KPCR_PRCB)
                                        (CCHAR)Cpu
                                        KeLoaderBlock)
         里  物理页面清零
    }
    +++++++++++++++++++++++++++++++++++++++++
    VOID
    FASTCALL
    KiRosPrepareForSystemStartup(IN ULONG Dummy
                                 IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
    {
        PLOADER_PARAMETER_BLOCK NtLoaderBlock
        ULONG size i  0 *ent
    #if defined(_X86_)
        PKTSS Tss
        PKGDTENTRY TssEntry
        KDESCRIPTOR IdtDescriptor

        __sidt(&IdtDescriptorLimit) 
        RtlCopyMemory(KiBootIdt (PVOID)IdtDescriptorBase IdtDescriptorLimit + 1)
        IdtDescriptorBase  (ULONG)&KiBootIdt 变量重 启动
        IdtDescriptorLimit  sizeof(KiBootIdt)  1

        * Load the GDT and IDT *
        Ke386SetGlobalDescriptorTable(&KiGdtDescriptorLimit) 全局描述符
        __lidt(&IdtDescriptorLimit)                          局部描述符 

        * Initialize the boot TSS *
        Tss  &KiBootTss 指 TSS 变量
        
        TssEntry  &KiBootGdt[KGDT_TSS  sizeof(KGDTENTRY)]
        TssEntry>HighWordBitsType  I386_TSS
        TssEntry>HighWordBitsPres  1
        TssEntry>HighWordBitsDpl  0
        TssEntry>BaseLow  (USHORT)((ULONG_PTR)Tss & 0xFFFF)
        TssEntry>HighWordBytesBaseMid  (UCHAR)((ULONG_PTR)Tss >> 16)
        TssEntry>HighWordBytesBaseHi  (UCHAR)((ULONG_PTR)Tss >> 24)

        * Set the TSS selector *
        Ke386SetTr(KGDT_TSS) 安装TSS 寄存器变量
    #endif

    #if defined(_M_PPC)
         Zero bats  We might have residual bats set that will interfere with
         our mapping of ofwldr
        for (i  0 i < 4 i++)
        {
            SetBat(i 0 0 0) SetBat(i 1 0 0)
        }
        KiSetupSyscallHandler()  什意思
        
        DbgPrint(Kernel Power (08x)\n LoaderBlock)
        DbgPrint(ArchExtra (08x)\n LoaderBlock>ArchExtra)
    #endif

        * Save pointer to ROS Block *
        KeRosLoaderBlock  LoaderBlock

        * Save memory manager data *
        KeMemoryMapRangeCount  0
        if (LoaderBlock>Flags & MB_FLAGS_MMAP_INFO)  映射BIOS 存
        {
            * We have a memory map from the nice BIOS *
            ent  ((PULONG)(LoaderBlock>MmapAddr  sizeof(ULONG)))
            size  *ent
            i  0

            * Map it until we run out of size *5
            while (i < LoaderBlock>MmapLength)
            {
                * Copy into the Kernel Memory Map *
                memcpy (&KeMemoryMap[KeMemoryMapRangeCount]
                (PVOID)(LoaderBlock>MmapAddr + i)
                sizeof(ADDRESS_RANGE))

                * Increase Memory Map Count *
                KeMemoryMapRangeCount++

                * Increase Size *
                i + size
            }

            * Save data *
            LoaderBlock>MmapLength  KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE)
            LoaderBlock>MmapAddr  (ULONG)KeMemoryMap
        }
        else
        {
            * Nothing from BIOS *
            LoaderBlock>MmapLength  0
            LoaderBlock>MmapAddr  (ULONG)KeMemoryMap
        }

        * Convert the loader block *
        KiRosFrldrLpbToNtLpb(KeRosLoaderBlock &NtLoaderBlock)

    #if defined(_M_PPC)
        DbgPrint(Finished KiRosFrldrLpbToNtLpb\n)
    #endif

        * Do general System Startup *
        KiSystemStartupReal(NtLoaderBlock) kiinitc 文件中
    }
    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Bootsect MBRasm 扇区磁盘中 程序  freeldrsys 载入存  
     然 freeldrsys  载入存 ntoskernlexe  启动

     call _KiInitializeKernel@24   *****非常关键*   初始化核 容里面
                    KiSetupStackAndInitializeKernel  调 初始化核函数中完成疑问处进程线程什时候创建?
    VOID
    NTAPI                                        
    KiInitializeKernel(IN PKPROCESS InitProcess 
                       IN PKTHREAD InitThread   
                       IN PVOID IdleStack
                       IN PKPRCB Prcb
                       IN CCHAR Number
                       IN PLOADER_PARAMETER_BLOCK LoaderBlock)
    {
        BOOLEAN NpxPresent
        ULONG FeatureBits
        ULONG PageDirectory[2]
        PVOID DpcStack
        ULONG Vendor[3]

        * Detect and set the CPU Type *
        KiSetProcessorType() 设置cpu类型

        * Set CR0 features based on detected CPU *
        KiSetCR0Bits()  设置页面 寄存器类型

        * Check if an FPU is present *
        NpxPresent  KiIsNpxPresent()

        * Initialize the Power Management Support for this PRCB *
        PoInitializePrcb(Prcb)

        * Bugcheck if this is a 386 CPU *
        if (Prcb>CpuType  3) KeBugCheckEx(0x5D 0x386 0 0 0)

        * Get the processor features for the CPU *
        FeatureBits  KiGetFeatureBits()

        * Set the default NX policy (optin) *
        SharedUserData>NXSupportPolicy  NX_SUPPORT_POLICY_OPTIN

        * Check if NPX is always on *
        if (strstr(KeLoaderBlock>LoadOptions NOEXECUTEALWAYSON))
        {
            * Set it always on *
            SharedUserData>NXSupportPolicy  NX_SUPPORT_POLICY_ALWAYSON
            FeatureBits | KF_NX_ENABLED
        }
        else if (strstr(KeLoaderBlock>LoadOptions NOEXECUTEOPTOUT))
        {
            * Set it in optout mode *
            SharedUserData>NXSupportPolicy  NX_SUPPORT_POLICY_OPTOUT
            FeatureBits | KF_NX_ENABLED
        }
        else if ((strstr(KeLoaderBlock>LoadOptions NOEXECUTEOPTIN)) ||
                 (strstr(KeLoaderBlock>LoadOptions NOEXECUTE)))
        {
            * Set the feature bits *
            FeatureBits | KF_NX_ENABLED
        }
        else if ((strstr(KeLoaderBlock>LoadOptions NOEXECUTEALWAYSOFF)) ||
                 (strstr(KeLoaderBlock>LoadOptions EXECUTE)))
        {
            * Set disabled mode *
            SharedUserData>NXSupportPolicy  NX_SUPPORT_POLICY_ALWAYSOFF
            FeatureBits | KF_NX_DISABLED
        }

        * Save feature bits *
        Prcb>FeatureBits  FeatureBits

        * Save CPU state *
        KiSaveProcessorControlState(&Prcb>ProcessorState)

        * Get cache line information for this CPU *
        KiGetCacheInformation()

        * Initialize spinlocks and DPC data *
        KiInitSpinLocks(Prcb Number)

        * Check if this is the Boot CPU *
        if (Number)  启动CPU
        {
            * Set Node Data *
            KeNodeBlock[0]  &KiNode0
            Prcb>ParentNode  KeNodeBlock[0]
            KeNodeBlock[0]>ProcessorMask  Prcb>SetMember

            * Set bootlevel flags *
            KeI386NpxPresent  NpxPresent
            KeI386CpuType  Prcb>CpuType
            KeI386CpuStep  Prcb>CpuStep
            KeProcessorArchitecture  PROCESSOR_ARCHITECTURE_INTEL
            KeProcessorLevel  (USHORT)Prcb>CpuType
            if (Prcb>CpuID) KeProcessorRevision  Prcb>CpuStep
            KeFeatureBits  FeatureBits
            KeI386FxsrPresent  (KeFeatureBits & KF_FXSR)  TRUE  FALSE
            KeI386XMMIPresent  (KeFeatureBits & KF_XMMI)  TRUE  FALSE

            * Detect 8byte compare exchange support *
            if ((KeFeatureBits & KF_CMPXCHG8B))
            {
                * Copy the vendor string *
                RtlCopyMemory(Vendor Prcb>VendorString sizeof(Vendor))

                * Bugcheck the system Windows *requires* this *
                KeBugCheckEx(0x5D
                             (1 << 24 ) | (Prcb>CpuType << 16) | Prcb>CpuStep
                             Vendor[0]
                             Vendor[1]
                             Vendor[2])
            }

            * Set the current MP Master KPRCB to the Boot PRCB *
            Prcb>MultiThreadSetMaster  Prcb

            * Lower to APC_LEVEL *
            KeLowerIrql(APC_LEVEL)

            * Initialize some spinlocks *
            KeInitializeSpinLock(&KiFreezeExecutionLock)
            KeInitializeSpinLock(&Ki486CompatibilityLock)

            * Initialize portable parts of the OS *
            KiInitSystem()      初始化系统 变量 尤系统服务表 函数

            * Initialize the Idle Process and the Process Listhead *
            InitializeListHead(&KiProcessListHead)
            PageDirectory[0]  0
            PageDirectory[1]  0
            初始化进程 赋值
            KeInitializeProcess(InitProcess
                                0
                                0xFFFFFFFF
                                PageDirectory
                                FALSE)
            InitProcess>QuantumReset  MAXCHAR
        }
        else
        {
            * FIXME *
            DPRINT1(SMP Boot support not yet present\n)
        }

        * Setup the Idle Thread * 安装空闲线程 安装
        KeInitializeThread(InitProcess
                           InitThread
                           NULL
                           NULL
                           NULL
                           NULL
                           NULL
                           IdleStack)

        InitThread>NextProcessor  Number
        InitThread>Priority  HIGH_PRIORITY
        InitThread>State  Running
        InitThread>Affinity  1 << Number
        InitThread>WaitIrql  DISPATCH_LEVEL
        InitProcess>ActiveProcessors  1 << Number

        * HACK for MmUpdatePageDir * 处单线程  建立线程 赋值初始化进程
        ((PETHREAD)InitThread)>ThreadsProcess  (PEPROCESS)InitProcess

        * Set basic CPU Features that user mode can read *
        SharedUserData>ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] 
            (KeFeatureBits & KF_MMX)  TRUE FALSE
        SharedUserData>ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] 
            (KeFeatureBits & KF_CMPXCHG8B)  TRUE FALSE
        SharedUserData>ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] 
            ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI))  TRUE FALSE
        SharedUserData>ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] 
            ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64))  TRUE FALSE
        SharedUserData>ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] 
            (KeFeatureBits & KF_3DNOW)  TRUE FALSE
        SharedUserData>ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] 
            (KeFeatureBits & KF_RDTSC)  TRUE FALSE

        * Set up the threadrelated fields in the PRCB *
        Prcb>CurrentThread  InitThread前线程等 空闲线程  没线程 
        Prcb>NextThread  NULL
        Prcb>IdleThread  InitThread  第线程终堕落 空闲线程

        * Initialize the Kernel Executive * 执行体阶段  关键处
        ExpInitializeExecutive(Number LoaderBlock)
        执行体 完成变成线程   返回 未必执行   
        然回 boots 中 页面清零函数中
        *
        call @KfLowerIrql@4        降低中断级 引起 线程调度
        * Set the right wait IRQL *
        mov byte ptr [ebx+KTHREAD_WAIT_IRQL] DISPATCH_LEVEL
        
        * Jump into the idle loop *
        jmp @KiIdleLoop@0             Idleexe 系统线程 处理脏 页面
        *
        * Only do this on the boot CPU *
        if (Number)
        {
            * Calculate the time reciprocal *
            KiTimeIncrementReciprocal 
                KiComputeReciprocal(KeMaximumIncrement
                                    &KiTimeIncrementShiftCount)
            * Update DPC Values in case they got updated by the executive *
            Prcb>MaximumDpcQueueDepth  KiMaximumDpcQueueDepth
            Prcb>MinimumDpcRate  KiMinimumDpcRate
            Prcb>AdjustDpcThreshold  KiAdjustDpcThreshold

            * Allocate the DPC Stack *
            DpcStack  MmCreateKernelStack(FALSE 0)
            
            if (DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE 1 0 0 0)
            Prcb>DpcStack  DpcStack
            * Allocate the IOPM save area *
            Ki386IopmSaveArea  ExAllocatePoolWithTag(PagedPool
                                                      PAGE_SIZE * 2
                                                      '  eK')
            if (Ki386IopmSaveArea)
            {
                * Bugcheck We need this for V86VDM support *
                KeBugCheckEx(NO_PAGES_AVAILABLE 2 PAGE_SIZE * 2 0 0)
            }
        }
        * Raise to Dispatch *
        KfRaiseIrql(DISPATCH_LEVEL)
        * Set the Idle Priority to 0 This will jump into Phase 1 *
        KeSetPriorityThread(InitThread 0)
        * If there's no thread scheduled put this CPU in the Idle summary *
        KiAcquirePrcbLock(Prcb)
        if (Prcb>NextThread) KiIdleSummary | 1 << Number
        KiReleasePrcbLock(Prcb)

        * Raise back to HIGH_LEVEL and clear the PRCB for the loader block *
        KfRaiseIrql(HIGH_LEVEL)
        LoaderBlock>Prcb  0
    }
    ++++++++++++++++++++++++++++++++++++++++++++++

    VOID
    NTAPI
    ExpInitializeExecutive(IN ULONG Cpu            初始化执行体 组件
                           IN PLOADER_PARAMETER_BLOCK LoaderBlock)
    {
        PNLS_DATA_BLOCK NlsData
        CHAR Buffer[256]
        ANSI_STRING AnsiPath
        NTSTATUS Status
        PCHAR CommandLine PerfMem
        ULONG PerfMemUsed
        PLDR_DATA_TABLE_ENTRY NtosEntry
        PRTL_MESSAGE_RESOURCE_ENTRY MsgEntry
        ANSI_STRING CsdString
        ULONG Remaining  0
        PCHAR RcEnd  NULL
        CHAR VersionBuffer [65]

        * Validate Loader *
        if (ExpIsLoaderValid(LoaderBlock))
        {
            * Invalid loader version *
            KeBugCheckEx(MISMATCHED_HAL
                         3
                         LoaderBlock>Extension>Size
                         LoaderBlock>Extension>MajorVersion
                         LoaderBlock>Extension>MinorVersion)
        }

        * Initialize PRCB pool lookaside pointers *
        ExInitPoolLookasidePointers()

        * Check if this is an application CPU *
        if (Cpu)
        {
            * Then simply initialize it with HAL *
            if (HalInitSystem(ExpInitializationPhase LoaderBlock))
            {
                * Initialization failed *
                KeBugCheck(HAL_INITIALIZATION_FAILED)
            }

            * We're done *
            return
        }

        * Assume no textmode or remote boot *
        ExpInTextModeSetup  FALSE
        IoRemoteBootClient  FALSE

        * Check if we have a setup loader block *
        if (LoaderBlock>SetupLdrBlock)
        {
            * Check if this is textmode setup *
            if (LoaderBlock>SetupLdrBlock>Flags & SETUPLDR_TEXT_MODE) ExpInTextModeSetup  TRUE

            * Check if this is network boot *
            if (LoaderBlock>SetupLdrBlock>Flags & SETUPLDR_REMOTE_BOOT)
            {
                * Set variable *
                IoRemoteBootClient  TRUE

                * Make sure we're actually booting off the network *
                ASSERT(_memicmp(LoaderBlock>ArcBootDeviceName net(0) 6))
            }
        }

        * Set phase to 0 *
        ExpInitializationPhase  0

        * Get boot command line *
        CommandLine  LoaderBlock>LoadOptions
        if (CommandLine)
        {
            * Upcase it for comparison and check if we're in performance mode *
            _strupr(CommandLine)
            PerfMem  strstr(CommandLine PERFMEM)
            if (PerfMem)
            {
                * Check if the user gave a number of bytes to use *
                PerfMem  strstr(PerfMem )
                if (PerfMem)
                {
                    * Read the number of pages we'll use *
                    PerfMemUsed  atol(PerfMem + 1) * (1024 * 1024  PAGE_SIZE)
                    if (PerfMem)
                    {
                        * FIXME TODO *
                        DPRINT1(BBT performance mode not yet supported
                                PERFMEM option ignored\n)
                    }
                }
            }

            * Check if we're burning memory *
            PerfMem  strstr(CommandLine BURNMEMORY)
            if (PerfMem)
            {
                * Check if the user gave a number of bytes to use *
                PerfMem  strstr(PerfMem )
                if (PerfMem)
                {
                    * Read the number of pages we'll use *
                    PerfMemUsed  atol(PerfMem + 1) * (1024 * 1024  PAGE_SIZE)
                    if (PerfMem)
                    {
                        * FIXME TODO *
                        DPRINT1(Burnable memory support not yet present
                                BURNMEM option ignored\n)
                    }
                }
            }
        }

        * Setup NLS Base and offsets *
        NlsData  LoaderBlock>NlsData
        ExpNlsTableBase  NlsData>AnsiCodePageData
        ExpAnsiCodePageDataOffset  0
        ExpOemCodePageDataOffset  ((ULONG_PTR)NlsData>OemCodePageData 
                                    (ULONG_PTR)NlsData>AnsiCodePageData)
        ExpUnicodeCaseTableDataOffset  ((ULONG_PTR)NlsData>UnicodeCodePageData 
                                         (ULONG_PTR)NlsData>AnsiCodePageData)

        * Initialize the NLS Tables *
        RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
                                 ExpAnsiCodePageDataOffset)
                         (PVOID)((ULONG_PTR)ExpNlsTableBase +
                                 ExpOemCodePageDataOffset)
                         (PVOID)((ULONG_PTR)ExpNlsTableBase +
                                 ExpUnicodeCaseTableDataOffset)
                         &ExpNlsTableInfo)

        RtlResetRtlTranslations(&ExpNlsTableInfo)

        * Now initialize the HAL *
        if (HalInitSystem(ExpInitializationPhase LoaderBlock))
        {
            * HAL failed to initialize bugcheck *
            KeBugCheck(HAL_INITIALIZATION_FAILED)
        }

        * Make sure interrupts are active now *
        _enable()

        * Clear the crypto exponent *
        SharedUserData>CryptoExponent  0

        * Set global flags for the checked build *
    #if DBG
        NtGlobalFlag | FLG_ENABLE_CLOSE_EXCEPTIONS |
                        FLG_ENABLE_KDEBUG_SYMBOL_LOAD
    #endif

        * Setup NT System Root Path *
        sprintf(Buffer Cs LoaderBlock>NtBootPathName)

        * Convert to ANSI_STRING and nullterminate it *
        RtlInitString(&AnsiPath Buffer)
        Buffer[AnsiPathLength]  ANSI_NULL

        * Get the string from KUSER_SHARED_DATA's buffer *
        RtlInitEmptyUnicodeString(&NtSystemRoot
                                  SharedUserData>NtSystemRoot
                                  sizeof(SharedUserData>NtSystemRoot))

        * Now fill it in *
        Status  RtlAnsiStringToUnicodeString(&NtSystemRoot &AnsiPath FALSE)
        if (NT_SUCCESS(Status)) KeBugCheck(SESSION3_INITIALIZATION_FAILED)

        * Setup bugcheck messages *
        KiInitializeBugCheck()

        * Setup initial system settings *
        CmGetSystemControlValues(LoaderBlock>RegistryBase CmControlVector)

        * Load static defaults for Service Pack 1 and add our SVN revision *
        CmNtCSDVersion  0x100 | (KERNEL_VERSION_BUILD_HEX << 16)
        CmNtCSDReleaseType  0

        * Set Service Pack data for Service Pack 1 *
        CmNtSpBuildNumber  1830
        if ((CmNtCSDVersion & 0xFFFF0000))
        {
            * Check the release type *
            if (CmNtCSDReleaseType  1) CmNtSpBuildNumber | 1830 << 16
        }

        * Initialize the executive at phase 0 *
        if (ExInitSystem()) KeBugCheck(PHASE0_INITIALIZATION_FAILED)

        * Initialize the memory manager at phase 0 *
        if (MmInitSystem(0 LoaderBlock)) KeBugCheck(PHASE0_INITIALIZATION_FAILED)

        * Load boot symbols *
        ExpLoadBootSymbols(LoaderBlock)

        * Check if we should break after symbol load *
        if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C)

        * Check if this loader is compatible with NT 52 *
        if (LoaderBlock>Extension>Size > sizeof(LOADER_PARAMETER_EXTENSION))
        {
            * Setup headless terminal settings *
            HeadlessInit(LoaderBlock)
        }

        * Set system ranges *
        SharedUserData>Reserved1  (ULONG_PTR)MmHighestUserAddress
        SharedUserData>Reserved3  (ULONG_PTR)MmSystemRangeStart

        * Make a copy of the NLS Tables *
        ExpInitNls(LoaderBlock)

        * Get the kernel's load entry *
        NtosEntry  CONTAINING_RECORD(LoaderBlock>LoadOrderListHeadFlink
                                      LDR_DATA_TABLE_ENTRY
                                      InLoadOrderLinks)

        * Check if this is a service pack *
        if (CmNtCSDVersion & 0xFFFF)
        {
            * Get the service pack string *
            Status  RtlFindMessage(NtosEntry>DllBase
                                    11
                                    0
                                    WINDOWS_NT_CSD_STRING
                                    &MsgEntry)
            if (NT_SUCCESS(Status))
            {
                * Setup the string *
                RtlInitAnsiString(&CsdString MsgEntry>Text)

                * Remove trailing newline *
                while ((CsdStringLength > 0) &&
                       ((CsdStringBuffer[CsdStringLength  1]  '\r') ||
                        (CsdStringBuffer[CsdStringLength  1]  '\n')))
                {
                    * Skip the trailing character *
                    CsdStringLength
                }

                * Fill the buffer with version information *
                Status  RtlStringCbPrintfA(Buffer
                                            sizeof(Buffer)
                                            Z uc
                                            &CsdString
                                            (CmNtCSDVersion & 0xFF00) >> 8
                                            (CmNtCSDVersion & 0xFF) 
                                            'A' + (CmNtCSDVersion & 0xFF)  1 
                                            ANSI_NULL)
            }
            else
            {
                * Build default string *
                Status  RtlStringCbPrintfA(Buffer
                                            sizeof(Buffer)
                                            CSD 04x
                                            CmNtCSDVersion)
            }

            * Check for success *
            if (NT_SUCCESS(Status))
            {
                * Fail *
                KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
            }
        }
        else
        {
            * Then this is a beta *
            Status  RtlStringCbCopyExA(Buffer
                                        sizeof(Buffer)
                                        VER_PRODUCTBETA_STR
                                        NULL
                                        &Remaining
                                        0)
            if (NT_SUCCESS(Status))
            {
                * Fail *
                KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
            }

            * Update length *
            CmCSDVersionStringMaximumLength  sizeof(Buffer)  (USHORT)Remaining
        }

        * Check if we have an RC number *
        if (CmNtCSDVersion & 0xFFFF0000)
        {
            * Check if we have no version data yet *
            if ((*Buffer))
            {
                * Set defaults *
                Remaining  sizeof(Buffer)
                RcEnd  Buffer
            }
            else
            {
                * Add comma and space *
                Status  RtlStringCbCatExA(Buffer
                                           sizeof(Buffer)
                                            
                                           &RcEnd
                                           &Remaining
                                           0)
                if (NT_SUCCESS(Status))
                {
                    * Fail *
                    KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
                }
            }

            * Add the version format string *
            Status  RtlStringCbPrintfA(RcEnd
                                        Remaining
                                        v u
                                        (CmNtCSDVersion & 0xFFFF0000) >> 16)
            if (NT_SUCCESS(Status))
            {
                * Fail *
                KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
            }
        }

        * Now setup the final string *
        RtlInitAnsiString(&CsdString Buffer)
        Status  RtlAnsiStringToUnicodeString(&CmCSDVersionString
                                              &CsdString
                                              TRUE)
        if (NT_SUCCESS(Status))
        {
            * Fail *
            KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
        }

        * Add our version *
        Status  RtlStringCbPrintfA(VersionBuffer
                                    sizeof(VersionBuffer)
                                    uu
                                    VER_PRODUCTMAJORVERSION
                                    VER_PRODUCTMINORVERSION)
        if (NT_SUCCESS(Status))
        {
            * Fail *
            KeBugCheckEx(PHASE0_INITIALIZATION_FAILED Status 0 0 0)
        }

        * Build the final version string *
        RtlCreateUnicodeStringFromAsciiz(&CmVersionString VersionBuffer)

        * Check if the user wants a kernel stack trace database *
        if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB)
        {
            * FIXME TODO *
            DPRINT1(Kernelmode stack trace support not yet present
                    FLG_KERNEL_STACK_TRACE_DB flag ignored\n)
        }

        * Check if he wanted exception logging *
        if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
        {
            * FIXME TODO *
            DPRINT1(Kernelmode exception logging support not yet present
                    FLG_ENABLE_EXCEPTION_LOGGING flag ignored\n)
        }

        * Initialize the Handle Table *
        ExpInitializeHandleTables()   执行体中句柄表 系统全局 句柄表进程句柄表

    #if DBG
        * On checked builds allocate the system call count table *
        KeServiceDescriptorTable[0]Count 
            ExAllocatePoolWithTag(NonPagedPool
                                  KiServiceLimit * sizeof(ULONG)
                                  'llaC')

        * Use it for the shadow table too *
        KeServiceDescriptorTableShadow[0]Count  KeServiceDescriptorTable[0]Count

        * Make sure allocation succeeded *
        if (KeServiceDescriptorTable[0]Count)
        {
            * Zero the call counts to 0 *
            RtlZeroMemory(KeServiceDescriptorTable[0]Count
                          KiServiceLimit * sizeof(ULONG))
        }
    #endif

        * Create the Basic Object Manager Types to allow new Object Types *
        if (ObInitSystem()) KeBugCheck(OBJECT_INITIALIZATION_FAILED)

        * Load basic Security for other Managers *
        if (SeInitSystem()) KeBugCheck(SECURITY_INITIALIZATION_FAILED)

        * Initialize the Process Manager *
        if (PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS_INITIALIZATION_FAILED)

        * Initialize the PnP Manager *
        if (PpInitSystem()) KeBugCheck(PP0_INITIALIZATION_FAILED)

        * Initialize the UserMode Debugging Subsystem *
        DbgkInitialize()

        * Calculate the tick count multiplier *
        ExpTickCountMultiplier  ExComputeTickCountMultiplier(KeMaximumIncrement)
        SharedUserData>TickCountMultiplier  ExpTickCountMultiplier

        * Set the OS Version *
        SharedUserData>NtMajorVersion  NtMajorVersion
        SharedUserData>NtMinorVersion  NtMinorVersion

        * Set the machine type *
        SharedUserData>ImageNumberLow  IMAGE_FILE_MACHINE_ARCHITECTURE
        SharedUserData>ImageNumberHigh  IMAGE_FILE_MACHINE_ARCHITECTURE
    }

    VOID NTAPI Phase1Initialization(IN PVOID Context)
    {
    * Do the INIT part of Phase 1 which we can free later *
    Phase1InitializationDiscard(Context)
    * Jump into zero page thread *
    MmZeroPageThreadMain(NULL) 页面清零 函数
    }

    VOID
    NTAPI
    Phase1InitializationDiscard(IN PVOID Context)       系统线程 关键函数  
    {
        PLOADER_PARAMETER_BLOCK LoaderBlock  Context
        NTSTATUS Status MsgStatus
        TIME_FIELDS TimeFields
        LARGE_INTEGER SystemBootTime UniversalBootTime OldTime Timeout
        BOOLEAN SosEnabled NoGuiBoot ResetBias  FALSE AlternateShell  FALSE
        PLDR_DATA_TABLE_ENTRY NtosEntry
        PRTL_MESSAGE_RESOURCE_ENTRY MsgEntry
        PCHAR CommandLine Y2KHackRequired SafeBoot Environment
        PCHAR StringBuffer EndBuffer BeginBuffer MpString  
        PINIT_BUFFER InitBuffer
        ANSI_STRING TempString
        ULONG LastTzBias Size Length YearHack  0 Disposition MessageCode  0
        PRTL_USER_PROCESS_INFORMATION ProcessInfo      户进程 会话进程
        KEY_VALUE_PARTIAL_INFORMATION KeyPartialInfo
        UNICODE_STRING KeyName DebugString
        OBJECT_ATTRIBUTES ObjectAttributes
        HANDLE KeyHandle OptionHandle
        PRTL_USER_PROCESS_PARAMETERS ProcessParameters  NULL

        * Allocate the initialization buffer *
        InitBuffer  ExAllocatePoolWithTag(NonPagedPool
                                           sizeof(INIT_BUFFER)
                                           'tinI')
        if (InitBuffer)
        {
            * Bugcheck *
            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED STATUS_NO_MEMORY 8 0 0)
        }

        * Set to phase 1 *
        ExpInitializationPhase  1  阶段 值 增加 1 开始第二次 调

        * Set us at maximum priority *
        KeSetPriorityThread(KeGetCurrentThread() HIGH_PRIORITY)

        * Do Phase 1 HAL Initialization *
        if (HalInitSystem(1 LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED)

        * Get the command line and upcase it *
        CommandLine  _strupr(LoaderBlock>LoadOptions)

        * Check if GUI Boot is enabled *
        NoGuiBoot  (strstr(CommandLine NOGUIBOOT))  TRUE FALSE

        * Get the SOS setting *
        SosEnabled  strstr(CommandLine SOS)  TRUE FALSE

        * Setup the boot driver *
        InbvEnableBootDriver(NoGuiBoot)  启动 端口 视频驱动 然 显示图画 
        InbvDriverInitialize(LoaderBlock 18)

        * Check if GUI boot is enabled *
        if (NoGuiBoot)
        {
            * It is display the boot logo and enable printing strings *
            InbvEnableDisplayString(SosEnabled)
            DisplayBootBitmap(SosEnabled)
        }
        else
        {
            * Release display ownership if not using GUI boot *
            InbvNotifyDisplayOwnershipLost(NULL)

            * Don't allow boottime strings *
            InbvEnableDisplayString(FALSE)
        }

        * Check if this is LiveCD (WinPE) mode *
        if (strstr(CommandLine MININT))
        {
            * Setup WinPE Settings *
            InitIsWinPEMode  TRUE
            InitWinPEModeType | (strstr(CommandLine INRAM))  0x80000000  1
        }

        * Get the kernel's load entry *
        NtosEntry  CONTAINING_RECORD(LoaderBlock>LoadOrderListHeadFlink
                                      LDR_DATA_TABLE_ENTRY
                                      InLoadOrderLinks)

        * Find the banner message *
        MsgStatus  RtlFindMessage(NtosEntry>DllBase
                                   11
                                   0
                                   WINDOWS_NT_BANNER
                                   &MsgEntry)

        * Setup defaults and check if we have a version string *
        StringBuffer  InitBuffer>VersionBuffer
        BeginBuffer  StringBuffer
        EndBuffer  StringBuffer
        Length  256
        if (CmCSDVersionStringLength)
        {
            * Print the version string *
            Status  RtlStringCbPrintfExA(StringBuffer
                                          255
                                          &EndBuffer
                                          &Length
                                          0
                                           wZ
                                          &CmCSDVersionString)
            if (NT_SUCCESS(Status))
            {
                * Bugcheck *
                KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 7 0 0)
            }
        }
        else
        {
            * No version *
            Length  255
        }

        * Nullterminate the string *
        *EndBuffer++  ANSI_NULL

        * Build the version number *
        StringBuffer  InitBuffer>VersionNumber
        Status  RtlStringCbPrintfA(StringBuffer
                                    24
                                    uu
                                    VER_PRODUCTMAJORVERSION
                                    VER_PRODUCTMINORVERSION)
        if (NT_SUCCESS(Status))
        {
            * Bugcheck *
            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 7 0 0)
        }

        * Check if we had found a banner message *
        if (NT_SUCCESS(MsgStatus))
        {
            * Create the banner message *
            Status  RtlStringCbPrintfA(EndBuffer
                                        Length
                                        MsgEntry>Text
                                        StringBuffer
                                        NtBuildNumber & 0xFFFF
                                        BeginBuffer)
            if (NT_SUCCESS(Status))
            {
                * Bugcheck *
                KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 7 0 0)
            }
        }
        else
        {
            * Use hardcoded banner message *
            Status  RtlStringCbCopyA(EndBuffer Length REACTOS (R)\n)
            if (NT_SUCCESS(Status))
            {
                * Bugcheck *
                KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 7 0 0)
            }
        }

        * Display the version string onscreen *
        InbvDisplayString(EndBuffer)

        * Initialize Power Subsystem in Phase 0 *
        if (PoInitSystem(0)) 
           KeBugCheck(INTERNAL_POWER_ERROR)

        * Check for Y2K hack *
        Y2KHackRequired  strstr(CommandLine YEAR)
        if (Y2KHackRequired) Y2KHackRequired  strstr(Y2KHackRequired )
        if (Y2KHackRequired) YearHack  atol(Y2KHackRequired + 1)

        * Query the clock *
        if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields)))
        {
            * Check if we're using the Y2K hack *
            if (Y2KHackRequired) TimeFieldsYear  (CSHORT)YearHack

            * Convert to time fields *
            RtlTimeFieldsToTime(&TimeFields &SystemBootTime)
            UniversalBootTime  SystemBootTime

            * Check if real time is GMT *
            if (ExpRealTimeIsUniversal)
            {
                * Check if we don't have a valid bias *
                if (ExpLastTimeZoneBias  MAXULONG)
                {
                    * Reset *
                    ResetBias  TRUE
                    ExpLastTimeZoneBias  ExpAltTimeZoneBias
                }

                * Calculate the bias in seconds *
                ExpTimeZoneBiasQuadPart  Int32x32To64(ExpLastTimeZoneBias * 60
                                                        10000000)

                * Set the boot timezone bias *
                SharedUserData>TimeZoneBiasHigh2Time  ExpTimeZoneBiasHighPart
                SharedUserData>TimeZoneBiasLowPart  ExpTimeZoneBiasLowPart
                SharedUserData>TimeZoneBiasHigh1Time  ExpTimeZoneBiasHighPart

                * Convert the boot time to local time and set it *
                UniversalBootTimeQuadPart  SystemBootTimeQuadPart +
                                             ExpTimeZoneBiasQuadPart
            }

            * Update the system time *
            KeSetSystemTime(&UniversalBootTime &OldTime FALSE NULL)

            * Do system callback *
            PoNotifySystemTimeSet()

            * Remember this as the boot time *
            KeBootTime  UniversalBootTime
            KeBootTimeBias  0
        }

        * Initialize all processors *
        if (HalAllProcessorsStarted())
            KeBugCheck(HAL1_INITIALIZATION_FAILED)

    #ifdef CONFIG_SMP
        * HACK We should use RtlFindMessage and not only fallback to this *
        MpString  MultiProcessor Kernel\r\n
    #endif

        * Setup the MP String *
        RtlInitAnsiString(&TempString MpString)

        * Make sure to remove the \r\n if we actually have a string *
        while ((TempStringLength > 0) &&
               ((TempStringBuffer[TempStringLength  1]  '\r') ||
                (TempStringBuffer[TempStringLength  1]  '\n')))
        {
            * Skip the trailing character *
            TempStringLength
        }

        * Get the information string from our resource file *
        MsgStatus  RtlFindMessage(NtosEntry>DllBase
                                   11
                                   0
                                   KeNumberProcessors > 1 
                                   WINDOWS_NT_INFO_STRING_PLURAL 
                                   WINDOWS_NT_INFO_STRING
                                   &MsgEntry)

        * Get total RAM size *
        Size  MmNumberOfPhysicalPages * PAGE_SIZE  1024  1024

        * Create the string *
        StringBuffer  InitBuffer>VersionBuffer
        Status  RtlStringCbPrintfA(StringBuffer
                                    256
                                    NT_SUCCESS(MsgStatus) 
                                    MsgEntry>Text 
                                    u System Processor [u MB Memory] Z\n
                                    KeNumberProcessors
                                    Size
                                    &TempString)
        if (NT_SUCCESS(Status))
        {
            * Bugcheck *
            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 4 0 0)
        }

        * Display RAM and CPU count *
        InbvDisplayString(StringBuffer)

        * Update the progress bar *
        InbvUpdateProgressBar(5)

        * Call OB initialization again *
        if (ObInitSystem()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED)

        * Initialize Basic System Objects and Worker Threads *
        if (ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED 0 0 1 0)

        * Initialize the later stages of the kernel *
        if (KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED 0 0 2 0)

        * Call KD Providers at Phase 1 *
        if (KdInitSystem(ExpInitializationPhase KeLoaderBlock))
        {
            * Failed bugcheck *
            KeBugCheckEx(PHASE1_INITIALIZATION_FAILED 0 0 3 0)
        }

        * Initialize the SRM in Phase 1 *
        if (SeInitSystem()) KeBugCheck(SECURITY1_INITIALIZATION_FAILED)

        * Update the progress bar *
        InbvUpdateProgressBar(10)

        * Create SystemRoot Link *
        Status  ExpCreateSystemRootLink(LoaderBlock)
        if (NT_SUCCESS(Status))
        {
            * Failed to create the system root link *
            KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED Status 0 0 0)
        }

        * Set up Region Maps Sections and the Paging File *
        if (MmInitSystem(1 LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED)

        * Create NLS section *
        ExpInitNls(KeLoaderBlock)

        * Initialize Cache Views *
        if (CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED)

        * Initialize the Registry *
        if (CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED)

        * Initialize Prefetcher *
        CcPfInitializePrefetcher()

        * Update progress bar *
        InbvUpdateProgressBar(15)

        * Update timezone information *
        LastTzBias  ExpLastTimeZoneBias
        ExRefreshTimeZoneInformation(&SystemBootTime)

        * Check if we're resetting timezone data *
        if (ResetBias)
        {
            * Convert the local time to system time *
            ExLocalTimeToSystemTime(&SystemBootTime &UniversalBootTime)
            KeBootTime  UniversalBootTime
            KeBootTimeBias  0

            * Set the new time *
            KeSetSystemTime(&UniversalBootTime &OldTime FALSE NULL)
        }
        else
        {
            * Check if the timezone switched and update the time *
            if (LastTzBias  ExpLastTimeZoneBias) 
            ZwSetSystemTime(NULL NULL)
        }

        * Initialize the File System Runtime Library *
        if (FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED)

        * Initialize range lists *
        RtlInitializeRangeListPackage()

        * Report all resources used by HAL *
        HalReportResourceUsage()

        * Call the debugger DLL *
        KdDebuggerInitialize1(LoaderBlock)

        * Setup PnP Manager in phase 1 *
        if (PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED)

        * Update progress bar *
        InbvUpdateProgressBar(20)

        * Initialize LPC *
        if (LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED)

        * Make sure we have a command line *
        if (CommandLine)
        {
            * Check if this is a safe mode boot *
            SafeBoot  strstr(CommandLine SAFEBOOT)
            if (SafeBoot)
            {
                * Check what kind of boot this is *
                SafeBoot + 9
                if (strncmp(SafeBoot MINIMAL 7))
                {
                    * Minimal mode *
                    InitSafeBootMode  1
                    SafeBoot + 7
                    MessageCode  BOOTING_IN_SAFEMODE_MINIMAL
                }
                else if (strncmp(SafeBoot NETWORK 7))
                {
                    * With Networking *
                    InitSafeBootMode  1
                    SafeBoot + 7
                    MessageCode  BOOTING_IN_SAFEMODE_NETWORK
                }
                else if (strncmp(SafeBoot DSREPAIR 8))
                {
                    * Domain Server Repair *
                    InitSafeBootMode  3
                    SafeBoot + 8
                    MessageCode  BOOTING_IN_SAFEMODE_DSREPAIR

                }
                else
                {
                    * Invalid *
                    InitSafeBootMode  0
                }

                * Check if there's any settings left *
                if (*SafeBoot)
                {
                    * Check if an alternate shell was requested *
                    if (strncmp(SafeBoot (ALTERNATESHELL) 16))
                    {
                        * Remember this for later *
                        AlternateShell  TRUE
                    }
                }

                * Find the message to print out *
                Status  RtlFindMessage(NtosEntry>DllBase
                                        11
                                        0
                                        MessageCode
                                        &MsgEntry)
                if (NT_SUCCESS(Status))
                {
                    * Display it *
                    InbvDisplayString(MsgEntry>Text)
                }
            }
        }

        * Make sure we have a command line *
        if (CommandLine)
        {
            * Check if bootlogging is enabled *
            if (strstr(CommandLine BOOTLOG))
            {
                * Find the message to print out *
                Status  RtlFindMessage(NtosEntry>DllBase
                                        11
                                        0
                                        BOOTLOG_ENABLED
                                        &MsgEntry)
                if (NT_SUCCESS(Status))
                {
                    * Display it *
                    InbvDisplayString(MsgEntry>Text)
                }

                * Setup boot logging *
                IopInitializeBootLogging(LoaderBlock InitBuffer>BootlogHeader)
            }
        }

        * Setup the Executive in Phase 2 *
        ExInitSystemPhase2()

        * Update progress bar *
        InbvUpdateProgressBar(25)

    #ifdef _WINKD_
        * No KD Time Slip is pending *
        KdpTimeSlipPending  0
    #endif

        * Initialize inplace execution support *
        XIPInit(LoaderBlock)

        * Set maximum update to 75 *
        InbvSetProgressBarSubset(25 75)

        * Initialize the IO Subsystem *
        if (IoInitSystem(LoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED)

        * Set maximum update to 100 *
        InbvSetProgressBarSubset(0 100)

        * Are we in safe mode *
        if (InitSafeBootMode)
        {
            * Open the safe boot key *
            RtlInitUnicodeString(&KeyName
                                 L\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET
                                 L\\CONTROL\\SAFEBOOT)
            InitializeObjectAttributes(&ObjectAttributes
                                       &KeyName
                                       OBJ_CASE_INSENSITIVE
                                       NULL
                                       NULL)
            Status  ZwOpenKey(&KeyHandle KEY_ALL_ACCESS &ObjectAttributes)
            if (NT_SUCCESS(Status))
            {
                * First check if we have an alternate shell *
                if (AlternateShell)
                {
                    * Make sure that the registry has one setup *
                    RtlInitUnicodeString(&KeyName LAlternateShell)
                    Status  NtQueryValueKey(KeyHandle
                                             &KeyName
                                             KeyValuePartialInformation
                                             &KeyPartialInfo
                                             sizeof(KeyPartialInfo)
                                             &Length)
                    if (NT_SUCCESS(Status)) AlternateShell  FALSE
                }

                * Create the option key *
                RtlInitUnicodeString(&KeyName LOption)
                InitializeObjectAttributes(&ObjectAttributes
                                           &KeyName
                                           OBJ_CASE_INSENSITIVE
                                           KeyHandle
                                           NULL)
                Status  ZwCreateKey(&OptionHandle
                                     KEY_ALL_ACCESS
                                     &ObjectAttributes
                                     0
                                     NULL
                                     REG_OPTION_VOLATILE
                                     &Disposition)
                NtClose(KeyHandle)

                * Check if the key create worked *
                if (NT_SUCCESS(Status))
                {
                    * Write the safe boot type *
                    RtlInitUnicodeString(&KeyName LOptionValue)
                    NtSetValueKey(OptionHandle
                                  &KeyName
                                  0
                                  REG_DWORD
                                  &InitSafeBootMode
                                  sizeof(InitSafeBootMode))

                    * Check if we have to use an alternate shell *
                    if (AlternateShell)
                    {
                        * Remember this for later *
                        Disposition  TRUE
                        RtlInitUnicodeString(&KeyName LUseAlternateShell)
                        NtSetValueKey(OptionHandle
                                      &KeyName
                                      0
                                      REG_DWORD
                                      &Disposition
                                      sizeof(Disposition))
                    }

                    * Close the options key handle *
                    NtClose(OptionHandle)
                }
            }
        }

        * Are we in Win PE mode *
        if (InitIsWinPEMode)
        {
            * Open the safe control key *
            RtlInitUnicodeString(&KeyName
                                 L\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET
                                 L\\CONTROL)
            InitializeObjectAttributes(&ObjectAttributes
                                       &KeyName
                                       OBJ_CASE_INSENSITIVE
                                       NULL
                                       NULL)
            Status  ZwOpenKey(&KeyHandle KEY_ALL_ACCESS &ObjectAttributes)
            if (NT_SUCCESS(Status))
            {
                * Bugcheck *
                KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 6 0 0)
            }

            * Create the MiniNT key *
            RtlInitUnicodeString(&KeyName LMiniNT)
            InitializeObjectAttributes(&ObjectAttributes
                                       &KeyName
                                       OBJ_CASE_INSENSITIVE
                                       KeyHandle
                                       NULL)
            Status  ZwCreateKey(&OptionHandle
                                 KEY_ALL_ACCESS
                                 &ObjectAttributes
                                 0
                                 NULL
                                 REG_OPTION_VOLATILE
                                 &Disposition)
            if (NT_SUCCESS(Status))
            {
                * Bugcheck *
                KeBugCheckEx(PHASE1_INITIALIZATION_FAILED Status 6 0 0)
            }

            * Close the handles *
            NtClose(KeyHandle)
            NtClose(OptionHandle)
        }

        * Unmap Low memory and initialize the MPW and Balancer Thread *
        MmInitSystem(2 LoaderBlock)

        * Update progress bar *
        InbvUpdateProgressBar(80)

        * Initialize VDM support *
    #if defined(_M_IX86)
        KeI386VdmInitialize()
    #endif

        * Initialize Power Subsystem in Phase 1*
        if (PoInitSystem(1)) KeBugCheck(INTERNAL_POWER_ERROR)

        * Initialize the Process Manager at Phase 1 *
        if (PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED)

        * Update progress bar *
        InbvUpdateProgressBar(85)

        * Make sure nobody touches the loader block again *
        if (LoaderBlock  KeLoaderBlock) KeLoaderBlock  NULL
        LoaderBlock  Context  NULL

        * Update progress bar *
        InbvUpdateProgressBar(90)

        * Launch initial process *
        ProcessInfo  &InitBuffer>ProcessInfo 面载入 smssexe 核应程序
        ExpLoadInitialProcess(InitBuffer &ProcessParameters &Environment)

        * Update progress bar *
        InbvUpdateProgressBar(100)

        * Allow strings to be displayed *
        InbvEnableDisplayString(TRUE)

        * Wait 5 seconds for it to initialize *
        TimeoutQuadPart  Int32x32To64(5 10000000) 等面进程5秒钟 变成信号 否崩溃
        Status  ZwWaitForSingleObject(ProcessInfo>ProcessHandle FALSE &Timeout)
        if (InbvBootDriverInstalled) FinalizeBootLogo()
        if (Status  STATUS_SUCCESS)
        {
            * Failed display error * 失败显示 回话启动失败
            RtlInitUnicodeString(&DebugString LINIT Session Manager terminated)
            ZwDisplayString(&DebugString)

            * Bugcheck the system if SMSS couldn't initialize *
            KeBugCheck(SESSION5_INITIALIZATION_FAILED)
        }

        * Close process handles *
        ZwClose(ProcessInfo>ThreadHandle)
        ZwClose(ProcessInfo>ProcessHandle)

        * Free the initial process environment *
        Size  0
        ZwFreeVirtualMemory(NtCurrentProcess()
                            (PVOID*)&Environment
                            &Size
                            MEM_RELEASE)

        * Free the initial process parameters *
        Size  0
        ZwFreeVirtualMemory(NtCurrentProcess()
                            (PVOID*)&ProcessParameters
                            &Size
                            MEM_RELEASE)

        * Increase init phase *
        ExpInitializationPhase++

        * Free the boot buffer *
        ExFreePool(InitBuffer)
    }

    VOID
    NTAPI
    Phase1Initialization(IN PVOID Context)   systemThread 系统线程  入口函数
    {
        * Do the INIT part of Phase 1 which we can free later *
        Phase1InitializationDiscard(Context)

        * Jump into zero page thread *
        MmZeroPageThreadMain(NULL)            堕落空闲线程 页面清零线程
    }
    BOOLEAN
    NTAPI
    PsInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
    {
        * Check the initialization phase *
        switch (ExpInitializationPhase)
        {
        case 0

            * Do Phase 0 *
            return PspInitPhase0(LoaderBlock)安装系统线程 线程

        case 1

            * Do Phase 1 *
            return PspInitPhase1()

        default

            * Don't know any other phase Bugcheck *
            KeBugCheckEx(UNEXPECTED_INITIALIZATION_CALL
                         1
                         ExpInitializationPhase
                         0
                         0)
            return FALSE
        }
    }
    BOOLEAN
    NTAPI
    PspInitPhase1()
    {
        * Initialize the System DLL and return status of operation *
        if (NT_SUCCESS(PspInitializeSystemDll())) return FALSE
        return TRUE 载入映射 NTDLLdll 中介模块
    }

    BOOLEAN
    NTAPI
    PspInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
    {
        NTSTATUS Status
        OBJECT_ATTRIBUTES ObjectAttributes
        HANDLE SysThreadHandle
        PETHREAD SysThread
        MM_SYSTEMSIZE SystemSize
        UNICODE_STRING Name
        OBJECT_TYPE_INITIALIZER ObjectTypeInitializer
        ULONG i

        * Get the system size *
        SystemSize  MmQuerySystemSize()

        * Setup some memory options *
        PspDefaultPagefileLimit  1
        switch (SystemSize)
        {
            * Medimum systems *
            case MmMediumSystem

                * Increase the WS sizes a bit *
                PsMinimumWorkingSet + 10
                PsMaximumWorkingSet + 100

            * Large systems *
            case MmLargeSystem

                * Increase the WS sizes a bit more *
                PsMinimumWorkingSet + 30
                PsMaximumWorkingSet + 300

            * Small and other systems *
            default
                break
        }

        * Setup callbacks *  安装种 回调函数
        for (i  0 i < PSP_MAX_CREATE_THREAD_NOTIFY i++)
        {
            ExInitializeCallBack(&PspThreadNotifyRoutine[i]) 线程安装时候回调函数
        }
        for (i  0 i < PSP_MAX_CREATE_PROCESS_NOTIFY i++)
        {
            ExInitializeCallBack(&PspProcessNotifyRoutine[i]) 进程安装时候回调函数
        }
        for (i  0 i < PSP_MAX_LOAD_IMAGE_NOTIFY i++)
        {
            ExInitializeCallBack(&PspLoadImageNotifyRoutine[i]) 载入模块时候回调函数
        }

        * Setup the quantum table *
        PsChangeQuantumTable(FALSE PsRawPrioritySeparation)

        * Set quota settings *
        if (PspDefaultPagedLimit) PspDefaultPagedLimit  0
        if (PspDefaultNonPagedLimit) PspDefaultNonPagedLimit  0
        if ((PspDefaultNonPagedLimit) && (PspDefaultPagedLimit))
        {
            * Enable givebacks *
            PspDoingGiveBacks  TRUE
        }
        else
        {
            * Disable them *
            PspDoingGiveBacks  FALSE
        }

        * Now multiply limits by 1MB *
        PspDefaultPagedLimit << 20
        PspDefaultNonPagedLimit << 20
        if (PspDefaultPagefileLimit  MAXULONG) PspDefaultPagefileLimit << 20

        * Initialize the Active Process List *
        InitializeListHead(&PsActiveProcessHead)  活动进程链表 
        KeInitializeGuardedMutex(&PspActiveProcessMutex)

        * Get the idle process *
        PsIdleProcess  PsGetCurrentProcess()

        * Setup the locks *
        PsIdleProcess>ProcessLockValue  0
        ExInitializeRundownProtection(&PsIdleProcess>RundownProtect)

        * Initialize the thread list *
        InitializeListHead(&PsIdleProcess>ThreadListHead)

        * Clear kernel time *
        PsIdleProcess>PcbKernelTime  0

        * Initialize Object Initializer *
        RtlZeroMemory(&ObjectTypeInitializer sizeof(ObjectTypeInitializer))
        ObjectTypeInitializerLength  sizeof(ObjectTypeInitializer)
        ObjectTypeInitializerInvalidAttributes  OBJ_OPENLINK |
                                                  OBJ_PERMANENT |
                                                  OBJ_EXCLUSIVE |
                                                  OBJ_OPENIF
        ObjectTypeInitializerPoolType  NonPagedPool
        ObjectTypeInitializerSecurityRequired  TRUE

        * Initialize the Process type *
        RtlInitUnicodeString(&Name LProcess)
        ObjectTypeInitializerDefaultNonPagedPoolCharge  sizeof(EPROCESS)
        ObjectTypeInitializerGenericMapping  PspProcessMapping
        ObjectTypeInitializerValidAccessMask  PROCESS_ALL_ACCESS
        ObjectTypeInitializerDeleteProcedure  PspDeleteProcess
        ObCreateObjectType(&Name &ObjectTypeInitializer NULL &PsProcessType)

        *  Initialize the Thread type  *
        RtlInitUnicodeString(&Name LThread)
        ObjectTypeInitializerLength  sizeof(ObjectTypeInitializer)
        ObjectTypeInitializerDefaultNonPagedPoolCharge  sizeof(ETHREAD)
        ObjectTypeInitializerGenericMapping  PspThreadMapping
        ObjectTypeInitializerValidAccessMask  THREAD_ALL_ACCESS
        ObjectTypeInitializerDeleteProcedure  PspDeleteThread
        ObCreateObjectType(&Name &ObjectTypeInitializer NULL &PsThreadType)

        *  Initialize the Job type  *
        RtlInitUnicodeString(&Name LJob)
        ObjectTypeInitializerLength  sizeof(ObjectTypeInitializer)
        ObjectTypeInitializerDefaultNonPagedPoolCharge  sizeof(EJOB)
        ObjectTypeInitializerGenericMapping  PspJobMapping
        ObjectTypeInitializerValidAccessMask  JOB_OBJECT_ALL_ACCESS
        ObjectTypeInitializerDeleteProcedure  PspDeleteJob
        ObCreateObjectType(&Name &ObjectTypeInitializer NULL &PsJobType)

        * Initialize job structures external to this file *
        PspInitializeJobStructures()

        * Initialize the Working Set data *
        InitializeListHead(&PspWorkingSetChangeHeadList)
        KeInitializeGuardedMutex(&PspWorkingSetChangeHeadLock)

        * Create the CID Handle table *
        PspCidTable  ExCreateHandleTable(NULL)  全局 客户 句柄表
        if (PspCidTable) return FALSE

        * FIXME Initialize LDTVDM support *

        * Setup the reaper *
        ExInitializeWorkItem(&PspReaperWorkItem PspReapRoutine NULL)

        * Set the boot access token *
        PspBootAccessToken  (PTOKEN)(PsIdleProcess>TokenValue & ~MAX_FAST_REFS)

        * Setup default object attributes *
        InitializeObjectAttributes(&ObjectAttributes
                                   NULL
                                   0
                                   NULL
                                   NULL)  啥空

        * Create the Initial System Process *   system 进程
        Status  PspCreateProcess(&PspInitialSystemProcessHandle 初始化进程
                                  PROCESS_ALL_ACCESS
                                  &ObjectAttributes
                                  0
                                  FALSE
                                  0
                                  0
                                  0
                                  FALSE)
        if (NT_SUCCESS(Status)) return FALSE

        * Get a reference to it *
        ObReferenceObjectByHandle(PspInitialSystemProcessHandle
                                  0
                                  PsProcessType
                                  KernelMode
                                  (PVOID*)&PsInitialSystemProcess
                                  NULL)

        * Copy the process names *  
        前面 没 进程结构体 构建 空闲进程 唯单线程吧
        strcpy(PsIdleProcess>ImageFileName Idle)  第进程    空闲进程 
        strcpy(PsInitialSystemProcess>ImageFileName System)  刚创建  系统进程

        * Allocate a structure for the audit name *  审核名字
        PsInitialSystemProcess>SeAuditProcessCreationInfoImageFileName 
            ExAllocatePoolWithTag(PagedPool
                                  sizeof(OBJECT_NAME_INFORMATION)
                                  TAG_SEPA)
        if (PsInitialSystemProcess>SeAuditProcessCreationInfoImageFileName)
        {
            * Allocation failed *
            return FALSE
        }
        * Zero it *
        RtlZeroMemory(PsInitialSystemProcess>
                      SeAuditProcessCreationInfoImageFileName
                     sizeof(OBJECT_NAME_INFORMATION))
        * Setup the system initialization thread *
        Status  PsCreateSystemThread(&SysThreadHandle
                                      THREAD_ALL_ACCESS
                                      &ObjectAttributes
                                      0
                                      NULL
                                      Phase1Initialization  安装系统线程 线程
                                      LoaderBlock)
        if (NT_SUCCESS(Status)) return FALSE
        * Create a handle to it *
        ObReferenceObjectByHandle(SysThreadHandle
                                  0
                                  PsThreadType
                                  KernelMode
                                  (PVOID*)&SysThread
                                  NULL)
        ZwClose(SysThreadHandle)
        SysThreadCreated  TRUE
        * Return success *
        return TRUE
    }
    文档香网(httpswwwxiangdangnet)户传

    《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
    该内容是文档的文本内容,更好的格式请下载文档

    下载文档到电脑,查找使用更方便

    文档的实际排版效果,会与网站的显示效果略有不同!!

    需要 10 香币 [ 分享文档获得香币 ]

    下载文档

    相关文档

    $windows内核情景分析学习笔记

    windows内核情景分析学习笔记6分类: windows MFC2010-10-19 11:37226人阅读评论(0)收藏举报1、用于数据存储的内存区间分类①全局数据所占空间。由编译器在编译...

    3年前   
    365    0

    Windows操作系统及其应用

    Windows操作系统及其应用一. Windows操作系统的若干常识1、 Windows操作系统的主要功能是_B_____。A.实现软、硬件转换B.管理系统所有的软、硬件C.把源程序转换为目标...

    4年前   
    790    0

    双系统卸载Windows7的方法

    双系统完全卸载Windows 7的方法   目前window 7 逐渐代替我们现在电脑系统,在window 7的步入之际,你是否觉得还不适应,是否还在window 7和window XP ...

    10年前   
    7356    0

    Windows Server系统管理实训报告

    江西现代职业技术学院Windows Server系统管理实训报告姓 名 郑济青 学 号 190628590240 学 院 信...

    4年前   
    2130    0

    仿QQ聊天系统课程设计

    仿QQ聊天系统课程设计目录绪论 1一.需求分析 11.1软件功能需求分析 21.2 安全需求分析 2二.总体设计 32.1 软件结构图 32.2 功能描述 32.2.1注册功能概要 42.2....

    3年前   
    663    0

    仿QQ聊天系统实验报告

    软件工程项目实践 大作业 仿QQ软件的设计与实现软件工程项目实践 大作业仿QQ软件的设计与实现班级:学号:姓名:教师:平时成绩30分: + 大作业成绩:70分: = 总分:...

    3年前   
    745    0

    $GetMessage-PeekMessage-SendMessage内核解析

    最近忙公司的项目(或是毕设吧),发现很长时间没有总结了。是该换换脑子了。“为什么没有SendThreadMessage呢?”这个问题,就来自自己平时实现的一些程序逻辑中。在一些具体的场景中,对...

    3年前   
    290    0

    《电力通信网络管理信息系统的设计与实现》源代码

    头文件: /****************************************************************** * All rights reserved...

    5年前   
    962    0

    仿仿瓷及外墙漆工程合同

    仿仿瓷及外墙漆工程合同仿仿瓷及外墙漆工程合同 发包方:***市教育局                                        (以下简称甲方)承包方:***       ...

    10年前   
    561    0

    源代码使用许可协议

    ________源代码使用许可合同甲方:XX软件有限公司 乙方:法定地址: 法定地址:法定代表人: 法定代表人:联系电话: ...

    4年前   
    1731    0

    linux与windows 编程区别

    linux windows 编程的区别 如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix...

    7年前   
    2605    0

    windows实训报告

    实训是教学工作的重要环节,是课堂理论教学的检验和延续,是培养学生实践技能的重要场所。通过实训,使学生能够完成企业windows服务器的配置、管理与维护。通过实际操作,使学生掌握一定的操作技能,能...

    3年前   
    2024    0

    Windows各操作系统常见PPPoE拨号错误代码说明

    Windows各操作系统常见PPPoE拨号错误代码说明本文列出Windows系统使用系统自带的宽带连接拨号可能出现的错误代码及解决方法。一、错误代码678/651Windows XP拨号提示错...

    2年前   
    710    0

    Windows操作系统及其应用操作题复习指南

    《第二章 Windows操作系统及其应用》操作题复习指南 一、学习的主要内容 1.了解:WINDOWS运行环境、桌面和窗口的组成、菜单约定和剪贴板概念。 2.理解:文件、文件夹、路径的概...

    11年前   
    10448    0

    仿写句子80例

    仿写句子80例  仿写句子(一):  1.仿(要求句式相同,字数一样,资料新颖独特,有创意)  例句:青春是多彩的朝霞,映照着广阔的大地;青春是智慧的火花,点缀着灿烂的星空;青春是美丽的鲜花,...

    3年前   
    635    0

    课堂仿写大有可为仿写课堂上的小古文

    课堂仿写大有可为仿写课堂上的小古文  课堂仿写大有可为仿写课堂上的小古文  乡村  乡间农家,竹篱茅屋,临水成村。水边杨柳数(许多)株,中夹(夹杂)桃李。飞燕一双,忽高忽低,来去甚(非常)捷(...

    4年前   
    1622    0

    数据结构大作业(含源代码)

    数据结构大作业作业题目: 职工信息管理系统 姓 名: 学 号: ...

    3年前   
    453    0

    关于异地开发中的源代码管理问题

    关于异地开发中的源代码管理问题最近在带领一个异地的团队在进行.NetB/S系统开发工作。两地相隔1000多公里,两地都有开发人员,源码的统一管理就成了需要解决的问题。针对这个问题,想到如下的解...

    10年前   
    516    0

    2021年PE加载器源代码解析

    1【原创】一段仿真PE加载器行为的程序 以下程序假定PE文件是合法的,所以很多地方都没有提供容错处理bool PELoader(char *lpStaticPEBuff, long lStat...

    2个月前   
    242    0

    计算机源代码编写规范

     计算机源代码编写规范 文件编号: NW506104 ...

    12年前   
    25789    0

    文档贡献者

    奋斗不止500年

    贡献于2024-02-07

    下载需要 10 香币 [香币充值 ]
    亲,您也可以通过 分享原创文档 来获得香币奖励!
    下载文档

    该用户的其他文档