Asi pred tydnem jsem s Mirou Lachmanem resil, ze nainstalovane FreeBSD nerozpoznava NVMe disky, ktere v pocitaci jsou. Resili jsme to mimo konferenci, protoze to byla pomerne zdlouhava iterativni analyza plna dlouhejch LOGu z nichz navic casto po analyze vypadl prosty zaver "tak tohle nam nijak nepomuze".

Ale strucne to tu shrnu, presneji, vyuziju to jako "modelovku" k lehkemu popisu toho, jak FreeBSD vlastne detekuje zarizeni. Soustredim se na PCI, ale u ostatnich je to v zasade podobne.

Neobejdu se bez velice zjednoduseneho popisu toho, jak vypada hadrware. PCI sbernice je drat po kterem chodi data oznacena adresou. Kdyz zarizeni spatri svoji adresu, vi, ze nasledujici data jsou "jeho", jina zarizeni si dat nevsimaji.

Presneji - zpravy jsou tri typu, 1. vstupne/vystupni port| 2. pamet | 3. preruseni a zarizeni ma zpravu za vlastni jen pokud je oznacena spravnou kombinaci typ/adresa.

Jen malinko to zkomplikuju informaci, ze fyzicke pripojene zarizeni muze byt vnitrne virtualizovane - tedy - jako by to bylo vice nezavislych zarizeni.

Zvlastnim typem koncoveho zarizeni je "PCI-PCI bridge". Ten lze prirovnat k (dvouportovemu) switchi na LAN. Pokud nevite k cemu je dvouportovy switch tak k prodlouzeni dosahu. Delka PCI dratu je omezena a je omezen i pocet zarizeni, ktere na nej jde pripojit. Za bridgem je tak dalsi PCI sbernice.

Bridge jako koncove zarizeni jedne smernice prijima zpravy pro vsechna zarizeni, ktera jsou "za nim" (a predava je).

Adresy zarizeni nejsou pevne, prideluji se "autokonfiguraci" pri startu systemu - a tim uz se od hardwaru dostavame k tomu, jak system zarizeni hleda a inicializuje.

Operacni system je schopen oslovovat jednotliva zarizeni na sbernici v poradi v jakem jsou na ni pripojena a z kazdeho ziska identifikacni informaci. Ziska jich pomerne hodne, pro maximalni zjednoduseni zminim jen ty, ktere nas kriticky zajimaji ted.

Dostane identifikaci vyrobce a zarizeni, typ zarizeni a jake adresy a kolik jich zarizeni potrebuje pridelit.

Pokud si na svem FreeBSD spustite prikaz pciconf -lvb dostanete vypis pro ta zarizeni, ktera v pocitaci mate. Pro jedno z nich to muze vypadat napriklad takto:

ahci0@pci0:0:31:2:      class=0x010601 card=0x1c028086 chip=0x1c028086 rev=0x05 
hdr=0x00
    vendor     = 'Intel Corporation'
    device     = '6 Series/C200 Series Chipset Family 6 port SATA AHCI 
Controller'
    class      = mass storage
    subclass   = SATA
    bar   [10] = type I/O Port, range 32, base 0xf050, size  8, enabled
    bar   [14] = type I/O Port, range 32, base 0xf040, size  4, enabled
    bar   [18] = type I/O Port, range 32, base 0xf030, size  8, enabled
    bar   [1c] = type I/O Port, range 32, base 0xf020, size  4, enabled
    bar   [20] = type I/O Port, range 32, base 0xf000, size 32, enabled
    bar   [24] = type Memory, range 32, base 0xf7c02000, size 2048, enabled

V polozce chip= mame identifikaci vyrobku (1c02) a vyrobce (8086). Muj system vi co ta cisla znamenaji a tam mi to textove rozepsal v radcich "vendor=" a device=".

Zde je ale potreba zduraznit, ze znalost "co ta cisla znamenaji" a "umet zarizeni pouzivat" jsou dve nezavisle veci. System vam muze napsat presne co to je za zarizeni a presto nemusi mit pro dane zariznei ovadac a nebud eho umet pouzivat, muze to ale byt i ibracene - system ma pro dane zarizeni ovladac a umi s nim pracovat, ale nezna "textove interpretace" tech ciselnych identifikaci.

Typ zarizeni je v polozce class=0x010601, vyznam je castecne textove rozklicovan v polozkach class a subclass, ale tady plati totez co vyse - (ne)znalost textoveho popisu je nezavisla od schopnosti systemu zarizeni obsluhovat.

