2011-10-26 3 views
6

에뮬레이트하려는 일부 하드웨어가 있습니다. 나는 내가 이렇게 낮은 수준에서 그것을 할 수 있는지 궁금해.메모리 매핑 I/O를 에뮬레이트하는 방법

#include <stdint.h> 
struct MyControlStruct 
{ 
    uint32_t data_reg_1; 
    uint32_t data_reg_2; 
    uint32_t dummy[2]; // to make the following registers have certain addresses 
    uint32_t control_reg_1; 
    uint32_t control_reg_2; 
}; 
volatile struct MyControlStruct* MyDevice = (struct MyControlStruct*)0xDeadF00; 

그래서, 내가 하드웨어 Windows에서 액세스 및 리눅스에 대한 다음 구문을 지원하려는 : 하드웨어 내가 구조체에 배치 많은 레지스터가

MyDevice->data_reg_1 = 42; 
MyDevice->data_reg_2 = 100; 
MyDevice->control_reg_1 = 1; 

을하면 코드의 마지막 줄 나는 하드웨어 에뮬레이터가 "깨어나서"몇 가지 일을하기를 원한다. 이 Windows 및/또는 Linux에서 구현할 수 있습니까? 나는 어떻게 든 "segmentation fault"신호를 잡는 것에 대해 생각했지만, 이것이 Windows에서 할 수 있는지 또는 전혀 할 수 있는지 확신하지 못했습니다.

나는 mmap의 매뉴얼 페이지를 보았다. 그것은 도울 수있는 것처럼 보이지만 어떻게 사용할 수 있는지 이해할 수 없었습니다.

물론, WriteToMyDevice과 같은 기능을 정의하여 하드웨어에 대한 액세스를 추상화 할 수 있으며, 모든 것이 쉬운 (어쩌면) 것이지만이 정확한 방식으로 내 하드웨어에 대한 액세스를 조정할 수 있는지 알고 싶습니다.

+0

"낮음"이 너무 높습니다 ... Windows 및 Linux 모두 하드웨어 액세스가 커널 모드에서 수행됩니다. 구현 세부 사항, 즉 하드웨어와 대화하는 방법에 대해 생각할 필요가 있습니다. 예를 들어, 실제 드라이버 및 드라이버 에뮬레이션을 작성할 수 있습니다. –

+0

그래서 사용자 모드에서 사전 정의 된 메모리 주소를 사용할 수 없습니까? – anatolyg

+0

직접 메모리 액세스를 사용하는 Windows/Linux 사용자 모드에서 하드웨어 장치와 직접 대화 할 수 없습니다. 이것은 커널 모드에서만 가능합니다. 이것이 구현 세부 사항에 대해 먼저 생각해 보라고 제안하는 이유입니다. 그들 없이는 에뮬레이션 할 대상을 실제로 모릅니다. –

답변

2

원칙적으로 원하지 않는 페이지에 대한 액세스를 트래핑하고 처리하며 지정된 주소에 액세스했는지 확인할 수있는 SIGSEGV에 대한 처리기를 프로그래밍 할 수 있습니다 (unportably).

Linux에서이를 수행하려면 SA_SIGINFO으로 sigaction 시스템 호출을 사용하고 신호 처리기의 세 번째 인수 인 ucontext_t*을 사용해야합니다.

이것은 매우 유보합니다. 다른 Unix (Linux 커널의 버전 번호조차도 문제가 될 수 있음)와 프로세서를 변경할 때 다르게 코딩해야합니다.

그리고 나는 리눅스 커널이 그렇게 처리되지 않는다고 들었습니다.

다른 좋은 커널 (Hurd, Plan9)은 사용자 수준의 페이지 매김을 제공하므로 도움이됩니다.

1

실제로 에뮬레이터는 Linux에서 순수한 사용자 공간 코드로 (다소 조잡하게) 가능합니다.

에뮬레이터를 구축하려면 (공유 메모리, 또는 아마도 확실히 mmap 파일을 사용 inotify를) 두 번째 스레드 또는 프로세스를 실제 하드웨어 드라이버의 메모리 맵핑 된 장치

를 에뮬레이션 된 메모리를보고 , 당신은 약간의 커널 코드가 필요 하겠지만, 이것은 단순히 실제 하드웨어 주소를 적절한 권한으로 사용자 공간에 매핑하는 것일 수 있습니다. 실제로 이것은 현대의 다중 사용자 운영 환경을 구식 도스 박스 또는 단순한 마이크로 컨트롤러처럼 행동하는 것으로 회귀합니다. 위대한 관행은 아니지만 적어도 보안이 중요하지 않은 곳에서는 작동 할 수 있습니다.

가상 머신에서 코드를 실행하는 것도 고려해 볼 수 있습니다.

운동 할 코드가 직접 작성된 것이라면 하드웨어 접근을 각 플랫폼 (예 : OS, 하드웨어 버전 또는 물리적/에뮬레이트 된). 이러한 기술은 환경을 만들 필요가있는 다른 사람의 기존 코드 인 경우 더 유용합니다. 고려할 수있는 또 다른 사항은 (예 : 원본이 너무 긴밀하게 통합되지 않은 경우) Linux의 LD_PRELOAD 또는 Windows의 래퍼 DLL과 같은 특정 기능의 동적 라이브러리 레벨 차단을 사용하는 것입니다. 또는 그 문제에 대해 바이너리를 패치하십시오.

1

처음에는 질문에 대한 오해가 있습니다. 메모리 매핑 하드웨어가 있고 에뮬레이션이 바이너리 호환 가능해야합니다. Windows에서는 VirtualAlloc을 사용하여 구조체에 메모리를 할당하고 SEH를 사용하여 가드 페이지로 만들고 액세스 할 수 있습니다.