본문 바로가기
OS/만들면서 배우는 OS 커널의 구조와 원리

1. 부트스트랩

by 내용증명장인 2026. 4. 3.

들어가기에 앞서 레지스터나 세그먼트, 스택에 대해서 간단하게 정리하려 한다.

범용 레지스터

AX(Accumulator) : 산술 연산
BX(Base) : 주소를 가리키는 포인터
CX(Count) : 반복문 횟수
DX(Data) : AX 보조 역할, 큰 수 연산 또는 H/W 포트 I/O 주소 지정

포인터 및 인덱스 레지스터

SI(Source Index) : 데이터를 가져올 출발지
DI(Destination Index) : 데이터를 가져올 목적지
BP(Base Pointer) : 스택 접근 시 기준점(현 함수, 서브 루틴 등의 첫 번째 스택 값)
SP(Stack Pointer) : 현재 스택의 꼭대기 주소

세그먼트 레지스터

CS(Code Segment) : 지금 실행 중인 기계어 코드가 있는 영역
DS(Destination Segment) : 프로그램이 사용하는 변수나 데이터가 있는 영역
SS(Stack Segment) : 스택 메모리 영역
ES(Extra Segment) : DS 보조 공간

제어 및 상태 레지스터

IP(Instruction Pointer) : 다음에 실행할 명령어 주소, PC(Program Counter)랑 같음, 아키텍처에 따라 이름만 다르다.


부트스트랩이란?

컴퓨터에 전원이 들어온 후 무슨 일을 해야하는지 알려주는 것을 부트스트랩이라 한다.
전원이 들어오면 BIOS는 장치 점검 후 마지막 단계로 MBR영역의 첫 512바이트를 메모리로 로드한다.

해당 챕터에서 작성한 프로그램을 플로피디스크를 통해 부팅시키는 것이 목적이다.

[org 0]
[bits 16]

    jmp 0x07C0:start

start:
    mov ax, cs
    mov ds, ax
    
    mov ax, 0xB800
    mov es, ax
    mov di, 0
    mov ax, word [msgBack]
    mov cx, 0x7FF

paint:
    mov word [es:di], ax
    add di, 2
    dec cx
    jnz paint

    mov edi, 0
    mov byte [es:edi], 'A'
    inc edi
    mov byte [es:edi], 0x06
    inc edi
    mov byte [es:edi], 'B'
    inc edi
    mov byte [es:edi], 0x06
    inc edi
    mov byte [es:edi], 'C'
    inc edi
    mov byte [es:edi], 0x06
    inc edi
    mov byte [es:edi], '1'
    inc edi
    mov byte [es:edi], 0x06
    inc edi
    mov byte [es:edi], '2'
    inc edi
    mov byte [es:edi], 0x0
    inc edi
    mov byte [es:edi], '3'
    inc edi
    mov byte [es:edi], 0x06
    inc edi
        jmp $
    
    msgBack db '.', 0x67

    times 510-($-$$) db 0
    dw 0xAA55

far jmp 수행

jmp 0x07C0:start

far jmp란 CS 세그먼트 값을 바꾸는 것을 의미 → 현재 실행 중인 프로그램의 코드 영역으로 주소 값을 옮기는 작업
또한 0x07C0은 인텔 계열 아키텍처에서 고정된 boot sector 주소

세그먼트 값 수정

mov ax, cs
mov ds, ax

위 어셈블리는 결국 mov ds, cs를 의미하게 되는데, 인텔 계열 아키텍처(ex. x86-64)는 세그먼트 값을 수정하려면 범용 레지스터를 거쳐야함
ds와 cs의 값을 맞추는 이유는 ds에 어떤 값이 들어있을지 모르니, cs 코드 영역 부분에서 데이터를 찾게 하기 위해 서로 값을 맞추게 된다.

times 510-($-$$) db 0
509번지까지 0으로 채움 → padding

dw 0xAA55
부트로더의 마지막을 알려주는 역할
0xAA55은 고정 값임, 시스템에서 정해진 값

위 코드를 컴파일 후 vmware에서 플로피디스크에 포함시켜 실행하니 다음과 같은 화면이 나온 것을 확인

프로그램이 부팅된 것을 확인함.(위 사진에선 2의 색깔을 0으로 설정하여 안보임)

