specifichnyh dlya dannogo tipa drajvera. Kogda pozdnee process vypolnyaet chte- nie (read) ili zapis' (write), yadro peresylaet adres smeshcheniya iz tablicy fajlov v adresnoe prostranstvo zadachi, podobno tomu, kak eto imeet mesto pri rabote s fajlami obychnogo tipa, i ustrojstvo fizicheski peremeshchaet golovku k sootvetstvuyushchemu smeshcheniyu, ukazannomu v prostranstve zadachi. |tot sluchaj il- lyustriruetsya na primere v razdele 10.3. 300 Periferijnye Soedinitel'naya Vektor ustrojstva panel' preryvaniya +------------------+ | - | tty00 -------------+ | - | tty01 .... | | - | ... | +--+ +------------------+ tty07 -------------+-+ |------------| ttyintr 0 | tty08 -------------+ +--+ +------------------+ tty09 .... +-+ |------------| ttyintr 1 | ... +--------+ +--+ +------------------+ tty15 ----+ +--------+ |------------| consintr | konsol' ------+ +--+ +------------------+ printer00 -------------+-+ |------------| printintr 0 | .... | +--+ +------------------+ printer03 -------------+ | | | - | | | | - | +--+ +------------------+ Risunok 10.6. Preryvaniya ot ustrojstv 10.1.3 Programmy obrabotki preryvanij Kak uzhe govorilos' vyshe (razdel 6.4.1), vozniknovenie preryvaniya pobuzh- daet yadro zapuskat' programmu obrabotki preryvanij, v osnove algoritma koto- roj lezhit sootnoshenie mezhdu ustrojstvom, vyzvavshim preryvanie, i smeshcheniem v tablice vektorov preryvanij. YAdro zapuskaet programmu obrabotki preryvanij dlya dannogo tipa ustrojstva, peredavaya ej nomer ustrojstva ili drugie para- metry dlya togo, chtoby identificirovat' edinicu ustrojstva, vyzvavshuyu prery- vanie. Naprimer, v tablice vektorov preryvanij na Risunke 10.6 pokazany dve tochki vhoda dlya obrabotki preryvanij ot terminalov ("ttyintr"), kazhdaya iz kotoryh ispol'zuetsya dlya obrabotki preryvanij, postupivshih ot 8 terminalov. Esli ustrojstvo tty09 prervalo rabotu sistemy, sistema vyzyvaet programmu obrabotki preryvaniya, associirovannuyu s mestom apparatnogo podklyucheniya ust- rojstva. Poskol'ku s odnoj zapis'yu v tablice vektorov preryvanij mozhet byt' svyazano mnozhestvo fizicheskih ustrojstv, drajver dolzhen umet' raspoznavat' ustrojstvo, vyzvavshee preryvanie. Na risunke zapisi v tablice vektorov pre- ryvanij, sootvetstvuyushchie preryvaniyam ot terminalov, imeyut metki 0 i 1, chtoby sistema razlichala ih mezhdu soboj pri vyzove programmy obrabotki preryvanij, ispol'zuya k primeru etot nomer v kachestve peredavaemogo programme parametra. Programma obrabotki preryvanij ispol'zuet etot nomer i druguyu informaciyu, peredannuyu mehanizmom preryvaniya, dlya togo, chtoby udostoverit'sya, chto imenno ustrojstvo tty09, a ne tty12, prervalo rabotu sistemy. |tot primer v upro- shchennom vide pokazyvaet to, chto imeet mesto v real'nyh sistemah, gde na samom dele sushchestvuet neskol'ko urovnej kontrollerov i sootvetstvuyushchih programm obrabotki preryvanij, no on illyustriruet obshchie principy. Esli podvesti itog, mozhno skazat', chto nomer ustrojstva, ispol'zuemyj programmoj obrabotki preryvanij, identificiruet edinicu apparatury, a mlad- shij nomer v fajle ustrojstva identificiruet ustrojstvo dlya yadra. Drajver us- trojstva ustanavlivaet sootvetstvie mezhdu mladshim nomerom ustrojstva i nome- rom edinicy apparatury. 10.2 DISKOVYE DRAJVERY Tak slozhilos' istoricheski, chto diskovye ustrojstva v sistemah UNIX raz- bivalis' na razdely, soderzhashchie razlichnye fajlovye sistemy, chto oznachalo 301 "delenie [diskovogo] paketa na neskol'ko upravlyaemyh po-svoemu chastej" (sm. [System V 84b]). Naprimer, esli na diske raspolagayutsya chetyre fajlovye sis- temy, administrator mozhet ostavit' odnu iz nih nesmontirovannoj, odnu smon- tirovat' tol'ko dlya chteniya, a dve drugih tol'ko dlya zapisi. Nesmotrya na to, chto vse fajlovye sistemy sosushchestvuyut na odnom fizicheskom ustrojstve, pol'- zovateli ne mogut ni obrashchat'sya k fajlam nemontirovannoj fajlovoj sistemy, ispol'zuya metody dostupa, opisannye v glavah 4 i 5, ni zapisyvat' fajly v fajlovye sistemy, smontirovannye tol'ko dlya chteniya. Bolee togo, tak kak kazh- dyj razdel (i, sledovatel'no, fajlovaya sistema) zanimaet na diske smezhnye dorozhki i cilindry, skopirovat' vsyu fajlovuyu sistemu legche, chem v tom slu- chae, esli by razdel zanimal uchastki, razbrosannye po vsemu diskovomu tomu. Diskovyj drajver transliruet adres fajlovoj sistemy, sostoyashchij iz logi- cheskogo nomera ustrojstva i nomera bloka, v tochnyj nomer diskovogo sektora. Drajver poluchaet adres odnim iz sleduyushchih putej: libo strategicheskaya proce- dura ispol'zuet bufer iz bufernogo pula, zagolovok kotorogo soderzhit nomera ustrojstva i bloka, libo procedury chteniya i zapisi peredayut logicheskij (mladshij) nomer ustrojstva v kachestve parametra; oni preobrazuyut adres sme- shcheniya v bajtah, hranyashchijsya v prostranstve zadachi, v adres sootvetstvuyushchego bloka. Diskovyj drajver ispol'zuet nomer ustrojstva dlya identifikacii fizi- cheskogo ustrojstva i ukazaniya ispol'zuemogo razdela, obrashchayas' pri etom k vnutrennim tablicam dlya poiska sektora, otmechayushchego nachalo razdela na diske. Nakonec, on dobavlyaet nomer bloka v fajlovoj sisteme k nomeru bloka, s koto- rogo nachinaetsya kazhdyj sektor, chtoby identificirovat' sektor, ispol'zuemyj dlya vvoda-vyvoda. +---------------------------------------------+ | Razdel Nachal'nyj blok Dlina v blokah | | | | Razmer bloka = 512 bajt | | | | 0 0 64000 | | 1 64000 944000 | | 2 168000 840000 | | 3 336000 672000 | | 4 504000 504000 | | 5 672000 336000 | | 6 840000 168000 | | 7 0 1008000 | +---------------------------------------------+ Risunok 10.7. Razdely na diske RP07 Istoricheski slozhilos' tak, chto razmery diskovyh razdelov ustanavlivayutsya v zavisimosti ot tipa diska. Naprimer, disk DEC RP07 razbit na razdely, ha- rakteristika kotoryh privedena na Risunke 10.7. Predpolozhim, chto fajly "/dev/dsk0", "/dev/dsk1", "/dev/dsk2" i "/dev/dsk3" sootvetstvuyut razdelam diska RP07, imeyushchim nomera ot 0 do 3, i imeyut analogichnye mladshie nomera. Pust' razmer logicheskogo bloka v fajlovoj sisteme sovpadaet s razmerom dis- kovogo bloka. Esli yadro pytaetsya obratit'sya k bloku s nomerom 940 v fajlovoj sisteme, hranyashchejsya v "/dev/dsk3", diskovyj drajver pereadresuet zapros k bloku s nomerom 336940 (razdel 3 nachinaetsya s bloka, imeyushchego nomer 336000; 336000 + 940 = 336940) na diske. Razmery razdelov na diske var'iruyutsya i administratory raspolagayut faj- lovye sistemy v razdelah sootvetstvuyushchego razmera: bol'shie fajlovye sistemy popadayut v razdely bol'shego razmera i t. d. Razdely na diske mogut perekry- vat'sya. Naprimer, razdely 0 i 1 na diske RP07 ne peresekayutsya, no vmeste oni zanimayut bloki s nomerami ot 0 do 1008000, to est' ves' disk. Razdel 7 tak zhe zanimaet ves' disk. Perekrytie razdelov ne imeet znacheniya, poskol'ku faj- 302 lovye sistemy, hranyashchiesya v razdelah, razmeshchayutsya takim obrazom, chto mezhdu nimi net peresechenij. Imet' odin razdel, vklyuchayushchij v sebya vse diskovoe prostranstvo, vygodno, poskol'ku ves' tom mozhno bystro skopirovat'. Ispol'zovanie razdelov fiksirovannogo sostava i razmera ogranichivaet gibkost' diskovoj konfiguracii. Informaciyu o razdelah v zakodirovannom vide ne sleduet vklyuchat' v diskovyj drajver, no nuzhno pomestit' v tablicu soder- zhimogo diskovogo toma. Odnako, najti obshchee mesto na vseh diskah dlya razmeshche- niya tablicy soderzhimogo diskovogo toma i sohranit' tem samym sovmestimost' s predydushchimi versiyami sistemy dovol'no trudno. V sushchestvuyushchih realizaciyah versii V predpolagaetsya, chto blok nachal'noj zagruzki pervoj iz fajlovyh sis- tem na diske zanimaet pervyj sektor toma, hotya po logike eto, kazalos' by, samoe podhodyashchee mesto dlya tablicy soderzhimogo toma. I vse zhe diskovyj draj- ver dolzhen imet' zakodirovannuyu informaciyu o meste raspolozheniya tablicy so- derzhimogo toma dlya kazhdogo diska, ne prepyatstvuya sushchestvovaniyu diskovyh raz- delov peremennogo razmera. V svyazi s tem, chto dlya sistemy UNIX yavlyaetsya tipichnym vysokij uroven' diskovogo trafika, drajver diska dolzhen maksimizirovat' peredachu dannyh s tem, chtoby obespechit' nailuchshuyu proizvoditel'nost' vsej sistemy. Novejshie diskovye kontrollery osushchestvlyayut planirovanie vypolneniya zadanij, trebuyushchih obrashcheniya k disku, pozicioniruyut golovku diska i obespechivayut peredachu dan- nyh mezhdu diskom i central'nym processorom; inache eto prihoditsya delat' dis- kovomu drajveru. Servisnye programmy mogut neposredstvenno obrashchat'sya k disku v obhod standartnogo metoda dostupa k fajlovoj sisteme, rassmotrennogo v glavah 4 i 5, kak pol'zuyas' blochnym interfejsom, tak i ne pribegaya k strukturirovaniyu dannyh. Neposredstvenno rabotayut s diskom dve vazhnye programmy - mkfs i fsck. Programma mkfs formatiruet razdel diska dlya fajlovoj sistemy UNIX, sozdavaya pri etom superblok, spisok indeksov, spisok svobodnyh diskovyh blo- kov s ukazatelyami i kornevoj katalog novoj fajlovoj sistemy. Programma fsck proveryaet celostnost' sushchestvuyushchej fajlovoj sistemy i ispravlyaet oshibki, kak pokazano v glave 5. Rassmotrim programmu, privedennuyu na Risunke 10.8, v primenenii k fajlam "/dev/dsk15" i "/dev/rdsk15", i predpolozhim, chto komanda ls vydala sleduyushchuyu informaciyu: ls -1 /dev/dsk15 /dev/rdsk15 br-------- 2 root root 0,21 Feb 12 15:40 /dev/dsk15 crw-rw---- 2 root root 7,21 Mar 7 09:29 /dev/rdsk15 Otsyuda vidno, chto fajl "/dev/dsk15" sootvetstvuet ustrojstvu blochnogo tipa, vladel'cem kotorogo yavlyaetsya pol'zovatel' pod imenem "root", i tol'ko pol'zovatel' "root" mozhet chitat' s nego neposredstvenno. Ego starshij nomer - 0, mladshij - 21. Fajl "/dev/rdsk15" sootvetstvuet ustrojstvu posimvol'nogo vvoda-vyvoda, vladel'cem kotorogo yavlyaetsya pol'zovatel' "root", odnako prava dostupa k kotoromu na zapis' i chtenie est' kak u vladel'ca, tak i u gruppy. Ego starshij nomer - 7, mladshij - 21. Process, otkryvayushchij fajly, poluchaet dostup k ustrojstvu cherez tablicu klyu- chej ustrojstv vvoda-vyvoda blokami i tablicu klyuchej ustrojstv posimvol'nogo vvoda-vyvoda, sootvetstvenno, a mladshij nomer ustrojstva 21 informiruet drajver o tom, k kakomu razdelu diska proizvoditsya obrashchenie, naprimer, dis- kovod 2, razdel 1. Poskol'ku mladshie nomera u fajlov sovpadayut, oni ssylayut- sya na odin i tot zhe razdel diska, esli predpolozhit', chto eto odno ustrojstvo (***). Takim obrazom, process, vypolnyayushchij programmu, otkryvaet odin i tot --------------------------------------- (***) Ne sushchestvuet inogo sposoba ustanovit', chto simvol'nyj i blochnyj draj- very ssylayutsya na odno i to zhe ustrojstvo, krome prosmotra tablic sis- temnoj konfiguracii i teksta programm drajvera. 303 zhe drajver dvazhdy (ispol'zuya razlichnye interfejsy), pozicioniruet golovku k smeshcheniyu s adresom 8192 i schityvaet dannye s etogo mesta. Rezul'taty vypol- neniya operacij chteniya dolzhny byt' identichnymi pri uslovii, chto rabotaet tol'ko odna fajlovaya sistema. +------------------------------------------------------------+ | #include "fcntl.h" | | main() | | { | | char buf1[4096], buf2[4096] | | int fd1, fd2, i; | | | | if (((fd1 = open("/dev/dsk5/", O_RDONLY)) == -1) || | | ((fd2 = open("/dev/rdsk5", O_RDONLY)) == -1))| | { | | printf("oshibka pri otkrytii\n"); | | exit(); | | } | | | | lseek(fd1, 8192L, 0); | | lseek(fd2, 8192L, 0); | | | | if ((read(fd1, buf1, sizeof(buf1)) == -1) || | | (read(fd2, buf2, sizeof(buf2)) == -1)) | | { | | printf("oshibka pri chtenii\n"); | | exit(); | | } | | | | for (i = 0; i < sizeof(buf1); i++) | | if (buf1[i] != buf2[i]) | | { | | printf("razlichie v smeshchenii %d\n", i); | | exit(); | | } | | printf("dannye sovpadayut\n"); | | } | +------------------------------------------------------------+ Risunok 10.8. CHtenie dannyh s diska s ispol'zovaniem blochnogo interfejsa i bez strukturirovaniya dannyh Programmy, osushchestvlyayushchie chtenie i zapis' na disk neposredstvenno, pred- stavlyayut opasnost', poskol'ku manipuliruyut s chuvstvitel'noj informaciej, riskuya narushit' sistemnuyu zashchitu. Administratoram sleduet zashchishchat' interfej- sy vvoda-vyvoda putem ustanovki prav dostupa k fajlam diskovyh ustrojstv. Naprimer, diskovye fajly "/dev/dsk15" i "/dev/rdsk15" dolzhny prinadlezhat' pol'zovatelyu s imenem "root", i prava dostupa k nim dolzhny byt' opredeleny takim obrazom, chtoby pol'zovatelyu "root" bylo razresheno chtenie, a vsem os- tal'nym pol'zovatelyam i chtenie, i zapis' dolzhny byt' zapreshcheny. Programmy, osushchestvlyayushchie chtenie i zapis' na disk neposredstvenno, mogut takzhe narushit' celostnost' dannyh v fajlovoj sisteme. Algoritmy fajlovoj sistemy, rassmotrennye v glavah 3, 4 i 5, koordiniruyut vypolnenie operacij vvoda-vyvoda, svyazannyh s diskom, tem samym podderzhivaya celostnost' informa- cionnyh struktur na diske, v tom chisle spiska svobodnyh diskovyh blokov i ukazatelej iz indeksov na informacionnye bloki pryamoj i kosvennoj adresacii. Processy, obrashchayushchiesya k disku neposredstvenno, obhodyat eti algoritmy. Pust' dazhe ih programmy napisany s bol'shoj ostorozhnost'yu, problema celostnosti vse 304 ravno ne ischeznet, esli oni vypolnyayutsya parallel'no s rabotoj drugoj fajlo- voj sistemy. Po etoj prichine programma fsck ne dolzhna vypolnyat'sya pri nali- chii aktivnoj fajlovoj sistemy. Dva tipa diskovogo interfejsa razlichayutsya mezhdu soboj po ispol'zovaniyu bufernogo kesha. Pri rabote s blochnym interfejsom yadro pol'zuetsya tem zhe al- goritmom, chto i dlya fajlov obychnogo tipa, isklyuchenie sostavlyaet tot moment, kogda posle preobrazovaniya adresa smeshcheniya logicheskogo bajta v adres smeshche- niya logicheskogo bloka (sm. algoritm bmap v glave 4) ono traktuet adres sme- shcheniya logicheskogo bloka kak fizicheskij nomer bloka v fajlovoj sisteme. Za- tem, ispol'zuya bufernyj kesh, yadro obrashchaetsya k dannym, i, v konechnom itoge, k strategicheskomu interfejsu drajvera. Odnako, pri obrashchenii k disku cherez simvol'nyj interfejs (bez strukturirovaniya dannyh), yadro ne prevrashchaet adres smeshcheniya v adres fajla, a peredaet ego nemedlenno drajveru, ispol'zuya dlya peredachi rabochee prostranstvo zadachi. Procedury chteniya i zapisi, vhodyashchie v sostav drajvera, preobrazuyut smeshchenie v bajtah v smeshchenie v blokah i kopiru- yut dannye neposredstvenno v adresnoe prostranstvo zadachi, minuya bufery yadra. Takim obrazom, esli odin process zapisyvaet na ustrojstvo blochnogo tipa, a vtoroj process zatem schityvaet s ustrojstva simvol'nogo tipa po tomu zhe adresu, vtoroj process mozhet ne schitat' informaciyu, zapisannuyu pervym pro- cessom, tak kak informaciya mozhet eshche nahodit'sya v bufernom keshe, a ne na diske. Tem ne menee, esli vtoroj process obratitsya k ustrojstvu blochnogo ti- pa, on avtomaticheski popadet na novye dannye, nahodyashchiesya v bufernom keshe. Pri ispol'zovanii simvol'nogo interfejsa mozhno stolknut'sya so strannoj situaciej. Esli process chitaet ili pishet na ustrojstvo posimvol'nogo vvo- da-vyvoda porciyami men'shego razmera, chem, k primeru, blok, rezul'taty budut zaviset' ot drajvera. Naprimer, esli proizvodit' zapis' na lentu po 1 bajtu, kazhdyj bajt mozhet popast' v lyuboj iz lentochnyh blokov. Preimushchestvo ispol'zovaniya simvol'nogo interfejsa sostoit v skorosti, esli ne voznikaet neobhodimost' v keshirovanii dannyh dlya dal'nejshej raboty. Processy, obrashchayushchiesya k ustrojstvam vvoda -vyvoda blokami, peredayut infor- maciyu blokami, razmer kazhdogo iz kotoryh ogranichivaetsya razmerom logicheskogo bloka v dannoj fajlovoj sisteme. Naprimer, esli razmer logicheskogo bloka v fajlovoj sisteme 1 Kbajt, za odnu operaciyu vvoda-vyvoda mozhet byt' peredano ne bol'she 1 Kbajta informacii. Pri etom processy, obrashchayushchiesya k disku s po- moshch'yu simvol'nogo interfejsa, mogut peredavat' za odnu diskovuyu operaciyu mnozhestvo diskovyh blokov, v zavisimosti ot vozmozhnostej diskovogo kontrol- lera. S funkcional'noj tochki zreniya, process poluchaet tot zhe samyj rezul'- tat, no simvol'nyj interfejs mozhet rabotat' gorazdo bystree. Esli vospol'zo- vat'sya primerom, privedennym na Risunke 10.8, mozhno uvidet', chto kogda pro- cess schityvaet 4096 bajt, ispol'zuya blochnyj interfejs dlya fajlovoj sistemy s razmerom bloka 1 Kbajt, yadro proizvodit chetyre vnutrennie iteracii, na kazh- dom shage obrashchayas' k disku, prezhde chem vyzvannaya sistemnaya funkciya vozvrashcha- et upravlenie, no kogda process ispol'zuet simvol'nyj interfejs, drajver mo- zhet zakonchit' chtenie za odnu diskovuyu operaciyu. Bolee togo, ispol'zovanie blochnogo interfejsa vyzyvaet dopolnitel'noe kopirovanie dannyh mezhdu adres- nym prostranstvom zadachi i buferami yadra, chto otsutstvuet v simvol'nom in- terfejse. 10.3 TERMINALXNYE DRAJVERY Terminal'nye drajvery vypolnyayut tu zhe funkciyu, chto i ostal'nye drajvery: upravlenie peredachej dannyh ot i na terminaly. Odnako, terminaly imeyut odnu osobennost', svyazannuyu s tem, chto oni obespechivayut interfejs pol'zovatelya s sistemoj. Obespechivaya interaktivnoe ispol'zovanie sistemy UNIX, terminal'nye drajvery imeyut svoj vnutrennij interfejs s modulyami, interpretiruyushchimi vvod i vyvod strok. V kanonicheskom rezhime interpretatory strok preobrazuyut nest- rukturirovannye posledovatel'nosti dannyh, vvedennye s klaviatury, v kanoni- cheskuyu formu (to est' v formu, sootvetstvuyushchuyu tomu, chto pol'zovatel' imel v 305 vidu na samom dele) prezhde, chem poslat' eti dannye prinimayushchemu processu; strokovyj interfejs takzhe preobrazuet nestrukturirovannye posledovatel'nosti vyhodnyh dannyh, sozdannyh processom, v format, neobhodimyj pol'zovatelyu. V rezhime bez obrabotki strokovyj interfejs peredaet dannye mezhdu processami i terminalom bez kakih-libo preobrazovanij. Programmisty, naprimer, rabotayut na klaviature terminala dovol'no byst- ro, no s oshibkami. Na etot sluchaj terminaly imeyut klavishu stiraniya ("erase"; klavisha mozhet byt' oboznachena takim obrazom), chtoby pol'zovatel' imel voz- mozhnost' stirat' chast' vvedennoj stroki i vvodit' korrektivy. Terminaly pe- resylayut mashine vsyu vvedennuyu posledovatel'nost', vklyuchaya i simvoly stiraniya (*** *). V kanonicheskom rezhime strokovyj interfejs buferizuet informaciyu v stroki (nabor simvolov, zakanchivayushchijsya simvolom vozvrata karetki (*****)) i processy stirayut simvoly u sebya, prezhde chem pereslat' ispravlennuyu posledo- vatel'nost' schityvayushchemu processu. V funkcii strokovogo interfejsa vhodyat: * postrochnyj razbor vvedennyh posledovatel'nostej; * obrabotka simvolov stiraniya; * obrabotka simvolov "udaleniya", otmenyayushchih vse ostal'nye simvoly, vveden- nye do togo v tekushchej stroke; * otobrazhenie simvolov, poluchennyh terminalom; * rasshirenie vyhodnyh dannyh, naprimer, preobrazovanie simvolov tabulyacii v posledovatel'nosti probelov; * signalizirovanie processam o zavisanii terminalov i preryvanii strok ili v otvet na nazhatie pol'zovatelem klavishi udaleniya; * predostavlenie vozmozhnosti ne obrabatyvat' special'nye simvoly, takie kak simvoly stiraniya, udaleniya i vozvrata karetki. Funkcionirovanie bez obrabotki podrazumevaet ispol'zovanie asinhronnogo terminala, poskol'ku processy mogut schityvat' simvoly v tom vide, v kakom oni byli vvedeny, vmesto togo, chtoby zhdat', kogda pol'zovatel' nazhmet klavi- shu vvoda ili vozvrata karetki. Richi otmetil, chto pervye strokovye interfejsy, ispol'zuemye eshche pri raz- rabotke sistemy v nachale 70-h godov, rabotali v sostave programm komandnogo processora i redaktora, no ne v yadre (sm. [Ritchie 84], str.1580). Odnako, poskol'ku v ih funkciyah nuzhdaetsya mnozhestvo programm, ih mesto v sostave yad- ra. Nesmotrya na to, chto strokovyj interfejs vypolnyaet takie funkcii, iz ko- toryh logicheski vytekaet ego mesto mezhdu terminal'nym drajverom i ostal'noj chast'yu yadra, yadro ne zapuskaet strokovyj interfejs inache, chem cherez termi- nal'nyj drajver. Na Risunke 10.9 pokazany potok dannyh, prohodyashchij cherez terminal'nyj drajver i strokovyj interfejs, i sootvetstvuyushchie emu upravlyayu- shchie vozdejstviya, prohodyashchie cherez terminal'nyj drajver. Pol'zovateli mogut ukazat', kakoj strokovyj interfejs ispol'zuetsya posredstvom vyzova sistemnoj funkcii ioctl, no realizovat' shemu, po kotoroj odno ustrojstvo ispol'zovalo by neskol'ko strokovyh interfejsov odnovremenno, pri chem kazhdyj interfejsnyj modul', v svoyu ochered', uspeshno vyzyval by sleduyushchij modul' dlya obrabotki dannyh, dovol'no trudno. 10.3.1 Simvol'nye spiski Strokovyj interfejs obrabatyvaet dannye v simvol'nyh spiskah. Simvol'nyj spisok (clist) predstavlyaet soboj peremennoj dliny spisok simvol'nyh blokov s ispol'zovaniem ukazatelej i s podschetom kolichestva simvolov v spiske. Sim- --------------------------------------- (****) V etom razdele rassmatrivaetsya ispol'zovanie terminalov vvoda-vyvoda, kotorye peredayut vse simvoly, vvedennye pol'zovatelem, bez obrabotki. (*****) V dannoj glave ispol'zuetsya obshchij termin "vozvrat karetki" dlya oboz- nacheniya simvolov vozvrata karetki i perevoda stroki. 306 Potok dannyh Potok upravlyayushchih vozdejstvij +-----------------------+ +-----------------------+ | Process chteniya/zapisi | | Process chteniya/zapisi | +-----------------------+ +-----------------------+ - | ^ - | ^ - v | - v | - +---------------------+ - +-----------------------+ vyvod | Strokovyj interfejs| vvod | Terminal'nyj drajver | - +---------------------+ - +-----------------------+ - | ^ - | ^ - v | - v | +-----------------------+ +---------------------+ | Terminal'nyj drajver | | Strokovyj interfejs | +-----------------------+ +---------------------+ | ^ v | +-----------------------+ | Drajver vvoda-vyvoda | +-----------------------+ | ^ v | +-------------------------+ | Ustrojstvo vvoda-vyvoda | +-------------------------+ Risunok 10.9. Posledovatel'nost' obrashchenij i potok dannyh che- rez strokovyj interfejs Ukazatel' Smeshchenie Smeshchenie na do do sleduyushchij nachala konca Massiv simvolov blok 0 1 2 3 4 5 6 7 8 9 14 ----------+---------+---------++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--- | 7 | 14 ||g|a|r|b|a|g|e||| |e|q|n| ||| |... ----+-----+---------+---------++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--- | v Risunok 10.10. Simvol'nyj blok vol'nyj blok (cblock) soderzhit ukazatel' na sleduyushchij blok v spiske, nebol'- shoj massiv hranimoj v simvol'nom vide informacii i adresa smeshchenij, pokazy- vayushchie mesto raspolozheniya vnutri bloka korrektnoj informacii (Risunok 10.10). Smeshchenie do nachala pokazyvaet pervuyu poziciyu raspolozheniya korrektnoj informacii v massive, smeshchenie do konca pokazyvaet pervuyu poziciyu raspolozhe- niya nekorrektnoj informacii. YAdro obespechivaet vedenie spiska svobodnyh simvol'nyh blokov i vypolnyaet nad simvol'nymi spiskami i simvol'nymi blokami shest' operacij. 1. YAdro naznachaet drajveru simvol'nyj blok iz spiska svobodnyh simvol'nyh blokov. 2. Ono takzhe vozvrashchaet simvol'nyj blok v spisok svobodnyh simvol'nyh blo- kov. 3. YAdro mozhet vybirat' pervyj simvol iz simvol'nogo spiska: ono udalyaet pervyj simvol iz pervogo simvol'nogo bloka v spiske i ustanavlivaet zna- cheniya schetchika simvolov v spiske i ukazatelej v bloke takim obrazom, chtoby posleduyushchie operacii ne vybirali odin i tot zhe simvol. Esli v re- 307 zul'tate operacii vybran poslednij simvol bloka, yadro pomeshchaet v spisok svobodnyh simvol'nyh blokov pustoj blok i pereustanavlivaet ukazateli v simvol'nom spiske. Esli v simvol'nom spiske otsutstvuyut simvoly, yadro vozvrashchaet pustoj simvol. 4. YAdro mozhet pomestit' simvol v konec simvol'nogo spiska putem poiska pos- lednego simvol'nogo bloka v spiske, vklyucheniya simvola v nego i pereusta- novki adresov smeshchenij. Esli simvol'nyj blok zapolnen, yadro vydelyaet no- vyj simvol'nyj blok, vklyuchaet ego v konec simvol'nogo spiska i pomeshchaet simvol v novyj blok. 5. YAdro mozhet udalyat' ot nachala spiska gruppu simvolov po odnomu bloku za odnu operaciyu, chto ekvivalentno udaleniyu vseh simvolov v bloke za odin raz. 6. YAdro mozhet pomestit' blok s simvolami v konec simvol'nogo spiska. Simvol'nye spiski pozvolyayut sozdat' neslozhnyj mehanizm buferizacii, po- leznyj pri nebol'shom ob®eme peredavaemyh dannyh, tipichnom dlya medlennyh ust- rojstv, takih kak terminaly. Oni dayut vozmozhnost' manipulirovat' s dannymi s kazhdym simvolom v otdel'nosti i s gruppoj simvol'nyh blokov. Naprimer, Risu- nok 10.11 illyustriruet udalenie simvolov iz simvol'nogo spiska; yadro udalyaet po odnomu simvolu iz pervogo bloka v spiske (Risunok 10.11a-v) do teh por, poka v bloke ne ostanetsya ni odnogo simvola (Risunok simvol'nyj simvol'nye spisok bloki +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | p | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----------+-+ | | 0 8 | | * | | | | | t | b | l | | | 27 | +--+ ++------+ +---+---+---+---+---+---+---+---+ | simvolov | +--+ v +----------+-+ | +-------+ +---+---+---+---+---+---+---+---+ | | 0 8 | | | | | t | r | o | f | f | | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 3 | | - | m | m | | | | | | +-------+ +---+---+---+---+---+---+---+---+ (a) +-------+ +---+---+---+---+---+---+---+---+ +----->| 1 8 | | | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----------+-+ | | 0 8 | | * | | | | | t | b | l | | | 26 | +--+ ++------+ +---+---+---+---+---+---+---+---+ | simvolov | +--+ v +----------+-+ | +-------+ +---+---+---+---+---+---+---+---+ | | 0 8 | | | | | t | r | o | f | f | | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 3 | | - | m | m | | | | | | +-------+ +---+---+---+---+---+---+---+---+ (b) 308 +-------+ +---+---+---+---+---+---+---+---+ +----->| 2 8 | | | | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----------+-+ | | 0 8 | | * | | | | | t | b | l | | | 25 | +--+ ++------+ +---+---+---+---+---+---+---+---+ | simvolov | +--+ v +----------+-+ | +-------+ +---+---+---+---+---+---+---+---+ | | 0 8 | | | | | t | r | o | f | f | | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 3 | | - | m | m | | | | | | +-------+ +---+---+---+---+---+---+---+---+ (v) +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | * | | | | | t | b | l | | | ++------+ +---+---+---+---+---+---+---+---+ +----------+-+ | v | 19 | +--+ +-------+ +---+---+---+---+---+---+---+---+ | simvolov | +--+ | 0 8 | | | | | t | r | o | f | f | | +----------+-+ | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 3 | | - | m | m | | | | | | +-------+ +---+---+---+---+---+---+---+---+ (g) Risunok 10.11. Udalenie simvolov iz simvol'nogo spiska simvol'nyj simvol'nye spisok bloki +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | p | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ +----------+-+ | v | 22 | +--+ +-------+ +---+---+---+---+---+---+---+---+ | simvola | +--+ | 0 8 | | * | | | | | t | b | l | | +----------+-+ | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 6 | | | | | t | r | o | f | | | +-------+ +---+---+---+---+---+---+---+---+ (a) +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | p | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ +----------+-+ | v | 23 | +--+ +-------+ +---+---+---+---+---+---+---+---+ | simvola | +--+ | 0 8 | | * | | | | | t | b | l | | +----------+-+ | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 7 | | | | | t | r | o | f | f | | +-------+ +---+---+---+---+---+---+---+---+ 309 (b) +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | p | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ +----------+-+ | v | 24 | +--+ +-------+ +---+---+---+---+---+---+---+---+ | simvola | +--+ | 0 8 | | * | | | | | t | b | l | | +----------+-+ | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | | | | t | r | o | f | f | | +-------+ +---+---+---+---+---+---+---+---+ (v) +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 8 | | p | i | c | | f | i | l | e | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----------+-+ | | 0 8 | | * | | | | | t | b | l | | | 25 | +--+ ++------+ +---+---+---+---+---+---+---+---+ | simvolov | +--+ v +----------+-+ | +-------+ +---+---+---+---+---+---+---+---+ | | 0 8 | | | | | t | r | o | f | f | | | ++------+ +---+---+---+---+---+---+---+---+ | v | +-------+ +---+---+---+---+---+---+---+---+ +----->| 0 1 | | - | | | | | | | | +-------+ +---+---+---+---+---+---+---+---+ (g) Risunok 10.12. Vklyuchenie simvolov v simvol'nyj spisok 10.11g); zatem ono ustanavlivaet ukazatel' spiska na sleduyushchij blok, kotoryj stanovitsya pervym blokom v spiske. Podobno etomu na Risunke 10.12 pokazano, kak yadro vklyuchaet simvoly v simvol'nyj spisok; pri etom predpolagaetsya, chto v odnom bloke pomeshchaetsya do 8 simvolov i chto yadro razmeshchaet novyj blok v konce spiska (Risunok 10.12g). 10.3.2 Terminal'nyj drajver v kanonicheskom rezhime Struktury dannyh, s kotorymi rabotayut terminal'nye drajvery, svyazany s tremya simvol'nymi spiskami: spiskom dlya hraneniya dannyh, vyvodimyh na termi- nal, spiskom dlya hraneniya nestrukturirovannyh vvodnyh dannyh, postupivshih v rezul'tate vypolneniya programmy obrabotki preryvaniya ot terminala, vyzvanno- go popytkoj pol'zovatelya vvesti dannye s klaviatury, i spiskom dlya hraneniya obrabotannyh vhodnyh dannyh, postupivshih v rezul'tate preobrazovaniya stroko- vym interfejsom special'nyh simvolov (takih kak simvoly stiraniya i udaleniya) v nestrukturirovannom spiske. Kogda process vedet zapis' na terminal (Risunok 10.13), terminal'nyj drajver zapuskaet strokovyj interfejs. Strokovyj interfejs v cikle schityvaet simvoly iz adresnogo prostranstva processa i pomeshchaet ih v simvol'nyj spisok dlya hraneniya vyvodnyh dannyh do teh por, poka potok dannyh ne budet ischer- pan. Strokovyj interfejs obrabatyvaet vyvodimye simvoly, naprimer, zamenyaya simvoly tabulyacii na posledovatel'nosti probelov. Esli kolichestvo simvolov v spiske dlya hraneniya vyvodnyh dannyh prevysit verhnyuyu otmetku, strokovyj in- terfejs vyzyvaet procedury drajvera, peresylayushchie dannye iz simvol'nogo spiska na terminal i posle etogo priostanavlivayushchie vypolnenie processa, ve- 310 +------------------------------------------------------------+ | algoritm terminal_write | | { | | vypolnit' (poka iz prostranstva zadachi eshche postupayut | | dannye) | | { | | esli (na terminal postupaet informaciya) | | { | | pristupit' k vypolneniyu operacii zapisi dannyh | | iz spiska, hranyashchego vyvodnye dannye; | | priostanovit'sya (do togo momenta, kogda termi- | | nal budet gotov prinyat' sleduyushchuyu porciyu dan- | | nyh); | | prodolzhit'; /* vozvrat k nachalu cikla */ | | } | | skopirovat' dannye v ob®eme simvol'nogo bloka iz | | prostranstva zadachi v spisok, hranyashchij vyvodnye | | dannye: strokovyj interfejs preobrazuet simvoly | | tabulyacii i t.d.; | | } | | | | pristupit' k vypolneniyu operacii zapisi dannyh iz spis-| | ka, hranyashchego vyvodnye dannye; | | } | +------------------------------------------------------------+ Risunok 10.13. Algoritm perepisi dannyh na terminal dushchego zapis'. Kogda ob®em informacii v spiske dlya hraneniya vyvodnyh dannyh padaet za nizhnyuyu otmetku, programma obrabotki preryvanij vozobnovlyaet vypol- nenie vseh processov, priostanovlennyh do togo momenta, kogda terminal smo- zhet prinyat' sleduyushchuyu porciyu dannyh. Strokovyj interfejs zavershaet cikl ob- rabotki, skopirovav vsyu vyvodimuyu informaciyu iz adresnogo prostranstva zada- chi v sootvetstvuyushchij simvol'nyj spisok, i vyzyvaet vypolnenie procedur draj- vera, peresylayushchih dannye na terminal, o kotoryh uzhe bylo skazano vyshe. Esli na terminal vedut zapis' neskol'ko processov, oni nezavisimo drug ot druga sleduyut ukazannoj procedure. Vyvodimaya informaciya mozhet byt' iska- zhena; to est' na terminale dannye, zapisyvaemye processami, mogut perese- kat'sya. |to mozhet proizojti iz-za togo, chto processy vedut zapis' na termi- nal, ispol'zuya neskol'ko vyzovov sistemnoj funkcii write. YAdro mozhet perek- lyuchat' kontekst, poka process vypolnyaetsya v rezhime zadachi, mezhdu posledova- tel'nymi vyzovami funkcii write, i vnov' zapushchennye processy mogut vesti za- pis' na terminal, poka pervyj iz processov priostanovlen. Vyvodimye dannye mogut byt' takzhe iskazheny i na terminale, poskol'ku process mozhet priostano- vit'sya na seredine vypolneniya sistemnoj funkcii write, ozhidaya zaversheniya vy- voda na terminal iz sistemy predydushchej porcii dannyh. YAdro mozhet zapustit' drugie processy, kotorye veli zapis' na terminal do togo, kak pervyj process byl povtorno zapushchen. Po etoj prichine, yadro ne garantiruet, chto soderzhimoe bufera dannyh, vyvodimoe v rezul'tate vyzova sistemnoj funkcii write, poya- vitsya na ekrane terminala v nepreryvnom vide. Rassmotrim programmu, privedennuyu na Risunke 10.14. Roditel'skij process sozdaet do 18 porozhdennyh processov; kazhdyj iz porozhdennyh processov zapisy- vaet stroku (s pomoshch'yu bibliotechnoj funkcii sprintf) v massiv output, koto- ryj vklyuchaet soobshchenie i znachenie schetchika i v moment vypolneniya funkcii fork, i zatem vhodit v cikl poshagovoj perepisi stroki v fajl standartnogo vyvoda. Esli standartnym vyvodom yavlyaetsya terminal, terminal'nyj drajver re- guliruet potok postupayushchih dannyh. Vyvodimaya stroka imeet bolee 64 simvolov 311 +----------------------------------------------------------------+ | char form[]="eto primer vyvoda stroki iz porozhdennogo processa"| | | main() | | { | | char output[128]; | | int i;