Što je Linux sistemski poziv?

What Is Linux System Call



Prije nego što zađemo u definiciju sistemskog poziva za Linux i ispitamo pojedinosti o njegovom izvođenju, najbolje je početi s definiranjem različitih softverskih slojeva tipičnog Linux sustava.

Linux kernel specijalizirani je program koji se pokreće i izvodi na najnižoj dostupnoj razini vašeg hardvera. Ima zadatak organizirati sve što radi na računalu, uključujući rukovanje događajima na tipkovnici, disku i mreži kako bi osiguralo vremenske presjeke za paralelno izvršavanje više programa.







Kad jezgra izvršava program na razini korisnika, virtualizira memorijski prostor tako da programi vjeruju da su oni jedini proces koji se izvodi u memoriji. Ovaj zaštitni mjehurić izolacije hardvera i softvera povećava sigurnost i pouzdanost. Neprivilegirana aplikacija ne može pristupiti memoriji drugih programa, a ako se taj program sruši, jezgra se prekida tako da ne može naštetiti ostatku sustava.



Probijanje barijere pomoću Linux sustavskih poziva

Ovaj sloj izolacije između neprivilegiranih aplikacija pruža izvrsnu granicu za zaštitu drugih aplikacija i korisnika u sustavu. Međutim, bez načina povezivanja s drugim elementima u računalu i vanjskom svijetu, programi ne bi mogli postići ništa.



Kako bi se olakšala interakcija, kernel određuje softverska vrata koja dopuštaju pokrenutom programu da zahtijeva da kernel djeluje u njegovo ime. Ovo sučelje poznato je kao sistemski poziv.





Budući da Linux slijedi UNIX filozofiju da je sve datoteka, mnoge se funkcije mogu izvršavati otvaranjem i čitanjem ili pisanjem u datoteku, koja bi mogla biti uređaj. Na primjer, u sustavu Windows možete koristiti funkciju koja se zove CryptGenRandom za pristup nasumičnim bajtovima. No, na Linuxu se to može učiniti jednostavnim otvaranjem datoteke/dev/urandom i čitanjem bajtova iz nje pomoću standardnih sistemskih poziva za unos/izlaz datoteke. Ova ključna razlika omogućuje jednostavnije sučelje za sistemske pozive.

Omotač tanki za pločice

U većini aplikacija sistemski pozivi ne upućuju se izravno u jezgru. Gotovo svi programi povezani su u standardnoj C knjižnici, koja pruža tanak, ali važan omot oko sistemskih poziva Linuxa. Knjižnica osigurava da se argumenti funkcije kopiraju u ispravne registre procesora, a zatim izdaje odgovarajući sistemski poziv za Linux. Kad se podaci dobiju iz poziva, omot tumači rezultate i vraća ih natrag u program na dosljedan način.



Iza scene

Svaka funkcija u programu koja stupa u interakciju sa sustavom na kraju se prevodi u sistemski poziv. Da bismo to vidjeli na djelu, počnimo s osnovnim primjerom.

poništitiglavni() {
}

Ovo je vjerojatno najtrivijalniji C program koji ćete ikada vidjeti. Jednostavno stječe kontrolu putem glavne ulazne točke, a zatim izlazi. Ne vraća čak ni vrijednost jer je main definiran kao void. Spremite datoteku kao ctest.c i sastavimo je:

gcc ctest.c -ctest

Nakon što se sastavi, možemo vidjeti veličinu datoteke kao 8664 bajta. Može se malo razlikovati na vašem sustavu, ali bi trebao biti oko 8k. To je mnogo koda samo za ulazak i izlazak! Razlog zbog kojeg je 8k je to što je uključeno vrijeme izvođenja libc -a. Čak i ako skinemo simbole, to je ipak malo više od 6k.

U još jednostavnijem primjeru, možemo učiniti da sustav Linux pozove izlaz, a ne ovisiti o vremenu izvođenja C da to učini umjesto nas.

poništiti_početak() {
asm('movl 1 USD,%eax;'
'xorl %ebx, %ebx;'
'int $ 0x80');
}

Ovdje premještamo 1 u EAX registar, brišemo EBX registar (koji bi inače sadržavao povratnu vrijednost), a zatim pozivamo prekid sistemskog poziva sustava Linux 0x80 (ili 128 u decimalnom obliku). Ovaj prekid pokreće jezgru da obradi naš poziv.

Ako sastavimo naš novi primjer, nazvan asmtest.c, i uklonimo simbole i isključimo standardnu ​​knjižnicu:

gcc-s-nostdlib asmtest.c -o asmtest

proizvest ćemo binarni format manji od 1 k (u mom sustavu daje 984 bajta). Većina ovog koda su izvršna zaglavlja. Sada pozivamo izravni sistemski poziv Linuxa.

Za sve praktične svrhe

U gotovo svim slučajevima nikada nećete morati izravno upućivati ​​sistemske pozive u svoje C programe. Ako koristite asemblerski jezik, može se pojaviti potreba. Međutim, u optimizaciji bi bilo najbolje dopustiti funkcijama C knjižnice da upućuju sistemske pozive i da imaju samo vaš kôd kritičan za performanse ugrađen u direktive sklapanja.

Kako programirati vodiče za sistemske pozive

Popis svih sistemskih poziva

Ako želite vidjeti popis svih dostupnih sistemskih poziva za Linux, možete provjeriti ove stranice sa uputama: Potpuni popis sistemskih poziva na LinuxHint.com, filippo.io/linux-syscall-table/ i ili syscalls.kernelgrok.com