Apel sistem - System call

O imagine de ansamblu la nivel înalt a interfeței de apel a sistemului kernel-ului Linux, care gestionează comunicarea între diferitele sale componente și spațiul utilizatorilor

În calcul , un apel de sistem (prescurtată în mod uzual la syscall ) este modul programatic în care un program de calculator solicită un serviciu de kernel al sistemului de operare pe care este executat. Aceasta poate include servicii legate de hardware (de exemplu, accesarea unei unități de disc sau accesarea camerei dispozitivului), crearea și executarea de noi procese și comunicarea cu serviciile integrale ale nucleului, cum ar fi planificarea proceselor . Apelurile de sistem oferă o interfață esențială între un proces și sistemul de operare.

În majoritatea sistemelor, apelurile de sistem pot fi efectuate numai din procesele din spațiul utilizatorilor , în timp ce în unele sisteme, OS / 360 și succesori, de exemplu, codul de sistem privilegiat emite și apeluri de sistem.

Privilegii

Arhitectura de procesoare cele mai moderne, cu excepția unor sisteme integrate, implică un model de securitate . De exemplu, modelul de inele specifică mai multe niveluri de privilegii sub care software-ul poate fi executat: un program este, de obicei, limitat la propriul spațiu de adrese, astfel încât să nu poată accesa sau modifica alte programe care rulează sau sistemul de operare în sine și este de obicei împiedicat să manipuleze direct dispozitive hardware (de exemplu, buffer-ul de cadre sau dispozitive de rețea ).

Cu toate acestea, multe aplicații au nevoie de acces la aceste componente, astfel încât apelurile de sistem sunt puse la dispoziție de sistemul de operare pentru a oferi implementări bine definite și sigure pentru astfel de operațiuni. Sistemul de operare se execută la cel mai înalt nivel de privilegiu și permite aplicațiilor să solicite servicii prin apeluri de sistem, care sunt adesea inițiate prin întreruperi . O întrerupere pune automat CPU-ul într-un anumit nivel de privilegiu ridicat și apoi trece controlul către kernel, care determină dacă programul apelant ar trebui să primească serviciul solicitat. Dacă serviciul este acordat, nucleul execută un set specific de instrucțiuni asupra cărora programul apelant nu are control direct, returnează nivelul de privilegiu la cel al programului apelant și apoi returnează controlul programului apelant.

Biblioteca ca intermediar

În general, sistemele oferă o bibliotecă sau un API care se află între programele normale și sistemul de operare. Pe sistemele de tip Unix , acel API face parte, de obicei, dintr-o implementare a bibliotecii C (libc), cum ar fi glibc , care oferă funcții de împachetare pentru apelurile de sistem, deseori denumite la fel ca apelurile de sistem pe care le invocă. În Windows NT , acel API face parte din Native API , în biblioteca ntdll.dll ; acesta este un API nedocumentat utilizat de implementările API-ului Windows obișnuit și utilizat direct de unele programe de sistem pe Windows. Funcțiile de împachetare ale bibliotecii expun o convenție obișnuită de apelare a funcțiilor (un apel de subrutină la nivel de asamblare ) pentru utilizarea apelului de sistem, precum și pentru a face apelul de sistem mai modular . Aici, funcția principală a wrapper-ului este de a plasa toate argumentele care trebuie transmise apelului de sistem în registrele procesorului corespunzător (și poate și în stiva de apeluri ), precum și de a seta un număr de apel de sistem unic pentru nucleul de apelat . În acest fel, biblioteca, care există între sistemul de operare și aplicație, crește portabilitatea .

Apelul la funcția de bibliotecă în sine nu determină trecerea la modul kernel și este de obicei un apel normal de subrutină (folosind, de exemplu, o instrucțiune de asamblare „CALL” în unele arhitecturi de seturi de instrucțiuni (ISA)). Apelul real al sistemului transferă controlul către kernel (și este mai dependent de implementare și de platformă decât apelul de bibliotecă care îl abstractizează). De exemplu, în Unix-ca sisteme, forkși execvesunt C funcții de bibliotecă , care la rândul său , să execute instrucțiuni care invoca forkși execapeluri de sistem. Efectuarea apelului de sistem direct în codul aplicației este mai complicată și poate necesita utilizarea unui cod de asamblare încorporat (în C și C ++ ), precum și necesitatea cunoașterii interfeței binare de nivel scăzut pentru funcționarea apelului de sistem, care poate fi supus să se schimbe în timp și astfel să nu facă parte din interfața binară a aplicației ; funcțiile bibliotecii sunt menite să abstragă acest lucru.

