rildandroid
Ⅰ android.rild.kernel.logs文件可以刪嗎
一些日誌文件,是可以刪掉的,大部分都是用來記錄一些行為或者緩存的數據。
Ⅱ HAL 硬體抽象層
綁定式 HAL 。以 HAL 介面定義語言 (HIDL) 或 Android 介面定義語言 (AIDL) 表示的 HAL。這些 HAL 取代了早期 Android 版本中使用的傳統 HAL 和舊版 HAL。在綁定式 HAL 中,Android 框架和 HAL 之間通過 Binder 進程間通信 (IPC) 調用進行通信。所有在推出時即搭載了 Android 8.0 或後續版本的設備都必須只支持綁定式 HAL。
直通式 HAL 。以 HIDL 封裝的傳統 HAL 或 舊版 HAL 。這些 HAL 封裝了現有的 HAL,可在綁定模式和 Same-Process(直通)模式下使用。升級到 Android 8.0 的設備可以使用直通式 HAL。
Android 要求所有 Android 設備(無論是搭載 Android O 的設備還是升級到 Android O 的設備)上的下列 HAL 均為綁定式:
[email protected]。取代 Android 8.0 中已不存在的 fingerprintd。
[email protected]。Android 8.0 中的新 HAL。
[email protected]。此 HAL 提供的原始介面可能無法繼續使用,並且已更改。因此,mpstate_board 必須在指定的設備上重新實現(這是一個可選的 HAL)。
[email protected]。在 Android 8.0 中,此 HAL 必須為綁定式,因此無需在可信進程和不可信進程之間分享文件描述符。
[email protected]。取代由存活於自身進程中的 rild 提供的介面。
[email protected]。Android 8.0 中的新 HAL。
[email protected]。Android 8.0 中的新 HAL,可取代此前載入到 system_server 中的舊版 WLAN HAL 庫。
[email protected]。在現有 wpa_supplicant 進程之上的 HIDL 介面。
注意 :Android 提供的以下 HIDL 介面將一律在綁定模式下使用:android.frameworks.*、android.system.* 和 android.hidl.*(不包括下文所述的 [email protected])。
Android 要求所有 Android 設備(無論是搭載 Android O 的設備還是升級到 Android O 的設備)上的下列 HAL 均在直通模式下使用:
[email protected]。將內存映射到其所屬的進程中。
[email protected]。在同一進程中傳遞項(等同於 openGL)。
上方未列出的所有 HAL 在搭載 Android O 的設備上都必須為綁定式。
Ⅲ ril位於android哪一層
上圖清楚的標識了ril在整個Android系統各層的表現形式,我們這里主要分析Ril(RIDL、librefrenece_ril.so、libril.so);
…/Hardware/ril/rild RILD的代碼實現,有main函數,作為ril層的入口點,常駐系統進程,負責與上下層交互
…/Hardware/ril/libril 負責與守護進程交互???
…/Hardware/ril/reference-ril/ Ril庫的實現,主要負責與modem進行交互
實現詳細分析:
從init.rc中service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyUSB1 -u /dev/ttyUSB2
可以知道,Android啟動時,系統會啟動一個與ril相關的service (ril-daemon),其入口命令為/system/bin/rild
(一)那麼首先看看rild(/hardware/ril/rild/*);該目錄下有兩文件radiooptions.c、rild.c
Radiooptions.c 看Makefile知道最終會被編譯成radiooptions二進制工具,放在/system/bin/下面,具體用法我在這里就不說了,我到終點裡面執行一下,把他的help信息打出了,再詳細的就自己看吧,源碼不長,也不復雜。
# radiooptions
Ⅳ 如何查找喚醒android系統
如果在休眠中系統被中斷或者其他事件喚醒,接下來的代碼就會開始執行,這個喚醒的順序是和休眠的循序相反的,所以系統設備和匯流排會首先喚醒,使能系統中斷,使能休眠時候停止掉的非啟動CPU,以及調用suspend_ops->finish(),而且在suspend_devices_and_enter()函數中也會繼續喚醒每個設備,使能虛擬終端,最後調用suspend_ops->end().
在返回到enter_state()函數中的,當suspend_devices_and_enter()返回以後,外設已經喚醒了,但是進程和任務都還是凍結狀態,這里會調用suspend_finish()來解凍這些進程和任務,而且發出Notify來表示系統已經從suspend狀態退出,喚醒終端.
到這里,所有的休眠和喚醒就已經完畢了,系統繼續運行了.
Android系統Suspend和resume的函數流程
Android 休眠(suspend)介紹
在一個打過android補丁的內核中,state_store()函數會走另外一條路,會進入到request_suspend_state()中,這個文件在earlysuspend.c中.這些功能都是android系統加的,後面會對earlysuspend和lateresume進行介紹。
涉及到的文件:
linux_source/kernel/power/main.c
linux_source/kernel/power/earlysuspend.c
linux_source/kernel/power/wakelock.c
特性介紹
1)EarlySuspend
Early suspend是android引進的一種機制,這個機製作用在關閉顯示的時候,一些和顯示有關的設備,比如LCD背光,重力感應器,觸摸屏,這些設備都會關掉,但是系統可能還是在運行狀態(這時候還有wakelock)進行任務的處理,例如在掃描SD卡上的文件等.在嵌入式設備中,背光是一個很大的電源消耗,所以android會加入這樣一種機制。
2)LateResume
Late Resume是和suspend配套的一種機制,是在內核喚醒完畢開始執行的,主要就是喚醒在EarlySuspend的時候休眠的設備.
當所有的喚醒已經結束以後,用戶進程都已經開始運行了,喚醒通常會是以下的幾種原因:
來電
如果是來電,那麼Modem會通過發送命令給rild來讓rild通知WindowManager有來電響應,這樣就會遠程調用PowerManagerService來寫"on"到/sys/power/state來執行lateresume的設備,比如點亮屏幕等.
用戶按鍵用戶按鍵事件會送到WindowManager中,WindowManager會處理這些按鍵事件,按鍵分為幾種情況,如果案件不是喚醒鍵(能夠喚醒系統的按鍵)那麼WindowManager會主動放棄wakeLock來使系統進入再次休眠,如果按鍵是喚醒鍵,那麼WindowManger就會調用PowerManagerService中的介面來執行Late Resume.
Late Resume會依次喚醒前面調用了EarlySuspend的設備.
3)WakeLock
Wake Lock在Android的電源管理系統中扮演一個核心的角色.Wake Lock是一種鎖的機制,只要有人拿著這個鎖,系統就無法進入休眠,可以被用戶態程序和內核獲得。這個鎖可以是有超時的或者是沒有超時的,超時的鎖會在時間過去以後自動解鎖。如果沒有鎖了或者超時了,內核就會啟動休眠的那套機制來進入休眠。
3)AndroidSuspend
當用戶寫入mem或者standby到/sys/power/state中的時候,state_store()會被調用,然後Android會在這里調用request_suspend_state()而標準的Linux會在這里進入enter_state()這個函數.如果請求的是休眠,那麼early_suspend這個workqueue就會被調用,並且進入early_suspend狀態。調用request_suspend_state()後在suspend_work_queue工作線程上面注冊一個early_suspend_work工作者,
然後又通過staticDECLARE_WORK(early_suspend_work, early_suspend);注冊一個工作任務early_suspend。所以系統最終會調用early_suspend函數。
注冊加入suspend和resume流程
platform_device_register()-->platform_device_add()-->device_add()-->device_pm_add()-->,最終加入到了dpm_list的鏈表中,在其中的dpm_suspend和dpm_suspend中通過遍歷這個鏈表來進行查看哪個device中包含suspend和resume項。
系統喚醒和休眠
Kernel層[針對AndroidLinux2.6.28內核]:
其主要代碼在下列位置:
Drivers/base /main.c
kernel/power /main.c
kernel/power/wakelock.c
kernel/power/earlysuspend.c
其對Kernel提供的介面函數有
EXPORT_SYMBOL(wake_lock_init);//初始化Suspendlock,在使用前必須做初始化
EXPORT_SYMBOL(wake_lock);//申請lock,必須調用相應的unlock來釋放它
static DEFINE_TIMER(expire_timer,expire_wake_locks, 0, 0);//定時時間到,加入到suspend隊列中;
EXPORT_SYMBOL(wake_unlock);//釋放lock
EXPORT_SYMBOL_GPL(device_power_up);//打開特殊的設備
EXPORT_SYMBOL_GPL(device_power_down);//關閉特殊設備
EXPORT_SYMBOL_GPL(device_resume);//重新存儲設備的狀態;
EXPORT_SYMBOL_GPL(device_suspend);:保存系統狀態,並結束掉系統中的設備;
EXPORT_SYMBOL(register_early_suspend);//注冊earlysuspend的驅動
EXPORT_SYMBOL(unregister_early_suspend);//取消已經注冊的earlysuspend的驅動
Android的suspent執行流程
函數的流程如下所示:
應用程序通過對/sys/power/state的寫入操作可以使系統進行休眠的狀態,會調用/kernel/power/main.c中的state_store函數。pm_states包括:
PM_SUSPEND_ON,PM_SUSPEND_STANDBY,PM_SUSPEND_MEM滿足的狀態。
1)當狀態位PM_SUSPEND_ON的狀態的時候,request_suspend_state();當滿足休眠的狀態的時候,調用request_suspend_state在suspend_work_queue工作線程上創建early_suspend_work隊列,queue_work(suspend_work_queue,&early_suspend_work)。
2)然後通過DECLARE_WORK(early_suspend_work,early_suspend);在early_suspend_work工作隊列中添加工作任務調用early_suspend,所以early_suspend函數會被調用。
3)early_suspend函數中通過
list_for_each_entry(pos,&early_suspend_handlers, link) {
if (pos->suspend != NULL)
pos->suspend(pos);
在鏈表中找注冊的suspend函數,這個suspend是early的。early_suspend後面調用wake_unlock函數。語句:wake_unlock(&main_wake_lock);
4)wake_unlock()中調用mod_timer啟動expire_timer定時器,當定時時間到了,則執行expire_wake_locks函數,將suspend_work加入到suspend_work_queue隊列中,分析到這里就可以知道了early_suspend_work和suspend_work這兩個隊列的先後順序了(先執行early,定義一段時間後才執行suspend_work),然後會在suspend_work隊列中加入suspend的工作任務,所以wakelock.c中的suspend函數會被調用。
5)suspend調用了pm_suspend,通過判斷當前的狀態,選擇enter_state(),在enter_state中,經過了suspend_prepare,suspend_test和suspend_device_and_enter(),在suspend_device_and_enter中調用dpm_suspend_start(),然後調用dpm_suspend()。
6)dpm_suspend中利用while循環在dpm_list鏈表查找所有devic,然後調用device_suspend來保存狀態和結束系統的設備。到了這里,我們就又可以看見在初始化的時候所看到的隊列dpm_list。
dpm_list鏈表的添加是在device_pm_add中完成,請看上一節中。
Wake Lock
我們接下來看一看wakelock的機制是怎麼運行和起作用的,主要關注wakelock.c文件就可以了。
wake lock有加鎖和解鎖兩種狀態,加鎖的方式有兩種,一種是永久的鎖住,這樣的鎖除非顯示的放開,是不會解鎖的,所以這種鎖的使用是非常小心的.第二種是超時鎖,這種鎖會鎖定系統喚醒一段時間,如果這個時間過去了,這個鎖會自動解除.
鎖有兩種類型:
WAKE_LOCK_SUSPEND這種鎖會防止系統進入睡眠
WAKE_LOCK_IDLE這種鎖不會影響系統的休眠,作用我不是很清楚.
在wakelock中,會有3個地方讓系統直接開始suspend(),分別是:
1)在wake_unlock()中,如果發現解鎖以後沒有任何其他的wakelock了,就開始休眠
2)在定時器都到時間以後,定時器的回調函數會查看是否有其他的wakelock,如果沒有,就在這里讓系統進入睡眠.
3)在wake_lock()中,對一個wakelock加鎖以後,會再次檢查一下有沒有鎖,我想這里的檢查是沒有必要的,更好的方法是使加鎖的這個操作原子化,而 不是繁冗的檢查.而且這樣的檢查也有可能漏掉.
Android於標准Linux休眠的區別
pm_suspend()雖然會調用enter_state()來進入標準的Linux休眠流程,但是還是有一些區別:
當進入凍結進程的時候,android首先會檢查有沒有wakelock,如果沒有,才會停止這些進程,因為在開始suspend和凍結進程期間有可能有人申請了wake lock,如果是這樣,凍結進程會被中斷.
在suspend_late()中,會最後檢查一次有沒有wakelock,這有可能是某種快速申請wakelock,並且快速釋放這個鎖的進程導致的,如果有這種情況,這里會返回錯誤,整個suspend就會全部放棄.如果pm_suspend()成功了,LOG的輸出可以通過在kernelcmd裡面增加"no_console_suspend"來看到suspend和resume過程中的log輸出。
Android的電源管理主要是通過Wakelock來實現的,在最底層主要是通過如下隊列來實現其管理:
LIST_HEAD(dpm_list);
系統正常開機後進入到AWAKE狀態,,Backlight會從最亮慢慢調節到用戶設定的亮度,系統screenoff timer(settings->sound & display-> Display settings ->Screen timeout)開始計時,在計時時間到之前,如果有任何的activity事件發生,如Touchclick, keyboard pressed等事件,則將Resetscreen off timer, 系統保持在AWAKE狀態.如果有應用程序在這段時間內申請了Fullwake lock,那麼系統也將保持在AWAKE狀態,除非用戶按下powerkey.在AWAKE狀態下如果電池電量低或者是用AC供電screenoff timer時間到並且選中Keepscreen on while pluged in選項,backlight會被強制調節到DIM的狀態。
如果Screenoff timer時間到並且沒有Fullwake lock或者用戶按了powerkey,那麼系統狀態將被切換到NOTIFICATION,並且調用所有已經注冊的early_suspend_handlers函數,通常會把LCD和Backlight驅動注冊成earlysuspend類型,如有需要也可以把別的驅動注冊成earlysuspend,這樣就會在第一階段被關閉.接下來系統會判斷是否有partialwake lock acquired, 如果有則等待其釋放,在等待的過程中如果有useractivity事件發生,系統則馬上回到AWAKE狀態;如果沒有partialwake lock acquired, 則系統會馬上調用函數pm_suspend關閉其它相關的驅動,讓CPU進入休眠狀態。
系統在Sleep狀態時如果檢測到任何一個Wakeupsource,則CPU會從Sleep狀態被喚醒,並且調用相關的驅動的resume函數,接下來馬上調用前期注冊的earlysuspend驅動的resume函數,最後系統狀態回到AWAKE狀態.這里有個問題就是所有注冊過earlysuspend的函數在進Suspend的第一階段被調用可以理解,但是在resume的時候,Linux會先調用所有驅動的resume函數,而此時再調用前期注冊的earlysuspend驅動的resume函數有什麼意義呢?個人覺得android的這個earlysuspend和lateresume函數應該結合Linux下面的suspend和resume一起使用,而不是單獨的使用一個隊列來進行管理。
Ⅳ android系統shell腳本中傳帶空格參數
問題:需要通過shell腳本,執行「setprop rild.libargs -d /dev/ttyUSB2」命令,即:設置rild.libargs=-d /dev/ttyUSB2。
寫法:
LTE_ARGS="rild.libargs"
DATA_PATH="-d /dev/ttyUSB2"
DATA_PATH2="-d /dev/ttyUSB3"
setprop " DATA_PATH"
說明:上面將$DATA_PATH加了雙引號,即把「-d /dev/ttyUSB2」當做一個整體,如果不加的話會提示:「setprop: Max 2 arguments」。
Ⅵ Android 怎樣在應用程序中通過串口(比如ttyS0)來發送和接收數據
可以參考rild的實現
Ⅶ Android系統下的build.prop文件
Android系統下的build.prop文件,用adb shell進入,再進入到system目錄,查看該目錄下的文件,會看到build.prop文件,用exit命令退出。
C:\Users\Administrator\Desktop>adb root
adbd is already running as root
C:\Users\Administrator\Desktop>adb remount
remount succeeded
//把文件拉到桌面
C:\Users\Administrator\Desktop>adb pull /system/build.prop
436 KB/s (4474 bytes in 0.010s)
//修改之後,推送回/system/,例如修改了ro.sf.hwrotation=180,使屏幕旋轉180°
C:\Users\Administrator\Desktop>adb push C:\Users\Administrator\Desktop\build
p /system/
19 KB/s (4459 bytes in 0.227s)
C:\Users\Administrator\Desktop>adb shell
root@T508AC:/ # cd system/
root@T508AC:/system # ls
app
bin
build.prop
etc
fonts
framework
lib
lost+found
manifest.xml
media
priv-app
tts
usr
vendor
xbin
//執行這個命令才可以生效
root@T508AC:/system # chmod 644 build.prop
//重啟設備就可以看到屏幕旋轉180讀已經生效了
root@T508AC:/system # reboot
build.prop的文件內容:
ro.build.id=LMY49F
ro.build.display.id=rk3288-eng 5.1.1 LMY49F eng.zhangfeng.20190306.051048 test-keys
ro.build.version.incremental=eng.zhangfeng.20190306.051048
ro.build.version.sdk=22
ro.build.version.codename=REL
ro.build.version.all_codenames=REL
ro.build.version.release=5.1.1
ro.build.version.security_patch=2016-03-01
ro.build.version.base_os=
ro.build.date=Wed Mar 6 05:16:23 EST 2019
ro.build.date.utc=1551867383
ro.build.type=eng
ro.build.user=zhangfeng
ro.build.host=build
ro.build.tags=test-keys
ro.build.flavor=rk3288-eng
ro.proct.model=T508AC
ro.proct.brand=Android
ro.proct.name=T508AC
ro.proct.device=T508AC
ro.proct.board=rk30sdk
ro.jiebao.version=T508AC_OS_E0A_V0.0.29_LYNQ
ro.proct.cpu.abi=armeabi-v7a
ro.proct.cpu.abi2=armeabi
ro.proct.cpu.abilist=armeabi-v7a,armeabi
ro.proct.cpu.abilist32=armeabi-v7a,armeabi
ro.proct.cpu.abilist64=
ro.proct.manufacturer=rockchip
ro.proct.locale.language=zh
ro.proct.locale.region=CN
ro.wifi.channels=
ro.board.platform=rk3288
ro.build.proct=rk3288
ro.build.description=rk3288-eng 5.1.1 LMY49F eng.zhangfeng.20190306.051048 test-keys
ro.build.fingerprint=Android/rk3288/rk3288:5.1.1/LMY49F/zhangfeng03060514:eng/test-keys
ro.build.characteristics=tablet
ro.ril.ecclist=112,911
ro.opengles.version=196609
wifi.interface=wlan0
rild.libpath=/system/lib/libril-rk29-dataonly.so
rild.libpath.jb=/system/lib/libreference-ril-jb.so
rild.libpath.LYNQ=/system/lib/libreference-ril-LYNQ.so
rild.libpath.HW=/system/lib/libreference-ril-HW.so
rild.libpath.LS=/system/lib/libreference-ril-LS.so
rild.libargs=-d /dev/ttyUSB2
persist.tegra.nvmmlite = 1
ro.audio.monitorOrientation=true
persist.sys.strictmode.visual=0
persist.sys.strictmode.disable=1
debug.nfc.fw_download=false
debug.nfc.se=false
ro.rk.screenoff_time=60000
ro.rk.screenshot_enable=true
ro.rk.def_brightness=200
ro.rk.homepage_base= http://www.google.com/webhp?client= {CID}&source=android-home
ro.rk.install_non_market_apps=false
sys.hwc.compose_policy=6
sys.wallpaper.rgb565=0
sf.power.control=2073600
sys.rkadb.root=0
ro.sf.fakerotation=false
ro.sf.hwrotation=180
ro.rk.MassStorage=false
ro.rk.systembar.voiceicon=true
ro.rk.systembar.tabletUI=false
ro.rk.LowBatteryBrightness=false
ro.tether.denied=false
sys.resolution.changed=false
ro.default.size=100
persist.sys.timezone=
ro.proct.usbfactory=rockchip_usb
wifi.supplicant_scan_interval=15
ro.factory.tool=0
ro.kernel.android.checkjni=0
ro.sf.lcd_density=160
ro.adb.secure=0
ro.com.android.dateformat=MM-dd-yyyy
ro.config.ringtone=Ring_Synth_04.ogg
ro.config.notification_sound=pixiest.ogg
ro.carrier=unknown
ro.config.alarm_alert=Alarm_Classic.ogg
ro.target.proct=tablet
ro.factory.hasGPS=true
dalvik.vm.heapstartsize=16m
dalvik.vm.heapgrowthlimit=192m
dalvik.vm.heapsize=512m
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=512k
dalvik.vm.heapmaxfree=8m
net.dns1=8.8.8.8
net.dns2=8.8.4.4
camera2.portability.force_api=1
persist.sys.strictmode.visual=false
dalvik.vm.jniopts=warnonly
ro.rk.bt_enable=true
ro.factory.hasUMS=true
persist.sys.usb.config=mass_storage
testing.mediascanner.skiplist=/mnt/internal_sd/Android/
ro.factory.storage_suppntfs=true
ro.factory.without_battery=false
keyguard.no_require_sim=true
ro.com.android.dataroaming=true
ril.function.dataonly=1
ro.config.enable.remotecontrol=false
ro.proct.version=1.0.0
ro.proct.ota.host= www.rockchip.com:2300
persist.sys.dalvik.vm.lib.2=libart.so
dalvik.vm.isa.arm.features=div
ro.kernel.android.checkjni=1
dalvik.vm.image-dex2oat-filter=verify-none
dalvik.vm.dex2oat-filter=interpret-only
dalvik.vm.dexopt-flags=m=y
net.bt.name=Android
dalvik.vm.stack-trace-file=/data/anr/traces.txt
ro.fota.platform=RK3288_5.1
ro.fota.type=pad_phone
ro.fota.app=5
ro.fota.oem=jiebao-RK3288_5.1
ro.fota.device=T508AC
ro.fota.version=T508AC_OS_E0A_V0.0.29_LYNQ_20190306-0516
Ⅷ android rild占滿CPU
CPU和內存小。在PC上運行android虛擬機AVD,打開任務管理器我們會發現AVD進程對CPU和內存的佔用非常高,所以CPU和內存較小的電腦就會出現androidrild占滿CPU的情況,所以androidrild占滿CPU是因為CPU和內存小。
Ⅸ 當我們按下電源鍵,Android 究竟做了些什麼
一、啟動電源及系統啟動
系統從 ROM 中開始啟動,載入引導程序到 RAM ,然後執行。
二、引導程序引導程序是 Android 操作系統開始運行前的一個小程序,因此它需要針對特定主板與晶元,並不是 Android 操作系統的一部分。引導程序是OEM廠商或運行商進行加鎖、限制的地方。
1、兩個階段 檢測外部 RAM 以及為第二階段載入程序; 設置網路、內存等,搭建內核運行環境(為了達到特殊目的時,引導程序可以根據配置參數或者輸入數據來設置內核)。 2、引導程序的載入器Android引導程序可以在ootableootloaderlegacyusbloader找到,傳統的載入器包含的兩個文件:
init.s 初始化堆棧,清零BSS段,會調用 main.c 中的 _main()函數 (bss segment:通常是指用來存放程序中未初始化的全局變數的一塊內存區域;BSS - Block Started by Symbol。BSS段屬於靜態內存分配); main.c 初始化硬體,創建 linux 標簽。 三、內核啟動Android 內核啟動方式類似桌面 linux,主要步驟:
1. 設置緩存 2. 被保護存儲器 3. 計劃列表 4. 載入驅動
當內核完成系統設置,接下來即將啟動系統的第一個進程 —init 進程
四、init 進程作為 Android 系統的第一個進程,其PID為0,通過解析 init.rc 腳本來構建出系統初始運行形態,這一階段中,「Android」 logo 會顯示出來。
備註:系統中,大多數系統服務程序都是在該腳本中描述並被相繼啟動的。
init.rc 由4種類型聲明組成:Actions、Commands、Services、Options
Actions: 響應某事件的過程。當「trigger」所描述的觸發事件產生時,則依次執行各種「command」; 源碼角度來看,系統會對 init.rc 中各「trigger」進行匹配,當發現符合條件的 Action,就將它加入「命令執行隊列」尾部(除非 Action 已存在隊列中),然後系統再對這些命令按順序進行。 on <trigger> ##觸發條件 <command1> ##執行命令 <command2> ##可執行多個命令 ... Commands: 命令將在所屬事件發生時被一個個執行。 Services: 可執行程序,它們在特定選項的約束下會被 init 程序運行或者重啟 備註:Service 可以在配置中指定是否需要退出重啟,那麼,當 Service 出現異常 crash 時,可有機會復原。 service <name><pathname> [<argument>]* <option> <option> Options: 對 service 的約束選項 五 &六、 ServiceManager、Zygote、SystemServer科普: Daemons - 守護進程
init進程通過解析 init.rc 來陸續啟動其他關鍵的系統服務進程,其中最重要的是 ServiceManager、Zygote 和 SystemServer 三者,下面我們逐一解析:
1、ServiceManager — Binder 機制支撐者概述:ServiceManager 是 Binder 機制中的支撐者,負責某 Binder 服務注冊信息到底層 Binder 驅動分配的值解析。
ServiceManager 由 init 進程解析 rc 腳本時啟動,屬於 core 類,其他同類進程包括:uenetd、console、adbd等。根據 core 組的特性,這些進程會同時啟動或停止。另外,ServiceManager 配置含有 critical 屬性,這意味著它是系統關鍵進程(如果進程不幸在4分鍾內異常退出超過4次,設備將重啟並進入還原模式)。當 ServiceManager 每次重啟時,其他關鍵進程:zygote、media、surfaceflinger 等也會被 restart。
2、Zygote — 「孕育」新線程與進程Android 中大多數應用進程與系統進程都是通過 Zygote 來生成的。Zygote 同樣由 init 解析 rc 腳本時啟動,屬於 main 類,同屬 main 類的系統進程有:netd、debuggerd、rild等。Zygote並不是處於獨立的程序中的,它所在程序名為「app_process」,觀察 app_process 主函數實現知道,如果 init.rc 中指定了 —zygote選項,app_process 接下來將啟動「ZygoteInit」,並傳入「start-system-server」,這樣,ZygoteInit 就會運行在虛擬機上(Dalvik VM)上了。
ZygoteInit 函數有兩項重要工作:
預裝載各種系統類; 搭建 SystemServer 環境,並啟動 SystemServer(大部分的 Android 系統服務都在其中,由 Java 編寫)。ZygoteInit 流程總結(摘自:Gityuan — Android 系統啟動-Zygote 篇):
解析init.zygote.rc中的參數,創建AppRuntime並調用AppRuntime.start()方法; 調用AndroidRuntime的startVM()方法創建虛擬機,再調用startReg()注冊JNI函數; 通過JNI方式調用ZygoteInit.main(),第一次進入Java世界; registerZygoteSocket()建立socket通道,zygote作為通信的服務端,用於響應客戶端請求; preload()預載入通用類、drawable和color資源、openGL以及共享庫以及WebView,用於提高ap啟動效率; zygote完畢大部分工作,接下來再通過startSystemServer(),fork得力幫手system_server進程,也是上層framework的運行載體; zygote功成身退,調用runSelectLoop(),隨時待命,當接收到請求創建新進程請求時立即喚醒並執行相應工作。ZygoteInit 結束後,開機Logo就出來了。 注意:這里並不包括開機動畫,而是開機前 「Android」 Logo 出現的那個畫面,開機動畫出現之前還需要進行各種載入,開機動畫是在「Android」 Logo 出現之後才播放的。
3、SystemServer — 大部分 Android 系統服務所在地SystemServer 是 Android 進入 Launcher 前的最後准備,它提供了眾多的由「Java」語言編寫的系統服務。 如果 init.rc 中為 zygote 指定啟動參數 —start-system-server,那麼 ZygotyeInit 就會調用 startSystemServer 來進入 SystemServer。
startSystemServer函數解析:
首先 ZygoteInit 通過 Zygote.forkSystemServer 來生成一個新的線程(fork),用於承載各種系統服務。(源碼角度:Zygote 內部由 Native 函數 Dalvik_dalvik_system_Zygote_forkSystemServer 來進一步實現,最終調用底層介面的 fork 介面來實際產生進程); 根據fork特性,子進程與父進程將獲得相同的代碼環境。pid為0為子進程,否則為父進程;如果是前者,則進一步調用 handleSystemServerProcess(parseArgs)函數來完成最核心的工作 —「啟動各系統服務」(源碼角度:handleSystemServerProcess 方法將 startSystemServer 中的 parsedArgs.remainingArgs 參數傳給 RuntimeInit.zygoteInit,後者又調用 nativeZygoteInit 函數); nativeZygoteInit 調用後,接著,三個重要的 static 函數就要被執行了:init1 - 完成本地Service(SurfaceFlinger、AudioFlinger等)啟動,完成後調用 init2、init2 - 新建一個新的帶 Looper 的線程 ServerThread來啟動 Java層各 Service。Ⅹ android怎麼用代碼實現kill命令
由於adb shell中的kill命令後面跟的參數是pid,因此先ps所有的應用程序:
adb在shell下:
ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 204 c008de04 0000c74c S /init
root 2 0 0 0 c004b334 00000000 S kthreadd
root 3 2 0 0 c003cf68 00000000 S ksoftirqd/0
root 4 2 0 0 c00486b8 00000000 S events/0
root 5 2 0 0 c00486b8 00000000 S khelper
root 10 2 0 0 c00486b8 00000000 S suspend
root 42 2 0 0 c00486b8 00000000 S kblockd/0
root 45 2 0 0 c00486b8 00000000 S cqueue
root 47 2 0 0 c016f13c 00000000 S kseriod
root 51 2 0 0 c00486b8 00000000 S kmmcd
root 96 2 0 0 c0065c7c 00000000 S pdflush
root 97 2 0 0 c0065c7c 00000000 S pdflush
root 98 2 0 0 c006990c 00000000 S kswapd0
root 100 2 0 0 c00486b8 00000000 S aio/0
root 268 2 0 0 c016c884 00000000 S mtdblockd
root 302 2 0 0 c0181200 00000000 S mmcqd
root 309 2 0 0 c00486b8 00000000 S rpciod/0
root 548 1 740 312 c0141bb0 afe0c1bc S /system/bin/sh
system 549 1 808 264 c01654b4 afe0c45c S /system/bin/servicemanager
root 550 1 848 392 c008e3f4 afe0c584 S /system/bin/vold
root 551 1 668 264 c0192c20 afe0cdec S /system/bin/debuggerd
radio 552 1 5392 684 ffffffff afe0cacc S /system/bin/rild
root 553 1 72432 20840 c008e3f4 afe0c584 S zygote
media 554 1 17720 3496 ffffffff afe0c45c S /system/bin/mediaserver
root 556 1 800 300 c01f3b04 afe0c1bc S /system/bin/installd
root 560 1 840 356 c00ae7b0 afe0d1dc S /system/bin/qemud
root 563 1 3332 152 ffffffff 0000e8c4 S /sbin/adbd
system 577 553 186652 24600 ffffffff afe0c45c S system_server
radio 617 553 106860 17432 ffffffff afe0d3e4 S com.android.phone
app_3 619 553 108804 19168 ffffffff afe0d3e4 S android.process.acore
app_15 643 553 95536 13220 ffffffff afe0d3e4 S com.android.mms
app_0 660 553 94292 12604 ffffffff afe0d3e4 S com.android.alarmclock
app_4 671 553 96440 13636 ffffffff afe0d3e4 S android.process.media
app_5 681 553 96556 13124 ffffffff afe0d3e4 S com.android.email
root 709 563 740 328 c003aa1c afe0d08c S /system/bin/sh
app_3 713 553 96328 12920 ffffffff afe0d3e4 S com.android.inputmethod.lat
in
app_9 720 553 94476 14524 ffffffff afe0d3e4 S com.android.music
root 726 709 884 336 00000000 afe0c1bc R ps
#
例如要關掉music
# kill 720
kill 720
# ps
ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 204 c008de04 0000c74c S /init
root 2 0 0 0 c004b334 00000000 S kthreadd
root 3 2 0 0 c003cf68 00000000 S ksoftirqd/0
root 4 2 0 0 c00486b8 00000000 S events/0
root 5 2 0 0 c00486b8 00000000 S khelper
root 10 2 0 0 c00486b8 00000000 S suspend
root 42 2 0 0 c00486b8 00000000 S kblockd/0
root 45 2 0 0 c00486b8 00000000 S cqueue
root 47 2 0 0 c016f13c 00000000 S kseriod
root 51 2 0 0 c00486b8 00000000 S kmmcd
root 96 2 0 0 c0065c7c 00000000 S pdflush
root 97 2 0 0 c0065c7c 00000000 S pdflush
root 98 2 0 0 c006990c 00000000 S kswapd0
root 100 2 0 0 c00486b8 00000000 S aio/0
root 268 2 0 0 c016c884 00000000 S mtdblockd
root 302 2 0 0 c0181200 00000000 S mmcqd
root 309 2 0 0 c00486b8 00000000 S rpciod/0
root 548 1 740 312 c0141bb0 afe0c1bc S /system/bin/sh
system 549 1 808 264 c01654b4 afe0c45c S /system/bin/servicemanager
root 550 1 848 392 c008e3f4 afe0c584 S /system/bin/vold
root 551 1 668 264 c0192c20 afe0cdec S /system/bin/debuggerd
radio 552 1 5392 684 ffffffff afe0cacc S /system/bin/rild
root 553 1 72432 20840 c008e3f4 afe0c584 S zygote
media 554 1 17720 3496 ffffffff afe0c45c S /system/bin/mediaserver
root 556 1 800 300 c01f3b04 afe0c1bc S /system/bin/installd
root 560 1 840 356 c00ae7b0 afe0d1dc S /system/bin/qemud
root 563 1 3332 152 ffffffff 0000e8c4 S /sbin/adbd
system 577 553 186648 24656 ffffffff afe0c45c S system_server
radio 617 553 106860 17528 ffffffff afe0d3e4 S com.android.phone
app_3 619 553 108804 19168 ffffffff afe0d3e4 S android.process.acore
app_15 643 553 95536 13220 ffffffff afe0d3e4 S com.android.mms
app_0 660 553 94292 12604 ffffffff afe0d3e4 S com.android.alarmclock
app_4 671 553 96440 13636 ffffffff afe0d3e4 S android.process.media
app_5 681 553 96556 13124 ffffffff afe0d3e4 S com.android.email
root 709 563 740 328 c003aa1c afe0d08c S /system/bin/sh
app_3 713 553 96328 12920 ffffffff afe0d3e4 S com.android.inputmethod.la
in
root 728 709 884 336 00000000 afe0c1bc R ps
#