Nerozpoznane zarizeni.

Dan Lukes dan at obluda.cz
Mon May 11 18:23:43 CEST 2020


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 at 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



More information about the Users-l mailing list