update qemu study

This commit is contained in:
2025-12-30 08:19:49 +00:00
parent ac241a9148
commit 8f1a81b699
11 changed files with 885 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
; mybios_real.asm
[BITS 16]
[ORG 0]
bios_start:
; 1. 세그먼트 초기화
mov ax, 0xF000
mov ds, ax
mov es, ax
xor ax, ax
mov ss, ax
mov sp, 0x7C00
; ==========================================================
; [VGA BIOS (Option ROM) 실행하기]
; QEMU는 0xC0000 번지에 표준 VGA BIOS를 올려둡니다.
; 이걸 실행해야 화면이 켜지고 curses가 작동합니다.
; ==========================================================
; 2-1. VGA BIOS가 있는지 확인 (Signature Check)
; 0xC000:0000 = 0x55, 0xC000:0001 = 0xAA 여야 함
mov ax, 0xC000
mov es, ax
cmp byte [es:0], 0x55
jne no_vga
cmp byte [es:1], 0xAA
jne no_vga
; 2-2. VGA BIOS 실행 (Far Call)
; 보통 3번째 바이트부터 코드가 시작됩니다.
; PUSH CS, PUSH IP 방식으로 돌아올 주소를 저장하고 점프합니다.
push cs ; 돌아올 세그먼트 (0xF000)
push word .vga_ret ; 돌아올 오프셋 (Label 주소)
; 0xC000:0003 으로 점프!
push 0xC000 ; VGA Segment
push 0x0003 ; VGA Entry Point
retf ; (Far Return을 이용한 점프 기법)
.vga_ret:
; 여기까지 오면 VGA BIOS가 화면을 초기화하고 돌아온 상태입니다!
; 이제 다시 우리의 세그먼트 복구
mov ax, 0xF000
mov ds, ax
mov es, ax
; 3. 화면 파란색으로 칠하기 (이제 먹힘!)
mov ax, 0xB800
mov es, ax
xor di, di
mov cx, 2000
mov ax, 0x1F20 ; 파란바탕 + 공백
rep stosw
; 4. 메시지 출력
mov si, msg_title
mov di, 0
call print_vga
mov si, msg_menu
mov di, 160
call print_vga
; 5. 메인 루프 (키보드 0x60)
main_loop:
in al, 0x64
test al, 1
jz main_loop
in al, 0x60
cmp al, 0x02 ; '1'
je action_shutdown
cmp al, 0x03 ; '2'
je action_reboot
jmp main_loop
; --- 에러 처리: VGA BIOS가 없을 때 ---
no_vga:
; 시리얼로 에러 메시지라도 보내야 함 (여기선 생략하고 무한루프)
cli
hlt
jmp $
; ===========================================================
; [Actions] (이전과 동일)
; ===========================================================
action_shutdown:
mov si, msg_bye
mov di, 320
call print_vga
; ACPI PIIX4 Shutdown
mov dx, 0xCF8
mov eax, 0x80000B04
out dx, eax
mov dx, 0xCFC
mov eax, 0x0001
out dx, eax
mov dx, 0xCF8
mov eax, 0x80000B40
out dx, eax
mov dx, 0xCFC
mov eax, 0x0000B001
out dx, eax
mov dx, 0xCF8
mov eax, 0x80000B80
out dx, eax
mov dx, 0xCFC
mov eax, 0x00000001
out dx, eax
mov dx, 0xB004
mov ax, 0x2000
out dx, ax
hlt
jmp $
action_reboot:
mov si, msg_reboot
mov di, 320
call print_vga
mov dx, 0x64
mov al, 0xFE
out dx, al
hlt
jmp $
; ===========================================================
; [Drivers]
; ===========================================================
print_vga:
mov ah, 0x1F
.loop:
lodsb
cmp al, 0
je .done
stosw
jmp .loop
.done:
ret
; ===========================================================
; [Data]
; ===========================================================
msg_title db "=== REAL BIOS (VGA Initialized) ===", 0
msg_menu db "Press [1] to Shutdown, [2] to Reboot", 0
msg_bye db "System Halted.", 0
msg_reboot db "Rebooting...", 0
; --- BIOS 크기 맞추기 (64KB) ---
times 65520-($-$$) db 0
reset_vector:
jmp 0xF000:0x0000
times 16-($-reset_vector) db 0