Archive for December, 2010

An analysis into Android internals: Initial Startup

Issuing “adb shell” and “ps” inside the adb shell, we get a list of running process – among them:

root 28 1 656 168 c01a65e8 afe0d40c S /system/bin/debuggerd
radio 29 1 5420 464 ffffffff afe0d0ec S /system/bin/rild
root 30 1 82016 13580 c009a694 afe0cba4 S zygote
media 31 1 20948 1004 ffffffff afe0ca7c S /system/bin/mediaserver
root 32 1 784 244 c02094ac afe0c7dc S /system/bin/installd
keystore 33 1 1616 196 c01a65e8 afe0d40c S /system/bin/keystore
root 34 1 728 188 c003d444 afe0d6ac S /system/bin/sh
root 35 1 824 260 c00b7dd0 afe0d7fc S /system/bin/qemud
root 37 1 4544 296 ffffffff 0000eca4 S /sbin/adbd
root 44 34 780 232 c02094ac afe0c7dc S /system/bin/qemu-props
system 52 30 149372 25184 ffffffff afe0ca7c S system_server
app_7 99 30 110548 17700 ffffffff afe0da04 S com.android.inputmethod.pinyin
radio 101 30 117988 15832 ffffffff afe0da04 S com.android.phone
app_7 105 30 125536 19760 ffffffff afe0da04 S android.process.acore
app_3 158 30 103656 15560 ffffffff afe0da04 S android.process.media
app_14 178 30 109528 19600 ffffffff afe0da04 S com.android.mms
app_17 202 30 102916 15388 ffffffff afe0da04 S com.android.alarmclock
app_23 212 30 106020 16392 ffffffff afe0da04 S com.android.email
app_25 220 30 102032 15980 ffffffff afe0da04 S com.example.android.BluetoothChat
app_12 231 30 101888 13912 ffffffff afe0da04 S com.svox.pico
root 244 37 728 324 c003d444 afe0d6ac S /system/bin/sh
root 245 244 668 328 c019ba10 afe0c7dc S logcat
root 1307 37 728 324 c003d444 afe0d6ac S /system/bin/sh
root 1341 37 728 324 c003d444 afe0d6ac S /system/bin/sh
root 1342 1341 55068 9396 ffffffff ad05892e R app_process
root 1346 1307 868 332 00000000 afe0c7dc R ps

Starting up the DDMS, and looking into logcat output, and comparing the output with the Android source code:

12-29 19:36:40.096: INFO/DEBUG(28): debuggerd: May 6 2010 09:07:51
12-29 19:36:40.196: INFO/vold(27): Android Volume Daemon version 2.0
12-29 19:36:40.246: DEBUG/qemud(35): entering main loop
12-29 19:36:40.286: INFO/vold(27): New MMC card ‘SU02G’ (serial 1012966) added @ /devices/platform/goldfish_mmc.0/mmc_host/mmc0/mmc0:e118
12-29 19:36:40.326: INFO/vold(27): Disk (blkdev 179:0), 4192256 secs (2047 MB) 0 partitions
12-29 19:36:40.326: INFO/vold(27): New blkdev 179.0 on media SU02G, media path /devices/platform/goldfish_mmc.0/mmc_host/mmc0/mmc0:e118, Dpp 0
12-29 19:36:40.326: INFO/vold(27): Evaluating dev ‘/devices/platform/goldfish_mmc.0/mmc_host/mmc0/mmc0:e118/block/mmcblk0’ for mountable filesystems for ‘/sd
card’
12-29 19:36:40.326: INFO/vold(27): Aborting start of /sdcard (bootstrap = 1)
12-29 19:36:40.326: INFO/vold(27): Volmgr not ready to handle device

And looking into debuggerd implementation (system/core/debuggerd/debuggerd.c):

int main()
{
int s;
struct sigaction act;
int logsocket = -1;

logsocket = socket_local_client(“logd”,
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM);
if(logsocket < 0) {
logsocket = -1;
} else {
fcntl(logsocket, F_SETFD, FD_CLOEXEC);
}

act.sa_handler = SIG_DFL;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGCHLD);
act.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &act, 0);

