a journey with the pyra


sebt3

homebrew player (P. & C.)
Joined
Sep 9, 2008
Messages
4,886
Age
43
Location
France
Website
sebt3.openpandora.org
To tell the truth, it's not my first day with a pyra, far from it. About a week ago I received my "proto" from ED's salvation process. It's pretty much an other device. My charging issues are gone. I have speakers ! (thanks heir dragon :) Now the device feel like it should be: robust and awesome. I've toyed with it like a anyone would. The issue is : my rootfs is not pristine anymore. Which mean I cannot test anything I could produce. bad Seb, very bad Seb :p
Today I'm fixing this.
So let's start by reflashing it to a pristine state. Following the fine instructions from the dragon (#12), I downloaded the image and uncompressed it to my second sdcard (right slot) then, I flashed it :
Code:
cd /media/seb/data32
wget https://packages.pyra-handheld.com/images/buster/pyra-38-install.img.7z
7z x pyra-38-install.img.7z
sudo dd if=pyra-38-install.img of=/dev/mmcblk3 status=progress
sudo reboot
Note : at the time of the writing 38 is the lastest image produced it could be an other version all toghether when you read this. Check the directory bellow :p

The whole process isnt that long. The longest might probably be the download. When the flashing is complete, I removed the left SDCard from it's slot and booted the pyra once again. Followed the fine 1rst run wizard. and got a pyra working once again. Setting up the wifi once again... I might setup usbnet later on, but for now as the wifi is reliable, let's just use that.
Updating the beast :
Code:
sudo apt update
sudo apt-get -y dist-upgrade

Now time for a dev environement on the pyra. First debootstraping a plain debian buster :
Code:
cd /media/seb/data32
sudo apt install -y debootstrap systemd-container
sudo mount -oremount,suid,dev /dev/mmcblk5p1
sudo debootstrap --include=systemd-container "buster" "$PWD/rootfs" "http://deb.debian.org/debian"
Note that I needed to disable some security features from udisks2. Devices are user mountable, but no executables are welcome there which wont help with a chroot.
Let's make this a pyra clone :
Code:
sudo cp /etc/hosts rootfs/etc/hosts
sudo cp /etc/apt/sources.list rootfs/etc/apt/sources.list
sudo cp /etc/apt/trusted.gpg.d/pyra-unstable.gpg rootfs/etc/apt/trusted.gpg.d/
sudo chroot ./rootfs/ apt install -y ca-certificates
sudo chroot ./rootfs/ apt update
sudo chroot ./rootfs/ apt -y dist-upgrade
apt-mark showmanual|awk '!/^lib/&&!/systemd-container/&&!/debootstrap/'|sudo chroot ./rootfs xargs apt install -y

