Zmiany interfejsu ION ABI

Na działanie jądra systemu wysyłanego na urządzenia w wersji 4.14 lub nowszej wpływa poważna refaktoryzacja modułu jądra ION. Wiele implementacji sprzętowej warstwy abstrakcji pamięci graficznej (gralloc) dostawców zewnętrznych wymaga przydzielenia współdzielonych buforów pamięci. Na tej stronie znajdziesz wskazówki dotyczące migracji starszego kodu dostawcy do nowej wersji ION oraz informacje o możliwych przyszłych przerwach w interfejsie binarnym aplikacji (ABI).

Informacje o ION

ION jest częścią drzewa przejściowego nadrzędnego jądra. Podczas testowania w wersji roboczej ABI ION w przestrzeni użytkownika do jądra może nie działać prawidłowo w przypadku różnych wersji jądra. Chociaż przerwy w interfejsie ION ABI nie mają bezpośredniego wpływu na zwykłe aplikacje ani już uruchomione urządzenia, producenci przechodzący na nowe główne wersje jądra mogą napotkać zmiany, które wpływają na kod producenta wywołujący ION. Ponadto w przyszłości mogą wystąpić przerwy w ABI, ponieważ zespół ds. systemów Androida współpracuje z zespołem upstream, aby przenieść ION poza drzewo stagingu.

Zmiany w wersji android-4.14

W jądrze 4.12 dokonano gruntownej refaktoryzacji kodu jądra ION, usuwając z niego te jego części, które nakładały się na inne frameworki jądra. W związku z tym wiele starszych ioctl ION nie jest już przydatna i została usunięta.

Usunięcie klientów i uchwytów ION

Przed jądrem 4.12 otwarcie aplikacji /dev/ion przydzieliło klienta ION. ioctl ION_IOC_ALLOC przydzielił nowy bufor i zwrócił go do przestrzeni użytkownika jako element sterujący ION (nieprzejrzysty typ całkowity, który ma znaczenie tylko dla klienta ION, który go przydzielił). Aby mapować bufory w przestrzeni użytkownika lub udostępniać je innym procesom, uchwyty ION zostały ponownie wyeksportowane jako dma-buf fds za pomocą polecenia ioctl ION_IOC_SHARE.

W jądrze 4.12 ioctl ION_IOC_ALLOC bezpośrednio wyprowadza dma-buf fds. Pośredni stan uchwytu ION oraz wszystkie ioctle, które wykorzystują lub generują uchwyty ION, zostały usunięte. Ponieważ dma-buf fds nie jest powiązany z konkretnymi klientami ION, ioctl ION_IOC_SHARE nie jest już potrzebny, a cała infrastruktura klienta ION została usunięta.

Dodanie ioctli spójności pamięci podręcznej

Przed wersją jądra 4.12 ION udostępniał polecenie ioctl ION_IOC_SYNC do synchronizowania deskryptora pliku z pamięcią. Ten ioctl był słabo udokumentowany i nieelastyczny. W rezultacie wielu dostawców wdrożyło niestandardowe ioctle do obsługi konserwacji pamięci podręcznej.

W jądrze 4.12 zmienna ION_IOC_SYNC została zastąpiona zmienną DMA_BUF_IOCTL_SYNC ioctl zdefiniowaną w linux/dma-buf.h. wywołać funkcję DMA_BUF_IOCTL_SYNC na początku i na końcu każdego dostępu do procesora, z flagami określającymi, czy te dostępy są odczytami czy zapisami. Chociaż DMA_BUF_IOCTL_SYNC jest bardziej obszerny niż ION_IOC_SYNC, daje użytkownikowi większą kontrolę nad operacjami konserwacji pamięci podręcznej.

DMA_BUF_IOCTL_SYNC jest częścią stabilnego interfejsu ABI jądra i można go używać we wszystkich plikach dma-buf fds, niezależnie od tego, czy zostały one przydzielone przez ION.

Migracja kodu dostawcy na Androida w wersji 4.12 lub nowszej

W przypadku klientów userspace zespół systemów Androida zdecydowanie zaleca korzystanie z libion zamiast korzystania z otwartego kodu wywołań ioctl(). Począwszy od Androida 9, libion automatycznie wykrywa ABI ION w czasie wykonywania i próbuje ukryć wszelkie różnice między jądrami. Jednak po wydaniu jądra 4.12 wszystkie funkcje libion, które wygenerowały lub zużyły ion_user_handle_t, przestają działać. Te funkcje możesz zastąpić następującymi operacjami na sterownikach dma-buf, które działają we wszystkich wersjach jądra do tej pory.

Wywołanie starszej funkcji ion_user_handle_t Odpowiednie wywołanie dma-buf fd
ion_alloc(ion_fd, …, &buf_handle) ion_alloc_fd(ion_fd, ..., &buf_fd)
ion_share(ion_fd, buf_handle, &buf_fd) Nie dotyczy (w przypadku dma-buf fds to połączenie nie jest potrzebne)
ion_map(ion_fd, buf_handle, ...) mmap(buf_fd, ...)
ion_free(ion_fd, buf_handle) close(buf_fd)
ion_import(ion_fd, buf_fd, &buf_handle) Nie dotyczy (w przypadku dma-buf fds to połączenie nie jest potrzebne)
ion_sync_fd(ion_fd, buf_fd)
If (ion_is_legacy(ion_fd))
    ion_sync_fd(ion_fd, buf_fd);
else
    ioctl(buf_fd, DMA_BUF_IOCTL_SYNC, ...);

W przypadku klientów w jądrze, ponieważ ION nie eksportuje już żadnych interfejsów API dla jądra, sterowniki, które wcześniej używały interfejsu ION kernel API z ion_import_dma_buf_fd(), muszą zostać przekonwertowane na interfejs dma-buf API w jądrze z dma_buf_get().

Przyszłe awarie interfejsu ION ABI

Zanim będzie można przenieść ION z drzewa etapu przejściowego, w kolejnych wersjach jądra może być konieczne ponowne uszkodzenie interfejsu ION ABI. Zespół systemów Android nie spodziewa się, że te zmiany wpłyną na urządzenia wprowadzone na rynek z kolejną wersją Androida, ale mogą one mieć wpływ na urządzenia wprowadzane na rynek z kolejnymi wersjami Androida.

Na przykład społeczność nadrzędna zaproponowała podzielenie pojedynczego węzła /dev/ion na wiele węzłów na każdą stertę (na przykład /dev/ion/heap0), aby urządzenia mogły stosować różne zasady SELinux na każdej stercie. Jeśli ta zmiana zostanie wdrożona w przyszłej wersji jądra, spowoduje to uszkodzenie interfejsu ION ABI.