FORUMS
Remove All Ads from XDA

Fire TV 2 - Ubuntu (Headless) Install Guide

287 posts
Thanks Meter: 190
 
Post Reply Email Thread
This guide is intend to help you with "installing" Ubuntu 14.04 (12.04 also works) on the Amazon Fire TV 2 after @rbox recovery has been setup. Only headless mode is possible, similar to Ubuntu Server, but it still makes a nice little ARMv8 development box. Starting X.org or running systemd based Linux distributions will likely never be possible due to features missing from the Amazon kernel. Creative use of the framebuffer is possible if desired, maybe eventually a terminal emulator could be started. As long as you don't mount and modify mmcblk0pX there should be no possible way to mess up Android or brick the device. It's 100% reversible by just removing the SD card. You accept all responsibility for what you do with this work should something go wrong and the device becomes inoperable. With disclaimers and precursor knowledge out of the way let's get started.

To follow this guide you will need:
  • A micro SD card (2 GB+ recommended)
  • A Linux system

To login into Ubuntu you will need either:
  • A 1.8 V TTY USB serial device connected to the UART
  • A pair of USB serial devices and a null modem cable

I actually used a pair of Xbee's for testing the ttyUSB0 stuff, so hence a pair of FTDI chips would also work.

Preparing the SD Card

To get started you need to first partition the micro SD card:
  • Type = MBR
  • Part 1 = 100 MB, Fat32 (vfat)
  • Part 2 = Remainder, Ext4

Extract the attached zip file to the root of the first partition (extracted filename must be "ramdisk-recovery.cpio.lzma"). This is an alternative initramfs that simply uses busybox to clean up from the partial Android boot and prepare the filesystem for regular Linux. Extract an Ubuntu core root filesystem archive, ubuntu-core-14.04.4-core-arm64.tar.gz, to the root of the second partition as the root user (to preserve ownership/permissions). Make sure you sync or eject the device when done with this work so the data gets flushed to the SD card.

Now we need to make a few changes to the root filesystem to avoid usability issues and allow logins.

Replace /etc/fstab with the following contents to correct some mount options. This "disables" SELinux which fixes dpkg errors and some other login annoyances.

Code:
/dev/mmcblk1p2 / ext4 defaults,relatime 0 0
selinuxfs /sys/fs/selinux selinuxfs ro,relatime 0 0
Replace /etc/init/console.conf with the following contents to allow logins from the UART. Once the root password has been set (root is disabled by default) you can remove "-a root" if desired.

Code:
# console - getty
#
# This service maintains a getty on console from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]

stop on runlevel [!2345]

respawn
exec /sbin/getty -s -a root console
Create /etc/init/ttyUSB0.conf with the following contents to allow logins from an attached USB serial device. This should help people who don't want to take apart their device to solder wires onto the UART test points. SSH would of course be an alternative but it's not installed by default in Ubuntu core and this guide is about the building blocks not providing pre-made images (yet). Since udev doesn't work due to devtmpfs not being enabled in the kernel you will need to attach the USB serial device before booting for this to work. As before you can remove "-a root" later if desired once the root password is set. Also you should change the baud rate if needed.

Code:
start on (tty-device-added ttyUSB0)
stop on (runlevel [!2345] or tty-device-removed ttyUSB0)

respawn
exec /sbin/getty -L -a root 115200 ttyUSB0 vt102
Preparing the Fire TV

Until the search order for the initramfs file is changed by @rbox you will need to rename the initramfs on the system partition so it will continue to search for one on the SD card or USB stick. You need to connect to the device using adb either over USB or the network to execute the following commands.

Code:
adb$ su
adb# mount -o remount,rw /system
adb# mv /system/recovery/ramdisk-recovery.cpio.lzma /system/recovery/ramdisk-recovery.cpio.lzma.bak
adb# mount -o remount,ro /system
Right now this prevents "su" from working, which should be fixed by @rbox in due time. To get "su" working again you should extract the original recovery initramfs file to a USB stick and boot the device with that USB stick inserted instead of the previously created SD card. Then to restore "su" you can repeat the above steps just swapping the order of the files in the "mv" command.

Booting Ubuntu

After connecting your serial device of choice simply insert the SD card and power on the device. It's that easy! With luck you should get a shell prompt that is already logged in as root. It's a good idea to set the root password before going much further. The device isn't too useful without networking, so you can install more packages. To solve that connect an ethernet cable (since it's simpler) and type "dhclient eth0" to get online. At this point you can install openssh-server using apt-get or do anything else you'd normally do on an Ubuntu VM or headless Ubuntu system. I'm interested in hearing what people plan to do with a more-or-less high-end ARM development system.
Attached Files
File Type: zip ramdisk-recovery.cpio.lzma.zip - [Click for QR Code] (838.5 KB, 70 views)
The Following 5 Users Say Thank You to zeroepoch For This Useful Post: [ View ] Gift zeroepoch Ad-Free
 
 
26th February 2016, 09:08 AM |#2  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
Tips and Tricks
NOTE: These changes, unless otherwise noted, are performed while logged into the target Ubuntu system.

Setting the Hostname

