ADB(Android Debug Bridge): How it works?

tetsu.koba 31,784 views 44 slides Feb 13, 2012
Slide 1
Slide 1 of 44
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44

About This Presentation

No description available for this slideshow.


Slide Content

1
ADB
(Android Debug Bridge):
How it works?
Tetsuyuki Kobayashi
2012.2.13 Android Builders Summit

2
Let's talk about inside of Android.
http://www.kmckk.co.jp/eng/kzma9/
http://www.kmckk.co.jp/eng/jet_index.html

3
Who am I?
20+ years involved in embedded systems
10 years in real time OS, such as iTRON
10 years in embedded Java Virtual Machine
Now GCC, Linux, QEMU, Android, …
Blogs
http://d.hatena.ne.jp/embedded/ (Personal)
http://blog.kmckk.com/ (Corporate)
http://kobablog.wordpress.com/(English)
Twitter
@tetsu_koba

4
Today's topics
What is ADB?
ADB internal
Command details & Tips
Advanced Topics

What is ADB?
If you are an Android builder, you have used
”adb logcat”, ”adb shell”
Even if you only use DDMS in Eclipse, adb is
working under the hood.
Using adb, you can connect emulator or actual
target device.
”adb kill-server”? what does it mean?

6
How to connect?
Adb clients
”adb shell”
Adbd
Host
Emulator
QEMU Adbd
Target device
How to connect?

7
3 elements of ADB
adb clients
executable with subcommand
”adb shell”, ”adb logcat” : the end point of host side
adb server
running on host on back-ground
act as proxy between adb clients and adbd
adb daemon (adbd)
running on target device
started by init, if die, restarted by init again

8
ADB overview
Adb clients
Adb server
Adbd
Host
Emulator
TCP port:5037
QEMU Adbd
Target device
USB/TCP
TCP
Execute services on
new thread/subprocess

9
2 roles of ADB
Providing ”Transport”
communication path between host and target
device
USB or TCP: but clients don't have to aware
Providing ”Services”
executing something on the target devices through
the transport.
”adb shell” for executing command
”adb push/pull” for file transfer

10
When does adb server start?
Explicitly, ”adb start-server”
It starts adb server as back ground process.
Usually it does automatically on demand. You
don't have to do ”adb start-server”.
When you want to restart adb server, do ”adb
kill-server”
Actually, adb clients and adb server shares
same executable
”adb start-server” equals ”adb fork-server server &”

11
Port forwarding
Host Target device
server socket
port 1234
client socket
port 1234
adb forward tcp:1234 tcp:1234
Transport
USB or TCP

12
Port forwarding (cont.)
Host Target device
server socket
port 1234
client socket
port 1234
adb forward tcp:1234 tcp:1234
gdbserver
gdb client
listen to
localhost:1234
connect to
localhost:1234
USB or TCP
Transport
Both gdb client and gdbserver
do not aware of transport
example: connecting to gdbserver in the device from gdb client from host

13
ADB internal
Source code
How to get ADB logs
Sequence chart
Simple ruby script to connect adb server
Secure mode
Switching transport mode

14
Source code
system/core/adb in Android source tree
16,000 lines in *.[ch]
From this directory adb and adbd are built
Don't confuse.
common files between adb and adbd
adb.c, fdevent.c, transort.c, transport_local.c,
tansport_usb.c, service.c, sockets.c, util.c
#if ADB_HOST
/* code for adb*/
#else
/* code for adbd */
#endif

15
Source code(cont.)
files only for adbd
backup_service.c, file_sync_service.c,
jdwp_service.c, framebuffer_service.c,
remount_services.c, usb_linux_clients.c,
log_service.c
files only for adb
console.c, adb_clients.c, file_sync_client.c,
usb_vendors.c,
get_my_path_{linux,darwin,windows,freebsd}.c,
usb_{linux,macos,libusb,windows}.c
documents
OVERVIEW.TXT, SERVICES.TXT, protocol.txt

16
How to get ADB logs
For adb clients and adb server, set environment
variable ADB_TRACE


For adbd, set system property
”persist.adb.trace_mask” in hexadecimal

I found some trivial bugs. see below
http://blog.kmckk.com/archives/4080002.html
http://blog.kmckk.com/archives/4087230.html
$ adb kill-server
$ ADB_TRACE=all start-server
# set_property persist.adb.trace_mask 0xfff

17
Sequence chart
ls
host:version
OKAY0004001d
host:transport-any
OKAY
OKAY
shell:ls
[OPEN]shell:ls
[OPEN]shell:ls
[WRITE]len=247
len=247
len=247
stdout
subprocess
adbdAdb server
Adb client
“adb shell ls”
Check version
Specify the
destination
Command
to adbd

