Skip to content

Using gdb to enable core dumps on a running process

09-Aug-11

From C we would call getrlimit

int getrlimit(int resource, struct rlimit *rlim);

Where resource:

#define RLIMIT_CORE 4

And rlimit:

struct rlimit {
    unsigned long   rlim_cur;
    unsigned long   rlim_max;
};

Calculating rlimit size from gdb:

user@computer:$ (gdb) print sizeof(struct rlimit)
$1 = 16

And mallocing the memory:

user@computer:$ (gdb) set $limit=(long long *)malloc(sizeof(struct rlimit))
user@computer:$ (gdb) print $limit
$2 = 0x805b428

Set both rlim_cur and rlim_max to RLIM_INFINITY.

user@computer:$ (gdb) set $limit[0]=0x7fffffffffffffff
(gdb) set $limit[1]=0x7fffffffffffffff

Call setrlimit. Note that 4 is RLIMIT_CORE.

user@computer:$ (gdb) call (int)setrlimit(4, $limit)
$1 = 0

Detach from the process and quit.

user@computer:$ (gdb) detach
(gdb) q

Now if you signal your process to core dump, it will

user@computer:$ killall -ABRT myprocess

If getrlimit is not callable but is linked in, you can try:

user@computer:$ (gdb) info function getrlimit
All functions matching regular expression "getrlimit":

Non-debugging symbols:
0x0079e930 __getrlimit
0x0079e930 __new_getrlimit
0x0079e930 getrlimit@@GLIBC_2.2
0x0079e9d0 __new_getrlimit64
0x0079e9d0 getrlimit64@@GLIBC_2.2
0x007a7380 __GI___old_getrlimit
0x007a7380 __old_getrlimit
0x007a7380 getrlimit@GLIBC_2.0
0x007e4250 __old_getrlimit64
0x007e4250 getrlimit64@GLIBC_2.1

Which would be callable by:

((int (*)(int, struct rlimit)) p)(resource, rlp)
user@computer:$ (gdb) print ((int (*)(int, struct rlimit)) 0x0079e930)(4, 0x805b428)
$6 = 0

Checking the malloced struct rlimit:

user@computer:$ (gdb) x/2xw 0x805b428
0x805b428: 0xffffffff 0xffffffff

Debugging Android core dumps

04-Aug-11

When a process crashes, a core dump (called Tombstone in Android) is printed out in the logcat and stored under /data/tombstones/tombstone_nn, where nn is just a counter.

To get some useful info out of it we need to dereference it with the source. The libraries on the target are stripped of symbols, so you'll need the unstripped ones from /out/product/name/symbols/system/libwhatever.so.

Then you can use the addr2line located in ${android-src}/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-addr2line to dereference it.

Getting hands on, the crash I am looking at looks like:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'unknown'
pid: 1384, tid: 1384  >>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr e08f3007
 r0 69708128  r1 00000000  r2 00000002  r3 00000000
 r4 00000000  r5 69708128  r6 69709214  r7 0000adf8
 r8 00000000  r9 00000000  10 00000000  fp 00000000
 ip 697108f8  sp 7e8fca08  lr e08f3003  pc 4013eb04  cpsr 80000010
 d0  968f6dec00000000  d1  6f20656c69709214
 d2  6e6f635f726f6c62  d3  2e6e6f697372652f
 d4  0000000000000000  d5  0000000000000000
 d6  3f80000000000000  d7  00000000ced2e124
 d8  0000000000000000  d9  0000000000000000
 d10 0000000000000000  d11 0000000000000000
 d12 0000000000000000  d13 0000000000000000
 d14 0000000000000000  d15 0000000000000000
 d16 0000000000000000  d17 0000000000000000
 d18 0000000000000000  d19 0000000000000000
 d20 0000000000000000  d21 0000000000000000
 d22 0000000000000000  d23 0000000000000000
 d24 0000000000000000  d25 0000000000000000
 d26 0000000000000000  d27 0000000000000000
 d28 0000000000000000  d29 0000000000000000
 d30 0000000000000000  d31 0000000000000000
 scr 00000010

         #00  pc 0003eb04  /system/lib/libasound.so
         #01  pc 0003edc8  /system/lib/libasound.so
         #02  pc 0000a9bc  /system/lib/libaudio.so
         #03  pc 0000c2d8  /system/lib/libaudio.so
         #04  pc 000234f8  /system/lib/libaudioflinger.so
         #05  pc 00029a06  /system/lib/libaudioflinger.so
         #06  pc 000088f2  /system/bin/mediaserver
         #07  pc 000089e6  /system/bin/mediaserver
         #08  pc 00014b52  /system/lib/libc.so

code around pc:
4013eae4 e1a0e00f e59cf000 e8bd8010 e92d4010
4013eaf4 e590e010 e1a03001 e3a02002 e3a01000
4013eb04 e59ec004 e1a0e00f e59cf000 e8bd8010
4013eb14 e590c010 e1a03002 e92d4010 e59c2008
4013eb24 e3120008 03e00015 08bd8010 e1a02001

code around lr:
e08f2fe0 ffffffff ffffffff ffffffff ffffffff
e08f2ff0 ffffffff ffffffff ffffffff ffffffff
e08f3000 ffffffff ffffffff ffffffff ffffffff
e08f3010 ffffffff ffffffff ffffffff ffffffff
e08f3020 ffffffff ffffffff ffffffff ffffffff

stack:
    7e8fc9c8  0000aed0
    7e8fc9cc  697107b8
    7e8fc9d0  0000afa0
    7e8fc9d4  6970c17f  /system/lib/libaudio.so
    7e8fc9d8  00000000
    7e8fc9dc  0000aa98
    7e8fc9e0  0000aaf8
    7e8fc9e4  0000aac8
    7e8fc9e8  68223204
    7e8fc9ec  0000b854
    7e8fc9f0  0000aaf8
    7e8fc9f4  00000000
    7e8fc9f8  0000001b
    7e8fc9fc  0000aeb8
    7e8fca00  df002777
    7e8fca04  e3a070ad
#00 7e8fca08  00000000
    7e8fca0c  4013edcc  /system/lib/libasound.so
#01 7e8fca10  0000adc8
    7e8fca14  3f800000
    7e8fca18  00000000
    7e8fca1c  6970a9c0  /system/lib/libaudio.so
#02 7e8fca20  0000adc8
    7e8fca24  6970c2db  /system/lib/libaudio.so
#03 7e8fca28  0000adc8
    7e8fca2c  68d234fb  /system/lib/libaudioflinger.so
#04 7e8fca30  0000adc8
    7e8fca34  00000000
    7e8fca38  00000000
    7e8fca3c  3f800000
    7e8fca40  00000000
    7e8fca44  68d29a0b  /system/lib/libaudioflinger.so
