Device Maintainers

WARNING:

The following tips are for those few who have the ability to accept changes into gerrit’s official CM repositories and/or who are able to bypass gerrit entirely. They are posted for convenience for these maintainers only, in case anyone forgets the steps :)

Note: Required Gerrit Permissions

To mass-submit to Gerrit, you will need the “Push” and “Create Reference” permissions. For mass pushes that include commits you didn’t create yourself, you may also need “Forge Author” and “Forge Committer” permissions. If you believe you are lacking appropriate permissions, contact a Gerrit admin (currently arcee, cyanogen, or ciwrl) for assistance.

Bypass Gerrit

Say you have a bunch of changes and want to skip gerrit’s interface entirely, pushing directly to the repository. For this you will need special privileges.

This is a summary of the user-upload feature, described in detail here.

To bypass Gerrit:

  1. repo sync
  2. branch the repository to anything.
  3. In the new branch, add your commits (or merge from another branch, git pull from AOSP, or whatever gets your changes in).
  4. Next, enter cmremote. This command will add the remote (use git remote -v to see it).
  5. To bypass gerrit, type git push cmremote HEAD:refs/heads/cm-13.0 (assuming cm-13.0 is the branch to which you are pushing).

To mass-push commits to Gerrit for review

  1. Repeat steps 1-4 above.
  2. Then, to mass-push TO Gerrit, use refs/for/branch instead of refs/heads/branch.

To create a new remote branch (on github)

  1. Repeat steps 1-4 above.
  2. Then, to create a new (remote) branch, type git push -u cmremote HEAD:refs/heads/new-branch-name.

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Dropbear

Note: LEGACY

This guide is provided for support on CM7 devices, OpenSSH is now used instead as of CM9

This short article explains how to connect to your Android device from another computer using the SSH protocol. This allows you to use a big screen and real keyboard to work on the device. This article focuses mainly on connecting with a Linux based computer. We will be using Dropbear on the Android device as an SSH server. Dropbear is already installed in CyanogenMod. [EDIT: Cyanogenmod 9.0 RC2 no longer includes Dropbear.]

The Android terminal is a fine app, but I prefer a big screen and real keyboard any time.

Prerequisites

  • CyanogenMod ≥ 5.0.6 (for dropbear & dropbear-keygen)
  • An SSH client such as OpenSSH or PuTTY
  • Android debug bridge tool. Please see SDK documentation for information on how to do this.
  • After the SDK is installed, ensure the device is connected to the computer through USB with ADB Debugging enabled in settings.

Create a SSH key for logging in

Create an SSH key on the computer that you wish to connect to your Android device with either `ssh-keygen` or `puttygen`. The public key will copied to the Android device and the private key remains on the computer. Only computers with the private key correctly installed can login to the Android device.

In linux:

ssh-keygen -t rsa

The output should look something like this:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in <Filename>.
Your public key has been saved in <Filename>.
adb push <Filename> /sdcard/authorized_keys

In Windows:
If using puttygen, paste the string from the puttygen window (looks like “ssh-rsa AAAAB3…hclQ==rsa-key-20100227”) in authorized_keys.

(Do not try to rename the file created by puttygen – it’s format is incompatible with dropbear)

A password can be used to connect to the device, in this case you can skip the steps above.

Prepare the Android Device

On the computer, open terminal and run the following commands:

adb shell
mkdir /data/dropbear
chmod 755 /data/dropbear
mkdir /data/dropbear/.ssh
chmod 700 /data/dropbear/.ssh
mv /sdcard/authorized_keys /data/dropbear/.ssh/
chown root: /data/dropbear/.ssh/authorized_keys
chmod 600 /data/dropbear/.ssh/authorized_keys
dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key
dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key

The end result should look something like this:

# ls -la /data/dropbear
drwxr-xr-x    1 root     root          2048 Sep  5 14:55 .
drwxrwx--x    1 system   system        2048 Sep  5 14:08 ..
drwx------    1 root     root          2048 Sep  5 14:51 .ssh
-rw-------    1 root     root           458 Sep  5 14:09 dropbear_dss_host_key
-rw-------    1 root     root           427 Sep  5 14:09 dropbear_rsa_host_key
# ls -la /data/dropbear/.ssh
drwx------    1 root     root          2048 Sep  5 14:51 .
drwxr-xr-x    1 root     root          2048 Sep  5 14:55 ..
-rw-------    1 root     root           406 Sep  5 14:01 authorized_keys
  • Creating directories and generating rsa/dsa keys is required even if you plan to use password login.

Finding the IP address of your Android device

Now to test Dropbear, first the IP address of the Android device must be determined, so as to communicate with it. On the Android device, through either adb shell or terminal emulator, do the following.

If connected through a WiFi network, use the following:

ifconfig eth0

The result should look something like this:

eth0: ip 192.168.1.64 mask 255.255.255.0 flags [up broadcast running multicast]

If connected through a mobile network, use the following:

ifconfig rmnet0

The result should look something like this:

rmnet0: ip 200.200.200.200 mask 255.255.255.252 flags [up broadcast multicast]

You can also list all interfaces using

ip addr
NOTE: It may not be possible host services such as SSH via your mobile network.

If that doesn’t work run cat /proc/net/dev to see the possible interfaces and use ifconfig with the appropriate interface.

Testing Dropbear

We’ll run dropbear in the foreground for testing with debugging information on the Android device. The “-s” option disables password logins (SSH public key authentication is still allowed though which is what we’re using). Use either adb shell or terminal emulator to do the following.

