Saya pikir solusi paling sederhana adalah membuat perangkat karakter di driver kernel Anda, dengan operasi file Anda sendiri untuk file virtual. Kemudian userspace dapat membuka perangkat ini O_RDWR
. Anda harus mengimplementasikan dua operasi file utama:
-
read
-- beginilah cara kernel mengembalikan data ke ruang pengguna. Fungsi ini dijalankan dalam konteks thread userspace yang memanggilread()
panggilan sistem, dan dalam kasus Anda itu harus diblokir sampai kernel memiliki nilai benih lain yang perlu diketahui keluarannya. -
write
-- beginilah cara userspace meneruskan data ke dalam kernel. Dalam kasus Anda, kernel hanya akan menanggapi pembacaan sebelumnya dan meneruskannya ke perangkat keras.
Kemudian Anda berakhir dengan loop sederhana di ruang pengguna:
while (1) {
read(fd, buf, sizeof buf);
calculate_output(buf, output);
write(fd, output, sizeof output);
}
dan tidak ada loop sama sekali di kernel -- semuanya berjalan dalam konteks proses userspace yang menggerakkan berbagai hal, dan driver kernel hanya bertanggung jawab untuk memindahkan data ke/dari perangkat keras.
Bergantung pada apa "lakukan beberapa hal acak di sini" Anda di sisi kernel, mungkin tidak mungkin melakukannya dengan begitu sederhana. Jika Anda benar-benar membutuhkan loop kernel, Anda perlu membuat utas kernel untuk menjalankan loop itu, dan kemudian memiliki beberapa variabel di sepanjang baris input_data
, input_ready
, output_data
dan output_ready
, bersama dengan beberapa antrian tunggu dan penguncian apa pun yang Anda perlukan.
Saat utas kernel membaca data, Anda memasukkan data ke dalam input_ready
dan atur input_ready
tandai dan beri tanda antrian tunggu input, lalu lakukan wait_event(<output_ready is set>)
. read
operasi file akan melakukan wait_event(<input_ready is set>)
dan kembalikan data ke ruang pengguna saat sudah siap. Demikian pula write
operasi file akan menempatkan data yang diperolehnya dari ruang pengguna ke output_data
dan atur output_ready
dan beri sinyal antrian tunggu keluaran.
Cara lain (lebih jelek, kurang portabel) adalah dengan menggunakan sesuatu seperti ioperm
, iopl
atau /dev/port
untuk melakukan semuanya sepenuhnya di ruang pengguna, termasuk akses perangkat keras tingkat rendah.