#05 7e8fca48  00000000
    7e8fca4c  00000000
    7e8fca50  00000000
    7e8fca54  00000000
    7e8fca58  00000000
    7e8fca5c  00000000
    7e8fca60  00000000
    7e8fca64  00000000
    7e8fca68  7e8fcab4
    7e8fca6c  00000000
    7e8fca70  00000000
    7e8fca74  00000000
    7e8fca78  00000000
    7e8fca7c  0000adc8
    7e8fca80  6821764d  /system/lib/libbinder.so
    7e8fca84  0000ad50
    7e8fca88  7e8fcaec
    7e8fca8c  000088f5  /system/bin/mediaserver
#06 7e8fca90  00000019
    7e8fca94  7e8fc660
    7e8fca98  0000ad98
    7e8fca9c  0000ad50
    7e8fcaa0  7e8fcab4
    7e8fcaa4  7e8fcae4
    7e8fcaa8  00000001
    7e8fcaac  000089eb  /system/bin/mediaserver
#07 7e8fcab0  00000001
    7e8fcab4  7e8fcae4
    7e8fcab8  0000ad50
    7e8fcabc  0000b848
    7e8fcac0  00008894  /system/bin/mediaserver
    7e8fcac4  6fd14b55  /system/lib/libc.so
#08 7e8fcac8  00000000
    7e8fcacc  00000000
    7e8fcad0  00000000
    7e8fcad4  00000000
    7e8fcad8  00000000
    7e8fcadc  ffffffe4
    7e8fcae0  00000001
    7e8fcae4  7e8fcbf0
    7e8fcae8  00000000
    7e8fcaec  7e8fcc08
    7e8fcaf0  7e8fcc45
    7e8fcaf4  7e8fcc6d
    7e8fcaf8  7e8fcc80
    7e8fcafc  7e8fcc95
    7e8fcb00  7e8fccb0
    7e8fcb04  7e8fccc3
    7e8fcb08  7e8fcce0
    7e8fcb0c  7e8fcd00

Which can be dereferenced as follows:

#00  pc 0003eb04  /system/lib/libasound.so

${android-src}/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-addr2line -f -e out/target/product/imx51_ccwmx51js/symbols/system/lib/libasound.so 0003eb04

snd_mixer_selem_has_playback_channel
/home/alex/Projects/android/external/alsa-lib/src/mixer/simple.c:270

I'll omit the addr2line call from now on and just show the results.

#01  pc 0003edc8  /system/lib/libasound.so

snd_mixer_selem_set_playback_volume_all
/home/alex/Projects/android/external/alsa-lib/src/mixer/simple.c:478

#02  pc 0000a9bc  /system/lib/libaudio.so

_ZN7android9ALSAMixer15snd_mixer_selem_set_playback_volume_all
/home/alex/Projects/android/hardware/alsa_sound/ALSAMixer.cpp:237

#03  pc 0000c2d8  /system/lib/libaudio.so

_ZN7android18A2dpAudioInterface15setMasterVolumeEf
/home/alex/Projects/android/frameworks/base/services/audioflinger/A2dpAudioInterface.cpp
:210

#04  pc 000234f8  /system/lib/libaudioflinger.so

_ZN7android12AudioFlinger15setMasterVolumeEf
/home/alex/Projects/android/frameworks/base/services/audioflinger/AudioFlinger.cpp:445

#05  pc 00029a06  /system/lib/libaudioflinger.so

AudioFlinger
/home/alex/Projects/android/frameworks/base/services/audioflinger/AudioFlinger.cpp:144

#06  pc 000088f2  /system/bin/mediaserver

_ZN7android13BinderServiceINS_12AudioFlingerEE7publishEv
/home/alex/Projects/android/frameworks/base/include/binder/BinderService.h:39

#07  pc 000089e6  /system/bin/mediaserver

_ZN7android13BinderServiceINS_12AudioFlingerEE11instantiateEv
/home/alex/Projects/android/frameworks/base/include/binder/BinderService.h:50

#08  pc 00014b52  /system/lib/libc.so

__libc_init
/home/alex/Projects/android/bionic/libc/bionic/libc_init_dynamic.c:114

The netlink socket interface

26-May-11

Simply put Netlink is a communication channel between kernel and user space processes. Many applications that use the interface use the libnetlink library to abstract its API. I haven't found the library elsewhere, so recently I had to extract it from iproute. Here it is along with an usage example.

libnetlink.h (Right click and save as)

libnetlink.c (Right click and save as)

#include <stdio.h>
#include <stdlib.h>
#include <sys socket.h="">
#include <libnetlink.h>
 
#define RTNLGRP_MSGS \
(RTNLGRP_IPV4_IFADDR|RTNLGRP_IPV4_ROUTE|RTNLGRP_IPV6_IFADDR|RTNLGRP_IPV6_ROUTE)
 
int accept_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	switch(n-&gt;nlmsg_type)
	{
		case RTM_NEWLINK:
			printf(&quot;Link state changed\n&quot;);
			break;
		case RTM_DELLINK:
			printf(&quot;Interface Down\n&quot;);
			break;
		case RTM_GETLINK:
		case RTM_SETLINK:
		case RTM_NEWADDR:
		case RTM_DELADDR:
		case RTM_GETADDR:
		case RTM_NEWROUTE:
		case RTM_DELROUTE:
		case RTM_GETROUTE:
		case RTM_NEWRULE:
		case RTM_DELRULE:
		case RTM_GETRULE:
		default:
			printf(&quot;other message: %d %p\n&quot;, n-&gt;nlmsg_type, arg);
			break;
	}
}
 
 
int main()
{
	int res;
	struct rtnl_handle rth;
	unsigned int groups = RTNLGRP_MSGS;
 
	if (rtnl_open(&amp;rth,groups) &lt; 0)
	{
		printf(&quot;rtnl_open() failed in %s %s\n&quot;,__FUNCTION__,__FILE__);
		return -1;
	}
	if (rtnl_listen(&amp;rth, accept_msg, &quot;cookie&quot;)&lt;0)
	{
		printf(&quot;failed in rtnl_listen()\n&quot;);
		return -1;
	}
	printf(&quot;main done.\n&quot;);
 
}
</libnetlink.h></sys></stdlib.h></stdio.h>

 

Just place all the files in the same folder and do:

user@computer:$ gcc libnetlink.c netmon.c -I. -o netmon

References:

netlink man page

Kernel Korner – Why and How to Use Netlink Socket

Short Range Devices: 802.15.4/ZigBee/DigiMesh

26-May-11

Short Range Devices in Europe

A Short Range Device (SRD) is a radio transmitter with low interference capability. They usually operate on the ISM (Industrial, Scientific and Medical) unlicensed band, and they must accept interference caused by other ISM devices.

The European Conference of Postal and Telecommunications Administrations (CEPT) is in charge of frequency assignments and output power.

For 868MHz and 2.4GHz all european countries have implemented the ERC REC 70-03 recommendation (Short Range Devices).

Networks Topology

  • Wired Network Types: Ring, Bus, Star
  • Wireless Network Types: Start (Point to multipoint) 802.15.4, Peer to peer mesh (DigiMesh) , Cluster tree mesh (ZigBee).