dropbear -s -v -F

(You can use the -Y option to specify a master password for login into any account, if not using key based authentication)

The output should look something like this:

...
TRACE (3220): listening on ':22'
TRACE (3220): enter dropbear_listen
TRACE (3220): dropbear_listen: all interfaces
TRACE (3220): bind(22) failed
TRACE (3220): leave dropbear_listen: success, 1 socks bound
[3220] Sep 05 15:16:43 Not backgrounding
NOTE: For more information about dropbear, run dropbear -h.

Now, on the computer, we will try to login to the Android device. Replace the path to your SSH private key and IP address as appropriate. On the computer’s terminal, do the following.

ssh -i ./The previously selected name for this key -l root 192.168.1.64

The output should look something like this:

Enter passphrase for key '/home/user/<Filename>':
TRACE (3229): entering fake-getpwnam
TRACE (3229): leaving fake-getpwnam
TRACE (3229): enter sign_key_free
TRACE (3229): enter dsa_key_free
TRACE (3229): leave dsa_key_free
TRACE (3229): enter rsa_key_free
TRACE (3229): leave rsa_key_free
TRACE (3229): leave sign_key_free

If it didn’t run ssh with the -v option to get verbose debugging output to try and see what went wrong.

If you get authentication errors, run this to show the device’s public rsa key

dropbearkey -y -f /data/dropbear/dropbear_rsa_host_key
  • the key is formatted like ‘ssh-rsa Som3Rand0mStr1n6 root@localhost’
  • copy and paste it to your PCs known_hosts file, ~/.ssh/known_hosts
  • and try connecting from your PC again

Assuming everything worked, dropbear can be turned off by running:

killall dropbear
NOTE: For Windows (PuTTY with SSH keyfile) you need to configure putty as follows:

  • Connection » Data » Auto-login Username = root
  • Connection » SSH » Auth » Private key file = Previously selected key file

Running dropbear normally

To run dropbear, from the Android device, run:

su
dropbear -s

The shell (whether or adb or terminal emulator) can now be exited safely and dropbear will continue to run.

Dropbear can be turned off by running:

killall dropbear

Automatic startup of the sshd-server on your device

To modify the file in /system/etc/ you need to remount the partition to read/write mode using

mount -o remount,rw /system

To run Dropbear on start up, edit the /etc/init.local.rc file (Your preferred editor can be used, as long as it doesn’t introduce Windows/DOS line breaks), and add the following snippet to the end of the file

# start Dropbear (ssh server) service on boot
service sshd /system/xbin/dropbear -s
   user  root
   group root
   oneshot

The `oneshot` option instructs Android that the service should not be restarted if it is killed. For a full understanding of the Android Init system see here.

Prepare the Android device (using a root password) for OLD BUILDS of CyanogenMod

NOTE: The native dropbear binary included in CyanogenMod 4.0.4 and later seems not to support correctly password protected logins in the sense that you can login even when providing a wrong password. To make it work correctly you need to compile your own dropbear binary statically linked with uClibc.
  1. Compile dropbear (statically linked with uClibc)
  2. Compile busybox (statically linked with uClibc) and enable
    1. Support for shadow passwords
    2. Use internal password and group functions rather than system func
    3. Use internal shadow password functions
    4. Use internal crypt functions
    5. passwd
    6. Check new passwords for weakness
  3. Copy the new dropbear and busybox binaries to the device:
    adb push busybox /sdcard/busybox
    adb push dropbear /sdcard/dropbear
    adb push dropbearkey /sdcard/dropbearkey
  4. Open the terminal and become superuser/root
  5. Create /data/local/bin directory
  6. Copy dropbear, dropbearkey and busybox to /data/local/bin and setup file permissions, ownership and links
  7. Remount /system read-write
  8. Create the needed passwd files
  9. Change the root password
  10. Create /etc/profile with a usable path
  11. Create /etc/shells
  12. Remount /system read-only
  13. Create the dropbear directory
  14. Generate rsa and dsa keys
  15. Link /data/dropbear directory to /system/etc/dropbear
    su
    mkdir /data/local/bin
    cp /sdcard/busybox /data/local/bin/busybox
    cp /sdcard/dropbear /data/local/bin/dropbear
    cp /sdcard/dropbear /data/local/bin/dropbearkey
    chown root.root /data/local/bin/dropbear
    chown root.root /data/local/bin/dropbearkey
    chown root.root /data/local/bin/busybox
    chmod 4755 /data/local/bin/busybox
    chmod 755 /data/local/bin/dropbear
    chmod 755 /data/local/bin/dropbearkey
    ln -s /data/local/bin/busybox /data/local/bin/passwd
    busybox mount -o remount,rw /dev/block/mtdblock3 /system
    echo "root:x:0:0::/data/dropbear:/system/bin/sh" > /etc/passwd
    echo "root::14531:0:99999:7:::" > /etc/shadow
    echo "root:x:0:" > /etc/group
    echo "root:!::" > /etc/gshadow
    echo "/system/bin/sh" > /etc/shells
    echo "PATH=\"/usr/bin:/usr/sbin:/bin:/sbin:/system/sbin:/system/bin:/system/xbin:/system/xbin/bb:/data/local/bin\"" > /etc/profile
    echo "export PATH" >> /etc/profile
    /data/local/bin/passwd
    Changing password for root
    New password:
    Retype password:
    Password for root changed by root
    mkdir /data/dropbear
    /data/local/bin/dropbearkey -t rsa -f /data/dropbear/dropbear_rsa_host_key
    /data/local/bin/dropbearkey -t dss -f /data/dropbear/dropbear_dss_host_key
    ln -s /data/dropbear /system/etc/dropbear
    busybox mount -o remount,ro /dev/block/mtdblock3 /system
  16. Then as root to run the compiled version, call it with the full path:
    /data/local/bin/dropbear

