九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
為Android應(yīng)用程序讀取/dev下設(shè)備而提權(quán)(二)
為Android應(yīng)用程序讀取/dev下設(shè)備而提權(quán)(二)
        
          在為Android應(yīng)用程序讀取/dev下設(shè)備而提權(quán)(一)中,簡(jiǎn)單總結(jié)了提權(quán)的兩種方法: device_initinit.rc 。在此篇文章中,我將詳細(xì)總結(jié)的是稍一不留神,就容易把人弄暈乎的init.c、device_initinit.rc 三者之間的關(guān)系,TA們到底是如何工作的。


目錄結(jié)構(gòu) 

         ls一下system/core/init/ 
devices.c、devices.h、init.c、init.h、keywords.h、parser.c、property_service.c....
        另外system/core/rootdir/init.rc ,當(dāng)然init.rc的位置可以另行指定。



init流程

         init過(guò)程的起點(diǎn)是init.c :        *注釋中的序號(hào)表示執(zhí)行順序    
  1. int main(int argc, char **argv)  
  2. {  
  3.     … …  
  4.     mkdir("/dev", 0755); //建立基本文件系統(tǒng)節(jié)點(diǎn)  
  5.     mkdir("/proc", 0755);  
  6.     mkdir("/sys", 0755);  
  7.     mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");  
  8.     mkdir("/dev/pts", 0755);  
  9.     mkdir("/dev/socket", 0755);  
  10.     mount("devpts", "/dev/pts", "devpts", 0, NULL);  
  11.     mount("proc", "/proc", "proc", 0, NULL);  
  12.     mount("sysfs", "/sys", "sysfs", 0, NULL);  
  13. … …  
  14.     INFO("reading config file\n");  
  15.     parse_config_file("/init.rc");   // 1、 調(diào)用parse_config 函數(shù)解析init.rc腳本   
  16.     //11、經(jīng)過(guò)解析,init.rc的內(nèi)容就被分為多少個(gè)段,被串在action_list鏈表中。on 開(kāi)頭的都是action類型的段,比如init段,init段用一個(gè)結(jié)構(gòu)體struct action表示,    其中name是init,所有這個(gè)段內(nèi)的命令,都被串在commands鏈表中。  
  17.     action_for_each_trigger("early-init", action_add_queue_tail);  //12、 遍歷action_list鏈表,查找name是early-init的那個(gè)action,將這個(gè)節(jié)點(diǎn)放在action_queu    e的尾部。  
  18.     drain_action_queue(); // 13、將action_queue尾部的節(jié)點(diǎn)遍歷,然后刪除。就相當(dāng)于遍歷name是early-init的action節(jié)點(diǎn)內(nèi)的commands鏈表。就是在執(zhí)行init.rc腳本中    on early-init段內(nèi)的所有命令。  
  19.     … …  
  20.     INFO("device init\n");  
  21.     device_fd = device_init();  //常見(jiàn)必要的設(shè)備節(jié)點(diǎn)  
  22.     property_init(); //init 以后的任務(wù)就是proper_service  
  23.   
  24.     action_for_each_trigger("init", action_add_queue_tail);  //14、將init 段,加入action_queue  
  25.     drain_action_queue(); // 執(zhí)行init段得命令  
  26.     … …  
  27. }  