Mesh adds extending range, self healing and discovery.

IEEE 802.15.4

Defines 4 PHYs:

  • 868/915MHZ DSSS (Direct Sequence Spread Spectrum) with BPSK (Binary Phase-Shift Keying) modulation.
  • 868/915MHz DSSS with O-QPSK modulation.
  • 868/915MHz PSSS (Parallel Sequence Spread Spectrum) with BPSK modulation.
  • 2450MHz DSSS with O-QPSK modulation (Offset Quadrature Phase-Shift Keying).

IEEE 802.15.4 features:

  • Supports point to point and point to multipoint(Star) network types.
  • Coordinator and end nodes.
  • Reliable delivery (CSMZ/CA and MAC level p2p acks)
  • 64bit IEEE and 16bit addressing
  • 16 DSSS channels

Zigbee (2006)

Zigbee (2006) is 802.15.4 plus:

  • Mesh network type
  • Router node
  • Mesh network level acks.

Zigbee (2006) features include:

  • Low cost, low power, secure, reliable.
  • Lower data rates than others, more range than Bluetooth or Wi-Fi.

Zigbee stack

 

Where:

PHY: Physical operation including receive sensitivity, channel rejection, output channel, modulation and transmission rate specs.

MAC: Manages RF data transactions between nighbour devices. Includes retrieas and acks, and collision avoidance techniques (CSMA-CA).

Network: Adds routing capabilities to traverse multiple devices.

APS(AF): Application support layer and application framework. Defines various addressing objects including profiles, clusters and endpoints.

ZDO: Zigbee Device Objects, an application layer that provides device and service discovery, and advanced network management capabilities.

Devices and Addressing

There are three types of Zigbee devices: Coordinators, routers and end devices. They are addressed with 64bits or 16bits addresses.

  • 64bit IEEE is unique to every 802.15.4 device 
  • 16bit is PAN (Personal Area Network) unique. It is volatile.

Broadcast and unicast transmissions.

A broadcast message do not send acks. Routers listen to neighbours to know if the message was transmitted before trasmitting. It can retrasmit twice if the message is not heard. A BTT (broadcast transmission table) is used not to repeat messages already broadcasted. It is an expensive method time wise.

Coordinator network formation

The coordinator selects an unused channel, PANid(64 and 16bits), security policy and stack profile for the network. For that it energy scans all channels, sends a beacon request (broadcast PANid) and listens for responses. Devices can join for a specified time (node join time).

The coordinator is not needed after network setup, but each Zigbee network must have only one coordinator. The 16bit 0×0000 address is reserved for the coordinator.

Router startup

A new router must locate a router that has already joined a PANid or a coordinator. For this it sends a broadcast PAN id on each channel, and receives a unicast answer. It will attempt to join a router or coordinator.

End nodes

Low power sleep modes, can join a router or coordinator in the same way as above, but cannot act as router itself. The parent (router or coordinator) takes over Zigbee communications while the child is asleep. The parent must always be awake. The number of children is limited.

Data transmission

Network Address Discovery: The 64bit address is used to find the 16bit addr then used in routing tables. If the network address discovery fails the data is discarded.

Route discovery

  • Route request (broadcast).
  • Route reply (unicast)

Routing types:

  • AODV (Ad hoc on demand distance vector) mesh routing: Routing paths are created traversing multiple nodes.  Each device knows how to send data to the next hop. Will not scale for more that around 40 devices.
  • Many to one routing: A single broadcast configures reverse routes on all devices into the device that sends the broadcast. Useful if multiple remote devices must send data to a single collector device.
  • Source routing: Data packets include the whole route. Improves routing efficiency in networks with more than 40 devices.

MAC acks are transmitted at each hop. A network ack is transmitted from destination to source nodes..

Zigbee PRO (2007)

Application Support Sublayer (APS): Supports application profiles, clusters and endpoints.

Zigbee application profiles

Formed by a collection of device descriptions. They can be private, defined by a manufacturer, or public, defined, developed and maintained by the Zigbee alliance. They have a unique profile identifier. Examples include Home Automation and Smart Energy.

By defining standard communication protocols and device functionality public profiles allow interoperability between device manufacturers.

For example the Digi XBee ZB firmware operates on a private Digi Drop-In Networking profile. However the API firmware can be used to talk to devices on public or non-Digi profiles.

Zigbee clusters

A collection of commands and attributes which define an interface to a specific functionality.

They are used to specify a unique function, service or action within an application profile. For example in the Home Automation profile we have On/Off and level control profiles.

Each cluster has a 2 byte cluster ID included in all application transmissions. 

The Zigbee alliance had defined a Zigbee Cluster Library (ZCL) that contains general use clusters to be used in any profile.

Endpoints

Similar to a TCP/IP port, a device can support one or more endpoints. Each application endpoint is defined by a 1 byte (1-240) value. Each endpoint is tied to an application profile.

The Zigbee device profile (profileID 0×0000) is implemented on all Zigbee devices. Endpoint 0 is a reserved endpoint for the Zigbee device profile, called the ZDO endpoint. 

Zigbee Device Objects (ZDO)

The ZDO (endoint 0) supports the discovery and management capabilities of the Zigbee Device Profile. All ZDP services are listed on the Zigbee specificiation. Each service has an associated clusterID.

DigiMesh

A Digi International propietary peer to peer protocol (one node type) using the same AODV routing algorithm as Zigbee, but supporting sleeping routers.

Digi International XBee Products

Digi's Zigbee products are based on Ember ZNet 2.5

  • XBee PRO 868: 869,4 to 869,65 MHz
  • XBee: 2405 to 2480 MHz
  • XBee Pro: 2410 to 2470 MHZ.

The 2.4 GHz product line conflicts with Wi-Fi 802.11b. The best channel configuration is:

  • 802.11b Channel 12: 2454,5 to 2479,5 MHz
  • 802.11b Channel 13: 2459,5 to 2484,5 MHz
  • 802.11b Channel 14: 2464,5 to 2489,5 MHz
  • 802.15.4 Channel 25: 2472,5 to 2477,5 MHz
  • 802.15.4 Channel 26: 2477,5 to 2482,5 MHz

Digi's Zigbee PRO products (XBee ZB stack) are based on Ember ZNet 3.x.x ZigBee-PRO stack. Not over the air compatible with ZNet 2.5.

The XBee ZB firmware allows applications to easily send ZDO messages.

The Digi XBee offers:

  • UART data input
  • 4 ADCs 10bit resolution 1KHz max sample rate (no DACs)
  • 8+1 DIO lines
  • PWM (RSSI) output
  • Supply voltage monitoring
  • Over the air configuration change, DIO set/reset, read ADC values, update firmware, automatic low battery warning.

Digi API/AT

An application layer on top of 802.15.4/DigiMesh/Ember ZNet 2.5/Ember ZNet 3.x

