Framebuffer console na telefonie z Androidem (Snapdragonie)
10.03.2021 | aktual.: 13.03.2021 12:02
Prawdopodobnie większość osób interesujących się linuksem wie o tym, że podczas bootowania system ten wyświetla komunikaty o zidentyfikowanym sprzęcie, systemach plików itd. Możliwe jest uzyskanie takiego samego efektu na urządzeniach z androidem (lub innych urządzeniach opartych o SoC MSM). Nie zawsze jest to proste.
Sony E1 (MSM8x10) z Linux 3.4.113, funkcja kernel_init rozpoczyna inicjalizację urządzeń, później uruchamia skrypt określony poprzez parametr init=, tak jak widać na zdjęciu, jest pewien problem w mdss_fb_probe
Po co?
Napewno takie rozwiązanie ułatwia debuggowanie. Oprócz framebuffer console mamy również pstore, uart poprzez port usb (jeśli Micro-USB IC na to pozwala), android ram console (później zostało usunięte ponieważ ma taką samą funkcjonalność jak pstore). Pstore wymaga od nas aby urządzenie mialo persistent ram, czyli taka pamięć ram, która jest zachowywana po ponownym uruchomieniu. Można skonfigurować też w inny sposób, aby linuks korzystał tylko z danego obszaru pamięci, a inny obszar jest zarezerwowany dla pstorefs. Później zostało dodane pstore_blk, chyba niedawno. Możemy więc użyć partycji do przechowywania dump'ów.
Jeżeli chcemy, aby w przypadku jakiegoś niepowodzenia system "spanikował" wystarczy dodać do modułu następującą linijkę:
panic("Nie można zarezerwować pamięci dla framebuffer!");
Aby framebuffer console działał i wyświetlał się na ekranie, musimy usunąć z device tree sources (arch/$ARCH/boot/dts) odniesienia do qcom,cont-splash-enabled oraz skompilować linuksa z odpowiednimi ustawieniami. Trzecim krokiem będzie zmodyfikowanie MSM FB driver tak aby wspierał FB console (to nie jest zawsze konieczne).
MDSS to display controler mojego urządzenia. Możemy użyć albo sterownika od CAF, albo mainline'owego, który został dodany w 2013r. Drugi wspomniany sterownik wydaje się mieć wsparcie dla fbconn.
1. Będąc w boot/dts trzeba uruchomić komendę poniżej, albo zrobić to samemu ręcznie
for i in *; do sed -i 's/qcom,cont-splash-enabled//g'
2. Aby ustawić wsparcie dla framebuffer:
(zmienna ARCH służy do określenia architektury systemu)
export ARCH=arm export CROSS_COMPILE=/path/do/arm-eabi-x.x/bin/arm-eabi- make tw_urzadzenie_defconfig make menuconfig
Następnie w menu przejść do drivers -> character devices i dodać wsparcie dla Virtual terminal. Później w graphics support dodać Framebuffer console, zaznaczyc opcję aby automatycznie zmapował do pierwszego wyświetlacza, oraz opcje do mozliwości obrócenia ekranu. PostmarketOS community twierdzi, że sterowniki MSM 3D i 2D mogą sprawiać, że framebuffer może nie działać prawidłowo1.
3. Huawei y530 ma taki sam Soc, jaki jest w moim telefonie Sony, udało im się uruchomić framebuffer na Huaweiu zmieniając odpowiednio niektóre fragmentu kodu2. Zaaplikowałem te patche do swojego kernela.
Największy problem leży w tym, że sterownik framebuffer MSM jest (i działa), ale nie jest przystosowany do fbcon. Trzeba zrobić zmiany w kodzie, ukazany pod tym commitem.
Po dodaniu tego kodu musimy włączyć "CONFIG_FB_MSM_CONSOLE".
Kiedy uruchomimy urządzenie z "console=tty0,115200 fbcon=font:VGA8x8" będziemy już wszystko widzieć. Możemy użyć "fbcon=rotate:1", aby widok był poziomy.
Logo producenta jest wyświetlone przez bootloader, qcom,cont-splash-enabled powoduje, że urządzenie nic nie wyświetla podczas rozruchu (później podobnym sposobem taka blokada jest wyłączana). Na samsungach kiedy wyłączymy tą opcje z dts, będziemy widzieć napis "ODIN mode" z różnymi informacjami. Zupełnie tak jak w download mode, tyle że po środku ekranu jest logo producenta, zamiast powiadomienia z download mode.
Wcześniej msm_fb miało natywne wsparcie dla framebuffer console. Tak jest przynajmniej w android-msm-2.6.35. Wskazują na to przede wszystkim członkowie struktury mdss_fb_ops. Historia dla tego repo jest bardzo krótka, znalazłem commit mówiący o tym, że fbcon w zamyśle miał działać. Wciąż poszukuję commitu, w którym wsparcie dla fbcon mogło zostać usunięte, aby tą zmiane "odwrócić".
Sony wyrzuca mnóstwo błędów prawdopodobnie przez to, że jeden z pointerów, do którego nowo dodane funkcje sie odnoszą ma wartość równą NULL. Kiedy będę miał sprawny framebuffer console (albo ogarnę pstore) będę mógł zabrać się za portowanie innych urządzeń na nowszego linuksa (spróbuję na mainline). Telefon może nie uruchamiać się przez milion powodów i jeśli nie mam z nim kontaktu poprzez serial port, nie wiem co sie z nim dzieje. Aby telefon uruchomił pełnego androida (nawet bez wsparcia dla grafiki) potrzeba bardzo dużo. Nie chodzi tutaj nawet o sensory, ponieważ telefon bez touchscreen, aparatu, kompasu, czujnika jaśności i wszystkich innych urządzeń, i tak uruchomi się. Potrzebny jest devicetree blob i sparcie dla chipsetu. msm‑3.10 ma wsparcie dla 8x10, ma oczywiście msm SDHCI, dodałem device tree, a i tak nie uruchamia się. Teoretycznie wszystko co jest potrzebne do uruchomienia, jest obecne.
Sterownik mdss jest aktywnie poprawiany, widać, że w ciągu 2015-2017 znaleziono wiele błędów takich jak race condition, NULL pointer dereference, buffer overflow. Sądzę, że przez te (juz wykryte) błędy telefon nie chce uruchomić się.
Długo mnie nie było, i nie będzie. Sporo kodu do msm nie jest dobrze udokumentowana. diagchar może też sie okazać czymś pomocnym do debuggowania. Mam nadzieję, że komuś pomogłem tym wpisem :)