X69mini amlogic S905W install report

I have an cheap chinese android tv box. I have it attached to a 1080p tv
and use it to play videos from the internet. It says x96mini. It says
amlogic S905W cpu and mali450 gpu. It says it can play 4K video. It plays
480p and 720p h264 videos well. There are some problems with some other
formats. I have not tested higher resolutions.

I prefer linux to android. So I tried installing manjaro.

I made an SD card using image
https://github.com/manjaro-arm/am6-plus-images/releases/download/22.06/Manjaro-ARM-xfce-am6-plus-22.06.img.xz
and dtb amlogic/meson-gxl-s905w-p281.dtb. I do not know if other images or
dtbs would be better or worse.

To limit filesystem damage from disconnecting the power without doing a
normal shutdown, I divided the sdcard into a readonly and a readwrite
partition, and used bind mounts so that most subdirectories of the root
directory were on the readonly partition, but some subdirectories like /home
and /var were on the readwrite partition.

Usb keyboard, usb mouse, video, and sound worked. I did nothing to
configure these.

Ethernet mostly worked. Sometimes, usually about a minute after poweron,
there would be a message about disconnecting from the network, and ethernet
would not work. If I unplugged the ethernet cable and plugged it in again,
then in about 30 seconds there would be a message about connecting to the
network, and ethernet would work, and would not disconnect again.

Wifi did not work. I think the dtb does not support the wifi hardware.

The remote control did not work. I think it would work if I edit the
configuration files.

/etc/fstab has two entries for /boot. This does not seem to be a
problem.

With a fresh clean install, I tried to do pacman -Syu, and got an error
message about conflict between wireplumber and pipewire-media-session. I
got pacman -Syu to work by excluding a few things.

So there were no major problems installing manjaro on x96mini.

I tried playing videos with mpv. Quality was bad. I tried using mpv
–hwdec, top showed cpu load was a little less, but video quality did not
look better, and mpv crashed sometimes. I tried vlc, but vlc crashed
frequently. I tried changing the video mode to 720p, because lower
resolution means fewer pixels to calculate which means lower cpu load; top
showed cpu load was a little less, but video quality did not look better.

I conclude x96mini cannot play videos without using hardware decoding, and
manjaro does not have enough software support for hardware decoding. This
probably applies to all android tv boxes with mali450 GPU running all
versions of linux.

Here is a script which shows exactly how I installed manjaro:

#!/bin/bash
set -o noclobber   # display an error message and return a nonzero exit code
                   # if redirection would overwrite an existing file.
set -e    # Exit immediately if a command exits with a non-zero status
set -x  # echo all commands

URL_OF_COMPRESSED_IMAGE=https://github.com/manjaro-arm/am6-plus-images/releases/download/22.06/Manjaro-ARM-xfce-am6-plus-22.06.img.xz

DEV_OF_SDCARD=/dev/sde

# expand the readonly root partition to this size.  The size of the boot
# partition will remain unchanged.  All remaining unpartitioned space will
# become the readwrite partition.
# [size of boot partition] + [size of readonly root partition] + [size of readwrite partition] = [size of sdcard]
# Use suffixes like MiB, GiB, TiB, because sfdisk requires that.
NEW_SIZE_FOR_ROOT_PARTITION=16GiB

MOUNT_POINT=/media/x96mini

# an internet rumor said p281 is the best dtb for x96mini
# the path is relative to the boot partition
NEW_DTB=/dtbs/amlogic/meson-gxl-s905w-p281.dtb

if test "$USER" != root ; then
  echo run this script with sudo, or run as root
  exit 1
fi

wget -O - $URL_OF_COMPRESSED_IMAGE | xz --decompress | dd of=$DEV_OF_SDCARD bs=4M conv=fsync

# After writing an image with gpt partition table to a disk which is not the same size as the image,
# the backup gpt partition table at the end of the disk is no longer at the end of the disk.
# Fix the gpt partition table.
sgdisk --move-second-header $DEV_OF_SDCARD
# Some versions of some partition table programs will fix gpt partition
# tables automatically.  So this step might not be needed.

PARTITION_TYPE_FOR_LINUX=0FC63DAF-8483-4772-8E79-3D69D8477DE4
PARTITION_TYPE_FOR_WINDOWS_VFAT=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7

