亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

android servicemanager與binder源碼分析二(暫時(shí)作廢,后面會(huì)重新整理)

Ocean / 746人閱讀

摘要:抱歉,此文暫時(shí)作廢,不會(huì)使用的刪除功能。我會(huì)在后面重新整理后再繼續(xù)寫(xiě)下去。是內(nèi)部的一個(gè)機(jī)制,通過(guò)設(shè)備驅(qū)動(dòng)的協(xié)助能夠起到進(jìn)程間通訊的的作用。這個(gè)應(yīng)該是個(gè)全局表,統(tǒng)計(jì)所有結(jié)構(gòu)。實(shí)際上是保存在打開(kāi)的設(shè)備文件的結(jié)構(gòu)中。目前還未涉及到其他操作,只是。

抱歉,此文暫時(shí)作廢,不會(huì)使用segmentfault的刪除功能。我會(huì)在后面重新整理后再繼續(xù)寫(xiě)下去。

繼續(xù)上篇的文,這篇打算進(jìn)入到android的內(nèi)核世界,真正接觸到binder。
binder是android內(nèi)部的一個(gè)機(jī)制,通過(guò)設(shè)備驅(qū)動(dòng)的協(xié)助能夠起到進(jìn)程間通訊的(ipc)的作用。那么binder的設(shè)備驅(qū)動(dòng)的源碼在/drivers/staging/android/binder.c這個(gè)路徑下。
先看下定義:

3632static const struct file_operations binder_fops = {
3633    .owner = THIS_MODULE,
3634    .poll = binder_poll,
3635    .unlocked_ioctl = binder_ioctl,
3636    .compat_ioctl = binder_ioctl,
3637    .mmap = binder_mmap,
3638    .open = binder_open,
3639    .flush = binder_flush,
3640    .release = binder_release,
3641};

這里說(shuō)明了設(shè)備的各項(xiàng)操作對(duì)應(yīng)的函數(shù)。
設(shè)備驅(qū)動(dòng)是在系統(tǒng)剛開(kāi)始的時(shí)候就初始化好的,初始化的過(guò)程看binder_init,不是重點(diǎn),因此不在這里累述。這個(gè)初始化的過(guò)程如果進(jìn)入的以及怎么發(fā)展的,有機(jī)會(huì)再其他文中敘述吧。
上文的servicemanager的main函數(shù)中首先就是open設(shè)備,因此先從open開(kāi)始:

2941static int binder_open(struct inode *nodp, struct file *filp)
2942{
2943    struct binder_proc *proc;
2944
2945    binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d
",
2946             current->group_leader->pid, current->pid);
2947
2948    proc = kzalloc(sizeof(*proc), GFP_KERNEL);
2949    if (proc == NULL)
2950        return -ENOMEM;
2951    get_task_struct(current);
2952    proc->tsk = current;
2953    INIT_LIST_HEAD(&proc->todo);
2954    init_waitqueue_head(&proc->wait);
2955    proc->default_priority = task_nice(current);
2956
2957    binder_lock(__func__);
2958
2959    binder_stats_created(BINDER_STAT_PROC);
2960    hlist_add_head(&proc->proc_node, &binder_procs);
2961    proc->pid = current->group_leader->pid;
2962    INIT_LIST_HEAD(&proc->delivered_death);
2963    filp->private_data = proc;
2964
2965    binder_unlock(__func__);
2966
2967    if (binder_debugfs_dir_entry_proc) {
2968        char strbuf[11];
2969
2970        snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
2971        proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
2972            binder_debugfs_dir_entry_proc, proc, &binder_proc_fops);
2973    }
2974
2975    return 0;
2976}

1.創(chuàng)建binder_proc結(jié)構(gòu);
2.各種維護(hù)性的鏈表及結(jié)構(gòu)的添加;
3.存儲(chǔ)proc到私有數(shù)據(jù)內(nèi);

