← Back to team overview

ubuntu-phone team mailing list archive

Galaxy S different sized kernel mystery

 

This is a brain dump. None of these instructions produces working images.
It's just for reproducing an issue.

Currently the samsung kernel only needs one patch to build. It used to need
two but it was fixed up stream. Now the only patch it needs is the common
Ubuntu config.

First I build vanilla CyanogenMod, but with the Ubuntu kernel config. This
means it won't work on the phone, but the point is to demonstrate that the
changed kernel config isn't the problem, and to have a baseline for
comparison:

mkdir cm
cd cm
repo init -u git://github.com/CyanogenMod/android.git -b cm-10.1
repo sync
breakfast galaxysmtd
nano -w .repo/local_manifests/roomservice.xml
---
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <project name="CyanogenMod/android_device_samsung_galaxysmtd"
path="device/samsung/galaxysmtd" remote="github" />
  <project name="CyanogenMod/android_packages_apps_SamsungServiceMode"
path="packages/apps/SamsungServiceMode" remote="gith$
  <project name="CyanogenMod/android_device_samsung_aries-common"
path="device/samsung/aries-common" remote="github" />
  <project name="ali1234/android_kernel_samsung_aries"
path="kernel/samsung/aries" remote="github" revision="saucy" />
  <project name="CyanogenMod/android_hardware_samsung"
path="hardware/samsung" remote="github" />
</manifest>
---
repo sync
cd devices/samsung/galaxysmtd
./extract-files.sh
cd -
cd vendor/cm
./get-prebuilts
cd -
brunch galaxysmtd

The kernel files are now at out/target/product/galaxysmtd and
out/target/product/galaxysmtd/obj/KERNEL_OBJ
Take note of the sizes!

Now build Ubuntu Touch with the same kernel source. Some patches are needed
in other repos for this but again I already put them online:

Ubuntu Touch:

phablet-dev-bootstrap phablet
cd phablet
repo init -b phablet-saucy
breakfast galaxysmtd
nano -w .repo/local_manifests/roomservice.xml
---
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <project name="CyanogenMod/android_device_samsung_galaxysmtd"
path="device/samsung/galaxysmtd" remote="github" />
  <project name="CyanogenMod/android_packages_apps_SamsungServiceMode"
path="packages/apps/SamsungServiceMode" remote="gith$
  <project name="ali1234/android_device_samsung_aries-common"
path="device/samsung/aries-common" remote="github" revision="saucy" />
  <project name="ali1234/android_kernel_samsung_aries"
path="kernel/samsung/aries" remote="github" revision="saucy" />
  <project name="ali1234/android_hardware_samsung" path="hardware/samsung"
remote="github" revision="saucy" />
</manifest>
---
repo sync
cd devices/samsung/galaxysmtd
./extract-files.sh
cd -
brunch galaxysmtd

This will fail with "no rule to make target android-boot.img"

To get around this error, edit device/samsung/aries-common/shbootimg.mk and
change "boot.img" to "android-boot.img"

Now the build will fail because the "kernel" is huge.

So now the question is, why is the same kernel source, same .config, same
compiler producing two different kernels?

al@al-desktop:~/Source/ubuntu-touch$ ls -l
cm/out/target/product/galaxysmtd/obj/KERNEL_OBJ/arch/arm/boot/zImage
-rwxrwxr-x 1 al al 6253960 Aug  2 15:31
cm/out/target/product/galaxysmtd/obj/KERNEL_OBJ/arch/arm/boot/zImage
al@al-desktop:~/Source/ubuntu-touch$ ls -l
phablet/out/target/product/galaxysmtd/obj/KERNEL_OBJ/arch/arm/boot/zImage
-rwxrwxr-x 1 al al 8469884 Aug  2 18:35
phablet/out/target/product/galaxysmtd/obj/KERNEL_OBJ/arch/arm/boot/zImage

8469884 - 6253960 = 2215924 bytes difference

The latter is much larger. Ok, let's look at the System.map to see why:

al@al-desktop:~/Source/ubuntu-touch$ diff -y
cm/out/target/product/galaxysmtd/obj/KERNEL_OBJ/System.map
phablet/out/target/product/galaxysmtd/obj/KERNEL_OBJ/System.map | grep -C 4
\| | head -n 10
c002d4c8 T __initramfs_start                    c002d4c8 T __initramfs_start
c002d4c8 t __irf_start                        c002d4c8 t __irf_start
c002d4c8 T __security_initcall_end                c002d4c8 T
__security_initcall_end
c002d4c8 T __security_initcall_start                c002d4c8 T
__security_initcall_start
c04bb4c8 T __initramfs_size                      |    c06ad4c8 T
__initramfs_size
c04bb4c8 t __irf_end                          |    c06ad4c8 t __irf_end
c04bb4d0 t kthreadd_done                      |    c06ad4d0 t kthreadd_done
c04bb4dc t done.29697                          |    c06ad4dc t done.29697
c04bb4e0 t tmp_cmdline.29698                      |    c06ad4e0 t
tmp_cmdline.29698
c04bb8e0 T boot_command_line                      |    c06ad8e0 T
boot_command_line

Notice here that __irf_start is the same in both, but __irf_end is
different. They match up with __initramfs_start and __initramfs_size.
0xc06ad4c8 - 0xc04bb4c8 = 2039808 bytes difference
0xc04bb4c8 - 0xc002d4c8 = 4775936 bytes
0xc06ad4c8 - 0xc002d4c8 = 6815744 bytes

from http://wiki.sourcemage.org/HowTo%282f%29Initramfs.html and
http://comments.gmane.org/gmane.linux.kernel/1027539 this does indeed
appear to be a built in initramfs inside the zImage. This is different to
the way most android devices use mkbootimg to combine a zImage and ramdisk.
In a real CyanogenMod rom for galaxysmtd, boot.img is not a mkbootimg
image, nor is it it my earlier ubuntu-touch port. The offsets in System.map
seem to be before compression, so perhaps this isn't the whole story, but
for sure both kernels have an initramfs with different contents, and
nothing else gets added later. I don't know where it comes from or how it
ends up in the kernel though, at this point, but I have a theory:

2039808 bytes is almost the same as the difference between the original
android ramdisk and the ubuntu touch ramdisk. Perhaps the android-boot.img
actually contains the ubuntu-touch ramdisk by some accident? In which case,
android-boot.img is already exactly what we want to boot from. I can't see
any other reasonable explanation for why the kernel is bigger.

The issue.

Ubuntu Touch always wants the original android boot.img as android-boot.img
and then it tries to build it's own boot.img using the kernel and ramdisk.
But in this device, the kernel already contains a ramdisk (apparently).
So then you get this error:

   ERROR: boot size (10670080) is 135.68% of limit (7864320)

10670080 is the 8469884 byte kernel + the ramdisk which is around 2M.
Note that the kernel+initramfs combo is already too big alone at 8469884
bytes, but this is a separate problem if, as I suspect, the extra size is
down to the ubuntu ramdisk being used instead of the original android one.



-- 
Alistair Buxton
a.j.buxton@xxxxxxxxx