1. Reaalitilan muistinhallinta
2. Johdanto suojattuun tilaan
3. Suojatun tilan muistinhallinta
4. Keskeytykset ja poikkeukset

Katso myös:
1. Prashant TR:n laaja-alainen ja havainnollinen suojattua tilaa käsittelevä opas
2. Chris Giesen opas suojatusta tilasta

Johdanto suojattuun tilaan

Tekijä: Yariv Kaplan
Suomentanut Jouni Kähkönen 2.4.2005, 13.9.2005, 24.2.2007, 24.3.2007, 30.4.2007

Historia

1970-luvun loppupuolella esiteltiin 8086-suoritin, jota pidettiin suurena tekniikan läpimurtona. Kyseessä oli edullinen ja tehokas 16-bittinen suoritin, joka hyödynsi valtavaa muistimäärää (jopa 1 megatavua).

8086 saavutti heti käyttöönottonsa jälkeen suuren suosion, sillä IBM:n insinöörit valitsivat ensimmäistä henkilökohtaista tietokonetta suunnitellessaan juuri tämän suorittimen (itse asiassa he käyttivät 8086:n varianttiversiota, 8088:aa, mutta erot ovat merkityksettömiä). Koska 1 megatavu muistia nähtiin henkilökohtaisen tietokoneen käytössä yliampuvan suurena, IBM päätti käyttää työmuistina vain ensimmäiset 640 kilotavua ja varata loput 384 kilotavua BIOS-järjestelmän ja ISA-laajennuskorttien tarpeisiin. Aluksi lähes kaikki sovellukset olivat niin pieniä, että 640 kilotavun rajoitus ei ollut niille haitaksi. Lopulta markkinoille tuli roppakaupalla paljon muistia syöviä sovelluksia, ja Intelin oli pakko keksiä ongelmalle jokin ratkaisu.

Ratkaisu löytyi vuonna 1982, jolloin Intel esitteli uuden suorittimensa, 80286:n (yleensä puhutaan 286-suorittimesta). Toisin kuin 8086, joka tarjosi vain yhden toimintatilan, 80286:ssa yhdistyi periaatteessa kaksi toimintatilaa: 8086:n kanssa yhteensopivan reaalitilan sekä toissijaisena edistyksekkään suojatun tilan.

Suojatun tilan ansiosta 80286 pystyi hyödyntämään 24-bittistä osoiteväylää, ja siten sillä pääsi käsiksi jopa 16 megatavuun fyysistä muistia. Valitettavasti DOS-sovelluksia ei voitu helposti muuntaa suojattuun tilaan sopiviksi; olihan suojattu tila yhteensopimaton 8086-toteutuksen kanssa, jolle DOS oli alun perin kehitetty. Tästäkin syystä suojattu tila ei houkuttanut sen ajan ohjelmistokehittäjiä.

Suojatusta tilasta ei voinut myöskään sulavasti palata takaisin reaalitilaan. Ainoa keino oli suorittimen nollaaminen alkutilaansa (paljon aikaa vievä toimenpide). Vaikuttaa siltä, että Intelin insinöörit olettivat, että suojatusta tilasta ei koskaan haluta palata takaisin "vähäpätöiseen" reaalitilaan. Toinen 80286:n puute liittyi segmenttien enimmäiskokoon. Vaikka suoritin pystyi suojatussa tilassa ollessaan käyttämään koko osoiteavaruuttaan, muistia ei käytetty lineaarisesti, vaan muistinosoitukseen oli käytettävä segmenttejä. Segmentin enimmäiskoko oli saman verran kuin 8086:ssa eli 64 kilotavua.

80286-suorittimen rajoitusten takia Intel toi markkinoille seuraavan innovaationsa, 80386-suorittimen. 80386 oli edeltäjiinsä verrattuna ylivertainen. 80286-suorittimen 24-bittisen osoiteväylän tilalle tuli 32-bittinen väylä. Sen ansiosta käyttäjä sai käyttöönsä 4 gigatavun kokoisen fyysisen osoiteavaruuden. Uuden suorittimen myötä esiteltiin myös kolmas toimintatila, ns. virtuaalitila. Virtuaalitilan avulla oli mahdollista suorittaa 8086-koodia suojatun tilan alaisuudessa. Lisäksi 386 tuki sivutusta.

Suojatun tilan arkkitehtuurissa yhdistyy monet kehittyneet ominaisuudet. Suojattu tila ratkaisee 8086:ssa olleet muistirajoituksetkin. 80386-suoritin suojattuine tiloineen loi pohjan 80486-, Pentium- ja Pentium Pro -suorittimien ominaisuuksille. Näistä ominaisuuksista kerrotaan tarkemmin seuraavissa kappaleissa.

