[컴] BIOS 동작

인터럽트 / interrupt / boot sequence / booting / 부팅 과정 / bootstrap program




updated

아마 아래와 같은 해킹을 막기 위해 Microsoft 에서 Secure Boot policy 같은 것들을 이용한 듯 하다. 그런데 이 policy 말고, debug policy 가 있었는데, 이녀석이 유출됐다고 한다. 그것도 MS 가 실수로 같이 배포한 듯 하다. 여하튼 그래서 Secure Boot policy 를 없애고, 새로운 policy 를 깔아서 windows 이외의 os 를 loading 할 수 있는 여건이 됐다고 하는 듯 하다. 자세한 것은 아래 글을 참고하자.



--------------------


우리가 잘 알고 있는 러시아 보안회사 카스퍼스키랩이 2월 16일에 Equation group 이라는 해커단체의 방법을 분석해서 뿌렸다. 아래 블로그에 그 내용이 간략하게 나와있다.
그래서 어떻게 HDD 의 firmware 를 호출하게 되는지 궁금해 져서 찾다가 결국 BIOS 까지 왔다. 예전에 boot loader 을 올리는 짓(?)을 해본 기억은 있는데, 역시나 오래된 일이라 잘 기억도 나지 않고, 적어놓은 얘기도 없어서 다시 적는다. 자세한 내용은 ref. 1 을 보도록 하자. 여기글은 ref.1 을 보고 필자가 이해하기 좋게 편집했다. 참고로 ref.1 의 내용은 2003년에 작성된 글이니 현재의 시스템과 조금 차이가 있을 수도 있음을 고려하자.

일단 그전에 HDD의 firmware 는 아마도 BIOS 가 실행될 때 사용할 수 있는 상태가 돼야 할 듯 하다.



pc 에 전원을 넣은 후 os 의 kernel 이 load 되기 까지


pc 에 전원을 넣게 되면, BIOS 가 실행된다.(BIOS 가 실행되는 routine 은 정확히 모른다.) 이 BIOS 가 실행되면 PC 의 장치들을 구동할 수 있는지에 대한 간단한 test 를 하게 되고(POST, Power-On Self Test) 이 test 가 완료된 후 setup menu 로 들어갈 수 있는 기회가 잠깐 생긴다(흔히, 컴퓨터 첫화면서 <f2> 나 <del> 키등을 누르고 들어갈 수 있다. 이 때가 이미 POST 가 끝난 상태라고 보면 되겠다.)

BIOS 가 초기화되고 나서 다른 하드웨어가 초기화 된다. 그리고 그 하드웨어들의 firmware 가 메모리로 load 된다.

이제 BIOS 는 setup 에 정해진 boot sequence 에 맞게 device(usb, hdd, ssd 등) 에 접근하게 된다. 처음에 접근한 device 의 첫 sector 를 접근해서 RAM 의 주소 0x0000~0x7C00 으로 가져오고 PC(program counter) 를 0x0000 으로 변경하게 된다.

이 때 device 의 첫 sector 가 우리가 아는 MBR 이 되고, 이렇게 가져온 프로그램이 boot sector program(boot loader) 이 된다. 참고로 각 partition 의 첫 sector 를 boot sector라 부르기 때문에 위에서 프로그램을 boot sector program 이라 칭한다.

boot sector 를 load 한 것이 BIOS 의 마지막 일이라고 보면 된다. boot sector program이 하게 된다.




보통 os 가 한개만 깔린 상태라면 boot sector program(boot loader) 이 kernel 을 바로 메모리로 load 하거나 second stage boot loader 를 먼저 memory 로 load 한 후에 second stage boot loader 가 kernel 을 load 하게 된다.

여기서 의문점이 생기게 된다. 어떻게 boot sector program 이 kernel 이나 second stage boot loader 가 disk 의 어느위치에 있는지 알수 있을까?

이것은 우리가 boot sector program(boot loader) 을 MBR 에 write 할 때 정해진다. 보통 booting 이 가능한 device 를 만들기 위해 우리가 MBR 에 작업을 하게 되는데, 이 때 이런 작업을 해주는 프로그램들을 이용한다. (MBRwiz 같은...)

이런 녀석들이 boot loader installer 라고 보면 되는데, 이 boot loader가 MBR 에 second stage boot loader 의 위치를 알려주거나(보통 segment 번호로 알려준다고 한다.) kernel 의 위치등을 알려주게 된다.(자세한 것은 아래를 참고하자.)


UEFI(UnifiedExtensibleFirmwareInterface)

UEFI 는 하나의 완전한 boot manager 를 갖고 있고, 그래서 여러 stage 를 갖는 BIOS boot process 보다 빠르다.


--------------------------------

아래의 대부분의 내용은 ref. 1 의 내용을 번역한 것이다.



BIOS

