This Christmas I went back to my home country to spend some holiday time with my family. My mom complained that her tablet (aka my ancient tablet from 2013) was too slow and she was not able to play her games. I bought her a new one and took my old Asus Memo Pad Smart 10 back to Amsterdam.
After all, despite being old and not good enough for properly playing games, it still performs well at playing movies, checking emails and doing some casual Web browsing. Suffice to say, I had plans for it: I wanted to tweak it a little bit and install Magisk so that I had the freedom to ran all the apps I wanted. For more information about what that means, look at this page.
First thing first: the device was running Android 4.2.1. That is quite old, but luckily, some developers on XDA came up with a custom ROM. Scanno did a great job into creating an Android 4.4 ROM while lj50036 provided the community with an Android 5.1 ROM. These two ROMs are working perfectly, but that was not enough for what I had in mind. I wanted to use Magisk and therefore I needed some kernel-level customizations. At the beginning I went straight for the kernel provided by Asus, but it did not really work out for me, so I decided to learn how to build the OmniROM image from scratch, to get a better idea of what kernel to use (and alter).
So in this article, I am gonna discuss how to compile Android OmniROM on Gentoo and at the same time, how to make kernel customizations.
The reason why the kernel shipped with the aforementioned OmniROM images was not working for me is that the kernel version is 3.1.10, not enough to support Magisk. Magisk requires mount_namespace that is only available from Kernel 3.8. Luckily, this is not an insurmountable problem as pointed out on this XDA forum post. More details in the Kernel patching section. Let's proceed with setting up the environment and continue with the compilation of the ROM.
I was already prepared to do cross-compiling by setting my ARCH, SUBARCH and CROSS_COMPILE env variables when I figure out that there is a cooler way of doing that. A set of scripts are provided by Android. On top of that, OmniROM has a, now deprecated, page on how to set up your compile environment at the old OmniROM documentation page. Given that I am building an Android 5 image for a device with almost 6 years of life, documentation deprecation is not gonna be a problem.
To compile the OmniROM for your device, you need to have the right version of Java. Refer to the Android requirements page for more information. In my case, for Lollipop, I needed Java 7.
Unfortunately, Gentoo dropped the support for Java 7 in December 2017. Suffice to say, there was no overlay with a working Java 7 ebuild. Bubba has an ebuild for the binary version of icedtea, but it did not work for me. I ended up creating a small local overlay and copying the original ebuild (along with the files) for icedtea-bin-184.108.40.206 from the Gentoo repository.
Also, make sure that your Python interpreter is 2.x
Setting up the compiling environment
Although everything is specified in the original post from OmniROM and re-published on XDA as well, I am gonna briefly describe them here as well. After all, it is better to have some redundancy, right? :)
Of course, there are some small customizations along the way.
Note: Find a partition with a lot of free space cause once you build, the output will occupy roughly 100G.
Place yourself in your working copy
cd MY_SPACY_DIR mkdir -p bin mkdir -p android/omni
Download the repo tool and make it executable and available
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > bin/repo chmod a+x bin/repo echo "export PATH=MY_SPACY_DIR/bin:$PATH" >> ~/.bashrc source ~/.bashrc
Configure git for the upcoming download of code
git config --global user.email "email@example.com" git config --global user.name "Your Name"
Set up your local repo
cd android/omni repo init -u https://github.com/omnirom/android.git -b android-5.1
Add missing dependencies to the manifest.xml file
The default manifest file you will get from the previous
repo init...command, does not include vendor-specific repositories. You will have to add them. Moreover, the link to the
android_system_corerepository is broken for android-5.1. You will have to use the
commit idinstead of the branch name. In conclusion, you can either download my manifest.xml here on Gist.
Alternatively, you can download the patch here.
Sync the repositories
To sync the repos, do
repo sync -j4 -f --no-clone-bundle
If you try to compile the kernel beforehand building the ROM, you will get a small problem in a Perl script. If you are curious, you can try it by yourself with a very simple script:
export CROSS_COMPILE=/usr/bin/armv7a-unknown-linux-gnueabi- export ARCH=arm export SUBARCH=arm make clean make mrproper make tegra3_android_defconfig make -j4
Of course, you will need to set up a cross build environment for ARM. For Gentoo you can find great documentation about this on the wiki page.
Regardless of what you may decide to do (try or not to compile the kernel only) you will need the patch to compile it (timeconst), the path for mnt_namespace and make sure to prperly set the defconfig file.
You have two alternatives now:
Patch your kernel source
You can apply the patches for
- timeconst available here
- mnt_namespace backport available here
- Make sure to append the proper configuration flag with
echo "CONFIG_NAMESPACES=y" > arch/arm/configs/tegra3_android_defconfig
Applying only the first one will allow you to compile a working Kernel, but without support for Magisk. In order to do that you will need to apply the second patch as well. The second one backports the support for mnt namespace from Kernel 3.8
Use a patched Kernel source
I have forked the kernel source and applied the needed patches. You can check it out on my GitHub fork. If you want to use my kernel, overwrite the manifest.xml file with the gist from here: https://gist.github.com/rafspiny/e13553d1daf5aa52962d21fdae6ca03f
Then delete the old folder with
rm -rf android/omni/kernel/asus/tegra3
Execute again step 6, to download the repositories.
Remember that my fork does the following:
- backport mnt_namespace
- activate CONFIG_NAMESPACES
Set up the env variables and commands
export USE_CCACHE=1 android/omni/prebuilts/misc/linux-x86/ccache/ccache -M 25G . build/envsetup.sh
Et Voilà, after around 150 minutes (depending to your hardware) you will find a nice zip file containing your ROM.
You can keep following the tutorial on XDA on how to flash the ROM to your device and check it out.
I will try to upload the image on androidfileshost, but for the time being you can download it here if you want to try: https://www.rafspiny.eu/files/me301t/
In the picture below you can see my version of the kernel and ROM being in execution on the device.
Lastly, Magisk finally running properly.
If you forgot to export LC_ALL you will end up getting the following error:
flex-2.5.39: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (sizeof (_nl_value_type_LC_TIME) / sizeof (_nl_value_type_LC_TIME))' failed . Aborted
It is due to
locale, as described here: https://stackoverflow.com/questions/49301627/android-7-1-2-armv7
Please make sure to export the variable with
If you encounter problems download the
android_system_core repo after the changed the ref from
android-5.1 to the commit_id, try to do the following:
- comment out the line about
- rerun the
repo sync ...command
- uncomment the
- rerun the
repo sync ...for the last time