System Boot Up 을 Power-Button 을 누르는 시점부터 써 놓은 글을 번역합니다.

site URL : http://duartes.org/gustavo/blog/post/how-computers-boot-up


아래에 그린 image들은 원본을 참고로 새로 그린 것입니다. 물론 원본 작성자에게 허락을 맡고 쓰는 것이니 오해하지 마시길 바랍니다. 

잘못 번역으로 인한 전달된 지식에 대해 책임지지 않습니다. ^^ 모르는 부분은 대충 넘어가서 빠져있는 부분이 있을 수도.. 



I confirmed to re-use of image with gustavo-web@duartes.org, If you want to see a original image, just click this image

<An outline of the boot sequence>


Power Button 을 누르면 mainboard 에서는 자신만의 firmware 를 초기화 하고 CPU를 running 한다. 만약 실패 한다면 여러가지(beep 음 등) 실패의 알림을 해줄 것이다. CPU가 정상 동작했다면, Multi-core 또는 Multi-processor 시스템에서 하나의 CPU 만이 BSP(Bootstrap processor) 가 되어 BIOS 및 kernel 초기화를 수행한다. 남은 core 및 processor는 AP(Application Processor)라고 불리며 kernel에서 명시적으로 살려주지 않는 이상 "halt" state 로 유지된다. Intel CPU 들은 backwards compatibility 를 완전히 지원하기 위해 현대에 개발되는 CPU 들도 초기 부팅시에는 마치 1978년대의 intel 8086 처럼 동작을 한다. 이를 real mode 라고 부르며 이 시점에는 paging 이 disable 되어 있는 상태이다. 이 상태에서는 전체 memory의 1MB 영역까지만 접근이 되며 1MB 내의 memory 어디든 read/write 가 가능하다. 이 시점에는 protection 및 privilege 는 의미가 없다. 


CPU 내부 대부분의 register 들은 부팅 이후에 명확한 값을 갖게 되는데 이중 Instruction pointer(EIP)라고 불리는 register에는 CPU 가 실행해야 하는 instruction의 memory address를 갖고 있다. Intel CPU들은 초기 부팅 때 1MB 밖에 접근 하지 못함에도 불구하고 hack을 이용하여 EIP 에 처음 수행하여야 할 instruction이 존재하는 hidden address를 적용한다. (0xFFFF FFF0 : 4GB - 16byte 영역이며 reset vector 라 불리고 현재의 CPU-32bit의 경우에만- 들은 이것을 갖고 있다.)


mainboard 는 reset vector 에 있는 instruction이 BIOS entry point 로 mapping 되는 memory location으로 jump 하도록 되어 있다. 이 jump 는 이 숨겨진 address(0xFFFF FFF0) 가 전원을 켰을 때, 항상 그자리에 있음을 암시한다. 또한 32bit 의 cpu vendor 들은 memory 에 정상적인 contents(BIOS, reset vector 등)이 memory map에 맞도록 유지하고 있어 변경될 수 없다. 대략적인 memory map은 다음과 같다.



I confirmed to re-use of image with gustavo-web@duartes.org, If you want to see a original image, just click this image

<Important memory regions during boot>


reset vector를 통해 CPU는 BIOS code 를 수행한다. BIOS는 machine 내부의 일부 hardware를 초기화 하고 바로 POST(Power-on Self Test)를 수행한다. 이는 computer에 있는 다양한 component들을 테스트 하는데 그 중 video card의 테스트가 실패하면 beep 및 다양한 방법으로 알린 후, system이 멈춘다.(물론 아무것도 안되겠지). 만약 video card의 테스트가 정상적이었다면 제조사의 logo 를 출력한다. 다음으로 memory, keyboard 등을 POST로 테스트 한다. 예전 pentium까지는 내기억으론 keyboard가 설치되어 있지 않다면 beep 음을 내고 error를 내놓았던 것 같은데 지금은 그런지는 모르겠다. 결과적으로 POST는 모든 PIC 디바이스를 위한 resource(interrups, memory ranges, I/O ports)를 초기화 및 테스트를 진행한다. 또한 근대의(?) BIOS 들은 ACPI(Advanced Configuration and Power Interface)를 이용하여 컴퓨터 내부에 있는 device를 표현하는 data를 기록해두고 향후 kernel에서 사용할 수 있도록 준비한다. 


