Apa yang dimaksud dengan "panggilan sistem" jika bukan implementasi dalam bahasa pemrograman?

14

Saya ingin memahami istilah "system call". Saya tahu bahwa panggilan sistem digunakan untuk mendapatkan layanan kernel dari aplikasi userspace.

Bagian yang saya perlu klarifikasi adalah perbedaan antara "panggilan sistem" dan "implementasi C dari panggilan sistem".

Berikut adalah kutipan yang membingungkan saya:

Pada sistem mirip Unix, API itu biasanya merupakan bagian dari implementasi pustaka C (libc), seperti glibc, yang menyediakan fungsi wrapper untuk pemanggilan sistem, seringkali dinamai sama dengan pemanggilan sistem yang mereka panggil

Apa "panggilan sistem yang mereka panggil"? Di mana sumber mereka? Bisakah saya memasukkannya langsung ke dalam kode saya?

Apakah "system call" dalam arti umum hanya antarmuka yang didefinisikan POSIX tetapi untuk benar-benar melihat implementasinya orang dapat memeriksa sumber C dan di dalamnya melihat bagaimana sebenarnya userspace to kernel communication berjalan?

Catatan latar belakang: Saya mencoba memahami jika, pada akhirnya, setiap fungsi c akhirnya berinteraksi dengan perangkat /dev.

TheMeaningfulEngineer
sumber

Jawaban:

21

Panggilan sistem per se adalah sebuah konsep. Mereka mewakili tindakan yang proses dapat meminta kernel untuk melakukan.

Panggilan sistem tersebut diimplementasikan dalam kernel sistem mirip UNIX. Implementasi ini (ditulis dalam C, dan dalam asm untuk bagian-bagian kecil) sebenarnya melakukan tindakan dalam sistem.

Kemudian, proses menggunakan antarmuka untuk meminta eksekusi sistem dari panggilan sistem. Antarmuka ini ditentukan oleh POSIX. Ini adalah seperangkat fungsi perpustakaan standar C. Mereka sebenarnya adalah pembungkus, mereka dapat melakukan beberapa pemeriksaan dan kemudian memanggil fungsi khusus sistem di kernel yang memerintahkannya untuk melakukan tindakan yang diperlukan oleh panggilan sistem. Dan triknya adalah bahwa fungsi-fungsi yang merupakan antarmuka diberi nama sama dengan panggilan sistem itu sendiri dan sering disebut langsung dengan "panggilan sistem".

Anda dapat memanggil fungsi di kernel yang melakukan panggilan sistem secara langsung melalui mekanisme khusus sistem. Masalahnya adalah itu membuat kode Anda sama sekali tidak portabel.

Jadi, panggilan sistem adalah:

  • sebuah konsep, serangkaian tindakan yang dilakukan oleh kernel untuk menawarkan layanan ke proses pengguna
  • fungsi pustaka standar C yang harus Anda gunakan dalam kode Anda untuk mendapatkan layanan ini dari kernel.
lororget
sumber
1
Apakah Anda memiliki contoh "fungsi pembungkus" dan panggilan sistem yang sebenarnya? (jalur file di Linux atau tautan ke sumber)
TheMeaningfulEngineer
3
Sebagai contoh, ini adalah implementasi dari getpidpemanggilan sistem di kernel Linux: lxr.free-electrons.com/source/kernel/timer.c?v=2.6.35#L1337 . Dan ini adalah fungsi wrapper di perpustakaan standar GNU C glibc-2.19: fossies.org/dox/glibc-2.19/… .
lgeorget
@Igeorget: tautan Anda tidak lagi berfungsi. Tautan yang diperbarui untuk implementasi kernel: github.com/torvalds/linux/blob/… . Saya tidak dapat menemukan apa yang glibc lakukan hari ini, kode itu tidak mungkin dinavigasi.
rchard2scout
6

Sebuah system call adalah cara untuk meminta sistem operasi (kernel) untuk melakukan beberapa operasi atas nama program Anda, bahwa program ini tidak dapat melakukan dengan sendirinya (atau hanya nyaman). Alasan untuk tidak dapat melakukan beberapa operasi biasanya karena memungkinkan program acak untuk melakukannya dapat membahayakan integritas sistem, seperti melakukan I / O (langsung ke RAM, menimpa apa pun).

POSIX mendefinisikan antarmuka untuk program, fungsi-fungsi tertentu yang dapat dipanggil oleh program Anda. Beberapa dari mereka menerjemahkan kurang lebih secara langsung ke panggilan sistem, yang lain membutuhkan lebih banyak elaborasi. Ini adalah runtime untuk bahasa Anda, misalnya pustaka C, yang bertanggung jawab untuk menawarkan antarmuka POSIX, dan untuk mengemas argumen dan menerima hasil secara langsung ke pemanggil.

Sistem Unixy menawarkan antarmuka POSIX lebih atau kurang secara langsung sebagai panggilan sistem. Biasanya ada cara untuk memanggil panggilan sistem secara langsung, cari syscall(2)detail tentang cara menggunakan fasilitas ini di Linux.

