원문 및 참고 : 본 문서는 오역 및 잘못된 이해로 인해 내용의 문제가 있을 수 있습니다. 2007년에 포스팅된 How Windows starts up part 1은 몇 주간에 걸쳐 Windows 시작에 대한 내용을 다룬다는 필자의 소개가 있었으나… 2009년이 된 지금도 여전히 Part 2까지 밖에 없습니다. ㅜㅜ 본 내용의 기본 뼈대는 How Windows starts up 을 번역해 주신 !analyze –v 블로그의 내용을 기본으로 하여 작성되었습니다. Windows 부팅 과정은 크게 아래와 같은 단계로 이루어 집니다. Windows 부팅 단계 1. 초기화 단계 1) POST - POST 단계의 문제 해결 2) 초기 디스크 접근 이번 시작 단계에서 발생하는 이벤트를 이야기 하기 전에 부트 디스크에 대해서 먼저 이해 해야 합니다. 하드 디스크는 아래 그림과 같이 나타낼 수 있습니다. (아래 그림의 각 블럭 들이 크기를 나타내지는 않습니다. ) 하드 디스크는 실린더, 헤드, 섹터로 나뉘어 집니다. 섹터는 디스크의 가작 작은 저장 단위로 보통 512 바이트 입니다. 하드 디스크의 물리적 구조에 대한 보다 자세한 정보는 아래 리소스를 참고 하시기 바랍니다. 아래 두 개의 섹터는 컴퓨터가 시작되는데 아주 중요한 것으로 뒤에서 보다 자세히 다루도록 하겠습니다. . 마스터 부트 레코드 (MBR) MBR 레코드 예시 MBR은 언제나 물리 디스크의 섹터1, 실린더 0, 헤드 0에 위치 합니다. (즉 512 Byte의 크기를 지니게 됩니다. ) 부트 섹터는 각 파티션의 첫 번째 섹터에 위치 합니다. 이 섹터들은 실행 코드와 코드가 실행되는데 필요한 정보를 가지고 있습니다. 섹터 숫자를 표시하는데 약간 모호함은 실린더/헤드/섹터(CHS)는 C0/H0/S1이 시작 이라는 것 입니다. 절대적인 섹터의 숫자는 0에서 시작하고 DskProbe 와 같은 툴에서도 0을 사용 합니다. 아래 문서에서 이 모호함을 설명하고 있습니다. Q97819 Ambiguous References to Sector One and Sector Zero 언제 디스크에서 정보를 얻어오게 될까요? MBR 은 디스크가 파티션 될 때 만들어 집니다. 부트 섹터는 볼륨을 포맷할 때 생성 됩니다. 아래 예는 앞으로 우리가 보게 될 MBR의 가장 마지막 데이터 입니다. 000001F0: 00 00 00 00 00 00 00 00 – 00 00 00 00 00 00 55 AA 0x1B8에 위치하는 디스크 시그니쳐는 디스크를 운영체제에 인식 시킵니다. Windows 2000 이상의 운영체제에서 이 시그니쳐를 아래 레지스트리 키의 인덱스로 사용하여 정보를 저장 합니다. (해당 위치를 확인해 보면 c, f 와 같이 설정되어 있거나 아래 레지스트리 키의 index 값을 가집니다.) HKLM\System\MountedDevices A8 E1 B9 D2 00 7E 00 00 00 00 00 00 첫 번째 4Byte 는 Disk signature 를 말합니다. (실제로는 리틀 엔디언 즉 꺼꾸로 기록되어 있습니다.) 리틀 엔디언 노테이션으로 기록되어 있는 64 bit 값은 파티션의 위치를 나타내는 옵셋으로 사용됩니다. 이 경우 해당 값은 0x7E00 (나머지 숫자는 00 임으로 리틀 엔디언 방식으로 계산 하면 0x7E00 가 됨) 10진수 32,256에 해당하는데 이 값을 섹터의 크기인 512로 나누게 되면 63이 나오고 이를 통해 실제 파티션의 첫 번째 섹터의 위치를 알 수 있습니다. 만약 해당 디스크에 다른 파티션이 있고, 해당 값이 A8 E1 B9 D2 00 F8 93 71 02 00 00 00 이라면 이를 리틀 엔디언 방식으로 치환 하면 0x27193f800 10진수 10,495,457,280 인 것을 알 수 있고 이를 섹터의 크기인 512로 나누게 되면 20,498,940 이 나오게 됩니다. 즉 해당 파티션의 두 번째 논리 디스크는 20,498,940 째 섹터에 위치하게 됩니다. MBR 및 시그니처를 설명하는데 너무 시간이 길어졌습니다. 파티션 테이블은 MBR내의 64Byte 의 데이터 구조로 타입과 하드 디스크에서의 위치 정보를 가지고 있습니다. 각 파티션 테이블은 16Byte길이로 (최대 4개의 파티션까지 지원) 각 항목은 아래와 같이 미리 정해진 위치에서 시작 됩니다. 아래는 MBR의 샘플로 3개의 파티션 테이블이 사용되어 있고 하나가 비어 있는 상태 입니다. 000001B0: 80 01 (끝 두 자리 입니다.) 위와 같이 MBR에는 총 4개의 파티션에 대한 설명을 기술할 수 있습니다. 그 첫 번째 필드는 0x1BE 에 위치합니다. 000001C0: 01 00 07 FE BF 09 3F 00 - 00 00 4B F5 7F 00 00 00 두 번째 값은 0x1BE에 위치하며, 시작 해드를 의미합니다. 000001B0: 80 01 세 번째 값은 시작 섹터 및 시작 실린더를 의미 합니다. 위의 2Byte 값은 아래와 같이 실린더 및 섹터의 값을 의미합니다. 네 번째 값은 시스템 ID를 의미하며 0x07 은 NTPS를 의미합니다. 000001B0: 80 01 다음은 시스템 ID 값들입니다. FE는 마지막 해드를 의미하며 254번째 해드가 마지막 해드라는 의미 입니다. 000001B0: 80 01 BF 09은 이전과 마찮가지로 마지막 섹터와 마지막 실린더를 나타냅니다. 000001B0: 80 01 이 값은 다시 표시하면 0x09BF가 되며 이는 100110111111 이 됩니다. 이는 즉 실린더 1001000001 (521)의 섹터 111111 (63)이 마지막 실린더이며 섹터임을 의미합니다. 디스크의 시작 부터 볼륨까지의 섹터 수를 의미하며, 상대 섹터라 부릅니다. 000001B0: 80 01 0x1CA 부터 4byte의 값은 전체 섹터의 수를 나타냅니다. 000001B0: 80 01 이제 Disk이 있는 데이터 구조를 이해하게 되었고 이제는 진행 순서를 알아보고자 합니다. 기억할 것은 POST 가 성공적으로 완료된 이후 과정이라는 것 입니다. 1) 마더보드의 롬 바이오스가 바이오스에 설정되어 있는 첫 부트 디바이스에 접근을 시도 합니다. (일반적으로 사용자가 BIOS 설정 유틸리티를 사용해서 설정 가능합니다.) 2) 롬 바이오스는 첫 번째 부트 디바이스에서 실린더0, 헤드0, 섹터 1를 읽습니다. 3) 롬 바이오스가 한 섹터를 메모리로 읽어 들이고 테스트 합니다. 4) 하드 드라이브로 부팅할 경우 롬 바이오스는 섹터 1의 마지막 두 바이트를 확인하여 55AA 인지 확인 합니다. 5) MBR은 파티션 테이블을 검색하여 0x80 즉 부트 파티션인 활성 파티션을 찾습니다. 6) MBR은 활성 파티션의 부트섹터를 읽어 들인 후 55AA인지 확인 합니다. (MBR도 부트 섹터의 한 종류입니다. 부트 섹터는 볼륨 부트 레코드를 의미 하며, 이는 파티션의 첫 번째 섹터 로써, 해당 파티션에는 OS가 인스톨 되어 있으며, 기본적으로 OS 로딩 및 호출을 위한 코드를 포함 하고 있습니다. 역시 55 AA 로 끝나는 섹터 입니다.) 7) 활성 파티션의 부트 섹터가 실행되고 NTLDR을 찾습니다. 부트 섹터에 들어 있는 내용은 무엇으로 포멧되었느냐에 따라 달라 집니다. 예를 들어 부프 파티션이 FAT 파티션 이라면 Windows는 부트 섹터를 FAT 파일 시스템을 읽을 수 있도록 작성 합니다. 부트 섹터의 역할은 루트 디렉토리에서 NTLDR을 읽을 수 있도록 논리 드라이브의 포멧과 정보를 제공해 주는 것 입니다. 이 지점에서의 오류는 파일 시스템에 따라 달라 집니다. 아래 FAT 일 경우와 NTFS 일 경우의 에러가 있습니다. 9). NTLDR을 찾으면 메모리로 로드 하고 실행 시킵니다. 이 시점에 부트 로더 단계가 시작 됩니다. |