2013-10-11 2 views
0

저는 64 비트의 매우 간단한 운영체제를 만들려고합니다. 먼저 보호 모드를 시작하려고하는데이 시점에서 실패합니다.보호로 전환하면 시스템이 다시 시작되는 이유는 무엇입니까?

32 비트로 멀리 점프하면 컴퓨터가 다시 시작됩니다.

내 코드는 0x100에 다른 어셈블리 프로그램과 함께 메모리에로드됩니다.

코드가 nasm으로 컴파일되었고 qemu -fda을 사용하여 프로그램을 실행 중입니다. 나는 멀리뛰기 전에 jmp $을 할 경우 멀리뛰기이 완료되면

[BITS 16] 

jmp _start 

_start: 
    cli 

    lgdt [GDT64] 

    ; Switch to protected mode 
    mov eax, cr0 
    or al, 1b 
    mov cr0, eax 

    ; Desactivate pagination 
    mov eax, cr0 
    and eax, 01111111111111111111111111111111b 
    mov cr0, eax 

    jmp (CODE_SELECTOR-GDT64):pm_start 

[BITS 32] 

pm_start: 
    jmp $ 

GDT64: 
    NULL_SELECTOR: 
     dw GDT_LENGTH ; limit of GDT 
     dw GDT64  ; linear address of GDT 
     dd 0x0 

    CODE_SELECTOR:   ; 32-bit code selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10011010b 
     db 11001111b 
     db 0x0 

    DATA_SELECTOR:   ; flat data selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10010010b 
     db 10001111b 
     db 0x0 

    LONG_SELECTOR: ; 64-bit code selector (ring 0) 
     dw 0x0FFFF 
     db 0x0, 0x0, 0x0 
     db 10011010b  ; 
     db 10101111b 
     db 0x0 

    GDT_LENGTH: 

는, 작동, 프로그램이 제대로 정지하지만, 그것은 재부팅 : 여기

내가 지금까지 가지고 코드입니다 기계.

세그먼트 나 이와 비슷한 것을 설정하는 것을 잊었습니까?

답변

2

의견에 따르면 GDT의 선형 주소가 필요합니다. ORG 지시문을 지정하지 않은 것으로 보입니다. 따라서 어셈블러는 기본 주소 0을 사용하며 런타임시 주소와 일치하지 않습니다.

또한 코드를 0x100에로드하는 방법을 모르면 부트 섹터는 일반적으로 0x7c00에로드됩니다.

해결책은 파일 상단에 ORG 0x7c00을 지정하는 것처럼 간단 할 수 있습니다.

+0

하나님, 이미 시도했지만 세그먼트 레지스터를 재설정하는 것을 잊어 버렸습니다. 이제는 잘 작동합니다. 감사. –