Første ting først
Før vi dykker ned i definitionen af et Linux-systemopkald og undersøger detaljerne i dets udførelse, er det bedst at starte med at definere de forskellige softwarelag i et typisk Linux-system.
Linux-kernen er et specialiseret program, der starter og kører på det laveste tilgængelige niveau på din hardware. Det har til opgave at orkestrere alt, der kører på computeren, herunder håndtering af tastatur, disk og netværkshændelser for at give tidssnit til udførelse af flere programmer parallelt.
Når kernen udfører et brugerniveauprogram, virtualiserer det hukommelsespladsen, så programmer tror, at de er den eneste proces, der kører i hukommelsen. Denne beskyttende boble af isolering af hardware og software øger sikkerheden og pålideligheden. Et ikke-privilegeret program kan ikke få adgang til hukommelse, der tilhører andre programmer, og hvis programmet går ned, afsluttes kernen, så den ikke kan skade resten af systemet.
Ridning af barrieren med Linux-systemopkald
Dette isolationslag mellem uprivilegerede applikationer giver en fremragende grænse til at beskytte andre applikationer og brugere på systemet. Uden en eller anden måde at interface med de andre elementer i computeren og omverdenen ville programmer ikke være i stand til at udrette meget af noget.
For at lette interaktion udpeger kernen en softwareport, der gør det muligt for det kørende program at anmode om, at kernen handler på dens vegne. Denne grænseflade er kendt som et systemopkald.
Da Linux følger UNIX-filosofien om "alt er en fil", kan mange funktioner udføres ved at åbne og læse eller skrive til en fil, som kan være en enhed. På Windows kan du for eksempel bruge en funktion kaldet CryptGenRandom til at få adgang til tilfældige bytes. Men på Linux kan dette gøres ved blot at åbne "filen" / dev / urandom og læse bytes fra den ved hjælp af standardopkald til systeminput / output-system. Denne afgørende forskel muliggør en enklere systemopkaldsgrænseflade.
Wafer-Thin Wrapper
I de fleste applikationer foretages ikke systemopkald direkte til kernen. Næsten alle programmer linker i standard C-biblioteket, som giver en tynd, men vigtig indpakning omkring Linux-systemopkald. Biblioteket sørger for, at funktionsargumenterne kopieres til de korrekte processorregistre, og derefter udsender det tilsvarende Linux-systemopkald. Når der modtages data fra opkaldet, fortolker indpakningen resultaterne og returnerer dem tilbage til programmet på en ensartet måde.
Bag scenen
Hver funktion i et program, der interagerer med systemet, oversættes til sidst til et systemopkald. For at se dette i aktion, lad os starte med et grundlæggende eksempel.
ugyldig hoved ()Dette er sandsynligvis det mest trivielle C-program, du nogensinde vil se. Det får simpelthen kontrol via hovedindgangspunktet og afslutter derefter. Det returnerer ikke engang en værdi, da main er defineret som ugyldig. Gem filen som ctest.c og lad os kompilere det:
gcc ctest.c-o ctestNår det er samlet, kan vi se filstørrelsen som 8664 bytes. Det kan variere lidt på dit system, men det skal være omkring 8k. Det er meget kode bare for at komme ind og ud! Årsagen til, at det er 8k, er, at libc-runtime inkluderes. Selvom vi stripper symbolerne, er det stadig en smule over 6k.
I et endnu enklere eksempel kan vi få Linux-systemet til at kalde for at afslutte snarere end afhængigt af C-runtime for at gøre det for os.
ugyldigt _start ()asm ("movl $ 1,% eax;"
"xorl% ebx,% ebx;"
"int $ 0x80");
Her flytter vi 1 ind i EAX-registeret, rydder EBX-registeret (som ellers ville indeholde returværdien) og kalder derefter Linux-systemopkaldsafbrydelsen 0x80 (eller 128 i decimal). Denne afbrydelse udløser kernen til at behandle vores opkald.
Hvis vi kompilerer vores nye eksempel, kaldet asmtest.c, og fjern symbolerne og ekskluder standardbiblioteket:
gcc -s -nostdlib asmtest.c-o asmtestvi producerer en binær mindre end 1k (på mit system giver det 984 bytes). Det meste af denne kode er eksekverbare overskrifter. Vi kalder nu det direkte Linux-systemopkald.
Til alle praktiske formål
I næsten alle tilfælde behøver du aldrig foretage direkte systemopkald i dine C-programmer. Hvis du bruger monteringssprog, kan behovet dog opstå. Ved optimering ville det dog være bedst at lade C-biblioteksfunktionerne foretage systemopkald og kun have din præstationskritiske kode integreret i forsamlingsdirektiverne.
Sådan programmeres systemopkaldsvejledninger
- Exec System Call
- Gaffelsystemopkald
- Stat-systemopkald
Liste over alle systemopkald
Hvis du vil se en liste over alle tilgængelige systemopkald til Linux, kan du tjekke disse referencesider: Fuld liste over systemopkald på LinuxHint.com, filippo.io / linux-syscall-table / og eller syscalls.kernelgrok.com