Bagian ini akan membahas bagaimana teknik dan struktur antarmuka yang memungkinkan I/O diperlakukan secara seragam. Salah satu contohnya adalah ketika suatu aplikasi ingin membuka data yang ada dalam suatu disk tanpa mengetahui jenis disk apa yang akan diaksesnya. Untuk mempermudah pengaksesan, sistem operasi melakukan standarisasi pengaksesan pada perangkat I/O. Pendekatan inilah yang dinamakan aplikasi antarmuka I/O.
Seperti layaknya permasalahan dari software-engineering yang rumit lainnya, aplikasi antarmuka I/O melibatkan abstraksi, enkapsulasi, dan software layering. Abstraksi dilakukan dengan membagi-bagi detail perangkat-perangkat I/O ke dalam kelas-kelas yang lebih umum. Dengan adanya kelas-kelas yang umum ini, maka akan lebih mudah bagi fungsi-fungsi standar ( antarmuka) untuk mengaksesnya. Selanjutnya, keberadaan device driver pada masing-masing peralatan I/O akan berfungsi meng-enkapsulasi perbedaan-perbedaan yang ada dari setiap anggota kelas-kelas yang umum tadi.
Tujuan dari adanya lapisan device driver ini adalah untuk menyembunyikan perbedaan-perbedaan yang ada pada pengendali perangkat dari subsistem I/O yang terdapat dalam kernel. Dengan demikian, subsistem I/O dapat bersifat mandiri dari perangkat keras. Hal ini sangat menguntungkan dari segi pengembangan perangkat keras, karena tidak perlu menunggu vendor sistem operasi untuk mengeluarkan support code untuk perangkat-perangkat keras baru yang akan dikeluarkan oleh para vendor perangkat keras tersebut.
Spooling adalah proses yang sangat berguna saat berurusan dengan perangkat I/O dalam sistem multiprogram. Sebuah spool adalah sebuah buffer yang menyimpan keluaran untuk sebuah perangkat yang tidak dapat menerima interleaved data streams. Salah satu perangkat spool yang paling umum adalah printer.
Printer hanya dapat melayani satu pekerjaan pada waktu tertentu, namun beberapa aplikasi dapat meminta printer untuk mencetak. Spooling memungkinkan keluaran mereka tercetak satu per satu, tidak tercampur. Untuk mencetak sebuah berkas, pertama-tama sebuah proses mengeneralisasi berkas secara keseluruhan untuk di cetak dan ditempatkan pada spooling directory. Sistem operasi akan menyelesaikan masalah ini dengan meng-intercept semua keluaran kepada printer. Tiap keluaran aplikasi sudah di-spooled ke disk berkas yang berbeda. Ketika sebuah aplikasi selesai mencetak, sistem spooling akan melanjutkan ke antrian berikutnya.
Di dalam beberapa sistem operasi, spooling ditangani oleh sebuah sistem proses daemon. Pada sistem operasi yang lain, sistem ini ditangani oleh in-kernel thread. Pada kedua penanganan tersebut, sistem operasi menyediakan antarmuka kontrol yang membuat users and sistem administrator dapat menampilkan antrian tersebut, untuk mengenyahkan antrian-antrian yang tidak diinginkan sebelum mulai dicetak.
Contoh lain adalah penggunaan spooling pada transfer berkas melalui jaringan yang biasanya menggunakan daemon jaringan. Untuk mengirim berkas ke suatu tempat, user menempatkan berkas tersebut dalam spooling directory jaringan. Selanjutnya, daemon jaringan akan mengambilnya dan mentransmisikannya. Salah satu bentuk nyata penggunaan spooling jaringan adalah sistim email via Internet. Keseluruhan sistem untuk mail ini berlangsung di luar sistem operasi.
Beberapa perangkat, seperti drive tape dan printer, tidak dapat me-multiplex permintaan I/O dari beberapa aplikasi. Selain dengan spooling, dapat juga diatasi dengan cara lain, yaitu dengan membagi koordinasi untuk multiple concurrent ini. Beberapa sistem operasi menyediakan dukungan untuk akses perangkat secara eksklusif, dengan mengalokasikan proses ke device idle dan membuang perangkat yang sudah tidak diperlukan lagi. Sistem operasi lainnya memaksakan limit suatu berkas untuk menangani perangkat ini. Banyak sistem operasi menyediakan fungsi yang membuat proses untuk menangani koordinat exclusive akses diantara mereka sendiri.
Sebuah sistem operasi yang menggunakan protected memory dapat menjaga banyak kemungkinan error akibat perangkat keras mau pun aplikasi. Perangkat dan transfer I/O dapat gagal dalam banyak cara, bisa karena alasan transient, seperti overloaded pada jaringan, maupun alasan permanen yang seperti kerusakan yang terjadi pada disk controller. Sistem operasi seringkali dapat mengkompensasikan untuk kesalahan transient. Seperti, sebuah kesalahan baca pada disk akan mengakibatkan pembacaan ulang kembali dan sebuah kesalahan pengiriman pada jaringan akan mengakibatkan pengiriman ulang apabila protokolnya diketahui. Akan tetapi untuk kesalahan permanen, sistem operasi pada umumnya tidak akan bisa mengembalikan situasi seperti semula.
Sebuah ketentuan umum, yaitu sebuah sistem I/O akan mengembalikan satu bit informasi tentang status panggilan tersebut, yang akan menandakan apakah proses tersebut berhasil atau gagal. Sistem operasi pada UNIX menggunakan integer tambahan yang dinamakan ERRNO untuk mengembalikan kode kesalahan sekitar 1 dari 100 nilai yang mengindikasikan sebab dari kesalahan tersebut. Sebaliknya, beberapa perangkat keras dapat menyediakan informasi kesalahan yang detail, walau pun banyak sistem operasi yang tidak mendukung fasilitas ini.
Sebagai contoh, kesalahan pada perangkat SCSI dilaporkan oleh protokol SCSI dalam bentuk sense key yang mengindentifikasi kesalahan yang umum seperti error pada perangkat keras atau permintaan yang ilegal; sebuah additional sense code yang mengkategorikan kesalahan yang muncul, seperti kesalahan parameter atau kesalahan self-test; dan sebuah additional sense code qualifier yang memberitahukan kesalahan secara lebih mendalam dan mendetil, seperti parameter yang error.
Kernel membutuhkan informasi keadaan tentang penggunakan komponen I/O. Kernel menggunakan banyak struktur yang mirip untuk melacak koneksi jaringan, komunikasi perangkat karakter, dan aktivitas I/O lainnya.
UNIX menyediakan akses sistem berkas untuk beberapa entiti, seperti berkas pengguna, raw devices, dan alamat tempat proses. Walau pun tiap entiti ini didukung sebuah operasi baca, semantiksnya berbeda untuk tiap entiti. Seperti untuk membaca berkas pengguna, kernel perlu memeriksa buffer cache sebelum memutuskan apakah akan melaksanakan I/O disk. Untuk membaca sebuah raw disk, kernel perlu untuk memastikan bahwa ukuran permintaan adalah kelipatan dari ukuran sektor disk, dan masih terdapat di dalam batas sektor. Untuk memproses citra, cukup perlu untuk mengkopi data ke dalam memori. UNIX mengkapsulasikan perbedaan-perbedaan ini di dalam struktur yang seragam dengan menggunakan teknik object oriented.
Beberapa sistem operasi bahkan menggunakan metode object oriented secara lebih ekstensif. Sebagai contoh, Windows NT menggunakan implementasi message-passing untuk I/O. Sebuah permintaan I/O akan dikonversikan ke sebuah pesan yang dikirim melalui kernel kepada I/O manager dan kemudian ke device driver, yang masing-masing bisa mengubah isi pesan. Untuk output, isi message adalah data yang akan ditulis. Untuk input, message berisikan buffer untuk menerima data. Pendekatan message-passing ini dapat menambah overhead, dengan perbandingan dengan teknik prosedural yang membagi struktur data, tetapi akan mennyederhanakan struktur dan design dari sistem I/O tersebut dan menambah fleksibilitas.
Kesimpulannya, subsistem I/O mengkoordinasi kumpulan-kumpulan service yang banyak sekali, yang tersedia dari aplikasi maupun bagian lain dari kernel. Subsistem I/O mengawasi:
1. Manajemen nama untuk berkas dan perangkat.
2. Kontrol akses untuk berkas dan perangkat.
3. Kontrol operasi, contoh: model yang tidak dapat dikenali.
4. Alokasi tempat sistem berkas.
5. Alokasi perangkat.
6. Buffering, caching, spooling.
7. Penjadwalan I/O
8. Mengawasi status perangkat, error handling, dan kesalahan dalam recovery.
9. Konfigurasi dan utilisasi driver device.
Di bagian sebelumnya, kita mendeskripsikan handshaking antara device driver dan pengendali perangkat, tapi kita tidak menjelaskan bagaimana Sistem Operasi menyambungkan permintaan aplikasi untuk menyiapkan jaringan menuju sektor disk yang spesifik.
Sistem Operasi yang modern mendapatkan fleksibilitas yang signifikan dari tahapan-tahapan tabel lookup di jalur diantara permintaan dan pengendali perangkat physical. Kita dapat mengenalkan perangkat dan driver baru ke komputer tanpa harus meng-compile ulang kernelnya. Sebagai fakta, ada beberapa sistem operasi yang mampu untuk me- load device drivers yang diinginkan. Pada waktu boot, sistem mula-mula meminta bus perangkat keras untuk menentukan perangkat apa yang ada, kemudian sistem me- load ke dalam driver yang sesuai; baik sesegera mungkin, mau pun ketika diperlukan oleh sebuah permintaan I/O.
Sistem V UNIX mempunyai mekanisme yang menarik, yang disebut streams, yang membolehkan aplikasi untuk men- assemble pipeline dari kode driver secara dinamis. Sebuah stream adalah sebuah koneksi full duplex antara sebuah device driver dan sebuah proses user-level. Stream terdiri atas sebuah stream head yang merupakan antarmuka dengan user process, sebuah driver end yang mengontrol perangkat, dan nol atau lebih stream modules di antara mereka. Modules dapat didorong ke stream untuk menambah fungsionalitas di sebuah layered fashion. Sebagai gambaran sederhana, sebuah proses dapat membuka sebuah alat port serial melalui sebuah stream, dan dapat mendorong ke sebuah modul untuk memegang edit input. Stream dapat digunakan untuk interproses dan komunikasi jaringan. Faktanya, di Sistem V, mekanisme soket diimplementasikan dengan stream.
Berikut dideskripsikan sebuah lifecycle yang tipikal dari sebuah permintaan pembacaan blok:
1. Sebuah proses mengeluarkan sebuah blocking read system call ke sebuah berkas deskriptor dari berkas yang telah dibuka sebelumnya.
2. Kode system-call di kernel mengecek parameter untuk kebenaran. Dalam kasus input, jika data telah siap di buffer cache, data akan dikembalikan ke proses dan permintaan I/O diselesaikan.
3. Jika data tidak berada dalam buffer cache, sebuah physical I/O akan bekerja, sehingga proses akan dikeluarkan dari antrian jalan ( run queue) dan diletakkan di antrian tunggu ( wait queue) untuk alat, dan permintaan I/O pun dijadwalkan. Pada akhirnya, subsistem I/O mengirimkan permintaan ke device driver. Bergantung pada sistem operasi, permintaan dikirimkan melalui call subrutin atau melalui pesan in-kernel.
4. Device driver mengalokasikan ruang buffer pada kernel untuk menerima data, dan menjadwalkan I/O. Pada akhirnya, driver mengirim perintah ke pengendali perangkat dengan menulis ke register device control.
5. Pengendali perangkat mengoperasikan perangkat keras perangkat untuk melakukan transfer data.
6. Driver dapat menerima status dan data, atau dapat menyiapkan transfer DMA ke memori kernel. Kita mengasumsikan bahwa transfer diatur oleh sebuah DMA controller, yang menggunakan interupsi ketika transfer selesai.
7. Interrupt handler yang sesuai menerima interupsi melalui tabel vektor-interupsi, menyimpan sejumlah data yang dibutuhkan, menandai device driver, dan kembali dari interupsi.
8. Device driver menerima tanda, menganalisa permintaan I/O mana yang telah diselesaikan, menganalisa status permintaan, dan menandai subsistem I/O kernel yang permintaannya telah terselesaikan.
9. Kernel mentransfer data atau mengembalikan kode ke ruang alamat dari proses permintaan, dan memindahkan proses dari antrian tunggu kembali ke antrian siap.
Proses tidak diblok ketika dipindahkan ke antrian siap. Ketika penjadwal ( scheduler) mengembalikan proses ke CPU, proses meneruskan eksekusi pada penyelesaian dari system call