Pe sistemele bazate pe exokernel , biblioteca este deosebit de importantă ca intermediar. Pe exokernel, bibliotecile protejează aplicațiile utilizatorilor de API-ul kernel de nivel foarte scăzut și oferă abstracții și gestionarea resurselor .

OS / 360 și DOS / 360 IBM implementează majoritatea apelurilor de sistem printr-o bibliotecă de macro-uri de limbaj de asamblare , deși există câteva servicii cu o legătură de apeluri. Acest lucru reflectă originea lor într-un moment în care programarea în limbaj de asamblare era mai obișnuită decât utilizarea limbajului la nivel înalt . Apelurile de sistem IBM nu erau, prin urmare, executabile în mod direct de către programele de limbaj la nivel înalt, dar necesitau un subrutină de înfășurare a limbajului de asamblare apelabil. De atunci, IBM a adăugat multe servicii care pot fi apelate din limbi de nivel înalt în, de exemplu, z / OS și z / VSE .

Exemple și instrumente

Pe Unix , Unix- ului si a altor POSIX sisteme de operare -compliant, apeluri de sistem populare sunt open, read, write, close, wait, exec, fork, exit, și kill. Multe sisteme de operare moderne au sute de apeluri de sistem. De exemplu, Linux și OpenBSD au fiecare peste 300 de apeluri diferite, NetBSD are aproape 500, FreeBSD are peste 500, Windows are aproape 2000, împărțit între apelurile de sistem win32k (grafice) și ntdll (de bază) în timp ce Planul 9 are 51.

Instrumente precum strace , ftrace și truss permit unui proces să se execute de la început și să raporteze toate apelurile de sistem pe care le invocă procesul sau se pot atașa la un proces deja în desfășurare și pot intercepta orice apel de sistem efectuat de procesul menționat dacă operațiunea nu încalcă permisiunile a utilizatorului. Această abilitate specială a programului este de obicei implementată și cu apeluri de sistem precum ptrace sau apeluri de sistem pe fișiere în procfs .

Implementări tipice

Implementarea apelurilor de sistem necesită un transfer de control din spațiul utilizatorului în spațiul kernel, ceea ce implică un fel de caracteristică specifică arhitecturii. O modalitate tipică de a pune în aplicare acest lucru este de a utiliza o întrerupere software sau o capcană . Întrerupe controlul transferului către nucleul sistemului de operare , astfel încât software-ul trebuie pur și simplu să configureze un anumit registru cu numărul de apel de sistem necesar și să execute întreruperea software-ului.

Aceasta este singura tehnică furnizată pentru multe procesoare RISC , dar arhitecturile CISC precum x86 acceptă tehnici suplimentare. De exemplu, setul de instrucțiuni x86 conține instrucțiunile SYSCALL/ SYSRETși SYSENTER/ SYSEXIT(aceste două mecanisme au fost create independent de AMD și respectiv de Intel , dar în esență fac același lucru). Acestea sunt instrucțiuni de transfer de control „rapide”, care sunt concepute pentru a transfera rapid controlul către nucleu pentru un apel de sistem, fără cheltuielile generale ale unei întreruperi. Linux 2.5 a început să folosească acest lucru pe x86 , acolo unde este disponibil; anterior folosea INTinstrucțiunea, unde numărul de apel al sistemului era plasat în EAX registru înainte de executarea întreruperii 0x80.

Un mecanism mai vechi este poarta de apel ; folosit inițial în Multics și ulterior, de exemplu, vezi poarta de apel pe Intel x86 . Permite unui program să apeleze direct o funcție de nucleu folosind un mecanism de transfer de control sigur, pe care sistemul de operare îl configurează în avans. Această abordare a fost nepopulară pe x86, probabil din cauza cerinței unui apel îndepărtat (un apel către o procedură situată într-un segment diferit de segmentul de cod curent) care utilizează segmentarea memoriei x86 și lipsa de portabilitate pe care o cauzează, precum și existența instrucțiunilor mai rapide menționate mai sus.

Pentru arhitectura IA-64 , EPCse folosește instrucțiunea (Introduceți codul privilegiat). Primele opt argumente de apel de sistem sunt transmise în registre, iar restul sunt transmise în stivă.

