Järjestelmäkutsu
Järjestelmäkutsu eli käyttöjärjestelmäkutsu (engl. system call, "systeemikutsu") on ohjelmoinnissa sovellusohjelmien käyttämä matalan tason mekanismi käyttöjärjestelmän ytimen tarjoamien palveluiden suorittamiseksi.
Järjestelmäkutsu ei ole suora funktiokutsu kuten sovelluksissa, vaan kutsun on ylitettävä ytimen ja käyttäjäavaruuden välinen jako.[1] Kutsutavat eroavat alustojen ja arkkitehtuurin mukaan.[1]
Käyttöjärjestelmissä voi olla satoja eri järjestelmäfunktioita.[2][3][4][5][6] Plan 9 -käyttöjärjestelmässä eri järjestelmäfunktioita on vain noin 50 kappaletta.[7] Alkuperäisessä Unix-järjestelmässä oli alle 50 järjestelmäkutsua.[8]
Tyypillisesti järjestelmäkutsut suoritetaan standardikirjaston avulla suoraan kutsumisen sijaan. Järjestelmäkutsu voi olla huomattavasti hitaampaa käyttäjäavaruuden funktiokutsuun verrattuna.[9] Kirjastot kuten glibc toteuttavat kutsujen optimointeja käyttäjäavaruudessa muun muassa vDSO-toiminnolla.[9][10]
Suorittimet kuten Motorola 68000 tukevat käyttäjämoodia (user-mode) ja kernelimoodia (supervisor-mode), kun taas eräät muut suorittimet käyttävät ohjelmasegmentin tasoa.[11]
Järjestelmäkutsun hitauteen vaikuttavia tekijöitä ovat muun muassa muistiavaruuden vaihdosta seuraavat toiminnot (TLB-tyhjennys) sekä tarve tallettaa ja palauttaa rekisterien tilat (pinon käsittely).[12]
Käyttötapaukset
muokkaaJärjestelmäkutsuilla toteutetaan muun muassa seuraavia toimintoja:[13]
- prosessien ja säikeiden käsittely
- muistinhallinta[14]
- levy-IO, tiedostojärjestelmät
Toteutukset
muokkaaIntel x86-arkkitehtuuripohjaisissa Linux-järjestelmissä järjestelmäkutsuja voidaan käyttää kahdella tavalla. Perinteinen tapa on käyttää ohjelmistokeskeytystä 80h (tai 0x80, desimaaleina 128), jolloin järjestelmäkutsun numero laitetaan rekisteriin eax ja funktion parametrit rekistereihin ebx - edx.[15] Uudempi ja nopeampi tapa on käyttää suorittimen SYSENTER
/SYSEXIT
-käskyjä, jotka välttävät keskeytyssignaalin lisäkuorman.[16][17] 64-bittisessä x86-64-arkkitehtuurissa vastaava kutsu tehdään rekistereillä rax ja rdi - r9, ja käytetään SYSCALL
/SYSRET
-käskyjä.[13][15][17] vDSO-toiminto ja ajonaikainen kirjasto voivat automaattisesti valita suorittimen tukeman toiminnon taaksepäin yhteensopivuuden vuoksi.[10]
MS-DOS-tyyppisissä käyttöjärjestelmissä taas käytetään keskeytystä 21h järjestelmäkutsuun.[18]
FreeBSD käyttää Unix-tyylistä kutsumistapaa ja 80h-keskeytystä, jossa oletetaan että kutsuttu funktio herättää keskeytyksen kutsuvan ohjelman sijaan ja parametrit välitetään pinossa.[19]
Windows NT on käyttänyt laitteistokeskeytystä keskeytysporttien lisäksi sekä 2e-keskeytystä järjestelmäkutsuun.[20][11]
Esimerkki
muokkaaEsimerkki on laadittu assembly-konekielellä Linux-järjestelmään. Siinä pyydetään käyttöjärjestelmää suorittamaan palvelu sys_close.
mov eax, 6 ; järjestelmäkutsu sys_close(unsigned int fd), sulkee tiedostokahvan
mov ebx, 1 ; tiedostokahva, 1 = stdout
int 80h ; tee järjestelmäkutsu
Vastaava esimerkki uudemmalla menettelyllä:
mov $6, %rax ; järjestelmäkutsun numero
mov $1, %rdi ; parametri
syscall ; tee järjestelmäkutsu
Myös ylemmän tason kielillä voi tehdä järjestelmäkutsuja suoraan:
#include <linux/unistd.h>
#include <sys/syscall.h>
int main()
{
long pid = syscall(SYS_getpid);
printf("Prosessinumero on %lx\n", pid);
return 0;
}
Lähteet
muokkaa- ↑ a b M. Jones: Kernel command using Linux system calls 21.3.2007. IBM developerWorks. Arkistoitu . Viitattu 5.11.2017.
- ↑ Linux Programmer's Manual man7.org. Viitattu 5.11.2017.
- ↑ http://bxr.su/OpenBSD/sys/kern/syscalls.c
- ↑ http://bxr.su/NetBSD/sys/kern/syscalls.c
- ↑ http://fxr.watson.org/fxr/source/kern/syscalls.c
- ↑ Mateusz "j00ru" Jurczyk: Windows WIN32K.SYS System Call Table (NT/2000/XP/2003/Vista/2008/7/8/10) j00ru.vexillium.org. Viitattu 5.11.2017.
- ↑ http://9p.io/sources/plan9/sys/src/libc/9syscall/sys.h
- ↑ K. Thompson & D. M. Ritchie: Unix Programmers's Manual - Second Edition. Bell Telephone Laboratories.
- ↑ a b Stephan Soller: Measurements of system call performance and overhead arkanis.de. Viitattu 6.11.2017.
- ↑ a b vdso - overview of the virtual ELF dynamic shared object Linux Programmer's Manual. Viitattu 6.11.2017.
- ↑ a b John Gulbrandsen: How Do Windows NT System Calls REALLY Work? codeguru.com. 26.8.2004. Viitattu 6.11.2017.
- ↑ Liedtke, Jochen: On u-Kernel Construction (PDF) os.itec.kit.edu. Viitattu 6.11.2017.
- ↑ a b Linux System Calls cs.lmu.edu. Viitattu 6.11.2017.
- ↑ Process Memory Concepts gnu.org. Viitattu 10.11.2017.
- ↑ a b Manu Garg: Sysenter Based System Call Mechanism in Linux 2.6 articles.manugarg.com. Viitattu 5.11.2017.
- ↑ Linus Torvalds: Re: Intel P6 vs P7 system call performance 16.12.2002. LKML.org. Viitattu 6.11.2017. (englanniksi)
- ↑ a b SYSENTER OSDev. Viitattu 5.11.2017.
- ↑ Porting MS-DOS System Calls Microsoft. Viitattu 8.11.2017.
- ↑ 11.3. System Calls freebsd.org. Viitattu 6.11.2017.
- ↑ John Gulbrandsen: System Call Optimization with the SYSENTER Instruction codeguru.com. 8.10.2004. Viitattu 6.11.2017.
Kirjallisuutta
muokkaa- Stevens, W. Richard: Advanced Programming in the UNIX Environment. Addison-Wesley, 1993. ISBN 0201563177.
Aiheesta muualla
muokkaa- Linuxin järjestelmäkutsut - Linuxin kernel 2.2:n järjestelmäkutsujen luettelo[vanhentunut linkki]
- Linuxin järjestelmäkutsut ytimen versiolle 4.7
- How System Calls Work on Linux/i86 (englanniksi)
- Unix assembly language programming