Mobile/Fennec/Android/Profiling

From MozillaWiki
< Mobile‎ | Fennec‎ | Android
Revision as of 18:55, 7 June 2011 by AlexPakhotin (talk | contribs) (Created page with "= Custom kernel for Nexus One = == Background information == ''oprofile'' is disabled in Nexus One kernel, so the kernel needs to be rebuilt to include it. These links have ins...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Custom kernel for Nexus One

Background information

oprofile is disabled in Nexus One kernel, so the kernel needs to be rebuilt to include it. These links have instructions on how to build a custom kernel:
http://androidboss.com/custom-linux-kernel-for-nexus-one/
http://atechyblog.blogspot.com/2010/08/enabling-serial-port-on-nexus-one.html
http://osdir.com/ml/android-platform/2010-07/msg00278.html

The key point is to add the following options to the .config to enable profiling:

CONFIG_OPROFILE_ARMV7=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y

Nexus One specifics

oprofile code included in the kernel needs to be fixed to work on Nexus One. The known fixes are for kernel version 2.6.32, branch "2.6.32-nexusonec". They are mentioned in the following posts:
Post 1, Post 2, The fix on Gerrit

Here's the combined patch:

--- a/arch/arm/oprofile/op_model_v7.c
+++ b/arch/arm/oprofile/op_model_v7.c
@@ -371,6 +371,11 @@
 #ifdef CONFIG_ARCH_OMAP3
 	INT_34XX_BENCH_MPU_EMUL,
 #endif
+#ifdef CONFIG_ARCH_MSM
+#ifdef CONFIG_ARCH_MSM_SCORPION
+        INT_ARM11_PM,
+#endif
+#endif
 };
 
 static void armv7_pmnc_stop(void)
@@ -386,12 +391,19 @@
 {
 	int ret;
 
+        if(ARRAY_SIZE(irqs) == 0) {
+            printk(KERN_ERR "oprofile: no interrupts for this CPU\n");
+            return -EINVAL;
+        }
+
 #ifdef DEBUG
 	armv7_pmnc_dump_regs();
 #endif
 	ret = armv7_request_interrupts(irqs, ARRAY_SIZE(irqs));
-	if (ret >= 0)
+	if (ret >= 0) {
+		armv7_setup_pmnc();
 		armv7_start_pmnc();
+	}
 
 	return ret;
 }

That specific branch is not available in the main repository at git://android.git.kernel.org/kernel/msm.git anymore, but still can be found here: git://github.com/Kali-/kernel_msm.git

Apparently this kernel was used in Android 2.2 Froyo. The latest official version of Android for Nexus One is 2.2.1. It is based on the kernel version 2.6.32.9-27240-gbca5320. This corresponds to the branch "android-msm-2.6.32" at git://android.git.kernel.org/kernel/msm.git

The patches above are still compatible with this branch, though enabling oprofile in this version of kernel has to be done carefully, as it's very easy to make the kernel unbootable.

Prerequisites

  • Linux (the steps below were used on Ubuntu 10.04)
  • Rooted Nexus One with Android 2.2.1, and unlocked bootloader
  • fastboot utility

You can find information on how to unlock and root your device here and on Google.

How to build a kernel with working oprofile for Nexus One

(These steps are based on the links mentioned above)

Get the kernel source:

$ git clone git://android.git.kernel.org/kernel/msm.git

The stock kernel version is 2.6.32.9. Once you get the source there are several branches in there. Check the branches and make a local branch of 2.6.32.9:

$ git branch -a
$ git checkout -b android-msm-2.6.32 origin/android-msm-2.6.32

Apply the op_model_v7.c fix from the section above.

Get the configuration from your device:

$ adb pull /proc/config.gz .
$ gzip -cd config.gz >.config

At this point you have to enable oprofile. The standard way would be to run

$ ARCH=arm CROSS_COMPILE=arm-eabi- make menuconfig

and enable it in General setup - Profiling support, but this may result in an unbootable kernel, so it's safer to enable it by adding the required options manually, i.e. by applying this patch:

--- a/msm/.config
+++ a/msm/.config
@@ -20,6 +20,7 @@
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 CONFIG_CONSTRUCTORS=y
@@ -106,7 +107,9 @@
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_KPROBES=y

