Bagaimana cara kerja perangkat karakter atau file khusus karakter?

22

Saya mencoba memahami file karakter khusus. Dari wikipedia , saya mengerti bahwa file-file ini "menyediakan antarmuka" untuk perangkat yang mengirimkan data satu karakter pada satu waktu. Pemahaman saya adalah bahwa sistem entah bagaimana memanggil perangkat karakter daripada memanggil driver perangkat secara langsung. Tetapi bagaimana file menyediakan antarmuka ini? Apakah ini executable yang menerjemahkan system call? Dapatkah seseorang menjelaskan apa yang terjadi.

bernie2436
sumber

Jawaban:

19

Mereka sebenarnya hanya itu - antarmuka. Dienkodekan oleh nomor "utama" dan "kecil", mereka menyediakan pengait ke kernel.

Mereka datang dalam dua rasa (well, tiga, tetapi pipa bernama berada di luar cakupan penjelasan ini untuk saat ini): Perangkat Karakter dan Perangkat Blok.

Block Devices cenderung menjadi perangkat penyimpanan, mampu buffering output dan menyimpan data untuk pengambilan nanti.

Perangkat Karakter adalah hal-hal seperti kartu audio atau grafik, atau perangkat input seperti keyboard dan mouse.

Dalam setiap kasus, ketika kernel memuat driver yang benar (baik pada saat boot, atau melalui program seperti udev ) itu memindai berbagai bus untuk melihat apakah ada perangkat yang ditangani oleh driver yang benar-benar hadir pada sistem. Jika demikian, itu mengatur perangkat yang 'mendengarkan' pada nomor utama / minor yang sesuai.

(Misalnya, Digital Signal Processor dari kartu audio pertama yang ditemukan oleh sistem Anda mendapatkan pasangan angka mayor / minor 14/3; yang kedua mendapatkan 14,35, dll.)

Terserah udev untuk membuat entri /devbernama dspperangkat karakter bertanda 14 minor 3.

(Dalam versi Linux yang jauh lebih tua atau jejak minimum, /dev/mungkin tidak dimuat secara dinamis tetapi hanya berisi semua file perangkat yang mungkin secara statis.)

Kemudian, ketika program userspace mencoba mengakses file yang ditandai sebagai 'file karakter khusus' dengan nomor utama / minor yang sesuai (misalnya, pemutar audio Anda mencoba mengirim audio digital ke /dev/dsp), kernel tahu bahwa data ini perlu ditransmisikan melalui driver yang nomor mayor / minor dilampirkan; mungkin kata pengemudi tahu apa yang harus dilakukan dengan itu pada gilirannya.

Shadur
sumber
1
1. Jadi bilangan utama / minor dianalogikan dengan port?
bernie2436
2. Jadi ketika program mengakses file apa saja, kernel membaca antarmuka khusus ini untuk mengetahui apakah program tersebut mendapat gangguan dari perangkat tertentu? Mis: jika suatu program membuka file kata, ia membaca file karakter perangkat khusus untuk mengetahui program harus merespons input keyboard?
bernie2436
1) Agaknya . Ini analogi dengan pria miskin, tetapi itu akan berhasil.
Shadur
2
2) Anda kehilangan sekitar tiga atau empat lapisan abstraksi di sana. Program Anda membuka file teks dengan tidak tahu atau tidak peduli apa perangkat keyboard itu. Komunikasi dengan perangkat keras yang mendasarinya terjadi baik melalui emulator terminal (jika Anda berada dalam mode konsol) atau melalui lapisan peristiwa X (jika Anda berada dalam mode grafis), yang keduanya akan mendengarkan keyboard dan drive lain dan memutuskan apa , jika ada, untuk meneruskan ke program. Saya merangkum sistem multilayer yang cukup kompleks di sini; Anda sebaiknya membaca pada Sistem X Window secara umum.
Shadur
1
Perhatikan juga bahwa, pada beberapa rasa UN * X, ada file karakter khusus untuk perangkat penyimpanan; membaca atau menulis ke file khusus berubah menjadi membaca atau menulis ke urutan blok pada perangkat. (Dalam versi terbaru dari FreeBSD, mereka adalah hanya file khusus untuk perangkat penyimpanan, ada yang tidak ada blok file khusus.)
10