# the next tests should stop the script if anything is wrong
# because we do not want to change the partitions if anything is wrong
# make sure the first partition is windows vfat
test $(sfdisk --part-type $DEV_OF_SDCARD 1) = "$PARTITION_TYPE_FOR_WINDOWS_VFAT" || exit 1
# make sure the second partition is linux
test $(sfdisk --part-type $DEV_OF_SDCARD 2) = "$PARTITION_TYPE_FOR_LINUX"  || exit 1
# make sure the third partition does not exist
sfdisk --part-type $DEV_OF_SDCARD 3 &> /dev/null && exit 1

# expand root partition.  -N 2 means partition 2, which is the root partition.
# start and type are not specified, but are already set because the partition already exists, so start and type will remain unchanged.
echo "size=$NEW_SIZE_FOR_ROOT_PARTITION" | sfdisk -N 2 $DEV_OF_SDCARD
sleep 2

# create readwrite partition.  -N 3 means partition 3, which is the readwrite partition.
# start and size are not specified, and there are no previous values because the partition does not exist yet,
# so start will set to default of beginning of unpartitioned free space,
# and size will be set to default of all unpartitioned free space.
echo "type=$PARTITION_TYPE_FOR_LINUX" | sfdisk -N 3 $DEV_OF_SDCARD
sleep 2

# when sfdisk changes the partition table, sfdisk should tell the kernel to reread the
# partition table, but this sometimes fails. So we use partprobe to force the
# kernel to reread the partition table.
partprobe $DEV_OF_SDCARD
sleep 2

# after changing the size of partition 2 (the root partition), we must adjust the filesystem
# to match the partition table.
e2fsck -fp ${DEV_OF_SDCARD}2
sleep 2
resize2fs ${DEV_OF_SDCARD}2
sleep 2
e2fsck -fp ${DEV_OF_SDCARD}2
sleep 2

# make the filesystem for the readwrite partition.
mkfs.ext4 ${DEV_OF_SDCARD}3
sleep 2
e2fsck -fp ${DEV_OF_SDCARD}3
sleep 2

# mount the partitions on the sd card
mkdir --parents $MOUNT_POINT
mount ${DEV_OF_SDCARD}2 $MOUNT_POINT
mount ${DEV_OF_SDCARD}1 $MOUNT_POINT/boot
mkdir --parents $MOUNT_POINT/readwrite_partition
mount ${DEV_OF_SDCARD}3 $MOUNT_POINT/readwrite_partition



# change the *.dtb
mv $MOUNT_POINT/boot/uEnv.ini $MOUNT_POINT/boot/uEnv.ini.asoriginallyinstalled
echo "dtb_name=$NEW_DTB" > $MOUNT_POINT/boot/uEnv.ini
cat $MOUNT_POINT/boot/uEnv.ini.asoriginallyinstalled | grep --invert-match '^dtb_name=' >> $MOUNT_POINT/boot/uEnv.ini
chmod 0755 $MOUNT_POINT/boot/uEnv.ini



# move /etc/fstab to /fstab, add /readwrite_partition to fstab, make new version of fstab for readonly root filesystem
test ! -e $MOUNT_POINT/fstab.fromimage
test ! -e $MOUNT_POINT/fstab
test -e $MOUNT_POINT/etc/fstab
mv  $MOUNT_POINT/etc/fstab $MOUNT_POINT/fstab
ln -s ../fstab $MOUNT_POINT/etc/fstab
cp --archive  $MOUNT_POINT/fstab $MOUNT_POINT/fstab.fromimage

PARTUUID_OF_ROOT_PARTITION=$(lsblk --noheadings --output PARTUUID ${DEV_OF_SDCARD}2)
PARTUUID_OF_BOOT_PARTITION=$(lsblk --noheadings --output PARTUUID ${DEV_OF_SDCARD}1)
PARTUUID_OF_READWRITE_PARTITION=$(lsblk --noheadings --output PARTUUID ${DEV_OF_SDCARD}3)

echo "PARTUUID=$PARTUUID_OF_READWRITE_PARTITION   /readwrite_partition  ext4   defaults  0 2" >> $MOUNT_POINT/fstab

cat << EOF > $MOUNT_POINT/fstab.ro
PARTUUID=$PARTUUID_OF_ROOT_PARTITION   /                     ext4   ro        0 1
PARTUUID=$PARTUUID_OF_BOOT_PARTITION   /boot                 vfat   ro        0 2
PARTUUID=$PARTUUID_OF_READWRITE_PARTITION   /readwrite_partition  ext4   defaults  0 2
# use bind mounts so that /etc is /readwrite_partition/etc, /home is /readwrite_partition/home, etc
/readwrite_partition/etc  /etc  none bind 0 0
/readwrite_partition/home /home none bind 0 0
/readwrite_partition/srv  /srv  none bind 0 0
/readwrite_partition/tmp  /tmp  none bind 0 0
/readwrite_partition/var  /var  none bind 0 0
EOF