Build the kernel (note: arm-eabi- tools from NDK have to be in the $PATH):

$ ARCH=arm CROSS_COMPILE=arm-eabi- make

This command will build a kernel image in arch/arm/boot/zImage. You can now boot with this image using fastboot without flashing.

First boot Nexus One to the FastBoot mode by turning power on with trackball pressed down, or, if it is already connected, use this command: adb reboot bootloader. When the device displays the screen saying "FASTBOOT USB", run the following command:

$ sudo fastboot boot /path/to/arch/arm/boot/zImage

This should boot your device with the custom kernel, which has oprofile enabled.

You'll need opcontrol and oprofiled, which you could download from here. These could be built manually, just opcontrol has to be patched as mentioned in the Post 1 above. The patch can be found here.

The stock WiFi driver does not work with the custom kernel, it needs to be replaced with the module built together with the new kernel. It is located here: drivers/net/wireless/bcm4329/bcm4329.ko. Copy it to the device:

$ adb push drivers/net/wireless/bcm4329/bcm4329.ko /data/local/tmp

Backup the stock module and copy the new one over:

$ adb shell
$ su
# mount -o rw,remount /dev/block/mtdblock3 /system
# cd /system/lib/modules
# mv bcm4329.ko bcm4329_stock.ko
# dd if=/data/local/tmp/bcm4329.ko of=./bcm4329.ko
# chmod 644 bcm4329.ko
# mount -o ro,remount /dev/block/mtdblock3 /system/
# exit
$ exit

Now if you reboot with your new kernel, WiFi should work.

Congratulations! You've got a working system with oprofile!

Ready to use ROM with oprofile

Due to the legal issues, the ROM is not available publicly. If you have Intranet access, you can find it here.


Adding oprofile to CyanogenMod ROM for Nexus One

Note: Currently it doesn't seem possible to use CyanogenMod ROMs, as they are based on the newer kernels, where oprofile code was changed, so the Nexus One specific patches cannot be applied "as is". But this approach could be still used if the solution could be found to that.

The approach with a custom kernel may not work as the rest of the ROM may not be compatible with it, so it might be safer to build the whole ROM.

Here are the instructions how to do this:
http://wiki.cyanogenmod.com/index.php?title=Compile_CyanogenMod_for_Passion

"device/htc/passion/extract-files.sh" may not find some libraries, as they are missing on the device, but they are required for the build. Those files could be extracted from the compiled CyanogenMod image downloaded from here:
http://wiki.cyanogenmod.com/index.php?title=Latest_Version#N1CM6

Also "vendor/cyanogen/get-google-files" script may not find Google applications, as the link it uses could be obsolete. A link to the latest package can be found on the same page:
http://wiki.cyanogenmod.com/index.php?title=Latest_Version#Google_Apps
You need HDPI version.

Kernel config has to be modified before the build to include the same OPROFILE options as above. The default config, which needs to be updated, is located here:

kernel-msm/arch/arm/configs/cyanogen_mahimahi_defconfig

(This needs to be verified. If it doesn't work, the actual .config used during the build could be found here: out/target/product/passion/obj/kernel/.config)

Issues

The main issue currently is that though the initial setup with "opcontrol --setup" seems to succeed, the oprofile counter configuration fails:

# opcontrol --event=CPU_CYCLES:64
Cannot open /dev/oprofile/0/user: No such file or directory
Cannot open /dev/oprofile/0/kernel: No such file or directory
Cannot open /dev/oprofile/0/unit_mask: No such file or directory
Cannot open /dev/oprofile/0/enabled: No such file or directory
Cannot open /dev/oprofile/0/count: No such file or directory
Cannot open /dev/oprofile/0/event: No such file or directory
Counter configuration failed for CPU_CYCLES
Did you do "opcontrol --setup" first?

This needs to be investigated, but it looks like oprofile compiled into the kernel does not have proper support for Nexus One hardware, and has to be fixed.


Using oprofile

After the new ROM is flashed to the device, oprofile can be controlled with opcontrol.

Manuals, examples, cheat sheet are here: OProfile documentation

Some Android-specific instructions can be found here:
http://www.omappedia.org/wiki/Android_Debugging#OProfile_on_OMAP3