가상 블록 디바이스 드라이버 구현

Jin Hur·2021년 8월 9일
0
post-custom-banner

reference: "리눅스 커널 내부구조" / 백승제, 최종무

설계: 메모리의 일부를 가상적인 디스크 디바이스 공간으로 사용.
간단한 가상 블록 디바이스 드라이버를 구현하여 이 공간에 쓰기와 데이터 읽기 연산 제공.

  1. 디바이스 드라이버의 이름과 주 번호를 결정한다.(주 번호의 동적 할당 사용)
  2. 디바이스 드라이버가 제공하는 인터페이스를 위한 함수 구현
  3. 인터페이스 함수들의 시작 주소는 file_operations 자료구조에 초기회
  4. 커널에 디바이스 드라이버 추가.
  5. /dev 디렉터리에 구현한 디바이스 드라이버를 접근할 수 있도록 장치파일 생성
  1. 8MB 크기의 가상적인 디스크 공간을 vmalloc 함수를 통해 할당받는다.
  2. 드라이브 초기화 함수(mydrv_init) 구현.
    2-1. register_blkdev()를 통해 드라이버 주 번호를 할당.
    2-2. alloc_disk() 함수를 이용하여 리눅스에 논리적인 디스크를 등록시키기 위한 gendisk 자료구조를 할당받음.
    2-3. blk_alloc_queue() 함수를 이용하여 커널과 통신하기 위한 큐 생성.
  3. 생성된 큐 처리 함수(mydrv_make_requeset) 구현.
    3-1. blk_queue_make_request() 함수를 호출, 리눅스와 통신하기 위한 블록 크기를 512B로 설정.
  4. add_disk() 함수를 아용하여 커널에 디바이스 드라이버 등록.

    블록 장치 파일에 readk, write 요청 발생 시 등록한 mydrv_make_request 함수 호출 => bio 구조체를 통해 현재 요청 유형 파악 => read, write에 걸맞게 할당된 공간에 복사 작업 수행.

my block device driver code

#include <linux/...h>           // 다양한 linux/ 헤더파일
#include <asm/uaccess.h>

#define DEVICE_NAME	        "mydrv"		// 디바이스 드라이버 이름
#define	MYDRV_MAX_LENGTH	(8*1024*1024)	// 커널 내 가상 디스크 공간 크기
#define MYDRV_BLK_SIZE	        512		// 블록의 크기 지정 
#define MYDRV_TOTAL_BLK	(MYDRV_MAX_LENGTH >> 9)	// 전체 블록 갯수(디스크 공간 크기 / 512)

static int MYDRV_MAJOR = 0;
static char * mydrv_data;
struct request_queue * mydrv_queue;
struct gendisk * mydrv_disk;

static void mydrv_make_request(struct requset_queue *q, struct bio *bio);
int mydrv_open(struct block_device *dev, fmode_t mode);
void mydrv_release(struct gendisk *gd, fmode_t mode);
int mydrv_ioctl(struct block_device *bdev, fmode_f mode, unsigned int cmd, unsigned long arg);

// block_device_operations 구조체 등록
static struct block_device_operations mydrv_fops ={
    .owner = THIS_MODULE,
    .open = mydrv_open,
    .release = mydrv_release,
    .ioctl = mydrv_ioctl,
};

int mydrv_init(void);	// 모듈 초기화 
void mydrv_exit(void); 	// 모듈 exit

module_init(mydrv_init);
module_exit(mydrv_exit);
MODULE_LICENSE("GPL");

블록 장치 디바이스 드라이버 적재
$ make
$ insmod blk_test.ko

해당 (가상)디스크를 관리하는 파일 시스템 구축
$ mkfs.ext4 /dev/mydrv

마운드
$ mkdir mnt
$ mount -t ext4 -o loop /dev/mydrv ./mnt
=> 이후 일반적인 하드디스크를 사용할 때처러 ls, vim, gcc, cat 등을 이용하여 mydrv 장치에 데이터를 읽고 쓸 수 있음.

post-custom-banner

0개의 댓글