18
Simple ruby script to connect to
adb server
require 'socket'
def error_exit
puts "Error"
exit 1
end
def send_to_adb(s, msg)
s.printf("%04x%s",
msg.length, msg)
end
def check_okay(s)
(s.read(4) == "OKAY")
end
def check_version(s)
(s.read(12) ==
"OKAY0004001d")
end
hostname = 'localhost'
port = 5037
s = TCPSocket.open(hostname, port)
send_to_adb(s, "host:version")
error_exit if ! check_version(s)
s.close
s = TCPSocket.open(hostname, port)
send_to_adb(s, "host:transport-any")
error_exit if ! check_okay(s)
send_to_adb(s, "shell:ls")
error_exit if ! check_okay(s)
while line = s.gets
puts line.chop
end
s.close
change ”shell:ls” as you like.
http://blog.kmckk.com/archives/4092210.html

19
Secure mode
Android smart phone products have adbd.
Usually it runs on secure mode. (secure = 1)
if secure == 1, change adbd as SHELL user(=
not privileged), else it keeps running as root
user
In secure mode, all services invoked by adbd
ran as SHELL user. Some causes ”permission
denied”.

20
How secure mode decided
Running on emulator → secure = 0
System property ”ro.secure” == 1 → secure = 1
if ”ro.debuggable” == 1, you can restart adb
unsecure by ”adb root”
All Android phone products are shipped in
”ro.secure” = 1, ”ro.debuggable” = 0.
See adb.c: adb_main
http://blog.kmckk.com/archives/4099821.html

21
Switching transport mode
$ adb shell netcfg
lo UP 127.0.0.1 255.0.0.0 0x00000049
eth0 UP 192.168.1.139 255.255.255.0 0x00001043
$ adb tcpip 5555
restarting in TCP mode port : 5555
$ adb devices
List of devices attached
$
$ adb kill-server
$ ADBHOST=192.168.1.139 adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
emulator-5554 device
$
Switching USB mode to TCP mode
disconnected from USB. Then restart adb server with specifying target IP address.

22
Switching transport mode (What
happen inside?)
See service.c restart_tcp_service
property_set(”service.adb.tcp.port”, value);
Note: before Android 4.0, this cause
”permission denied” in secure mode and
ignored silently!
After that, exit(1);
init restarts adbd.
”service.adb.tcp.port” is checked in adb.c
adb_main

Patch to enable switching to TCP
mode in secure Android 2.3
$ diff -u property_service.c.2 property_service.c
--- property_service.c.2 2012-02-07 18:40:34.472414791
+0900
+++ property_service.c 2012-02-07 18:41:24.782801630
+0900
@@ -79,6 +79,7 @@
{ "debug.", AID_SHELL, 0 },
{ "log.", AID_SHELL, 0 },
{ "service.adb.root", AID_SHELL, 0 },
+ { "service.adb.tcp.port", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
system/core/init/property_service.c
This avoids ”permission denied” when set property ”service.adb.tcp.port”.
http://blog.kmckk.com/archives/4098873.html

24
Command details & Tips
adb logcat
adb install/uninstall
adb reboot/reboot-bootloader
adb emu
adb backup/restore
Joke commands
Add USB vendor ID
Restriction of server socket of Android emulator
Similar restriction in server socket created by
”adb forward”

25
adb logcat
There is ”log:” subcommand in adb server, but
”adb logcat” doesn't use it
”adb logcat” executes /system/bin/logcat
remotely
Tag filtering is done in target side
Logging in DDMS filtering in host side
similar to
”adb shell \
ANDROID_LOG_TAGS=$ANDORID_LOG_TAGS \
logcat args..”

adb install/uninstall
adb install
transfer apk file and then execute
/system/bin/pm at the device
adb uninstall
just execute /system/bin/pm remotely

adb reboot/reboot-bootloader
fork&exec /system/bin/vdc to unmount
storage
wait for the process and then reboot
by system call

28
adb emu
You can send a single command to emulator
console easily
send only. can not receive.
For emulator console,
http://developer.android.com/guide/developing/devices/emulator.html
Simple example. ”adb emu window scale 0.5”
after starting emulator
http://blog.kmckk.com/archives/4091258.html

29
adb backup/restore
New in Android 4.0
You can backup/restore installed
applications with their saved status.

30
Joke commands
adb hell
same as ”adb shell” except ”hell” color :)
Just try.
adb lolcat
same as ”adb logcat”

