상세 컨텐츠

본문 제목

버퍼동기화

청강컴정/시스템프로그래밍

by luckey 2009. 4. 30. 20:06

본문

디바이스 드라이버가 응용프로그램의 버퍼를 확인 했을 때 실제 버퍼를 볼 수 없는 일이 발생할 수 있다.
왜? 어플리케이션은 일단 명령을 던져두고 다시 응답이 있을때까지 기다리는 것이 아니라 다른 일을 하러 가야하기 때문에

시스템 버퍼 방식(METHOD_BUFFERED) : 시스템 버퍼에 사용자의 버퍼를 보관하고 사용자의 버퍼라고 간주하고 사용되는 방식
운영체제는 응용 프로그램이 제공하는 버퍼를 보호하기 위해서, 응용프로그램의 버퍼와 똑같은 크기의 버퍼를 새로 할당한다.
디바이스 드라이버는 이렇게 새로 할당된 시스템 버퍼를 사용한다. 이때 실제 응용프로그램버퍼와 시스템 버퍼간의 동기화 문제는 운영체제가 관여한다.

MDL 방식(METHOD_IN_DIRECT, METHOD_OUT_DIRECT) : 사용자 버퍼의 설명자를 작성해서 디바이스 드라이버에 전달한다.
사용자의 버퍼의 주소와 크기를 알 수 있다. 또한 원한다면 같은 메모리 처럼 보이게도 할 수 있다.(매핑방식)
MDL(Memory Descriptor List - 메모리를 설명하는 구조체) 이라는 자료 구조체를 사용하여 응용프로그램의 버퍼를 나름대로 표현한다.
MDL에는 StartVa(시작번지), Byteoffset(실제 시작번지까지의 크기), ByteCount(사용자버퍼의 크기)
사용자버퍼의 시작위치 = StartVa(시작번지) - Byteoffset(실제 시작번지까지의 크기) 로 알 수 있다.
MDL버퍼는 시스템버퍼의 NEXT를 이용해서 링크되어 관리되어 진다.



NEITHER방식 : 운영체제가 관여하지 않는다. 그렇기 때문에 해당 버퍼가 페이징 되어 있는지 반드시 확인해야 한다.

IRP -> AssociatedIrp.SystemBuffer : 하나의 시스템 버퍼(InputBuffer, OuputBuffer의 버퍼를 표현)

InputBuffer와 OutputBuffer 이 2개의 버퍼가 어떻게 하나의 버퍼 AssociatedIrp.SystemBuffer로 표현될 수 있을까??
일단 IO관리자는 2개의 사용자 버퍼중 가장 큰 크기를 가지는 버퍼와 동일한 크기의 시스템버퍼를 준비한다.

그런다음 InputBuffer에 담겨진 내용을 SystemBuffer에 복사한 후 드라이버를 호출한다.
그런다음 드라이버에서 넘어온 사용자에게 넘겨줄 내용을 SystemBuffer에 기록한다.
그러면 IO관리자는 응용프로그램측으로 되돌아가는 과정 중에 SystemBuffer에 들어 있는 내용을 OutputBuffer로 복사한다.

이와 같이 동시에 InputBuffer와 OutputBuffer를 사용할 수는 없지만 순서를 정해서 사용하는 방법을 이용하는 것이다.




관련글 더보기

댓글 영역