先說(shuō)下,內(nèi)核開(kāi)空間都是使用kzalloc與應(yīng)用層的malloc類似。
這里用到一個(gè)current結(jié)構(gòu),是linux的一個(gè)指針,指向當(dāng)前正在運(yùn)行的進(jìn)程結(jié)構(gòu)task_struct,這里還是先不深究,大體意思了解不影響后續(xù)即可。后面就是INIT_LIST_HEAD(&proc->todo);初始化鏈表頭,這個(gè)鏈表是怎么回事兒呢?先看下proc的結(jié)構(gòu)吧:

292struct binder_proc {
293    struct hlist_node proc_node;
294    struct rb_root threads;
295    struct rb_root nodes;
296    struct rb_root refs_by_desc;
297    struct rb_root refs_by_node;
298    int pid;
299    struct vm_area_struct *vma;
300    struct mm_struct *vma_vm_mm;
301    struct task_struct *tsk;
302    struct files_struct *files;
303    struct hlist_node deferred_work_node;
304    int deferred_work;
305    void *buffer;
306    ptrdiff_t user_buffer_offset;
307
308    struct list_head buffers;
309    struct rb_root free_buffers;
310    struct rb_root allocated_buffers;
311    size_t free_async_space;
312
313    struct page **pages;
314    size_t buffer_size;
315    uint32_t buffer_free;
316    struct list_head todo;
317    wait_queue_head_t wait;
318    struct binder_stats stats;
319    struct list_head delivered_death;
320    int max_threads;
321    int requested_threads;
322    int requested_threads_started;
323    int ready_threads;
324    long default_priority;
325    struct dentry *debugfs_entry;
326};

這個(gè)結(jié)構(gòu)的寫(xiě)法很c很linux,可以看到可能會(huì)有很多個(gè)proc結(jié)構(gòu)被貫穿成為一個(gè)鏈表統(tǒng)一管理,那么結(jié)合之前的內(nèi)容猜測(cè),binder_proc結(jié)構(gòu)可以支持多個(gè)每個(gè)對(duì)應(yīng)一個(gè)進(jìn)程,然后通過(guò)鏈表來(lái)維護(hù),那么進(jìn)一步思考,本身binder就是為了支持跨進(jìn)程通訊的,那么這些通訊之間的binder銜接就是在這個(gè)鏈表結(jié)構(gòu)中維護(hù)。
下面,init_waitqueue_head(&proc->wait);初始化linux的等待隊(duì)列。又是個(gè)宏,內(nèi)容如下:

71#define init_waitqueue_head(q)                
72    do {                        
73        static struct lock_class_key __key;    
74                            
75        __init_waitqueue_head((q), #q, &__key);    
76    } while (0)
77
78#ifdef CONFIG_LOCKDEP
79# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) 
80    ({ init_waitqueue_head(&name); name; })
81# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) 
82    wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name)
83#else
84# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
85#endif
86

帶入的參數(shù)是proc結(jié)構(gòu)中的一個(gè)成員wait,感覺(jué)這里也是個(gè)隊(duì)列(鏈表),用來(lái)維護(hù)等待處理的binder_proc結(jié)構(gòu)。那么大膽猜測(cè)下,系統(tǒng)利用這個(gè)來(lái)建立等待通訊處理的binder進(jìn)程隊(duì)列,可在這基礎(chǔ)上進(jìn)行各種策略調(diào)配來(lái)管理binder通訊的過(guò)程,不能放著驅(qū)動(dòng)自我的承載力來(lái)決定(可能帶來(lái)穩(wěn)定性隱患)。
再往后看,proc->default_priority = task_nice(current); 記錄當(dāng)前進(jìn)程的優(yōu)先級(jí)??窗?,之前的策略這里就會(huì)體現(xiàn)。
然后hlist_add_head(&proc->proc_node, &binder_procs);又一個(gè),真linux真c,不得不說(shuō):看系統(tǒng)源碼就必須習(xí)慣各種鏈表的這種方式,其實(shí)很好,不用額外維護(hù)什么東西,這種原始的方式其實(shí)有時(shí)候是最適合的,所以說(shuō),機(jī)制不是多復(fù)雜就牛逼的,而是看是否符合當(dāng)前的體系當(dāng)前的場(chǎng)景。這個(gè)應(yīng)該是個(gè)全局hash表,統(tǒng)計(jì)所有binder_proc結(jié)構(gòu)。

