MBR과 부트 섹터를 지나 부트 로더인 Ntldr(비스타 이후 Winload.exe로 변경되었다)를 통해 BCD(Windows Boot Manager)의 실행까지 알아보았다.
이후 BCD는 지정된 시간 동안 입력이 없으면, 기본적으로 지정된 운영제체를 실행하여 부팅을 위한 윈도우 커널 초기화 작업을 진행하게 된다. 이때 부트 파티션에서 커널 초기화에 필요한 적절한 커널(Ntoskrnl.exe외 3가지) 파일과 HAL(Hardware Abstraction Layer) 이미지 등을 로드하고, 레지스트리 %SystemRoot%\System32\Config\System을 HIVE(연결) 하여 디바이스 드라이버를 로드하는 작업을 진행하게 된다(레지스트리에 대해서는 추후 커널과 유저의 소통에서 다룬다).
커널 초기화를 진행하는 Ntos****.exe은 CPU 개수 및 앞서 얘기한 Boot.ini에서 메모리의 PAE 기능 활성화 유무에 따라 아래 4개의 프로세스중 하나가 실행된다.
프로세스와 메모리 기능별 사용하는 커널 프로세스 정보는 다음과 같다.
Ntoskrnl.exe: 1 CPU
Ntkrnlmp.exe: n CPU
Ntkrnlpa.exe: 1 CPU, PAE 활성화
Ntkrpamp.exe: n CPU, PAE 활성화
커널 생성을 위한 작업을 크게 0, 1 두 단계로 나눌수 있으며, 단계 0은 단계 1을 하기 위한 준비 단계라 할 수 있다.
단계 0에서는 인터럽트(Interrupts)를 비활성화 한 이후에 Ntldr(혹은 Winload.exe)로부터 건네 받은 정보를 통해, KiSystemStartup 커널 함수를 호출하며 시작하게 되는데, 대략적인 MBR부터 Ntoskrnl.exe까지 흐름을 그림으로 나타낸다면 다음과 같다.
위 그림을 요약하면, 각 CPU의 인터럽터 컨트롤러 초기화를 먼저 진행한다.
그리고 메모리 관리자를 초기화하고, File system cache와 Non-paged Pool, Paged Pool를 만든다.
그 후 개체 관리자(Object Manger)는 첫번째 프로세스를 할당하기 위해 Security token을 초기화 하고, 프로세스 관리자(Process Manager)는 스스로 Idle Process 와 System Process를 생성하게 된다.
이렇게 단계 0를 마치고, 단계 1에서는 인터럽트를 다시 활성화 한 후, Bootvid.dll(윈도우 로그와 진행바 출력)를 로드하여, 윈도우 부팅 상태 스크린을 출력하게 한다. 그리고 기존에 Ntldr(혹은 Winload.exe)에서 하이브한 System, Hardware 레지스트리를 복사하여 로드한 후에 필요한 드라이버들과 커널의 Executive 영역에 위치한 관리자들을 초기화 한다.
이 진행 순서를 표로 정리하면 아래와 같다.
진행 순서(함수명) | 설명 |
단계 0 | |
Interrupts 비활성화 | 프로세서 초기화를 위해 인터럽트를 비활성화 |
KiSystemStartup | 커널 초기화 시작 |
-HalInitializeProcessor | 프로세서 초기화 시작 |
-KiInitializeKernel | 부트 CPU에서 시스텀 전역 커널 초기화를 진행하여(KiInitSystem), 모든 CPU가 공유하는 데이터 구조체를 초기화한다. |
--KiInitSystem | KeServiceDescriptorTable 초기화 |
--ExpInitializeExecutive | 부트 CPU만이 ExpInitializeExecutive를 호출해 커널 초기화를 진행한다. 이는 단계0의 다른 모든 초기화 작업을 담당한다. (메모리 관리자, 개체 관리자 등) 그 외 CPU는 HalInitSystem만 호출 |
---HalInitSystem | HAL 제어권 획득 각 CPU는 Interrupt의 System interrupt controller 구성하고 CPU시간을 계산하기 위해 Internal clock timer interrupt 구성 |
----MmInitSystem | 메모리 관리자 초기화 |
----ObInitSystem | 개체 관리자 초기화 |
----SeInitSystem | 보안 참조 모니터 초기화, Security token 관리 |
----PsInitSystem | 프로세서 관리자 초기화, PsInitPhase0과 함께 Idle Process, System Process가 생성한다. |
----PpInitSystem | 플러그앤 플레이 관리자 초기화 |
Idle Loop | 스레드를 실행할 수 있는 준비가 완료됨 |
-- KeRaiseIrql | 단계1의 Phase1Initialization 스레드를 수행할 수 있도록 IRQL을 DISPATCH_LEVEL로 설정한다. |
단계 1 | |
Phase1Initialization | Phase1InitializationDiscard를 진행하고, MmZeroPageThread를 통해 스레드의 메모리 해제에 이용되는 Zero-page 스레드를 초기화 한다(2부 11장 참조). |
-Phase1InitializationDiscard | |
--HalInitSystem | Interrupts 활성화 |
--InbvEnableBootDrive | Bootvid.dll(Boot video driver) 윈도우 로그와 함께 진행바가 표시된다. |
--PoInitSystem | Power Manager 초기화 |
--KeSetSystemTime | HalQueryRealTimeClock을 이용하여, 시스템 시간 초기화 |
--KeStartAllProcessors | Non boot CPU들에 대해 초기화 |
--ObInitSystem | 개체 매니저를 초기화 한다(네임스페이스 Root (\), \ObjectTypes, etc 초기화). |
--ExInitSystem | Executive object types(Semaphore, Mutex, Event, Timer 등) 생성 |
--KeInitSystem | 멀티프로세서시 이를 이용하여 커널을 초기화 한다. (Scheduler, SSDT(System service dispatch table) 초기화) |
--KdInitSystem | 커널 디버거 초기화 |
--SeInitSystem | 보안 참조 모니터 초기화 |
--MmInitSystem | 메모리 관리자 초기화 |
--NLS Mapping | 국가 언어 지원(NLS) 테이블을 시스템 공간인 Ntdll.dll에 매핑한다. |
--CcInitializeCacheManager | 캐시 관리자 초기화 |
--CmInitSystem1 | Ntoskrnl.exe 실행 초기 로드한 Hardware 정보 복사하여 레지스트리 System에 하이브한다. |
--FsRtlInitSystem | 글로벌 파일 시스템 드라이버 데이터 구조를 초기화한다. |
--PpInitSystem | 플러그앤 플레이 관리자 초기화 |
--LpcInitSystem | LPC 초기화(LPC포트와 타입, 개체) |
--IoInitSystem | I/O관리자 초기화 드라이버(Driver)와 디바이스(Device) 개체 생성 디이나믹 디바이스(Dynamic device) 초기화 및 할당, WMI 지원과 드라이버를 초기화한다. |
--PoInitSystem | 전원 관리 초기화 |
--PsInitSystem | 프로세스 관리자 초기화, Smss.exe와 Ntdll.dll 찾는다. |
--SeRmInitPhase1 | LPC 서버 스레드를 생성하고, SeRmCommandPort LPC포트을 만들어, Lsass.exe와 통신한다. |
--RtlCreateUserProcess | Smss.exe, 세션 관리자 생성하고 유저 모드 생성을 진행하게 된다. |
현재 시스템에 사용되는 커널을 Windbg의 !lmi nt 혹은 lm vm nt 명령으로 확인할 수 있다.
System과 Idle
시스템 프로세스(System process)는 커널에서만 실행되는 시스템 스레드(System thread)들을 호스팅하는 프로세스로서, 앞서 Ntoskrnl.exe의 커널 생성 단계에서 생성하게 된다. 이는 디바이스 드라이버와 함께 시스템 공간에 로드되어 커널 모드에서 동작하는 스레드를 관리한다. 추가로 시스템 스레드는 커널 모드에서만 호출할 수 있는 PsCreateSystemThread 함수에 의해 생성됨을 알아두자.
유휴 프로세스(Idle process)도 커널 생성 단계에서 생성되며, CPU당 하나의 유휴 스레드를 할당 받아, 유휴 CPU 사용률(남은 CPU 사용률)을 계산하는 역할을 수행한다.
일부 프로그램에서 다른 이름으로 표기되지만(Process explorer는 System Idle Process라 하고, Tlist에서는 System Process라 한다), 이는 표시만 다를 뿐 PID가 동일한, 같은 프로세스이다.
같은 프로세스이지만, 표시 이름은 다르다. 4개의 프로세서를 위해 개별 유휴 스레드가 실행된다.
이들 프로세스는 CPU 현황과 관리를 돕는 프로세스로서, Windbg에서 !cpuinfo, !cpuid 명령으로 프로세서 정보를 확인할 수 있다.
kd> !cpuinfo
CP F/M/S Manufacturer MHz PRCB Signature MSR 8B Signature Features
0 6,30,5 GenuineIntel 2691 0000000000000000 0000000000000000 00013fff
Cached Update Signature 0000000000000000
Initial Update Signature 0000000000000000
kd> !cpuid
CP F/M/S Manufacturer MHz
0 6,30,5 GenuineIntel 2691
'WebBook > 윈도우 구조' 카테고리의 다른 글
시스템 프로세스(Windows Startup Process) - 서비스 관리자 Services.exe (0) | 2022.03.14 |
---|---|
시스템 프로세스(Windows Startup Process) - 보안 관리자 Lsass.exe (0) | 2022.03.05 |
시스템 프로세스(Windows Startup Process) - 로그인 관리자 Winlogon.exe (0) | 2022.03.03 |
시스템 프로세스(Windows Startup Process) - 서브시스템(Subsystem) (0) | 2022.02.21 |
MBR에서 로그온까지 (0) | 2022.02.09 |