At this point grab a coffee, last command might be a little long (especially if your sdcard is as slow as mine : installing over 2Go of debs... it's over 900 packages; took me over 2 hours).
I had dpkg issues, let's fix them and do a little configuration:
Code:
sudo chroot ./rootfs bash -l
dpkg-reconfigure -plow locales
rm -rf /var/lib/dpkg/info/udisks2.postinst
dpkg --configure udisks2
dpkg --configure -a
exit

Duplicating my user:
Code:
sudo mkdir -p rootfs/home/$(whoami)/.config/systemd/user/bamfdaemon.service.d/
sudo chown -r $(whoami):$(whoami) rootfs/home/$(whoami)
cp $HOME/.bashrc rootfs/home/$(whoami)/
echo "export DISPLAY=:0" >>rootfs/home/$(whoami)/.bashrc
echo "export PULSE_SERVER=/run/user/$(id -u)/pulse/native" >>rootfs/home/$(whoami)/.bashrc
echo "export XDG_SESSION_TYPE=X11">>rootfs/home/$(whoami)/.bashrc
cat >rootfs/home/$(whoami)/.config/systemd/user/bamfdaemon.service.d/override.conf <<END
[Service]
ExecStart=
ExecStart=/usr/libexec/bamf/bamfdaemon --display=:0
END
egrep "^$(whoami)" /etc/passwd|sudo chroot ./rootfs/ tee -a /etc/passwd
sudo egrep "^$(whoami)" /etc/shadow|sudo chroot ./rootfs/ tee -a /etc/shadow
grep "$(whoami)" /etc/group|sudo chroot ./rootfs/ tee -a /etc/group
Remove the duplicated lines using:
Code:
sudo vi rootfs/etc/group

Now I'm going to make this a nspawn container for confort:
Code:
sudo mkdir -p /etc/systemd/nspawn/ /etc/systemd/system/systemd-nspawn@dev.service.d/
sudo tee /etc/systemd/nspawn/dev.nspawn <<END
[Files]
BindReadOnly=/tmp/.X11-unix
Bind=/home/$(whoami)/.Xauthority
Bind=/run/user/$(id -u)/pulse/
Bind=/dev/dri/
[Exec]
Boot=true
Environment=DISPLAY=:0
Environment=PULSE_SERVER=/run/user/$(id -u)/pulse/native
Environment=XDG_SESSION_TYPE=X11
SystemCallFilter=add_key keyctl
END
sudo tee /etc/systemd/system/systemd-nspawn@dev.service.d/overwrite.conf<<END
[Service]
DevicePolicy=
DevicePolicy=auto
DeviceAllow=char-* rwm
ExecStartPre=mount -oremount,suid,dev /dev/mmcblk5p1
ExecStart=
ExecStart=/usr/bin/systemd-nspawn --quiet -D $PWD/rootfs --keep-unit --boot --link-journal=try-guest --settings=override --machine=%i
END
sudo systemctl daemon-reload
A fews notes for these 2 files:
- the BindReadOnly and the Bind for .Xauthority will allow acces to X11
- the Bind for dri will let me have the device files for the SGX
- while the DeviceAllow line in the second file will allow the container to interact with the SGX freely
- that ExecStartPre command will make sure the SDcard will allow binaries before stating the container (otherwise it will fail)

Starting the container is a simple:
Code:
sudo systemctl start systemd-nspawn@dev
Login into it :
Code:
sudo machinectl shell $(whoami)@dev

Let's disable some services (this command is started from within the container...) so next time we start this container it doesnt bother us with these:
Code:
sudo systemctl disable --now ssh pyrainput pyra_volumed omap5-sgx-ddk-um-linux lightdm ufw wpa_supplicant pyra-wwan pyra-thermal ModemManager NetworkManager networking lm-sensors led-config ifupdown-pre cpufrequtils
Now installing dev tools (still within that machinectl command) :
Code:
sudo apt install -y pkg-config build-essential cmake libx11-dev libdrm-dev git squashfs-tools

Fine everything is up to start building things. Let's try this container for good mesure:
Code:
mkdir -p ~/projects/estest
cd ~/projects/estest
wget https://cgit.freedesktop.org/mesa/demos/plain/src/egl/opengles1/es1_info.c
export PKG_CONFIG_PATH=/opt/omap5-sgx-ddk-um-linux/lib/pkgconfig DISPLAY=:0
gcc $(pkg-config --libs --cflags egl gles_cm) es1_info.c -o esinfo -lX11
gcc $(pkg-config --libs --cflags egl glesv2) es1_info.c -o es2info -lX11
Now starting both binaries should display you GLESv1 and GLESv2 capabilities repectivly.
Drawing ?
Code:
wget https://cgit.freedesktop.org/mesa/demos/plain/src/egl/opengles2/es2tri.c
gcc $(pkg-config --libs --cflags egl glesv2) es2tri.c -o es2tri -lX11 -lm
./es2tri
yes working ;) So the SGX can be used from this container

I've said I'll make an updated supertux dbp, let's to this :
Code:
mkdir -p ~/projects/supertux
cd ~/projects/supertux/
git clone https://github.com/SuperTux/supertux.git src
cd src;git checkout v0.6.1.1
git submodule update --init --recursive
mkdir -p ../build ../target
cd ../build
sudo apt build-dep -y supertux
sudo apt install -y libharfbuzz-dev libfribidi-dev
cmake ../src/ -DCMAKE_INSTALL_PREFIX:PATH=/mnt/dbp/union/supertux_sebt3 -DBUILD_DOCUMENTATION:BOOL=OFF -DCMAKE_STAGING_PREFIX=../target -L
make -j4
make install
Easy, right ? :p Now it's time to make the package and test it. From an other terminal (thuss outside of the container) :
Code:
ldd /media/seb/data32/rootfs/home/seb/projects/supertux/target/games/supertux2 |grep not
        libboost_filesystem.so.1.67.0 => not found
        libboost_locale.so.1.67.0 => not found
        libboost_system.so.1.67.0 => not found
        libboost_date_time.so.1.67.0 => not found
        libraqm.so.0 => not found
        libGLEW.so.2.1 => not found