system/core/init/parser.c:

  1. static void parse_config(const char *fn, char *s)  
  2. {  
  3.     struct parse_state state;  
  4.     char *args[MAXARGS];  
  5.     int nargs;  
  6.   
  7.     nargs = 0;  
  8.     state.filename = fn;  
  9.     state.line = 1;  
  10.     state.ptr = s;  
  11.     state.nexttoken = 0;  
  12.     state.parse_line = parse_line_no_op;  //這個(gè)函數(shù)是空的,就是什么都不做  
  13.     for (;;) {  
  14.         switch (next_token(&state)) {  // 2、 和T_TEXT狀態(tài)配合,先把把每一行的參數(shù)都放在args數(shù)組里  
  15.         case T_EOF:  
  16.             state.parse_line(&state, 0, 0); // 最后看這,到此文件解析完成,也是上一段的完成,需要寫個(gè)NULL表示末尾。  
  17.             return;  
  18.         case T_NEWLINE:  
  19.             if (nargs) {  
  20.                 int kw = lookup_keyword(args[0]);  // 3、得到新的一行,開(kāi)始解析,判斷一下拿到的第一個(gè)參數(shù)是什么關(guān)鍵字,這里面有幾種情,命令COMMAND,段SECTION,和選項(xiàng)OPTION,這個(gè)選項(xiàng)是針對(duì)服務(wù)的,開(kāi)啟,關(guān)閉等操作。  
  21.                 if (kw_is(kw, SECTION)) {   // 4、判斷得到的關(guān)鍵字是不是段,keywords.h里定義了各種能解析的關(guān)鍵字分別是什么屬性。  
  22.                     state.parse_line(&state, 0, 0); // 表示上一段解析結(jié)束,因?yàn)槭褂玫氖请p向鏈表,這樣就給鏈表最后一個(gè)元素寫NULL,表示到末尾了。  
  23.                     parse_new_section(&state, kw, nargs, args);  // 5、創(chuàng)建一個(gè)新段的鏈表,比如init段,先跳到這個(gè)函數(shù)看,然后再回來(lái)。  
  24.                 } else {  
  25.                     state.parse_line(&state, nargs, args); //10、 得到新的一行,通過(guò)上面的操作已經(jīng)知道現(xiàn)在是在什么段中,是on 還是service,行解析函數(shù)也做了相應(yīng)變化,開(kāi)始解析這一行,加入action的commands鏈表中。  
  26.                 }  
  27.                 nargs = 0;  
  28.             }  
  29.             break;  
  30.         case T_TEXT:  
  31.             if (nargs < MAXARGS) {  
  32.                 args[nargs++] = state.text;  
  33.             }  
  34.             break;  
  35.         }  
  36.     }  
  37. }  
  38.   
  39.   
  40. void parse_new_section(struct parse_state *state, int kw,  
  41.                        int nargs, char **args)  
  42. {  
  43.     printf("[ %s %s ]\n", args[0],  
  44.            nargs > 1 ? args[1] : "");  
  45.     switch(kw) {  // 6、這里判斷 是什么類型的段,不同類型的段使用的解析函數(shù)不同,說(shuō)白了就是分命令還是服務(wù)。  
  46.     case K_service:  
  47.         state->context = parse_service(state, nargs, args);  
  48.         if (state->context) {  
  49.             state->parse_line = parse_line_service;  
  50.             return;  
  51.         }  
  52.         break;  
  53.     case K_on:  
  54.         state->context = parse_action(state, nargs, args); // 7、創(chuàng)建一個(gè)action 鏈表,把這個(gè)鏈表加入到action_list中  
  55.         if (state->context) {  
  56.             state->parse_line = parse_line_action; // 8、把行解析函數(shù)換掉,原來(lái)是parse_no_op 什么都不做,再在要把每行都解析成一個(gè)命令動(dòng)作。把這個(gè)命令動(dòng)作加入到action中的commands鏈表內(nèi)  
  57.             return;  
  58.         }  
  59.         break;  
  60.     }  
  61.     state->parse_line = parse_line_no_op; // 9、走到這就是出錯(cuò)了,段的名字沒(méi)寫或者寫多了  
  62. }  


本章小結(jié)


        經(jīng)過(guò)上面的分析,對(duì)/dev/設(shè)備權(quán)限的修改放在不同的位置會(huì)有覆蓋的效果,device.c內(nèi)的修改會(huì)覆蓋early-init段內(nèi)的命令,init 段內(nèi)的命令會(huì)覆蓋device.c中的修改,如果3個(gè)位置都有對(duì)用一個(gè)設(shè)備權(quán)限的修改,那init段的修改會(huì)最終生效。




本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android系統(tǒng)init.rc分析
下接 android linux 基礎(chǔ)知識(shí)總結(jié)[下]5
Android init 啟動(dòng)過(guò)程分析 - gpephone
Android中init.rc文件的解析
Android培訓(xùn)班(16) -- android/linux-啟動(dòng)分析
Linux From Scratch (簡(jiǎn)體中文版)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服