| 注册
home doc ppt pdf
请输入搜索内容

热门搜索

年终总结个人简历事迹材料租赁合同演讲稿项目管理职场社交

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

奋斗不止500年

贡献于2024-02-07

字数:56472

引导序号
引导程
引导执行代码位数
目标文件名称
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、用于数据存储的内存区间分类①全局数据所占空间。由编译器在编译链接时就静态分配好的,与整个进程共存亡。其分配和释放都是不可见、不可为的②局部数据所占的空间。调用函数时自动从堆栈上动态分配的,其寿命取决于函数的作用域。其分配和释放是隐含的。③通过malloc一

奋斗不止500年 3年前 上传371   0

Windows操作系统及其应用

Windows操作系统及其应用一. Windows操作系统的若干常识1、 Windows操作系统的主要功能是_B_____。A.实现软、硬件转换B.管理系统所有的软、硬件C.把源程序转换为目标程序D.进行数据处理 [解析]操作系统属于系统软件,它的主要功能是:管理系统所有的软件和硬件资源。2、 Windows XP 系统是___C___。(请看解析)

豆***2 4年前 上传799   0

双系统卸载Windows7的方法

双系统完全卸载Windows 7的方法   目前window 7 逐渐代替我们现在电脑系统,在window 7的步入之际,你是否觉得还不适应,是否还在window 7和window XP 之间徘徊,为了解决这个问题,很多朋友都是装了双系统(window 7和window xp)本人就是这样,本人把window xp装在C盘,window 7装在了D盘,在厌倦了window xp的时候,可以登

基***7 10年前 上传7359   0

Windows Server系统管理实训报告

江西现代职业技术学院Windows Server系统管理实训报告姓 名 郑济青 学 号 190628590240 学 院 信息工程学院 专 业 计算机网络技术 班 级 19计算机网络(网工)二班 指导教师 王 勉一、 实训目的通过在VMWare中Windo

书***辞 4年前 上传2136   0

仿QQ聊天系统课程设计

仿QQ聊天系统课程设计目录绪论 1一.需求分析 11.1软件功能需求分析 21.2 安全需求分析 2二.总体设计 32.1 软件结构图 32.2 功能描述 32.2.1注册功能概要 42.2.2登录功能概要 42.2.3聊天功能概要 52.3 安全设计 6三.数据库设计 63.1概念结构设计 63.2逻辑结构设计 73.3物理结构设计 7四.详细设计 84.1

文***享 3年前 上传668   0

仿QQ聊天系统实验报告

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

文***品 3年前 上传748   0

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

头文件: /****************************************************************** * All rights reserved. * * 文件名称:baserule.h ******************************************************************/ #ifndef

文***享 5年前 上传966   0

$GetMessage-PeekMessage-SendMessage内核解析

最近忙公司的项目(或是毕设吧),发现很长时间没有总结了。是该换换脑子了。“为什么没有SendThreadMessage呢?”这个问题,就来自自己平时实现的一些程序逻辑中。在一些具体的场景中,对像我这样的初学者来说,往往喜欢通过windwos的消息机制来完成UI线程和worker线程之间的同步,而不是去通过信号量或其他的去做。所以,这个问题一直困惑了自己很久。而现在,就来搞明白这个、googl

奋斗不止500年 3年前 上传294   0

仿仿瓷及外墙漆工程合同

仿仿瓷及外墙漆工程合同仿仿瓷及外墙漆工程合同 发包方:***市教育局                                        (以下简称甲方)承包方:***                                                    (以下简称乙方)甲乙双方依照建筑施工有关合同规定及《合同法》有关规定,经协商订立如下条款。一

g***k 10年前 上传562   0

源代码使用许可协议

________源代码使用许可合同甲方:XX软件有限公司 乙方:法定地址: 法定地址:法定代表人: 法定代表人:联系电话: 联系电话:鉴于:1、 甲方设计开发了________软件,依法对________源代码享有著作权;2、 乙方希望获得________源代码的使用许可,甲方同意授予乙方对________源代

文***享 4年前 上传1736   0

linux与windows 编程区别

linux windows 编程的区别 如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大。我写这篇文章并不是想贬低windows下面开发的人,做windows开发的人看了可能会感觉不舒服,我并不是这个意思,我只是说说我自己的感受,我最早开始学习编程也是在wi

g***7 7年前 上传2606   0

windows实训报告

实训是教学工作的重要环节,是课堂理论教学的检验和延续,是培养学生实践技能的重要场所。通过实训,使学生能够完成企业windows服务器的配置、管理与维护。通过实际操作,使学生掌握一定的操作技能,能认真、细致、准确的操作。通过实践过程,培养学生独立思考、独立工作的能力及团队协作精神。

带***识 3年前 上传2045   0

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

Windows各操作系统常见PPPoE拨号错误代码说明本文列出Windows系统使用系统自带的宽带连接拨号可能出现的错误代码及解决方法。一、错误代码678/651Windows XP拨号提示错误678,远程计算机没反应,如下图:Windows 7/8/8.1/10提示错误代码651,调制解调器(或其他连接设备)报告了一个错误。如下图:注意:Windows 10系统只有在创建新连

教***心 2年前 上传712   0

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