31
Add USB Vendor ID
When connecting USB device, adb checks USB
Vendor ID
Many USB Vendor IDs are hard coded in adb.
(But not enough)
To add USB Vendor ID, make
”$HOME/.android/adb_usb.ini” and write one ID
in one line
See usb_vendors.c

32
Restriction of server socket of
Android emulator
Adb clients
Adb server
Adbd
Host
Emulator
TCP port:5037
QEMU
TCP
Adb server
Adb clients
TCP port:5037
Adb clients
TCP port:5037
Other host
All server sockets in Android emulator accepts only from localhost.
If you feel inconvenient in this restriction, apply the patch in next page.
http://blog.kmckk.com/archives/3882865.html

33
Patch to allow connecting from
outside (for experiment)
diff --git a/slirp-android/socket.c b/slirp-android/socket.c
index 439590a..ed16d5a 100644
--- a/slirp-android/socket.c
+++ b/slirp-android/socket.c
@@ -650,7 +650,7 @@ solisten(u_int port, u_int32_t laddr, u_int lport, int
flags)
so->so_laddr_ip = laddr; /* Ditto */
so->so_haddr_port = port;

- s = socket_loopback_server( port, SOCKET_STREAM );
+ s = socket_inaddr_any_server( port, SOCKET_STREAM );
if (s < 0)
return NULL;

diff --git a/sockets.c b/sockets.c
index 1063339..55b5d57 100644
--- a/sockets.c
+++ b/sockets.c
@@ -1337,6 +1337,11 @@ socket_in_client( SockAddress* to, SocketType type )
return socket_connect_client( s, to );
}

+int
+socket_inaddr_any_server( int port, SocketType type )
+{
+ return socket_in_server( INADDR_ANY, port, type );
+}

int
socket_loopback_server( int port, SocketType type )
external/qemu

34
Similar restriction in server
socket created by ”adb forward”
adb forward tcp:1234 tcp:1234
Host Target device
server socket
port 1234
client socket
port 1234
Transport
USB or TCP
client
Other host
From localhost only

Patch to allow connecting from
outside (for experiment)
diff --git a/adb/adb.c b/adb/adb.c
index f5e6e0c..1405e1c 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -481,7 +481,8 @@ int local_name_to_fd(const char *name)
if(!strncmp("tcp:", name, 4)){
int ret;
port = atoi(name + 4);
- ret = socket_loopback_server(port, SOCK_STREAM);
+ ret = socket_inaddr_any_server(port, SOCK_STREAM);
return ret;
}
#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */
system/core

36
Advanced Topics
adb in Android device
Port adbd to other than Android

37
adb in Android device
Usually, adb is running on the host side,
such as Linux, MacOS and Windows
In Android 4.0 there is /system/bin/adb in
Android file system
What for is this?

38
Connect its own adbd by adb
Restart adbd in TCP mode
Then type ”adb devices”
It can connect its own adbd by local loop back
Adb clients
Adb serverAdbd
Target device
TCP port:5038
TCP
But what is
the use case?
http://blog.kmckk.com/archives/4092970.html

39
Connect other Android device by
adb on Android
USB Host
(A connector)
USB device
(micro B connector)
NexusOne
(Android 2.3.6)
KZM-A9-Dual board
(Android 4.0.3)
http://blog.kmckk.com/archives/4094716.html

40
Connect other Android device by
adb on Android(cont.)
# adb devices
* daemon not running. starting it now on port 5038 *
* daemon started successfully *
List of devices attached
HT015P803242 device
#
It worked!
You can do ”adb shell”, ”adb logcat”, too.
Even you can install application from the board
to NexusOne by ”adb install foo.apk”.
At the serial console on KZM-A9-Dual board

41
Port adbd to other than Android
Quick hack!
Consider dependency for better porting
ARM Ubuntu 11.10
ARM Ubuntu 11.10
Kernel with Android patch
Kernel with Android patch
Adbd

42
Quick hack!
/sbin/adbd is statically linked executable.
Just copy this file to ARM Ubuntu 11.10 just for
experiment (using Android patched kernel)
Somehow, it worked without any recompilation
sudo chmod 666 /dev/android_adb*
make symbolic link /bin/sh to /system/bin/sh
adbd runs in secure mode
It worked ”adb shell”, ”adb push/pull”
http://blog.kmckk.com/archives/4093193.html

43
Consider dependency for better
porting
Some service requires other android
commands
adb install/uninstall, adb bugreport
framebuffer service invokes /system/bin/screencap
Adbd uses Android system properties
At the binary experiment, all property_get returns
default values.
That's why adbd ran in secure mode.
Switching adbd mode assumes that init restarts
adbd process

44
Q & A
Thank you for listening!
Any comments to blogs are welcome.