Wydanie jądra Linuksa 5.18

Po dwóch miesiącach prac Linus Torvalds przedstawił wydanie jądra Linuksa 5.18. Do najbardziej znaczących zmian zalicza się: dokonano gruntownego oczyszczenia przestarzałej funkcjonalności, uznano Reiserfs FS za przestarzały, zaimplementowano zdarzenia śledzenia procesów użytkownika, dodano obsługę mechanizmu blokowania exploitów Intel IBT, włączono tryb wykrywania przepełnienia bufora przy za pomocą funkcji memcpy() dodano mechanizm śledzenia wywołań funkcji fprobe, poprawiono wydajność harmonogramu zadań na procesorach AMD Zen, dodano sterownik do zarządzania funkcjonalnością procesora Intel (SDS), zintegrowano niektóre poprawki do restrukturyzacji plików nagłówkowych i zatwierdzono użycie standardu C11.

Nowa wersja zawiera 16206 2127 poprawek od 14203 1995 programistów (w ostatniej wersji było 108 14235 poprawek od 1340982 593836 programistów), rozmiar łatki to 44 MB (zmiany dotyczyły 5.18 16 plików, dodano 11 3 3 linii kodu, usunięto XNUMX XNUMX linii). Około XNUMX% wszystkich zmian wprowadzonych w wersji XNUMX dotyczy sterowników urządzeń, około XNUMX% zmian dotyczy aktualizacji kodu specyficznego dla architektur sprzętowych, XNUMX% dotyczy stosu sieciowego, XNUMX% dotyczy systemów plików, a XNUMX% są powiązane z wewnętrznymi podsystemami jądra.