See also

Link to alternative explanation: dropbear login

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

sshd

NOTE: Many of the commands used here are redundant or unnecessary. They are included to further illustrate what is happening behind the scenes.

Prerequisites

  • CyanogenMod 10.1 on your remote device (build after May 12, 2013)
  • An SSH client on your local machine (such as OpenSSH or PuTTY)
  • A private SSH key. (If you don’t already have one, see this helpful article for information on how to make one.)
  • A means of running commands on your phone as root. This guide uses an adb connection to your device (see ADB intro for more information)

Setting up sshd

All command are executed from the adb root shell (su to root from adb shell), unless otherwise specified. Properly setting the file and directory permissions is critical for sshd to function as expected.

Setting up the directory structure

mkdir -p /data/ssh/empty
chmod 700 /data/ssh
chmod 700 /data/ssh/empty

/data/ssh holds the server’s host keys and configuration file. /data/ssh/empty is used for privsep.

NOTE: Both /data/ssh and /data/ssh/empty should have already existed. They are created here in case of previous accidental deletion.

Helpful Tip

Commands can be pasted into PuTTY by right-clicking or pressing Shift-Ins.

Creating the server configuration file

cat /system/etc/ssh/sshd_config | \
sed 's/#PermitRootLogin yes$/PermitRootLogin no/' | \
sed 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' | \
sed 's/#PasswordAuthentication yes/PasswordAuthentication no/' | \
sed 's/#PermitEmptyPasswords no/PermitEmptyPasswords no/' | \
sed 's/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/' | \
sed 's;/usr/libexec/sftp-server;internal-sftp;' > \
/data/ssh/sshd_config
chmod 600 /data/ssh/sshd_config
  • PermitRootLogin no forbids root login (We’ll be logging in as shell.)
  • PubkeyAuthentication yes allows the public key authentication method
  • PasswordAuthentication no prevents the password authentication method
  • PermitEmptyPasswords no prevents submitting empty passwords (probably redundant, since we disabled password authentication *shrug*)
  • ChallengeResponseAuthentication no prevents the challenge response authentication method
  • Subsystem sftp internal-sftp allows sftp without the need for the sftp-server binary

NOTE: You could probably set a password for shell with passwd and use the password authentication method, but I am unsure of what, if any, effects this might have.

Helpful Tip

Lines that end in a \ continue the same command on the following line. This was done above improve readability of a long command.

Setting the Authorised Public Key

Upload your public key to your phone to /data/.ssh/authorized_keys in a text file on a single line. This file is a list of all the public keys that sshd will allow with one key per line. Since only your public key will be allowed, there will only be one line in it. First, make the directory where the public key will be stored, and grant it the correct permissions.

mkdir -p /data/.ssh
chmod 700 /data/.ssh
chown shell:shell /data/.ssh

Then upload your public key to your phone. (This one command is done on your computer.)

adb push your_public_key /data/.ssh/authorized_keys

Now, fix the permissions.

chmod 600 /data/.ssh/authorized_keys
chown shell:shell /data/.ssh/authorized_keys

NOTE: /data/.ssh should have already existed. As with, /data/ssh and /data/ssh/empty, it is created here in case of previous accidental deletion.

Helpful Tip

Some sftp clients may require the use of an SSH key agent to manage the key.

Starting sshd

There is a script already on the phone called start-ssh that will start sshd, but it requires modification:

mkdir -p /data/local/userinit.d
cat /system/bin/start-ssh | \
sed 's;/system/etc/ssh/sshd_config;/data/ssh/sshd_config;' > \
/data/local/userinit.d/99sshd
chmod 755 /data/local/userinit.d/99sshd
  • /system/etc/ssh/sshd_config is changed to /data/ssh/sshd_config so configuration changes are not lost after a /system flash

To start sshd, run /data/local/userinit.d/99sshd, the new version of start-ssh. It must be run as root. It will also get run automatically by /system/etc/init.d/90userinit on startup, along with any other scripts you put in /data/local/userinit.d.

Connecting and Usage

Once sshd has been started on the phone, you can connect to it with your favourite SSH client and the username shell. This is the same username adb shell gives you, so your permissions are the same until you choose to elevate them using su. You can connect as root (you’ll have to edit sshd_config to allow it), but that is highly inadviseable. Only using root when you have to puts you at a much smaller risk of accidentally wrecking things.

The shell user is pretty weak, so you might like to carve out a home folder, where shell has write access. There you can also keep settings for all your favourite shelly programs, like emacs, vim, and bash. The following is an example of just that.

Make the folder (as root, using su):

mkdir /data/home
chmod 755 /data/home
chown shell:shell /data/home

Everything else from here on in can be done as shell over SSH or with scp. Copy over some key config files (run on the computer):

scp .inputrc .bash_profile .bashrc .vimrc .screenrc shell@hostname:/data/home

Now, we’d like a fast way of configuring the home directory, since it gets ignored when we first log in. Put the following in /data/home/login:

#!/system/xbin/bash

HOME='/data/home'
cd
exec bash --login

Then set its permissions to allow execution:

chmod 755 /data/home/login

Now, to switch to the new home directory when you log in, just type exec /data/home/login.

