Etusivu | Materiaali | -- Luennot -- | Miksi | Ajatuksia |
ITKA203 Käyttöjärjestelmät --- kesä 2007 --- Luennot ja muistiinpanot
Luennot on nyt pidetty. Alla on lista otsikoista ja käsitellyistä aiheista. Luennoilla näytettiin käytännön esimerkkejä auditorion tietokoneella, ja tuotettiin muistiinpanoja kurssimateriaalin pohjaksi.
Luento 1: Kurssi-info ja esitietojen varmistaminen
ti 22.5.
Yhteenveto luennolla puhutusta
- Kalvosarja: Kuka luennoi, kenelle, mitä, miksi ja millä tavoin
- Arkihavaintoja käyttöjärjestelmästä:
- Auditorion tietokoneessa on Windows; käyttäjä voi klikkailla kuvakkeita työpöydällä ja useita ohjelmia aukeaa eri ikkunoihin
- Digitaalikameran käyttäjä voi painella painikkeita; kamerassa on valikoita ja toimintoja; valosähköinen ilmiö tallentuu kameraan ja tulostuu sen LCD-näytölle.
- Jalava-koneessa on monta käyttäjää duunailemassa omia puuhiaan yhtä aikaa. Pystyn näkemään muiden käyttäjien kotihakemistot ulkopuolelta, mutta niiden sisällön listaaminen on kiellettyä. "Permission Denied". Luotan, että vastaavasti muut eivät näe minun tiedostojani.
- "Kertauksena" katsottiin läpi kuvia Tietotekniikan Perusteet -monisteesta
(sivuilta 3,6,17,19,26,27,31,26,29,41,43,45):
- Tietokone on automaatti (vähän niinkuin juoma-automaatti mutta pienempi ja useampitilainen)
- Tietokone rakennetaan yksinkertaisista elektroniikkakomponenteista koostamalla
- Digitaalinen järjestelmä ottaa vastaan koodatun syötteen ja palauttaa koodatun vasteen
- Syötteen ja vasteen koodaus ykkösinä ja nollina, jotka ilmenevät sähköjännitteinä niissä pikkukomponenteissa
- Turingin kone on pieni, kuvitteellinen puksutin äärettömän pitkällä nauhalla; toistaiseksi ei ole tietokonetta, joka tekisi sellaista mitä kyseinen puksutin ei saisi aikaan.
Lisämateriaalia
- "Esitieto:" Tietotekniikan perusteet -moniste
- Laskennan teoriasta jatkokurssi: Automaatit ja kieliopit
Luento 2: Käyttöjärjestelmä konepellin päältä, alta ja rajapinnasta
ke 23.5.
Monisteviitteet
- Luentomonisteen sivut 1-5
- Tulkittiin kuvia Tietotekniikan Perusteet -monisteesta (sivuilta 52,58-62,64,68,92-93,96);
Yhteenveto luennolla puhutusta
- Tietokonearkkitehtuuri: keskusyksikkö, muisti, väylä, I/O-laitteet
- Tunnetaan usein nimellä Von Neumann -arkkitehtuuri, vaikka John Von Neumann ei ollut ainoa keksijä
- Väylän rakenne:
ohjauslinja, osoitelinja, datalinja ("piuhoja" elektronisten
komponenttien välillä, yksi bitti per "piuha"; kukin linja
yhdistetään tai katkaistaan tilanteen mukaisesti väylän
ohjauskoneiston hoitamana.)
- Osoiteväylän leveys (bittipiuhojen lukumäärä) määrittelee osoiteavaruuden laajuuden eli montako muistiosoitetta tietokoneessa voi olla
- Osoiteavaruus: Väylän kautta pääsee käsiksi moniin paikkoihin, ja osoiteavaruus jaetaan usein (laitteistotasolla) osiin siten, että tietty osoitteiden joukko tavoittaa ROM-muistin (tehtaalla kiinnitetty), osa RAM-muistin (jota ohjelmat käyttävät), osa I/O-laitteet, osa prosessorin rekisterit.
- Dataväylän leveys (bittipiuhojen lukumäärä) määrittelee kuinka paljon tietoa väylä korkeintaan voi siirtää yhdellä siirto-operaatiolla
- Keskusyksikön eli prosessorin
rakenne: ALU, kontrolliyksikkö, rekisterit, sisäinen väylä
- Välttämättömät rekisterit:
- PC (program counter) kertoo, mistä haetaan (väylän kautta) seuraava suoritettava käsky
- IR (instruction register) tallentaa väliaikaisesti tällä hetkellä suoritettavan käskyn
- Vähintään yksi datarekisteri laskutoimituksia varten
- Vähintään yksi osoiterekisteri muistiosoitteiden tallentamista varten
- Lippurekisteri kertomaan suorituksen jälkitilanteesta, esim. yhteenlaskun muistibitti
- Käskykanta: se joukko konekielisiä komentoja (bittijonoja) jotka joku tietty prosessorimalli osaa suorittaa; vaihtelee mallien välillä; yleensä käskyjä on melko vähän ja ne tekevät varsin pienen operaation kerrallaan (kuten yhteenlasku, kertolasku, bittien siirto rekisteristä toiseen, bittien siirto muistipaikan ja jonkun rekisterin välillä, suoritusjärjestyken muuttaminen hyppäämällä eli käskyosoiterekisterin arvon muuttaminen).
- Prosessoriarkkitehtuuri: Tietyn prosessorimallin käskykanta ja lisäksi ne tavat, joilla käskyt muunnetaan biteiksi; tähän liittyy prosessorista löytyvät rekisterit ja tavat, joilla rekistereitä voidaan käyttää käskyissä
- Välttämättömät rekisterit:
- Virtuaalikone virtuaalikonehierarkia käsitteenä, esimerkkeinä Emacs-editori ja Javalla tehty Fotoalbumi; kerrokset ja rajapinnat
- Käyttöjärjestelmän tarkoitus ja tehtävät: käyttää fyysisen laitteiston rajapintaa, tarjoaa yleisemmän (so. virtuaalisen) rajapinnan seuraavalle tasolle eli ohjelmointikielille ja niiden apukirjastoille. Ilmeisesti tarkoituksen toteuttamiseksi täytyy toteuttaa keinoja, joilla hallitaan useita ohjelmia, tietokonearkkitehtuurin osia, tiedostoja ja käyttäjiä
HUOM: Yksinkertaisuuden vuoksi ei mainittu ainakaan tässä kohtaa mitään nykyprosessorien ominaisuuksista kuten ennakkonoudosta, liukuhihnoista, mikrokoodista tai välimuisteista. Olennaisia toki, mutta eivät Käyttöjärjestelmien ymmärtämisen kannalta. Moniprosessoriarkkitehtuureista puhutaan pari sanaa säikeiden yhteydessä parin viikon päästä. Muistinhallintaan liittyvästä prosessoriteknologiasta puhutaan hieman muistinhallinnan yhteydessä.
Lisämateriaalia
- "Esitieto:" Tietotekniikan perusteet -moniste
- Laitteistosta ja prosessoreista jatkokurssi: TIES523 Laitteistoläheinen ohjelmointi
- Intel Pentium -prosessorin manuaalit ("hardcore"...) -- Huolella kirjoitettua teknistä dokumentaatiota (lueskele, "jos jää luppoaikaa"). Tätä aikansa silmäilemällä ymmärtää jo aika paljon tietokoneen sielunelämästä. Muistit, prosessorin toimintatilat ja rekisterit, kaikki Intelin konekieliset käskyt ja kuinka ne muutetaan bittikoodiksi...
-
SPARC -prosessoriarkkitehtuurin kuvaus
("hardcore"...)
-- vertailun vuoksi toinen manuaali. Ei prosessori vaan arkkitehtuuri sellaiselle.
Näköjään atk-keskuksen (edesmenneet) koneet
tukki
jakanto
olivat Sparceja. Mikroluokissa, töissä ja kotona meillä useimmilla lienee x86-prosessori kuten Pentium. - The Java Virtual Machine Specification kertoo miten Java-virtuaalikone toimii. (myös hiukan HC, mutta ei liene paha hieman silmäillä tätäkin joskus kun kaipaa jotain kivaa tekemistä)
Luento 3: Ohjelmointi ja ohjelmointikieli ==> suoritus ja konekieli
to 24.5.
Monisteviitteet
- (Luentomonisteessa ei varsinaisesti ole vastaavaa kohtaa; kielijärjestelmät mainitaan sivulla 3, ja eräästä konekielestä on esimerkkejä s. 6-16)
Yhteenveto luennolla puhutusta
- Kalvosarja luennon pääkohdista
- Unix-shellit, interaktiivisen shellin käyttö, varoituksia
- Pääteyhteys PuTTY SSH Clientilla
- Mikroluokkien U: -asema on sama asia kuin kotihakemistosi THK:n suorakäyttökoneissa
- Joitakin unix-komentoja; demossa 1 tulee lisää.
- Tiedosto heksaeditorilla nähtynä: 8-bittisiä tavuja peräkkäin
- Tekstitiedon koodaus; vaihtelevia käytäntöjä mm. ääkköset ja rivinvaihdot
- Ohjelmointikieliä: kääntämistä ja tulkkausta
- Java-ohjelman kääntäminen, binäärinen tavukoodi
- Luennolla tehty esimerkkiohjelma: MunOhjelma.java
- Komentorivi ja ohjelman argumentit; kaikille ohjelmille voi antaa argumentteja (toiselta nimeltään komentoriviparametreja)
- C-ohjelman kääntäminen, binäärinen natiivi konekielikoodi
- Luennolla käsitelty esimerkkiohjelma: bytes_to_bits.c
- em. esimerkki olettaa, että char-muuttujan pituus olisi aina 8 bittiä. Vaarallista :-(
- C:n ja Javan vertailua
- Varoituksia C:n vaaroista
- Miksi laitteita tai käyttöjärjestelmiä ei ohjelmoida Javalla (ainakaan toistaiseksi)
- Demossa 2 on käytännön harjoitteina C-kielen ja imperatiivisen paradigman pikakurssi Sinulle, joka olet toistaiseksi ohjelmoinut Java-kielellä olioita käyttäen
Lisämateriaalia
- Netistä löytyi tällainen: Learning C from Java -- tuntuisi olevan ihan hyvä matsku C-kielen yksityiskohtiin Java-näkökulmasta
- Historiaa: Jonkinlainen kartta ohjelmointikielistä 1950-luvulta saakka
- 2500 muuta ohjelmointikieltä
Luento 4: Assembler, konekieli, aliohjelmat ja keskeytykset
ti 29.5.
Yhteenveto luennolla puhutusta
- Aiheotsikot (PDF)
- Ensimmäinen, härskisti asiavirheitä sisältävä versio materiaalista, jolla tällä kertaa korvataan luentomonisteen sivut 6-21, kunhan teksti vähän aikuistuu nykyisestä -- toivottavasti reilusti ennen tenttiä.
- Luentomonisteen sivut 6-17 ovat ihan hyödyllistä lukemista; siinä esitelty arkkitehtuuri on Intel 8086 tai ehkä 80286 (80-luvun prosessoriteknologiaa; pohjimmiltaan nykyinen on samanlaista, vaikka prosessoreissa on enemmän toiminnallisuutta pienemmässä fyysisessä tilassa.)
- Luentomonisteen sivut 18-21
Lisämateriaalia
Tässä nykyaikaista lisämateriaalia ihmeteltäväksi. Ei todellakaan ole tarkoitus lukea 1500 sivua, vaan korkeintaan nähdä vähän päältä, että millaisen käyttöohjeen prosessorivalmistaja aina julkaisee. Intro-luvut (parikymmentä ensimmäistä sivua) kertovat dokkarien sisällöstä ja oletetusta kohderyhmästä. Terminologian ja käsiteltyjen asioiden pitäisi tulla esille tällä kurssilla, eli täällä pitäisi syntyä pohjat tuollaisten manuaalien lukemiseen jatkossa, tarvittaessa.
- AMD64-arkkitehtuuri
- Erityisesti AMD64 -arkkitehtuurin rekisterit ja käskykanta (linkki)
- Intel 64 -- Intelin " kopio" kyseisestä arkkitehtuurista
- THK:mme Jalava-kone on 4-prosessorinen Intel Xeon -- olennaisesti yhdenlainen "x86-64".
- IT-porukan työ- ja opintopalvelimena toimiva Charra puolestaan on 2-prosessorinen AMD Opteron -- siis myös "x86-64".
Luento 5: Prosessit ja prosessien vuorottelu
ke 30.5.- Luentomonisteen sivut 22-34
- Muistiavaruudet (fyysinen ja prosessin oma virtuaalinen) luentotuhruna.
- Muistiosoitteet: mistä prosessori milloinkin noutaa käskyjä.
- Alustus prosessin käsitteeseen
- Lopullisempi versio nouto-suoritus -syklistä, sisältäen keskeytyksen käsittelyn
- FLIH eli first level interrupt handling; prosessorin atomiset toimenpiteet ennen paluuta nouto-suoritus -sykliin
- Keskeytysvektori
- Moniajon idea, aikaviipale, prosessin tilat running, ready ja suspended
- Prosessorin siirtyminen keskeytyskäsittelijään
- käyttöjärjestelmäkutsu, "prosessin itse pyytämä keskeytys"
Luento 6: Prosessit ja prosessien vuorottelu, jatkoa
Prosessien synkronointi ja kommunikointi (IPC), alkua
to 31.5.
- Luentomonisteen sivut 22-34
- Luentomonisteen sivut 35-42
- Luentosuhrut täydennettynä: prosessikasitteita.txt
- Lisää prosessien tiloista ja vuorontamisesta
- Tilanvaihdokset keskeytysten ja käyttöjärjestelmäkutsujen kohdalla
- Vuorontamismenettelyjä: eräajo (yksi prosessi alusta loppuun, sitten seuraava ==> hukkaa prosessoriaikaa I/O-suorituksiin), kiertojono (round robin, yksi aika-annos Ready-jonon prosesseille aina samassa järjestyksessä paitsi I/O:ta odottavat prosessit Blocked-jonossa normaalikierron ulkopuolella), prioriteettimenettelyt (vuorontaja ratkaisee jollakin perusteilla, mikä prosessi tarvitsee juuri nyt seuraavan aika-annoksen)
- Prosessitaulu, prosessielementti (PCB)
- Konteksti ja kontekstin vaihto
- Prosessin luonti: Unixin fork() -kutsu. Koodiesimerkki: minish.c -- yksinkertainen shell-ohjelma Unixille
- Alustus prosessien väliseen kommunikointiin (IPC)
- Viestijonot PCB:ssa
- Signaali. Koodiesimerkki: sigesim.c -- ohjelma, joka määrittelee signaalien käsittelyn itse.
- ensi viikolla lisää
Luento 7: Prosessien synkronointi ja kommunikointi, jatkoa. Säikeet.
ti 5.6.- Luentomonisteen sivut 22-42
- Lisää prosessien kommunikoinnista ja synkronoinnista
- Motivointia moniohjelmointiin: tausta-ajot ja GUIt yhtäaikaa
- Säikeet vs. prosessit
- ULT ja KLT -säikeistys. Pienet lisähuomiot: saie.txt
- Prosessien välinen kommunikointi viestijonon avulla ("send()- ja receive()"). Esimerkkikoodi: chattomyself.c
- Moniohjelmoinnin ongelmakohtia, jotka pitäisi ratkaista, mm. poissulkeminen ja lukkiutumisen välttäminen
- Esimerkkikoodi, jossa säikeet tulostavat coolisti
Matrix-elokuvatyyppisesti merkki kerrallaan yhteiseen
tulostusvirtaan:
Linkki
alkuperäiseen netistä löydettyyn esimerkkiin, joka
on siis ihan jonkun muun kurssimateriaalia, jonka pöllin
huolella täysin luvatta. Kääntäminen jalavassa vaati
pari muutosta; rohkenen laittaa tähän nämä, vaikkeivät
ole omia tekeleitäni: thread_nosem.c (ongelmallinen) ja
thread_sem.c (ongelma
ratkaistu). Käännös vaatii säiekirjaston eli
kääntäjäoption
-lpthread
. - HUOM! Vaikka Java tarjoaa sovellusohjelmoijalle helpot tavat moniohjelmointiin, on näkökohdat otettava huomioon sielläkin! Katso esimerkiksi Deadlock.java (Sunin Java-säieohjelmointi -introsta)
- Em. intro muuten opastaa säieohjelmointiin
Java-näkökulmasta, joten siihen kannattaa jossain
vaiheessa tutustua, jos ei vielä ole ehtinyt. Ja
kirkkaana mielessä tällä kurssilla opitut yleiset
ongelmat perusteluineen! Ratkaisut vaan on tehty
Java-ohjelmoijan kannalta helpoiksi sillä, että
välissä on se virtuaalikone JVM ja ohjelmointikieli
tukee suoraan moniohjelmoinnin käsitteitä, avainsana
synchronized
ym. Säieohjelmien tekeminen ei siis ole tämän kurssin asiaa, mutta säikeiden toteutus, yleiset ongelmat, ratkaisut ja ratkaisuun osallistujat "konepellin alla, päällä ja rajapinnassa" ovat.
Yritän eksplikoida motivaatioajatuksen: Tietojärjestelmän tekijän (konepellin päällä) tulee ymmärtää järjestelmässä olevien ohjelmakomponenttien suorituksiin (konepellin alla) liittyvä pelikenttä, jotta hän osaa tehdä tarvittavat suunnitteluratkaisut (abstraktisti). Lopputulos toteutuu rajapinnan avulla (mutta se on pikkujuttu em. yleiskuvaan verrattuna, ja se on työkalusta riippuen erilainen). Tämä kurssin puoliväliin sijoittuva motivaatioajatus ei liity ainoastaan säikeisiin, vaan kaikkeen muuhunkin. Se nyt vaan tulee heitettyä sanoiksi tässä kohtaa.
Luento 8: Prosessien synkronointi ja kommunikointi loppuun
Pikkuhuomioita microkernel-mallista ja moniprosessorikoneista.
ke 6.6.
- Luentomonisteen sivut 22-42
- Jaettu muistialue kommunikointitapana, esimerkiksi rengaspuskuri
- Moniohjelmoinnin ongelmakohtia, jotka pitäisi ratkaista, mm. synkronointi eli vuoronnusjärjestyksen hallinta, tuottaja-kuluttaja -ongelma
- Semafori: käyttöjärjestelmäkutsujen ohjelmointi sovelluksen kriittisen alueen ympärille; kyseisten käyttöjärjestelmäkutsujen toteutus ja toiminta KJ-tasolla
- Semaforin käyttö poissulkemiseen
- Semaforien käyttö synkronointiin, tuottaja-kuluttaja -ongelman ratkaiseminen kolmella semaforilla
- Luennolla kirjoitettu esimerkkiteksti: synkronointi.txt. (luennolla mulla tuli joku oikosulku logiikkaan, mm. unohdin mikä alkuperäinen ongelma olikaan; teksti on nyt koetettu täydentää paremmaksi ja rautalankamaisemmaksi)
- Pari huomiota microkernel-toteutuksesta verrattuna monoliittiseen käyttöjärjestelmään
- Flynn-luokitus
- Moniprosessorit: Prosessoriteknologian nykytilanne ja tulevaisuus: rinnakkaiset prosessorit ja yksi keskusmuisti; haasteellinen käyttöjärjestelmän ja laitteiston toteutustavoille; käyttäjän ja sovellusohjelmoijan kannalta moniohjelmoinnin hyödyt (mm. ohjelmien moniajo, ohjelman sisäiset tausta-ajot, ohjelmien modulaarisuus) sekä ongelmakohdat (mm. lukkiutuminen, suoritteiden synkronointi, poissulun tarve) ihan samoja kuin yhden prosessorin moniajossa.
Luento 9: Muistinhallinta, virtuaalimuisti.
ti 12.6.- Luentomonisteen sivut 43-47
- Luentomonisteen sivut 48-57
- (ja osittain myös alkupään sivut korvaava lisämateriaali)
- muistit_sivutus.txt Tekstimuotoinen luentohuhru. Graafinen tulossa oikopiirrettynä...
- Fyysinen muisti, muistin jakaminen prosesseille
- Yleisidea, oheismuistin (kovalevyn) käyttö
- Segmentointi, sivutus
- Toteutuksesta: Käyttöjärjestelmän tietorakenteet, laitteistotason tuki prosessoreissa, TLB
- Sivuviittausvirhe ja sen käsittely
- Muistin organisointi: välimuistit
Luento 10: Oheislaitteet ja I/O. Tiedostojärjestelmistä
ke 13.6.- Luentomonisteen sivut 58-64
- Fyysinen laite, esim. moderni kovalevy (+huomioita muista laitteista; näppäimistö, hiiri, monitori, verkkoyhteys)
- Väylä ja I/O -moduulit (t. kanavat, ohjaimet, kontrollerit)
- Keskeytykset, DMA
- Käyttöjärjestelmän vastuut, tarvittavat ohjelmat ja tietorakenteet
- Laiteriippuva- ja laiteriippumaton ohjelmisto; abstraktiot
- Laiteajuri
- Kovalevyjen ja tiedostojärjestelmien kenttää: välimuistit, RAID, journalointi
- (jatkuu/tarkennetaan luennolla 11 tai 12, jos jää kesken)
Luento 11: Pieni syvennys shell-ohjelmointiin
to 14.6. (huomioi paikka: Beeta)Ensin käydään eilinen aihe loppuun; ehkä n. 20 minuuttia tjsp. eli sivutaan aihetta "laiteajurin toteutuksesta"
- Käytiin läpi demo 1:n lisukkeena ollutta skriptiä, joka mm. käsittelee grafiikkaa komentoriveillä apuohjelmiston avulla
- Ohjelmoinnin perusrakenteita shellissä: muuttujat, ehdot, toistot, aliohjelmat, argumentit, rekursio (käsittely jäi hiukan lyhyeksi; lisää demossa 4 tai sitten tulevat vastaan joskus myöhemmin)
- Käyttötarkoituksia: mm. login-asetukset, ajoitetut tehtävät, usein toistuvat komentorimpsut
- Ympäristömuuttujat (ei ehditty käsittelemään; demossa 4 tai sitten tulevat vastaan joskus myöhemmin)
Luento 12: Valaistuneempi näkökulma tietokoneeseen
ti 19.6.- Käytiin läpi kertaavia poimintoja aiemmista luennoista, ja yritettiin liittää asioita toisiinsa; tuli vähän sellanen monologinpajattajaolo.
- Tietokone tietokoneessa: emulaattorit ja simulaattorit; toteutustapoja ja käyttötarkoituksia
Lisämateriaalia
- Bochs -- yksi avoin toteutus "tietokoneelle tietokoneessa". Tällaisen kun asennat, voit kokeilla x86-64 -koneellasi (siis sillä asennetulla virtuaalisella Bochsilla) vaarattomasti ihan mitä vaan (eksoottiset käyttöjärjestlmät, oman käyttöjärjestelmän tekeminen, ohjelmalliset tietoturvahyökkäykset ...)
Luento 13: Linux Kernel
ke 20.6.- Linux Kernel lähdekoodi ja dokumentaatio: n. 8M riviä koodia (ja dokumentaatiota), n. 2% assembleria, loput C-kieltä. Paljon laitespesifisiä ajureita.
- Moduulijako toiminnallisen samuuden mukaan; päätasolla suurin piirtein kurssillamme käsiteltyjen aihekokonaisuuksien nimet (ja pari sellaista, joita emme ehdi tällä kurssilla käsitellä); monta kerrosta moduulihierarkiaa
- Prosessielementin toteutus Linuxissa:
task_struct
-tietorakenne - Initialisointi: Linuxin ensimmäiset toimenpiteet heti koneen käynnistämisen jälkeen (itse asiassa ns. boot loaderin suorituksen jälkeen); erilaisia konekieliä.
- Tiedostojärjestelmän tietorakenteita käytännön toteutuksena (näihin ei ehditty, mutta siellä ne tietenkin ytimessä olisivat, omassa moduulissaan)
Lisämateriaalia
- Linux kernel
- Pieni "kartta", josta voi ottaa suuntaa koodien tutkimisessa. Tämä on osa isompaa nettijulkaisua.
Luento 14: Kertaus, paikkaukset, loppukeskustelu, tenttitärpit
to 21.6.- Kesän 2007 tenttitärpit (PDF)
- Mitä käsiteltiin, mikä oli tärkeintä; mitä seuraavaksi
- Paikattu kirjallinen materiaali julkaistaan sivulla Materiaali. Luennoilla suusta päässeihin sammakoihin ja asiavirheisiin on aika vaikea tässä vaiheessa puuttua muuten kuin kirjoittamalla ne niin kuin ne piti sanoa. Ja sekin on edelleen luennoitsijan (aina) epätäydellinen ymmärrys asioista. Kriittisyys ja kuulijan vastuu tässäkin ...
- Loppukeskustelu jopa tapahtui! Yhteenveto sivulla Ajatuksia.
- SUURI KIITOS luennoilla istuneille; teidän edessä oli mukava yrittää selvennellä tärkeäksi näkemääni asiaa!
Viimeksi kajottu 2007-06-26.