借用一張網(wǎng)絡(luò)上的圖說(shuō)明下proc結(jié)構(gòu):

最后保存這個(gè)proc倒private_data里,這個(gè)私有數(shù)據(jù)中。然后完了。
再回顧一下吧,每次打開(kāi)設(shè)備就創(chuàng)建一個(gè)binder_proc結(jié)構(gòu),并將當(dāng)前進(jìn)程的信息保存在這里,然后將其掛接在系統(tǒng)的各個(gè)鏈表或紅黑樹(shù)或hash表中,為了便于日后的策略和維護(hù)。之后再將這個(gè)proc結(jié)構(gòu)保留到私有數(shù)據(jù)中。實(shí)際上是保存在打開(kāi)的設(shè)備文件的結(jié)構(gòu)中。目前還未涉及到其他操作,只是binder_open。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65002.html

相關(guān)文章

  • android servicemanagerbinder源碼分析一 ------ native層的

    摘要:以版本源碼為例。源碼位于下打開(kāi)驅(qū)動(dòng)設(shè)備,將自己作為的管理者,進(jìn)入循環(huán),作為等待的請(qǐng)求位于首先,建立一個(gè)結(jié)構(gòu)體,然后剩下的就是給這個(gè)結(jié)構(gòu)體的成員賦值。同屬于這一層,因此我們看看具體內(nèi)容剛才從驅(qū)動(dòng)設(shè)備讀取的的前位取出來(lái)作為進(jìn)行判斷處理。 前一陣子在忙項(xiàng)目,沒(méi)什么更新,這次開(kāi)始寫(xiě)點(diǎn)android源碼內(nèi)部的東西分析下。以6.0.1_r10版本android源碼為例。servicemanager...

    馬忠志 評(píng)論0 收藏0
  • android servicemanagerbinder源碼分析 ------ servicem

    摘要:也同時(shí)可以看到責(zé)任鏈的應(yīng)用,一個(gè)請(qǐng)求從上到下會(huì)經(jīng)過(guò)很多層,每層都只處理和自己相關(guān)的部分,如果沒(méi)有則交由下層繼續(xù)傳遞,如果有直接返回。因此雖然看著費(fèi)勁點(diǎn),但是在此還是要對(duì)搞操作系統(tǒng)的以及研究操作系統(tǒng)的人們給予敬意。 承接上篇,serviceManager是怎么被調(diào)用的呢?如何為app提供服務(wù)支持?怎么銜接的?。這次我打算從最上層開(kāi)始逐步把脈絡(luò)屢清楚。首先,我們?cè)趯?xiě)app的時(shí)候需要使用Au...

    Anleb 評(píng)論0 收藏0
  • android servicemanagerbinder源碼分析三------如何進(jìn)入內(nèi)核通訊

    摘要:的構(gòu)造傳遞進(jìn)入的就是。如果狀態(tài)是,直接返回。到底是否正確呢看代碼先創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象是個(gè)存儲(chǔ)讀寫(xiě)內(nèi)容的對(duì)象。然后終于進(jìn)入了內(nèi)核驅(qū)動(dòng)的部分。 承接上文,從getService開(kāi)始,要開(kāi)始走binder的通訊機(jī)制了。首先是上文的java層 /frameworks/base/core/java/android/os/ServiceManagerNative.java: 118 pu...

    lijy91 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<