                         Linux on (Android) Tablet
                         -------------------------


 I'm Hermit (Mihaly Horvath) again with a strange but hopefully useful mod: 
Putting real Linux onto tablets which are intended for Android. My solution is
not a full-blown graphic Linux, just console at the moment. There are a few
(very few) descriptions in this topic on the net if you look for GUI systems.
Also, some hardware like network-cards are not operational in my case.
 Anyway, I share the knowledge I collected and the source of my additional code
so others may benefit from it and avoid looking for info in too many places.
Some base knowledge of linux, fastboot, adb is good as I don't explain the
commands one-by-one below, but you can search for their syntax on the internet.

I start by explaining why I did this: I don't like Android, it's too dumb and
it seems they do everything to keep it that way. No problem until someone like
me wants to use his tablet for serious and low-level stuff, programming, etc. 
 I say, why not? Tablets/phablets and even smartphones are very efficient
devices with small power consumption and they take small place. The only problem
is that as they get faster the OS and apps get more bloated, as dictated by the
business-life. I've been dreaming about a machine what I can use fore everything
related to computing and production from everyday browsing/mailing to coding.
 Avoiding bringing pendrives around between main desktop and embedded devices.
Who knows, one day this might be realized by the manufacturers but for now the
trend seems to be quite the opposite. That's why I experimented how I could at
least put a full Linux on an arbitrarily selected Android tablet...

 In my country the good models are not even known by shopkeepers, so I can't 
