장치 드라이버 개발 공부 - 윈도우 8.1 운영체제용 장치 드라이버 및 커널 드라이버 개발 공부 - Whitmem
장치 드라이버 개발 공부 - 윈도우 8.1 운영체제용 장치 드라이버 및 커널 드라이버 개발 공부
장치 드라이버 개발 (초보)
2025-06-17 23:31 게시 29d99d38b44a2e9cbd16

0
0
10
이 페이지는 외부 공간에 무단 복제할 수 없으며 오직 있는 그대로 게시되며 부정확한 내용을 포함할 수 있습니다. 법률이 허용하는 한 가이드 라인에 맞춰 게시 내용을 인용하거나 출처로 표기할 수 있습니다.
This page is not to be distributed to external services; it is provided as is and may contain inaccuracies.
장치 드라이버는 보통 기기를 연결하면 커널단에서 동작되어 저수준 단계에서 어떤 작업을 수행하고 동작할 수 있도록 하는 소프트웨어이다. 일반 유저 공간에서 실행되는 프로그램이 아니기 때문에 C# 이나 Python 와 같은 고수준 언어로는 개발 할 수 없다.
이번에 나만의 가상 장치 드라이버를 만들어보고 싶어져서 윈도우 WDK 를 활용해 장치 드라이버 개발에 입문하였다.
하지만 정보를 위해서 작성하는 것은 아닌게, 필자도 아직 정확하지 않은 정보에 헷갈리는 내용이 많아 직접 시도해본 것들을 기록 삼아 올리기로 한다. 기록 카테고리에 올려야하지만, 카테고리가 지저분해져서 프로그래밍 카테고리에 하위로 종속하였다.
아무튼 장치 드라이버를 개발하기 위해서는 단순 개발 도구뿐만이 아니라 윈도우 SDK 및 Windows Driver Kit 를 다운로드 해서 설치해야 한다. 이 부분은 여기서는 생략한다. 설치하고 Visual Studio 설치 도구에서 장치 드라이버 관련된 옵션을 활성화하여 추가 기능을 설치해야 한다.
아무튼 위 작업들을 완료하면 Kernel Mode Driver, Empty 가 존재한다. WDM 드라이버는 많이 봤었는데, KMDF 는 생소하다. 찾아보니 WDM 이 매우 저수준, 이를 그나마 추상적으로 개발하기 쉽도록 만든 것이 Kernel Mode Driver 프로젝트라고 한다.
아무튼 위 템플릿으로 프로젝트를 하나 생성한다. 처음 Source Files 는 모두 비어있는데, 진입점 파일을 생성해야하는 것으로 보인다. 파일 명은 Driver.c 로 생성하면 된다고 드라이버 개발 튜토리얼 입문 사이트에 명시되어 있다. (튜토리얼이라기에는 진입점 짜는 것 밖에 코드가 없다...)
드라이버 파일은 cpp 가 아니라 c 파일이므로 Driver.c 로 생성하며 cpp 파일 및 헤더로 생성하지 않도록 유의한다.
그런다음 프로젝트 속성에 들어가서 VC++ 디렉터리 외부 인클루드를 추가해야 하는데, (또는 포함 디렉터리) 그 위치는 Windows Kits 의 최신 버전 내에 있는 km 디렉터리를 경로로 잡으면 된다.
필자의 경우는 C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\km 였다. 이게 찾아보니 WDK 를 설치한 SDK 에만 km 디렉터리가 있는 것으로 보인다. 아마 kernel 으로 시작하는 줄임말이 아닐까 싶다.
그러면 이제 Driver. c에 기본 헤더를 인클루드 해야하는데, 오류가 없으면 앞까지의 설정은 성공이라고 볼 수 있다.
기본적으로 보니 ntddk.h 는 필수고 wdf.h 는 선택적인 것 같은데, 정확한 용도는 아직 잘 모르겠다.
헤더가 잘못꼬이지 않도록 ntddk.h 먼저 그냥 다시 작성해주고, 드라이버의 진입점 함수를 만들어준다.
반환 형식은 NTSTATUS로 드라이버 객체 생성 성공 여부를 반환하면 되는 듯 싶다.
DriverObject 는 WDM 오브젝트에 관련된 것으로 시스템이 생성해서 넘겨준다. 시스템이 DriverObject를 생성해서 넘겨주면 우리가 여기에 여러 작업을 연결하고 콜백 기능을 추가해야하는 것으로 보인다. 콜백 기능은 포인터로 접근해서 MajorFunction에 각 콜백 함수를 등록해주면 되는 것으로 보이는데, 아직은 정확치 않다.
그리고 RegistryPath 는 시스템이 관련된 레지스트리 경로를 제공하는 것으로 보인다. 설치된 레지스트리 위치라고 보면되는 것 같다. 아무래도 키(레지스트리 디렉터리) 값인 것 같은데 이 위치안에서 세팅한 각 설정값을 드라이버에서 읽어들일 수 있는 것으로 보인다. 즉 설치과정에서 레지스트리에 다양한 설정 값을 쓰고 드라이버 엔트리에서 이 값을 읽여들여 어떠한 처리를 할 수 있는 것으로 보인다. 즉 위 함수는 시스템이 드라이버의 초기화가 필요한 시점 (윈도우 운영체제 부팅 등)시에 호출하는 것으로 시스템이 DriverObject와 RegistryPath 를 생성해서 넘겨준다. RegistryPath 는 PUNICODE 긴 하지만 아무튼 String 이므로 읽어들여서 레지스트리 처리를 하면 될 것으로 보이고, DriverObject 는 드라이버 객체를 포인터로 넘겨주는 것이니 이 위치 안에 어떤 값들을 실제 할당해서 마무리 지으면 되는 것으로 보인다.
그리고 그 성공 여부를 반환하면 되는 것 같은데, 여기서는 테스트로 STATUS_UNSUCCESSFUL 을 반환하였다.
근데 여기서 무작정 컴파일을 하려고 하니 오류가 발생하는데, 경고가 오류로 뜨도록 설정이 되어 있다. 여기서 지금 RegistryPath 와 DriverObject 를 하나도 사용하지 않아서 그 경고가 뜨는데, 이 것이 기본 오류 발생으로 설정되어 있다.
따라서 사용한 것 처럼 만들어주는 매크로 함수인 UNREFERENCED_PARAMETER 을 사용하여 해당 변수들을 기입한다.
그러면 위 처럼 빌드가 되는 것을 볼 수 있다.
위 처럼 빌드가 되면 cer, inf, pdb, sys 가 생성되는데, sys가 실질적인 드라이버 파일이고, inf 는 설치 파일 (흔히 드라이버를 수동으로 설치해봤다면 inf 파일을 많이 봤을 것이다.) 이외 인증서 파일인 cer 파일이 존재한다. 드라이버 프로그램은 아무래도 민감한 소프트웨어이다 보니, 인증서 없이는 절대 설치할 수 없도록 기본 설정되어 있다. 즉 일반 사용자 컴퓨터에서는 인증서가 없으면 (그것도 공인 인증된 인증서여야 한다.)배포할 수 없으며 설치가 거부된다. 여기서는 테스트로 생성하는 것이기 때문에 테스트 인증서를 서명하거나, 또는 윈도우 운영체제 부팅 과정에서 드라이버 서명을 비활성화함으로써 강제 설치를 수행할 수 있는 것으로 보인다. (윈도우 운영체제 8.1 넘어와서 안전하지 않는 드라이버 설치가 강제적으로 차단되는 것 같다. XP 운영체제 시절에는 쉽게 제 3자 드라이버를 설치한 기억이 있다.)
그런데 나는 윈도우 8.1 운영체제에서 빌드를 해야하기에 8.1 SDK 와 WDK 를 내려받고 설치하고 2시간 삽질을 했는데, 결과적으로 10 WDK 에서 오류를 무시해주면 빌드가 되는 것을 확인했다... 물론 오류를 띄우는 게 기본 값이라면 불안정하다든지 비권장하는 이유가 있겠지만 여기서는 공부가 목적이기 때문에 윈도우 8.1 운영체제에서 빌드하기로 결정한다.
이런 지원되지 않는 다는 메시지들이 뜨면 더블클릭해서
위 오류 필터 부분들을 주석해주면 된다. 물론 Universal 모드에 대해서 윈도우 8.1 운영체제 드라이버로 빌드가 가능한지는 확인하지 않았기 때문에 프로젝트 솔루션 속성에 들어가서 드라이버 옵션에 타겟 드라이버를 Universal 외 Desktop , Windows Driver 등으로 바꿔가며 시도했다.
이런식으로 바꾸는 작업을 몇 번 반복하니 문제가 해결됐다.
물론 저 오류 무시 작업은 실제 프로덕션 (테스트 환경에서도 본인 컴이 아닌 가상 컴으로..)에서는 절대 하면 안될 것으로 보인다...
아무튼 윈도우 8.1 운영체제 버전으로 드라이버가 빌드 되었고,
이렇게 윈도우 8.1 운영체제가 실행 중인 가상 컴퓨터에 들고왔다. 다만, 막상 설치하려고 inf 에 우클릭 후 설치를 누르니 인증 서명이 되어있지 않다고 실패하는데, 윈도우 8.1 운영체제 복구 모드로 들어가서 드라이버 서명 사용 안함 모드로 부팅해야 한다.
안전 모드 부팅 과정에서 1번부터 약 10번대까지 다양한 옵션으로 부팅이 가능한데, 7 번 드라이버 서명 적용 사용 안함 모드로 부팅하고 드라이버를 설치하면 아래와 같이 경고 메시지가 뜨는 것을 확인할 수 있다.
이 드라이버 소프트웨어를 설치합니다. 를 눌러 설치를 하면 완료되는 것을 볼 수 있다.
다만 인터넷 자료를 확인해보니 이렇게 설치하는 건 의미가 없다고 한다. INF 를 devcon 소프트웨어와 함께 Root\가상드라이버 객체에 같이 연결해서 설치해야 장치 관리자에서 잡힌다고 한다.
아직 디버그 메시지를 출력하는 방법도 모르고 테스트를 하는 방법도 모르기 때문에 이 부분은 차차 공부해서 기록하려고 한다.
댓글 0개
댓글을 작성하는 경우 댓글 처리 방침에 동의하는 것으로 간주됩니다. 댓글을 작성하면 일회용 인증키가 발급되며, 해당 키를 분실하는 경우 댓글을 제거할 수 없습니다. 댓글을 작성하면 사용자 IP가 영구적으로 기록 및 부분 공개됩니다.
확인
Whitmemit 개인 일지 블로그는 개인이 운영하는 정보 공유 공간으로 사용자의 민감한 개인 정보를 직접 요구하거나 요청하지 않습니다. 기본적인 사이트 방문시 처리되는 처리 정보에 대해서는 '사이트 처리 방침'을 참고하십시오. 추가적인 기능의 제공을 위하여 쿠키 정보를 사용하고 있습니다. Whitmemit 에서 처리하는 정보는 식별 용도로 사용되며 기타 글꼴 및 폰트 라이브러리에서 쿠키 정보를 사용할 수 있습니다.
이 자료는 모두 필수 자료로 간주되며, 사이트 이용을 하거나, 탐색하는 경우 동의로 간주합니다.