BIOS 는 PC 메인보드의 ROM 에 들어 있는 firmware 이다.(요새 android 를 자꾸 보다보니 ROM 의 의미가 헷갈렸는데, 혹시 나같은 사람이 있을 듯 해서 자세하게 말하자면, 여기서는 Read Only Memory 를 뜻하는 보드에 붙어있는 하드웨어 ROM 을 이야기한다.)

우리가 PC 를 켜면 가장먼저 실행되는 녀석이다. 많이들 봤겠지만, <F2> 나 <del> 키를 눌러서 bios 의 setup menu 로 들어갈 수 있는 것도 BIOS 가 실행된 상태이기 때문이다.
BIOS 는 4가지부분으로 되어 있다.
  • POST(Power On Self Test) : 우리가 pc 를 켰을 때 나오는 memory 가 몇 byte 인지 보여주는 화면등이 이런 전원을 켤때 자기 점검(POST) 하는 것 중에 하나다.
  • Setup Menu : 여기서 boot sequence 등을 정할 수 있다.
  • boot sector loader
  • BIOS interrupts : 프로그램들이 화면, 키보드, disk 에 접근하기 위한 간단한 device driver 들이다. 대부분 os 들은 이용하지 않는다.

BIOS는 다른 ROM (이 ROM 을 extension ROM 이라 한다.)을 실행시킬 수 있다. 이런 extension ROM 은 VGA card, SCSI host adapter, Ethernet card 등에 있을 수 있다.

이런 확장 ROM 을 이용한 예가, 우리가 알고 있는 "네트워크로 부팅하기" 이다. 이 기능을 위해 Ethernet card 에 EPROM 을 추가하고, 이 EPROM 을 BIOS 가 실행하게 해서 hdd 에서 가져오던 data 대신에 network 로 부터 필요한 data 를 가지고 와서 부팅을 시킬 수 있는 것이다.

load the Boot sector to RAM

PC BIOS 가 다른 computer system 들에 비해서는 비교적 원시적인 녀석이라고 한다. 여하튼 그래서 PC BIOS 는 disk 에 대해서 가능한 것이라고는 "첫 512-byte 섹터" 를 메모리(RAM) load 하는 방법뿐이다.

디스켓의 첫 섹터(흔히 MBR 이라 부르는 부분)는 RAM 의 주소 0x0000 ~ 주소 0x7C00 에 load 된다. 이 디스켓의 첫 섹터의 마지막 2 byte 는 0x55 와 0xAA 여야 한다. BIOS 는 마지막 2byte 의 값으로 sanity check 를 하는데 이 마지막 2 byte 가 0x55 와 0xAA이면 된다. sanity check 를 통과하면 BIOS 는 RAM 의 주소 0x0000~0x7C00 으로 jump 한다.
CD-ROM 부팅에선 좀 다르게 동작하는데, CD-ROM 부팅에선 CD-ROM 의 특정 파일을 diskette image 로 생각해서 다루게 된다. 그러면 이 diskette image 의 첫 sector 를 RAM 의 0x0000~0x7C00 으로 load 하고 BIOS 가 이 주소로 jump 하게 된다.

real mode 

여하튼 이렇게 boot sector 가 RAM 에 load 되고 나면, CPU 는 real mode 에 있게 된다. real mode 는 x86 architecture 에 있는데, 32-bit protected mode 보다 좀 더 제한된 mode 이다. (참고 : [컴][디버그] INT 3 의 동작분석)

예를 들면, 이 real mode 에서는 64k segment 밖의 data 는 segment register 를 바꿔야만 접근이 가능하고, 주소공간(address space)의 첫 1MB 의 밖에 있는 data 는 전혀 접근이 불가능하다.

gcc 같은 compiler 는 이 real mode 에 대해 모르기 때문에 대부분의 boot loader 들(GRUB 을 제외한)이 assembly 로 짜여져 있다. boot sector 에 들어있는 program 들은 전부 assembly 로 되어 있다.

BIOS interrupts

BIOS interrupts 는 INT instruction 을 통해 호출할 수 있는 sub routine 인데 boot loader 가 이 녀석을 사용할 수 있다.(참고 : [컴][디버그] INT 3 의 동작분석) 이 BIOS interrupts 들은 real mode 에서만 동작한다. 대부분의 boot loader 에서는 아래 routine 들이 사용된다.
  • INT 0x10 : 화면 output
  • INT 0x16 : 키보드 input
  • INT 0x13 : disk I/O
  • INT 0x15 : 모든 BIOS 함수들을 위한 잡동사니통(catch-all)

boot sector program

boot sector program 이 BIOS 의 boot loader 에 의해서 RAM 의 0x0000 ~ 0x7C00 부분으로 load 가 되면 BIOS 는 이 boot sector program 을 실행하게 된다. 이 때 여기서 boot sector program 이 second stage boot loader 를 호출하게 된다. 

