cr0 보호모드 진입시 무한리부팅 현상..
아래는 부트로더 소스입니다..
여기서 cr0의 pe bit를 1로 설정하게되면 리부팅 현상이 발생합니다..
원인을 모르겟네요;;
gdt디스크립터도 가장 중요한 code 디스크립터와 data 디스크립터만 등록한 상황이라
디스크립터가 잘못되진 않은것같구요;;
ㅠ.ㅠ 뭐 잘못된 부분이 잇나요;;
.MODEL SMALL
.386P
.DATA
;===============================================================================
; GDT table descriptor
;===============================================================================
GDT_DESCR STRUCT
ALIGN 4
gdt_size WORD GDT_END - GDT - 1
gdt_location DWORD GDT+7E00H
GDT_DESCR ENDS
;===============================================================================
; GDT table
;===============================================================================
;----------------------------------
; GDT TABLE INDEX #0
; INDEX : NULL SELECTOR
;----------------------------------
GDT dd 0
dd 0
;----------------------------------
; GDT TABLE INDEX #1
; INDEX : 0x0008h
; TYPE : CODE SEGMENT
; RING LEVEL : 0
; ATTRIBUTES : Excute/Read, Nonconforming, 4GB
;----------------------------------
dw 0ffffh ; segment limit 15:00
dw 0000h ; base address 15:00
db 00h ; base address 23:16
db 10011010b ; P | DPL | S | TYPE
db 11001111b ; G | D/B | 0 | AVL | segment limit 19:16
db 00h ; base address 31:24
;----------------------------------
; GDT TABLE INDEX #2
; INDEX : 0x0010h
; TYPE : DATA SEGMENT
; RING LEVEL : 0
; ATTRIBUTES : Read/Write, 4GB
;----------------------------------
dw 0ffffh
dw 0000h
db 00h
db 10010010b
db 11001111b
db 00h
GDT_END EQU $
gdt_descriptor GDT_DESCR <>
msg_loader db "kernel loading..", 0h
.CODE
MAIN PROC
mov ax, 07E0h
push word ptr ax
mov ax, offset init
push word ptr ax
retf
init:
; Set DS and ES to the data segment.
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
MOV SS, AX
CLI
LGDT gdt_descriptor
mov eax, cr0
or eax, 1
mov cr0, eax
jmp $+2
db 66h
db 0EAh
dd EntryPoint32
dw 08h
finish:
HLT
jmp finish
MAIN ENDP
EntryPoint32 PROC NEAR
finish:
HLT
jmp finish
EntryPoint32 ENDP
MSGOUT PROC
push bp
mov bp, sp
pusha
mov si, WORD ptr [bp+4]
print:
lodsb
or al, al
jz finish
mov ah, 0eh ; teletype output function
mov bx, 08h ; back/fore ground color
int 10h
jmp print
finish:
popa
pop bp
ret
MSGOUT ENDP
END MAIN
딱히 문제가
딱히 문제가 보이지는 않습니다만 부트섹터에서 점프하는 위치가 정확한지 메모리 덤프를 떠서 확인
해보시길 권장해드립니다. 가끔 어셈블러 버그인지 엉뚱한곳에 패딩을 넣거나 해서 문제가 생기는
경우가 종종 있더군요. 그리고 생성된 기계어가 정상적으로 어셈소스와 일치하는지도 확인해보시기 바랍니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
부트섹터에서 점프하는 위치는..
부트섹터에서 점프한후 cr0을 바꾸기전에 출력을 해봣는데 정상적인 출력이 되더군요...
bochs로 로그파일을 보면 cs에 7e00 이 제대로 들어가있구요..
그렇다면 점프 위치가 틀린게 아니지 않나욤??!!
cr0 밑에 기계어를 빼도 똑같은 무한재부팅이라.. 기계어도 문제는 아닌것같은데...
그리고..한가지 메모리덤프툴로 괜찮은 툴 있을까요..?!
예전에 objdump 인가.. 잘생각이안나네요.. 이건 리눅스 툴인것같고..
쓰시는툴있으시다면 윈도우툴 하나 추천도 좀 부탁드립니다^^;;
-현재 FAR 점프하는 기계어 명령이 문제가있나봅니다..
주석처리를하면 재부팅하지않네요..
근데 기계어는 저게 맞는것같은데..
db 66h
db 0eah
dd EntryPoint32
dw 08h
왜그럴까요...제가봣을땐 저부분이 맞는것같은데..
어셈블리 코드에
어셈블리 코드에 기준점(org)도 확인해보시고 플로피에서 읽은 부트섹터 이후의 코드가
정상적으로 메모리에 위치하는지 확인해보시는게 가장 좋을것 같습니다.
저같은 경우 메모리 덤프는..... 딱히 가상머신에서 지원하지 않으면 안되므로 vmware에 돌리고
vmware가 작동시 설정한 메모리 크기만큼 하드디스크에 메모리 파일이 생성됩니다.(확장자가 vmem)
이를 그냥 hex에디터로 열어서 확인하고 있습니다.
far점프시 문제가 생긴다면 저같은 경우에는 어셈블러가 삽질해서 컴파일된 기계어 코드 정렬이 틀어진
경우가 있었습니다.(align을 썼더니 멋대로 잘못된 위치에 패딩을 넣거나)
또는 어셈블러에게 16비트 코드를 만들랬더니 이상한 코드를 만들어서 문제가 됬었습니다.(nasm에서 [bit 16]을 [org xx]보다 앞에 놓으면 오동작)
ps. 점프하는 기계어 코드는 맞는것 같습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
음...
게답변 감사합니다 그런데 이상한게.. vmware의 veme파일은
하드디스크에 기록되잇다고하셧는데 그렇다면 일단문자열이출력이된다는건
플로피 디스크에서 메모리에 올라가서 실행이된다는건데요
그렇다면 7c00번지에 어떠한 hex코드가잇어야되는데
0밖에없네요... 운영체제가 깔려져있는 veme파일은 정상적으로 hex값들이잇는데요;;
원래는 정상적으로
원래는 정상적으로 부트섹터의 코드들이 들어있어야지 정상입니다.
그런데 자꾸 리붓이 되니까 순간 계속 메모리가 리셋되니까 그렇습니다.
컴퓨터가 리붓되는 어셈 명령어 바로 위에 jmp $와 같이 컴퓨터를 정지 시키신 다음에
복사하셔야지 제대로 보실 수 있습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
감사합니다.
vmware 을 일시정시시키고나서 보게되면 정상적으로 보이는군요..
안그러면 vmem파일이 없어지네욤..
일단봣는데
7c00번지부터 7df0 마지막에 55aa 라는 문자가 있으니 부트섹터는 일단잘들어간것같구요
그다음 부트로더를 올렸던 7e00 부터 hex값이 있네요
값은 잘들어간것같은데.. 정확히 딱 점프 기계어코드에서 에러가 발생하게되네요
jmp $를 점프기계어 코드 위에 햇을땐 멈추었으나
기계어코드 뒤에 넣으면 계속 리부팅되는현상입니다...
원인을 모르겟네요...메모리도 정상적으로 들어가있는것같은데.....
보호모드 전환직후
보호모드 전환직후 리붓한다면 GDTR 잘못 로드하거나 GDTR이 가리키는 디스크립터가 잘못된 경우가 대부분입니다.
GDTR 값도 덤프 떠볼 필요가 있을 걸로 판단되네요.
그리고 전환직후 DS, SS는 로드시킬 필요가 있을 것으로 판단되네요. 안쓸것이면 0으로 놓고요.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
보호모드 전환중에는
보호모드 전환중에는 인터럽트, 특히 외부 인터럽트(IRQ)를 막아야 하는데,
보통은 cli 만으로는 안되고, 8259A의 포트를 제어해서 막을 필요가 있습니다.
IDTR 셋팅되고 외부 IRQ를 자체내에서 처리할 수 있을 때에 다시 허용을 하죠.
추가 : A20 Gate Enable 작업도 없네요. 보호모드 전환 목적 대부분이 1M 이상 메모리를 대량으로 쓰는건데, 이때문에 거의 필수로 들어갑니다.
Written By the Black Knight of Destruction
Written By the Black Knight of Destruction
아..일단은
일단 gdt부터 할려고하고있습니다 어떤책에서도 a20gate와 인터럽트를 하지않고 그냥 바로 gdt부터 하더라구요
일단 보호모드로 진입하는데는 gdt만 잇어도상관은 없는것같습니다..
근데 지금 gdt만을해서 보호모드로 들갈려는데 무한 재부팅현상이 생겨서 그렇습니다..
- 현재 8259A의 포트를 제어해서 외부인터럽트를 막앗음에도 불구하고.. 현상은 같네요;;
댓글 달기