Android has made it so that the files and directories shell creates can only be accessed by itself by default. If you want to access the files you make with shell from your other apps, like file browsers, without root access, you’ll need to change the default file and directory creation permissions. Add the following to your .bash_profile on a line by itself to allow read-only access from all apps: umask 0022. To allow all apps read/write access, use umask 0000 instead.

To emulate sudo behaviour, you might like to put the following alias in your .bashrc: alias sudo='su root'.

Troubleshooting

  • Change # DEBUG=1 to DEBUG=1 in /data/local/userinit.d/99sshd to enable debug logging to logcat
  • Reboot remote device (or kill the sshd process and run 99sshd)
  • Run logcat | grep sshd to show the debug log
  • When in debug mode, sshd will quit after the first ssh session exits. Recomment the DEBUG=1 line and restart 99sshd for normal behavior.

NOTE: Most issues will be related to permissions.

Helpful Tip

Some devices may be sluggish with the screen locked. Try unlocking the screen to see if performance improves.

Todo

  • Find specific versions of CM where supported
  • Identify effects of setting password for shell user
  • Add more troubleshooting information
  • Add a section for client (PuTTY) setup; specifically, private key conversion (puttygen) and/or ssh-agent (pageant) usage (this may be more useful has a it’s own document)

Problem with SELinux

My solution for problem:

W/sshd type=1400 audit(0.0:16): avc: denied { open } for name="sshd_config"
  • Install SuperSu ([1])
  • create directory /system/su.d
  • modify file 99sshd and add/change
supolicy --live "allow sysinit self:capability setgid;allow sysinit system_data_file:file open;"
/system/bin/logwrapper /system/bin/sshd -f /data/ssh/sshd_config

Notice I removed the -D param. Because with it the sshd was killed.
And added the logwrapper, because sshd can generate an output when error.

  • put the file 99sshd into /system/su.d/ (remount rw)

I choosed this directory because the userinit.sh had problems (selinux) with running another scripts.

Allowing root login

Modify file /data/ssh/sshd_config

AuthorizedKeysFile      /data/.ssh/authorized_keys.%u
PermitRootLogin yes

and rename file /data/.ssh/authorized_keys to authorized_keys.root and authorized_keys.shell

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Compatibility Test Suite – CTS

What is CTS

From the official documentation:

The Android compatibility program works for the benefit of the entire Android community, including users, developers, and device manufacturers.

Each group depends on the others. Users want a wide selection of devices and great apps; great apps come from developers motivated by a large market for their apps with many devices in users’ hands; device manufacturers rely on a wide variety of great apps to increase their products’ value for consumers.

The CTS is an automated testing harness that includes two major software components:

  1. The CTS test harness runs on your desktop machine and manages test execution.
  2. Individual test cases are executed on attached mobile devices or on an emulator. The test cases are written in Java as JUnit tests and packaged as Android .apk files to run on the actual device target.

Setup CTS

Downloads

Download and unzip the latest CTS package from Google. You will want the following:

  1. Compatibility Test Suite zip
  2. CTS Verifier APK
  3. Media 1.0

APK Install

From extracted zip go to android-cts/repository/testcases:

adb install CtsDeviceAdmin.apk

Device Preparation

In Developer Options:

  1. Enable Stay Awake
  2. Enable Android Debugging
  3. Enable Allow Mock Locations
  4. Enable Allow Mock SMS

In Security:

  1. Set Screen Lock to None
  2. Tap Device Administrators – check the two check boxes for CTS (requires CtsDeviceAdmin.apk from above):
android.deviceadmin.cts.CtsDeviceAdminReceiver
android.deviceadmin.cts.CtsDeviceAdminReceiver2
  • Do NOT check the 3rd box for android.deviceadmin.cts.CtsDeviceAdminDeactivatedReceiver

Media Files:

In Android Media 1.0 zip run the following:

$ bash ./copy_media.sh all
  • This will push all media files to the device

Additional tasks:

  1. Device should have SIM card with data
  2. Device should be connected to Wi-Fi
  3. Install GMS packages (gapps)
  4. For tests, Default the browser to Chrome (do an activity to launch the chooser, select Chrome and press Always)
    1. Go through Chrome’s brief setup
  5. Do not log in to any accounts (Google, CM Account, etc)

Run CTS

In the extracted CTS zip, go to android-cts/tools and run the following command:

$ ./cts-tradefed

This opens the CTS command window. Here are useful commands:

  • This runs a full CTS test pass
cts-tf> run cts --plan CTS
  • To view all sessions in your /repository/results directory and number them:
cts-tf> l r

Re-run failures:

To re-run failures, create a plan based on results of a previous session:

cts-tf> add derivedplan --plan name_of_plan -s # -r fail
  • the -s # is for session. Enter the number that corresponds with the session based on ‘l r’
  • name_of_plan is a unique name for the plan you create – example n1_fails0411

Run a derived plan:

cts-tf> run cts --plan name_of_plan

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Submitting A Port

Congratulations!

You’ve got the device, you spent weeks (months?) getting it to work. Now you want to submit your device and kernel tree back upstream to be recognized by CyanogenMod as an “official” device.

Here’s how to do it…

Prerequisites

