2013-08-29 12 views
6

Używam wbudowanego systemu Linux na płycie, która jest konfigurowana głównie za pomocą mechanizmu drzewa urządzeń (pliki .dts/.dtc), tzn. Wpisy w pliku drzewa urządzenia wskazują, które urządzenia należy zarejestrować, a tym samym które sterowniki obciążenie.Drzewo urządzeń i rejestracja ręczna

Czy istnieje sposób ręcznego załadowania modułu dynamicznego w sposób podobny do tego, jaki byłby przy ładowaniu sterownika przez program obsługi drzewa urządzeń?

Aby wyjaśnić: zamiast wpisu urządzenia XXX w moim pliku .dts mogę "ręcznie" zarejestrować to urządzenie (na przykład dynamicznie ładując moduł jądra opakowania) po tym, jak przestrzeń użytkownika jest już w górze (tak jak jest możliwe z sterownikami dts-unaware)?

Używając prostego modprobe/insmod nie jest to, co myślę, że prace, ponieważ byłoby to po prostu załadować sterownika, ale nie zarejestrować urządzenie i jego parametry (które zazwyczaj pochodzą z pliku .dts).

Odpowiedz

9

Dynamiczne modyfikowanie załadowanego drzewa urządzeń nie jest czymś, co zwykle robimy, chociaż jest to możliwe.

Rozumiem, że nie interesuje cię drzewo urządzeń dla tego nowego urządzenia.

Proponuję utworzyć nowy moduł, aby dodać urządzenie, a po jego załadowaniu (po insmod ing), insmod swój moduł sterownika. W rzeczywistości kolejność nie ma znaczenia. Po dodaniu urządzenia wszystkie sterowniki zostaną sprawdzone, a te, które pasują, zostaną sondowane, a po dodaniu sterownika wszystkie urządzenia zostaną sprawdzone.

Aby utworzyć urządzenie, należy najpierw przydzielić go:

struct platform_device *pdev; 
int inst_id = 1; /* instance unique ID: base address would be a good choice */ 
pdev = platform_device_alloc("unique_name_here", inst_id); 

Następnie będziemy chcieli, aby utworzyć zasoby, przynajmniej jeden dla pamięci mapowane zakresie. W tym celu utwórz i wypełnij tablicę z struct resource. A struct resource jest całkiem proste. Oto przykład, w jaki sposób wypełnić zasób pamięci:

struct resource res = { 
    .start = 0x50000000, 
    .end = 0x50001fff, 
    .name = "some_name", 
    .flags = IORESOURCE_MEM, 
}; 

Kiedy już, że, dodać go do urządzenia platformy budujesz:

platform_device_add_resources(pdev, &res, 1); 

Upewnij res nie jest na stosie, choć (uczyń go globalnym lub kzalloc it i kfree podczas rozładowywania modułu).

Jesteś teraz gotowy, aby dodać urządzenie Platforma:

platform_device_add(pdev); 

Device drzewo bok urządzenia platformy są dopasowane do kierowców platformy przez „autobus Platform” (nie prawdziwa rzeczywista magistrali fizycznej) przez nazwy. Tak więc sterownik twojej platformy będzie musiał podać równoważną nazwę (unique_name_here powyżej). Twój sterownik platformy będzie miał coś takiego:

static struct platform_driver my_platform_driver = { 
    .probe = my_probe, 
    .remove = my_remove, 
    .driver = { 
     .name = "unique_name_here", 
     .owner = THIS_MODULE, 
    }, 
}; 

module_platform_driver(my_platform_driver); 

i voila. Twój sterownik powinien zostać sondowany, jeśli dodano urządzenie platformy o tej samej nazwie.

Sterowniki korzystające z drzewa urządzeń dodają kolejnego użytkownika do .driver, czyli .of_match_table. Podano tam tabelę odpowiedników (tablicę łańcuchów).Dopasowanie następnie wykorzystuje właściwość compatible węzłów drzewa urządzeń.

+3

Dzięki za tę naprawdę miłą odpowiedź! – pmf