s = socket_local_server(“android:debuggerd”,
ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
if(s < 0) return -1;
fcntl(s, F_SETFD, FD_CLOEXEC);

LOG(“debuggerd: ” __DATE__ ” ” __TIME__ “\n”);

 

The last line above is the first line in the logcat output.

Hm….who started debuggerd? Searching around, in the root directory there is a /init.rc file:

# cat /init.rc

on init

sysclktz 0

loglevel 3

# setup the global environment
export PATH /sbin:/system/sbin:/system/bin:/system/xbin
export LD_LIBRARY_PATH /system/lib
export ANDROID_BOOTLOGO 1
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
export EXTERNAL_STORAGE /sdcard
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar

# Backward compatibility
symlink /system/etc /etc
symlink /sys/kernel/debug /d

# create mountpoints and mount tmpfs on sqlite_stmt_journals
mkdir /sdcard 0000 system system
mkdir /system
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /config 0500 root root
mkdir /sqlite_stmt_journals 01777 root root
mount tmpfs tmpfs /sqlite_stmt_journals size=4m

mount rootfs rootfs / ro remount

write /proc/sys/kernel/panic_on_oops 1
write /proc/sys/kernel/hung_task_timeout_secs 0
write /proc/cpu/alignment 4
write /proc/sys/kernel/sched_latency_ns 10000000
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000
write /proc/sys/kernel/sched_compat_yield 1
write /proc/sys/kernel/sched_child_runs_first 0

# Create cgroup mount points for process groups
mkdir /dev/cpuctl
mount cgroup none /dev/cpuctl cpu
chown sytem system /dev/cpuctl
chown system system /dev/cpuctl/tasks
chmod 0777 /dev/cpuctl/tasks
write /dev/cpuctl/cpu.shares 1024

mkdir /dev/cpuctl/fg_boost
chown system system /dev/cpuctl/fg_boost/tasks
chmod 0777 /dev/cpuctl/fg_boost/tasks
write /dev/cpuctl/fg_boost/cpu.shares 1024

mkdir /dev/cpuctl/bg_non_interactive
chown system system /dev/cpuctl/bg_non_interactive/tasks
chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
# 5.0 %
write /dev/cpuctl/bg_non_interactive/cpu.shares 52

# mount mtd partitions
# Mount /system rw first to give the filesystem a chance to save a checkpoint
mount yaffs2 mtd@system /system
mount yaffs2 mtd@system /system ro remount

# We chown/chmod /data again so because mount is run as root + defaults
mount yaffs2 mtd@userdata /data nosuid nodev
chown system system /data
chmod 0771 /data

# Create dump dir and collect dumps.
# Do this before we mount cache so eventually we can use cache for
# storing dumps on platforms which do not have a dedicated dump partition.

mkdir /data/dontpanic
chown root log /data/dontpanic
chmod 0750 /data/dontpanic

# Collect apanic data, free resources and re-arm trigger
copy /proc/apanic_console /data/dontpanic/apanic_console
chown root log /data/dontpanic/apanic_console
chmod 0640 /data/dontpanic/apanic_console

copy /proc/apanic_threads /data/dontpanic/apanic_threads
chown root log /data/dontpanic/apanic_threads
chmod 0640 /data/dontpanic/apanic_threads

write /proc/apanic_console 1

# Same reason as /data above
mount yaffs2 mtd@cache /cache nosuid nodev
chown system cache /cache
chmod 0770 /cache

# This may have been created by the recovery system with odd permissions
chown system system /cache/recovery
chmod 0770 /cache/recovery

#change permissions on vmallocinfo so we can grab it from bugreports
chown root log /proc/vmallocinfo
chmod 0440 /proc/vmallocinfo

# create basic filesystem structure
mkdir /data/misc 01771 system misc
mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth
mkdir /data/misc/keystore 0700 keystore keystore
mkdir /data/misc/vpn 0770 system system
mkdir /data/misc/vpn/profiles 0770 system system
# give system access to wpa_supplicant.conf for backup and restore
mkdir /data/misc/wifi 0770 wifi wifi
chmod 0770 /data/misc/wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
mkdir /data/local 0771 shell shell
mkdir /data/local/tmp 0771 shell shell
mkdir /data/data 0771 system system
mkdir /data/app-private 0771 system system
mkdir /data/app 0771 system system
mkdir /data/property 0700 root root

# create dalvik-cache and double-check the perms
mkdir /data/dalvik-cache 0771 system system
chown system system /data/dalvik-cache
chmod 0771 /data/dalvik-cache

# create the lost+found directories, so as to enforce our permissions
mkdir /data/lost+found 0770
mkdir /cache/lost+found 0770

# double check the perms, in case lost+found already exists, and set owner
chown root root /data/lost+found
chmod 0770 /data/lost+found
chown root root /cache/lost+found
chmod 0770 /cache/lost+found

on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain

# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40

# Define the oom_adj values for the classes of processes that can be
# killed by the kernel. These are used in ActivityManagerService.
setprop ro.FOREGROUND_APP_ADJ 0
setprop ro.VISIBLE_APP_ADJ 1
setprop ro.SECONDARY_SERVER_ADJ 2
setprop ro.BACKUP_APP_ADJ 2
setprop ro.HOME_APP_ADJ 4
setprop ro.HIDDEN_APP_MIN_ADJ 7
setprop ro.CONTENT_PROVIDER_ADJ 14
setprop ro.EMPTY_APP_ADJ 15

# Define the memory thresholds at which the above process classes will
# be killed. These numbers are in pages (4k).
setprop ro.FOREGROUND_APP_MEM 1536
setprop ro.VISIBLE_APP_MEM 2048
setprop ro.SECONDARY_SERVER_MEM 4096
setprop ro.BACKUP_APP_MEM 4096
setprop ro.HOME_APP_MEM 4096
setprop ro.HIDDEN_APP_MEM 5120
setprop ro.CONTENT_PROVIDER_MEM 5632
setprop ro.EMPTY_APP_MEM 6144

# Write value must be consistent with the above properties.
# Note that the driver only supports 6 slots, so we have HOME_APP at the
# same memory level as services.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15

write /proc/sys/vm/overcommit_memory 1
write /proc/sys/vm/min_free_order_shift 4
write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144

# Set init its forked children’s oom_adj.
write /proc/1/oom_adj -16

# Tweak background writeout
write /proc/sys/vm/dirty_expire_centisecs 200
write /proc/sys/vm/dirty_background_ratio 5

# Permissions for System Server and daemons.
chown radio system /sys/android_power/state
chown radio system /sys/android_power/request_state
chown radio system /sys/android_power/acquire_full_wake_lock
chown radio system /sys/android_power/acquire_partial_wake_lock
chown radio system /sys/android_power/release_wake_lock
chown radio system /sys/power/state
chown radio system /sys/power/wake_lock
chown radio system /sys/power/wake_unlock
chmod 0660 /sys/power/state
chmod 0660 /sys/power/wake_lock
chmod 0660 /sys/power/wake_unlock
chown system system /sys/class/timed_output/vibrator/enable
chown system system /sys/class/leds/keyboard-backlight/brightness
chown system system /sys/class/leds/lcd-backlight/brightness
chown system system /sys/class/leds/button-backlight/brightness
chown system system /sys/class/leds/jogball-backlight/brightness
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/red/device/grpfreq
chown system system /sys/class/leds/red/device/grppwm
chown system system /sys/class/leds/red/device/blink
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/green/brightness
chown system system /sys/class/leds/blue/brightness
chown system system /sys/class/leds/red/device/grpfreq
chown system system /sys/class/leds/red/device/grppwm
chown system system /sys/class/leds/red/device/blink
chown system system /sys/class/timed_output/vibrator/enable
chown system system /sys/module/sco/parameters/disable_esco
chown system system /sys/kernel/ipv4/tcp_wmem_min
chown system system /sys/kernel/ipv4/tcp_wmem_def
chown system system /sys/kernel/ipv4/tcp_wmem_max
chown system system /sys/kernel/ipv4/tcp_rmem_min
chown system system /sys/kernel/ipv4/tcp_rmem_def
chown system system /sys/kernel/ipv4/tcp_rmem_max
chown root radio /proc/cmdline

# Define TCP buffer sizes for various networks
# ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,
setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208
setprop net.tcp.buffersize.wifi 4095,87380,110208,4096,16384,110208
setprop net.tcp.buffersize.umts 4094,87380,110208,4096,16384,110208
setprop net.tcp.buffersize.edge 4093,26280,35040,4096,16384,35040
setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680

class_start default

## Daemon processes to be run by init.
##
service console /system/bin/sh
console

# adbd is controlled by the persist.service.adb.enable system property
service adbd /sbin/adbd
disabled

# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd

on property:persist.service.adb.enable=1
start adbd

on property:persist.service.adb.enable=0
stop adbd

service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media

service vold /system/bin/vold
socket vold stream 0660 root mount

service nexus /system/bin/nexus
socket nexus stream 0660 root system
disabled

#service mountd /system/bin/mountd
# socket mountd stream 0660 root mount

service debuggerd /system/bin/debuggerd

service ril-daemon /system/bin/rild
socket rild stream 660 root radio
socket rild-debug stream 660 radio system
user root
group radio cache inet misc audio

service zygote /system/bin/app_process -Xzygote /system/bin –zygote –start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media

service media /system/bin/mediaserver
user media
group system audio camera graphics inet net_bt net_bt_admin

service bootsound /system/bin/playmp3
user media
group audio
oneshot

service bootanim /system/bin/bootanimation
user graphics
group graphics
disabled
oneshot

service dbus /system/bin/dbus-daemon –system –nofork
socket dbus stream 660 bluetooth bluetooth
user bluetooth
group bluetooth net_bt_admin

service bluetoothd /system/bin/bluetoothd -n
socket bluetooth stream 660 bluetooth bluetooth
socket dbus_bluetooth stream 660 bluetooth bluetooth
# init.rc does not yet support applying capabilities, so run as root and
# let bluetoothd drop uid to bluetooth with the right linux capabilities
group bluetooth net_bt_admin misc
disabled

service hfag /system/bin/sdptool add –channel=10 HFAG
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service hsag /system/bin/sdptool add –channel=11 HSAG
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service opush /system/bin/sdptool add –channel=12 OPUSH
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service pbap /system/bin/sdptool add –channel=19 PBAP
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot

service installd /system/bin/installd
socket installd stream 600 system system

service flash_recovery /system/etc/install-recovery.sh
oneshot

service racoon /system/bin/racoon
socket racoon stream 600 system system
# racoon will setuid to vpn after getting necessary resources.
group net_admin
disabled
oneshot

service mtpd /system/bin/mtpd
socket mtpd stream 600 system system
user vpn
group vpn net_admin net_raw
disabled
oneshot

service keystore /system/bin/keystore /data/misc/keystore
user keystore
group keystore
socket keystore stream 666

 

service dumpstate /system/bin/dumpstate -s
socket dumpstate stream 0660 shell log
disabled
oneshot

Among the line is “service debuggerd /system/bin/debuggerd” which clearly indicate the stage at which debuggerd is started.

Next line in the logcat output indicated vold started up. The directory implementing the vold daemon is located in system/vold. What is its purpose?

According to:

http://www.91linux.com/html/article/qianrushiyingyong/google_android/20101204/21332.html

vold served to replace udevd. In a way, yes.

Taking a peep into the source of vold’s main.c:

int main() {

VolumeManager *vm;
CommandListener *cl;
NetlinkManager *nm;

SLOGI(“Vold 2.1 (the revenge) firing up”);

mkdir(“/dev/block/vold”, 0755);

/* Create our singleton managers */
if (!(vm = VolumeManager::Instance())) {
SLOGE(“Unable to create VolumeManager”);
exit(1);
};

if (!(nm = NetlinkManager::Instance())) {
SLOGE(“Unable to create NetlinkManager”);
exit(1);
};

cl = new CommandListener();
vm->setBroadcaster((SocketListener *) cl);
nm->setBroadcaster((SocketListener *) cl);

if (vm->start()) {
SLOGE(“Unable to start VolumeManager (%s)”, strerror(errno));
exit(1);
}

if (process_config(vm)) {
SLOGE(“Error reading configuration (%s)… continuing anyways”, strerror(errno));
}

if (nm->start()) {
SLOGE(“Unable to start NetlinkManager (%s)”, strerror(errno));
exit(1);
}

coldboot(“/sys/block”);
// coldboot(“/sys/class/switch”);

/*
* Now that we’re up, we can respond to commands
*/
if (cl->startListener()) {
SLOGE(“Unable to start CommandListener (%s)”, strerror(errno));
exit(1);
}


From above we can see that its role is mainly to startup the volume manager and netlink manager.

And next is the coldboot(“/sys/block”);

Inside the /sys/block directory are the following files (on the3 Android device itself):

ram0 ram1 ram2 ram3 ram4 ram5 ram6 ram7 ram8 xxxxxxx……
mtdblock0 mtdblock1 mtdblock2 mmcblk0

which correspond to the various next messages in the logcat.

Further device drivers setup information can be found here:

http://source.android.com/porting/bring_up.html

Some of the Volume Manager APIs:

void VolumeManager::readInitialState() {
char *VolumeManager::asecHash(const char *id, char *buffer, size_t len) {
void VolumeManager::setDebug(bool enable) {
int VolumeManager::start() {
int VolumeManager::stop() {
int VolumeManager::addVolume(Volume *v) {
void VolumeManager::notifyUmsAvailable(bool available) {
void VolumeManager::handleSwitchEvent(NetlinkEvent *evt) {
void VolumeManager::handleUsbCompositeEvent(NetlinkEvent *evt) {
void VolumeManager::handleBlockEvent(NetlinkEvent *evt) {
int VolumeManager::listVolumes(SocketClient *cli) {
int VolumeManager::formatVolume(const char *label) {
int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) {
int VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) {
int VolumeManager::createAsec(const char *id, unsigned int numSectors,
int VolumeManager::finalizeAsec(const char *id) {
int VolumeManager::renameAsec(const char *id1, const char *id2) {
int VolumeManager::unmountAsec(const char *id, bool force) {
int VolumeManager::unmountObb(const char *fileName, bool force) {
int VolumeManager::unmountLoopImage(const char *id, const char *idHash,
int VolumeManager::destroyAsec(const char *id, bool force) {
int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) {
int VolumeManager::mountObb(const char *img, const char *key, int ownerUid) {
int VolumeManager::mountVolume(const char *label) {
int VolumeManager::listMountedObbs(SocketClient* cli) {
int VolumeManager::shareAvailable(const char *method, bool *avail) {
int VolumeManager::shareEnabled(const char *label, const char *method, bool *enabled) {
int VolumeManager::simulate(const char *cmd, const char *arg) {
int VolumeManager::shareVolume(const char *label, const char *method) {
int VolumeManager::unshareVolume(const char *label, const char *method) {
int VolumeManager::unmountVolume(const char *label, bool force) {
bool VolumeManager::isMountpointMounted(const char *mp)
int VolumeManager::cleanupAsec(Volume *v, bool force) {

extern “C” void dos_partition_dec(void const *pp, struct dos_partition *d);
extern “C” void dos_partition_enc(void *pp, struct dos_partition *d);
extern “C” void dos_partition_dec(void const *pp, struct dos_partition *d);
extern “C” void dos_partition_enc(void *pp, struct dos_partition *d);
const char *Volume::SECDIR = “/mnt/secure”;
const char *Volume::SEC_STGDIR = “/mnt/secure/staging”;
const char *Volume::SEC_STG_SECIMGDIR = “/mnt/secure/staging/.android_secure”;
const char *Volume::SEC_ASECDIR = “/mnt/secure/asec”;
const char *Volume::ASECDIR = “/mnt/asec”;
const char *Volume::LOOPDIR = “/mnt/obb”;
static const char *stateToStr(int state) {
void Volume::protectFromAutorunStupidity() {
void Volume::setDebug(bool enable) {
dev_t Volume::getDiskDevice() {
dev_t Volume::getShareDevice() {
void Volume::handleVolumeShared() {
void Volume::handleVolumeUnshared() {
int Volume::handleBlockEvent(NetlinkEvent *evt) {
void Volume::setState(int state) {
int Volume::createDeviceNode(const char *path, int major, int minor) {
int Volume::formatVol() {
bool Volume::isMountpointMounted(const char *path) {
int Volume::mountVol() {
int Volume::createBindMounts() {
int Volume::doMoveMount(const char *src, const char *dst, bool force) {
int Volume::doUnmount(const char *path, bool force) {
int Volume::unmountVol(bool force) {
int Volume::initializeMbr(const char *deviceNode) {

More info next time….

An initial walkthrough of an android emulator environment

After “adb shell” and and then “df”:

./adb shell
# df
/dev: 47084K total, 0K used, 47084K available (block size 4096)
/sqlite_stmt_journals: 4096K total, 0K used, 4096K available (block size 4096)
/system: 73600K total, 73600K used, 0K available (block size 4096)
/data: 65536K total, 18964K used, 46572K available (block size 4096)
/cache: 65536K total, 1156K used, 64380K available (block size 4096)
/sdcard: 2087940K total, 8122K used, 2079818K available (block size 2048)

then “ps” gives:

# ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 204 c009a694 0000c93c S /init
root 2 0 0 0 c004dea0 00000000 S kthreadd
root 3 2 0 0 c003f778 00000000 S ksoftirqd/0
root 4 2 0 0 c004aaf4 00000000 S events/0
root 5 2 0 0 c004aaf4 00000000 S khelper
root 6 2 0 0 c004aaf4 00000000 S suspend
root 7 2 0 0 c004aaf4 00000000 S kblockd/0
root 8 2 0 0 c004aaf4 00000000 S cqueue
root 9 2 0 0 c017bb3c 00000000 S kseriod
root 10 2 0 0 c004aaf4 00000000 S kmmcd
root 11 2 0 0 c006ecac 00000000 S pdflush
root 12 2 0 0 c006ecac 00000000 S pdflush
root 13 2 0 0 c007349c 00000000 S kswapd0
root 14 2 0 0 c004aaf4 00000000 S aio/0
root 21 2 0 0 c017933c 00000000 S mtdblockd
root 22 2 0 0 c004aaf4 00000000 S hid_compat
root 23 2 0 0 c004aaf4 00000000 S rpciod/0
root 24 2 0 0 c018e530 00000000 S mmcqd
root 25 1 728 240 c01537e8 afe0c7dc S /system/bin/sh
system 26 1 796 252 c019a854 afe0ca7c S /system/bin/servicemanager
root 27 1 832 364 c009a694 afe0cba4 S /system/bin/vold
root 28 1 656 224 c01a65e8 afe0d40c S /system/bin/debuggerd
radio 29 1 5420 584 ffffffff afe0d0ec S /system/bin/rild
root 30 1 82016 15712 c009a694 afe0cba4 S zygote
media 31 1 20948 1660 ffffffff afe0ca7c S /system/bin/mediaserver
root 32 1 784 292 c02094ac afe0c7dc S /system/bin/installd
keystore 33 1 1616 384 c01a65e8 afe0d40c S /system/bin/keystore
root 34 1 728 244 c003d444 afe0d6ac S /system/bin/sh
root 35 1 824 320 c00b7dd0 afe0d7fc S /system/bin/qemud
root 37 1 4468 220 ffffffff 0000eca4 S /sbin/adbd
root 44 34 780 292 c02094ac afe0c7dc S /system/bin/qemu-props
system 59 30 149980 26620 ffffffff afe0ca7c S system_server
app_7 99 30 107840 15960 ffffffff afe0da04 S com.android.inputmethod.pinyin
radio 102 30 119980 16784 ffffffff afe0da04 S com.android.phone
app_7 104 30 122600 21592 ffffffff afe0da04 S android.process.acore
app_3 161 30 103656 16336 ffffffff afe0da04 S android.process.media
app_14 177 30 112536 16460 ffffffff afe0da04 S com.android.mms
app_17 200 30 102916 15956 ffffffff afe0da04 S com.android.alarmclock
app_25 213 30 102060 16600 ffffffff afe0da04 S com.example.android.BluetoothChat
app_23 219 30 106004 16932 ffffffff afe0da04 S com.android.email
app_12 230 30 101888 14472 ffffffff afe0da04 S com.svox.pico
root 237 37 728 328 c003d444 afe0d6ac S /system/bin/sh
root 241 237 868 332 00000000 afe0c7dc R ps
#

and “ls /data/dalvik-cache”:

-rw-r–r– system app_25 24312 2010-12-26 23:04 data
-rw-r–r– root root 3721808 2010-12-16 22:15 system
-rw-r–r– root root 1014960 2010-12-16 22:16 system
-rw-r–r– root root 6198448 2010-12-16 22:16 system
-rw-r–r– root root 166520 2010-12-16 22:16 system
-rw-r–r– root root 1095816 2010-12-16 22:16 system
-rw-r–r– system system 171288 2010-05-07 00:16 system
-rw-r–r– system system 55024 2010-05-07 00:16 system
-rw-r–r– system system 21384 2010-05-07 00:16 system
-rw-r–r– system system 14936 2010-05-07 00:16 system
-rw-r–r– system system 68496 2010-05-07 00:16 system
-rw-r–r– system system 6232 2010-05-07 00:16 system
-rw-r–r– system system 25456 2010-05-07 00:16 system
-rw-r–r– system system 7744 2010-05-07 00:16 system
-rw-r–r– system system 4136 2010-05-07 00:16 system
-rw-r–r– system system 11448 2010-05-07 00:16 system
-rw-r–r– system system 42352 2010-05-07 00:16 system
-rw-r–r– system radio 530496 2010-05-07 00:16 system
-rw-r–r– system radio 84688 2010-05-07 00:16 system
-rw-r–r– system app_8 2008 2010-05-07 00:16 system
-rw-r–r– system app_7 152544 2010-05-07 00:16 system
-rw-r–r– system app_7 129328 2010-05-07 00:16 system
-rw-r–r– system app_7 195184 2010-05-07 00:16 system
-rw-r–r– system app_7 373744 2010-05-07 00:16 system
-rw-r–r– system app_7 16832 2010-05-07 00:16 system
-rw-r–r– system app_7 14584 2010-05-07 00:16 system
-rw-r–r– system app_17 67616 2010-05-07 00:16 system
-rw-r–r– system app_3 13488 2010-05-07 00:16 system
-rw-r–r– system app_3 74896 2010-05-07 00:16 system
-rw-r–r– system app_3 87536 2010-05-07 00:16 system
-rw-r–r– system app_14 524104 2010-05-07 00:16 system
-rw-r–r– system app_23 979800 2010-05-07 00:16 system
-rw-r–r– system app_12 6632 2010-05-07 00:16 system
-rw-r–r– system system 588928 2010-05-07 00:16 system
-rw-r–r– system app_24 5104 2010-12-16 22:31 data
-rw-r–r– system app_0 329624 2010-05-07 00:17 system
-rw-r–r– system app_7 402048 2010-05-07 00:17 system
-rw-r–r– system system 40264 2010-05-07 00:16 system

And using dexdump to dump the framework file:

Processing ‘system’…
Opened ‘system’, DEX version ‘035’
Class #0 –
Class descriptor : ‘Landroid/Manifest$permission;’
Access flags : 0x30011 (PUBLIC FINAL VERIFIED OPTIMIZED)
Superclass : ‘Ljava/lang/Object;’
Interfaces –
Static fields –
#0 : (in Landroid/Manifest$permission;)
name : ‘ACCESS_CHECKIN_PROPERTIES’
type : ‘Ljava/lang/String;’
access : 0x0019 (PUBLIC STATIC FINAL)
#1 : (in Landroid/Manifest$permission;)
name : ‘ACCESS_COARSE_LOCATION’
type : ‘Ljava/lang/String;’
access : 0x0019 (PUBLIC STATIC FINAL)
#2 : (in Landroid/Manifest$permission;)
name : ‘ACCESS_FINE_LOCATION’
type : ‘Ljava/lang/String;’
access : 0x0019 (PUBLIC STATIC FINAL)
#3 : (in Landroid/Manifest$permission;)
name : ‘ACCESS_LOCATION_EXTRA_COMMANDS’
type : ‘Ljava/lang/String;’

wow…..140000 lines long.

looking at all the tools available in /system/bin:

# ls -l
lrwxr-xr-x root shell 2010-05-07 00:13 dd -> toolbox
-rwxr-xr-x root shell 14288 2010-05-07 00:13 dumpstate
lrwxr-xr-x root shell 2010-05-07 00:13 ln -> toolbox
-rwxr-xr-x root shell 9816 2010-05-07 00:13 dumpsys
lrwxr-xr-x root shell 2010-05-07 00:13 setprop -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 ls -> toolbox
-rwxr-sr-x root net_raw 26652 2010-05-07 00:13 ping
-rwxr-xr-x root shell 201 2009-09-19 04:08 input
lrwxr-xr-x root shell 2010-05-07 00:13 watchprops -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 rm -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 kill -> toolbox
-rwxr-xr-x root shell 191 2009-09-19 04:08 pm
lrwxr-xr-x root shell 2010-05-07 00:13 log -> toolbox
-rwxr-xr-x root shell 5432 2010-05-07 00:14 system_server
lrwxr-xr-x root shell 2010-05-07 00:13 iftop -> toolbox
-rwxr-xr-x root shell 5420 2010-05-07 00:13 radiooptions
-rwxr-xr-x root shell 5488 2010-05-07 00:13 dvz
lrwxr-xr-x root shell 2010-05-07 00:13 rmdir -> toolbox
-rwxr-xr-x root shell 9696 2010-05-07 00:13 logwrapper
lrwxr-xr-x root shell 2010-05-07 00:13 lsmod -> toolbox
-rwxr-xr-x root shell 90924 2010-05-07 00:13 applypatch
-rwxr-xr-x root shell 22568 2010-05-07 00:13 fsck_msdos
lrwxr-xr-x root shell 2010-05-07 00:13 vmstat -> toolbox
-rwxr-xr-x root shell 5512 2010-05-07 00:13 dalvikvm
-rwxr-xr-x root shell 5552 2010-02-12 08:54 keypress
-rwxr-xr-x root shell 199 2009-09-19 04:08 bmgr
-rwxr-xr-x root shell 251780 2010-05-07 00:13 updater
lrwxr-xr-x root shell 2010-05-07 00:13 insmod -> toolbox
-rwxr-xr-x root shell 9676 2010-05-07 00:13 flash_image
-rwxr-sr-x root inet 5640 2010-05-07 00:13 netcfg
-rwxr-xr-x root shell 5396 2010-05-07 00:13 schedtest
-rwxr-xr-x root shell 10716 2010-05-07 00:13 showlease
lrwxr-xr-x root shell 2010-05-07 00:13 setconsole -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 rmmod -> toolbox
-rwxr-xr-x root shell 9860 2010-05-07 00:13 service
-rwxr-xr-x root shell 9740 2010-05-07 00:13 dexopt
lrwxr-xr-x root shell 2010-05-07 00:13 reboot -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 hd -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 getevent -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 newfs_msdos -> toolbox
-rwxr-xr-x root shell 301436 2010-05-07 00:13 recovery
lrwxr-xr-x root shell 2010-05-07 00:13 wipe -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 printenv -> toolbox
-rwxr-xr-x root shell 5504 2010-05-07 00:13 bugreport
-rwxr-xr-x root shell 14048 2010-05-07 00:13 installd
-rwxr-xr-x root shell 205 2009-09-19 04:08 monkey
lrwxr-xr-x root shell 2010-05-07 00:13 stop -> toolbox
-rwxr-xr-x root shell 13760 2010-05-07 00:13 qemud
lrwxr-xr-x root shell 2010-05-07 00:13 smd -> toolbox
-rwxr-xr-x root shell 10024 2010-05-07 00:13 keystore
-rwxr-xr-x root shell 194 2009-09-19 04:08 ime
lrwxr-xr-x root shell 2010-05-07 00:13 chown -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 date -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 ps -> toolbox
-rwxr-xr-x root shell 5452 2010-05-07 00:14 mediaserver
lrwxr-xr-x root shell 2010-05-07 00:13 umount -> toolbox
-rwxr-xr-x root shell 23144 2010-05-07 00:13 bootanimation
lrwxr-xr-x root shell 2010-05-07 00:13 renice -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 df -> toolbox
-rwxr-xr-x root shell 143584 2010-05-07 00:13 pppd
lrwxr-xr-x root shell 2010-05-07 00:13 mount -> toolbox
-rwxr-xr-x root shell 5524 2010-05-07 00:13 gzip
lrwxr-xr-x root shell 2010-05-07 00:13 dmesg -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 sync -> toolbox
-rwxr-xr-x root shell 39052 2010-05-07 00:13 vold
lrwxr-xr-x root shell 2010-05-07 00:13 mv -> toolbox
-rwxr-xr-x root shell 9760 2010-05-07 00:13 logcat
-rwxr-xr-x root shell 214600 2010-05-07 00:13 applypatch_static
-rwxr-xr-x root shell 6520 2010-05-07 00:13 keystore_cli
-rwxr-xr-x root shell 18240 2010-05-07 00:13 mtpd
-rwxr-xr-x root shell 5512 2010-05-07 00:13 qemu-props
-rwxr-xr-x root shell 192 2009-09-19 04:08 svc
lrwxr-xr-x root shell 2010-05-07 00:13 cat -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 sendevent -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 notify -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 cmp -> toolbox
-rwxr-xr-x root shell 5676 2010-05-07 00:13 app_process
-rwxr-xr-x root shell 159044 2010-05-07 00:13 racoon
-rwxr-xr-x root shell 18056 2010-05-07 00:13 debuggerd
-rwxr-xr-x root shell 151868 2009-09-19 04:08 gdbserver
lrwxr-xr-x root shell 2010-05-07 00:13 dumpcrash -> dumpstate
-rwxr-xr-x root shell 9864 2010-05-07 00:13 servicemanager
-rwxr-xr-x root shell 9616 2010-03-02 03:43 fbtool
lrwxr-xr-x root shell 2010-05-07 00:13 netstat -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 ioctl -> toolbox
-rwxr-xr-x root shell 66724 2010-05-07 00:13 check_prereq
lrwxr-xr-x root shell 2010-05-07 00:13 ifconfig -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 sleep -> toolbox
-rwxr-xr-x root shell 5552 2010-05-07 00:13 sdutil
-rwxr-xr-x root shell 5628 2010-05-07 00:13 rild
-rwxr-xr-x root shell 44564 2010-05-07 00:13 dhcpcd
-rwxr-xr-x root shell 73200 2010-05-07 00:13 toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 start -> toolbox
-rwxr-xr-x root shell 64208 2010-05-07 00:13 linker
-rwxr-xr-x root shell 5440 2010-05-07 00:13 surfaceflinger
lrwxr-xr-x root shell 2010-05-07 00:13 chmod -> toolbox
-rwxr-xr-x root shell 191 2009-09-19 04:08 am
lrwxr-xr-x root shell 2010-05-07 00:13 getprop -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 schedtop -> toolbox
-rwxr-xr-x root shell 22112 2010-02-12 08:54 dmagent
lrwxr-xr-x root shell 2010-05-07 00:13 mkdir -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 route -> toolbox
-rwxr-xr-x root shell 86972 2010-05-07 00:13 sh
lrwxr-xr-x root shell 2010-05-07 00:13 id -> toolbox
lrwxr-xr-x root shell 2010-05-07 00:13 top -> toolbox

And “dumpstate” gives:

------ MEMORY INFO ------
MemTotal:          94172 kB
MemFree:            3424 kB
Buffers:            4116 kB
Cached:            35900 kB
SwapCached:            0 kB
Active:            32312 kB
Inactive:          47484 kB
Active(anon):      16532 kB
Inactive(anon):    25636 kB
Active(file):      15780 kB
Inactive(file):    21848 kB
Unevictable:         264 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         40084 kB
Mapped:            16400 kB
Slab:               4756 kB
SReclaimable:       2336 kB
SUnreclaim:         2420 kB
PageTables:         3200 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       47084 kB
Committed_AS:     916384 kB
VmallocTotal:     876544 kB
VmallocUsed:       11376 kB
VmallocChunk:     858116 kB

------ CPU INFO ------

User 5%, System 13%, IOW 0%, IRQ 0%
User 7 + Nice 0 + Sys 16 + Idle 99 + IOW 0 + IRQ 0 + SIRQ 0 = 122

PID   TID CPU% S     VSS     RSS PCY UID      Thread          Proc
330   330  17% R    932K    412K  fg shell    top             top
59   154   0% S 149312K  26320K  fg system   er$SensorThread system_server
59    68   0% S 149312K  26320K  fg system   er.ServerThread system_server
59   117   0% S 149312K  26320K  fg system   Binder Thread # system_server
102   102   0% S 115872K  17192K  fg radio    m.android.phone com.android.phone
4     4   0% S      0K      0K  fg root     events/0
102   193   0% S 115872K  17192K  fg radio    Binder Thread # com.android.phone
102   198   0% S 115872K  17192K  fg radio    Binder Thread # com.android.phone
104   104   0% S 122600K  21800K  fg app_7    d.process.acore android.process.acore

User 5%, System 13%, IOW 0%, IRQ 0%
User 7 + Nice 0 + Sys 16 + Idle 99 + IOW 0 + IRQ 0 + SIRQ 0 = 122

PID   TID CPU% S     VSS     RSS PCY UID      Thread          Proc
330   330  17% R    932K    412K  fg shell    top             top
59   154   0% S 149312K  26320K  fg system   er$SensorThread system_server
59    68   0% S 149312K  26320K  fg system   er.ServerThread system_server
59   117   0% S 149312K  26320K  fg system   Binder Thread # system_server
102   102   0% S 115872K  17192K  fg radio    m.android.phone com.android.phone
4     4   0% S      0K      0K  fg root     events/0
102   193   0% S 115872K  17192K  fg radio    Binder Thread # com.android.phone
102   198   0% S 115872K  17192K  fg radio    Binder Thread # com.android.phone
104   104   0% S 122600K  21800K  fg app_7    d.process.acore android.process.acore
104   105   0% S 122600K  21800K  fg app_7    HeapWorker      android.process.acore
104   107   0% S 122600K  21800K  fg app_7    Signal Catcher  android.process.acore
104   110   0% S 122600K  21800K  fg app_7    JDWP            android.process.acore
104   115   0% S 122600K  21800K  fg app_7    Binder Thread # android.process.acore
104   116   0% S 122600K  21800K  fg app_7    Binder Thread # android.process.acore
104   138   0% S 122600K  21800K  bg app_7    ApplicationsPro android.process.acore
104   146   0% S 122600K  21800K  bg app_7    ContactAggregat android.process.acore
104   196   0% S 122600K  21800K  fg app_7    Binder Thread # android.process.acore
177   177   0% S 112536K  16908K  bg app_14   com.android.mms com.android.mms
177   178   0% S 112536K  16908K  bg app_14   HeapWorker      com.android.mms
177   179   0% S 112536K  16908K  bg app_14   Signal Catcher  com.android.mms
177   181   0% S 112536K  16908K  bg app_14   JDWP            com.android.mms
177   184   0% S 112536K  16908K  fg app_14   Binder Thread # com.android.mms
177   185   0% S 112536K  16908K  fg app_14   Binder Thread # com.android.mms
200   200   0% S 102916K  16332K  bg app_17   roid.alarmclock com.android.alarmclock
200   201   0% S 102916K  16332K  bg app_17   HeapWorker      com.android.alarmclock
200   202   0% S 102916K  16332K  bg app_17   Signal Catcher  com.android.alarmclock
200   203   0% S 102916K  16332K  bg app_17   JDWP            com.android.alarmclock
200   205   0% S 102916K  16332K  fg app_17   Binder Thread # com.android.alarmclock
200   206   0% S 102916K  16332K  fg app_17   Binder Thread # com.android.alarmclock
213   213   0% S 102060K  17064K  bg app_25   d.BluetoothChat com.example.android.BluetoothChat
------ PROCRANK ------

------ VIRTUAL MEMORY STATS ------
nr_free_pages 830
nr_inactive_anon 6409
nr_active_anon 4145
nr_inactive_file 5462
nr_active_file 3945
nr_unevictable 66
nr_mlock 0
nr_anon_pages 10023
nr_mapped 4100
nr_file_pages 10004
nr_dirty 0
nr_writeback 0
nr_slab_reclaimable 586
nr_slab_unreclaimable 607
nr_page_table_pages 800
nr_unstable 0
nr_bounce 0
nr_vmscan_write 0
nr_writeback_temp 0
pgpgin 12591
pgpgout 8158
pswpin 0
pswpout 0
pgalloc_normal 76646
pgalloc_movable 0
pgfree 77495
pgactivate 15151
pgdeactivate 20880
pgfault 137772
pgmajfault 1169
pgrefill_normal 20882
pgrefill_movable 0
pgsteal_normal 17491
pgsteal_movable 0
pgscan_kswapd_normal 10752
pgscan_kswapd_movable 0
pgscan_direct_normal 17696
pgscan_direct_movable 0
pginodesteal 0
slabs_scanned 10752
kswapd_steal 6561
kswapd_inodesteal 0
pageoutrun 137
allocstall 219
pgrotated 0
unevictable_pgs_culled 66
unevictable_pgs_scanned 0
unevictable_pgs_rescued 0
unevictable_pgs_mlocked 0
unevictable_pgs_munlocked 0
unevictable_pgs_cleared 0
unevictable_pgs_stranded 0
unevictable_pgs_mlockfreed 0

------ SLAB INFO ------
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <nu
m_slabs> <sharedavail>
rpc_buffers            8      8   2048    2    1 : tunables   24   12    0 : slabdata      4      4      0
rpc_tasks              8     24    160   24    1 : tunables  120   60    0 : slabdata      1      1      0
rpc_inode_cache        0      0    416    9    1 : tunables   54   27    0 : slabdata      0      0      0
bridge_fdb_cache       0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0
flow_cache             0      0     80   48    1 : tunables  120   60    0 : slabdata      0      0      0
cfq_io_context         0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0
cfq_queue              0      0     88   44    1 : tunables  120   60    0 : slabdata      0      0      0
smb_request            0      0    256   15    1 : tunables  120   60    0 : slabdata      0      0      0
smb_inode_cache        0      0    320   12    1 : tunables   54   27    0 : slabdata      0      0      0
fat_inode_cache        5     11    352   11    1 : tunables   54   27    0 : slabdata      1      1      0
fat_cache              2    145     24  145    1 : tunables  120   60    0 : slabdata      1      1      0
kioctx                 0      0    160   24    1 : tunables  120   60    0 : slabdata      0      0      0
kiocb                  0      0    160   24    1 : tunables  120   60    0 : slabdata      0      0      0
inotify_event_cache      0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0
inotify_watch_cache      6     92     40   92    1 : tunables  120   60    0 : slabdata      1      1      0
dnotify_cache          0      0     24  145    1 : tunables  120   60    0 : slabdata      0      0      0
fasync_cache           0      0     16  203    1 : tunables  120   60    0 : slabdata      0      0      0
ashmem_range_cache      0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0
ashmem_area_cache     26     52    288   13    1 : tunables   54   27    0 : slabdata      4      4      0
shmem_inode_cache    227    250    392   10    1 : tunables   54   27    0 : slabdata     25     25      0
nsproxy                0      0     24  145    1 : tunables  120   60    0 : slabdata      0      0      0
posix_timers_cache      0      0    112   35    1 : tunables  120   60    0 : slabdata      0      0      0
uid_cache             18     59     64   59    1 : tunables  120   60    0 : slabdata      1      1      0
UNIX                  82     90    384   10    1 : tunables   54   27    0 : slabdata      9      9      0
ip_mrt_cache           0      0     96   40    1 : tunables  120   60    0 : slabdata      0      0      0
UDP-Lite               0      0    480    8    1 : tunables   54   27    0 : slabdata      0      0      0
tcp_bind_bucket        2    203     16  203    1 : tunables  120   60    0 : slabdata      1      1      0
inet_peer_cache        0      0     64   59    1 : tunables  120   60    0 : slabdata      0      0      0
secpath_cache          0      0     32  113    1 : tunables  120   60    0 : slabdata      0      0      0
xfrm_dst_cache         0      0    288   13    1 : tunables   54   27    0 : slabdata      0      0      0
ip_fib_alias           0      0     16  203    1 : tunables  120   60    0 : slabdata      0      0      0
ip_fib_hash            9     92     40   92    1 : tunables  120   60    0 : slabdata      1      1      0

------ VMALLOC INFO ------
0xc684c000-0xc684e000    8192 __arm_ioremap_pfn+0x68/0x2fc ioremap
0xc6850000-0xc6852000    8192 __arm_ioremap_pfn+0x68/0x2fc ioremap
0xc6854000-0xc6856000    8192 __arm_ioremap_pfn+0x68/0x2fc ioremap
0xc6880000-0xc68a1000  135168 binder_mmap+0xb4/0x200 ioremap
0xc6900000-0xc69ff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc6a00000-0xc6aff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc6b00000-0xc6bff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc6d00000-0xc6dff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc6e00000-0xc6eff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc6f00000-0xc6fff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc7400000-0xc74ff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc7500000-0xc75ff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc7700000-0xc77ff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc7800000-0xc78ff000 1044480 binder_mmap+0xb4/0x200 ioremap
0xc7900000-0xc79ff000 1044480 binder_mmap+0xb4/0x200 ioremap

------ ZONEINFO ------
Node 0, zone   Normal
pages free     830
min      312
low      390
high     468
scanned  0 (aa: 0 ia: 0 af: 0 if: 0)
spanned  24576
present  24384
nr_free_pages 830
nr_inactive_anon 6409
nr_active_anon 4159
nr_inactive_file 5462
nr_active_file 3945
nr_unevictable 66
nr_mlock     0
nr_anon_pages 10039
nr_mapped    4102
nr_file_pages 10004
nr_dirty     0
nr_writeback 0
nr_slab_reclaimable 586
nr_slab_unreclaimable 607
nr_page_table_pages 800
nr_unstable  0
nr_bounce    0
nr_vmscan_write 0
nr_writeback_temp 0
protection: (0, 0)
pagesets
cpu: 0
count: 3
high:  18
batch: 3
all_unreclaimable: 0
prev_priority:     12
start_pfn:         0
inactive_ratio:    1

…..yet to continue…..

How does the keyboard driver for my Lenovo R400 worked?

First it is Ubuntu 9.04 running Linus git version of Linux kernel (2.6.34-rc5).

Firstly doing a “od -tx1 /dev/input/by-path/platform-i8042-serio-0-event-kbd” at a command line will return the follow output whenever the keyboard is pressed (data depends on which key are pressed):

0000000 dd 26 38 4c 0c 39 09 00 04 00 04 00 1c 00 00 00
0000020 dd 26 38 4c 16 39 09 00 01 00 1c 00 00 00 00 00
0000040 dd 26 38 4c 17 39 09 00 00 00 00 00 00 00 00 00
0000060 de 26 38 4c e9 95 0c 00 04 00 04 00 38 00 00 00
0000100 de 26 38 4c f4 95 0c 00 01 00 38 00 01 00 00 00
0000120 de 26 38 4c f6 95 0c 00 00 00 00 00 00 00 00 00
0000140 de 26 38 4c a2 af 0e 00 04 00 04 00 0f 00 00 00
0000160 de 26 38 4c ac af 0e 00 01 00 0f 00 01 00 00 00
0000200 de 26 38 4c ae af 0e 00 00 00 00 00 00 00 00 00
0000220 df 26 38 4c a4 63 01 00 04 00 04 00 0f 00 00 00
0000240 df 26 38 4c ae 63 01 00 01 00 0f 00 00 00 00 00
0000260 df 26 38 4c b0 63 01 00 00 00 00 00 00 00 00 00
0000300 df 26 38 4c 8f bc 01 00 04 00 04 00 38 00 00 00
0000320 df 26 38 4c 9a bc 01 00 01 00 38 00 00 00 00 00
0000340 df 26 38 4c 9b bc 01 00 00 00 00 00 00 00 00 00
0000360 e0 26 38 4c ff 93 04 00 04 00 04 00 21 00 00 00
0000400 e0 26 38 4c 08 94 04 00 01 00 21 00 01 00 00 00

Doing a search: dmesg | grep 8042 returns:

[ 5.538045] serio: i8042 KBD port at 0x60,0x64 irq 1
[ 5.538061] serio: i8042 AUX port at 0x60,0x64 irq 12
[ 5.543089] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input3

From above we can guess the code lies somewhere in drivers/input/serio/i8042.c:

First the driver initialization codes:

Module initialization definition:

module_init(i8042_init);
module_exit(i8042_exit);

Doing a “nm /boot/vmlinux |grep 8042” we can verified that the i8042 functions are compiled into the kernel, and therefore not a module:

c094f0c4 b i8042_aux_irq
c085dca4 t i8042_aux_irq_delivered
c094f1ac b i8042_aux_irq_registered
c0837e6e t i8042_aux_test_irq
c04668e0 t i8042_aux_write
c07dde00 d i8042_blink_frequency
c094f0bf b i8042_bypass_aux_irq_test
c0465a90 T i8042_check_port_owner
c04663f0 T i8042_command
c07dde6c d i8042_command_reg
c0465f80 t i8042_controller_check
c0466820 t i8042_controller_reset
c0466440 t i8042_controller_selftest
c0837f24 t i8042_create_aux_port
c094f1a9 b i8042_ctr
c07dde70 d i8042_data_reg
c094f0be b i8042_debug
c094f0b9 b i8042_direct
c0878cc0 t i8042_dmi_dritek_table
c0879dc0 t i8042_dmi_laptop_table
c0875380 t i8042_dmi_noloop_table
c08765c0 t i8042_dmi_nomux_table
c08799c0 t i8042_dmi_nopnp_table
c0874520 t i8042_dmi_reset_table
c094f0bc b i8042_dritek
c04664e0 t i8042_dritek_enable
c07dde20 d i8042_driver
c094f0ba b i8042_dumbkbd
c04665e0 t i8042_enable_aux_port
c0466690 t i8042_enable_kbd_port
c0466640 t i8042_enable_mux_ports
c08a27c8 t i8042_exit
c0465ed0 t i8042_flush
c0466a30 t i8042_free_irqs
c0837a61 t i8042_init
c094f1a8 b i8042_initial_ctr
c0465e70 T i8042_install_filter
c0465ac0 t i8042_interrupt
c085dcb4 t i8042_irq_being_tested
c094f0c0 b i8042_kbd_irq
c094f1ab b i8042_kbd_irq_registered
c0466150 t i8042_kbd_write
c094f0a0 b i8042_lock
c0466b00 T i8042_lock_chip
c07ddf34 d i8042_mutex
c094f1aa b i8042_mux_present
c094f0b5 b i8042_noaux
c094f0b4 b i8042_nokbd
c094f0bb b i8042_noloop
c094f0b6 b i8042_nomux
c094f0bd b i8042_nopnp
c0465fb0 t i8042_panic_blink
c094f1b0 b i8042_platform_device
c094f1b4 b i8042_platform_filter
c05fe9e0 r i8042_pm_ops
c04668b0 t i8042_pm_reset
c04666f0 t i8042_pm_restore
c0465df0 t i8042_pm_thaw
c094f0d4 b i8042_pnp_aux_devices
c07ddee0 d i8042_pnp_aux_driver
c094f0e4 b i8042_pnp_aux_irq
c094f120 b i8042_pnp_aux_name
c0466b20 t i8042_pnp_aux_probe
c094f0d0 b i8042_pnp_aux_registered
c094f0d8 b i8042_pnp_command_reg
c094f0dc b i8042_pnp_data_reg
c04669e0 t i8042_pnp_exit
c094f0cc b i8042_pnp_kbd_devices
c07dde80 d i8042_pnp_kbd_driver
c094f0e0 b i8042_pnp_kbd_irq
c094f100 b i8042_pnp_kbd_name
c0466cb0 t i8042_pnp_kbd_probe
c094f0c8 b i8042_pnp_kbd_registered
c0466910 t i8042_port_close
c094f160 b i8042_ports
c083801b t i8042_probe
c05a9e6b t i8042_remove
c0465e10 T i8042_remove_filter
c094f0b8 b i8042_reset
c0466520 t i8042_set_mux_mode
c04668d0 t i8042_shutdown
c0465a70 t i8042_start
c094f140 b i8042_start_time
c0466ab0 t i8042_stop
c094f1ad b i8042_suppress_kbd_ack
c08379f0 t i8042_toggle_aux
c094f0b7 b i8042_unlock
c0466ae0 T i8042_unlock_chip
c05a9e3e t i8042_unregister_ports
c04660f0 t i8042_wait_write

Since the function is declared as “__init” above, its memory is freed up after initialization during bootup (the “vmlinux” file is the compiled kernel image) – which account for the 0xcc distributed in memory:

gdb /boot/vmlinux /proc/kcore
(gdb) disassemble i8042_init
Dump of assembler code for function i8042_init:
0xc0837a61 <i8042_init+0>: int3
0xc0837a62 <i8042_init+1>: int3
0xc0837a63 <i8042_init+2>: int3
0xc0837a64 <i8042_init+3>: int3
0xc0837a65 <i8042_init+4>: int3
0xc0837a66 <i8042_init+5>: int3

Some parameters configurable during kernel bootup:

static bool i8042_nokbd;
module_param_named(nokbd, i8042_nokbd, bool, 0);
MODULE_PARM_DESC(nokbd, “Do not probe or use KBD port.”);

static bool i8042_noaux;
module_param_named(noaux, i8042_noaux, bool, 0);
MODULE_PARM_DESC(noaux, “Do not probe or use AUX (mouse) port.”);

static bool i8042_nomux;
module_param_named(nomux, i8042_nomux, bool, 0);
MODULE_PARM_DESC(nomux, “Do not check whether an active multiplexing controller is present.”);

static bool i8042_unlock;
module_param_named(unlock, i8042_unlock, bool, 0);
MODULE_PARM_DESC(unlock, “Ignore keyboard lock.”);

Setup codes:

From i8042_init()–> i8042_probe()–>i8042_setup_kbd() etc.

static int __init i8042_init(void)
{
dbg_init();

err = i8042_platform_init();

err = i8042_controller_check();

pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);

and:

static int __init i8042_probe(struct platform_device *dev)
{

i8042_platform_device = dev;

error = i8042_controller_init();

error = i8042_setup_kbd();

i8042_register_ports();
….

static int __init i8042_setup_kbd(void)
{
int error;

error = i8042_create_kbd_port();

error = request_irq(I8042_KBD_IRQ, i8042_interrupt, IRQF_SHARED,
“i8042”, i8042_platform_device);

where i8042_create_kbd_port() will install the necessary callbacks:

serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL;
serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write;
serio->start = i8042_start;
serio->stop = i8042_stop;
serio->close = i8042_port_close;
serio->port_data = port;

Following that is the key function (request_irq()) that register hardware keyboard interrupts received to be called by the kernel. The function for processing interrupt is i8042_interrupt():

/*
* i8042_interrupt() is the most important function in this driver –
* it handles the interrupts from the i8042, and sends incoming bytes
* to the upper layers.
*/

static irqreturn_t i8042_interrupt(int irq, void *dev_id)
{
data = i8042_read_data();

Essentially i8042_read_data() is called.

At runtime, the possible calling dependencies are (http://lkml.org/lkml/2005/5/28/18):

May 27 23:15:54 cray kernel: [<c0103927>] dump_stack+0x17/0x20 May 27 23:15:54 cray kernel: [<c02bc412>] schedule+0x5d2/0x5e0 May 27 23:15:54 cray kernel: [<c02bcd1b>] schedule_timeout+0x5b/0xb0 May 27 23:15:54 cray kernel: [<c01fa97d>] ps2_sendbyte+0xbd/0x120 May 27 23:15:54 cray kernel: [<c01faab1>] ps2_command+0xd1/0x340 May 27 23:15:54 cray kernel: [<c025bb05>] atkbd_probe+0x35/0x110 May 27 23:15:54 cray kernel: [<c025c3d8>] atkbd_reconnect+0x88/0x120 May 27 23:15:54 cray kernel: [<c01f9427>] serio_resume+0x27/0x30 May 27 23:15:54 cray kernel: [<c020e5af>] resume_device+0x6f/0x80 May 27 23:15:54 cray kernel: [<c020e687>] dpm_resume+0xc7/0xd0 May 27 23:15:54 cray kernel: [<c020e6b3>] device_resume+0x23/0x40 May 27 23:15:54 cray kernel: [<c01336e8>] finish+0x8/0x40 May 27 23:15:54 cray kernel: [<c0133837>] pm_suspend_disk+0x57/0x80 May 27 23:15:54 cray kernel: [<c0131756>] enter_state+0x66/0x70 May 27 23:15:54 cray kernel: [<c0131893>] state_store+0xa3/0xaa May 27 23:15:54 cray kernel: [<c0184ba5>] subsys_attr_store+0x35/0x40 May 27 23:15:54 cray kernel: [<c0184dfe>] flush_write_buffer+0x2e/0x40 May 27 23:15:54 cray kernel: [<c0184e5f>] sysfs_write_file+0x4f/0x80 May 27 23:15:54 cray kernel: [<c01512a1>] vfs_write+0x91/0x100 May 27 23:15:54 cray kernel: [<c01513c1>] sys_write+0x41/0x70 May 27 23:15:54 cray kernel: [<c0102a79>] syscall_call+0x7/0xb

How is the input/serio/i8042.c and input/keyboard/atkbd.c linked?

First, from dmesg:

[ 5.529179] PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[ 5.537159] serio: i8042 KBD port at 0x60,0x64 irq 1
[ 5.537175] serio: i8042 AUX port at 0x60,0x64 irq 12
[ 5.537399] mice: PS/2 mouse device common for all mice
[ 5.537673] rtc_cmos 00:07: RTC can wake from S4
[ 5.537754] rtc_cmos 00:07: rtc core: registered rtc_cmos as rtc0
[ 5.537801] rtc0: alarms up to one month, y3k, 114 bytes nvram, hpet irqs

We can guess that serio is link to several types of Serial I/O: AUX/Keyboard and MUX.

MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);

static struct serio_driver atkbd_drv = {
.driver = {
.name = “atkbd”,
},
.description = DRIVER_DESC,
.id_table = atkbd_serio_ids,
.interrupt = atkbd_interrupt,
.connect = atkbd_connect,
.reconnect = atkbd_reconnect,
.disconnect = atkbd_disconnect,
.cleanup = atkbd_cleanup,
};

The function atkbd_interrupt() is registered via the function:

static int __init atkbd_init(void)
{
dmi_check_system(atkbd_dmi_quirk_table);

return serio_register_driver(&atkbd_drv);
}

serio’s interrupt processing path therefore will flow into atkbd_interrupt().

drivers/input/keyboard/atkbd.c:

static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
unsigned int flags)
{
struct atkbd *atkbd = serio_get_drvdata(serio);
struct input_dev *dev = atkbd->dev;
unsigned int code = data;
int scroll = 0, hscroll = 0, click = -1;
int value;
unsigned short keycode;

dev_dbg(&serio->dev, “Received %02x flags %02x\n”, data, flags);

if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
dev_warn(&serio->dev, “Frame/parity error: %02x\n”, flags);
serio_write(serio, ATKBD_CMD_RESEND);
atkbd->resend = true;
goto out;
}

….

input_event(dev, EV_MSC, MSC_RAW, code);

if (atkbd_platform_scancode_fixup)
code = atkbd_platform_scancode_fixup(atkbd, code);

if (atkbd->translated) {

if (atkbd->emul || atkbd_need_xlate(atkbd->xl_bit, code)) {
atkbd->release = code >> 7;
code &= 0x7f;
}

if (!atkbd->emul)
atkbd_calculate_xl_bit(atkbd, data);


keycode = atkbd->keycode;

where the keycode table atkbd->keycode is updated thus:

static void atkbd_set_keycode_table(struct atkbd *atkbd)
{
unsigned int scancode;
int i, j;

memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);

if (atkbd->translated) {
for (i = 0; i < 128; i++) {
scancode = atkbd_unxlate_table[i];
atkbd->keycode[i] = atkbd_set2_keycode[scancode];
atkbd->keycode[i | 0x80] = atkbd_set2_keycode[scancode | 0x80];
if (atkbd->scroll)
for (j = 0; j < ARRAY_SIZE(atkbd_scroll_keys); j++)
if ((scancode | 0x80) == atkbd_scroll_keys[j].set2)
atkbd->keycode[i
| 0x80] = atkbd_scroll_keys[j].keycode;
}
} else if (atkbd->set == 3) {
memcpy(atkbd->keycode, atkbd_set3_keycode, sizeof(atkbd->keycode));
} else {
memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));

if (atkbd->scroll)
for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) {
scancode = atkbd_scroll_keys[i].set2;
atkbd->keycode[scancode] = atkbd_scroll_keys[i].keycode;
}
}

And the actual memory for DMA:

./i8042-snirm.h:
kbd_iobase = ioremap(0x16000000, 4);
kbd_iobase = ioremap(0x14000000, 4);

seemed quite brand-independent, and from this reading of actual data is possible:
static void __iomem *kbd_iobase;

#define I8042_COMMAND_REG (kbd_iobase + 0x64UL)
#define I8042_DATA_REG (kbd_iobase + 0x60UL)

static inline int i8042_read_data(void)
{
return readb(kbd_iobase + 0x60UL);
}

static inline int i8042_read_status(void)
{
return readb(kbd_iobase + 0x64UL);
}

static inline void i8042_write_data(int val)
{
….

How does the Trackpoint on my Lenovo R400 worked?

Firstly, “dmesg” shows that Ubuntu detected the trackpoint thus:

[ 45.219976] input: TPPS/2 IBM TrackPoint as /devices/platform/i8042/serio1/input/input6

drivers/input/mouse/psmouse-base.c:

First the module and related structure is defined here:

MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);

static struct serio_driver psmouse_drv = {
.driver = {
.name = “psmouse”,
},
.description = DRIVER_DESC,
.id_table = psmouse_serio_ids,
.interrupt = psmouse_interrupt,
.connect = psmouse_connect,
.reconnect = psmouse_reconnect,
.disconnect = psmouse_disconnect,
.cleanup = psmouse_cleanup,
};

static const struct psmouse_protocol psmouse_protocols[] = {
{
.type = PSMOUSE_TRACKPOINT,
.name = “TPPS/2”,
.alias = “trackpoint”,
.detect = trackpoint_detect,
},

And then during psmouse_connection() other registration are done here:

/*
* psmouse_connect() is a callback from the serio module when
* an unhandled serio port is found.
*/
static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
{

/*
* If this is a pass-through port deactivate parent so the device
* connected to this port can be successfully identified
*/
if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
parent = serio_get_drvdata(serio->parent);
psmouse_deactivate(parent);
}

psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
input_dev = input_allocate_device();
if (!psmouse || !input_dev)
goto err_free;

ps2_init(&psmouse->ps2dev, serio);
INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), “%s/input0”, serio->phys);

psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);

……..

psmouse->rate = psmouse_rate;
psmouse->resolution = psmouse_resolution;
psmouse->resetafter = psmouse_resetafter;
psmouse->resync_time = parent ? 0 : psmouse_resync_time;
psmouse->smartscroll = psmouse_smartscroll;

psmouse_switch_protocol(psmouse, NULL);

psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
psmouse_initialize(psmouse);

error = input_register_device(psmouse->dev);

and during psmouse_connect() callback, the trackpoint is detected:

if (trackpoint_detect(psmouse, set_properties) == 0)

And the detection logic is in:

drivers/input/mouse/trackpoint.c:
int trackpoint_detect(struct psmouse *psmouse, bool set_properties)

Other defined APIs for interaction with external application:

PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
NULL,
psmouse_attr_show_protocol, psmouse_attr_set_protocol);
PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, rate),
psmouse_show_int_attr, psmouse_attr_set_rate);
PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resolution),
psmouse_show_int_attr, psmouse_attr_set_resolution);
PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resetafter),
psmouse_show_int_attr, psmouse_set_int_attr);
PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO,
(void *) offsetof(struct psmouse, resync_time),
psmouse_show_int_attr, psmouse_set_int_attr);

/*
* Device IO: read, write and toggle bit
*/
static int trackpoint_read(struct ps2dev *ps2dev, unsigned char loc, unsigned char *results)
{
if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
return -1;
}

return 0;
}

static int trackpoint_write(struct ps2dev *ps2dev, unsigned char loc, unsigned char val)

……

%d bloggers like this: