2011-04-27 2 views
1

일부 메모리 매핑 하드웨어 용 리눅스 드라이버를 작성하려고합니다 (FPGA에 있으므로 필요한 경우 양쪽 메모리 매핑 된 인터페이스를 조정할 수 있습니다).linux kernel-> userspace 멀티 캐스트 스트리밍 데이터 그램

이 FPGA 로직은 일련의 데이터 그램을 생성합니다.이 데이터 그램은 처리해야하며 이더넷 링크를 통해 전송해야합니다. 커널에 처리 또는 네트워킹 코드가있을 이유가 없으므로 하드웨어에서 사용자 공간으로 데이터 블록을 이동시키는 "최상의"메커니즘에 대해 묻고 있습니다. 가장 큰 문제는 사용자 공간 처리가 여러 프로세스간에 분산되어야한다는 것입니다.

데이터 속도가 매우 높지 않고 (최대 1Mbps) mmio 인터페이스가 상당히 깊은 FIFO (현재 2KB가 8KB까지 증가 할 수 있음)에 의해 공급되기 때문에 우선 순위가 높은 사용자 모드 프로세스가 유지하다.

필자가 원하는 것은 기존의 멀티 캐스트 사용자 인터페이스 인터페이스가있는 기존 드라이버에 대한 포인터입니다 (다른 많은 것들은 복잡하지 않습니다). 그러나해야 할 일의 개요는 합리적인 대체물이 될 것입니다.

지금까지 다음과 같은 아이디어를 수집했습니다

  • AF_NETLINK가 : 멀티 캐스트를 지원하는 나를 위해 버퍼링을 처리합니다. 하지만 API가 불안정하고 다른 인 - 트리 드라이버와 충돌 할 수있는 새로운 소켓 ID를 정의해야하고 사용자 모드 인터페이스는 상당히 전문화되어 있으므로 socat과 같은 표준 도구를 사용하여 데이터 스트림을 테스트 할 수 없습니다.

  • 데이터 그램 모드 소켓 또는 FIFO 파일 디스크립터를 사용자 공간에서 전달하고 쓰기 (how?). 적용 할 수있는 유닉스 도메인 데이터 그램 소켓 멀티 캐스트 패치가 있습니다.

  • unix-domain 데이터 그램 소켓 서버의 역할을하는 단일 우선 순위 사용자 모드 응용 프로그램에 문자 모드 장치를 노출하고 연결된 각 노드에 데이터 그램을 복사합니다. 데이터 모드 경계가 문자 모드 장치에서 유지됩니까 (즉, 내 드라이버 read 함수가 fread 버퍼 크기보다 적은 바이트 수를 반환하면 fread은 블록 단위로 데이터 블록을 반환합니까, 아니면 블록을 조각화하고 다시 어셈블 할 수 있습니까? 대신 fread (3)read (2)? 드라이버의 읽기 기능은 데이터 그램이 잘립니다, 또는 단지 소켓에 대한 것을 볼 수 있습니다 것을 표시하기 위해 사용할 수있는 EMSGSIZE 같은 일이 있나요?)

  • 가 열 수있는 문자 모드 장치를 노출 다중 사용자 모드 응용 프로그램을 동시에 수행하고 데이터를 각 커널 내부로 버퍼링합니다.

들어오는 패킷을 재 라우팅하는 유닉스 도메인 서버가있는 문자 모드 장치를 향하고 있습니다. 이렇게하면 커널 드라이버 내부에 버퍼링 로직을 구현하지 않아도됩니다. 문제는 인터럽트가 발생할 때 select 호출에서 사용자 프로세스를 깨우거나 읽기를 차단하는 방법이됩니다. 내 poll 함수는 컨트롤 레지스터를 읽고 데이터가 이미 사용 가능한 경우 POLLIN|POLLRDNORM을 반환하고 그렇지 않으면 인터럽트를 해제하는 것으로 보입니다. 그리고 나서 인터럽트 처리기는 wake_up을 사용하여 wait_queue 플래그를 준비 상태로 만듭니다. read은 항상 인터럽트를 마스크합니다.

+0

저는이 흥미로운 프로젝트에 흥미가 있습니다. – whoplisp

답변

1

char 드라이버가 더 좋은 옵션이라고 생각합니다. 설명서가 더 많고 커널 부분이 더 간단하기 때문입니다. API는 잘 알려져 있으며 char 드라이버에 대한 경험이 많은 사람들을 찾을 수 있습니다. 작동 매치를 중지 기반의 차단과

시작 작은, 즉 읽기 : 데이터를 사용할 수없는

  • 경우, 다른
  • 에 잠이 사용자 공간에 사용할 수있는 데이터를 반환합니다.

인터럽트 루틴을 사용하면 데이터를 사용할 수있는 경우 결국 대기열을 깨울 수 있습니다.

일단 작동하면 폴링을 구현하십시오.

+0

이렇게하면 끝납니다. 'hexdump','dd','socat'으로 테스트 할 수 있다는 것은 netlink보다 char 드라이버에 큰 이점이었습니다. –

2

netlink가 최선의 선택이라고 생각합니다. BTW, 당신은 일반 소켓으로 netlink 소켓을 취급하고 POLL, EPOLL을 사용할 수 있습니다.

또한 'API가 불안정합니다'라는 것은 무엇을 의미합니까?Netlink는 많이 사용되며 꽤 괜찮은 API를 가지고 있습니다.

일반 netlink를 사용하면 메시지를 보내고받을 수 있습니다. 단방향 통신 (예 : kernel -> userspace)이 있으면 작업이 훨씬 쉬워집니다.

편집 : 액세스 할 수있는 경우 페이지를 참조하십시오. Wrox에 의한 Professional Linux Kernel Architecture 책 810 장 (12 장). 내가 아는 한, 유저 랜드와의 통신을 위해 netlink를 어떻게 사용할 수 있는지에 대한 (상대적으로) 좋은 설명이 있습니다.

netlink의 유일한 결점은 부족한 문서입니다. 그렇지 않으면 내 의견으로는 괜찮습니다.

+1

"API가 불안정합니다"라는 말은 예제를 찾을 때마다 다음 커널 버전에서 더 이상 작동하지 않는다는 점에 대해 아래 의견에 불만을 나타냅니다. 예 : http://www.linuxjournal.com/article/7356 필자는이 책을 읽는 데 오랫동안 사용 된 코드가 더 이상 작성된대로 작동하지 않는다고 생각합니다. –

1

문자 장치 옵션을 사용하면 사용자 공간의 read(2)이 드라이버의 read() 함수 (사용자가 장치를 등록한 struct file_operations에 지정됨)를 호출하게됩니다. 따라서 데이터 그램 경계를 유지하는지 여부와 다양한 실패 사례에서 어떤 오류를 반환할지 결정하는 것은 구현에 달려 있습니다.

관련 문제