Files
kernel-study/study/first/boot.asm
T
2025-12-30 08:19:49 +00:00

62 lines
2.1 KiB
NASM

; boot.asm
[BITS 16]
[ORG 0x7C00]
start:
; 1. 세그먼트 레지스터 초기화 (DS, ES, SS)
xor ax, ax ; AX = 0
mov ds, ax ; DS = 0
mov es, ax ; ES = 0
mov ss, ax ; SS = 0
mov sp, 0x7C00 ; 스택 포인터를 0x7C00 밑으로 설정 (안전지대)
; 2. 커널 로딩 안내 메시지 출력
mov si, msg_boot
call print_string
; 3. 디스크에서 커널 읽기 (BIOS INT 0x13 사용)
; 우리는 커널을 디스크의 2번째 섹터(Sector 2)에 저장할 것입니다.
; 그것을 메모리 주소 0x8000 번지에 로드합시다.
mov ah, 0x02 ; BIOS 기능: 섹터 읽기
mov al, 1 ; 읽을 섹터 수: 1개
mov ch, 0 ; 실린더 번호: 0
mov cl, 2 ; 섹터 번호: 2 (1번은 부트로더니까 2번부터)
mov dh, 0 ; 헤드 번호: 0
; DL은 BIOS가 부팅된 드라이브 번호를 자동으로 넣어줍니다. (건드리지 말 것)
mov bx, 0x8000 ; 데이터를 저장할 메모리 주소 (ES:BX = 0x0000:0x8000)
int 0x13 ; 인터럽트 발생! (읽어와라!)
jc disk_error ; 만약 에러가 나면(Carry Flag=1) 에러 처리로 점프
; 4. 커널로 점프!
; 0x8000 번지에 커널 코드가 도착했으니 거기로 제어권을 넘깁니다.
mov si, msg_jump
call print_string
jmp 0x8000
disk_error:
mov si, msg_err
call print_string
jmp $ ; 무한 루프
; --- 문자열 출력 함수 ---
print_string:
mov ah, 0x0E ; BIOS 기능: 텔레타입 출력 (한 글자 찍기)
.loop:
lodsb ; [SI]의 데이터를 AL로 로드하고 SI 1 증가
cmp al, 0 ; 문자열 끝(NULL)인지 확인
je .done
int 0x10 ; 화면에 출력 (BIOS INT 0x10)
jmp .loop
.done:
ret
msg_boot db "Bootloader started...", 0x0D, 0x0A, 0
msg_jump db "Jumping to Kernel...", 0x0D, 0x0A, 0
msg_err db "Disk Read Error!", 0
; --- 부트 서명 (MBR 필수) ---
times 510-($-$$) db 0 ; 510바이트까지 0으로 채움
dw 0xAA55 ; 마지막 2바이트는 무조건 0x55, 0xAA (매직 넘버)