boot sector program 은 이론상 최대 512 byte 가 되지만, 실제로는 불가능하다. 일단 마지막 2byte 가 sanity check 용으로 사용되고, boot sector program 이 저장되는 MBR은 partition table 도 가지고 있는데, 이 partition table 이 64 bytes 가 된다. 그래서 실제로 사용가능한 용량은 446 bytes 이다.

이렇게 용량이 적은 관계로 우리가 생각하는 boot loader 의 기능들을 이 boot sector program 에서 전부 구현할 수 없다. 그래서 대체로 이 프로그램은 아래 일들을 한다.
  1. 다른 boot sector 를 load 한다. : 하드디스크의 MBR 에 있는 프로그램이 대부분 이런 일을 한다. 선택된 active partition 의 첫 sector(boot sector) 를 찾고 그것을 chain load(아래 참고) 한다.
    MBR 프로그램은 boot time 에 active partition 을 바꾸는 일은 할 수 없다. 그래서 LILO 의 MBR program 같은 경우는 유저가 partition 을 선택하는 메뉴를 보여준다.
  2. second stage boot loader 를 load 한다.
    boot sector program 으로는 특정 이름의 file 에 접근하기 위해 directory 를 들여다 보고 그것을 memory 로 load 하는 등의 행동을 할 수 없다.(단 예외는 있다. 적어도 DOS file system 들에서는 예외가 있다.)
    대부분의 boot sector program 은 파일이름이 아니라 sector 번호로 second stage boot loader 를 찾는다. sector 번호는 boot loader installer 에 의해 boot sector 에 적히게 된다.(밑에 boot loader installer 참고.)
  3. 직접 kernel 을 load 한다.
    보통 second stage boot loader 보다는 kernel 의 size 가 크다.
Linux kernel 에 있는 boot sector program 은 second stage boot loader 의 도움없이 kernel 을 memory 로 직접 load 한다. 커널이 디스켓에서 boot sector program 의 sector 의 다음 sector 에 존재한다면 굳이 file system 데이터 구조를 접근하지 않아도 된다. 그러나 bZimage 커널들을 위해서는 boot sector program 은 꼼수를 사용한다. 이 커널은 커널의 나머지 부분을 memory 로 load 하기 위해서 kernel 의 setup 부분에서 sub-routine 을 호출한다.

The boot loader e2boot fits into the first 1kB block of an ext2 partition (it is twice as big as a boot sector program), but with some tricks it finds both the kernel and the RAM disk by name on an ext2 partition and loads them into memory.

Also the boot sector on a DOS disk does not utilize a second stage boot loader to load the MS-DOS kernel files IO.SYS and MSDOS.SYS. The structure of an MSDOS file system is simple enough to find a file with a specific name in the root directory and load it into memory, at least part of it.

second stage boot loader

이녀석이 실제 boot 를 해주는 프로그램이다. 이 second stage boot loader(2차 부트로더) 는 아래 2가지를 가지고 있다.
  • UI : os 가 2개 이상 깔린 경우 선택하는 화면이 나오는데, 그 때의 화면이 이 second stage boot loader 가 보여주는 것이다. 그리고 윈도우의 경우에 비정상 종료가 된 경우에도 여러가지 선택옵션을 가진 선택화면을 보여주는데 이 화면도 이 second stage boot loader 에서 보여주는 것이라고 생각하면 되겠다.
  • kernel loader : os 를 memory 로 load 하고 그 os 를 실행하는 역할을 한다. 다른 os 와 관계된 boot loader 를 load 하고 그것을 실행할 수도 있다. 이렇게 다른 os 와 관계된 boot loader 를 load 하는 것을 chain loading 이라고 한다.

second stage boot loader 예

윈도우 비스타/7/8의 second stage boot loader :BOOTMGR 윈도우 XP : NTLDR 2차 부트로더는 파일의 형식으로 부팅 파티션의 루트경로에 존재합니다.
이녀석의 size 는 크게 상관없다. LILO 는 6.6KB 이고, GRUB 은 100KB 이다.

boot loader installer

이녀석은 말 그대로 boot loader 설치 프로그램이다. 이 녀석을 실행하면 MBR 에 boot sector program 을 copy 해 넣고, boot sector program 에 boot sector program 이 호출할 second stage boot loader 의 정보를 써주게 된다. 그리고 second stage boot loader에는 second stage boot loader 가 필요한 커널의 위치등도 적어준다.

See Also

  1. [컴] NERF 프로젝트: UEFI 의 부팅과정을 알 수 있다.

References

  1. How Boot Loaders Work
  2. 디지누리 - [만능 USB를 만들어 보자!] 2편 - 부트로더란?
  3. 멀티부팅시 부트로더 설치에 대한 이해..
  4. Diving into Secure Boot – Dubai Security Blog
  5. Operating System Concepts 10th edition






댓글 없음:

댓글 쓰기