How to build Android Marshmallow on Nexus 10

The story thus far...

Many were very sad when google chose not to update Nexus 10 to Android 6.0 Marshmallow. This simple guide will show you how to build Android 6.0 Marshmallow for Nexus 10. And for the lazy, I also have a pre-built AOSP Marshmallow image set to download on the bottom of this page. Since Nexus 10 was originally a Google-Play-equipped device, you can legally install Google Apps on this image and enjoy a full Google Android 6.0 experience on your Nexus 10. That part, however, is up to you to do yourself. I am not offering GApps downloads here.

For fun, to make this work a few very cool hacks had to be done, read further below in the "cool hacks" section about them, if you care.


How to build

#grab M(6.0) and L(5.1.1) android trees, into folders called M and L respectively

#get manta's kernel sources for 5.1.1
git clone https://android.googlesource.com/kernel/exynos.git
cd exynos
git checkout remotes/origin/android-exynos-manta-3.4-lollipop-mr1

#apply kernel patch
git apply ../kernel.patch

#build kernel
export CROSS_COMPILE=`pwd`/../M/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-
export ARCH=arm
make manta_defconfig
make -j4


#get to work on M userspace
cd M

#get blobs
wget https://dl.google.com/dl/android/aosp/audience-manta-lmy48t-ebbd0e38.tgz
wget https://dl.google.com/dl/android/aosp/broadcom-manta-lmy48t-bed1fa3f.tgz
wget https://dl.google.com/dl/android/aosp/samsung-manta-lmy48t-2c3015ac.tgz
tar xvfz audience-manta-lmy48t-ebbd0e38.tgz
tar xvfz broadcom-manta-lmy48t-bed1fa3f.tgz
tar xvfz samsung-manta-lmy48t-2c3015ac.tgz
dd if=extract-audience-manta.sh bs=14452 skip=1 | tar xvz
dd if=extract-broadcom-manta.sh bs=14464 skip=1 | tar xvz
dd if=extract-samsung-manta.sh bs=14463 skip=1 | tar xvz
rm *.tgz extract-*-manta.sh

#get pieces that we need from L
mkdir device/samsung
rm -rf hardware/invensense
cp -Rvf ../L/hardware/samsung_slsi hardware/
cp -Rvf ../L/hardware/invensense hardware/
cp -Rvf ../L/device/samsung/manta device/samsung/
cp -Rvf ../L/external/stlport external/

#put the new kernel into place
cp ../exynos/arch/arm/boot/zImage device/samsung/manta/kernel

#apply cool binary patch
echo -n dmitry | dd bs=1 seek=8211 conv=notrunc of=device/samsung/manta/gps/gpsd

#apply source patches
cd device/samsung/manta
git apply ../../../device-samsung-manta.patch
cd ../../../hardware/broadcom/libbt
git apply ../../../hardware-broadcom-libbt.patch
cd ../../invensense
git apply ../../hardware-invensense.patch
cd ../samsung_slsi/exynos5
git apply ../../../hardware-samsung_slsi-exynos5.patch
cd ../../../vendor
git apply ../vendor.patch
cd ..


#build it
source build/envsetup.sh
lunch aosp_manta-userdebug
make -j4



Cool hacks (or: "what the hell is libdmitry.so"?)

Problems:

  1. Nexus 10's GPS library was made to work with android L, and no sources are provided
  2. Android M changed a few things around that make it not work
    1. Sensor manager API changed in a few places
    2. BoringSSL replaced OpenSSL
  3. Due to these now-missing unresolved symbols GPS library will not load or run (missing symbols)

Curious information: Due to peculiarities of the ELF format, when a binary baz imports function foo() from libbar.so, nowhere in baz's ELF file does it say that foo() must from from libbar. In fact there are two separate records. One that says that libbar is "NEED"ed, and another that says that there is an import of function "foo". What that means is that if the process were to also load libxyz, which also exported foo(), there is no way to be sure which foo() would get called. Why do we care? Well, consider our problems above. We need to provide functions and variables that existing libraries no longer do. How?

A tricky but clever solution: INTERPOSITION library

  1. We'll edit the GPS library and replace one of its "NEED" record with one referencing a new library which we'll create. Need a library name? why not "libdmitry"?
  2. Make sure that libdmitry's NEED records include the library whose record we replaced in the GPS library, to make sure that the linker brings it in afterall and all symbols in it are found.
  3. Implement libdmitry such that it provides the missing things and does them in such a way that the GPS library is happy.
  4. Complications exist:
    1. This would be impossible to do in C++, as the compiler would barf at us implementing random chunks of random classes we do not control. Luckily, the linker has no idea about C++, C, or other such things. C++ names get converted to special symbol names by the compiler, and thus the linker is never even aware of overloading or such things. This process is called mangling. So we'll just export the C++ functions we need with the proper mangled names, and code them in C. This means that we need to follow the proper calling conventions by hand, etc. With some dissasembling to see how GCC does it, we can duplicate it here, as I did.
    2. Not all missing things are functions. There are a few variables that need to be exported and are not present in M's code. We have to provide them. Luckily, just like with functions, as long as our mangled name matches, the linker will be happy to make the connection for us.
    3. Some cleanup may be needed on exit. Luckily, there is a way to register functions to be called upon library load and unload. I use that here to free some state that may be left over on exit.

Result: GPS library works on M, with the help of libdmitry and a small binary patch to the GPS library itself (replacing one of the "NEED" records with a NEED record for "libdmitry")



Ok, ok, give me the files already!

Download patches if you want to make the build yourself: => [PACKAGE YOU'LL NEED (mirror)] <=

If you're not a person who wants to build android yourself from source, here is fully usable userdebug image. Tested: Sensors, NFC, WiFi, Bluetooth, Camera, GPS.

Fastboot-flashable images here => [FASTBOOT IMAGES (mirror)] <=
Or, if you prefer to flash from TWRP => [TWRP flashable zip (mirror)] <=



Plase do not re-host this elsewhere and claim this as your work.
© 2012-2024