BIOS의 POST 작업이 끝나면 OS 를 boot up 하기를 원한다. OS는 hard disk, CD-ROM 등에 저장되어 있는데, user 가 설정한 boot device를 찾는다. 찾은 device 첫번째 512byte의 sector(sector 0)를 읽는다. 이 부분을 MBR(Master Boot Record)라고 하는데 일반적으로 두 가지 중요한 component를 갖고 있다. 하나는 아주 작은(?) OS specific 한 bootstrapping 프로그램이 MBR 의 제일 처음에 들었다.  이 프로그램이 어떤 것인지는 상관없이 BIOS는 0x7c00 의 메모리에 올리고 Jump 한다. jump 와 동시에 memory에 올려진 MBR code 를 수행한다. 



I confirmed to re-use of image with gustavo-web@duartes.org, If you want to see a original image, just click this image

<Master Boot Record>


MBR 은 window의 MBR loader가 될수도 있고, Linux의 LILO나 GRUB 가 될 수도 있다. 중요한 component의 다른 하나는 partition table이다. 이는 얼마나 많은 disk partition이 있는지 기록을 해두는 공간이다. 전통적인 window MBR은 partition table을 뒤져서 active인 것을 찾고 boot sector를 active한 디스크에서 loading하여 code 수행한다. 그 boot sector는 partition의 first sector가 될 것이며, 전체 disk의 first sector와는 다른 내용인 것이다. 만약 boot sector loading하는 것이 실패한다면, "Invalid Partition Table"또는 "Missing Operating System" 이라는 message를 만나게 될 것이다. (이 message는 BIOS가 아니라 MBR에서 출력하는 것임)


Boot 의 loading은 전반적으로 더 정교하고 유연한 작업니다. Linux Bootloader 인 Lilo 와 GRUB는 다양한 OS, file system, boot configuration들을 조종(handle) 할 수 있다. 전통적인 window MBR과는 다르게 "active partition" 찾아 가지 않고 다음과 같이 수행된다. 

   1. MBR 자체에 first stage bootloader를 내장하고 있다. GRUB에서는 stage 1이라 한다.

   2.  disk로 부터 추가적인 bootstrap을 갖고 오기엔 MBR의 size가 작다. 첫번째 sector는 partition 정보와 hard-coded 된 MBR code들이 있는 곳이다. 

   3. MBR code는 step 2 에서 Bootloader 의 second stage 를 포함하는 file 하나를 읽는다. GRUB에서는 stage 2라고 불리며 grub.conf 라는 file을 읽는다. 이 시점에서 user는 booting 할 kernel을 선택하거나 default 로 부팅한다. 

   4. 이제 bootloader  는 kernel을 실행 시켜야 한다. boot partition으로 부터 kernel을 읽기 위한 file system 에 대한 정보를 갖고 있어야 한다. Linux에서는 "vmlinuz-x.x.x-version"과 같은 binary를 disk로 부터 읽어온다. 그리고 메모리로 loading하고 kernel bootstrap code로 jump 를 하며 bootloader에서 하는 모든 일들을 마무리한다. 


현재 kernel image를 만들면(압축을 하더라도) 2MB 가량된다. 이는 real mode에서 사용가능한 640KB 보다 많이 큰 상황이다. 이를 위해 앞서 써놓은 내용의 "hack" 이용한다는 점이 중요하다. Bootloader는 BIOS call을 통해 disk 로 부터 data를 읽어야 하기 때문에 꼭 real mode 로 수행되어야 한다.(kernel을 아직 못올린 상태이니..) kernel image 를 memory 에 올리려면 real mode 에서 cover하지 못하는 1MB 상위의 메모리를 사용할 수 있게 하는 방법이 있다. unreal mode 라고 불리며 이것은 BIOS에서 1MB 상위를 쓰기 위해 real mode 와 protected mode를 왔다갔다 변경할 수 있도록 한 방법이다. GRUB source를 본다면 이와 같은 Transition을 확인할 수 있다고 한다. 


Boot Loader에서 "Early Kernel Initialization"까지 살펴본 내용이다. 


다음 article은 "Kernel Boot process" 이다. 

+ Recent posts