国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
下接 android linux 基礎知識總結[下]5
S20nfs-kernel-server
S20samba
S20xinetd
S30gdm
S98usplash
S99rc.local
總結:
這樣一來,upstart管理的ubuntu啟動過程應該就清楚了。梳理一下:
1,內核啟動init
2,init找到/etc/event.d/rc-default文件,確定默認的運行級別(X)
3,觸發(fā)相應的runlevel事件,開始運行/etc/event.d/rcX
4,rcX運行/etc/init.d/rc,傳入參數X
5,/etc/init.d/rc腳本進行一系列設置,最后運行相應的/etc/rcX.d/中的腳本
6,/etc/rcX.d/中的腳本按事先設定的優(yōu)先級依次啟動,直至最后給出登錄畫面(啟動X服務器和GDM)
理解了這些,手動配置開機服務的啟動與否就很簡單了。Ubutnu默認的啟動級別是2,不想啟動的程序,只要把相應的符號鏈接從/etc/rc2.d/中刪去即可
注意:
想redat ,federa 這些系統(tǒng),他們用的是sysvinit ,有 /etc/inittab 文件,里面定義了 :
id:5:initdefault:
si::sysinit:/etc/init.d/rcS
init 直接解析 id:5:initdefault 字段,然后執(zhí)行 /etc/rc5.d/ 下面的腳本
================
參考文檔:
linux教程:upstart 和ubuntu啟動過程原理介紹
http://www.zhiweinet.com/jiaocheng/2009-06/12500.htm
6.2 小型嵌入式系統(tǒng)啟動流程
小型嵌入式的 init 通常使用busybox中自帶的,
6.3 android 系統(tǒng)啟動流程
參考文檔:
init 是內核進入文件系統(tǒng)后第一個運行的程序,我們可以在linux的命令行中進行指定,如果沒指定,內核將會到/sbin/, /bin/ 等目錄下
查找默認的init,如果沒有找到那么就報告出錯。
init 源代碼分析
init的mian函數在文件:./system/core/init/init.c 中,init會一步步完成下面的任務:
1.初始化log系統(tǒng)
2.解析/init.rc和/init.%hardware%.rc文件 
3. 執(zhí)行 early-init action in the two files parsed in step 2. 
4. 設備初始化,例如:在 /dev 下面創(chuàng)建所有設備節(jié)點,下載 firmwares. 
5. 初始化屬性服務器,Actually the property system is working as a share memory. Logically it looks like a registry under Windows system. 
6. 執(zhí)行 init action in the two files parsed in step 2. 
7. 開啟 屬性服務。
8. 執(zhí)行 early-boot and boot actions in the two files parsed in step 2. 
9. 執(zhí)行 Execute property action in the two files parsed in step 2. 
10. 進入一個無限循環(huán) to wait for device/property set/child process exit events.例如,如果SD卡被插入,init會收到一個設備插入事件,
它會為這個設備創(chuàng)建節(jié)點。系統(tǒng)中比較重要的進程都是由init來fork的,所以如果他們他誰崩潰了,那么init 將會收到一個 SIGCHLD 信號,把這個信號轉化
為子進程退出事件, 所以在loop中,init 會操作進程退出事件并且執(zhí)行 *.rc 文件中定義的命令。
例如,在init.rc中,因為有:
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
所以,如果zygote因為啟動某些服務導致異常退出后,init將會重新去啟動它。
int main(int argc, char **argv)
{
...
//需要在后面的程序中看打印信息的話,需要屏蔽open_devnull_stdio()函數
open_devnull_stdio();
...
//初始化log系統(tǒng)
log_init();
//解析/init.rc和/init.%hardware%.rc文件
parse_config_file("/init.rc");
...
snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
parse_config_file(tmp);
...
//執(zhí)行 early-init action in the two files parsed in step 2.
action_for_each_trigger("early-init", action_add_queue_tail);
drain_action_queue();
...
/* execute all the boot actions to get us started */
/* 執(zhí)行 init action in the two files parsed in step 2 */
action_for_each_trigger("init", action_add_queue_tail);
drain_action_queue();
...
/* 執(zhí)行 early-boot and boot actions in the two files parsed in step 2 */
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
drain_action_queue();
/* run all property triggers based on current state of the properties */
queue_all_property_triggers();
drain_action_queue();
/* enable property triggers */ 
property_triggers_enabled = 1; 
...
for(;;) {
int nr, timeout = -1;
...
drain_action_queue();
restart_processes();
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout 



重要的數據結構
兩個列表,一個隊列。
static list_declare(service_list);
static list_declare(action_list);
static list_declare(action_queue);
*.rc 腳本中所有 service關鍵字定義的服務將會添加到 service_list 列表中。
*.rc 腳本中所有 on 關鍵開頭的項將會被會添加到 action_list 列表中。
每個action列表項都有一個列表,此列表用來保存該段落下的 Commands
腳本解析過程
parse_config_file("/init.rc")
int parse_config_file(const char *fn)
{
char *data;
data = read_file(fn, 0);
if (!data) return -1;
parse_config(fn, data);
DUMP();
return 0;
}
static void parse_config(const char *fn, char *s)

...
case T_NEWLINE:
if (nargs) {
int kw = lookup_keyword(args[0]);
if (kw_is(kw, SECTION)) {
state.parse_line(&state, 0, 0);
parse_new_section(&state, kw, nargs, args);
} else {
state.parse_line(&state, nargs, args);
}
nargs = 0;
}
...

parse_config會逐行對腳本進行解析,如果關鍵字類型為 SECTION ,那么將會執(zhí)行 parse_new_section()
類型為 SECTION 的關鍵字有: on 和 sevice
關鍵字類型定義在 Parser.c (system\core\init) 文件中
Parser.c (system\core\init)
#define SECTION 0x01
#define COMMAND 0x02
#define OPTION 0x04
關鍵字 屬性 
capability, OPTION, 0, 0)
class, OPTION, 0, 0)
class_start, COMMAND, 1, do_class_start)
class_stop, COMMAND, 1, do_class_stop)
console, OPTION, 0, 0)
critical, OPTION, 0, 0)
disabled, OPTION, 0, 0)
domainname, COMMAND, 1, do_domainname)
exec, COMMAND, 1, do_exec)
export, COMMAND, 2, do_export)
group, OPTION, 0, 0)
hostname, COMMAND, 1, do_hostname)
ifup, COMMAND, 1, do_ifup)
insmod, COMMAND, 1, do_insmod)
import, COMMAND, 1, do_import)
keycodes, OPTION, 0, 0)
mkdir, COMMAND, 1, do_mkdir)
mount, COMMAND, 3, do_mount)
on, SECTION, 0, 0)
oneshot, OPTION, 0, 0)
onrestart, OPTION, 0, 0)
restart, COMMAND, 1, do_restart)
service, SECTION, 0, 0)
setenv, OPTION, 2, 0)
setkey, COMMAND, 0, do_setkey)
setprop, COMMAND, 2, do_setprop)
setrlimit, COMMAND, 3, do_setrlimit)
socket, OPTION, 0, 0)
start, COMMAND, 1, do_start)
stop, COMMAND, 1, do_stop)
trigger, COMMAND, 1, do_trigger)
symlink, COMMAND, 1, do_symlink)
sysclktz, COMMAND, 1, do_sysclktz)
user, OPTION, 0, 0)
write, COMMAND, 2, do_write)
chown, COMMAND, 2, do_chown)
chmod, COMMAND, 2, do_chmod)
loglevel, COMMAND, 1, do_loglevel)
device, COMMAND, 4, do_device)
parse_new_section()中再分別對 service 或者 on 關鍵字開頭的內容進行解析。
...
case K_service:
state->context = parse_service(state, nargs, args);
if (state->context) {
state->parse_line = parse_line_service;
return;
}
break;
case K_on:
state->context = parse_action(state, nargs, args);
if (state->context) {
state->parse_line = parse_line_action;
return;
}
break;
}
...
對 on 關鍵字開頭的內容進行解析
static void *parse_action(struct parse_state *state, int nargs, char **args)
{
...
act = calloc(1, sizeof(*act));
act->name = args[1];
list_init(&act->commands);
list_add_tail(&action_list, &act->alist);
...
}
對 service 關鍵字開頭的內容進行解析
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
struct service *svc;
if (nargs name = args[1];
svc->classname = "default";
memcpy(svc->args, args + 2, sizeof(char*) * nargs);
svc->args[nargs] = 0;
svc->nargs = nargs;
svc->onrestart.name = "onrestart";
list_init(&svc->onrestart.commands);
//添加該服務到 service_list 列表
list_add_tail(&service_list, &svc->slist);
return svc;
}
服務的表現形式:
service [ ]*
...
申請一個service結構體,然后掛接到service_list鏈表上,name 為服務的名稱 pathname 為執(zhí)行的命令 argument
為命令的參數。之后的 option 用來控制這個service結構體的屬性,parse_line_service 會對 service關鍵字后的
內容進行解析并填充到 service 結構中 ,當遇到下一個service或者on關鍵字的時候此service選項解析結束。
例如:
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
服務名稱為: zygote
啟動該服務執(zhí)行的命令: /system/bin/app_process
命令的參數: -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666: 創(chuàng)建一個名為:/dev/socket/zygote 的 socket ,類型為:stream
當*.rc 文件解析完成以后:
action_list 列表項目如下:
on init
on boot
on property:ro.kernel.qemu=1
on property:persist.service.adb.enable=1
on property:persist.service.adb.enable=0
init.marvell.rc 文件
on early-init
on init
on early-boot
on boot
service_list 列表中的項有:
service console
service adbd
service servicemanager
service mountd
service debuggerd
service ril-daemon
service zygote
service media
service bootsound
service dbus
service hcid
service hfag
service hsag
service installd
service flash_recovery
設備初始化
early-init 初始化
初始化屬性服務器
在init.c 的main函數中啟動狀態(tài)服務器。
property_set_fd = start_property_service();
狀態(tài)讀取函數:
Property_service.c (system\core\init)
const char* property_get(const char *name)
Properties.c (system\core\libcutils)
int property_get(const char *key, char *value, const char *default_value)
狀態(tài)設置函數:
Property_service.c (system\core\init)
int property_set(const char *name, const char *value)
Properties.c (system\core\libcutils)
int property_set(const char *key, const char *value)
在終端模式下我們可以通過執(zhí)行命令 setprop 
setprop 工具源代碼所在文件: Setprop.c (system\core\toolbox)
Getprop.c (system\core\toolbox): property_get(argv[1], value, default_value);
Property_service.c (system\core\init)
中定義的狀態(tài)讀取和設置函數僅供init進程調用,
handle_property_set_fd(property_set_fd);
property_set() //Property_service.c (system\core\init)
property_changed(name, value) //Init.c (system\core\init)
queue_property_triggers(name, value)
drain_action_queue()
只要屬性一改變就會被觸發(fā),然后執(zhí)行相應的命令: 
例如:
在init.rc 文件中有
on property:persist.service.adb.enable=1
start adbd
on property:persist.service.adb.enable=0
stop adbd
所以如果在終端下輸入:
setprop property:persist.service.adb.enable 1或者0
那么將會開啟或者關閉adbd 程序。
執(zhí)行action_list 中的命令:
從action_list 中取出 act->name 為 early-init 的列表項,再調用 action_add_queue_tail(act)將其插入到
隊列 action_queue 尾部。drain_action_queue() 從action_list隊列中取出隊列項 ,然后執(zhí)行act->commands
列表中的所有命令。
所以從 ./system/core/init/init.c mian()函數的程序片段:
action_for_each_trigger("early-init", action_add_queue_tail);
drain_action_queue();
action_for_each_trigger("init", action_add_queue_tail);
drain_action_queue();
action_for_each_trigger("early-boot", action_add_queue_tail);
action_for_each_trigger("boot", action_add_queue_tail);
drain_action_queue();
/* run all property triggers based on current state of the properties */
queue_all_property_triggers();
drain_action_queue();
可以看出,在解析完init.rc init.marvell.rc 文件后,action 命令執(zhí)行順序為:
執(zhí)行act->name 為 early-init,act->commands列表中的所有命令
執(zhí)行act->name 為 init, act->commands列表中的所有命令
執(zhí)行act->name 為 early-boot,act->commands列表中的所有命令
執(zhí)行act->name 為 boot, act->commands列表中的所有命令
關鍵的幾個命令:
class_start default 啟動所有service 關鍵字定義的服務。
class_start 在act->name為boot的 act->commands列表中,所以當 class_start 被觸發(fā)后,實際
上調用的是函數 do_class_start()
int do_class_start(int nargs, char **args)
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android系統(tǒng)init.rc分析
Android init 啟動過程分析 - gpephone
深入淺出
Android中init.rc文件的解析
android的init過程分析
Android研究-初始化程序init和初始化配置文件init.rc
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服