152 lines
3.3 KiB
NASM
152 lines
3.3 KiB
NASM
; mybios_ssh.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
|
|
|
|
; 2. 시리얼 포트 초기화 (가장 중요!)
|
|
call init_serial
|
|
|
|
; 3. 부팅 메시지 출력
|
|
mov si, msg_boot
|
|
call print_serial
|
|
|
|
; 4. 메인 루프 (입력 대기)
|
|
mov si, msg_menu
|
|
call print_serial
|
|
|
|
main_loop:
|
|
; --- Heartbeat (살아있음을 표시) ---
|
|
; 입력이 없어도 멈춘 게 아니라는 걸 보여주기 위해 점(.)을 찍을 수도 있지만,
|
|
; 너무 지저분해지니 생략하고 입력만 기다립니다.
|
|
|
|
; [입력 확인] 0x3FD 포트의 0번 비트가 1이면 데이터가 온 것임
|
|
mov dx, 0x3FD
|
|
in al, dx
|
|
test al, 1
|
|
jz main_loop ; 데이터 없으면 계속 뺑뺑이(Loop)
|
|
|
|
; [데이터 읽기] 0x3F8 포트에서 읽음
|
|
mov dx, 0x3F8
|
|
in al, dx
|
|
|
|
; [내가 누른 키 화면에 보여주기 (Echo)]
|
|
; 이게 없으면 내가 뭘 눌렀는지 터미널에 안 보임!
|
|
out dx, al
|
|
|
|
; [키 판별]
|
|
cmp al, '1'
|
|
je action_shutdown
|
|
|
|
cmp al, '2'
|
|
je action_reboot
|
|
|
|
jmp main_loop
|
|
|
|
; ===========================================================
|
|
; [Actions]
|
|
; ===========================================================
|
|
|
|
action_shutdown:
|
|
mov si, msg_bye
|
|
call print_serial
|
|
|
|
; PIIX4 ACPI Shutdown (Power Off)
|
|
; 1. I/O Enable
|
|
mov dx, 0xCF8
|
|
mov eax, 0x80000B04
|
|
out dx, eax
|
|
mov dx, 0xCFC
|
|
mov eax, 0x0001
|
|
out dx, eax
|
|
|
|
; 2. PMBA -> 0xB000
|
|
mov dx, 0xCF8
|
|
mov eax, 0x80000B40
|
|
out dx, eax
|
|
mov dx, 0xCFC
|
|
mov eax, 0x0000B001
|
|
out dx, eax
|
|
|
|
; 3. ACPI Enable
|
|
mov dx, 0xCF8
|
|
mov eax, 0x80000B80
|
|
out dx, eax
|
|
mov dx, 0xCFC
|
|
mov eax, 0x00000001
|
|
out dx, eax
|
|
|
|
; 4. Shutdown Command
|
|
mov dx, 0xB004
|
|
mov ax, 0x2000
|
|
out dx, ax
|
|
|
|
; 안 꺼지면 대기
|
|
hlt
|
|
jmp $
|
|
|
|
action_reboot:
|
|
mov si, msg_reboot
|
|
call print_serial
|
|
|
|
; Reboot Command
|
|
mov dx, 0x64
|
|
mov al, 0xFE
|
|
out dx, al
|
|
hlt
|
|
jmp $
|
|
|
|
; ===========================================================
|
|
; [Drivers]
|
|
; ===========================================================
|
|
init_serial:
|
|
mov dx, 0x3FB
|
|
mov al, 0x80 ; DLAB ON
|
|
out dx, al
|
|
mov dx, 0x3F8
|
|
mov al, 0x0C ; 9600 baud
|
|
out dx, al
|
|
mov dx, 0x3F9
|
|
mov al, 0x00
|
|
out dx, al
|
|
mov dx, 0x3FB
|
|
mov al, 0x03 ; 8N1, DLAB OFF
|
|
out dx, al
|
|
ret
|
|
|
|
print_serial:
|
|
mov dx, 0x3F8
|
|
.loop:
|
|
lodsb
|
|
cmp al, 0
|
|
je .done
|
|
out dx, al
|
|
jmp .loop
|
|
.done:
|
|
ret
|
|
|
|
; ===========================================================
|
|
; [Data]
|
|
; ===========================================================
|
|
; 줄바꿈(0x0D, 0x0A)을 명확히 넣었습니다.
|
|
msg_boot db 0x0D, 0x0A, "===============================", 0x0D, 0x0A
|
|
db " SSH Serial BIOS v1.0 ", 0x0D, 0x0A
|
|
db "===============================", 0x0D, 0x0A, 0
|
|
|
|
msg_menu db 0x0D, 0x0A, "COMMANDS: [1] Shutdown [2] Reboot", 0x0D, 0x0A
|
|
db "Input > ", 0
|
|
|
|
msg_bye db 0x0D, 0x0A, ">>> System is HALTING...", 0x0D, 0x0A, 0
|
|
msg_reboot db 0x0D, 0x0A, ">>> REBOOTING...", 0x0D, 0x0A, 0
|
|
|
|
times 65520-($-$$) db 0
|
|
reset_vector:
|
|
jmp 0xF000:0x0000
|
|
times 16-($-reset_vector) db 0 |