Główne innowacje w jądrze 5.18:

  • Podsystem dyskowy, wejścia/wyjścia i systemy plików
    • System plików Btrfs dodał obsługę przesyłania skompresowanych danych podczas wykonywania operacji wysyłania i odbierania. Poprzednio podczas korzystania z funkcji wysyłania/odbioru strona wysyłająca dekompresowała dane przechowywane w postaci skompresowanej, a strona odbierająca ponownie je kompresowała przed zapisaniem. W jądrze 5.18 aplikacje przestrzeni użytkownika korzystające z wywołań wysyłania/odbioru otrzymały możliwość przesyłania skompresowanych danych bez przepakowywania. Funkcjonalność jest realizowana dzięki nowym operacjom ioctl BTRFS_IOC_ENCODED_READ i BTRFS_IOC_ENCODED_WRITE, które umożliwiają bezpośredni odczyt i zapis informacji w zakresach.

      Ponadto Btrfs poprawia wydajność fsync. Dodano możliwość deduplikacji i wykonania linku reflink (klonowanie metadanych pliku poprzez utworzenie łącza do istniejących danych bez ich kopiowania) dla całej pamięci, nie ograniczając się do punktów montowania.

    • W trybie bezpośredniego wejścia/wyjścia możliwy jest dostęp do zaszyfrowanych plików, gdy fscrypt używa szyfrowania wbudowanego, w którym operacje szyfrowania i deszyfrowania są wykonywane przez kontroler dysku, a nie jądro. Przy zwykłym szyfrowaniu jądra dostęp do zaszyfrowanych plików przy użyciu bezpośredniego wejścia/wyjścia jest nadal niemożliwy, ponieważ dostęp do plików odbywa się z pominięciem mechanizmu buforowania w jądrze.
    • Serwer NFS domyślnie obsługuje protokół NFSv3, który teraz nie wymaga osobnego włączania i jest dostępny, gdy NFS jest ogólnie włączony. NFSv3 jest uważany za główną i zawsze obsługiwaną wersję NFS, a obsługa NFSv2 może zostać w przyszłości zakończona. Znacząco poprawiono efektywność odczytu zawartości katalogów.
    • System plików ReiserFS jest przestarzały i oczekuje się, że zostanie usunięty w 2025 roku. Wycofywanie ReiserFS zmniejszy wysiłek wymagany do utrzymania zmian w całym systemie plików związanych z obsługą nowego API do montowania, iomap i tomów.
    • Dla systemu plików F2FS zaimplementowano możliwość mapowania identyfikatorów użytkowników zamontowanych systemów plików, która służy do porównywania plików konkretnego użytkownika na zamontowanej partycji obcej z innym użytkownikiem w bieżącym systemie.
    • Kod do obliczania statystyk w programach obsługi mapowania urządzeń został przerobiony, co znacznie poprawiło dokładność rozliczania w programach obsługi takich jak dm-crypt.
    • Urządzenia NVMe obsługują teraz 64-bitowe sumy kontrolne do sprawdzania integralności.
    • Dla systemu plików exfat zaproponowano nową opcję montowania „keep_last_dots”, która wyłącza usuwanie kropek na końcu nazwy pliku (w systemie Windows kropki na końcu nazwy pliku są domyślnie usuwane).
    • EXT4 poprawia wydajność trybu fast_commit i zwiększa skalowalność. Opcja montowania „mb_optimize_scan”, która pozwala zwiększyć wydajność w warunkach dużej fragmentacji systemu plików, jest przystosowana do pracy z plikami o rozmiarach.
    • Zakończono obsługę strumieni zapisu w podsystemie obsługującym urządzenia blokowe. Ta funkcja była proponowana dla dysków SSD, ale nie była powszechna i obecnie nie ma w użyciu żadnych urządzeń obsługujących ten tryb i jest mało prawdopodobne, że pojawią się one w przyszłości.
  • Usługi pamięci i systemu
    • Rozpoczęła się integracja zestawu poprawek, pozwalających znacznie skrócić czas przebudowy jądra poprzez restrukturyzację hierarchii plików nagłówkowych i zmniejszenie liczby współzależności. Jądro 5.18 zawiera poprawki optymalizujące strukturę plików nagłówkowych harmonogramu zadań (kernel/sched). W porównaniu do poprzedniej wersji, zużycie czasu procesora podczas asemblowania jądra/sched/kodu zostało zmniejszone o 61%, a rzeczywisty czas o 3.9% (z 2.95 do 2.84 s).
    • Kod jądra może korzystać ze standardu C11, opublikowanego w 2011 roku. Wcześniej kod dodawany do jądra musiał być zgodny ze specyfikacją ANSI C (C89), utworzoną w 1989 roku. W skryptach kompilacji jądra 5.18 opcja „—std=gnu89” została zastąpiona opcją „—std=gnu11 -Wno-shift-negative-value”. Rozważano możliwość wykorzystania standardu C17, jednak w tym przypadku konieczne byłoby zwiększenie minimalnej obsługiwanej wersji GCC, natomiast włączenie obsługi C11 wpisuje się w obecne wymagania dla wersji GCC (5.1).
    • Poprawiona wydajność planowania zadań na procesorach AMD z mikroarchitekturą Zen, które zapewniają wiele pamięci podręcznej ostatniego poziomu (LLC) dla każdego węzła z lokalnymi kanałami pamięci. Nowa wersja eliminuje brak równowagi LLC pomiędzy węzłami NUMA, co doprowadziło do znacznego wzrostu wydajności dla niektórych typów obciążeń.
    • Rozszerzono narzędzia do śledzenia aplikacji w przestrzeni użytkownika. Nowa wersja jądra dodaje możliwość tworzenia zdarzeń użytkownika przez procesy użytkownika i zapisywania danych w buforze śledzenia, które można przeglądać za pomocą standardowych narzędzi do śledzenia jądra, takich jak ftrace i perf. Zdarzenia śledzenia przestrzeni użytkownika są izolowane od zdarzeń śledzenia jądra. Status zdarzenia można zobaczyć poprzez plik /sys/kernel/debug/tracing/user_events_status, a rejestrację zdarzeń i rejestrację danych poprzez plik /sys/kernel/debug/tracing/user_events_data.
    • Dodano mechanizm monitorowania wywołań funkcji (sondowania) - fprobe. API fprobe opiera się na ftrace, ale jest ograniczone jedynie możliwością dołączenia procedur obsługi wywołań zwrotnych do punktów wejścia i wyjścia funkcji. W przeciwieństwie do kprobes i kretprobes, nowy mechanizm pozwala na użycie jednego modułu obsługi do kilku funkcji jednocześnie.
    • Zakończono obsługę starszych procesorów ARM (ARMv4 i ARMv5), które nie są wyposażone w jednostkę zarządzania pamięcią (MMU). Zachowana została obsługa systemów ARMv7-M bez MMU.
    • Zakończono obsługę architektury NDS32 podobnej do RISC, stosowanej w procesorach Andes Technologies. Kod został usunięty ze względu na brak konserwacji i brak zapotrzebowania na obsługę NDS32 w głównym jądrze Linuksa (pozostali użytkownicy korzystają ze specjalistycznych kompilacji jądra od producentów sprzętu).
    • Domyślnie budowanie jądra z obsługą formatu pliku wykonywalnego a.out jest wyłączone dla architektur alfa i m68k, które nadal korzystają z tego formatu. Prawdopodobnie wkrótce obsługa starszego formatu a.out zostanie całkowicie usunięta z jądra. O planach usunięcia formatu a.out dyskutuje się od 2019 roku.
    • Architektura PA-RISC zapewnia minimalną obsługę mechanizmu vDSO (wirtualne dynamiczne obiekty udostępnione), który zapewnia ograniczony zestaw wywołań systemowych dostępnych w przestrzeni użytkownika bez przełączania kontekstu. Obsługa vDSO umożliwiła wdrożenie możliwości działania ze stosem niewykonywalnym.
    • Dodano obsługę mechanizmu Intel HFI (Hardware Feedback Interface), który umożliwia sprzętowi przesyłanie do jądra informacji o aktualnej wydajności i efektywności energetycznej każdego procesora.
    • Dodano sterownik mechanizmu Intel SDSi (Software-Defined Silicon), który pozwala kontrolować włączenie dodatkowych funkcji w procesorze (na przykład wyspecjalizowane instrukcje i dodatkową pamięć podręczną). Pomysł jest taki, że chipy można dostarczać po niższej cenie z zablokowanymi zaawansowanymi funkcjami, które można następnie „kupić” i aktywować dodatkowe możliwości bez wymiany sprzętowej chipa.
    • Dodano sterownik amd_hsmp obsługujący interfejs AMD HSMP (Host System Management Port), który zapewnia dostęp do funkcji zarządzania procesorem poprzez zestaw specjalnych rejestrów, które pojawiły się w procesorach serwerowych AMD EPYC począwszy od generacji Fam19h. Na przykład za pomocą HSMP można uzyskać dane dotyczące zużycia energii i temperatury, ustawić limity częstotliwości, aktywować różne tryby poprawy wydajności i zarządzać parametrami pamięci.
    • Asynchroniczny interfejs we/wy io_uring implementuje opcję IORING_SETUP_SUBMIT_ALL do rejestrowania zestawu deskryptorów plików w buforze pierścieniowym oraz operację IORING_OP_MSG_RING do wysyłania sygnału z jednego bufora pierścieniowego do innego bufora pierścieniowego.
    • Mechanizm DAMOS (Data Access Monitoring-Based Operation Schemes), pozwalający na zwalnianie pamięci z uwzględnieniem częstotliwości dostępu do pamięci, posiada rozszerzone możliwości monitorowania operacji pamięciowych z przestrzeni użytkownika.
    • Trzecia seria poprawek została zintegrowana z realizacją koncepcji folio stron, które przypominają strony złożone, ale mają poprawioną semantykę i przejrzystszą organizację pracy. Korzystanie z tomów pozwala przyspieszyć zarządzanie pamięcią w niektórych podsystemach jądra. W proponowanych łatkach funkcje zarządzania pamięcią wewnętrzną zostały przetłumaczone na folio, łącznie z odmianami funkcji get_user_pages(). Zapewniono obsługę tworzenia dużych woluminów w kodzie do odczytu z wyprzedzeniem.
    • System asemblera obsługuje teraz zmienne środowiskowe USERCFLAGS i USERLDFLAGS, za pomocą których można przekazywać dodatkowe flagi do kompilatora i linkera.
    • W podsystemie eBPF mechanizm BTF (BPF Type Format), który dostarcza informacji sprawdzających typ w pseudokodzie BPF, zapewnia możliwość dodawania adnotacji do zmiennych odnoszących się do obszarów pamięci w przestrzeni użytkownika. Adnotacje pomagają systemowi weryfikacji kodu BPF lepiej identyfikować i weryfikować dostępy do pamięci.
    • Zaproponowano nową procedurę alokacji pamięci do przechowywania załadowanych programów BPF, która pozwala na bardziej efektywne wykorzystanie pamięci w sytuacjach, gdy ładowana jest duża liczba programów BPF.
    • Do wywołania systemowego madvise() dodana została flaga MADV_DONTNEED_LOCKED udostępniająca narzędzia do optymalizacji zarządzania pamięcią procesu, która stanowi uzupełnienie istniejącej flagi MADV_DONTNEED, za pomocą której jądro może być informowane z wyprzedzeniem o zbliżającym się zwolnieniu bloku pamięci, tj. że ten blok nie jest już potrzebny i może być używany przez jądro. W przeciwieństwie do MADV_DONTNEED, użycie flagi MADV_DONTNEED_LOCKED jest dopuszczalne dla stron pamięci przypiętych do RAM, które po wywołaniu madvise są usuwane bez zmiany ich statusu przypiętego, a w przypadku późniejszego dostępu do bloku i wygenerowania „strony wina” są zwracane z zachowaniem powiązania. Dodatkowo dodano zmianę umożliwiającą użycie flagi MADV_DONTNEED w przypadku stron o dużej pamięci w HugeTLB.
  • Wirtualizacja i bezpieczeństwo
    • Dla architektury x86 dodano obsługę mechanizmu ochrony przepływu poleceń Intel IBT (Indirect Branch Tracking), który zapobiega stosowaniu technik konstruowania exploitów z wykorzystaniem technik programowania zorientowanego na zwrot (ROP, Return-Oriented Programming), w którym exploit tworzony jest w postaci łańcucha wywołań istniejących już w pamięci fragmentów instrukcji maszynowych zakończonych instrukcją powrotu sterującego (z reguły są to zakończenia funkcji). Istotą realizowanego sposobu zabezpieczenia jest blokowanie pośrednich przejść do treści funkcji poprzez dodanie na początku funkcji specjalnej instrukcji ENDBR i umożliwienie wykonania przejścia pośredniego jedynie w przypadku przejścia do tej instrukcji (pośrednie wywołanie przez JMP i CALL musi zawsze spaść na instrukcję ENDBR, która jest umieszczona na samym początku funkcji).
    • Włączono bardziej rygorystyczne sprawdzanie granic buforów w funkcjach memcpy(), memmove() i memset(), wykonywane w czasie kompilacji, gdy włączony jest tryb CONFIG_FORTIFY_SOURCE. Dodana zmiana sprowadza się do sprawdzenia, czy elementy konstrukcji o znanej wielkości wykraczają poza granice. Należy zauważyć, że zaimplementowana funkcja umożliwiłaby blokowanie wszystkich przepełnień bufora jądra związanych z memcpy() zidentyfikowanych w ciągu co najmniej ostatnich trzech lat.
    • Dodano drugą część kodu do zaktualizowanej implementacji generatora liczb pseudolosowych RDRAND, który odpowiada za działanie urządzeń /dev/random i /dev/urandom. Nowa implementacja wyróżnia się ujednoliceniem działania /dev/random i /dev/urandom, dodaniem ochrony przed pojawieniem się duplikatów w strumieniu liczb losowych podczas uruchamiania maszyn wirtualnych oraz przejściem na używanie funkcji skrótu BLAKE2s zamiast SHA1 dla Operacje mieszania entropijnego. Zmiana poprawiła bezpieczeństwo generatora liczb pseudolosowych poprzez wyeliminowanie problematycznego algorytmu SHA1 oraz wyeliminowanie nadpisania wektora inicjującego RNG. Ponieważ algorytm BLAKE2s jest lepszy pod względem wydajności od SHA1, jego użycie miało również pozytywny wpływ na wydajność.
    • Dla architektury ARM64 dodano obsługę nowego algorytmu uwierzytelniania wskaźników – „QARMA3”, który jest szybszy od algorytmu QARMA przy zachowaniu odpowiedniego poziomu bezpieczeństwa. Technologia pozwala na wykorzystanie specjalistycznych instrukcji ARM64 do weryfikacji adresów zwrotnych za pomocą podpisów cyfrowych, które są przechowywane w nieużywanych górnych bitach samego wskaźnika.
    • Dla architektury ARM64 zaimplementowano obsługę montażu z włączeniem w GCC 12 trybu zabezpieczenia przed nadpisaniem adresu zwrotnego z funkcji w przypadku przepełnienia bufora na stosie. Istotą zabezpieczenia jest zapisanie adresu zwrotnego na osobnym stosie „cienia” po przekazaniu sterowania do funkcji i odzyskaniu tego adresu przed wyjściem z funkcji.
    • Dodano nowy brelok - „maszyna”, zawierający klucze właściciela systemu (MOK, Machine Owner Keys), obsługiwany w bootloaderze podkładki. Kluczy tych można używać do cyfrowego podpisywania komponentów jądra ładowanych na etapie po uruchomieniu (na przykład modułów jądra).
    • Usunięto obsługę asymetrycznych kluczy prywatnych dla modułów TPM, które były oferowane w starszej wersji modułu TPM, wiązały się ze znanymi problemami związanymi z bezpieczeństwem i nie były powszechnie stosowane w praktyce.
    • Dodano ochronę danych typu size_t przed przepełnieniem liczb całkowitych. Kod zawiera procedury obsługi size_mul(), size_add() i size_sub(), które umożliwiają bezpieczne mnożenie, dodawanie i odejmowanie rozmiarów za pomocą typu size_t.
    • Podczas budowania jądra włączone są flagi „-Warray-bounds” i „-Wzero-length-bounds”, które wyświetlają ostrzeżenia, gdy indeks wykracza poza granicę tablicy oraz gdy używane są tablice o zerowej długości.
    • Urządzenie virtio-crypto dodało obsługę szyfrowania przy użyciu algorytmu RSA.
  • Podsystem sieciowy
    • Przy realizacji mostów sieciowych dodano obsługę trybu wiązania portów (tryb zablokowany), w którym użytkownik może przesyłać ruch przez port wyłącznie z autoryzowanego adresu MAC. Dodano także możliwość wykorzystania kilku struktur do oceny stanu protokołu STP (Spanning Tree Protocol). Wcześniej sieci VLAN można było mapować wyłącznie bezpośrednio na protokół STP (1:1), przy czym każda sieć VLAN była zarządzana niezależnie. Nowa wersja dodaje parametr mst_enable, po włączeniu stan sieci VLAN jest kontrolowany przez moduł MST (Multiple Spanning Trees), a powiązanie sieci VLAN może odpowiadać modelowi M:N.
    • Kontynuowano prace nad integracją narzędzi ze stosem sieciowym w celu śledzenia przyczyn upuszczania pakietów (kodów przyczyny). Kod przyczyny jest wysyłany, gdy pamięć związana z pakietem zostanie zwolniona i uwzględnia takie sytuacje, jak odrzucenie pakietu z powodu błędów nagłówka, wykrycie fałszowania rp_filter, nieprawidłowa suma kontrolna, brak pamięci, wyzwolenie reguł IPSec XFRM, nieprawidłowy numer sekwencyjny TCP itp.
    • Możliwe jest przesyłanie pakietów sieciowych z programów BPF uruchamianych z przestrzeni użytkownika w trybie BPF_PROG_RUN, w którym programy BPF są wykonywane w jądrze, ale wynik zwracają do przestrzeni użytkownika. Pakiety przesyłane są za pomocą podsystemu XDP (eXpress Data Path). Obsługiwany jest tryb przetwarzania pakietów na żywo, w którym procesor XDP może przekierowywać pakiety sieciowe w locie do stosu sieciowego lub do innych urządzeń. Możliwe jest także tworzenie programowych generatorów ruchu zewnętrznego lub zastępczych ramek sieciowych w stosie sieciowym.
    • Dla programów BPF dołączonych do grup sieciowych zaproponowano funkcje pomocnicze, które jawnie ustawiają wartość zwracaną wywołań systemowych, co pozwala na przekazanie pełniejszej informacji o przyczynach blokowania wywołania systemowego.
    • Podsystem XDP (eXpress Data Path) dodał obsługę pofragmentowanych pakietów umieszczonych w wielu buforach, co pozwala na przetwarzanie ramek Jumbo w XDP i wykorzystanie TSO/GRO (TCP Segmentation Offload/Generic Odbiór Offload) dla XDP_REDIRECT.
    • Proces usuwania sieciowych przestrzeni nazw został znacznie przyspieszony, co było pożądane w niektórych dużych systemach o dużym natężeniu ruchu.
  • Sprzęt
    • Sterownik amdgpu domyślnie zawiera technologię adaptacyjnej synchronizacji FreeSync, która pozwala dostosować częstotliwość odświeżania informacji na ekranie, zapewniając płynny i pozbawiony łez obraz podczas grania w gry i oglądania filmów. Ogłoszono, że obsługa GPU Aldebaran jest stabilna.
    • Sterownik i915 dodaje obsługę chipów Intel Alderlake N i dyskretnych kart graficznych Intel DG2-G12 (Arc Alchemist).
    • Sterownik nouveau zapewnia obsługę wyższych przepływności dla interfejsów DP/eDP oraz obsługę przedłużaczy kabli lttprs (Link-Training Tunable PHY Repeaters).
    • W podsystemie drm (Direct Rendering Manager) w sterownikach armada, exynos, gma500, hyperv, imx, ingenic, mcde, mediatek, msm, omap, rcar-du, rockchip, sprd, sti, tegra, tilcdc, xen i obsługa parametrów vc4 dodano nomodeset, który pozwala wyłączyć przełączanie trybów wideo na poziomie jądra i korzystanie z narzędzi sprzętowego przyspieszania renderowania, pozostawiając jedynie funkcjonalność związaną z systemowym buforem ramki.
    • Dodano obsługę procesorów ARM SoС Qualcomm Snapdragon 625/632 (używanych w smartfonach LG Nexus 5X i Fairphone FP3), Samsung Exynos 850, Samsung Exynos 7885 (używanych w Samsungu Galaxy A8), Airoha (Mediatek/EcoNet) EN7523, Mediatek mt6582 (Prestigio PMT5008 tablet 3G), Microchip Lan966, Renesas RZ/G2LC, RZ/V2L, Tesla FSD, TI K3/AM62 i i.MXRTxxxx.
    • Dodano obsługę urządzeń i płyt ARM firm Broadcom (Raspberry Pi Zero 2 W), Qualcomm (Google Herobrine R1 Chromebook, SHIFT6mq, Samsung Galaxy Book2), Rockchip (Pine64 PineNote, Bananapi-R2-Pro, STM32 Emtrion emSBS, Samsung Galaxy Tab S , tablet Prestigio PMT5008 3G), Allwinner (A20-Marsboard), Amlogic (Amediatek X96-AIR, CYX A95XF3-AIR, Haochuangy H96-Max, Amlogic AQ222 i OSMC Vero 4K+), Aspeed (Quanta S6Q, ASRock ROMED8HM3), Marvell MVEBU / Armada (NAS Ctera C200 V1 i V2), Mstar (DongShanPiOne, Miyoo Mini), NXP i.MX (Protonic PRT8MM, emCON-MX8M Mini, Toradex Verdin, Gateworks GW7903).
    • Dodano obsługę systemów dźwiękowych i kodeków AMD PDM, Atmel PDMC, Awinic AW8738, i.MX TLV320AIC31xx, Intel CS35L41, ESSX8336, Mediatek MT8181, nVidia Tegra234, Qualcomm SC7280, Renesas RZ/V2L, Texas Instruments TAS585M. Dodano wstępną implementację sterownika dźwięku dla układu Intel AVS DSP. Zaktualizowano obsługę sterowników dla Intel ADL i Tegra234 oraz wprowadzono zmiany w celu poprawy obsługi dźwięku w urządzeniach Dell, HP, Lenovo, ASUS, Samsung i Clevo.

    W tym samym czasie Latin American Free Software Foundation stworzyła wersję całkowicie darmowego jądra 5.18 - Linux-libre 5.18-gnu, oczyszczoną z elementów oprogramowania sprzętowego i sterowników zawierających niewolne komponenty lub sekcje kodu, których zakres jest ograniczony przez producenta. Nowa wersja czyści sterowniki dla paneli MIPI DBI, VPU Amphion, WiFi MediaTek MT7986 WMAC, Mediatek MT7921U (USB) i Realtek 8852a/8852c, układów dźwiękowych Intel AVS i Texas Instruments TAS5805M. Pliki DTS zostały również oczyszczone dla różnych układów Qualcomm SoC z procesorami opartymi na architekturze AArch64. Zaktualizowano kod czyszczenia obiektów blob w sterownikach i podsystemach procesorów graficznych AMD, MediaTek MT7915, Silicon Labs WF200+ WiFi, Mellanox Spectru Ethernet, Realtek rtw8852c, Qualcomm Q6V5, Wolfson ADSP, MediaTek HCI UART.

Źródło: opennet.ru

Dodaj komentarz