No a radky "bar" jsou uz jednotlive pozadavky zarizeni na adresy. Toto konretni zarizeni chce pet 32bitovych adresnich bloku typu "vstupne vystupni port", pricemz velikosti bloku (pocet takovych adres v kazdem bloku) jsou 8,4,8,4 a 32.

Krome toho chce zarizeni jeden 32bitovy adresni blok typu "pamet" o velikosti 2048 adres.

Jelikoz jsme pciconf spousteli na zivem systemu, v polozce "base" rovnou vidime vysledek - jake adresy system pridelil. Na startujicim systemu by tam nebylo nic (zarizeni je jedno jake adresy dostane) nebo by tam byla hodnota a pak to znamena, ze zarizeni preferuje uvedenou adresu (ale je vzdy na systemu jestli pozadovanou adresu prideli).

Pro ucely ladeni problemu "nenachazi zarizeni" je pro nas dulezity i udaj "pci0:0:31:2". V tom je zakodovano, kde ve stromu PCI sbernic toho kokretni zarizeni je pripojene.

V nasem pripade jde o prvni strom (cisluje se od nuly, proto pci0, prvni sbernici = neprosli jsme pres zadny bridge (to je ta druha nula), na teto sbernici to je zarizeni s poradovym cislem 31. Posledni cislo "2" je cislo vitualniho zarizeni v ramci daneho fyzickeho zarizeni.

Vratme se ake zpatky - system prochazi zarizeni jedno po druhem, od kazdeho
1. ziska tyto informace a prideli jim adresni bloky pozadovanych typu a velikosti.
2. zkusi pro zarizeni najit ovladac

Co se [2] tyce, funguje to takto - system ma ovladace (je jedno zda zakompilovane v kernelu nebo dynamicky nahrane). Ovladace je softwarova kopka funkci z nichz nas v teto chvili zajima funkce "probe". Ucelem teto funkce je pro konkretni zarizeni rict "ano, toto zarizeni umim obsluhovat" nebo "ne, netusim co to je". A system pro kazde nalezen zarizeni, kteremu pridelil pozadovane adresy vola funkc eprobe vsech ovladacu, cimz zjisti, zda ma pro dany hadrware alespon jeden softwarovy ovladac. Pokud ne, je to zarizeni bez ovladace a tim komunikace s nim konci. Pokud se jeden nebo vice softwarovych ovladaci najde, system mezi nimi vybere (ted nechci resit jak), ten danemu priradi a zavola (uz jen u toho jednoho ovladace) funkci "attach" - od toho okamziku zarizeni patri tomuto ovladaci a system uz s nim pracuje vyhradne prostrednictvim ovladace. Ovladac v ramci funkce attach zarizeni cele nakonfiguruje a pripravi na praci.

Takze jeste jednou, system na sbernici prochazi zarizeni jedno po drohem v poradi v jakem jsou pripojene a u kazdeho ziska informace a prideli pozadovane adresni bloky.

Nasledne se zarizeni predklada vsem ovladacum a nekteremu z tech ovladacu, ktere se k zarizeni "hlasi" ho prideli pricemz zavola funkci "attach" vybraneho ovladace. Ta zarizeni nainicializuje a pripravi pro "normalni pouziti".

Jen lehce se chci otrit po pripad, kdy k zarizeni patri ovladac "PCI-PCI bridge". Ten v ramci inicializace (funkce attach) zjisti, ze za timto zarizeni jsou dalsi PCI sbernice - a prida ji systemu na vrsek seznamu PCI sbernic. A protoze system prochazi seznam "odvrchu", nebude pristi zkoumane zarizeni "dalsi zarizeni na puvodni sbernici", ale zacne resit nove pridanou sbernici. K puvodni sbernici se system vrati a bude pokracovat dalsimi zarizenim teprve az vyridi sbernici nove objevenou.

Zbyva jeste zminit, ze kdyz se prideluji adresu nejakemu zarizeni za bridgem (za vice bridgi, kdyz je strom hlubsi), musi system pri pridelovani adres kazdemu bridgi po ceste rict, ze (i) tenhle adresni blok musi prijimat (a predavat dal na podrizenou sbernici).

No a to je vlastne vsechno - jak o hardwaru tak softwaru. Pokud nedojde k potizim, nic jineho uz se vlastne nedeje. Tohle ale potrebujeme znat kvuli tomu, ze se neco spatneho deje a my hledame co (nasledne proc a nasledne jak to opravit).

A o tom v pristim emailu (rozsekal jsme to, protoze to an jeden email je strasne dlouhy).

Dan

--
FreeBSD mailing list (users-l@freebsd.cz)
http://www.freebsd.cz/listserv/listinfo/users-l

Odpovedet emailem