În familia mainframe IBM System / 360 și succesorii săi, o instrucțiune Supervisor Call ( SVC ), cu numărul din instrucțiune mai degrabă decât într-un registru, implementează un apel de sistem pentru facilități vechi în majoritatea sistemelor de operare proprii IBM și pentru toate apelurile de sistem în Linux. În versiunile ulterioare ale MVS, IBM folosește instrucțiunile Program Call (PC) pentru multe facilități mai noi. În special, PC-ul este utilizat atunci când apelantul ar putea fi în modul Service Request Block (SRB).

PDP-11 minicalculatoare folosit EMT și IOT instrucțiuni, care, similar cu IBM System / 360 SVC și x86 INT , pune codul în instrucțiunea; generează întreruperi la adrese specifice, transferând controlul către sistemul de operare. VAX pe 32 de biți succesorul PDP-11 seria folosit CHMK , CHMe , și CHMS instrucțiunile pentru a efectua apeluri de sistem codului privilegiat la diferite niveluri; codul este un argument pentru instrucțiune.

Categorii de apeluri de sistem

Apelurile de sistem pot fi grupate aproximativ în șase categorii majore:

  1. Controlul procesului
  2. Gestionarea fișierelor
    • creați fișier, ștergeți fișier
    • deschide - inchide
    • citește, scrie, repoziționează
    • get / set atribute de fișiere
  3. Gestionarea dispozitivelor
    • solicitați dispozitiv, eliberați dispozitivul
    • citește, scrie, repoziționează
    • obțineți / setați atributele dispozitivului
    • atașați sau detașați în mod logic dispozitive
  4. Întreținerea informațiilor
    • obțineți / setați informații despre sistem (inclusiv ora, data, numele computerului, întreprinderea etc.)
    • obțineți / setați metadatele procesului, fișierului sau dispozitivului (inclusiv autorul, programul de deschidere, ora și data creației etc.)
  5. Comunicare
    • creați, ștergeți conexiunea de comunicare
    • trimite, primește mesaje
    • informații despre starea transferului
    • atașați sau detașați dispozitive la distanță
  6. Protecţie
    • obțineți / setați permisiunile de fișiere

Modul procesorului și comutarea contextului

Apelurile de sistem în majoritatea sistemelor de tip Unix sunt procesate în modul kernel , ceea ce se realizează prin schimbarea modului de execuție a procesorului într-unul mai privilegiat, dar nu este necesar un comutator context de proces - deși are loc un comutator context privilegiu . Hardware-ul vede lumea în termeni de mod de execuție în funcție de registrul de stare al procesorului , iar procesele sunt o abstractizare oferită de sistemul de operare. Un apel de sistem nu necesită, în general, o trecere de context la un alt proces; în schimb, este procesat în contextul oricărui proces invocat.

Într-un proces cu mai multe fire , apelurile de sistem pot fi efectuate din mai multe fire . Gestionarea unor astfel de apeluri depinde de proiectarea kernel-ului sistemului de operare specific și de mediul de execuție al aplicației. Următoarea listă prezintă modele tipice urmate de sisteme de operare:

  • Model multi-la-unu : Toate apelurile de sistem de la orice fir de utilizator dintr-un proces sunt tratate de un singur fir de nivel de nucleu. Acest model are un dezavantaj grav - orice apel de sistem de blocare (cum ar fi așteptarea intrării de la utilizator) poate îngheța toate celelalte fire. De asemenea, deoarece un singur fir poate accesa nucleul la un moment dat, acest model nu poate utiliza mai multe nuclee de procesoare.
  • Modelul unu la unu : fiecare fir de utilizator se atașează la un fir distinct de nivel de nucleu în timpul unui apel de sistem. Acest model rezolvă problema de mai sus a blocării apelurilor de sistem. Se găsește în toate distribuțiile majore Linux , macOS , iOS , versiunile recente de Windows și Solaris .
  • Model de la mulți la mulți : în acest model, un grup de fire de utilizator este mapat la un grup de fire de nucleu. Toate apelurile de sistem dintr - un bazin de fir de utilizator sunt gestionate de către firele în kernel - ul lor corespunzătoare piscina firului .
  • Model hibrid : Acest model implementează atât multe modele, cât și mai multe, în funcție de alegerea făcută de nucleu. Acest lucru se găsește în versiunile vechi ale IRIX , HP-UX și Solaris .

Vezi si

Note

Referințe

linkuri externe