|
|
^ Blog index    << Preprocessor C - zaawans. wykorzystanie    >> Broadcom ViceoCoreIV 3D - budowa z perspektywy GPGPU
Układ System on Chip Broadcom BCM2835 (BCM2836, BCM2837) w Raspberry Pi
2017-07-19    dr inż. Piotr Romaniuk
Spis treści
Wstęp
Architektura w zarysie,
VPU i trochę historii,
QPU i potok grafiki 3D,
CPU
Peryferia
Bootowanie & bare metal,
Linki
Wstęp
Płytki Raspberry Pi wykorzystują niezwykle ciekawy, wieloprocesorowy układ typu System On Chip (SoC) wyprodukowany przez firmę Broadcom.
W kolejnych wersjach płytki używane są niewiele różniące się odmiany układu, oznaczone symbolami BCM2835, BCM2836 i BCM2837.
Układy te są procesorami multimediów (Multimedia Processor), tzn. zawierają w sobie procesor aplikacji oraz dużo sprzętu wspomagającego
przetwarzanie multimediów (np. de/kompresja video), który występuje pod nazwą VideoCore IV.
Niestety producent nie udostępnia pełnej dokumentacji tego układu (t.j. BCM283x), a poszukiwanie po symbolu na stronach Broadcom kończy się
komunikatem "No results found".
Użytkownik dostaje działający Linux na ARMie (główny procesor układu BCM283x) i dość zagadkowy, wieloetapowy proces bootowania,
w którym ładowane są binarne fragmenty kodu z karty SD poprzedzające uruchomienie kernela systemu.
Okazuje się jednak, że materiały o tym układzie można znaleźć w Internecie. Przypomina to trochę składanie (rekonstrukcję) wazy z kilku łupin
i bardziej kojarzy się z archeologią, daje jednak możliwość lepszego poznania i wykorzystania układu.
Najlepszą stroną jest niewątpliwie strona programisty występującego pod pseudonimem Herman H. Hermitage, który zrobił
wiele w zakresie przybliżenia struktury układu. Na stronie github, w jego profilu uzmieszczone jest zdjęcie Konrada Zuse - niemieckiego wynalazcy i prekursora informatyki z czasów II. wojny światowej. Co ciekawe, współczesny programista stworzył też "swój" profil na linkedin.
Niniejsza strona powstała z ogólnie dostępnych materiałów w Internecie. Materiały tu zamieszczone i wskazywane odnośniki mogą być przydatne do wprowadzenia modyfikacji procesu bootowania - np. gdy potrzebna jest
szybka reakcja po włączeniu zasilania, zanim jeszcze uruchomi się Linux. Drugim zastosowaniem może być akceleracja obliczeń
z wykorzystaniem procesora graficznego. Można sobie też wyobrazić uruchomienie odrębnego mikrokernela na VPU do jakiś specyficznych zastosowań
(w rzeczywistości to się już dzieje, jest tam bowiem uruchomiony program, pod kontrola systemu ThreadX, kontrolujący działanie części graficznej).
Architektura układu w zarysie
W dużym skrócie architekturę układu można przedstawić poniższym diagramem:
Rys.1 Architektura układów BCM283x
gdzie:
- CPU - Host processor - główny procesor o architekturze ARM, na którym pracuje Linux
- VPU x2 - dwurdzeniowy procesor do przetwarzania multimediow
- QPU x4x4- zestaw procesorów, cześć potoku do grafiki 3D (3D pipeline).
- Peripherals - peryferia typu gpio, spi, uart, pwm itp.
- LPDDR2 - kontroler pamięci SDRAM
- DMA - kontroler DMA
- ISP - korekcja zniekształceń soczewek kamery
- Cache L2 - pamięć cache, poziom 2.
- AXI/ARB System Bus - magistrala łącząca poszczególne bloki
VPU i trochę historii
Układ BCM283x jest procesorem multimediów. W jego skład wchodzi dwurdzeniowy procesor VPU, który wydaje się być nieudokumentowany.
Jest on o tyle ważny, że właśnie od niego zaczyna się proces bootowania, to on inicjalizuje dostęp do SDRAMu i uruchamia procesor ARM.
Podczas późniejszej pracy VPU jest używany do przetwarzania multimediów (w tym video).
Jego konstrukcja pochodzi z firmy Alphamosaic Ltd, która to firma została wykupiona przez Broadcom w 2004r.
Autorzy architektury VPU opatentowali (na co zwrócił uwagę "H.Hermitage") wiele rozwiązań zastosowanych w tym procesorze, dzięki czemu można poznać jego budowę.
Rys.2 Architektura pojedynczego rdzenia VPU - rys z patentu US7043618
To źródło oraz trochę eksperymentów doprowadziło grupę zainteresowanych programistów do stworzenia narzędzi (kompilator GNU języka C, assembler, itp.) i dość bogatego opisu samego procesora VPU:
QPU i potok grafiki 3D
Najlepiej udokumentowanym elementem układu jest jego część wykorzystywana do grafiki 3D. Producent udostępnił dokumentację,
opisującą architekturę potoku przetwarzania grafiki, dokładny opis rdzeni QPU oraz wiele szczegółów jego wykorzystania:
Ten fragment układu, oprócz zgodnego z głównym przeznaczeniem zastosowania do grafiki 3D, może być też wykorzystywany
do obliczeń równoległych wspomagających CPU (GPGPU). W tym celu warto zapoznać się z:
- "Hacking the GPU for Fun and Profit" - przedstawiający podstawy programowania QPU, od minimalnego hello-world do obliczania SHA-256
(kod źródłowy do artykułu). Zawiera własny niepełny assembler.
- Obliczanie FFT - pełny kod ilustrujący zaawansowane techniki programowania QPU: uruchamianie programów na QPU z poziomu C,
różne metody przekazywanie danych, synchronizacja rdzeni, rozróźnianie programów dla rdzeni, wywoływanie podprogramów, wpływ potoku QPU, wykorzystanie makroasemblera. Źródła są w umieszczone w Raspbianie w /opt/vc/src/hello_pi/hello_fft i są częścią repozytorium firmware.
Jest tam dostępny kod shaderów - binarny kod dla QPU oraz ich źródła. Można pokusić się o samodzielne budowanie tej cześci. Należy do tego użyć makroasembler VC4ASM. Kod binarny QPU z firmware'u i skompilowany makroasemblerem (wersja 0.2.3) ma drobne,
nieistotne różnice binarne, nie wypływające na działanie - innym poleceniem są zerowane rejestry.
- VC4ASM (Marcel Muller) - najlepszy makroasembler dla QPU (projekt na github). Budowanie makroasemblera na raspberry-pi jest trywialne, pod windows wymaga paru poprawek kodu i konfiguracji (można zbudować pod MinGW albo Cygwin). Budowanie pod inny Linux niż Raspbian wymaga odpowiednio nowego kompilatora C++0x11.
- QPULib - definicja języka procesora QPU (analogia do CUDA) oraz jego kompilator budujący w czasie działania programy dla QPU. Całość
opiera się nowych typach danych, szablonach C++ oraz kompilacji przez wykonanie programu kernela (kernela dla QPU, a nie Linuxa) na CPU z przeciążonymi operatorami - dzięki czemu tworzy się Abstract Syntax Tree, które jest następnie kompilowane do kodu QPU.
- PyVideoCore (Koichi Nakamura) - biblioteka GPGPU dla Pythona
CPU
Układy BCM283x jako podstawowy procesor, na którym pracuje Linux, wykorzystuja rożne rodzaje procesora ARM (zobacz wersje i różnice).
Konkretny opis każdego rodzaju procesora ARM można znaleźć na stronach ARM Infocenter.
Dodatkowo na stronach raspberrypi.org można znaleźć opis przerwań i synchronizacji wielu rdzeni w BCM2836
Peryferia
BCM283x jest wyposażony w wiele układów peryferyjnych takich jak:
- porty szeregowe UART, SPI, I2C (nazywany w dokumentacji: BSC - Broadcom Serial Controller)
- GPIO
- External MMC
- PCM/I2S
- PWM
- Timery
- USB
Opis tych peryferiów można znaleźć w dokumencie: BCM2835 Peripherals. Jest też tam opisany kontroler przerwań, wzajemne zależności przesterzeni adresowych VPU i CPU (w tym adresy fizyczne i virtualne) oraz DMA.
Bootowanie & Bare metal
Proces bootowania rozpoczyna się w ROMie układu SoC. Kod jest wykonywany przez procesor VPU, podczas gdy CPU jest utrzymywany w resecie
(jest zablokowany). Pomijając bootowanie z różnych źródeł (zobacz opis na stronie raspberry.org),
wczytywany jest program bootcode.bin do pamięci RAM (Cache L2) i uruchamiany. Program ten odpowiada za inicjalizację SDRAM, konfigurację zegara oraz
uruchomienie CPU. Następnie uruchamiany jest start.elf, który wykorzystując config.txt, cmdline.txt uruchamia kernel.img (czyli startuje Linux)
Bootcode.bin, start.elf sa dostarczone w postaci binarnej. Niemniej jednak, istnieją próby ich zastąpienia oraz uruchomienia własnego kodu:
Linki
[1] Repozytorium Raspberry Pi zawierające źródła Linuxa, binarne pliki firmware'u, userspace'owe źrodła bibliotek zapewniające interface do QPU, instalator NOOBs, itp.
[2] "RPi Hub" - Raspberry Pi Wiki zawierające dużo informacji o płytce Raspberry Pi
[3] BCM2835 Datasheet Errata
|
|