You can save everyone a lot of time by making sure that you have met these requirements:

  • Full hardware support — Everything– every peripheral, every wireless feature– that is supported by stock *must* be supported by CyanogenMod. Any exceptions will be per device (case-by-case) and must be detailed in full.
  • Stability — Nothing should crash. Ever. CyanogenMod has a reputation for stability and your port must be rock-solid. This means no “sleep of deaths” either.
  • No overclock by default — While overclocking options in the Performance menu is well and good, leave the default speeds at stock.
  • Do not over-volt either — Do not go outside of the spec for power consumption. If you want to provide sysfs methods for upping the voltage, that’s up to you. But it must not be a default setting.
  • You have designated at least one device maintainer and at least one person to be responsible for the device’s wiki information. The former will evaluate submissions to the device’s repositories. The latter will ensure that the information/documentation about the device on the wiki is always up-to-date and correct. These people must be identified when applying for official recognition.

Optional (but awesome if you have it)

Submitting your device

  • Send an email to [email protected]
    • This email must contain links to your github repositories for your device
    • This email must contain gtalk and email addresses for contacting you
    • If a team worked on your device, all team members must be listed in the email

Once you have sent your email, expect a good amount of time to pass before a reply. This can take a couple of weeks. Your device will be reviewed. If things need to be changed, a conversation will start with you to help guide you through the process of being accepted. If your device is rejected, you will get a detailed response as to why. Not all devices will be accepted. Keep this in mind.

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Integrated Kernel Building

Why does CM want the kernel built together with Android?

Before CM9, we depended on having prebuilt kernels in every device repository. These were compiled separately from the framework and required the device maintainer to manually update the kernel image and modules any time a change is done. In addition, kernels were not using a consistent naming scheme, many were not managed by the CyanogenMod Gerrit, and were often compiled using compilers other than the one found in the Android toolchain. This has lead to major inconsistencies, and difficulty for others to match the maintainers build. [More info here]

Note:

Check the The CyanogenMod Learning Center to learn more about CyanogenMod building, and especially the Envsetup help for a list of build commands.

How to (edit and) build an officially supported kernel?

Option A: Building the full ROM (Kernel + Android) from the full CyanogenMod source

Follow the CM Build Guides for your device.
The kernel sources will be automatically downloaded if your device is supported. The ROM will be built into a ClockworkMod Recovery flashable zip file.
Note that the full CM Android and Kernel source will be downloaded (several GB) and along with the build files you will need ~40-50GB (for CM11.0, depends on your kernel) of disk space.

Option B: Building only the Kernel from the full CyanogenMod source

Follow the CM Build Guides for your device with the change explained below.
Your device kernel will be downloaded during the launch of the breakfast or lunch command as described in the build guide. Note that the full CM Android and Kernel source will be downloaded (several GB) and along with the build files you will need ~20GB (for CM11.0, depends on your kernel) of disk space.

So follow your device build guide but instead of:

$ brunch

run (also from the CM Android source root directory (croot), not from the kernel directory):

$ mka bootimage

This will only compile the kernel source into a boot.img. You will therefore save a lot of compilation time.
The boot.img file can be then flashed with fastboot or directly from the command line.
Note that to ensure kernel – ROM compatibility, your phone should run a ROM based on the same kernel version that you’re flashing, or things may break.

$ adb root
$ adb remount
$ installboot
$ adb reboot

Note: If your device supports fastboot (Samsung doesn’t), you can test the kernel instead of flashing it:

$ adb reboot bootloader
$ fastboot boot "$OUT/boot.img"
Changing the kernel configuration

The kernel configuration file used during the build process is referenced in TARGET_KERNEL_CONFIG variable in device/vendor-name/device-name/BoardConfig.mk. It generally points to kernel/vendor-name/kernel-name/arch/arm/configs/cyanogenmod_device-name_deconfig.

To make a custom kernel configuration file, you can use the configuration build tools from the kernel dir, e.g. make menuconfig, and save the resulting hidden .config file to the location specified in TARGET_KERNEL_CONFIG. Then run make mrproper from the kernel dir and go back to the CM android source root dir (croot) before building.

Re-building

To re-build the kernel after you’ve made some changes to the source files or config file, just run mka bootimage again. The build will be much faster due to caching, and selective build of modified files. Beware the errors during the re-build process: the building system may use previously built object/modules if some objects fail to build, leading to inconsistencies. In case of doubt, run mka clean.

Note that you can’t use mm‘s command for kernel modules. These commands are made for modules that use an Android.mk file and not a standard Makefile, like system (not kernel) modules.

Helpful Tip

Escaping a bootloop: If your device is stuck in a bootloop after flashing, flash again the device with a working kernel (or in the worst case with a full ROM / nandroid backup).

In your build directory, you can find the kernel zImage in $OUT/obj/KERNEL_OBJ/arch/arm/boot. This file can be flashed on supported devices with Heimdall (for some Samsung devices) or fastboot (for devices supporting fastboot mode).

Note that however, mka bootimage doesn’t generate a ClockWordMod or TWRP flashable zip file, you will have to build it yourself if you can’t use the zImage directly.

TO AVOID: Building only the kernel from the kernel source

As of CyanogenMod 9, we are deprecating the usage of prebuilt kernel images. The build system has been modified to ask for (and build) the kernel source. So don’t follow CM oldwiki kernel build guide.

Building an official kernel from the CyanogenMod build system will ensure your are using the proper Android toolchain. It will also bring more guarantee of compatibility between the kernel and the userspace (system calls, like ioctl, should be consistent between the kernel and userspace).

Moreover, the kernel Makefile generally doesn’t take care of creating the device-specific ramdisk, embedding the kernel image (zImage) and ramdisk into a boot.img (which structure is sometimes device specific) and pushing everything, including the loadable kernel modules, to the device. Whereas by building from the full CM source, the CM build tools will automate these steps.