Muistinhallinta

Muistinhallinta on järjestelmä, joka antaa käyttöjärjestelmille tehokkaita ominaisuuksia kuten muistin segmentoinnin ja sivutuksen.

8086-suorittimen alkuperäisellä segmentointiyksiköllä oli vain yksi tehtävä: toimia yhdyskäytävänä 1 megatavun fyysiselle osoiteavaruudelle. Intel ei muuttanut mieltään suojatun tilan käyttöönotosta ja segmentointiyksikön käytöstä. He halusivat säilyttää yhteensopivuuden vanhoihin sovelluksiin sekä helpottaa sovellusten sovittamista uuteen ympäristöön. Suojatussa tilassa ei ole enää kiinteäkokoisia, muistiin tasaisin välein ripoteltuja segmenttejä, vaan segmenttien koot ja sijainnit talletetaan segmenttideskriptori-nimisiin tietorakenteisiin. Muistia käsiteltäessä kaikki muistiviittaukset ovat suhteellisia kyseisessä segmentissä olevaan kantaosoitteeseen. Tämä helpottaa sovellusmoduulien lataamista, sillä käyttöjärjestelmän ei näin tarvitse muuttaa sovelluksen koodia tiettyyn muistiosoitteeseen sopivaksi.

Sivutuksen ollessa käytössä suoritin lisää ylimääräisen, epäsuoran osoitteenmuodostustason muistinkäännösprosessiin. Käyttämällä erityisiä muistissa olevia hakutaulukkoja suoritin hämää sovelluksia siten, että ne luulevat omistavansa 4 gigatavun osoiteavaruuden. Suoritin käyttää fyysisen osoitteen asemesta ohjelmallisesti luotua osoitetta, joka osoittaa johonkin kohtaan suorittimen hakutaulukosta. Tämä kohta taulukossa sisältää varsinaisen fyysisen osoitteen, joka lähetetään suorittimen osoiteväylälle (Tämä on hyvin yksinkertaistettu kuvaus toimenpiteestä). Nimi sivutus valittiin sen takia, että tätä epäsuoraa osoitteenmuodostusjärjestelmää ei voi soveltaa yksittäisiin tavuihin vaan 4 kilotavun kokoisiin sivuihin. Sivutuksella järjestelmä pystyy luomaan suoritettaville sovelluksille omat osoiteavaruudet, jolloin muistinkäyttö on yksinkertaisempaa, ja mahdollisilta ristiriidoilta voidaan välttyä.

Näennäismuistin (engl. virtual memory) avulla sovellukset voivat varata muistia enemmän kuin fyysisesti on saatavilla. Tämä saadaan aikaan pitämällä osa muistisivuista työmuistissa ja osa levyllä. Kun sovellus yrittää käyttää sivua, joka sattumoisin sijaitsee levyllä, suoritin aiheuttaa poikkeuksen (poikkeus on suorittimen aiheuttama keskeytys, joka viestittää kriittisestä tapahtumasta). Silloin käyttöjärjestelmä lataa sivun uudelleen siten, että virheen tehnyt sovellus (engl. faulting application) voi taas jatkaa koodinsa suorittamista.

Moniajo

Moniajo viittaa käyttöjärjestelmän kykyyn suorittaa useita tehtäviä (engl. task) samanaikaisesti. Todellinen moniajo voidaan saavuttaa vain moniydinsuorittimella varustetulla tietokoneella, jossa tehtävät suoritetaan erillisillä suorittimilla. Windows 98 ja XP ja monet muut tavanomaiset käyttöjärjestelmät matkivat aitoa moniajoa vuorottelemalla nopeasti suoritettavien tehtävien välillä ja antamalla kullekin tehtävälle pienen hetken aikaa suorittaa sovelluskoodiaan.

Suojatun tilan tehtävänvaihtoprosessissa suoritin tallentaa rekisterien arvot ja muut senhetkiset kontekstitiedot Task State -segmenttiin. Kun alkuperäisen tehtävän on taas aika jatkaa suoritustaan, suoritin palauttaa tallennetut tiedot takaisin suorittimen sisäisiin rekistereihin, jotta alkuperäinen tehtävä voi jatkaa sovelluskoodinsa suorittamista.

Suojaus

