2013-05-05 3 views
1

현재 커널을 개발 중이며 시스템 호출을 구현할 때 신비한 문제가 발생합니다. 다음과 같이 0x80th 인터럽트 처리기를 작성합니다.인터럽트 처리기에서 이상한 동작이 발생했습니다.

sys_call_s: 
    pushad 
    call sys_call 
    popad 
    iret 

"sys_call"은 실제 작업을 수행하는 C 함수의 이름입니다. 문제는 : "int 0x80"의 다음 명령을 실행할 때 트리플 오류가 발생했습니다. 예를 들어, 프로그램의 세 번째 행을 실행할 때 오류가 발생하고 마지막으로 boch가 스스로 재설정됩니다.

abc: mov eax,0    ; 0 means system call get_pid() 
    int 0x80 
    mov [pid_father],eax ; this is the instruction caused bochs to triple fault 
    mov eax,1    ; 1: fork() 
    int 0x80 
    jmp $ 

pid_father: dd 0 

더욱 strangly, 나는 "RET"와 "IRET"명령을 대체 할 때, 프로그램은 잘 작동하고 "JMP의 $"에서 그 자체를 회전.

이 문제가 발생하는 이유는 누구나 알 수 있습니까?

[편집] 이제이 문제는 스택 포인터의 잘못된 주소 때문에 발생했다고 생각합니다. 이 프로세스의 페이지를 매핑했습니다.이 페이지의 실제 주소는 0x401000이고 선형 주소는 0x800000 (8M)입니다. 이 프로세스의 스택 포인터를 0x800ff0으로 설정했지만 bochs에서 "print-stack"명령을 사용할 때마다 "실제 주소를 선형 0x00801000에 사용할 수 없습니다"라는 출력이 표시됩니다. 어떻게 해결할 수 있습니까?

[편집] 이제이 프로세스에서 데이터에 액세스 할 수 없음을 알게되었습니다. 예를 들어 "mov [pid_father], eax"를 "int 0x80"앞에두면 bochs가 자체를 재설정합니다. 왜 이런 일이 일어난거야?

답변

1

GDT 및 DS 레지스터 및 페이징 테이블의 내용을 표시해야한다고 생각합니다. 코드의 나머지 부분없이 해당 줄에 트리플 폴트가 표시되면 [pid_father]에 대한 액세스가 문제가된다는 것을 의미합니다. 데이터 세그먼트가 유효하지 않거나 페이지가 잘못되었거나 읽기 전용으로 표시되어 GPF 또는 페이지 오류 예외가 발생했습니다. GPF 또는 페이지 오류 예외가 두 번 오류 예외를 일으키는 오류 (동일한 이유로 또는 다른 오류 일 수 있음)가 다시 실패하여 CPU에 세 가지 오류 및 재설정이 발생합니다.

Bochs는 일반적으로 오류가 발생한 이유를 인쇄 할 때 (메모리에서) 아주 좋습니다. 히스토리를 조금 올리고 올린 첫 번째 예외를 찾아야 할 수 있습니다.

+0

힌트를 보내 주셔서 감사합니다. 스튜어트. –

+1

문제는 페이지 테이블에서 찾습니다. 해당 페이지 테이블 항목에 쓰기 가능 플래그를 설정하지 않았습니다. 따라서이 페이지에 글을 쓸 때마다 보호 오류가 발생합니다. "ret"명령어를 사용하여 인터럽트 핸들러에서 복귀하는 경우 코드 세그먼트의 선택자는 커널의 코드 선택기 인 0x10이며이 세그먼트의 코드는 모든 페이지에 대한 읽기/쓰기 권한이 있습니다. 이것은 바로 "iret"명령을 "ret"로 대체 한 직후의 첫 번째 프로세스 beheaviors를 설명합니다. –

+0

정말요? 나는 페이지 보호가 선택 자 보호를 초과한다고 생각했기 때문에 페이지 테이블이 읽기 전용으로 표시된 경우 페이지는 현재 코드 세그먼트와 상관없이 읽혀진다. BTW - 페이징을 사용할 수 있음을 언급하지 않았습니다. 그것은 언급 할만한 유용한 것이었을 것입니다. – Stewart

관련 문제