TO AVOID: Building only a kernel module and importing it on a different kernel version

Kernel modules (e.g. a Wi-Fi driver) are built for a specific kernel version. Indeed, the kernel module (.ko file) embed the version of the kernel it is built for (check modinfo module-name.ko). The module will not load if its version is different than the running kernel version (check uname -a from the device terminal prompt). One reason behind this version interdependency is that internal interfaces within the kernel (the interfaces used in your module to access other kernel resources/modules) can and do change between versions. [source: LKMPG]

Therefore you should build and flash a full kernel if you need to change a module.

Otherwise, and if you make no kernel configuration change, you can build a kernel module from the same exact kernel source version (i.e. Github commit) that you’re planning to import the module into. If you’ve not built the kernel yourself, this becomes highly complicated and deprecated: you may need to rebase your CM repository to the exact Github commit that your kernel was built from, extract and use the .config from your device, and eventually trick the source files that take care of defining the magic version of the built kernel module.

How to reference a custom kernel for building?

This chapter is intended for people that want to use a totally different kernel than the officially supported ones.
If you only need to modify an officially supported firmware, go back to the previous chapter and play with the kernel files in kernel/vendor-name/kernel-name (the official kernel files for your device will be downloaded after running the breakfast or lunch commands as described in the Build Guides).

Step 0. Preparing the build environment

Depending on whether your device is supported or not, follow the Build Guides or Porting Guide to prepare the Build Environment and get CM Android source code, prebuilt apps, device-specific code and proprietary blobs.

Step 1. Deploying the kernel source at the proper location

The minimal requirement is that the kernel’s source tree for that device be present at kernel/vendor-name/device-name of the CM Android source.

  • Officially supported devices:
    • For devices which are part of mainline CyanogenMod and have their kernels in CM’s github, this can be accomplished by usage of CyanogenMod’s roomservice feature. Create a device/vendor-name/device-name/cm.dependencies file (if it doesn’t exist yet), with the following syntax. This will take care of downloading the source automatically into the right location.
[
 {
   "repository": "name-of-repository-in-the-CyanogenMod-github",
   "target_path": "kernel/vendor-name/device-name",
   "branch": "name-of-branch"
 }
]
  • Work-in-progress, unofficial, or otherwise non-integrated devices:
    • For devices which don’t have their kernel source at the CM github, usage of local_manifest.xml is recommended in order to deploy the source at the right location, and keeping it synchronized.
  • Devices using shared kernel repositories:
    • If your device shares a kernel with others, the default kernel/vendor-name/device-name path will lead to unnecessary duplication of source trees, so usage of the TARGET_KERNEL_SOURCE configuration variable in device/vendor-name/device-name/BoardConfig.mk is advised. All devices sharing that source should have the following line in their BoardConfig.mk files:
TARGET_KERNEL_SOURCE := kernel/vendor-name/unique-shared-source-name

Step 2. Configuring the device to build the kernel

After the source is in place, configuration of the device to build the kernel is trivial. Just add the TARGET_KERNEL_CONFIG variable to your device/vendor-name/device-name/BoardConfig.mk file, pointing to the configuration file name for your device (as present in kernel/vendor-name/kernel-name/arch/arm/configs). For example:

TARGET_KERNEL_CONFIG := cyanogenmod_device-name_defconfig

This will trigger the full kernel build, including the modules (if present) as specified in that configuration. Any modules built will be deployed at /system/lib/modules/ in the final image

If your device requires uImage, also ensure the following is present in your ‘BoardConfig.mk’

BOARD_USES_UBOOT := true

Step 3. Configuring the build of out-of-tree kernel modules

If your device needs modules that aren’t part of the kernel source tree, those can also be built automatically. Some hardware (Texas Instruments’ TIWLAN adapters, Broadcom’s BCM adapters) is directly supported by CM repositories, but if that isn’t your case we suggest you add your module’s source to either your device repository, or an isolated path in your kernel source.

To build these modules, the TARGET_KERNEL_MODULES variable can be used, pointing to a make target that will build and install such modules. Definition of such a target is the device author’s responsibility, the only restriction is that it is a normal makefile recipe. To include, for example, the TI WLAN modules, this can be used:

TIWLAN_MODULES:
       make -C hardware/ti/wlan/wl1283/platforms/os/linux/ KERNEL_DIR=$(KERNEL_OUT) ARCH="arm" CROSS_COMPILE="arm-eabi-" TNETW=1273 RANDOM_MAC=n REPORT_LOG=n
       mv hardware/ti/wlan/wl1283/platforms/os/linux/tiwlan_drv.ko $(KERNEL_MODULES_OUT)
       make -C hardware/ti/wlan/wl1283_softAP/platforms/os/linux/ KERNEL_DIR=$(KERNEL_OUT) ARCH="arm" CROSS_COMPILE="arm-eabi-" TNETW=1273 REPORT_LOG=n
       mv hardware/ti/wlan/wl1283_softAP/platforms/os/linux/tiap_drv.ko $(KERNEL_MODULES_OUT)
    
TARGET_KERNEL_MODULES := TIWLAN_MODULES

As a rule of thumb, you can just paste your current standalone build commands into a make recipe, replacing the kernel source path with the $(KERNEL_OUT) variable.

Step 4. Configuring the fallback to prebuilts

If for some reason the kernel source can’t be present, you can still fall back to prebuilt binaries, by defining the TARGET_PREBUILT_KERNEL variable, like this:

TARGET_PREBUILT_KERNEL := device/vendor-name/device-name/kernel

Step 5. Building the kernel or full ROM

