Jawaban:
An ioctl
, yang berarti "kontrol input-output" adalah sejenis panggilan sistem khusus perangkat. Hanya ada beberapa panggilan sistem di Linux (300-400), yang tidak cukup untuk mengekspresikan semua fungsi unik yang mungkin dimiliki perangkat. Jadi driver dapat mendefinisikan ioctl yang memungkinkan aplikasi userspace mengirim pesanan. Namun, ioctl tidak terlalu fleksibel dan cenderung menjadi sedikit berantakan (lusinan "angka ajaib" yang hanya berfungsi ... atau tidak), dan juga tidak aman, saat Anda mengirimkan buffer ke kernel - penanganan yang buruk dapat merusak hal-hal dengan mudah.
Alternatifnya adalah sysfs
antarmuka, tempat Anda mengatur file di bawah /sys/
dan membaca / menulis itu untuk mendapatkan informasi dari dan ke driver. Contoh cara mengatur ini:
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);
Dan selama pengaturan driver:
device_create_file(dev, &dev_attr_version);
Anda kemudian akan memiliki file untuk perangkat Anda /sys/
, misalnya, /sys/block/myblk/version
untuk driver blokir.
Metode lain untuk penggunaan yang lebih berat adalah netlink, yang merupakan metode IPC (komunikasi antar proses) untuk berbicara dengan driver Anda melalui antarmuka soket BSD. Ini digunakan, misalnya, oleh driver WiFi. Anda kemudian berkomunikasi dengannya dari userspace menggunakan libnl
atau libnl3
perpustakaan.
The ioctl
Fungsi ini berguna untuk menerapkan driver perangkat untuk mengatur konfigurasi pada perangkat. mis. printer yang memiliki opsi konfigurasi untuk memeriksa dan mengatur kelompok font, ukuran font, dll. ioctl
dapat digunakan untuk mendapatkan font yang sekarang serta mengatur font ke font yang baru. Aplikasi pengguna digunakan ioctl
untuk mengirim kode ke printer yang memberitahukannya untuk mengembalikan font saat ini atau untuk mengatur font ke yang baru.
int ioctl(int fd, int request, ...)
fd
adalah file descriptor, yang dikembalikan oleh open
;request
adalah kode permintaan. mis. GETFONT
akan mendapatkan font saat ini dari printer, SETFONT
akan mengatur font pada printer;void *
. Bergantung pada argumen kedua, argumen ketiga mungkin ada atau tidak ada, misalnya jika argumen kedua adalah SETFONT
, argumen ketiga dapat berupa nama font seperti "Arial"
;int request
bukan hanya makro. Aplikasi pengguna diperlukan untuk membuat kode permintaan dan modul driver perangkat untuk menentukan konfigurasi mana pada perangkat yang harus dimainkan. Aplikasi mengirimkan kode permintaan menggunakan ioctl
dan kemudian menggunakan kode permintaan dalam modul driver perangkat untuk menentukan tindakan yang harus dilakukan.
Kode permintaan memiliki 4 bagian utama
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).
Jika kode permintaan adalah SETFONT
mengatur font pada printer, arah untuk transfer data akan dari aplikasi pengguna ke modul driver perangkat (Aplikasi pengguna mengirimkan nama font "Arial"
ke printer). Jika kode permintaannya GETFONT
, arahnya dari printer ke aplikasi pengguna.
Untuk menghasilkan kode permintaan, Linux menyediakan beberapa makro seperti fungsi yang telah ditentukan.
1. _IO(MAGIC, SEQ_NO)
keduanya 8 bit, 0 hingga 255, mis. Katakanlah kami ingin menjeda printer. Ini tidak memerlukan transfer data. Jadi kami akan menghasilkan kode permintaan seperti di bawah ini
#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM)
dan sekarang gunakan ioctl
sebagai
ret_val = ioctl(fd, PAUSE_PRIN);
Panggilan sistem yang sesuai dalam modul driver akan menerima kode dan menjeda printer.
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
dan SEQ_NO
sama seperti di atas, dan TYPE
memberikan jenis argumen berikutnya, ingat argumen ketiga ioctl
adalah void *
. W in __IOW
menunjukkan bahwa aliran data dari aplikasi pengguna ke modul driver. Sebagai contoh, misalkan kita ingin mengatur font printer "Arial"
.#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)
lebih lanjut,
char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font);
Sekarang font
adalah sebuah pointer, yang berarti itu adalah alamat yang direpresentasikan dengan sebaik-baiknya unsigned long
, maka bagian ketiga dari _IOW
tipe tersebut disebut demikian. Juga, alamat font ini diteruskan ke panggilan sistem yang sesuai yang diimplementasikan dalam modul driver perangkat unsigned long
dan kita perlu mengubahnya ke jenis yang tepat sebelum menggunakannya. Ruang kernel dapat mengakses ruang pengguna dan karenanya ini berfungsi. dua makro seperti fungsi lainnya adalah __IOR(MAGIC, SEQ_NO, TYPE)
dan di __IORW(MAGIC, SEQ_NO, TYPE)
mana aliran data akan dari ruang kernel ke ruang pengguna dan keduanya secara berurutan.
Tolong beri tahu saya jika ini membantu!