just walk in and say, hey I saw this or that tablet supports Linux to a degree,
I just have to select from what I see there. No Tizen or Sailfish tablets but
Android all the way down to the cheapest models. I think the power of them does
not differ much so I opted for the cheapest Navon Raptor 3G. Wow, they did every
possible work to make it look and feel cheap. Dust, wrong pixels, wrong viewing
angle, whatever. It didn't matter for me, I just want to be able to read text
on it in Linux commandline, and for that this Navon Raptor 3G was more than 
enough, I didn't waste money for a more expensive stuff that has this same 
bloatware on it. There's a Navon Predator which is quite the same, they didn't
even change the logo from Raptor to Predator. I laughed at it but I leave them
alone with their industrial rush problems and thank them for spreading out 
cheap tablets so poor people can experiment with it.
(We can learn from bad experience too, can't we?)
I don't go into details why I'm so disappointed with Android and Google in
general, everyone has the right to think differently about what the world should
be like. I like when something is reliable and fast, snappy...

 This Tablet has the MT8321 SoC which must be very cheap but still it has four
cores (for only 1 RAM: laugh) running around 1GHz. 512MB RAM is not really much
for Android but for a lightweight Linux distro it's quite huge. 4GB internal
EMMC storage is almost full but I could reduce the size of Android by throwing
out many-many unnecessary tools, junk. (Which I guess not a lot of people use.)
So the Linux can fit beside Android after around 2.5GB got freed up. More on 
that later in this doc...

                               First steps
                               -----------

 Of course I had to start by rooting the device to be able to backup its parti-
tions in case something goes wrong. The KingoRoot app did a fine job there. I
got all of the 22 eMMC partitions ripped by a partition backup tool on Android
then saved to my PC and put into safe place, just in case. 
First time I didn't disturb the partition-sizes of the Navon phablet.

 When the phablet is rooted (you lose varranty by that step you know), you are
able to run 'fastboot' on it and overwrite partitions. In order to unlock the
bootloader you first need to tap 'Build number' several times on the running
Android found in settings. Then you have to enable OEM unlocking in another
setting. That's followed by 'fastboot oem unlock'. I started by getting a
TWRP recovery image first. No CWM or TWRP was made specially for this device,
nor for MT8321, but when I examined the files in the partition-backups on my
PC I saw it might be MT6580. I found a TWRP for X510-D5110 devices, but after 
flashing it to the 'recovery' partition it didn't work, the phablet showed a
blank screen. So I needed a kernel which is able to handle the MT8321 inside.
 As MT8321 is closed-source (thanks guys for using open-source software to make
closed source software with it), the only option was using the original kernel
of the previously saved partition 'boot.img' extracted out by extractimg.sh in
'bootimg' folder here. I also extracted the TWRP recovery.img, then combined
them both into a new .img file with makeimg.sh (in the same folder). So what I
did is that I exchanged kernel (zImage) of TWRP for MT6580 to the MT8321 kernel.
It worked! TWRP3 started fine and I could use USB keyboard and mouse to control
it. (Only the touchscreen had problems, X and Y axis exchanged I guess...)

 From that point the next step was to simplify the TWRP folderlist, purge the
unnecessary files and scripts to get a pure adb shell. TWRP3 has a terminal
built in by now, but it's restricted into TWRP GUI. What I wanted to achieve is
a pure Linux console to build upon.
 The resulting folder tree can be seen in 'bootimg/initrd'. I could simplify it
to a great degree. I left adb shell in because it's always a good idea to have
it, it gives access (console) to the tablet already. But of course I needed a
real console to use the tablet in standalone mode, keyboard connected to it.

(Note: To ease testing, I flashed the original boot.img of the tablet into the
recovery partition and the custom .img to the boot partition, so my Linux starts
by default, and the volume-up button should be pressed during power-on to be
able to run Android... I like it better but it can be the other way round too.)


                             Creating Terminal
                             -----------------

 At this point I needed to do some coding, as fukkin Android kernel doesn't have
console. 'fbcon' is built into Linux kernel long ago but they wiped it out, I
think I know why. Never mind, there is a project called Yaft (Yet Another Frame-
Buffer Terminal). As it's name says it's intended for framebuffers on various
platform and it provides text console in a minimalist way. The problem is that
Android kernel doesn't have tty linux console (kbd) built-in either. When I
could compile and run Yaft from my custom image, and attach /dev/pts/ of the
adb shell to it I could see text output of adb. But that's just the half of the
happiness, though a good milestone. (I needed to maximize alpha-channel in the
Yaft source-code to see anything on this device btw.)
 I wrote keyboard-handler code from scratch into yaft.c with some layouts, and I
added code to make the cursor blink so it can be found better in crowded texts.
Also I made the cursor colour behave like on C64, so it always inverts on blink
and have the same colour as the character. Layouts are: dvorak, hu, geenasia
(Greenasia stands for a keyboard built into a tablet-case with weird layout.)
 Yaft was compiled with static linking so it only depends on the kernel, and
libc.so and linux-ld.so aren't needed. It's true for the other included files
like adbd and busybox. Adding midnight commander to '/system' is highly advised
to enhance working experience in commandline. This should be static too...
 I coded a touch-keyboard too into yaft, but not in the conventional way. You
can see on the photo Linux_on_Tablet.jpg that the touch-keyboard resides on the
left and right sides so they can be reached easily without stretching the thumbs
too much. I spiced my innovative way with a special key-layout too which is 
based on dvorak layout's philosophy: To reach the more frequently used letters
more ergonomically with the thumb than the less used ones. Needs some practising
and memorizing for sure. Especially that I utilized the 2nd framebuffer-layer of
Navon Raptor (maybe other devices have it too) to display the touchscreen-keypad
translucent, so it's not always seen well before the yaft-characters. The lines
separating the keys however perfectly fit between the 8x8 pixel characters and
can be seen easily all the time. If you plug an USB-OTG keyboard in, the touch-
screen display disappears to see the screen content better, but it's still sen-
sitive to touches.

 What you actually need to do is to copy the original Navon zImage into bootimg
folder and then run 'sh makeimg.sh' to create the boot.img file, then flash it
to the boot or recovery partition with fastboot. As it contains the precompiled
yaft inside, it should work fine and your Linux prompt should appear at reboot.
If you'd like to change the /dev/input/eventX device on which Yaft listens for
USB-keyboard or touchscreen events, change yaft-line in bootimg/initrd/init.rc
It's only needed if you Tablet is of other model. The defaults are for the Navon
Raptor in yaft (if not given as commandline argument). To find out the event
devfile numbers you can get help by typing 'cat /proc/bus/input/devices', this
can be performed in adb shell when yaft doesn't work with the current settings.


                   Partitioning, installing Linux on SD-card
                   -----------------------------------------

 So if everything went well we have a Linux prompt with my hacked Yaft and the
tablet can be used directly. It has busybox, we can initiate command 'dd' and
other essential tools like 'mount'. But it's not so much yet and it runs from
RAM unpacked at boot from 'initrd', and it can't be altered without reflashing.
 As the drivers are closed-source, we need to use the original kernel.The way to
use it for an ordinary Linux is to 'chroot' into the linux filesystem. (There's
a more modern approach called pivot-root, but I'm glad with chroot.)
The '/etc/profile' file in the initrd system checks if it can see a 2nd ext2/3/4
partition on the SD-card (mmcblk1p2) and if it can't find /dev/block/mmcblk1p2,
it tries to boot from mmcblk0. But for now this is not OK as we don't have a 
Linux on the internal eMMC yet. We can copy a Linux filesystem however onto the
2nd SD-card partition. Ubuntu for ARM processor can be found in some places,
I used Ubuntu 16.04 armhf for RPI2. The folder contents under / should be copied
to the SD-card partition mmcblk1p2. (Android terminal programs can probably be
used for that, Android itself is silly enough not to mount ext2/ext3/ext4 disks
by the file-manager. At least the ext partition can be mounted on a connected
PC when the Android device is connected in mass storage mode, and you can copy
the files to mmcblp1p2 from your PC. 
 If the root filesystem is present on the mmcblp1p2 partition you can restart
into your custom recovery and it should start the Linux from the SD-card's 2nd
partition. Maybe some tweaks/deletions are needed in /etc/profile or running
certain scripts at startup, this depends on the Linux version copied.
 The job is done if you're pleased to use the SD-card as system. From this point
installing and compiling applications is up to the user. The binaries will run
fine on the Android-kernel in chroot, but unfortunately there are some differen-
ces in the /sys and /proc and /dev filesystems in the Android kernel compared to
Linuxes. This means input/output/disk and other operations may require modifying
scripts or even recompiling of apps. For instance, as there's no full-featured
linux-console I couldn't start X server. It ran but it threw an error that it
lacks proper console. My modded Yaft is really just a bare console and some key
combinations requiring IOCTL messaging don't work in Midnight Commander.
 Framebuffer is /dev/graphics/fb0 on Android kernel, disks are at /dev/block and
there are many more differences. I couldn't even turn on ifconfig for ccmni0 and
similar 3G/Wifi devices yet so I don't have net connection. But in case I don't
have other option, I can develop on my tablet in midnight-commander editor and
other things can be done too, e.g. simple framebuffer image viewer (fbv/fbvis).
 The differences can only be eliminated if MT8321 gets reverse-engineered and a
proper Linux kernel can be compiled. Other devices might have better support.
Turning off this tablet can be done by 'echo freeze > /sys/power/state' after
syncing/unmounting drives. Setting brightness can be done by:
echo <value> > /sys/class/leds/lcd-backlight/brightness'

*Note the interesting fact that ordinary ARM executables (in my case those which
are compiled for RaspberryPI2) using GNU libc.so run quite fine on top of the 
Android kernel. First I was surprised (and glad) but I think at least the kernel
ABI is very similar if not the same in Android kernel and mainline Linux kernel,
that's why GNU libc and dependant apps can run on the Android kernel just like
the stripped down (or optimized/modified) Android-native 'bionic' std C library.
What's more I've read Android might get back closer again to the beloved main
linux kernel, but not very soon I suppose.


                    Installing Linux on internal eMMC
                    ---------------------------------

 To have the Linux on the internal eMMC, Android needs to be shrinked. This can
be done by mounting /dev/block/mmcblk0p19 on Navon Raptor 3G from the fresh 
linux, or by using 'mount -o loop system.img' on a PC and deleting unneded files
from it. To bring it to the system partition of the tablet fastboot may not be
used due to a size limit I've read somewhere. But 'dd' command can solve this
issue. E.g. you put the modified system.img on the SD-Card of the tablet, then
run your linux on it and type in shell (or adb-shell from PC):
dd if=/dev/block/mmcblk1p1/system.img of=/dev/block/mmcblk0p19 bs=1M
Cache (mmcblk0p20) and userdata (mmcblk0p21) partitions should be formatted for
a fresh start of the new stripped Android. Again, the partition numbers are
different for other devices, these are specific to Navon Raptor 3G. To list the
partitions and see which is which by name, you can use 'cat /proc/partitions'

Some big Android apps that I could remove from system.img without malfunction: 
(Of course you don't remove which you need. I'm quite minimalist.)

removed from 'app' folder:AutoDialer, Books, CloudPrint, DeskClock, DocumentsUI,
                          EngineerMode, Exchange2, FaceLock, FWUpgrade, Gmail2,
                          FWUpgradeProvider, GoogleTTS,Hangouts, LatinImeGoogle,
                          LiveWallpapers,LiveWallpapersPicker, Maps, MiraVision,
                          MTKLogger, Photos,PlusOne, PrintSpooler, SystemUpdate,
                          SystemUpdateAssistant,talkback,UserDictionaryProvider,
                          VisualizationWallpapers, VoiceCommand, VoiceUnlock,
                          Youtube

removed folder 'etc/voicecommand'

removed from 'priv-app' folder: BackupRestoreConfirmation, ElinkEngineerMode,
                          GmsCore, GoogleBackupTransport, GoogleFeedback, 
                          GoogleLoginService, GoogleOneTimeInitializer,
                          GooglePartnerSetup, GoogleServicesFramework, Velvet,
                          GooglePartnerSetup, SharedStorageBackup

removed from 'vendor' folder: pittpatt, operator/app/111.apk...555.apk (all)
   (Then I copied some useful apk into vendor/operator/app folder instead.)

Removing all of these results in a system.img around 600MB. ( I could make a
runnable Lollipop system in 450MB but phablet functions (like SMS) suffered.)

 As soon system.img is shrinked it is time to repartition the internal eMMC of
the tablet. Run your linux from SD-Card and find 'parted' application. It should
be there on Ubuntu, not sure about the others. Parted should be called with an
argument that is the disk to partition: 'parted /dev/block/mmcblk0'
 Type 'help' for help, and 'print' to see how the partitions currently look.
First thing to do (after stripped system.img copied to mmcblk0p19) is to
resize the 'system' partition. (You should be careful to run resize2fs and
tune2fs to move contents to the beginning of the partition before resizing the
partition itself if system.img was not copied with dd but by individual files.)
Then remove 'cache' and 'userdata partitions' to bring them back later smaller.
The flashinfo partition doesn't seem necessary and we have to remove it too
because we need the 22th partition number for our Linux, as according to parted
there's no more partition numbers to select from, table is full with 22 of them.
 After deleting the rest and mmcblk0p19 is the last partition followed by empty
space, create new partitions. I created only a 16MB mmcblk0p20 partition just as
a placeholder as I don't use it for cache/backup/restore/etc. (It should be ext2
if size is that small.) Create several hundred MByte of partition 21 (userdata),
it will be used for installed apps and it's populated at first boot of Android.
 We can now create our desired Linux partition at mmcblk0p22. I selected its end
to 3862 so it doesn't overwrite the 16MB info that was used for flashinfo. (It's
not needed but we never know.) ext4 is advised as partition type for eMMC.
 When ready with partition layout the names of the partitions are empty. The 
partitions need to be formatted by mkfs.ext2 / mkfs.ext4 after partitioning and
they can get a label by other commands: e2label is not sufficient in this case,
we need sgdisk tool to create real GUID partition names. See the tool's help how.

 Now that every partition is ready you may try booting your Android if it works
with this setup. If you did well it will start after some time (slow at first).
Now you can reboot and start your Linux from the SD-card and copy the Linux 
folders under / (root) of mmcblk0p22. If you copy the running system leave out
 /dev /sys /proc /mnt, but of course it's better to copy from an image/tarball
in the same way you copied the Linux system folders on the SD-Card before.


                        Final step, running Linux from eMMC
                        -----------------------------------

 To start the new Linux on mmcblk0p22 you have to take the SD-card off or remove
its 2nd partition, so /etc/profile in the boot image will chroot to mmcblk0p22
system partition. And we're ready... Customize your linux as you like, and good
luck to solve things on your hardware that I couldn't do on mine. Maybe a boot-
menu to select between Linux and Android is good too, I did not create one.
 I'm glad that I have a tablet that can be used as a kind of desktop and consu-
mes very little power, it can run from solar cells and it lasts for hours on the
go even with small batteries. I want no more from it now, when I need internet
and graphics I use Android but hopefully this changes later... This is not my
main machine of course but when needed it's more useful than having only 
Android on it...

 Every setup is different and I probably didn't cover all aspects of the topic
in this article. If you get stucked or want to know more, don't hesitate to 
contact me through the messagebox of my webpage for solution/discussion...



          2017 Hermit (Mihaly Horvath)   http://hermit.sidrip.com