Now that your custom kernel is linked to your device, you can build the device kernel or the device full ROM as you would do with an official kernel, as described in the first part of this page.

Full configuration example

The following is the p920’s configuration (device/vendor-name/device-name/BoardConfig.mk), which attempts to build the kernel, uses external modules, and has a prebuilt fallback:

# Try to build the kernel
TARGET_KERNEL_CONFIG := cyanogenmod_cosmo_defconfig
# Keep this as a fallback
TARGET_PREBUILT_KERNEL := device/lge/p920/kernel

KERNEL_EXTERNAL_MODULES:
make -C hardware/ti/wlan/wl1283/platforms/os/linux/ KERNEL_DIR=$(KERNEL_OUT) ARCH="arm" CROSS_COMPILE="arm-eabi-" TNETW=1273 RANDOM_MAC=n REPORT_LOG=n
mv hardware/ti/wlan/wl1283/platforms/os/linux/tiwlan_drv.ko $(KERNEL_MODULES_OUT)
make -C hardware/ti/wlan/wl1283_softAP/platforms/os/linux/ KERNEL_DIR=$(KERNEL_OUT) ARCH="arm" CROSS_COMPILE="arm-eabi-" TNETW=1273 REPORT_LOG=n
mv hardware/ti/wlan/wl1283_softAP/platforms/os/linux/tiap_drv.ko $(KERNEL_MODULES_OUT)

TARGET_KERNEL_MODULES := KERNEL_EXTERNAL_MODULES

See also

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Make Clean Vs Make Clobber

make is pretty smart, and picks up what has changed from the last build, so if you run repo sync and then build without cleaning, in most cases it should work just fine.

One exception would be after adding or updating proprietary vendor binaries. Per Google’s Android documentation, Building for devices, Google does recommend:

Cleaning up when adding proprietary binaries

In order to make sure that the newly installed binaries are properly taken into account after being extracted, the existing output of any previous build needs to be deleted with make clobber.

make clean does the same thing as make clobber, which is removing all generated files including those in ($OUT_DIR) if defined.

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Adding Your Own App

Intro: Adding a new app to the build

So after completing a build, people have been asking how to add their own app(s) to the CyanogenMod .zip file.

The “easy” way– Add it to the zip manually

One way to do this is to simply add the .apk into the .zip and then edit the recovery installation script (written in a simple scripting language called “edify“) to copy the file from the .zip to the device.

The “right” way: Make a part of the build repository so it auto-builds

Add app source to /packages/apps

