Programming/System

[OS] 1장 부트스트랩 : 만들면서 배우는 OS 커널의 구조와 원리

appHunter 2009. 6. 16. 17:26

기본적인 부트 로더의 코드를 가지고 부트로더에 대해서 이해한다.

 클릭하면 전체 소스를 볼 수 있다.


제일 먼저 부팅 시, 바이오스는 디스크의 MBR[각주:1] 를 읽어들여서, 램의 물리주소 0x07C00 번지에 복사 한후 0x7C00 (=0x07C00) 으로 점프한다.
  이는 CS[각주:2] 레지스터에 0x0000, IP[각주:3] 레지스터에 0x7C00 이 들어가 있는 상태.

   즉              0 0 0 0 ?      ; 세그먼트 시작주소 (CS)
                +    7 C 0 0      ; Offset (ip)
                ---------------- 
                   0 7 C 0 0     이 된다.
          < 16 Bit Real Mode 의 세그먼트와 오프셋 >

   1: [org 0]
   2: [bits 16]
   3:     jmp 0x07C0:start        ;far jmp 를 한다.

1. 오프셋 기준이 0부터 시작   
    만약 [org 10] 이면 ,   0x07C00 + start + 0x10 이 된다. 
2. 16 bit 용으로 사용 한다는 의미
3. 0x07C00 + start 로 jump 한다는 의미

   5: start:
   6:     mov ax, cs            ;cs 에는 0x07C0 이 들어 있다.
   7:     mov ds, ax             ;ds 를 cs 와 같게 해준다.

6,7. cs 와 ds 를 0x07C0 값으로

   9:     mov ax, 0xB800            ;비디오 메모리의 세그먼트를
  10:     mov es, ax            ;es 레지스터에 넣는다.
  11:     mov di, 0        ;제일 윗 줄의 처음에 쓸 것이다.
  12:     mov ax, word [msgBack]     ;써야 할 데이터의 주소값을 지정한다. 
  13:     mov cx, 0x7FF           ;화면 전체에 쓰기 위해서는 
  14:                     ;0x7FF(10진수 2047)개의 WORD 가 필요하다.
  50: msgBack db '.', 0xE7        ;배경색으로 사용할 데이터

9,10. es 를 0xB800 (비디오 메모리 세그먼트)
11. di = 0
12. msgBack에 있는 값을 2 Byte (워드) ax 로 읽어들인다.
     CPU 는 묵시적으로 DS:msgBack 과 같다.  ( 그래서 7번 줄에 ds 값을 0x07C0 으로 한다)
13,14. 2047 을 cx 에 대입.

  15: paint:
  16:     mov word [es:di], ax    ;비디오 메모리에 쓴다.
  17:     add di,2        ;한 WORD를 썼으므로, 2를 더한다.
  18:     dec cx                ;한 WORD를 썼으므로, CX 의 값을 하나 줄인다.
  19:     jnz paint           ;CX 가 0이 아니면, paint로 점프하여
  20:                    ;나머지를 더 쓴다.

16. B8000 + 0 (es:di) 에 ax (‘.’,0x67) 을 쓴다.
     참고 : 9,10,11,12
17. 주석 참고
18. 주석 참고
19. 주석 참고
16 ~ 19.
    B 8000 에 . 찍고
    B 8001 에 color 넣고
    B 8002 에 . 찍고
    B 8003 에 color 넣고 ……  반복

7 6 5 4 3 2 1 0

ASCI 코드

배경색

글자색

< 비디오 메모리에 사용하는 값의 형식 >

==> 모든 화면에 . 찍는다.

  23:     mov edi, 0        ;제일 윗 줄의 처음에 쓸 것이다.
  24:     mov byte [es:edi], 'A'  ;비디오 메모리에 쓴다.
  25:     inc edi            ;한 개의 BYTE를 썼으므로 1을 더한다.
  26:     mov byte [es:edi], 0x06 ;배경색을 쓴다.
  27:     inc edi            ;한 개의 BYTE를 썼으므로 1을 더한다.
  28:     mov byte [es:edi], 'B'
  29:     inc edi

…… 생략 ……


23. offset 값 (edi = 0) 을 정한다.
24. B 8000 + 0 (offset) 에 ‘A’ 를 쓴다.
25. 주석 참고
26,27  B 8001 + 1 (offset) 에 0x06 을 쓴다.
…  계속 반복.

==> 화면에 ABC123 이 찍힌다.

  48:     jmp $            ;이 번지에서 무한루프를 돈다.
  51:  
  52: times 510-($-$$) db 0        ;여기서 부터, 509 번지까지 0 으로 채운다.
  53:          dw 0xAA55    ;510 번지에 0xAA 를, 511 번지에 0x55 를 넣어 둔다.

48. 주석 참고
52. 510 – ( 시작 – 끝 ) , 주석참고
53. 바이오스가 부트섹터로 인식하기 위한 코드 (이 값만 있어도 부트섹터로 인식)

관련 글 : http://sagidong.tistory.com/188
참고 글 : 만들면서 배우는 OS 커널의 구조와 원리

  1. Master Boot Record , 첫 512 Byte [본문으로]
  2. code segment [본문으로]
  3. program counter 현재 CPU가 실행하고 있는 명령의 주소가 들어 있음. 프로그램이 진행되는 동안 값은 계속 변함. [본문으로]