vonbrand
sumber
1
Anda menyentuh satu poin penting yang hanya dijawab oleh jawaban lain. Setiap fungsi yang programmer cukup mampu bisa menulis untuk dirinya sendiri (seperti strlen, strcpy, sqrt, dan qsort) dapat dan mungkin di ruang pengguna, diambil dari perpustakaan. (Sebagian besar libc; fungsi matematika seperti sqrtdan fungsi trigonometri dan hiperbolik mungkin dalam libm, perpustakaan matematika.) ... (lanjutan)
Scott
1
(lanjutan) ... Tetapi tidak ada cara pengguna dapat menulis sendiri fork,, killatau openfungsinya, karena ini memerlukan akses ke ruang memori kernel sistem operasi (misalnya, tabel proses) atau instruksi istimewa (misalnya, I / O). Oleh karena itu kode yang melakukan fungsi-fungsi ini harus ada di kernel sistem operasi; karenanya, fungsi sistem atau panggilan sistem.
Scott
5

Tentu, mari kita lakukan berapa banyak arah-dapat-kita-lihat-ini-gajah-dari? benda.

Panggilan sistem yang sebenarnya adalah, dalam program yang Anda buat, instruksi mesin yang memicu peningkatan privilege ke mode kernel, dan di dalam kernel sendiri itu adalah kode yang diminta oleh instruksi. Kode libc (dan setiap runtime bahasa) mengatur register mesin dan parameter dalam penyimpanan di mana kode kernel mengharapkan untuk menemukannya, yang bisa menjadi tempat yang aneh karena kendala pada instruksi mesin itu.

Begitu berada dalam kode OS itu sendiri, ada sedikit mirror-image unwinding dari hal-hal spesifik mesin yang dilakukan oleh userland runtime dan kemudian panggilan subrutin yang sangat biasa.
Jika Anda ingin melihat persis bagaimana ini bekerja dalam OS skala penuh, tarik sumber kernel ( git clone https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/) dan lakukan mis git grep -i system\ call. Tarik sumber glibc dan lakukan juga.

jthill
sumber
Benar, tetapi mencari-cari di Linux atau glibc sedikit di sisi berat ...
vonbrand
3

Di Linux setidaknya mekanisme system call bekerja di bawah sebagian besar arsitektur dengan menempatkan beberapa data yang diformat secara khusus (biasanya beberapa jenis c struct) di beberapa register atau alamat memori yang telah ditentukan.

Masalahnya sebenarnya adalah memaksa CPU untuk melakukan pergantian ke ruang kernel sehingga dapat menjalankan kode kernel istimewa untuk melayani panggilan. Ini dilakukan dengan memaksa kesalahan dari beberapa jenis (kesalahan menjadi pembagian dengan 0, overflow yang tidak ditentukan atau segfault, dll) ini memaksa kernel untuk mengambil alih eksekusi untuk menangani kesalahan.

Biasanya kernel menangani kesalahan dengan mematikan proses penyebab atau menjalankan handler yang disediakan pengguna. Namun dalam kasus syscall ia akan memeriksa register yang telah ditentukan dan lokasi memori dan jika mereka berisi permintaan syscall itu akan dijalankan menggunakan data yang disediakan oleh proses pengguna dalam in-memory struct. Ini biasanya harus dilakukan dengan beberapa perakitan kerajinan tangan khusus dan untuk memudahkan penggunaan syscall untuk pengguna perpustakaan C sistem harus membungkusnya sebagai fungsi. Untuk antarmuka tingkat yang lebih rendah, silakan lihat http://man7.org/linux/man-pages/man2/syscall.2.html untuk beberapa informasi tentang cara kerja syscalls dan bagaimana Anda dapat menelepon kemudian tanpa bungkus C.

Ini diberikan penyederhanaan yang berlebihan, itu tidak benar di semua arsitektur (mips memiliki instruksi syscall khusus) dan tidak harus bekerja sama pada semua OS. Namun, jika Anda memiliki komentar atau pertanyaan, silakan tanyakan.

Diubah: Catatan, mengenai komentar Anda tentang hal-hal di / dev / ini sebenarnya adalah antarmuka tingkat tinggi ke kernel, bukan yang lebih rendah. Perangkat ini sebenarnya menggunakan (sekitar) 4 syscall di bawahnya. Menulis kepada mereka sama dengan syscall tulis, membaca syscall baca, membuka / menutupnya setara dengan buka dan tutup syscall dan menjalankan ioctl menyebabkan syscall ioctl khusus yang dengan sendirinya merupakan antarmuka untuk mengakses salah satu dari banyak sistem ioctl panggilan (khusus, biasanya panggilan khusus perangkat dengan penggunaan terlalu sempit untuk menulis syscall keseluruhan untuk mereka).

Vality
sumber
1

Setiap panggilan sistem memiliki bilangan bulat terkait. Nomor integer ini adalah fungsi dari nilai balik dari panggilan sistem, jumlah argumen untuk panggilan sistem dan jenis argumen. Nomor panggilan sistem ini tidak lain adalah offset ke vektor panggilan sistem global, vektor yang hanya dapat diakses dalam mode istimewa ini berisi pointer ke penangan yang sesuai. Proses pada saat memanggil system call, interupsi perangkat lunak (trap interrupt) akan dihasilkan, maka trap handler akan dijalankan yang menentukan system call mana yang harus dipanggil. Kemudian kernel akan menyalin argumen dari panggilan sistem yang dilewati oleh pengguna yang ada di tumpukan ke dalam register prosesor, dan setelah menyelesaikan layanan yang diminta, data akan disalin kembali ke dalam tumpukan dari register prosesor. Ini adalah salah satu alasan mengapa ada argumen terbatas untuk panggilan sistem,

Naresh
sumber
Setiap panggilan (operasi) diidentifikasi secara internal oleh suatu angka, benar. Tetapi jumlahnya tergantung pada operasi , bukan pada nilai balik atau jumlah argumen. Penjelasan tentang cara kerjanya dari userland di x86 ada di sini
vonbrand