引导程
引导执行代码位数
目标文件名称
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
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)户传
《香当网》用户分享的内容,不代表《香当网》观点或立场,请自行判断内容的真实性和可靠性!
该内容是文档的文本内容,更好的格式请下载文档