Ero sivun ”Järjestelmäkutsu” versioiden välillä
Siirry navigaatioon
Siirry hakuun
p
ei muokkausyhteenvetoa
Jem (keskustelu | muokkaukset) (Ak: Uusi sivu: Järjestelmäkutsut muodostavat rajapinnan prosessissa suoritettavan User Mode -ohjelman ja ytimen välillä. Rajapinnan avulla ohjelma voi käyttää ytimen tarjoamia palveluita,...) |
Jem (keskustelu | muokkaukset) pEi muokkausyhteenvetoa |
||
Rivi 9: | Rivi 9: | ||
toiset vähän harvemmin käytettyjä. On tärkeää huomata, että [[POSIX]]-standardi, jota | toiset vähän harvemmin käytettyjä. On tärkeää huomata, että [[POSIX]]-standardi, jota | ||
Linux noudattaa, ei erottele järjestelmäkutsuja tavallisista funktiokutsuista. | Linux noudattaa, ei erottele järjestelmäkutsuja tavallisista funktiokutsuista. | ||
POSIX määrittelee vain rajapinnan, ei sitä, mikä rajapinnan funktio on | POSIX määrittelee vain [[API|rajapinnan]], ei sitä, mikä rajapinnan funktio on | ||
tavallinen kirjastofunktio ja mikä oikeasti järjestelmäkutsu. | tavallinen kirjastofunktio ja mikä oikeasti järjestelmäkutsu. | ||
Järjestelmäkutsut ovat olemassa vain siksi, että ydin pystyisi takaamaan | Järjestelmäkutsut ovat olemassa vain siksi, että ydin pystyisi takaamaan | ||
Rivi 31: | Rivi 31: | ||
* käyttäjien hallinta: <tt>getuid, setuid, chown, chgrp</tt> | * käyttäjien hallinta: <tt>getuid, setuid, chown, chgrp</tt> | ||
Järjestelmäkutsut on dokumentoitu Linuxin manuaalin kappaleessa 2. | Järjestelmäkutsut on dokumentoitu Linuxin manuaalin kappaleessa 2. Lisätietoja: | ||
man 2 intro | |||
==Järjestelmäkutsumekanismi== | ==Järjestelmäkutsumekanismi== | ||
Rivi 45: | Rivi 45: | ||
oikeutta lukea tiedostoa tai tappaa prosessia. | oikeutta lukea tiedostoa tai tappaa prosessia. | ||
Järjestelmäkutsussa tapahtuu siirtymä | Järjestelmäkutsussa tapahtuu siirtymä suorittimen (CPU) tilassa User Modesta | ||
[[Kernel Mode]] -tilaan. Miten tämä tapahtuu riippuu käytetyn | [[Kernel Mode]] -tilaan. Miten tämä tapahtuu riippuu käytetyn suorittimen | ||
arkkitehtuurista, mutta tyypillinen tapa on niin sanottu "ohjelmallinen | arkkitehtuurista, mutta tyypillinen tapa on niin sanottu "ohjelmallinen | ||
keskeytys" (software interrupt). Tämä mekanismi toimii siten, että | keskeytys" (software interrupt). Tämä mekanismi toimii siten, että suoritin | ||
suorittaa 'int'- tai 'trap'-käskyn, jonka seurauksena | suorittaa 'int'- tai 'trap'-käskyn, jonka seurauksena suoritin vaihtaa | ||
tilansa Supervisor Mode -tilaan ja jatkaa suoritusta määritellystä | tilansa Supervisor Mode -tilaan ja jatkaa suoritusta määritellystä | ||
keskeytyksen käsittelijärutiinista. | keskeytyksen käsittelijärutiinista. | ||
Intel x86-perheen | Intel x86-perheen suorittimilla Linuxissa on järjestelmäkutsut perinteisesti toteutettu | ||
<tt>int $0x80</tt> - | <tt>int $0x80</tt> -käskyllä. Järjestelmäkutsun | ||
numero välitetään <tt>eax</tt>-rekisterissä, muut parametrit rekistereissä | numero välitetään <tt>eax</tt>-rekisterissä, muut parametrit rekistereissä | ||
<tt>ebx</tt>, <tt>ecx</tt>, jne., riippuen kutsun parametrien lukumäärästä. | <tt>ebx</tt>, <tt>ecx</tt>, jne., riippuen kutsun parametrien lukumäärästä. | ||
Rivi 69: | Rivi 69: | ||
Tällä tavalla saadaan eristettyä varsinaisen järjestelmäkutsun monimutkaisuus | Tällä tavalla saadaan eristettyä varsinaisen järjestelmäkutsun monimutkaisuus | ||
Libc-kirjaston hoidettavaksi Sovellusohjelmat voivat kutsua Libc:n vastaavaa | Libc-kirjaston hoidettavaksi Sovellusohjelmat voivat kutsua Libc:n vastaavaa | ||
funktiota normaalilla korkean tason kielen (C) kutsulla, assembly-koodin sijasta. | funktiota normaalilla korkean tason kielen ([[C]]) kutsulla, assembly-koodin sijasta. | ||
Lisäksi ytimen kutsutapa on riippumaton kääntäjän käyttämästä C-kielen kutsutavasta. | Lisäksi ytimen kutsutapa on riippumaton kääntäjän käyttämästä C-kielen kutsutavasta. | ||
Sovellusohjelmissa voidaan jopa vaihtaa kutsutapaa (esimerkiksi käyttämään parametrinvälitystä | Sovellusohjelmissa voidaan jopa vaihtaa kutsutapaa (esimerkiksi käyttämään parametrinvälitystä | ||
Rivi 76: | Rivi 76: | ||
kääntämistä uudella kääntäjällä tai kääntäjän optioita muuttaen.) | kääntämistä uudella kääntäjällä tai kääntäjän optioita muuttaen.) | ||
Suorittimen rekistereitä käytetään parametrien välittämiseen siksi, | |||
että | että suorittimen tilan vaihtuessa User Mode:sta Supervisor Mode -tilaan, | ||
vaihtuu myös käytettävä pino. | vaihtuu myös käytettävä pino. | ||
==Sysenter ja Sysreturn== | ==Sysenter ja Sysreturn== | ||
Intelin x86- | Intelin x86-suorittimissa on Pentium II:sta alkaen ollut vaihtoehtoinen | ||
käsky, jolla siirtymän User Modesta Kernel Mode -tilaan voi toteuttaa: <tt>sysenter</tt>. | käsky, jolla siirtymän User Modesta Kernel Mode -tilaan voi toteuttaa: <tt>sysenter</tt>. | ||
Tämä käsky keksittiin tuomaan ratkaisu int-käskyyn liittyvään ongelmaan. | Tämä käsky keksittiin tuomaan ratkaisu int-käskyyn liittyvään ongelmaan. | ||
<tt>int $0x80</tt> -mekanismi on hidas, eli suoritus vaatii monta | <tt>int $0x80</tt> -mekanismi on hidas, eli suoritus vaatii monta | ||
kellojaksoa, ja se on muuttunut nykyaikaisissa | kellojaksoa, ja se on muuttunut nykyaikaisissa suorittimissa | ||
suhteellisesti mitattuna yhä hitaammaksi. Uusi <tt>sysenter</tt>-käsky on | suhteellisesti mitattuna yhä hitaammaksi. Uusi <tt>sysenter</tt>-käsky on | ||
nopea, mutta vanhemmat | nopea, mutta vanhemmat suorittimet eivät tue sitä, jolloin on | ||
käytettävä | käytettävä perinteistä <tt>int $0x80</tt>-käskyä. (<tt>sysenter</tt>-käskyn kanssa | ||
samanaikaisesti esitellyllä <tt>sysreturn</tt>-käskyllä palataan järjestelmäkutsusta.) | samanaikaisesti esitellyllä <tt>sysreturn</tt>-käskyllä palataan järjestelmäkutsusta.) | ||
Tavoitteena on toisaalta | Tavoitteena on toisaalta | ||
pitää Libc riippumattomana | pitää Libc riippumattomana suorittimen versiosta ja myös puhtaana | ||
koodista, joka ajon aikana tutkii mitä käskyjä | koodista, joka ajon aikana tutkii mitä käskyjä suoritin tukee ja | ||
mitä se ei tue. | mitä se ei tue. | ||
Ratkaisuna tähän ongelmaan ''ydin'' tarjoaa koodin, jolla | Ratkaisuna tähän ongelmaan ''ydin'' tarjoaa koodin, jolla | ||
järjestelmäkutsu suoritetaan suoritinkohtaisesti optimaalisella | |||
tavalla: joko <tt>sysenter</tt>-käskyä käyttäen, <tt>int $0x80</tt>-käskyllä, | tavalla: joko <tt>sysenter</tt>-käskyä käyttäen, <tt>int $0x80</tt>-käskyllä, | ||
tai tulevaisuudessa mahdollisesti jollain muulla mekanismilla. Tämä | tai tulevaisuudessa mahdollisesti jollain muulla mekanismilla. Tämä |