Biri bana açıklayabilir mi
- Nedir
IOCTL
? - Ne için kullanılır?
- Nasıl kullanabilirim?
- Neden aynı işi yapan yeni işlevi tanımlayamıyorum
IOCTL
?
Biri bana açıklayabilir mi
IOCTL
?IOCTL
?Yanıtlar:
Bir ioctl
cihaza özel sistem çağrısı bir tür olan araçları "giriş-çıkış kontrol",. Linux'ta (300-400) yalnızca birkaç sistem çağrısı vardır ve bunlar aygıtların sahip olabileceği tüm benzersiz işlevleri ifade etmek için yeterli değildir. Böylece bir sürücü, bir kullanıcı alanı uygulamasının siparişleri göndermesine izin veren bir ioctl tanımlayabilir. Ancak, ioctl'ler çok esnek değildir ve biraz dağınık olma eğilimindedir (işe yarayan düzinelerce "sihirli sayı") ve ayrıca çekirdeğe bir arabellek geçirdiğinizde güvensiz olabilir - kötü kullanım bozulabilir şeyler kolayca.
Bir alternatif, sysfs
altında bir dosya /sys/
oluşturduğunuz ve sürücüden ve sürücüden bilgi almak için onu okuduğunuz / yazdığınız arabirimdir . Bunun nasıl kurulacağına dair bir örnek:
static ssize_t mydrvr_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", DRIVER_RELEASE);
}
static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);
Ve sürücü kurulumu sırasında:
device_create_file(dev, &dev_attr_version);
Daha sonra cihazınız için /sys/
, örneğin /sys/block/myblk/version
bir blok sürücüsü için bir dosyanız olur .
Daha ağır kullanım için başka bir yöntem, sürücünüzle BSD soket arabirimi üzerinden konuşmak için bir IPC (süreçler arası iletişim) yöntemi olan netlinktir. Bu, örneğin WiFi sürücüleri tarafından kullanılır. Daha sonra libnl
veya libnl3
kitaplıklarını kullanarak kullanıcı alanından onunla iletişim kurarsınız .
ioctl
Fonksiyon cihazda yapılandırmayı ayarlamak için bir aygıt sürücüsü uygulamak için yararlıdır. Örneğin, yazı tipi ailesini, yazı tipi boyutunu vb. kontrol etmek ve ayarlamak için yapılandırma seçeneklerine sahip bir yazıcı ioctl
, mevcut yazı tipini almak ve yazı tipini yenisine ayarlamak için kullanılabilir. Bir kullanıcı uygulaması, ioctl
yazıcıya geçerli yazı tipini döndürmesini veya yazı tipini yenisine ayarlamasını söyleyen bir kod göndermek için kullanır .
int ioctl(int fd, int request, ...)
fd
dosya tanımlayıcısıdır, döndüren open
;request
istek kodudur. örneğin GETFONT
yazıcıdan geçerli yazı tipini SETFONT
alacak, yazıcıdaki yazı tipini ayarlayacaktır;void *
. İkinci argümana bağlı olarak, üçüncü argüman mevcut olabilir veya olmayabilir, örneğin ikinci argüman ise SETFONT
, üçüncü argüman "Arial"
;int request
sadece bir makro değildir. Bir talep kodu oluşturmak için bir kullanıcı uygulaması ve cihaz üzerindeki hangi konfigürasyonun oynatılması gerektiğini belirlemek için cihaz sürücüsü modülü gereklidir. Uygulama, kullanarak istek kodunu gönderir ioctl
ve ardından hangi eylemin gerçekleştirileceğini belirlemek için aygıt sürücüsü modülündeki istek kodunu kullanır.
Bir istek kodunun 4 ana bölümü vardır
1. A Magic number - 8 bits
2. A sequence number - 8 bits
3. Argument type (typically 14 bits), if any.
4. Direction of data transfer (2 bits).
İstek kodu ise SETFONT
bir yazıcıda yazı tipini ayarlamaksa, veri aktarımının yönü kullanıcı uygulamasından aygıt sürücüsü modülüne olacaktır (Kullanıcı uygulaması yazı tipi adını "Arial"
yazıcıya gönderir ). Talep kodu ise GETFONT
, yön yazıcıdan kullanıcı uygulamasına doğrudur.
Bir istek kodu oluşturmak için, Linux önceden tanımlanmış bazı işlev benzeri makrolar sağlar.
1. _IO(MAGIC, SEQ_NO)
her ikisi de 8 bit, 0 - 255, örneğin yazıcıyı duraklatmak istediğimizi söyleyelim. Bu, veri aktarımı gerektirmez. Bu nedenle istek kodunu aşağıdaki gibi oluşturacağız
#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM)
ve artık kullanıma ioctl
kadar
ret_val = ioctl(fd, PAUSE_PRIN);
Sürücü modülündeki ilgili sistem çağrısı kodu alacak ve yazıcıyı duraklatacaktır.
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
ve SEQ_NO
yukarıdaki ile aynıdır ve TYPE
aşağıdaki tartışma tipini verir, üçüncü bağımsız değişken hatırlamak ioctl
olup void *
. W in __IOW
, veri akışının kullanıcı uygulamasından sürücü modülüne olduğunu gösterir. Örnek olarak, yazıcı yazı tipini olarak ayarlamak istediğimizi varsayalım "Arial"
.#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)
Daha ileri,
char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font);
Şimdi font
bir göstericidir, yani en iyi şekilde temsil edilen bir adres olduğu anlamına gelir unsigned long
, bu nedenle _IOW
türünden bahseden üçüncü bölümü bu şekilde. Ayrıca, bu yazı tipi adresi, aygıt sürücüsü modülünde uygulanan karşılık gelen sistem çağrısına iletilir unsigned long
ve kullanmadan önce uygun türe çevirmemiz gerekir. Çekirdek alanı kullanıcı alanına erişebilir ve dolayısıyla bu çalışır. diğer iki işlev benzeri makrolar __IOR(MAGIC, SEQ_NO, TYPE)
ve __IORW(MAGIC, SEQ_NO, TYPE)
veri akışının çekirdek alanından kullanıcı alanına ve sırasıyla her iki yönde olacağı yer.
Bunun yardımcı olup olmadığını lütfen bana bildirin!