Reaalitila ei sisällä tukea suojaukselle ja siten se ei suo sovelluksille turvallista ja luotettavaa ajoympäristöä. Virheelliset ja vahingolliset sovellukset saattavat horjuttaa käyttöjärjestelmän vakautta kirjoittamalla tietoa järjestelmän eri tietorakenteiden päälle. Suojauksen ollessa käytössä sovelluksissa ilmeneviä virheitä vastaan pystytään suojautumaan, ja käyttöjärjestelmä pystyy suorittamaan moniajoa vakaasti. Jokaista muistijaksoa (engl. memory cycle) ennen suoritetaan suojaustarkastus; muistin väärinkäyttö johtaa väärin käyttäytyneen muistijakson keskeytymiseen ja poikkeuksen käynnistymiseen.

Suojatusta tilasta on paljon apua myös ohjelmistokehitystyössä. Kehiteltävän sovelluksen laittomat muistiviittaukset voidaan estää ja analysoida virheenkorjaussovelluksella (engl. debugger). Samalla taataan ohjelmistokehitystyökalujen (kääntäjien, profiilien yms.) vakaa toiminta.

Virtuaalitila

Tarve ajaa MS-DOS-sovelluksia Windowsissa ja muissa suojatun tilan ympäristöissä johti siihen, että virtuaalitila sisällytettiin kaikkiin Intelin 32-bittisiin suorittimiin. Virtuaalitilassa toimiessaan suoritin käyttäytyy suojauksella, moniajolla ja sivutuksella varustettuna 8086-suorittimena. Tärkeää on huomata, että virtuaalitila ei suinkaan ole täysin erillinen suorittimen toimintaympäristö vaan ominaisuus, jota sovelletaan tehtäväkohtaisiin tarkoituksiin. Virtuaalitilassa toimiva tehtävä voidaan suorittaa järjestelmän muiden tehtävien ohella, sellaisetkin mukaan lukien, jotka on kirjoitettu hyödyntämään täysin suojatun tilan ominaisuuksia. Valitettavasti MS-DOS-sovelluksia ei suunniteltu toimimaan moniajoympäristössä, vaan ne edellyttävät järjestelmältä täydellistä omistusoikeutta.

Kyseiset sovellukset voisivat jumittaa koko järjestelmän esimerkiksi nollaamalla suorittimen keskeytyslipun ja estäen näin laitteistokeskeytysten toiminnan. Tällaisen tilanteen välttämiseksi kaikki keskeytyslipun tilaan vaikuttavat käskyt (CLI, STI, POPF jne.) aiheuttavat poikkeuksen virtuaalitilan tehtävää suoritettaessa. Käyttöjärjestelmän virtuaalikonemonitori on vastuussa näiden poikkeusten käsittelystä ja sellaisten käskyjen emuloimisesta, joita ei saa suorittaa. Tämä varmistaa sekä virtuaalitilan että suojatun tilan tehtäville sulavan ja turvallisen toimintaympäristön.

Tuki sovellusten virheenkorjaukselle

Sovellusten virheenkorjausta (engl. debugging) varten 80386 tarjoaa avuksi muutaman säädettävän virheenkorjausrekisterin. Keskeytyskohta eli sovelluskoodin kohta, jossa ajo väliaikaisesti keskeytetään (engl. breakpoint) asetetaan vaihtamalla yhden virheenkorjausrekisterin arvoksi haluttu muistiosoite ja määrittelemällä se suoritinjakson tyyppi, jonka halutaan käynnistävän keskeytyskohdan. Kun keskeytyskohtaan törmätään, suoritin aiheuttaa poikkeuksen, jolloin virheenkorjaussovellus saa ohjakset käsiinsä ja voi siten näyttää tietoja kehitettävästä sovelluksesta ja suorittimen sisäisestä tilasta.

80386-suorittimen virheenkorjaustuki on tullut vanhan, 8086-tyyppisen järjestelmän tilalle. Vanhassa järjestelmässä joutui asettamaan keskeytyskohdan suoraan suorittimen käskyvirtaan.

Olemme käsitelleet suojatun tilan perusominaisuudet. Seuraavaksi tarkastelemme tarkemmin 80386:n muistinhallintayksikköä. Pysy siis vireänä!


Copyright © 1997, 1998 Yariv Kaplan
yariv(at)internals(dot)com
Suomennos: Jouni Kähkönen, käyttäjä=kajouni, palvelin=mbnet.fi

Avainsanat: suojattu tila protected mode 386 80386 x86 os operating system developing reaalitila käyttöjärjestelmäohjelmointi käyttöjärjestelmäohjelmoinnin ohjelmointi ohjelmoinnin operating system development memory management interrupts ints keskeytykset poikkeukset keskeytys poikkeus interrupts expections exceptions suoritin suorittimen suoritinta suorittimien suoritinten prosessori prosessorin prosessoria prosessoreiden sovellus sovelluksen sovellusta ohjelma ohjelman ohjelmaa application program hallinnansiirto ohjauksensiirto ohjauksen siirto control transfer