You can do this manually, or you can do it via the .repo/local_manifests/*.xml. If you do it this way, a repo sync will update the source to your app from whatever git repository you name in the local manifest. It’s pretty easy to use, and allows you to override/replace/add/remove any official CM repository with one or more of your own.

Determine the name of the project from Android.mk

Regardless of how you put the source in packages/apps/, assuming that the source for the app has an Android.mk Makefile, you can get it to automatically build and install the resulting file in your $OUT directory (and thus your .zip) by simply determining the name of the project, which is typically defined in Android.mk with this:

LOCAL_PACKAGE_NAME := MyPackageName

Add the project to device.mk (or whatever .mk) in the device folder

Then just add that project to be built in the /device/[MANUFACTURER]/[CODENAME]/device.mk file.

Example:

Let’s look at the grouper device aka the Nexus 7. You want to find where the list of packages to build is for this device, in device/asus/grouper/device-common.mk.

Note:

For the nexus 7, the device-common.mk file is shared with the tilapia device (the Nexus 7 GSM version), so if you’re building for another device that doesn’t have device-common.mk, you’d probably make the edit to device.mk instead.

Now you have a choice. If PRODUCT_PACKAGES was previously defined, you can add a value like this:

PRODUCT_PACKAGES += MyPackageName

The += part means to append it to the list.

Or, if it’s simpler, you can just add it to the end an existing PRODUCT_PACKAGES list of projects by appending a “\” to the last item and then adding MyPackageName at the end. Notice that you can’t put any commented lines (ie, lines starting with #) or even blank lines in the list of items to be built.

So if the list looks like this…

PRODUCT_PACKAGES := \
lights.grouper \
audio.primary.grouper

…you’d add it to the end:

PRODUCT_PACKAGES := \
lights.grouper \
audio.primary.grouper \
MyPackage

If the source for your app does not have the Android.mk makefile stuff, you’ll need to add it. You can use any of the existing packages in packages/apps as a model for what needs to be done to build your particular app.

See here for official documentation on Android .mk files.

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Dealing With Build Errors

During a build, it’s normal to see the occasional warning pop by… let it go all the way to the end and see if you get a cm-[whatever].zip file

But if it stops generally you get a message at the end that says something about an error, and then if you scroll up (or do a reverse-search for “error” from the end), you’ll get the actual line that causes the error.

I usually run into one of four types of errors, although there are more:

  1. A missing file error — when the build first starts, the build system takes a look at all Android.mk files (and all the .mk files that those include, such as cm.mk or BoardConfig.mk). These Makefiles contain info about each of the projects (“modules”) that are going to be built. Some of these files, such as device/asus/grouper/device.mk, specify that as part of the build, certain non-compiled or pre-compiled files such as .gifs or binary blobs should be directly copied to a directory in $OUT (the target directory where the build goes). If the build system can’t find the file, you’ll get an error, usually really early because this stuff usually happens before other stuff is compiled. The solution is to find the missing file and supply it.
  2. An error in the build system itself (as opposed to the code once the compiling starts)– sometimes (very rarely) there are syntax errors in the .mk file itself… usually this type of error will occur very very early in the build, and you can get a clue of what’s wrong from the error. If it’s not a typo, it could be a missing build tool on your system, but the errors are usually pretty helpful in indicating the issue. If you don’t know what’s up, someone in the forum or on IRC can generally help. Also, if you type git log from within the directory, you can see a list of all the changes that have been made recently to the repository. If you say git show [LONGSTRINGIDOFTHECOMMIT], it will show you what changed recently. This can help figure what the deal is.
  3. a code-related error that happens during the build. This is the bulk of errors. Programming errors and such that happen as the build is going. Syntax errors and that kind of thing. The problem might be in a Java (.java) file, or in a C (.c) file, or in a C++ (.cpp) file or a header (.h) or whatever. This is just a regular building bug that needs to be fixed in the code, and may require some programming knowledge, although simple typos and such can be figured out just by looking at surrounding code. The error usually says something like “error 1” and then you have to scroll back (do a reverse-search if you can) for the word “error”, which should then show you the exact file and line # containing the error as well as a description of what the error is. This is your basic programming issue and not an Android specific thing.
  4. linking error— sometimes the files themselves compile fine, but there’s a linking error when various constituent files are combined together to create one binary (which may be an executable or a library or whatever). Sometimes this is the hardest one to solve, but again, people in the forums can usually help. Errors like this usually appear at the end when something depends on something you’ve built previously, but it doesn’t work right. And again, this is nothing specific to Android. It’s a basic programming thing.

99% of the time you do a repo sync and build a fresh version, the system will be stable and there shouldn’t be any show-stopping errors that halt the build– code usually isn’t checked into upstream unless it’s been thoroughly tested. That said, sometimes bugs sneak in, especially in the days following a Google code drop. So if you find a bug and are able to fix it, be sure to submit the fix back to review.cyanogenmod.org so that it can be quickly incorporated into the build.

Source: http://forum.xda-developers.com/showpost.php?p=30711199&postcount=39

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.

Development Resources

Aside from the information on this wiki, there are plenty of sites on the Internet that will teach you the basics of programming and development. Here are some of our favorite free external sites.

Note:

Not only is the source code for Android freely available, the tools, libraries, compilers, and everything else used to build Android apps and Android itself are also available at no cost. Even better, there are free instructions, tutorials, guides, sample code, lessons, and more all over the Internet. So provided that you have a decent computer, a reliable Internet connection, and enough time to sit and learn, you should have no financial barriers to writing your own apps and building CyanogenMod itself right at home.

Programming Basics

If you’re entirely new to the world of programming, it may not be a bad idea to spend a few days perusing some of the most basic concepts before you jump into specific languages. Here are a few sites that offer some elementary lessons that will get you started.

  • Code Academy — A web site dedicated to teaching you how to write programs. It’s interactive and tracks your progress, even allowing you to share what you’re learning with others. Code Academy uses the JavaScript language. JavaScript isn’t the same as Java (the language in which most Android apps are written), but the concepts are pretty much the same, and you’ll be able to apply what you learn to writing Android apps. It’s also worth noting that JavaScript is a language run on most Web browsers, so the skills you learn from this site will be instantly useful if you want to create interactive web pages and even user interface stuff in other languages.
  • MIT’s Introduction to Programming Class — if you’re more into traditional classroom style education, consider taking the free Open CourseWare classes from MIT. This class is for those who have little to no previous programming experience and uses the Python language. Python, a very powerful language, is available on Android devices, but concepts learned with Python also translate to Java, C, and C++.

Learn the Java language

Many apps on Android are written in Java, and much of Android’s internal frameworks are also written in Java. So having an familiarity of the Java language is helpful not only for writing your own apps, but if you want to tweak or add features to the Android user interface itself.

  • Thinking in Java — a free online book by Bruce Eckel. This book teaches the language of Java. It doesn’t include stuff particular to Android, but covers the basic syntax and linguistic concepts that Java programmers use. If you’re just starting with Java, this is a good book to read. Sample code is included. Should you prefer a newer paper-version, “Thinking in Java” is available as a printed edition as well.

Learn the C language

Much of the “lower level” portion of Android are written in the C language. The Linux-based Android kernel is also written in C, and C is used by many apps as well.

Learn the C++ language

C++ is an “object oriented” version of C.

Learn about the build system (GNU Make)

  • Google’s original documentation about the build system
  • GNU Make manual — the Android build system is built on top of the “make” command. It’s not quite a programming language, but it is a potentially complex mix of “recipes” and “rules” that you must understand to know how Android efficiently builds all the code into a flashable .zip you can install onto a device.
  • The Android-Building Group — this is Google’s official Google Group for building AOSP (Android Open Source Project– or vanilla Android from Google). If you have questions, this is a good place to find answers.

Learn about the Android kernel (based on the Linux kernel)

  • How To Build A Kernel A tutorial from Google on how to build the Android kernel from scratch. CyanogenMod will automatically build the kernel as part of the build, provided that the kernel is in /kernel/vendorname/device/codename and referenced from the appropriate .mk file.

Learn about the Android Frameworks

The official Android Developer Site — This is the central documentation site from Google about development for Android– in other words, bookmark this site, as you will refer to it again and again as you create your own apps (or change the framework itself to affect apps that run).

Android classes — If you’re going to write a Java program for Android, this is the central location for learning about all the Android-specific classes available.

Content of this page is based on informations from wiki.cyanogenmod.org, under CC BY-SA 3.0 licence.