Setiap file, perangkat atau lainnya, mendukung 6 operasi dasar dalam VFS:

  1. Buka
  2. Dekat
  3. Baca baca
  4. Menulis
  5. Mencari
  6. Menceritakan

Selain itu, file perangkat mendukung Kontrol I / O, yang memungkinkan operasi lain-lain yang tidak dicakup oleh 6 yang pertama.

Dalam kasus karakter khusus, mencari dan memberi tahu tidak dilaksanakan karena mereka mendukung antarmuka streaming . Yaitu, membaca atau menulis secara langsung seperti yang dilakukan dengan pengalihan di shell:

echo 'foo' > /dev/some/char
sed ... < /dev/some/char
Ignacio Vazquez-Abrams
sumber
6

file_operationsContoh runnable minimal

Begitu Anda melihat contoh minimal, semuanya menjadi jelas.

Gagasan utamanya adalah:

  • file_operations berisi panggilan balik untuk setiap syscall terkait file
  • mknod <path> c <major> <minor> menciptakan perangkat karakter yang menggunakannya file_operations
  • untuk perangkat karakter yang secara dinamis mengalokasikan nomor perangkat (norma untuk menghindari konflik), cari nomornya cat /proc/devices

character_device.ko modul kernel:

#include <asm/uaccess.h> /* copy_from_user, copy_to_user */
#include <linux/errno.h> /* EFAULT */
#include <linux/fs.h> /* register_chrdev, unregister_chrdev */
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/printk.h> /* printk */
#include <uapi/linux/stat.h> /* S_IRUSR */

#define NAME "lkmc_character_device"

MODULE_LICENSE("GPL");

static int major;

static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
    size_t ret;
    char kbuf[] = {'a', 'b', 'c', 'd'};

    ret = 0;
    if (*off == 0) {
        if (copy_to_user(buf, kbuf, sizeof(kbuf))) {
            ret = -EFAULT;
        } else {
            ret = sizeof(kbuf);
            *off = 1;
        }
    }
    return ret;
}

static const struct file_operations fops = {
    .owner = THIS_MODULE,
    .read = read,
};

static int myinit(void)
{
    major = register_chrdev(0, NAME, &fops);
    return 0;
}

static void myexit(void)
{
    unregister_chrdev(major, NAME);
}

module_init(myinit)
module_exit(myexit)

Program pengujian Userland:

insmod /character_device.ko
dev="lkmc_character_device"
major="$(grep "$dev" /proc/devices | cut -d ' ' -f 1)"
mknod "/dev/$dev" c "$major" 0
cat /dev/lkmc_character_device
# => abcd
rm /dev/lkmc_character_device
rmmod character_device

GitHub QEMU + Buildroot hulu dengan boilerplate untuk menjalankannya:

Contoh yang lebih kompleks:

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber
Ini berkat super membantu! Hanya satu pertanyaan, apa sebenarnya yang dilakukan *off = 1;, dan mengapa itu diatur 1?
SilverSlash
1
@SilverSlash bahwa nilai akan diteruskan melalui beberapa readpanggilan ke open(deskriptor file yang sama . Pengemudi dapat melakukan apa pun yang diinginkannya. Semantik yang biasa, adalah memuat jumlah byte yang dibaca. Namun dalam contoh ini, kami hanya memiliki semantik yang lebih sederhana: 0untuk bacaan pertama, 1setelah bacaan pertama. Cobalah untuk menjalankannya dan letakkan langkah printk atau GDB untuk debug itu.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
4

"Karakter pada suatu waktu" adalah istilah yang keliru (seperti gagasan bahwa perangkat karakter tidak mendukung pencarian dan kirim). Faktanya, perangkat "block at a time" (yaitu berorientasi rekaman, seperti tape drive *) harus berupa perangkat karakter. Demikian juga gagasan bahwa perangkat karakter harus selalu tidak dapat dilihat - driver perangkat karakter menentukan file_operationsstruktur penuh yang bebas untuk menentukan llseek atau tidak sesuai dengan apakah perangkat mendukung operasi. Perangkat karakter yang oleh kebanyakan orang dianggap sebagai contoh adalah null, urandom, perangkat TTY, kartu suara, mouse, dll ... yang semuanya tidak dapat dicari karena spesifik dari perangkat tersebut, tetapi / dev / vcs, / dev / fb0 , dan / dev / kmem juga merupakan perangkat karakter dan semuanya dapat dicari.

Seperti yang saya sebutkan, driver perangkat karakter mendefinisikan struktur file_operations yang memiliki pointer fungsi untuk semua operasi seseorang mungkin ingin memanggil file - mencari, membaca, menulis, ioctl, dll - dan ini masing-masing dipanggil sekali ketika panggilan sistem yang sesuai dieksekusi dengan file perangkat ini terbuka. Dan karena itu baca dan tulis dapat melakukan apa pun yang diinginkannya dengan argumennya - ia dapat menolak untuk menerima tulisan yang terlalu besar atau hanya menulis yang cocok; itu hanya dapat membaca data yang sesuai dengan satu catatan daripada seluruh jumlah byte yang diminta.

Jadi, apa itu perangkat blok? Pada dasarnya, perangkat blok adalah disk drive. Tidak ada jenis perangkat lain (kecuali untuk drive disk virtual , seperti ramdisk dan loopback) adalah perangkat blok. Mereka diintegrasikan ke dalam sistem permintaan I / O, lapisan sistem file, sistem buffer / cache, dan sistem memori virtual dengan cara yang tidak dilakukan oleh perangkat karakter, bahkan ketika Anda sedang mengakses misalnya / dev / sda dari proses pengguna . Bahkan "perangkat mentah" yang disebutkan sebagai pengecualian adalah perangkat karakter .

* Beberapa sistem UNIX mengimplementasikan apa yang sekarang disebut "mode blok-tetap" - yang memungkinkan kelompok kernel dan memecah permintaan I / O agar sesuai dengan batas-batas blok yang dikonfigurasikan kurang lebih dengan cara yang sama seperti yang dilakukan untuk drive disk - sebagai blok alat. Perangkat karakter diperlukan untuk "mode blok-variabel", yang mempertahankan batas blok dari program pengguna sebagai panggilan tulis tunggal (2) menulis satu blok dan panggilan baca tunggal (2) mengembalikan satu blok. Karena mode switching diimplementasikan sekarang sebagai ioctl daripada file perangkat yang terpisah, perangkat karakter digunakan. Drive tape variabel-variabel sebagian besar "tidak dapat dicari" karena pencarian melibatkan penghitungan sejumlah catatan daripada sejumlah byte, dan operasi pencarian asli diimplementasikan sebagai ioctl.

Random832
sumber
1

Perangkat karakter dapat dibuat oleh modul kernel (atau kernel itu sendiri). Ketika sebuah perangkat dibuat, pembuatnya memberikan petunjuk ke fungsi-fungsi yang mengimplementasikan handle panggilan standar seperti open, read, dll. Kernel Linux kemudian mengaitkan fungsi-fungsi itu dengan perangkat karakter, jadi misalnya ketika aplikasi mode pengguna memanggil read () berfungsi pada file perangkat karakter, itu akan menghasilkan syscall dan kemudian kernel akan merutekan panggilan ini ke fungsi baca yang ditentukan saat membuat driver. Ada tutorial langkah demi langkah tentang cara membuat perangkat karakter di sini , Anda dapat membuat proyek sampel dan langkah melalui menggunakan debugger untuk memahami bagaimana objek perangkat dibuat dan ketika penangan dipanggil.

bazis
sumber