Emulator konsoli NES w systemie Linux na komputerze SoMLabs VisonSOM

W portfolio większości elektroników/programistów bez trudu odnajdziemy hobbystyczne projekty, których finalna wartość użytkowa – zwłaszcza w stosunku do przeznaczonego na projekt nakładu pracy i środków – jest co najmniej dyskusyjna. Dlaczego zatem kosztem wolnego czasu decydujemy się realizować takie projekty? Niech najprostszym wyjaśnieniem będzie to, że wraz z upływem lat wciąż nie wyrastamy z hasła „nauka poprzez zabawę”, a hobbystycznie realizowane projekty mogą być dobrym ładunkiem praktycznej wiedzy, którą z powodzeniem wykorzystamy w życiu zawodowym.

W artykule, na przykładzie komputera VisionSOM (z procesorem NXP i.MX6 ULL Cortex-A7) firmy SoMLabs, wyposażonego w dedykowany moduł wyświetlacza LCD-TFT, uruchomiony zostanie emulator konsoli Famicon/NES (w Polsce znanej głównie dzięki klonowi oryginalnego projektu – konsoli Pegasus). Aby zwiększyć walor dydaktyczny projektu oraz pod kątem grywalności jak najbardziej zbliżyć się do wspomnień z minionych lat, sterowanie za pomocą tradycyjnej klawiatury zastąpiono podłączeniem i konfiguracją kontrolera konsoli Playstation 3/4 oraz prostym prototypem własnego 8-przyciskowego gamepada (co pozwoli również na zapoznanie się z konfiguracją magistrali SPI oraz wyprowadzeń GPIO w systemie Linux).
Zaczynajmy więc…

Przygotowanie karty z systemem Debian

Do budowy emulatora konsoli Famicon/NES wykorzystamy moduł komputera VisionSOM wyposażony w gniazdo karty pamięci SD (fotografia 1). Prace nad projektem rozpoczną się od przygotowania karty z systemem operacyjnym Linux. Producent komputera – firma SoMLabs – na stronach Wiki swojego produktu dostarcza użytkownikowi wsparcie w postaci gotowych obrazów z dystrybucją Debian oraz opisem budowy obrazów z wykorzystaniem takich narzędzi jak Buildroot oraz Yocto.

Fot. 1. Wygląd modułu VisionSOM-6ULL w wersji z kartą MicroSD

Przy wstępnym wyborze odpowiedniej dystrybucji lub narzędzi do budowy obrazu, pomocne jest jasne określenie celu projektu. Jeżeli finalnym celem projektu jest zbudowanie jak najwierniejszej kopii samej konsoli (z minimalnym obrazem systemu, wyposażonym wyłącznie w niezbędne oprogramowanie umożliwiające uruchomienie emulatora bezpośrednio po starcie urządzenia), wówczas zalecaną opcją jest wykorzystanie narzędzia Buildroot. Jeśli natomiast chcemy osiągnąć docelowy efekt jak najmniejszym nakładem pracy, a sam komputer jednopłytkowy ma pełnić również inne funkcje (np. korzystamy z pełnego środowiska graficznego, a emulacja konsoli NES jest wyłącznie dodatkową opcją), warto jest skorzystać z gotowych pakietów środowiska Debian – pozwoli to uniknąć m.in. samodzielnej kompilacji oprogramowania emulatora. W artykule wykorzystano drogę „na skróty” i użyto gotowych obrazów z dystrybucją Debian (autor na własnym przykładzie przekonał się, że wybór drugiej ścieżki jest bardziej „optymalny” – zaoszczędzony czas można wówczas poświęcić na „testowanie” projektu i radosny powrót do czasów dzieciństwa). Przygotowanie karty SD rozpoczynamy od pobrania obrazu systemu. W środowisku Linux operację tę można zrealizować poleceniem:

Po pobraniu pliku rozpakujmy jego zawartość za pomocą narzędzia unxz:

Przed przystąpieniem do dalszych prac, warto również sprawdzić integralność pobranych danych poprzez obliczenie sumy kontrolnej SHA256 i porównanie jej z informacjami udostępnianymi na stronie producenta:

Po pobraniu oraz rozpakowaniu pliku, możemy przystąpić do wgrania obrazu systemu na kartę micro-SD. Jedną najprostszych metod zapisania obrazu z pliku jest wykorzystanie linuksowego narzędzia dd. Ogólna składnia polecenia dd może może zostać zapisana następująco:

Plik wejściowy polecenia (if – Input File) będzie stanowił pobrany w uprzednim kroku obraz systemu debian-stretch-visionsom-6ull.img. Plik wyjściowy (of – Output File) to umieszczona w czytniku i podłączona do komputera karta SD, która jest reprezentowana w systemie jako plik specjalny w katalogu /dev. W celu zweryfikowania, który wpis jest odpowiedzialny za podłączone urządzenie, korzystając z terminala systemowego możemy wydać polecenie dmesg, które wyświetli komunikaty wypisywane w buforze komunikatów jądra, w tym informacje o ostatnio podłączonych urządzeniach, np:

W powyższym przypadku wpis /dev/sdb odnosi się do całej karty SD, natomiast wpisy /dev/sdb1, /dev/sdb2, dev/sdbX – do kolejnych partycji urządzenia, o ile zostały one uprzednio utworzone. W przypadku wykorzystania czytnika kart wbudowanego w komputer PC, sterownik urządzenia może zarejestrować kartę SD w postaci pliku o nazwie /dev/mmcblk0.

Polecenia dd używamy korzystając z praw administratora, tak więc należy bezwzględnie upewnić się, że wprowadzono poprawną wartość dla pliku wyjściowego. Błędnie określenie wyjścia może spowodować nadpisanie danych na głównym dysku użytkownika. Z powodu pomyłek, akronim narzędzia dd jest czasem rozwijany do „destroy disk” lub „delete data”. Poprawne określenie pliku wyjściowego reprezentującego podłączoną do czytnika kartę SD, pozwala na ostateczne określenie formy polecenia dd:

Powyższe polecenie skopiuje obraz debian-stretch-visionsom-6ull.img na wskazaną kartę SD. Dodatkowe parametry polecenia dd określają zapis w blokach po 4 MB (bs – Block Size) w sposób synchroniczny (bez buforowania). Ponieważ polecenie dd nie umożliwia nam monitorowania postępu zapisu danych na kartę SD, co w zależności od wielkości obrazu systemu może być dość czasochłonne, wygodnym rozwiązaniem jest wykorzystanie narzędzia pv, które wyświetla informacje o postępie odczytu danych z pliku. Przykładowa składnia polecenia z wykorzystaniem narzędzia pv, wygląda następująco:
Po wgraniu obrazu na kartę, do konsoli systemu możemy zalogować się wykorzystując wbudowany w płytę bazową VisionCB-STD konwerter UART-USB oraz dowolny program emulatora terminalu:
Po otwarciu połączenia należy zalogować się konto użytkownika root (bez hasła):

O autorze

Łukasz Skalski

Łukasz Skalski – absolwent Politechniki Gdańskiej, miłośnik FLOSS,
autor książki “Linux. Podstawy i aplikacje dla systemów embedded” oraz szeregu artykułów dotyczących programowania systemów wbudowanych.
Zawodowo związany z firmą Samsung. Wszystkie wolne chwile poświęca projektowaniu i programowaniu urządzeń wyposażonych w mikroprocesory 8-/16- i 32-bitowe. Szczególnym zainteresowaniem obejmuje tematykę systemu Linux w aplikacjach na urządzenia embedded.