2014-04-24 21 views
7

Tôi đã viết một chương trình điều khiển khối tạo ra một thiết bị khối giả (sbd0). Tôi đã đăng ký tất cả các hoạt động thiết bị cho thiết bị khối đó: (Tham khảo include/linux/blkdev.h trong nguồn hạt nhân 2.6.32)Tại sao hạt nhân sử dụng trình điều khiển khối mặc định thay vì mã trình điều khiển của tôi?

static struct block_device_operations sbd_ops = { 
    .owner   = THIS_MODULE, 
    .open   = sbd_open, 
    .release   = sbd_close, 
    .ioctl   = sbd_ioctl, 
    .getgeo   = sbd_getgeo, 
    .locked_ioctl = sbd_locked_ioctl, 
    .compat_ioctl = sbd_compat_ioctl, 
    .direct_access = sbd_direct_access, 
    .media_changed = sbd_media_changed, 
    .revalidate_disk = sbd_revalidate_disk 
}; 

Tôi đã biên soạn chương trình điều khiển. Tôi đã chèn mô-đun và /dev/sbd0 đã được tạo. Bây giờ tôi muốn kiểm tra mã trình điều khiển của tôi. Vì vậy, tôi đã viết một ứng dụng như sau.

fd = open("/dev/sbd0", O_RDONLY); 
retval = ioctl(fd, BLKBSZGET, &blksz); //trying to get logical block size 

Output là: 4096

tôi tự hỏi: Tôi đã không thực hiện ioctl cho BLKBSZGET. Nó không gọi sbd_ioctl của tôi, thay vào đó nó sử dụng trình điều khiển mặc định và cho tôi kết quả. Đối với open, close, cuộc gọi được thực hiện sbd_opensbd_close (mà tôi đã triển khai). Và sau đó tôi đã thử:

retval = ioctl(fd, HDIO_GETGEO, &geoinfo); 

Nó gọi sbd_getgeo nhưng tôi nghĩ nó sẽ gọi sbd_ioctl.

Dưới đây là những câu hỏi của tôi:

  1. tôi thực hiện một trình điều khiển và tạo ra một thiết bị. Nếu tôi thực hiện bất kỳ thao tác nào trên thiết bị đó, nó phải gọi ứng dụng trình điều khiển của tôi. Nhưng làm thế nào nó sử dụng một vài chức năng điều khiển của tôi và vài chức năng điều khiển mặc định?
  2. ioctl(fd, HDIO_GETGEO, ..) không gọi số .ioctl cuộc gọi, nhưng được gọi .getgeo. Sao có thể như thế được?

Trả lời

6

Chức năng ioctl sẽ xử lý trực tiếp một số ioctls, mà không cần gọi đến thói quen cụ thể của người lái xe.

Đối HDIO_GETGEO, nó gọi chức năng lái xe của bạn getgeo trực tiếp (từ kernel 3.13.6, không xuất hiện như đã thay đổi nhiều kể từ 2.6.32):

[...] 
/* 
* We need to set the startsect first, the driver may 
* want to override it. 
*/ 
memset(&geo, 0, sizeof(geo)); 
geo.start = get_start_sect(bdev); 
ret = disk->fops->getgeo(bdev, &geo); /* <- here */ 
[...] 

Đối BLKBSZGET, nó gọi block_size(bdev)), mà chỉ cần trả về bdev->bd_block_size.

Bạn sẽ tìm thấy blkdev_ioctl trong block/ioctl.c nếu bạn cần biết điều gì xảy ra cho các ioctls khác.

+0

ý bạn là, 'ioctl' đầu tiên được xử lý bởi 'blkdev_ioctl'. Vì vậy, trực tiếp vài thao tác 'ioctl' được xử lý bởi' blkdev_ioctl' và còn lại sẽ được xử lý bởi các chức năng điều khiển của tôi? – SGG

+0

Vâng, đó là chính xác. – Mat

+0

Tôi đã thấy định nghĩa của 'blkdev_ioctl'. thực sự tốt và rất rõ ràng. Bây giờ tôi muốn xem làm thế nào 'ioctl' gọi' blkdev_ioctl'. Tôi muốn xem tập tin nguồn. Trong đó tôi có được cái này? – SGG

Các vấn đề liên quan