위 어셈블리어를 컴파일한 기계어를 다시 디스어셈블 후 확인한 결과이다.

00000000  EA0500C007        jmp word 0x7c0:word 0x5
00000005  8CC8              mov ax,cs
00000007  8ED8              mov ds,ax
00000009  B800B8            mov ax,0xb800
0000000C  8EC0              mov es,ax
0000000E  BF0000            mov di,0x0
00000011  A17C00            mov ax,[0x7c]
00000014  B9FF07            mov cx,0x7ff
00000017  268905            mov [es:di],ax
0000001A  83C702            add di,0x2
0000001D  49                dec cx
0000001E  75F7              jnz 0x17
00000020  66BF00000000      mov edi,0x0
00000026  2667C60741        mov byte [es:edi],0x41
0000002B  6647              inc edi
0000002D  2667C60706        mov byte [es:edi],0x6
00000032  6647              inc edi
00000034  2667C60742        mov byte [es:edi],0x42
00000039  6647              inc edi
0000003B  2667C60706        mov byte [es:edi],0x6
00000040  6647              inc edi
00000042  2667C60743        mov byte [es:edi],0x43
00000047  6647              inc edi
00000049  2667C60706        mov byte [es:edi],0x6
0000004E  6647              inc edi
00000050  2667C60731        mov byte [es:edi],0x31
00000055  6647              inc edi
00000057  2667C60706        mov byte [es:edi],0x6
0000005C  6647              inc edi
0000005E  2667C60732        mov byte [es:edi],0x32
00000063  6647              inc edi
00000065  2667C60700        mov byte [es:edi],0x0
0000006A  6647              inc edi
0000006C  2667C60733        mov byte [es:edi],0x33
00000071  6647              inc edi
00000073  2667C60706        mov byte [es:edi],0x6
00000078  6647              inc edi
0000007A  EBFE              jmp 0x7a
0000007C  2E670000          add [cs:eax],al
00000080  0000              add [bx+si],al
00000082  0000              add [bx+si],al
00000084  0000              add [bx+si],al
....(내용 같음)
000001F8  0000              add [bx+si],al
000001FA  0000              add [bx+si],al
000001FC  0000              add [bx+si],al
000001FE  55                push bp
000001FF  AA                stosb

jmp 0x07C0: start → jmp word 0x7c0:word 0x5 로 바뀐 것을 확인 가능함.
start: 로 jmp하라는 뜻이므로 start 시작 부분인 00000005 주소인 0x5로 점프한 것으로 바뀐다.

[org 0]은 메모리의 0번지서부터 어셈블리가 시작할 거라고 알려주는 지시어이다.
[bits 16]은 프로그램이 16비트 용이라는 것을 알려주는 선언문이다.

여기서 [org 0]의 0은 10진수이다.
[org 10]이라면 jmp 명령어는 다음과 같이 바뀐다.

jmp word 0x7c0:word 0xf

[org 0x10] 이면 0xf 가 0x16으로 바뀔 것이다.
주의해서 봐야한다.

참고로 jmp $에서 $는 현 위치의 주소 값을 의미하는데, jmp $ 이면 jmp $ 위치로 계속 돌아가라는 뜻이 된다.

Real Mode와 Protected Mode

Real Mode란 컴퓨터가 처음 켜지면 활동하는 모드이다.
예로 MS-DOS가 있는데, 리얼 모드는 프로그램이 한 번에 한 개씩 밖에 동작하지 못한다.

Protected Mode란 현재 운영체제의 동작 모드이다.
프로그램들이 한번에 동작할 수 있다

컴퓨터에 전원이 들어온 후 Real Mode에서 세팅을 맞춘 후 Protected Mode로 전환한다.

Protected Mode의 경우 두 가지로 나뉜다.
유저 모드와 커널 모드로 나뉜다.

'OS > 만들면서 배우는 OS 커널의 구조와 원리' 카테고리의 다른 글

6. 보호  (0) 2026.04.13
5. 태스크 스위칭, 문맥 교환  (0) 2026.04.13
4. 인터럽트와 예외  (0) 2026.04.10
3. Protected Mode로 변환  (1) 2026.04.08
2. 커널 로드  (0) 2026.04.06