You can change the hostname using the following command:

Code:
echo sloane > /etc/hostname
You should also create a simple /etc/hosts file that matches the chosen hostname.

Code:
127.0.0.1  localhost
127.0.1.1  sloane
Enable Ethernet at Boot

Create the file /etc/network/interfaces.d/eth0 with the following contents:

Code:
auto eth0
iface eth0 inet dhcp
Allow Users Network Access

Since we are stuck running an Android kernel you need to create the following group and add users who need network access (such as ping) to this special group.

Code:
groupadd -g 3003 aid_inet
usermod -G aid_inet -a root
usermod -G aid_inet -a <username>
Removing Failed Services

There are a few services that fail to start due to hardware limitations. We should just prevent them from starting in the first place. We have no VT support enabled in the kernel (boo) so we can just remove the ttyX login prompt services. Also the console setup doesn't work since our console is a serial device not a virtual terminal or other "graphical" type terminal emulator.

Code:
rm /etc/init/tty?.conf
echo manual > /etc/init/console-font.override
echo manual > /etc/init/console-setup.override
Fix /dev Hotplug

As stated before udev doesn't work due to missing kernel features. The busybox applet mdev is a simple replacement for most users. After installing the "busybox-static" package run the following command:

Code:
ln -s /bin/busybox /sbin/mdev
Now add the following line to /etc/rc.local before "exit 0".

Code:
echo /sbin/mdev > /proc/sys/kernel/hotplug
Pre-installing SSH

See: http://forum.xda-developers.com/show...3&postcount=13 (thanks @segfault1978)
The Following User Says Thank You to zeroepoch For This Useful Post: [ View ] Gift zeroepoch Ad-Free
29th February 2016, 01:23 PM |#3  
Junior Member
Thanks Meter: 2
 
More
Thanks a lot, that was exactly the thing I was searching for. Since before today the Raspi3 came out, this box is the cheapest ARMv8 development machine available. With your instruction I was able to login via SSH and install all required software for my development environment. No GUI needed for that, I'm doing all remotely via SSH. Again, thank you!
The Following User Says Thank You to segfault1978 For This Useful Post: [ View ] Gift segfault1978 Ad-Free
29th February 2016, 04:35 PM |#4  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
Quote:
Originally Posted by segfault1978

Thanks a lot, that was exactly the thing I was searching for. Since before today the Raspi3 came out, this box is the cheapest ARMv8 development machine available. With your instruction I was able to login via SSH and install all required software for my development environment. No GUI needed for that, I'm doing all remotely via SSH. Again, thank you!

Awesome to hear that it worked for you. Just curious if you went the USB serial route or soldered to the UART pins.
29th February 2016, 04:41 PM |#5  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
There is also the Dragonboard 410c which is a quad core A53 but has a bit more than the raspberry pi. The price is higher though but it has been out probably a year or so. Just FYI. The raspberry pi 3 is a good deal.
29th February 2016, 08:09 PM |#6  
Junior Member
Thanks Meter: 2
 
More
Quote:
Originally Posted by zeroepoch

Awesome to hear that it worked for you. Just curious if you went the USB serial route or soldered to the UART pins.

None of these methods (since I was in my weekend and all cables and adapters reside in my office)
I placed all .deb-files for openssh-server including all requiremens onto the microSD card, and placed a call "dpkg -i /*.deb" with logging options in /etc/rc.local. I also configured network by mounting the sd card, editing /etc/network/interfaces, and last changed /etc/shadow to have a valid root account for login. It took my some try-and-error loops, but finally it worked as expected. Call me crazy, but I succeeded without any hardware.

---------- Post added at 09:09 PM ---------- Previous post was at 09:03 PM ----------

Quote:
Originally Posted by zeroepoch

There is also the Dragonboard 410c which is a quad core A53 but has a bit more than the raspberry pi. The price is higher though but it has been out probably a year or so. Just FYI. The raspberry pi 3 is a good deal.

Thank you for the hint, I'll have a look for the availability of this board in germany.
29th February 2016, 09:49 PM |#7  
Junior Member
Thanks Meter: 2
 
More
I'm facing a memory problem, resulting in a reboot of the device when all RAM is being used. My compile session takes more than 1.x GB of RAM for the quite complex compilation of all required packages. I can reproduce the situation where all memory is consumed and the device instantly reboots when hitting "no memory left" situation. Since "swapon" is not supported by the kernel (really?): is there any way to enable swap functionality, i.e. via a kernel module? How to overcome this situation where more memory is needed?
29th February 2016, 10:16 PM |#8  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
Quote:
Originally Posted by segfault1978

None of these methods (since I was in my weekend and all cables and adapters reside in my office)
I placed all .deb-files for openssh-server including all requiremens onto the microSD card, and placed a call "dpkg -i /*.deb" with logging options in /etc/rc.local. I also configured network by mounting the sd card, editing /etc/network/interfaces, and last changed /etc/shadow to have a valid root account for login. It took my some try-and-error loops, but finally it worked as expected. Call me crazy, but I succeeded without any hardware.

