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
+123
View File
@@ -0,0 +1,123 @@
; mybios.asm
[BITS 16]
[ORG 0]
bios_start:
; 1. 세그먼트 초기화 (CS=0xF000 이므로 DS, ES도 맞춤)
mov ax, 0xF000
mov ds, ax
mov es, ax
; mov ss, ax
; mov sp, 0xFFF0
xor ax, ax ; AX = 0
mov ss, ax ; SS = 0x0000 (RAM)
mov sp, 0xFFFE ; 0x0000 ~ 0xFFFF 영역 중 가장 끝!
; mov sp, 0x7C00 ; SP = 0x7C00 (부트로더가 쓰는 안전한 RAM 공간)
; 2. 시리얼 포트(COM1) 초기화 (필수!)
mov dx, 0x3FB ; Line Control Register
mov al, 0x80 ; DLAB bit set
out dx, al
mov dx, 0x3F8 ; Divisor (Low) - 9600 baud
mov al, 0x0C
out dx, al
mov dx, 0x3F9 ; Divisor (High)
mov al, 0x00
out dx, al
mov dx, 0x3FB ; LCR: 8 bits, no parity, 1 stop bit
mov al, 0x03
out dx, al
; 3. 메시지 출력
mov si, msg_bios
call print_serial
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ===========================================================
; [ACPI Shutdown Sequence for QEMU PIIX4 Chipset]
; Target: Bus 0, Device 1, Function 3 (Power Management)
; Address Format: 1(En) | Bus(0) | Dev(1) | Func(3) | Reg
; Hex Prefix: 0x80 | 00 | 08 | 03 | ..
; Combined: 0x80000B.. (Function 3 is the key)
; ===========================================================
; Step 0: Enable I/O Access (Command Register - 0x04)
; We must tell the chipset to allow I/O port access first.
mov dx, 0xCF8
mov eax, 0x80000B04 ; Address: Func 3, Reg 0x04
out dx, eax
mov dx, 0xCFC
mov eax, 0x0001 ; Value: Bit 0 (I/O Space Enable)
out dx, eax
; Step 1: Set ACPI Base Address (PMBA - 0x40)
; We map the ACPI registers to I/O port 0xB000.
mov dx, 0xCF8
mov eax, 0x80000B40 ; Address: Func 3, Reg 0x40
out dx, eax
mov dx, 0xCFC
mov eax, 0x0000B001 ; Value: Base 0xB000 | Bit 0 (Hardwired to 1)
out dx, eax
; Step 2: Enable ACPI Function (PMREGMISC - 0x80)
mov dx, 0xCF8
mov eax, 0x80000B80 ; Address: Func 3, Reg 0x80
out dx, eax
mov dx, 0xCFC
mov eax, 0x00000001 ; Value: Bit 0 (ACPI Enable)
out dx, eax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov si, msg_off
call print_serial
; ; Exit with return value 0
mov dx, 0xB004
mov ax, 0x2000 ; SLP_TYP(Soft Off) | SLP_EN
out dx, ax
; ; reboot
; mov dx, 0x64
; mov al, 0xFE
; out dx, al
; ; exit (isa-debug-exit; need '-device isa-debug-exit,iobase=0x501,iosize=0x04')
; mov dx, 0x501
; mov al, 0x02 ; exit code (2) -> qemu exits with exit code (al<<1)|1
; out dx, al
; 그래도 안 꺼지면 그냥 멈춰라
cli
hlt
jmp $
; --- 시리얼 출력 함수 ---
print_serial:
mov dx, 0x3F8 ; COM1 데이터 포트
.loop:
lodsb ; [DS:SI] -> AL
cmp al, 0
je .done
out dx, al ; 한 글자 전송
jmp .loop
.done:
ret
; msg_bios db "Hello! This is a CUSTOM BIOS running on QEMU!", 0x0D, 0x0A, 0
msg_bios db "Hello! This is a CUSTOM BIOS running on QEMU!", 0x0D, 0x0A, 0
msg_off db "ACPI Enabled. Powering Off NOW!", 0x0D, 0x0A, 0
; Padding
times 65520-($-$$) db 0
reset_vector:
jmp 0xF000:0x0000
times 16-($-reset_vector) db 0