블록 디바이스 드라이버 예제

블록의 모든 읽기 및 쓰기는 전략 루틴을 통해 수행됩니다. 이 루틴은 인수를 수행하지 않고 아무 것도 반환하지 않지만 I/O에 대한 요청 목록을 찾을 위치를 알고 있습니다(기본적으로 blk_dev[MAJOR_NR_current_request로 정의됨)는 장치에서 블록을 가져오기 위한 방법을 알고 있습니다. 그것은 경주 조건을 피하기 위해 비활성화 인터럽트와 호출, 반환하기 전에 sti ()에 대한 호출로 인터럽트를 켜는 책임이 있습니다. 이제 요청을 구성하는 바이오 구조와 직접 작동하는 블록 드라이버를 작성할 수 있습니다. 그러나 예를 들어 도움이 될 수 있습니다. sbull 드라이버가 request_mode 매개 변수를 1로 설정하여 로드되면 위에서 본 간단한 함수 대신 바이오 인식 요청 함수를 등록합니다. 이 함수는 다음과 같습니다: 파일 시스템 코드는 각 일반 파일 블록에 대해 논리 장치 주소 또는 논리 블록 번호를 결정하고 블록 장치를 향한 buf(9S) 구조의 형태로 블록 I/O 요청을 작성합니다. 그런 다음 드라이버 전략(9E) 진입점은 buf(9S) 구조를 해석하고 요청을 완료합니다. 장치 섹터 크기에 대해 커널에 알리려면 blk_queue_logic_block_size() 함수를 사용하여 요청 큐가 할당된 직후에 요청 큐의 매개 변수를 설정해야 합니다. 커널에서 생성된 모든 요청은 이 섹터 크기의 배수이며 그에 따라 정렬됩니다. 그러나 장치와 드라이버 간의 통신은 여전히 512바이트 크기의 섹터에서 수행되므로 매번 변환을 수행해야 합니다(위의 코드에서 set_capacity() 함수를 호출할 때 이러한 변환의 예가 있습니다). 디스크 장치 이름으로 설정해야 하는 필드입니다.

/proc/파티션 및 sysfs에 표시됩니다. 어느 쪽이든 드라이버가 사용자 지정 make_request 함수를 사용하고 있음을 블록 하위 시스템에 알려야 합니다. 이렇게 하려면 요청 큐를 할당해야 합니다: 큐 잠금을 사용하면 요청 기능이 잠금을 보유하는 동안 커널이 장치에 대한 다른 요청을 대기하지 못하게 됩니다. 일부 조건에서는 요청 함수가 실행되는 동안 해당 잠금을 삭제하는 것이 좋습니다. 그러나 이렇게 하면 잠금이 유지되지 않는 동안 요청 큐 또는 잠금으로 보호되는 다른 데이터 구조에 액세스하지 않아야 합니다. 요청 함수가 반환되기 전에 잠금을 다시 획득해야 합니다. 문자 장치와 마찬가지로 구조체 file_operations의 작업을 완료해야 하므로 블록 장치의 경우 구조형 block_device_operations의 작업을 완료해야 합니다. 작업 연결은 구조체 젠디스크 구조의 fops 필드를 통해 수행됩니다.