That's the list of libraries to include in the dbp (and being able to run that command is pretty much the point of this whole story). So from the container terminal:
Code:
mkdir ../target/lib
cp /lib/arm-linux-gnueabihf/libboost_filesystem.so.1.67.0 /lib/arm-linux-gnueabihf/libboost_chrono.so.1.67.0 /lib/arm-linux-gnueabihf/libboost_locale.so.1.67.0 /lib/arm-linux-gnueabihf/libboost_system.so.1.67.0 /lib/arm-linux-gnueabihf/libboost_date_time.so.1.67.0 /lib/arm-linux-gnueabihf/libGLEW.so.2.1 /lib/arm-linux-gnueabihf/libraqm.so.0 ../target/lib
cat >../target/supertux.sh<< END
#!/bin/bash
root=\$(cd \$(dirname \$0);pwd)
export LD_LIBRARY_PATH=\$root/lib
export SDL_OPENGL_LIBRARY=/usr/lib/arm-linux-gnueabihf/gl4es/libGL.so.1
export XDG_DATA_HOME=\$root
exec \$root/games/supertux2 "\$@"
END
chmod 755 ../target/supertux.sh
That will fix the missing libraries. That SDL_OPENGL_LIBRARY enable gl4es usage (see: https://pyra-handheld.com/wiki/index.php?title=Using_SDL2). And that XDG_DATA_HOME will make sure the dbp will save its data where it should, not in the HOME directory.
Making the rest of the package (help can be found: https://pyra-handheld.com/wiki/index.php?title=DBP_file_format and https://pyra-handheld.com/boards/threads/creating-a-dbp-amended-instructions.76085/):
Code:
cd ~/projects/supertux
mkdir -p icons meta
cp target/share/games/supertux2/images/engine/icons/supertux.png icons/
cp target/share/applications/supertux2.desktop meta/default.desktop
cat >>meta/default.desktop <<END

[Package Entry]
Id=supertux_sebt3
Arch=armhf
Exec=supertux.sh
Name=SuperTux
Version=0.6.1.1
Icon=supertux.png
END
cat target/share/applications/supertux2.desktop >>meta/default.desktop
sed -i 's/^Exec=.*/Exec=supertux.sh/' meta/default.desktop
zip -Z store -r target.zip meta icons
mksquashfs target target.squash -all-root -force-gid 0
cat target.squash target.zip > supertux.dbp
zip -A supertux.dbp

Since screenshots are usefull, still in the container, I installed :
Code:
sudo apt install graphicsmagick-imagemagick-compat
To take a screenshot :
Code:
import -window root ~/supertux.png
 
Last edited:
Nobody replied here. Great, let's make this thread a blog then :p

Now that supertux is done. Let's tacke something a little more challanging. (still withing my container see post#1)
I forgot to say something in the previous episode. You get the end result documented here. Obviously, there are many experiments/tests inbetween
For today's target, we'll need some more -dev packages, let's install them
Code:
sudo apt install -y libssl-dev libavutil-dev libavformat-dev libavcodec-dev libavdevice-dev libavresample-dev libswscale-dev libxkbcommon-dev zlib1g-dev libfreetype6-dev libgbm-dev libavcodec-dev libsdl2-dev libxml2-dev yasm

Let's start the next project :
Code:
mkdir ~/projets/retroarch
cd ~/projets/retroarch
git clone git://github.com/libretro/libretro-super.git super
./super/libretro-fetch.sh
Warning, this is going to download every single cores sources (160 !). It's going to takes time... and space (21Gb). If you want the minimum, then use this one instead :
Code:
./super/libretro-fetch.sh retroarch
./super/libretro-fetch.sh gpsp snes9x atari800 gambatte handy mgba pcsx1 picodrive ppsspp smsplus vbam mednafen_gba mednafen_lynx mednafen_ngp mednafen_pce mednafen_pce_fast mednafen_pcfx mednafen_snes mednafen_supafaust mednafen_supergrafx mednafen_vb mednafen_wswan


Now let's create a target directory and build the main thing
Code:
mkdir -p target/mnt/dbp/union target/lib/libretro meta icons
ln -s ../../.. target/mnt/dbp/union/retroarch_sebt3
cd retroarch;git checkout v1.9.6
export PKG_CONFIG_PATH=/opt/omap5-sgx-ddk-um-linux/lib/pkgconfig
export CFLAGS="-march=native -mcpu=cortex-a15 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm -mthumb-interwork -ftree-vectorize -fsigned-char"
./configure --disable-opengl --enable-opengles --disable-wayland --disable-flac --enable-pulse --disable-builtinflac --enable-sdl2 --enable-ffmpeg --enable-zlib --enable-neon --enable-floathard --disable-vg --disable-cg --prefix=/mnt/dbp/union/retroarch_sebt3
make -j4
make DESTDIR=../target install

Compiling some cores :
Code:
for i in gpsp snes9x atari800 gambatte handy mgba pcsx1 picodrive ppsspp smsplus vbam mednafen_gba mednafen_lynx mednafen_ngp mednafen_pce mednafen_pce_fast mednafen_pcfx mednafen_snes mednafen_supafaust mednafen_supergrafx mednafen_vb mednafen_wswan;do
 super/libretro-build.sh $i
;done
cp dist/unix/* target/lib/libretro/


Let's make the packaging:
Code:
cd ~/projets/retroarch
sed -i 's!# assets_directory =.*!assets_directory = /mnt/dbp/union/retroarch_sebt3/share/retroarch/assets/!' target/etc/retroarch.cfg
sed -i 's!# libretro_directory =.*!libretro_directory = /mnt/dbp/union/retroarch_sebt3/lib/libretro/!' target/etc/retroarch.cfg
sed -i 's!# libretro_info_path =.*!libretro_info_path = /mnt/dbp/union/retroarch_sebt3/share/libretro/info/!' target/etc/retroarch.cfg
cat target/share/applications/retroarch.desktop >meta/default.desktop
cat >>meta/default.desktop <<END

[Package Entry]
Id=retroarch_sebt3
Arch=armhf
Exec=retroarch.launch
Name=RetroArch
Version=1.9.6-0
Icon=retroarch.png
END
sed -i 's/^Exec=.*/Exec=retroarch.launch/' meta/default.desktop
rm -f target.zip;zip -Z store -r target.zip meta icons
rm -f target.squash;mksquashfs target target.squash -all-root -force-gid 0
cat target.squash target.zip >target.dbp
zip -F target.dbp --out retroarch.dbp

Well that was the initial story... because it didn't worked as expected. Somehow when launching a game, it crashed. My initial assumtion was that it somehow wasnt able to load a core.
Code:
LD_DEBUG=libs ./retroarch 2>&1|grep retro
strace ./retroarch
all went to the rescue, but to no avail : nothing obvious appeared.
I installed the debian version, it had the same behaviour.
playing with it I realized that :
Code:
sudo apt install retroarch libretro-mgba
export LD_LIBRARY_PATH=/opt/omap5-sgx-ddk-um-linux/lib/
LD_PRELOAD=/opt/omap5-sgx-ddk-um-linux/lib/libGLESv2.so.1 retroarch -f -L /usr/lib/arm-linux-gnueabihf/libretro/mgba_libretro.so path/to/your/rom.gba
worked like a charm. same with my own build. So my assumtion was wrong. It's something else. Well gdb is the friend of nobody, but... no other options now...
Here is the current patch to retroarch sources
Code:
diff --git a/retroarch.c b/retroarch.c
index 417fc84930..811b45e9e2 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -30519,8 +30519,8 @@ static void video_driver_free_internal(struct rarch_state *p_rarch)
       if (p_rarch->current_input)
          if (p_rarch->current_input->free)
             p_rarch->current_input->free(p_rarch->current_input_data);
-      if (p_rarch->joypad)
-         p_rarch->joypad->destroy();
+//      if (p_rarch->joypad)
+//         p_rarch->joypad->destroy();
       p_rarch->joypad                                     = NULL;
 #ifdef HAVE_MFI
       if (p_rarch->sec_joypad)
Ok that's ugly. One should instead find out why the data was badly intialized... and that mean some memory leaks... But at least, it works :)
 
Back
Top