시스템부팅절차 (System Boot Sequence) 이번에는 Windows NT 시스템을부팅한후부터콘솔상에 Windows Log On 화면이나타날때까지의과정을살펴보자. 시스템의부팅절차를알아보는것은여러분이 Device Driver를설계하는데유용할것이다. 시스템의부팅절차를이해하면여러분이개발한드라이버가언제로드되고, 시스템의부팅과정동안여러분이개발한드라이버의어떤부분을호출할것인가를결정할수있기때문이다. 시스템의부팅절차는시스템이나프로세서, 운영체제의버전, 아키텍쳐에종속적이기때문에, 여기서는시스템이부팅되었을때, 실제어떤일이발생하는가에대한일반적인정보만을제공할뿐이다. 시스템의부팅절차를설명하는데있어서주요한문제는시작시점을결정하는것이다. 여기서는운영체제의일부분으로써제공되는코드가실행되는시점을시작시점으로정하였다. 시스템의부팅순서에대해서알아보도록하자. 1. 시스템의시작모듈이 NT 시스템의시작루틴을호출한다. 시작루틴은 Boot Record 구조체를전달받는데, 이 Boot Record 구조체는기본하드웨어정보와나중에운영체제를구성하는 Loader가사용할환경정보를담고있다. NT 시스템시작루틴은운영체제에서사용할몇가지전역변수를초기화하고시스템이어디에서부팅될것인가에대한파티션과디스크드라이브를결정한다. 전역변수의초기화과정은초기시스템부팅단계동안사용할 Memory Descriptor의초기화하는과정을포함한다. 또한시스템시작루틴은 Boot Loader의 Heap 영역을초기화하는루틴을호출하는데, Heap 영역을초기화하는루틴은 Boot Loader가시스템을로딩하는동안메모리를계속해서사용할수있도록적절히 Memory Descriptor를설정한다. 여기서설명된부팅절차는 Windows NT 시스템의부팅절차 8단계중첫번째단계를구성한다. 2. 시스템시작루틴이 Boot Loader의시작루틴을호출한다. 시스템시작루틴은 Boot Loader 시작루틴의호출에대한응답을기대하지않는다. 왜냐하면 Boot Loader 시작루틴의호출에대한응답은시스템부팅절차가실패했다는것을나타내기때문이다. Boot Loader 시작루틴은미리프로세스에의해정의된 Boot Partition을열고 boot.ini 파일을읽는다. Boot Loader 시작루틴은 boot.ini 파일을읽기위한시도의한부분으로서 Boot Partition이 NTFS, CDFS, FAT, HPFS 파티션을가지고있는지결정하기위해내부적으로컴파일된코드를사용한다. 이때는기본적인파일시스템이로딩되지않은상태이고, Boot Loader 시작루틴은오직이러한파일시스템을위해지원되는 (Microsoft가부팅을지원할목적으로선택 ) 미리정의된코드를사용한다. 이것은표준 NT File - 1 -
System 구현에서발생한다. Boot File System의지원은 NT Boot Loader 시작코드에서생성하기때문에, third-party가부팅가능한 File System의구현을제공하는것은 Microsoft의실질적인지원없이는사실상불가능하다. 이시점에서 Boot Loader 시작루틴은 video adapter를 80*50에 16-color의 alphanumeric mode로설정하기위해 realmode에있는 BIOS Interrupt를호출한다. Real-mode에있는 BIOS Interrupt 호출은또한스크린을빈공간으로채움으로써화면을깨끗이제거한다. Boot Loader 시작루틴은 boot.ini 파일의전체내용을읽고, boot.ini 파일에기록되어있는사용자가사용가능한부팅가능한커널의목록을작성한다 ( 멀티운영체제의경우 boot.ini 파일의 [operating systems] 섹션에부팅가능한운영체제를정의하고있다 ). 파일을읽기위해 Boot Loader 시작루틴은일단 NTFS, FAT, CDFS와 HPFS 데이터구조를인식할수있는루틴들을다시사용한다. Boot.ini 파일이없다면, 설정된기본옵션은 Windows NT이며부팅을위한기본폴더는 C: WINNT이다 (boot.ini 파일에서 10 entry 이상은처리하지못한다 ). Boot Loader 시작루틴은 boot.ini 파일의 [operating systems] 섹션으로부터읽어들인옵션과사용자가제공한 [boot loader] 섹션에있는기본부팅위치와일치하는지조사한다. Boot Loader의시작루틴이기본 Boot Option과 [operation systems] 섹션에기록된옵션사이에일치하는내용을찾지못하면, 선택된기본부팅위치는 C: WINNT 이다. Boot Loader 시작루틴이 video display 지원루틴을사용하는사용자에게기본부팅위치와가능한옵션들을제공한다. 만약사용자가시스템을부팅하는기본위치를 C: 로선택했다면, NT Loader의시작코드는사용자가 DOS, Windows 3.x, Windows 95, OS/2 에서부팅될것을요구한다고생각하여 bootsect.dos 파일을읽어들이고, 대체가능한운영체제로시스템을다시부팅한다. 부팅위치가 Windows NT이면, Boot Loader 시작루틴은 Boot Partition의 Root Directory 로부터 ntdetect.com이라는실행파일을읽어온다. 만약 ntdetect.com이발견되지않거나파일의사이즈가잘못되었을경우, 그렇지않으면운영체제를구성하는 Loader의시작코드가만든다른일관성조사가실패했을때, 부팅절차는실패하고시스템을다시부팅한다. 그러나유효한실행파일이발견되었다면, 실행파일을메모리로읽어들이고, 시스템은현재하드웨어의구성정보를찾기위해하드웨어제작자가제공하는서비스를사용한다. 이시점에서시스템부팅초기화과정의 2단계로진입한다. OS Loader의시작루틴은필요한경우 SCSI Boot Driver를초기화한다. 그리고 ntldr.exe OS Loader가메모리로로드된다. 3. OS Loader 는콘솔입출력장치를열고, 시스템과 Boot Partition 을연다. 또한 OS Loader 인증메시지인 OS Loader 4.0 을콘솔에표시한다. Loader 는 Windows NT 커널시스템이미지파일인 ntoskrnl.exe 을위한완전한경로이 - 2 -
름을생성하기위해 Boot Partition 정보를사용한다. 시스템은 Boot Partition이위치한폴더밑의 System32 폴더에서 ntoskrnl.exe 파일을찾도록설계되어있다. 일단시스템이미지가메모리로로드되면, OS Loader는 hal.dll 시스템파일을메모리로읽어들인다. 이때로드된 ntoskrnl.exe 파일과 hal.dll 시스템파일이사용하는모든 DLL을확인하고메모리로읽어들인다. OS Loader는 NT 레지스트리로부터 SYSTEM 하이브 (hive) 를로딩하며, 이때는 Loader가레지스트리로부터 LastKnownGood Control Set을로드할것인지 Default Control Set을로드할것인지이미결정된상태이다. 이러한결정은 Control Set이시스템으로로드된 Boot Driver들을결정하기때문에중요하다. 메모리로 SYSTEM 하이브 (hive) 를읽어오기위해, OS Loader는 Boot Partition에위치한 System32 config 하이브 (hive) 로부터 SYSTEM 파일을열고이정보를읽는다. SYSTEM 파일의정보읽기가실패한다면, SYSTEM.ALT 파일을읽는다. 이러한파일읽기가다실패한다면, OS Loader는부팅을처리하지못한다. 파일읽기가성공하면파일의내용은유효하고, 디스크에있는파일목록을반영하기위해메모리에있는데이터구조체들을초기화한다. 또한 System Loader Block( 이것은결국로드된시스템이미지에전달된다 ) 은메모리에존재하는 SYSTEM 하이브 (hive) 의복사본에대한포인터를적절히수정한다. 이시점에서, OS Loader는메모리로읽어들이기위해필요한 Boot Driver들의목록을결정한다. 이러한목록에는 Boot Partition File System을담당하는드라이버가포함된다. Boot Driver는메모리에로드된 Control Set에있는드라이브키와관련된 Start( 이값은 0 으로설정되어있다 ) 값엔트리에의해결정된다. 일단, Boot Driver의목록이결정되면, OS Loader는이러한드라이버들을레지스트리에정의된 ServiceGroupOrder에기초하여정렬한다. Group 내부에있는연속된드라이버들은레지스트리에정의된 GroupOrderList 와레지스트리에있는각드라이버키와관련된 Tag 값엔트리에기초를두어정렬된다. 드라이버로드순서가결정되면모든 Boot Driver가로드된다. Boot Driver들을로딩하는동안에발생하는에러에대한이벤트는, 레지스트리에있는드라이버와관련된 ErrorControl 값을조사한다. 만약드라이버가시스템부팅절차를위한중요한드라이버로표시되어있다면, 현재진행중인부팅은실패하고, 그렇지않을경우 OS Loader는다른 Boot Driver들을로딩한다. 마지막으로 OS Loader는로드된시스템이미지를실행할준비를하고 NT 커널에있는엔트리포인트로제어를전송한다. 4. 시스템부팅처리의 3단계에서 5단계동안, 다양한 NT 운영체제의실행부 (Executive) 를구성하는요소들과 NT 커널이초기화된다. Start 값이 1로설정되어자동로딩되는드라이버들은시스템부팅처리의 5단계동안로드된다. 커널시스템시작루틴은 3단계의초기화과정동안 KiInitializeKernel() 라불리는 NT 커널초기화함수를호출한다. 이함수는 processor control block 데이터구조체, 커널데 - 3 -
이터구조체, idle thread와 process object들을초기화하고, NT 실행부의초기화루틴을호출한다. 커널데이터구조체와커널링크드리스트 (linked list) 구조체를보호하기위한여러종류의 Spin Lock이이곳에서초기화된다. 또한다양한커널링크드리스트헤더 (linked list header) 들 (DPC 큐리스트헤더, 타이머통지를위한리스트헤더, 다양한 thread table list들과다른종류의유사한커널데이터구조 ) 역시이곳에서초기화된다. 일단커널 Idle thread 구조체가초기화되면, 실행부의초기화루틴이 Idle thread context 에서호출된다. NT 실행부와이실행부를구성하는다양한구성요소들의초기화는 2단계로나누어서처리된다. 실행부의초기화단계의첫번째과정동안다음과같은구성요소들의내부상태를초기화한다. - Hardware Abstraction Layer(HAL) - NT 실행부구성요소 (Executive component) - Virtual Memory Manager(VMM) Paged와 non-paged pool를관리하는 Memory Manager, Page Frame Database, Page Table Entry(PTE) 관리구조체, Mutex와 Spin Lock 데이터구조체와같은다양한 VMM 자원들이이때초기화된다. 또한 VMM은시스템 Cache Working Set과시스템 cache를관리하기위해사용되는다양한 VMM 데이터구조체와같은 NT 시스템 cache와관련된데이터구조체들을초기화한다. - NT Object Manager - Security Subsystem - Process Manager NT 실행부 (Executive) 의첫번재초기화단계에서초기시스템프로세스가생성된다. 이때생성된시스템프로세스는초기에생성된 Idle Process와구분된다. 시스템 thread도이때초기시스템프로세스 context에서생성된다. NT 실행부의초기화과정중나머지단계에해당하는두번째단계는초기시스템프로세스에속한새롭게생성된 thread context에서구현된다. NT 실행부와이를구성하는다양한구성요소들의두번째초기화단계동안, 모든인터럽트는발생하지못하도록처리되며, 초기화를구현하는 context에속한 thread 권한은가장높은권한으로증가시켜어떠한선점 (preemption) 도허락하지않는다. 이과정에서시스템은전제적인기능을고려하고, 실행부를구성하는요소들 (subcomponent) 은초기화과정을마무리짓기위해요구된모든동작을구현한다. NT 실행부의초기화과정의두번째단계동안에다음과같은실행부를구성요소들이호출된다. - Hardware Abstraction Layer (HAL) 가초기화를완료하기위해호출된다. - 시스템날짜와시간이초기화된다. - 4 -
- Multiprocessor 시스템에서는다른프로세스들이이때시작된다. - Object Manager, Executive Subsystem, Security Subsystem들이자신의초기화과정중처리하지못한부분을구현하기위해호출된다. - Virtual Memory Manager(VMM) 의초기화단계 1이구현된다. 이때메모리매핑기능이초기화되고, 시스템의나머지부분을이용할수있다. VMM thread도이때시작된다. VMM은전제적인기능을고려하고, 초기화단계 1 이후시스템의나머지부분들의서비스를준비한다. - VMM의초기화가완료된후 NT Cache Manager가초기화된다. Cache Manager가초기화되는동안, 비동기적인 (Asynchronous) 동작을위해요구되는 worker thread의수가결정되며생성된다. 또한 Cache Manager 링크드리스트구조체와동기화를위한자원들이초기화된다. - Configuration Manager가자신을초기화하기위해호출된다. Configuration Manager는 NT 레지스트리를관리한다. 초기화단계동안 Configuration Manager(CM) 는레지스트리에있는 REGISTRY MACHINE SYSTEM 과 REGISTRY MACHINE HARDWARE 하이브 (hive) 를사용할수있도록한다. 이렇게함으로써초기에 ntdetect.com가포함한모든정보뿐만아니라, OS Loader가메모리로가져온정보들을 SYSTEM과 HARDWARE 하이브 (hive) 내에있는적절한엔트리값으로설정한다. 초기화단계가완료되면레지스트리에저장된정보를시스템을구성하는다른구성요소들이사용할수있다 ( 특히바로로드된 Kernel-mode Driver들은이때레지스트리정보를사용할수있다 ). 그러나 CM은이때수정된사항을레지스트리에저장하지는못한다. 드라이버에한정된초기화를구현하기위해요청된 Kernel-mode Driver들은레지스트리에등록된정보들을액세스하기위하여표준레지스트리루틴을사용할수있다. - NT I/O Manager가자신의초기화작업을구현하기위해호출된다. I/O Manager는먼저동기화데이터구조체, 링크드리스트, 메모리저장공간 ( 특히 IRP Zone/Lookaside List) 를포함하는지정된개체 (state object) 들을초기화한다. 그다음 I/O Manager는 ObCreateObjectType() 내부함수를사용하는 Object Manager를호출하여내부적으로정의된모든 Object 타입을등록한다. 내부적으로정의된 Object의종류에는 Adapter Objects, Controller Objects, Device Objects, Driver Objects, I/O Completion Objects와 File Objects들이포함된다. 이때 I/O Manager는 Object의이름을관리하는영역 (name space) 에 Device, DosDevices, Driver 루트폴더를생성한다. 그다음으로, I/O Manager는 OS Loader가메모리에로드한 Boot Driver들을초기화한다. 이것은드라이버에한정된초기화를구현하기위해로드된드라이버들각각의 Driver Entry Routine이호출된다. 이때 Raw File System Driver도로드된다. Raw File System Driver 이전에로드된다른 File System Driver는 Boot File System Driver가유 - 5 -
일하다. 드라이버들은 NT 레지스트리와상호동작하는기능을제안해야한다. 마지막으로 Start 엔트리값이 1로설정된드라이버들이로드되고, 드라이버에한정된초기화를위해드라이버가가지고있는 Driver Entry Routine이호출된다. 재초기화작업을요구하는모든로드된드라이버를위해드라이버의재초기화루틴이이어서호출된다. 드라이버의재초기화작업후에 NT I/O Manager는 Disk Partition을인식하기위해드라이브문자를할당한다. I/O Manager는 CD-ROM 드라이브나하드디스크드라이브파티션을보호하기위해고정으로할당한드라이브문자가있는지레지스트리를검사한다. 이러한드라이버문자의할당은동적으로 DOS 드라이버문자를할당할때사용할수없도록고정되어있다. 각각의하드디스크를위해드라이브문자를할당하기전에 I/O Manager는물리드라이브에대한 Open 동작을구현한다. 만약, 여러분이하드디스크 Device Driver나 Lower-level Filter Driver 또는 Intermediate Driver를개발한다면, 개발자는이시점에서 Open 요청을처리해야한다. Open 요청이성공하면 Device Object에대한 Symbolic Link가 NT Object 이름을관리하는영역 (name space) 내부에생성되며, 이링크에할당된이름은 DosDevices PhysicalDrive%d의형식을가진다. 여기서 %d 는순차적으로할당된디스크드라이브숫자이다. NT I/O Manager는이시점에서디스크드라이브로부터파티션정보를요구한다. 고정된 Disk Partition에드라이브문자를할당하기위한순서를결정하기위해 I/O Manager는다음과같은방법을사용한다. - NT I/O Manager는보호하기위한고정된드라이브문자가할당되어있는지레지스트리에요청한다. - 부팅가능한파티션이먼저 DOS에서사용가능한드라이브문자를동적으로할당한다 ( 특히파티션을대표하는 Device Object를위해 DosDevices %c라는이름을가진 Symbolic Link를생성한다. 여기서 %c는파티션을위해 NT I/O Manager가선택한드라이브문자를나타낸다 ). - 다음으로기본파티션 (Primary partition) 이동적으로드라이브문자를할당하기위해선택된다. - 확장파티션 (Extended partition) 이이어서 DOS 드라이브문자에할당된다. - 다른파티션에 DOS 드라이브문자들을할당한다. 하드디스크드라이브와 Removable Driver Partition을위해드라이브문자가할당된후, NT I/O Manager는하드웨어를검색하는동안에인식된모든 CD-ROM 드라이브들에대한드라이브문자를할당한다. - Local Procedure Call(LPC) Subsystem과 Process Manager Subsystem이지금자신의초기화과정을완료한다. - 다음으로 Reference Monitor와 Session Manager Subsystem이자신의초기화과정을완료하기위해호출된다. - 6 -
5. 여기까지시스템의부팅처리의 3단계에서 5단계까지마무리되었다. 여기서기억해야할것은 NT 실행부 (Executive) 를구성하는요소 (component) 들은 NT 커널이생성한시스템프로세스에속하는시스템 worker thread의 context에서초기화되었다는사실이다. 시스템 worker thread는 zero page thread라는 Memory Manager의역할을수행한다. Zero page thread는 VMM이 Free List에위치한페이지들을비동기적인방식으로 0으로제거하는데 (Zero Out) 사용되는가장낮은권한을가지고있는 thread이다. 모든페이지는시스템이 US Department Of Defense(DOD) 가정의한 C2 보안을확인하기위해페이지를다시사용하기전에 0으로제거하는 (zeroed out) 것이필요하다. 6. 이시점에서시스템의초기화완료되었다. 시스템부팅절차의 6단계에서 8단계동안다양한다른구성요소 (subsystem) 들이초기화되고 Service Controller Manager가다른서비스들을로드한다. 여기에는레지스트리에있는 Start 값이 2로설정된 Kernel-mode Driver의로딩이포함된다. - 7 -