That is pretty crazy, but since you knew the changes required it worked Not everyone I expected to have such experience. I figured someone might even try to do a qemu chroot or debbootstrap to preinstall openssh. Multiple ways to solve the same problem I guess.

Quote:
Originally Posted by segfault1978

I'm facing a memory problem, resulting in a reboot of the device when all RAM is being used. My compile session takes more than 1.x GB of RAM for the quite complex compilation of all required packages. I can reproduce the situation where all memory is consumed and the device instantly reboots when hitting "no memory left" situation. Since "swapon" is not supported by the kernel (really?): is there any way to enable swap functionality, i.e. via a kernel module? How to overcome this situation where more memory is needed?

Looking at the default kernel config from the source code drop from Amazon I see:

Code:
# CONFIG_SWAP is not set
Swap can not be compiled as a module. Even if you chose to use a USB stick or something as the swap device It wouldn't work. Given that we can't change the kernel we can't try stuff like zram or zswap either. The only other suggestion I might have is if you're using "-j4" or something while compiling just remove that so it does a single threaded compile. I'm sure you already tried that. Beyond that you could look at using the Linaro AArch64 toolchain and cross compile. Since we're running Ubuntu you shouldn't need to worry about static binaries.
29th February 2016, 10:31 PM |#9  
Junior Member
Thanks Meter: 2
 
More
Quote:
Originally Posted by zeroepoch

Looking at the default kernel config from the source code drop from Amazon I see:

Code:
# CONFIG_SWAP is not set
Swap can not be compiled as a module. Even if you chose to use a USB stick or something as the swap device It wouldn't work. Given that we can't change the kernel we can't try stuff like zram or zswap either. The only other suggestion I might have is if you're using "-j4" or something while compiling just remove that so it does a single threaded compile. I'm sure you already tried that. Beyond that you could look at using the Linaro AArch64 toolchain and cross compile. Since we're running Ubuntu you shouldn't need to worry about static binaries.

Unfortunately, I'm not compiling with parallel processes (I'm compilig Icinga2 for arm64), I'm running
Code:
dpkg-buildpackage -us -uc
within the source package. One single cpp call consumes so much memory (which is crazy in my eyes, never seen such a big compiler process until today), so I'll investigate the option of cross compiling and afterwards creating the deb file outside of the machine.
Code:
cd /root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib/base && /usr/bin/aarch64-linux-gnu-g++   -DI2_BASE_BUILD -Doverride="" -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2  -g -pthread -std=c++11 -Wno-inconsistent-missing-override -fPIC -I/root/icinga2-2.4.3 -I/root/icinga2-2.4.3/lib -I/root/icinga2-2.4.3/obj-aarch64-linux-gnu -I/root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib -I/root/icinga2-2.4.3/third-party/execvpe -I/root/icinga2-2.4.3/third-party/mmatch -I/root/icinga2-2.4.3/third-party/socketpair    -o CMakeFiles/base.dir/base_unity.cpp.o -c /root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib/base/base_unity.cpp
I'm a novice in android devices: What would be required to use a custom kernel? A hacked boot loader, which is not available for the AFTV2?
1st March 2016, 12:45 AM |#10  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
Quote:
Originally Posted by segfault1978

I'm a novice in android devices: What would be required to use a custom kernel? A hacked boot loader, which is not available for the AFTV2?

Yep... we need to be able to use fastboot to boot an unsigned kernel and initramfs (boot.img). I tried at one point to overwrite the boot partition with own image and it failed to boot. Since I had the preloader stuff worked out already I was able to restore the original boot image and get it working again.

On a side note, if you don't mind could you post the list of packages needed to install SSH server from rc.local? Others might find that useful. To get around the unset password issue you could have also saved a public key in /root/.ssh/authorized_keys which would also avoid you needing to change /etc/ssh/sshd_config to allow password logins as root.
1st March 2016, 12:50 AM |#11  
OP Senior Member
Flag San Francisco, CA
Thanks Meter: 190
 
Donate to Me
More
Quote:
Originally Posted by segfault1978

within the source package. One single cpp call consumes so much memory (which is crazy in my eyes, never seen such a big compiler process until today), so I'll investigate the option of cross compiling and afterwards creating the deb file outside of the machine.

Code:
cd /root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib/base && /usr/bin/aarch64-linux-gnu-g++   -DI2_BASE_BUILD -Doverride="" -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2  -g -pthread -std=c++11 -Wno-inconsistent-missing-override -fPIC -I/root/icinga2-2.4.3 -I/root/icinga2-2.4.3/lib -I/root/icinga2-2.4.3/obj-aarch64-linux-gnu -I/root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib -I/root/icinga2-2.4.3/third-party/execvpe -I/root/icinga2-2.4.3/third-party/mmatch -I/root/icinga2-2.4.3/third-party/socketpair    -o CMakeFiles/base.dir/base_unity.cpp.o -c /root/icinga2-2.4.3/obj-aarch64-linux-gnu/lib/base/base_unity.cpp

I see you are not using -pipe which is good, but a quick search suggested something that might not be simple since this package has it's own build system but changing from -O2 to -O1 might help.
Post Reply Subscribe to Thread

Tags
aftv2, linux

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes