; 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 (매직 넘버)