panda.jpg 


안녕하세요 판다 이우영입니다.


저번시간에 보여 들였던 그림 기억 나시나요?

그림 하나로 문자, 블럭, 네트워크 디바이스 드라이버의 다른점을 알아보았습니다.

기억이 안나신다면 다시한번 확인하시고 오늘 내용 시작하겠 습니다.


블럭 디바이스 등록!



먼저 블록 디바이스 드라이버의 등록 방법 부터 알아 보겠습니다.


블록 디바이스 드라이버를 커널에 등록하는 함수는 register_blkdev() 입니다.

자세하게 알아볼까요?


int register_blkdev( unsigned int major, const char *name );


필요한 인자는 단 2개 입니다.


major는 블록 디바이스의 주번호 이고, name은 당연하게도 디바이스의 이름입니다.

이 함수가 하는 일은 주번호 xx번호의 yy이름을 갖는 블럭 디바이스가 있다는 것을 커널에게 알려주는 행위 입니다.


그럼 제거 하는 함수도 있어야 겠죠?


int unregister_blkdev( unsigned int major, const char *name );


사용 방법은 등록하는 것과 동일 합니다.


그럼 이렇게 커널에게 알려주는 것만으로 커널이 이 디바이스 드라이버를 이용 할까요? 아니죠 

문자디바이스 드라이버에서 했던것 처럼 오퍼레이션구조체를 등록해주어야 합니다.


다만 이 구조체가 문자 디바이스 드라이버에서 사용하던것과 다릅니다.


커널 2.6.29버전에서  /include/linux/blkdev.h 를 보시면 다음과 같은 구조체가 있습니다.


1080struct block_device_operations {
1081        int (*open) (struct block_device *, fmode_t);
1082        int (*release) (struct gendisk *, fmode_t);
1083        int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1084        int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1085        int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
1086        int (*direct_access) (struct block_device *, sector_t,
1087                                                void **, unsigned long *);
1088        int (*media_changed) (struct gendisk *);
1089        int (*revalidate_disk) (struct gendisk *);
1090        int (*getgeo)(struct block_device *, struct hd_geometry *);
1091        struct module *owner;
1092};


전에 사용하던 file_operations과는 차이점이 많이 보입니다.

대표적으로 read,write가 안보이내요. 그리고 생소한 것들이 많이 보입니다.


그럼 오늘은 요부분을 간단하게 알아보고 마무리 하도록 하겠습니다.


struct module *owner;

이 구조체의 소유자를 나타내기 위해 사용된다고 합니다. 일반적으로 THIS_MODULE을 입력해 줍니다.

int (*open) (struct block_device *, fmode_t);

이 함수는 해당 블록 디바이스가 마운트 되는 경우에 호출된다. 
여기서는 별다른것은 없고 이 이 블록 디바이스의 사용된 수를 증가시켜 줍니다.

int (*release) (struct gendisk *, fmode_t);

이 함수는 open과 반대로 언마운트 시 호출되어 블록 디바이스의 사용된 수를 감소 시킵니다.

int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);

문자 디바이스와 마찬가지 역활을 합니다. 
다만 블록 디바이스에서는 조금 정형화 되어 있다는 차이점이 있습니다.
read, write 도 여기서 하게 됩니다.
locked_ioctl, compat_ioctl 는 커널 2.6.11에서 추가되었는데요 최근에는 ioctl을 대신해서 사용하게 됩니다.
자세한 사항은 다음기회로 미루겠습니다.

int (*media_changed) (struct gendisk *);

이 함수는 주기적으로 호출되어 장치가 연결 되었는지 확인하게 됩니다.
대표적으로 cd-rom 같이 장치가 연결되었다 빠졌다하는 장치는 필수 적으로 작성해주어야 합니다.

int (*revalidate_disk) (struct gendisk *);

만약 media_changed에 의해서 블록 디바이스가 제거되는등 재설정 되었을 경우 
디바이스의 등록 상태를 정검을 위해 호출해 줍니다.


이중 중요한 것은 struct gendisk 입니다. 
이 구조체가 생김으로 조금더 편하게 블록 디바이스 드라이버를 작성할 수 있게 되었습니다.

이건 다음 기회에 설명하도록 하겠습니다.

그럼 오늘은 이만 마무리 하겠습니다.

그럼 다음 시간에 만나요~~