"Embedded" Android
http://www.slideshare.net/opersys/embedded-android-workshop-with-nougat
... android history and platform overview
libc
- bionic
- bastardized but mostly works
- (I believe it's bsd's libc)
hal
- hardware abstraction layer
- biggest divergance from linux
init
- only userspace process started by kernel
- android has its own init semantics
- namely global properties and triggers (executed in response to changes)
shell
- toybox
- busybox is gpl so android doesn't use it
- toybox has many parts written by the original busybox author
zygote
- vm bootstrap (parent) process
services
$ service list
- system vs app
- system is boot to boot
- app service lifecycle is managed by the activity manager
- binder (ipc mechanism)
java
- openjdk now
kernel
- low memory killer
- when memory fills up system kills apps
- system has communicate memory conditions
- custom oom killer driver (lmk)
boot process
- cpu gets power
- first instruction address
- bootloader
- modern cpus usually have internal booloaders which handle various bootstrap things
- like secure boot
- kernel starts
- init
== identical to standard linux boot so far ==
- daemons
- zygote
- tailored for android user experience
- hot vm
- about 4k classes loaded
- when you start an activity the activity manager asks zygote to fork
- that's why the launcher is not the parent process for apps
bootloader
- doesn't manner
- fastboot is the modern protocol bootloaders adhere to
- reference bootloader is based on lk
storage layout
- boot image -- kernel _ ram disk
- system partition -- /system
- data partition -- /data
- cache partition -- /cache
- vendor partition -- /vendor
- recovery partition -- alternate boot image
boot
- kernel
- as mentioned, standard start (pretty hardware dependent)
- android init
linux kernel internals
- hardware components
- kernel right on top
- exposes userspace
- syscalls and signals (communication)
- hardware support
- HALs
- one HAL for each hardware type
- HAL modules are shared libraries
- still backed by a service unless otherwise specified
native user-space
- /system => system components or otherwise firmware
- /data => user data
- /cache => cache and ota update also:
- /dev
- /proc
- /sys
- /sbin
- /mnt
- etc..
android java
- oracle (sun) java
- java language + jvm + jdk libs
- android java
- java language + art + apache harmony | openjdk
art (android runtime)
- vs dalvik
- 64 bit
- multi-core
- aot (vs jit)
- better debugging
- profiling/stack/crashes
- largely replaced dalvik
"java is nice but sometimes you have to do real work" jni
- java native interface
- call gate for other languages
- usage: native app from code
- tools: ndk
system services
- the android os
-
95 or so on modern android
- 5 or 6 new every major release
- $ service list will not show app services, only system
- many are separate services
- some are combined
- some written in c some in java
- because performance
- story: flight sims
- devs would insert random 10/20ms delays if the test pilots were jerks
- moral: humans are sensative even to that type of latency (think video/audo sync)
- garbage collection sucks
- because performance
- some services are relaunched when they're killed
- e.g. phone, but not email
- android:persistent=true for platform apps
- activity manager starts persistent apps
- just their application is loaded into memory
- from there you can register your system service
- apps/services run as different users
- app api: getSystemService(id)
activity manager
- big thing kinda sucks but necessary
binder
- cobra/com-like ipc
- binder comes from bos/90s
- palm wanted to stop using bos
- engineers wanted to open-source it before it got killed
- everyone at palm hated it
- except the palm engineers who liked it
- android binder inspired by "open binder" the binder source drop
- kernel-supported
- /dev/binder
- /sys/kernel/debug/binder/*
- "object-oriented os on top of normal os"
- original open-binder was network capable so you could do rpc to remote resources
- android not so much )=
- vs sockets:
- sockets: port, feed data structures
- no pre-defined binder ids
- no port 80, or 443, etc.
- cursory name resolution
- ask for service named: "foo"
- it is actual remote method invocation
- feed method params then feed function name
- android parcelable is the way to feed things through binder
binder driver
- driver gets an init call on boot
- doesn't init hardware only does stuff in ram
- service manager talks to binder driver
- service manager is just a directory service
- remember: service list
- service manager declares itself as the context manager
- anyone talking to binder id:0 is talking to the service manager
- service manager serves as "dns" for system services
- system services must register with the service manager
- app does:
- get service
- looks up service via binder context service
- returns handle to service
- app calls into service using handle
- activity manager handles ids for some system services
- every service has a dump() function
- $ dumpsys dumps all system services
- $ dumpsys statusbar would just do statusbar (obviously)
- context manager is "first come first serve" usually registered very early in init
- for fun:
- $ service call statusbar 1|2 (expand/collapse status bar)
- binder explorer
- really cool visualization tool for android IPC (I need to check this out)
- https://github.com/opersys/binder-explorer-web
- extra
- kmsg failed (in-kernel dmsg impl)
- future: binder on top of bus1?
- linux plumbers conference last year
Hardware Abstraction Layer
- often closed source from vendors
- idea is that as a vendor all you need to provide is a hal module
- framework and apps use your HAL
- few dozen integration points.. not as simple as it could be
AOSP tools and location
- "standard" android build:
- http://android.googlesource.com
- use repo pointed at the manifest file
- use a named branch so you aren't building off master
content
- see slide 65
- changes for your hardware happen in the "device" tree
- libhardware/include/hardware is the hal
- kernel is not part of the aosp
- there is a dependency on kernel headers, though
building
- ubuntu friendly
- follow the instructions
- . or source the build/buildsetup.sh
- choose your
lunch
options (haha) - and
make
croot
takes you to the top of the android treegodir
file.name takes you to the directory that contains the filemm
rebuilds just the part of the tree you are inm snod
(snod is the system image target)- remember:
- hmm
- make help
build system architecture
- NOT RECURSIVE
- "recursive make considered harmful"
- Android.mk
- build "module"
- rules
- every Android.mk is self contained
- (vs recursive where parents matter)
- can load/include other Android.mk..
- PRODUCT_PACKAGES is configured with packages that should be built
- list begins at embedded.mk
- included by base.mk
- "object oriented build system with multiple inheritance" --guy who wrote it
- barf
- packages/apps/gallery/Android.mk
- include BUILD_PACKAGE
- determines what it's building
- LOCAL_PACKAGE_NAME = "apkname"
- include BUILD_PACKAGE
- frameworks/native/c2dm/service/Android.mk
- include BUILD_EXECUTABLE
- LOCAL_MODULE = "soname"
- more LOCAL things exist ^^ just examples
- ninja
- layer under make for module generation and and build progress caching
output
- [aosp]/out/target/product/generic/
- kernel
- prebuilt/android-arm/kernel/kernel-qemu
- emulator overrides kernel and initrd
adb
- use the help or something
- it's the debug bridge
add a new device
- device/acme/coyotepad/
- AndroidProducts.mk
- add to PRODUCT_MAKEFILES := $(LOCAL_DIR)/full_coyotepad.mk
- full_coyotepad.mk
- specifies options such as name, device, model, etc.
- BoardConfig.mk
- hardware options, kernel, arch, camera/audio etc.
- Android.mk
- AndroidProducts.mk
- menu integration:
- vendorsetup.sh
- add_lunch_combo full_[combo-level]
- vendorsetup.sh
- Android.mk as a filter so that it only gets picked up when building for the hardware
- lunch combos
- [device name]-[eng|userdebug|user]
- levels
- eng has root
- and extra tools
- userdebug is normal user by default but allows root
- user: production build
- no root
- eng has root
adding new apps
- vendor local
- device/acme/coyotepad
- Android.mk
- PRODUCT_PACKAGES
- global
- [aosp]/packages/apps
- [aosp]/build/target/product/core.mk
- overlays are used to provide your own resources (or even sources)
- DEVICE_PACKAGE_OVERLAYS := device/acme/coyotepad/overlay
- tools
- system[/core]/
- frameworks/[base|native]/cmds/
- external/
Kernel
Native Android User-Space
-
acct for scheduler
-
props
- property service
- /data/property
-
etc
- fstab: normal use
- selinux policies
- android rc
android rc
- system/core/rootdir/init.rc
- import
- "run level" strings
- not command line instructions, internal init language
- init binary determines orders
- hardware-specific init files can exist
- init process process all rc files and runs all "sections" together
- early init is the only thing that doesn't have something run before it
- service declarations
- service name and then a string
- service here means init service not system service (binder)
- traditional daemons +"launchctl-like" options: oneshot, last will instructions
- classes: core, main, default (if none is specified)
- classes are like the init levels
- this is how most user-space daemons start
- example: boot animation depends on surface flinger
- so the boot animation service is disabled initially
- then it is enabled by surface flinger after it has started
- special properties correspond to init services
- import
stop zygote
kills the userspace- surface flinger brings back the boot animation when the connection to the window manager dies
start zygote
brings it back- bootanimation is swapped back out for the windowmanager once it is restarted
binary utilities
- am => activity manager
- pm => package manager
- wm => window manager
- svc => binder service registry
- ... see slides for more (cf. 124...)
app home
- /data/data
- permission model: uid sandbox
- each app is its own uid
- multi-user
- user 0: /data/data
- user n: /data/data/userN
etc/passwd on android
- defined in a header file
- static mapping to strings since you don't create kernel/system users dynamically
- app ids are deltas from 10000
- each android user gets 100000 app uids
- unlisted shit goes to root as 644
adb
- usb
- tcp/ip
- different log buffers
- bugreport
shell
- was old netBSD crap shell
- moved to korn BSD shell
- now toybox
getting java up
- required:
- service manager
- zygote
- package manager
- finds dex files and processes them
- system things
- imput methods
- persistent apps
- home screen (home intent)
- BOOT_COMPLETED intent
- APPWIDGET_UPDATE intent
- framework is now ready for interactions
- naitive daemons
- exist for privelege separation
- rild exception to HAL model
- system talks to rild and rild talks to HAL
- system can crash without bringing the ril down
- doesn't quite actually end up working that way
- point is mission critical components are housed outside of android right on the kernel
observe system services
- look for pid and logcat
- dumpsys
android cross reference (opersys)
- cross refernce services
- might be helpful tool: http://xref.opersys.com/
implement service
- see slide 155