AT mode

  • Transparent out of the box operation. All received serial data is transmitted unless in command mode.
  • +++ to enter command mode.
  • No error information.
  • Easier for an application to support.

API frames

  • Easy to transmit to multiple destinations.
  • Simple frames require only module addressing
  • API frames can expose ZigBees addressing fields, including clusterIDs profileIDs.
  • Indicates delivery status, sender's adress and network level messaging.
  • Profiles are supported.

Further reading:  Tutorial: Making the right ZigBee systems design choices

Configuring a custom GPIO based keypad in Android

15-Feb-11

When developing for Android you need the basic keys to navigate. Usually on early stages a simple GPIO keypad where each key is mapped to a CPU GPIO is all you need.

 
The first thing to do is to add GPIO keyboard support to the Linux kernel, so reconfigure and add the following:
 
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+CONFIG_KEYBOARD_GPIO=y

+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
 
Then you'll need to register your specific keypad as follows:
 
#define GPIO_BUTTON_LOW(gpio_num, event_code, description)	\
	GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description)
 
#define HOME_KEY_GPIO_NR 70 /* Change to match GPIO number */
#define MENU_KEY_GPIO_NR 1 /* Change to match GPIO number */
 
static struct gpio_keys_button gpio_keys[] = {
		GPIO_BUTTON_LOW(MENU_KEY_GPIO_NR,	KEY_MENU /* 139	in input.h */,	&quot;menu&quot;),
		GPIO_BUTTON_LOW(HOME_KEY_GPIO_NR,	KEY_HOME /* 102 in input.h */,	&quot;home&quot;),
};
 
struct gpio_keys_platform_data gpio_key_info = {
	.buttons	= gpio_keys,
	.nbuttons	= ARRAY_SIZE(gpio_keys),
};
 
struct platform_device keys_gpio = {
	.name	= &quot;gpio-keys&quot;,
	.id	= -1,
	.dev	= {
		.platform_data	= &amp;gpio_key_info,
	},
};
 
platform_device_register(&amp;keys_gpio);
 
Once that is done and recompiled, booting into Android the logcat output shows:
 
/EventHub( 1051): New device: path=/dev/input/event1 name=mxc_ts id=0x10000 (of 0x1) index=1 fd=56 classes=0x4
E/EventHub( 1051): could not get driver version for /dev/input/mouse0, Not a typewriter
E/EventHub( 1051): could not get driver version for /dev/input/mice, Not a typewriter
I/EventHub( 1051): New keyboard: device->id=0x10001 devname='gpio-keys' propName='hw.keyboards.65537.devname' keylayout='/system/usr/keylayout/qwerty.kl'
I/EventHub( 1051): New device: path=/dev/input/event0 name=gpio-keys id=0x10001 (of 0x2) index=2 fd=59 classes=0x1
 
The next step is to avoid the default qwerty.kl layout and provide our own. So we add a new key layout to the Android user space:
 
device/<vendor>/<product>/gpio-keys.kl
key 139    MENU              WAKE
key 102    HOME              WAKE
 
And a key character map:
 
device/<vendor>/<product>/gpio-keys.kcm
[type=QWERTY]

# keycode       display number  base    caps    fn      caps_fn