《第二章 Windows操作系统及其应用》操作题复习指南 一、学习的主要内容 1.了解:WINDOWS运行环境、桌面和窗口的组成、菜单约定和剪贴板概念。 2.理解:文件、文件夹、路径的概念;资源管理器窗口的常用操作;控制面板的使用。 3.掌握:工具栏按钮操作、任务栏的操作以及开始菜单的定制;命令行方式;时间与日期的设置、程序的添加与删除、显示器属性的设置;“写字板”、“计算器”、“画图”

n***m 11年前 上传10453   0

仿写句子80例

仿写句子80例  仿写句子(一):  1.仿(要求句式相同,字数一样,资料新颖独特,有创意)  例句:青春是多彩的朝霞,映照着广阔的大地;青春是智慧的火花,点缀着灿烂的星空;青春是美丽的鲜花,装扮着绚丽的人生。  仿句:宽容是__________,__________;宽容是__________,__________。  参考答案:辽阔的大海,蕴蓄着不尽的情思;深邃的湖泊,孕育着无限的

四***廷 3年前 上传643   0

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

课堂仿写大有可为仿写课堂上的小古文  课堂仿写大有可为仿写课堂上的小古文  乡村  乡间农家,竹篱茅屋,临水成村。水边杨柳数(许多)株,中夹(夹杂)桃李。飞燕一双,忽高忽低,来去甚(非常)捷(敏捷)。  仿写: “水边杨柳数株。”  数 比如:铅笔盒里铅笔数只。  什么地方 有 什么东西 许多计数单位(根、株、个、杯)  “来去甚捷”  甚 比如:兔跃甚高。龟行甚迟。  或者

农***轩 4年前 上传1636   0

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

关于异地开发中的源代码管理问题最近在带领一个异地的团队在进行.NetB/S系统开发工作。两地相隔1000多公里,两地都有开发人员,源码的统一管理就成了需要解决的问题。针对这个问题,想到如下的解决方法:   一、利用MicrosoftVisualSourceSafe的Internet功能   优点:   1.考虑使用VSS是因为他与MicrosoftVisualStudio集成的很紧密。可以在

晓***1 10年前 上传521   0

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

数据结构大作业作业题目: 职工信息管理系统 姓 名: 学 号: 班 级: 计算机班 指导教师: 日 期: 2010年X月X日 职工信息管理系统(学院计算机科学

文***享 3年前 上传454   0

2021年PE加载器源代码解析

1【原创】一段仿真PE加载器行为的程序 以下程序假定PE文件是合法的,所以很多地方都没有提供容错处理bool PELoader(char *lpStaticPEBuff, long lStaticPELen){  long lPESignOffset = *(long *)(lpStaticPEBuff + 0x3c);  IMAGE_NT_HEADERS *pINH = (

奋斗不止500年 3个月前 上传256   0

计算机源代码编写规范

 计算机源代码编写规范 文件编号: NW506104 生效日期: 2000.3.20 受控编号: 密级:秘密 版次:Ver2.1 修改状态: 总页数 6 正文 6 附录 0 编制:马云生 审核:袁淮 批

w***1 12年前 上传25792   0

C语言通讯录报告及源代码

XX学院《C语言程序设计》课程设计报告 学 院:_电气与信息工程学院_ 专业班级: 计科班 学生姓名: 学 号: 设计地点(单位)________计算机基础自主学习中心 __ __设计题目:__ 个人通讯录设计_________________

文***享 3年前 上传357   0

1111000111如何写好_仿写句

1111000111如何写好_仿写句如何写好“仿写句”韩冬仿写是高考的必考项之一。但对这一考点的掌握,很多考生还不太熟练。在考查中,考生往往出现以下误区:要么不合要求,要么语意不明,要么没有文采。造成这些现象的原因,主要还是考生平常没有进行严格的训练。可以这样说,不少学生平时在做这种题目时非常毛糙,随意马虎,因而在考试时做得漏洞百出。其实,这种题目只要看清要求,有的放矢,就会做得令自

出***界 9年前 上传692   0

公文写作“模仿秀”

最近几期众秘夜思中,大家谈了不少选取和积累素材的话题。有料在手,如何有效运用到文章写作中,就是今晚的话题的中心。

z***q 5年前 上传1140   0

《大地的话》仿写(多篇)2

《大地的话》仿写(多篇)2   假如你是落叶,  我也不会让你心碎。  这里有待哺的春泥,  在等着与你相会。  你可以随风飞扬,  尽展你的风姿,  然后下坠。  让即将开垦的土壤,  因你的飘落而增肥.  假如你是水滴,  请来到我的体内。  这里有弯弯曲曲的小溪,  辽阔的大海。  你可以在这里交朋友,  和河流哥哥去给花儿浇水。  让你和伙伴成群结队

xiaochuichui 8个月前 上传148   0

《大地的话》仿写(多篇)3

《大地的话》仿写(多篇)3   《大地的话》是一首现代诗,诗人运用拟人化的手法,把大地拟人化为母亲,抒写着大地母亲宽容、慈爱,以及无私奉献的情怀。全诗韵味十足,朗朗上口,有一种清新明快的节奏美。  课后有一道思考题:仿照课文前四节,试着再写一节。对于诗歌的仿写,学生锻炼的很少,大部分同学不知如何写诗,但是当他们把一节节仿写的小诗拿给我看时,我则非常惊喜,不禁想起某位作家的话:儿童就是一

xiaochuichui 8个月前 上传181   0