# make a script for commands which need to run on x96mini, and need to be run after first boot
test ! -e $MOUNT_POINT/s 
cat << EOF > $MOUNT_POINT/s
#!/bin/bash
set -o noclobber   # display an error message and return a nonzero exit code
                   # if redirection would overwrite an existing file.
set -e    # Exit immediately if a command exits with a non-zero status
set -x  # echo all commands

if test "$USER" != root ; then
  echo run this script with sudo, or run as root
  exit 1
fi

# copy etc,home,srv,var,tmp to the readwrite partition
cp --archive /etc /home /srv /var /tmp /readwrite_partition

# switch to the fstab for readonly root filesystem
test -e /fstab
test -e /fstab.ro
test ! -e /fstab.afterfirstboot
mv /fstab /fstab.afterfirstboot
mv /fstab.ro /fstab

echo appending new keys and disabling old keys is very slow.
echo last time there was a message about wireplumber and pipewire-media-session conflict
pacman --noconfirm -Syu # Update and upgrade package database and packages
pacman --noconfirm -S base-devel dialog ffmpeg jq kodi lynx mpv openssh rsync socat vlc  # install packages

EOF
chmod 0755 $MOUNT_POINT/s


cat << EOF

The x96mini sd card filesystems are mounted at $MOUNT_POINT
When you are done checking it, do:
   sudo umount ${DEV_OF_SDCARD}3 ${DEV_OF_SDCARD}1 ${DEV_OF_SDCARD}2

When the x96mini is booted for the first time, it will prompt to set
timezone, language, keyboard, hostname; create a user, set root password,
enable autologin.

After configuration it will prompt to reboot. Run script /s, then reboot.
Next reboot it will autologin as the user which you created.
EOF


exit


https://wiki.manjaro.org/index.php/Amlogic_TV_boxes says use am6plus or
gtkingpro image.  There are multiple am6plus and multiple gtkingpro images. 
wiki does not say how to choose image.  I chose am6plus because it was newer
than gtkingpro.  I chose xfce because I thought it was a minimal window
manager

An early version of this script ran two sfdisk commands.  The second sfdisk
failed.  I did not understand why the second sfdisk command failed, so I ran
the second sfdisk command again, and it worked.  Maybe something about the
way sfdisk reports disk changes to the kernel means there needs to be a
delay between sfdisk commands.  Maybe this depends on the sfdisk and kernel
version.  To work around this, this script runs sleep and e2fsck between
every partition change.  This makes this script slower, but more reliable. 
I was using debian 9 stretch, which is several years old. This problem might
not occur with newer versions of sfdisk and linux kernel.

I tried to make the root filesystem mostly readonly to reduce filesystem
damage from disconnecting power without shutting down linux. I partitioned the
sdcard into a readonly filesystem and and a readwrite filesystem.

The root filesystem is mounted first, and needs to have all programs,
libraries, drivers, and configuration files needed to mount the other
filesystems.  The programs, libraries, and drivers should be on the readonly
filesystem, so the readonly filesystem should be the root filesystem, with
the readwrite filesystem mounted later.

When linux boots, it mounts the readonly filesystem, and /etc is on the
readonly filesystem.  Then linux mounts the readwrite filesystem, and /etc
on the readonly filesystem is replaced by /etc on the readwrite filesystem. 
Most services do not start until after the readwrite filesystem is mounted,
so the change of /etc has no effect, only the /etc on the readwrite
filesystem is used.  However, a few files in /etc such as fstab are used
before the readwrite filesystem is mounted.  There might be consequences
from swapping to the other version when the readwrite filesystem is mounted,
especially if the two versions are not the same.

The solution used here is to move /etc/fstab to /fstab, with /etc/fstab a
link to /fstab.  Both versions of /etc have the same link to /fstab.  Maybe
some module, systemd, and udev files are also read before the readwrite
partition is mounted.

The bind mounts of the readwrite directories hide the readonly directories.
If you need to access the readonly directories,you could bind mount
the readonly directories to somewhere else.

Some people have told me the mostly readonly root filesystem is a good idea. 
Other people have told me it is extra complexity with no benefit, because it
does nothing to protect from filesystem damage, because of the way sdcards
work.
1 Like

This can work if you know which wifi chip is used and how to add its support.

Yes as manjaro is more of a desktop use os, we don’t add remote pkgs and configs.

This is true too. No linux os have vpu support at userspace level. Only Libreelec, coreelec have it.

Thanks for sharing your experience.