A               'A'     '2'     'a'     'A'     '#'     0x00
B               'B'     '2'     'b'     'B'     '<'     0x00
C               'C'     '2'     'c'     'C'     '9'     0x00E7
D               'D'     '3'     'd'     'D'     '5'     0x00
E               'E'     '3'     'e'     'E'     '2'     0x0301
F               'F'     '3'     'f'     'F'     '6'     0x00A5
G               'G'     '4'     'g'     'G'     '-'     '_'
H               'H'     '4'     'h'     'H'     '['     '{'
I               'I'     '4'     'i'     'I'     '$'     0x0302
J               'J'     '5'     'j'     'J'     ']'     '}'
K               'K'     '5'     'k'     'K'     '"'     '~'
L               'L'     '5'     'l'     'L'     '''     '`'
M               'M'     '6'     'm'     'M'     '!'     0x00
N               'N'     '6'     'n'     'N'     '>'     0x0303
O               'O'     '6'     'o'     'O'     '('     0x00
P               'P'     '7'     'p'     'P'     ')'     0x00
Q               'Q'     '7'     'q'     'Q'     '*'     0x0300
R               'R'     '7'     'r'     'R'     '3'     0x20AC
S               'S'     '7'     's'     'S'     '4'     0x00DF
T               'T'     '8'     't'     'T'     '+'     0x00A3
U               'U'     '8'     'u'     'U'     '&'     0x0308
V               'V'     '8'     'v'     'V'     '='     '^'
W               'W'     '9'     'w'     'W'     '1'     0x00
X               'X'     '9'     'x'     'X'     '8'     0xEF00
Y               'Y'     '9'     'y'     'Y'     '%'     0x00A1
Z               'Z'     '9'     'z'     'Z'     '7'     0x00

# on pc keyboards
COMMA           ','     ','     ','     ';'     ';'     '|'
PERIOD          '.'     '.'     '.'     ':'     ':'     0x2026
AT              '@'     '0'     '@'     '0'     '0'     0x2022
SLASH           '/'     '/'     '/'     '?'     '?'     '\'

SPACE           0x20    0x20    0x20    0x20    0xEF01  0xEF01
ENTER         0xa     0xa     0xa     0xa     0xa     0xa

TAB             0x9     0x9     0x9     0x9     0x9     0x9
0               '0'     '0'     '0'     ')'     ')'     ')'
1               '1'     '1'     '1'     '!'     '!'     '!'
2               '2'     '2'     '2'     '@'     '@'     '@'
3               '3'     '3'     '3'     '#'     '#'     '#'
4               '4'     '4'     '4'     '$'     '$'     '$'
5               '5'     '5'     '5'     '%'     '%'     '%'
6               '6'     '6'     '6'     '^'     '^'     '^'
7               '7'     '7'     '7'     '&'     '&'     '&'
8               '8'     '8'     '8'     '*'     '*'     '*'
9               '9'     '9'     '9'     '('     '('     '('

GRAVE           '`'     '`'     '`'     '~'     '`'     '~'
MINUS           '-'     '-'     '-'     '_'     '-'     '_'
EQUALS          '='     '='     '='     '+'     '='     '+'
LEFT_BRACKET    '['     '['     '['     '{'     '['     '{'
RIGHT_BRACKET   ']'     ']'     ']'     '}'     ']'     '}'
BACKSLASH       '\'     '\'     '\'     '|'     '\'     '|'
SEMICOLON       ';'     ';'     ';'     ':'     ';'     ':'
APOSTROPHE      '''     '''     '''     '"'     '''     '"'
STAR            '*'     '*'     '*'     '*'     '*'     '*'
POUND           '#'     '#'     '#'     '#'     '#'     '#'
PLUS            '+'     '+'     '+'     '+'     '+'     '+'
 
And we se the system properties accordingly:
 
device/vendor/product/system.prop
android.keylayout.gpio-keys = /system/usr/keylayout/imx51_ccwmx51js_keypad.kl
android.keychar.gpio-keys = /system/usr/keychars/imx51_ccwmx51js_keypad.kcm
Finally we modify the Makefile adding the following:
 
device/&lt;vendor&gt;/%lt;product&gt;/AndroidBoard.mk
 
include $(CLEAR_VARS)
LOCAL_SRC_FILES := gpio-keys.kcm
include $(BUILD_KEY_CHAR_MAP)
 
include $(CLEAR_VARS)
 
file := $(TARGET_OUT_KEYLAYOUT)/gpio-keys.kl
 
ALL_PREBUILT += $(file)
 
$(file): $(LOCAL_PATH)/gpio-keys.kl | $(ACP)
	$(transform-prebuilt-to-target)
Recompiling and booting we should see the new keyboard in logcat.
 

Debugging keyboard problems

 
The first place to start debugging are your kernel changes. For this we will use evtest, which is a device test program. We cross-compile it with your favourite toolchain:
 
arm-cortex_a8-linux-gnueabi-gcc evtest.c -o evtest –static
 
And we should see:
 
file evtest
evtest: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
Then we run it on the target:
 
./evtest /dev/input/event0

/ # ./evtest /dev/input/event0
Input driver version is 1.0.0
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys"
Supported events:
  Event type 0 (Sync)
  Event type 1 (Key)
    Event code 102 (Home)
    Event code 116 (Power)
    Event code 139 (Menu)
    Event code 158 (Back)
    Event code 217 (Search)
Testing ... (interrupt to exit)
And we press some of those keys.
 
Event: time 45.259326, type 1 (Key), code 158 (Back), value 1
Event: time 45.259332, -------------- Report Sync ------------
Event: time 45.360582, type 1 (Key), code 158 (Back), value 0
Event: time 45.360586, -------------- Report Sync ------------
Event: time 46.301369, type 1 (Key), code 139 (Menu), value 1
Event: time 46.301374, -------------- Report Sync ------------
Event: time 46.472442, type 1 (Key), code 139 (Menu), value 0
Event: time 46.472446, -------------- Report Sync ------------
Event: time 47.469043, type 1 (Key), code 102 (Home), value 1
 
If the output is something similar to the above then all is fine, the kernel event system is recognizing your button presses.
 
Then we need to confirm that the Android framework is receiving the events. For that we can use getevent from the Android shell, or better a statically compiled busybox shell.
 
getevent

/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0003 0018 00000000
/dev/input/event1: 0001 014a 00000000
/dev/input/event1: 0000 0000 00000000
printf("%s: ", device_names[i]);
printf("%04x %04x %08x", event.type, event.code, event.value);
 
And it just prints from the kernel input_event struct:
 
struct input_event {
  27        struct timeval time;
  28        __u16 type;
  29        __u16 code;
  30        __s32 value;
  31
}
To understand the protocol you need to have a look at the kernel's input system.
 

Debugging early kernel booting problems

27-Jan-11

 

For the purpose of this entry let's assume we are working on the BSP for a new ARM hardware platform based on the Freescale MXC family.
 
The bootloader entry point to the kernel is in the start section of head.S, described in detail in the ARM Linux boot sequence page.
 
Depending on your hardware, you may be able to use a GPIO driven LED to check that the bootloader has done it's job and the kernel is effectively running. For a Digi ConnectCore Wi-i.MX51 some assembler that will turn off user led 2 is:
 
  ldr r1, data			@ mw 73f8c000 200
  ldr r2, gpio3
  str r1 , [r2]
 
gpio3:
		.word 0x73f8c000
data:
		.word 0x200
After we verify it is running, we might want to have some serial output.
 
The last bootloader serial output is:
user@computer:$ Starting kernel ..

And the first kernel serial output should be:
user@computer:$ Uncompressing Linux..

This does not come from the kernel itself, but from the kernel loader decompress_kernel function in misc.c
 
Which uses putstr, defined in the same place, and putc which is the platform specific code. In the case of the MXC platform it lives in uncompress.h
 
And looks like:
 
static void putc(int ch)
{
      if (!uart_base)
              return;
      if (!(UART(UCR1) &amp; UCR1_UARTEN))
              return;
 
      while (!(UART(USR2) &amp; USR2_TXFE))
            barrier();
      UART(TXR) = ch;
}
 
So the first thing is to check that the uart_base is correctly set up for your hardware.
 
After that, configuring the kernel with DEBUG_LL will give you serial output before the console is initialized.
 
You can use something like:
 
extern void printascii(const char *);
printascii("Literal string\n");
 
Or something more convoluted, as in:
 
extern void printascii(const char *);
 
static void edbg(const char *fmt, ...)
{
	va_list va;
	char buff[256];
 
	va_start(va, fmt);
	vsprintf(buff, fmt, va);
	va_end(va);
 
	printascii(buff);
}
 
You can also add it to printk with the following patch:
 
diff --git a/kernel/printk.c b/kernel/printk.c
index 444b770..bbe6c09 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -687,6 +687,7 @@ static inline void printk_delay(void)
        }
 }
 
+extern void printascii(const char*);
 asmlinkage int vprintk(const char *fmt, va_list args)
 {
        int printed_len = 0;
@@ -757,7 +758,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                        }
                }
        }
+       printascii(printk_buf);
        /*
         * Copy the output into log_buf.  If the caller didn&#39;t provide
         * appropriate log level tags, we insert them here
 
This is useful if you are working on the serial driver itself for example.

The Android build system

10-Dec-10

Build hierarchy

 

arch: Generic as arm or x86, or more specific as mx5x for Freescale's MX5 family.
board: The development board to use.
device: Peripherals connect to the device layer.
product: Defines a complete specification of a shipping product, defining which modules to build and how to configure them.
 
One architecture, n boards, 1 board n devices, 1 device n products.
 
Building (with the prebuilt toolchain included in the Android source)
 
Load enviromental variables.
 
. build/envsetup.sh
 
This also adds helpful shell functions as:
 
printconfig – Prints the current configuration as set by the lunch and choosecombo commands.
m – Runs make from the top of the tree. This is useful because you can run make from within subdirectories. If you have the TOP environment variable set, it uses that. If you don't, it looks up the tree from the current directory, trying to find the top of the tree.
croot – cd to the top of the tree.
sgrep – grep for the regex you provide in all .c, .cpp, .h, .java, and .xml files below the current directory.
 
Set the default product to build ( for example imx51_myboard):

 
choosecombo
 
Multithreaded make:
 
make -j4 PRODUCT-imx51_myboard-eng | tee build_imx51_myboard_android.log
 
Default build variants
 
eng (make)
 
 
This is the default.
  • Installs modules tagged with: eng, debug, user, and/or development.
  • Installs non-APK modules that have no tags specified.
  • Installs APKs according to the product definition files, in addition to tagged APKs.
    • ro.secure=0
    • ro.debuggable=1
    • ro.kernel.android.checkjni=1
  • adb is enabled by default.

user (make user)

 

This is the flavor intended to be the final release.
  • Installs modules tagged with user.
  • Installs non-APK modules that have no tags specified.
  • Installs APKs according to the product definition files; tags are ignored for APK
    • modules.
    • ro.secure=1
    • ro.debuggable=0
  • adb is disabled by default.

userdebug (make userdebug)

 

The same as user, except:
 
  • Also installs modules tagged with debug.
    • ro.debuggable=1
  • adb is enabled by default.

Cleaning

 

make clean will eliminate the binaries for your chosen combo.
make installclean will suffice to switch between flavours. make clean will take a lot longer.
make clobber elimnates the binaries for all combos (all content under /out)
 
Pseudo targets
 
  • droid – make droid is the normal build.
  • all – make all builds everything make droid does, plus everything whose LOCAL_MODULE_TAGS do not include the "droid" tag. Everything that is in the tree and has an Android.mk builds.
  • clean-$(LOCAL_MODULE) and clean-$(LOCAL_PACKAGE_NAME) - Let you selectively clean one target. For example, you can type make clean-libutils and it will delete libutils.so and all of the intermediate files.
  • clean – make clean deletes all of the output and intermediate files for this configuration. This is the same as rm -rf out/<configuration>/
  • clobber – make clobber deletes all of the output and intermediate files for all configurations. This is the same as rm -rf out/.
  • dataclean – make dataclean deletes contents of the data directory inside the current combo directory. This is especially useful on the simulator and emulator, where the persistent data remains present between builds.
  • showcommands – showcommands is a modifier target which causes the build system to show the actual command lines for the build steps, instead of the brief descriptions.  
  • LOCAL_MODULE – Anything you specify as a LOCAL_MODULE in an Android.mk is made into a pseudotarget. For example, make runtime might be shorthand for make out/linux-x86-debug/system/bin/runtime (which would work).
  • targets – make targets will print a list of all of the LOCAL_MODULE names you can make.

Makefile structure

 

Makefile: One at the top level.
Android.mk: Main makefiles on a source directory.
*.mk: Secondary makefiles for a source directory.
 
Build output
 
out/host: Stuff compiled for your host
out/target: Stuff compiled for your target or emulator (specifically out/target/product/<platform-name>)
 
Usually bundled up in image files that match the partition structure on an Android device: system.img, ramdisk.img, and userdata.img
 
out/target structure
  • root/ : root file system (including init, init.rc, etc). Mounted at /
  • system/:  Android system binary/libraries. Mounted at /system
  • data/: Android data area. Mounted at /data
The above three folders can be used to create your Android file system for NFS mounting. You can have a recovery folder with an alternative root filesystem.
  • ramdisk.img: Ramdisk image generated from "root/". Not directly used.
  • system.img: EXT4 image generated from "system/". Can be programmed to a "SYSTEM" partition on SD card with "dd"
  • userdata.img: EXT4 image generated from "data/".
  • recovery.img: EXT4 image generated from "recovery/". Can be programmed to a "RECOVERY" partition on SD card with "dd"

Adding a new program to the Android source tree

  • make a directory under 'external', e.g. android/external/myprogram
  • create your c/cpp files.
  • create Android.mk as clone of external/ping/Android.mk
  • Change the names ping.c and ping to match your C/cpp files and program name
  • add the directory name in ANDROID/build/core/main.mk after external/zlib as
  • external/myprogram
  • make from the root of the source tree

Creating an Android.mk file

 

Name: Give your build a name (LOCAL_MODULE := <build_name>).
Local Variables: Clear local variables with CLEAR_VARS (include $(CLEAR_VARS)).
Files: Determine which files your application depends upon (LOCAL_SRC_FILES := main.c).
Tags: Define tags, as necessary (LOCAL_MODULE_TAGS := eng development).
Libraries: Define whether your application links with other libraries (LOCAL_SHARED_LIBRARIES := cutils).
Template file: Include a template file to define underlining make tools for a particular target (include $(BUILD_EXECUTABLE)).
 
The following snippet illustrates a typical makefile.
 
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := <buil_name>
LOCAL_SRC_FILES := main.c
LOCAL_MODULE_TAGS := eng development
LOCAL_SHARED_LIBRARIES := cutils
include $(BUILD_EXECUTABLE)
(HOST_)EXECUTABLE, (HOST_)JAVA_LIBRARY, (HOST_)PREBUILT, (HOST_)SHARED_LIBRARY,
  (HOST_)STATIC_LIBRARY, PACKAGE, JAVADOC, RAW_EXECUTABLE, RAW_STATIC_LIBRARY,
  COPY_HEADERS, KEY_CHAR_MAP
 
Makefile helper functions
 
A whole bunch of build helper functions are defined in the file build/core/definitions.mk that you can use in your own Android.mk files.
 
Try grep define build/core/definitions.mk for an exhaustive list.
 
Some possibly interesting functions:
 
print-vars – shall all Makefile variables, for debugging
emit-line – output a line during building, to a file
dump-words-to-file – output a list of words to a file
copy-one-file – copy a file from one place to another (dest on target?)
 
Add a pre-built file directly to the output area
 
You can copy a file directly to the output area, without building anything, using the add-prebuilt-files function.
 
$(call add-prebuilt-files, EXECUTABLES, $(prebuilt_files))
 

References:

Android Linux kernel additions

07-Dec-10

Google made some changes to the Linux kernel that haven't been mainstreamed. There was an attempt by placing some drivers on staging, but those were removed on 2.6.33 due to lack of maintainers.

I will use as an example the Android Linux port for Freescale's MX51, which at the time of this writing can be accessed from their public git repository, specifically the imx_2.6.35_10.10.01 branch.

 

The binder

Background

OpenBinder was introduces at BeOS, continued at PalmSource and parts of it open sourced into Linux. It's an attempt to introduce object oriented design to operating system design. OpenBinder provides object oriented representations for processes, shared memory, files etc.

It contains a Binder Shell as an example of VM for OpenBinder that lets you write Binder code in its particular language. It's a POSIX compatible shell (like bash) that sits on top of the Binder framework giving a much richer environment than you would get from a shell designed for traditional operating system services.

OpenBinder is similar to COM or CORBA, and it can be used to design graphics, user interface, and multimedia frameworks.

More background on this Introduction to OpenBinder

The original spec for the Linux port is here, although the current code is no longer compatible.

Configuration

ANDROID_BINDER_IPC

Files

drivers/staging/android/binder.c

drivers/staging/android/binder.h

 

ashmem – Android Shared Memory

Similar to POSIX shm, with different behavior and a simpler file-based API, it can be used to share memory between processes.

The advantage of ashmem over traditional Linux shared memory is that it provides a means for the kernel to reclaim these shared memory blocks if they are not currently in use.

If a process then tries to access a shared memory block the kernel has freed, it will receive an error, and will then need to reallocate the block and reload the data.

To use this, programs open /dev/ashmem, use mmap() on it, and can perform one or more of the following ioctls:

ASHMEM_SET_NAME

ASHMEM_GET_NAME

ASHMEM_SET_SIZE

ASHMEM_GET_SIZE

ASHMEM_SET_PROT_MASK

ASHMEM_GET_PROT_MASK

ASHMEM_PIN

ASHMEM_UNPIN

ASHMEM_GET_PIN_STATUS

ASHMEM_PURGE_ALL_CACHES

Ashmem has reference counting so that if many processes use the same area the area will not be removed until all processes has released it, the memory is also virtual and not physically contiguous. If physically contiguous memory is needed like for hardware reasons pmem (see below) can be used, but it has no reference counting.

To use ashmem to allocate a shared memory region:

int fd = ashmem_create_region("SharedRegionName", size); if(fd == 0) {

  data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

  if(data != MAP_FAILED)

  {

    /* It works do your stuff*/

  }

}

The only way for another process to use this shared memory area is to use mmap with the same file descriptor (fd).

To share the file descriptor we can use the Binder introduced above, as explained here.

Configuration

ASHMEM

Files

include/linux/ashmem.h

mm/ashmem.c

 

pmem – Process Memory Allocator

Used to manage large (1-16+MB) physically contiguous regions of memory shared between userspace and kernel drivers (dsp, gpu,etc). It needs UID based statistics tracking exported to /proc/uid_stat.

Configuration

ANDROID_PMEM

UID_STAT

Files

drivers/misc/pmem.c

drivers/misc/uid_stat.c

include/linux/android_pmem.h

 

Logger – System Logging Facility

Adds three device nodes under /dev/log/, events, main and radio. The paths for open, read and write on these are optimized. A read will return one event or block if not opened in non blocking mode. Writing automatically saves pid, tgid and timestamp, with level, tag and message provided by the application.

Supported ioctls include:

LOGGER_GET_LOG_BUF_SIZE: returns the size of the entire log buffer

LOGGER_GET_LOG_LEN: returns the amount of data in the log

LOGGER_GET_NEXT_ENTRY_LEN: returns size of next log entry

LOGGER_FLUSH_LOG: clears the log of data

Android user space comes with a logcat application to read the log, either from the local filesystem or using adb logcat.

There is also a system property so that applications emit their stdout and/or stderr to the log.

Configuration

ANDROID_LOGGER

Files

drivers/staging/android/logger.c

drivers/staging/android/logger.h

 

Wake Locks

A wake lock prevents the kernel from getting into low power states. Wake locks can be held from both kernel and user space.

From kernel space:

#include <linux/wakelock.h>

wake_lock_init(struct wakelock *lock, int type, const char *name);

void wake_lock(struct wake_lock *lock);

void wake_unlock(struct wake_lock *lock);

void wake_lock_timeout(struct wake_lock *lock, long timeout);

void wake_lock_destroy(struct wake_lock *lock);

int wake_lock_active(struct wake_lock *lock);

long has_wake_lock(int type);

From user space:

echo "name" > /sys/power/wake_lock

echo "name" > /sys/power/wake_unlock

A wake lock can be of two types:

WAKE_LOCK_IDLE: The system will not enter idle mode, making the device more responsive.

WAKE_LOCK_SUSPEND: The system will not suspend.

cat /proc/wakelocks will list all waitlocks.

Configuration

WAKELOCK

WAKELOCK_STAT: Report wake lock stats in /proc/wakelocks

USER_WAKELOCK: User-space wake lock api.

Files

include/linux/wakelock.h

kernel/power/userwakelock.c

kernel/power/wakelock.c

 

Early suspend

Early suspend is an extension to the standard Linux power management stages. This is not suspending the device, but some of its components like LCD, touch sensor and maybe accelerometer. We could name "Late resume" the stage that resumes these devices. The kernel calls early suspend handlers when the user requested sleep state changes.

Configuration

EARLYSUSPEND

It can be configured in three modes:

NO_USER_SPACE_SCREEN_ACCESS_CONTROL

CONSOLE_EARLYSUSPEND: Register early suspend handler to perform a console switch to when user-space should stop drawing to the screen and a switch back when it should resume.

FB_EARLYSUSPEND: Register early suspend handler that notifies and waits for user-space through sysfs when user-space should stop drawing to the screen and notifies user-space when it should resume.

Files

include/linux/earlysuspend.h

kernel/power/consoleearlysuspend.c

kernel/power/fbearlysuspend.c

These patches were submitted to mainline and rejected. Some of the history.

 

OOM handling – The Android Out Of Memory killer

Kills processes as available memory becomes low.

The lowmemorykiller driver lets user-space specify a set of memory thresholds where processes with a range of oom_adj values will get killed. Specify the minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both files take a comma separated list of numbers in ascending order.

For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes with a oom_adj value of 8 or higher when the free memory drops below 4096 pages and kill processes with a oom_adj value of 0 or higher when the free memory drops below 1024 pages.

The driver considers memory used for caches to be free, but if a large percentage of the cached memory is locked this can be very inaccurate and processes may not get killed until the normal oom killer is triggered.

In an Android system, init.rc initializes both adj and minfree. Processes can set their oom_adj to place them in the correct class for their current operation.

These oom_adj levels end up being based on the process lifecycle defined here.

Configuration

ANDROID_LOW_MEMORY_KILLER

Files

drivers/staging/android/lowmemorykiller.c

A handy article regarding the standard Linux OOM killer.

 

Android alarm

This is the kernel implementation to support Android's AlarmManager. It lets user space tell the kernel when it would like to wake up, allowing the kernel to schedule that appropriately and come back (holding a wake lock) when the time has expired regardless of the sleep state of the CPU.

Configuration

RTC_INTF_ALARM

Files

drivers/rtc/alarm.c

include/linux/android_alarm.h

 

Android paranoid network security

According to the Android security architecture, each application is given its own uid and gid at install time. Data files are kept under /data/data/<app-name>/…, and are read-writable only by that application process.

When Dalvik (actually, the 'zygote' process') loads an application, it changes to the uid and gid for the application, so that the process is running in the correct security context.

The paranoid network security mode restricts access to some networking features depending on the group of the calling process.

The list of groups that are allowed access to networking features are on the following list of #defines, GID and capability:

AID_NET_BT_ADMIN 3001 Can create an RFCOMM, SCO, or L2CAPP Bluetooth socket
AID_NET_BT 3002 Can create a Bluetooth socket
AID_INET 3003 Can create IPv4 or IPv6 socket
AID_NET_RAW 3004 Can create raw sockets.
AID_NET_ADMIN 3005 Allow CAP_NET_ADMIN permissions for process.

Configuration

None

Files

include/linux/android_aid.h

 

Android timed output/GPIO

This exposes a user space interface for timed GPIOs. It is used in the vibrator code.

Configuration

ANDROID_TIMED_GPIO

ANDROID_TIMED_OUTPUT

Files

drivers/staging/android/timed_gpio.c

drivers/staging/android/timed_gpio.h

drivers/staging/android/timed_output.c

drivers/staging/android/timed_output.h

 

Android RAM console

This allows saving the kernel printk messages to a buffer in RAM, so that after a kernel panic they can be viewed in the next kernel invocation, by accessing /proc/last_kmsg.

Configuration

ANDROID_RAM_CONSOLE: Android RAM buffer console

ANDROID_RAM_CONSOLE_ENABLE_VERBOSE: Enable verbose console messages on Android RAM console

ANDROID_RAM_CONSOLE_ERROR_CORRECTION: Android RAM Console Enable error correction

    ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE: Android RAM Console Data data size

    ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE: Android RAM Console ECC size

    ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE: Android RAM Console Symbol size

    ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL: Android RAM Console Polynomial

ANDROID_RAM_CONSOLE_EARLY_INIT: Start Android RAM console early

ANDROID_RAM_CONSOLE_EARLY_ADDR: Android RAM console virtual address

ANDROID_RAM_CONSOLE_EARLY_SIZE: Android RAM console buffer size

Files

drivers/staging/android/ram_console.c

 

Other Android differences

Goldfish

The Android emulator runs a virtual CPU that Google calls Goldfish. Goldfish executes ARM926T instructions and has hooks for input and output — such as reading key presses from or displaying video output in the emulator.

YAFFS2

Flash memory file system.YAFFS2 was already freely available for Linux. However, it is not part of the standard Linux kernel, and so Google added it to Android.

Bluetooth

These changes fix apparent bugs related to Bluetooth headsets, and add Bluetooth debugging and access control functions.

Scheduler

The Android kernel also contains slight changes to the CPU process scheduler and time-keeping algorithms. Why???

Android Debug Bridge

A protocol that runs over a USB link between a hardware device running Android and a developer writing applications on a desktop PC. 

 

Overview of changes

Finally, an overview of changes from Greg Kroah-Hartman's "Android: A Case Study of an Embedded Linux Project".

drivers:

  • dcc_tty – arm tty driver (2007)
  • reset key driver (2008)
  • gpio input drivers (2008)
  • timed gpio driver (2008)
  • synaptics i2c touchscreen driver (2007) (added multitouch in July 2009)
  • ledtrig-sleep debug driver (2008)
  • apanic debug flash driver (2009) writes panic info to flash to catch it later
  • kernel debugger core (2008)
  • pmem driver (2008)
  • uid status (2009) collects per-user network statistics through a proc file
  • Bluetooth TI wl127x rfkill power control via GPIO (2009)
  • Loads of MMC changes (SDIO support, "paranoid mode, new host driver)
  • nvidia Tegra MDT NAND controller (2008)
  • RTC Alarm driver (2008)
  • Logger (2008)
  • ram console (2008)
  • Switch subsystem? (2008)
  • GPIO switch (2008)
  • USB Gadget subsystem rewrite (2008)
  • tegra USB gadget driver (2010)
  • tegra framebuffer driver (2010)
  • bluetooth fixes and extensions (2009)
  • disable /dev/mem

Security model:

  • Binder (2007)
  • "secure" networking (2008)

filesystem:

  • YAFFS2
  • FAT Volume ID ioctl (2008)
  • no inotify event under some situations
  • Partition uevents (2009)
  • special proc file type

networking:

  • PPP on L2TP Access Controller (2009)
  • PPP on PPTP Network server (2009)
  • sysfs files for networking controls (2008)

core:

  • low memory killer (2008)
  • wakelocks (2008)
  • "early" suspend (2008)
  • ashmem (anonymous shared memory) (2008)
  • panic timeout
  • cgroup/cset changes (2009)
  • futex speedup due to broken userspace code (2009)
  • min_free_order_shift sysctl for swapless systems (2009)

 

References

Porting Android to a new device

Android Kernel Features 

Android kernel configuration

kmemleak: In kernel memory leak detection

10-Nov-10

 Available since since 2.6.31. Compile with CONFIG_DEBUG_KMEMLEAK and probably increase the number of early log entries.

Boot the kernel, the information regarding memory leaks detected will appear on /sys/kernel/debug/kmemleak, which should be empty at startup. You may have to mount the debugfs. To see it working, compile and insmod the following dummy module with three not freed vmallocs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <linux init.h="">
#include <linux module.h="">
#include <linux kernel.h="">
#include <linux vmalloc.h="">
 
void myfunc(void)
{
        char *ptr;
        ptr = vmalloc(512);
        ptr = vmalloc(512);
        ptr = vmalloc(512);
}
 
int hello_init(void)
{
        printk(KERN_ALERT &quot;Hello World&quot;);
        myfunc();
        return 0;
}
 
static void hello_exit(void)
{
        printk(KERN_ALERT &quot;Goodbye World&quot;);
}
 
module_init(hello_init);
module_exit(hello_exit);
 
MODULE_LICENSE(&quot;GPL v2&quot;);
MODULE_AUTHOR(&quot;Your Name&quot;);
</linux></linux></linux></linux>
user@computer:$ echo clear > /sys/kernel/debug/kmemleak
insmod hello-kernel.ko

The memory leak detection thread runs periodically. If you want to perform a test at any instant you want:

user@computer:$ echo scan > /sys/kernel/debug/kmemleak

In /sys/kernel/debug/kmemleak you should see:

user@computer:$ unreferenced object 0xf9061000 (size 512):
comm "insmod", pid 12750, jiffies 14401507 (age 110.217s)
hex dump (first 32 bytes):
1c 0f 00 00 01 12 00 00 2a 0f 00 00 01 12 00 00 ........*.......
38 0f 00 00 01 12 00 00 bc 0f 00 00 01 12 00 00 8...............
backtrace:
[< c10b0001>] create_object+0x114/0x1db
[< c148b4d0>] kmemleak_alloc+0x21/0x3f
[< c10a43e9>] __vmalloc_node+0x83/0x90
[< c10a44b9>] vmalloc+0x1c/0x1e
[< f9055021>] myfunc+0x21/0x23 [hello_kernel]
[< f9058012>] 0xf9058012
[< c1001226>] do_one_initcall+0x71/0x113
[< c1056c48>] sys_init_module+0x1241/0x1430
[< c100284c>] sysenter_do_call+0x12/0x22
[< ffffffff>] 0xffffffff

kmemleak can take some time to detect the leak, so be patient.

via

Quiet program output

24-Oct-10
myprogram > /dev/null 2>&1

With:

stdin == 0

stdout == 1 (default if omitted)

stderr == 2 > /dev/null, redirects stdout (omitted) into /dev/null.

2>&1 Redirects stderr into stdout.

Some confusing syntax:

2>1 Would redirect stdoud into a file called 1.

2&>1 Execute file 2 in the background and redirect its output to a file called 1.