Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Àí½â Android Binder »úÖÆ£¨Ò»£©£ºÇý¶¯Æª
 
À´Ô´ÓÚ£ºqiangbo.space ·¢²¼ÓÚ£º 2017-4-12
  3042  次浏览      27
 

BinderµÄʵÏÖÊDZȽϸ´Ôӵģ¬ÏëÒªÍêȫŪÃ÷°×ÊÇÔõôһ»ØÊ£¬²¢²»ÊÇÒ»¼þÈÝÒ×µÄÊÂÇé¡£

ÕâÀïÃæÇ£Éæµ½ºÃ¼¸¸ö²ã´Î£¬Ã¿Ò»²ã¶¼ÓÐһЩģ¿éºÍ»úÖÆÐèÒªÀí½â¡£Õⲿ·ÖÄÚÈÝÔ¤¼Æ»á·ÖΪÈýƪÎÄÕÂÀ´½²½â¡£±¾ÎÄÊǵÚһƪ£¬Ê×ÏÈ»á¶ÔÕû¸öBinder»úÖÆ×öÒ»¸ö¼Ü¹¹ÐԵĽ²½â£¬È»ºó»á½«´ó²¿·Ö¾«Á¦ÓÃÀ´½²½âBinder»úÖÆÖÐ×îºËÐĵIJ¿·Ö£ºBinderÇý¶¯µÄʵÏÖ¡£

Binder»úÖÆ¼ò½é

BinderÔ´×ÔBe Inc¹«Ë¾¿ª·¢µÄOpenBinder¿ò¼Ü£¬ºóÀ´¸Ã¿ò¼Ü×ªÒÆµÄPalm Inc£¬ÓÉDianne HackbornÖ÷µ¼¿ª·¢¡£OpenBinderµÄÄں˲¿·ÖÒѾ­ºÏÈëLinux Kernel 3.19¡£

Android BinderÊÇÔÚOpneBinderÉϵĶ¨ÖÆÊµÏÖ¡£Ô­ÏȵÄOpenBinder¿ò¼ÜÏÖÔÚÒѾ­²»ÔÙ¼ÌÐø¿ª·¢£¬¿ÉÒÔ˵AndroidÉϵÄBinderÈÃÔ­ÏȵÄOpneBinderµÃµ½ÁËÖØÉú¡£

BinderÊÇAndroidϵͳÖдóÁ¿Ê¹ÓõÄIPC£¨Inter-process communication£¬½ø³Ì¼äͨѶ£©»úÖÆ¡£ÎÞÂÛÊÇÓ¦ÓóÌÐò¶Ôϵͳ·þÎñµÄÇëÇ󣬻¹ÊÇÓ¦ÓóÌÐò×ÔÉíÌṩ¶ÔÍâ·þÎñ£¬¶¼ÐèҪʹÓõ½Binder¡£

Òò´Ë£¬Binder»úÖÆÔÚAndroidϵͳÖеĵØÎ»·Ç³£ÖØÒª£¬¿ÉÒÔ˵£¬Àí½âBinderÊÇÀí½âAndroidϵͳµÄ¾ø¶Ô±ØÒªÇ°Ìá¡£

ÔÚUnix/Linux»·¾³Ï£¬´«Í³µÄIPC»úÖÆ°üÀ¨£º

1.¹ÜµÀ

2.ÏûÏ¢¶ÓÁÐ

3.¹²ÏíÄÚ´æ

4.ÐźÅÁ¿

5.Socket

ÓÉÓÚÆª·ùËùÏÞ£¬±¾ÎIJ»»á¶ÔÕâЩIPC»úÖÆ×ö½²½â£¬ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ²ÎÔÄ¡¶UNIXÍøÂç±à³Ì ¾í2£º½ø³Ì¼äͨÐÅ¡·¡£

AndroidϵͳÖжÔÓÚ´«Í³µÄIPCʹÓýÏÉÙ£¨µ«Ò²ÓÐʹÓã¬ÀýÈ磺ÔÚÇëÇóZygote fork½ø³ÌµÄʱºòʹÓõÄÊÇSocket IPC£©£¬´ó²¿·Ö³¡¾°ÏÂʹÓõÄIPC¶¼ÊÇBinder¡£

BinderÏà½ÏÓÚ´«Í³IPCÀ´Ëµ¸üÊʺÏÓÚAndroidϵͳ£¬¾ßÌåÔ­ÒòµÄ°üÀ¨ÈçÏÂÈýµã£º

1.Binder±¾ÉíÊÇC/S¼Ü¹¹µÄ£¬ÕâÒ»µã¸ü·ûºÏAndroidϵͳµÄ¼Ü¹¹

2.ÐÔÄÜÉϸüÓÐÓÅÊÆ£º¹ÜµÀ£¬ÏûÏ¢¶ÓÁУ¬SocketµÄͨѶ¶¼ÐèÒªÁ½´ÎÊý¾Ý¿½±´£¬¶øBinderÖ»ÐèÒªÒ»´Î¡£ÒªÖªµÀ£¬¶ÔÓÚϵͳµ×²ãµÄIPCÐÎʽ£¬ÉÙÒ»´ÎÊý¾Ý¿½±´£¬¶ÔÕûÌåÐÔÄܵÄÓ°ÏìÊǷdz£Ö®´óµÄ

3.°²È«ÐÔ¸üºÃ£º´«Í³IPCÐÎʽ£¬ÎÞ·¨µÃµ½¶Ô·½µÄÉí·Ý±êʶ£¨UID/GID)£¬¶øÔÚʹÓÃBinder IPCʱ£¬ÕâЩÉí·Ý±êʾÊǸúËæµ÷Óùý³Ì¶ø×Ô¶¯´«µÝµÄ¡£Server¶ËºÜÈÝÒ׾ͿÉÒÔÖªµÀClient¶ËµÄÉí·Ý£¬·Ç³£±ãÓÚ×ö°²È«¼ì²é

ÕûÌå¼Ü¹¹

BinderÕûÌå¼Ü¹¹ÈçÏÂËùʾ£º

´ÓͼÖпÉÒÔ¿´³ö£¬BinderµÄʵÏÖ·ÖΪÕâô¼¸²ã£º

1.Framework²ã

2.Java²¿·Ö

3.JNI²¿·Ö

4.C++²¿·Ö

5.Çý¶¯²ã

Çý¶¯²ãλÓÚLinuxÄÚºËÖУ¬ËüÌṩÁË×îµ×²ãµÄÊý¾Ý´«µÝ£¬¶ÔÏó±êʶ£¬Ï̹߳ÜÀí£¬µ÷Óùý³Ì¿ØÖƵȹ¦ÄÜ¡£Çý¶¯²ãÊÇÕû¸öBinder»úÖÆµÄºËÐÄ¡£

Framework²ãÒÔÇý¶¯²ãΪ»ù´¡£¬ÌṩÁËÓ¦Óÿª·¢µÄ»ù´¡ÉèÊ©¡£

Framework²ã¼È°üº¬ÁËC++²¿·ÖµÄʵÏÖ£¬Ò²°üº¬ÁËJava²¿·ÖµÄʵÏÖ¡£ÎªÁËÄܽ«C++µÄʵÏÖ¸´Óõ½Java¶Ë£¬Öмäͨ¹ýJNI½øÐÐÏνӡ£

¿ª·¢Õß¿ÉÒÔÔÚFrameworkÖ®ÉÏÀûÓÃBinderÌṩµÄ»úÖÆÀ´½øÐоßÌåµÄÒµÎñÂß¼­¿ª·¢¡£Æäʵ²»½ö½öÊǵÚÈý·½¿ª·¢Õߣ¬AndroidϵͳÖб¾ÉíÒ²°üº¬Á˺ܶàϵͳ·þÎñ¶¼ÊÇ»ùÓÚBinder¿ò¼Ü¿ª·¢µÄ¡£

¼ÈÈ»ÊÇ¡°½ø³Ì¼ä¡±Í¨Ñ¶¾ÍÖÁÉÙÇ£Éæµ½Á½¸ö½ø³Ì£¬Binder¿ò¼ÜÊǵäÐ͵ÄC/S¼Ü¹¹¡£ÔÚÏÂÎÄÖУ¬ÎÒÃǰѷþÎñµÄÇëÇó·½³ÆÖ®ÎªClient£¬·þÎñµÄʵÏÖ·½³ÆÖ®ÎªServer¡£

Client¶ÔÓÚServerµÄÇëÇó»á¾­ÓÉBinder¿ò¼ÜÓÉÉÏÖÁÏ´«µÝµ½Äں˵ÄBinderÇý¶¯ÖУ¬ÇëÇóÖаüº¬ÁËClient½«Òªµ÷ÓõÄÃüÁîºÍ²ÎÊý¡£ÇëÇóµ½ÁËBinderÇý¶¯Ö®ºó£¬ÔÚÈ·¶¨ÁË·þÎñµÄÌṩ·½Ö®ºó£¬»áÔÙ´ÓÏÂÖÁÉϽ«ÇëÇ󴫵ݸø¾ßÌåµÄ·þÎñ¡£Õû¸öµ÷Óùý³ÌÈçÏÂͼËùʾ£º

¶ÔÍøÂçЭÒéÓÐËùÁ˽âµÄ¶ÁÕ߻ᷢÏÖ£¬Õâ¸öÊý¾ÝµÄ´«µÝ¹ý³ÌºÍÍøÂçЭÒéÊÇÈç´ËµÄÏàËÆ¡£

³õʶServiceManager

Ç°ÃæÒѾ­Ìáµ½£¬Ê¹ÓÃBinder¿ò¼ÜµÄ¼È°üÀ¨ÏµÍ³·þÎñ£¬Ò²°üÀ¨µÚÈý·½Ó¦Óá£Òò´Ë£¬ÔÚͬһʱ¿Ì£¬ÏµÍ³ÖлáÓдóÁ¿µÄServerͬʱ´æÔÚ¡£ÄÇô£¬ClientÔÚÇëÇóServerµÄʱºò£¬ÊÇÈç¹ûÈ·¶¨ÇëÇó·¢Ë͸øÄÄÒ»¸öServerµÄÄØ£¿

Õâ¸öÎÊÌ⣬¾ÍºÍÎÒÃÇÏÖʵÉú»îÖÐÈçºÎÕÒµ½Ò»¸ö¹«Ë¾/É̳¡£¬ÈçºÎÈ·¶¨Ò»¸öÈË/Ò»Á¾³µÒ»Ñù£¬½â¾öµÄ·½·¨¾ÍÊÇ£ºÃ¿¸öÄ¿±ê¶ÔÏó¶¼ÐèÒªÒ»¸öΨһµÄ±êʶ¡£²¢ÇÒ£¬ÐèÒªÓÐÒ»¸ö×éÖ¯À´¹ÜÀíÕâ¸öΨһµÄ±êʶ¡£

¶øBinder¿ò¼ÜÖиºÔð¹ÜÀíÕâ¸ö±êʶµÄ¾ÍÊÇServiceManager¡£ServiceManager¶ÔÓÚBinder ServerµÄ¹ÜÀí¾ÍºÃ±È³µ¹ÜËù¶ÔÓÚ³µÅƺÅÂëµÄµÄ¹ÜÀí£¬ÅɳöËù¶ÔÓÚÉí·ÝÖ¤ºÅÂëµÄ¹ÜÀí£ºÃ¿¸ö¹«¿ª¶ÔÍâÌṩ·þÎñµÄServer¶¼ÐèҪע²áµ½ServiceManagerÖУ¨Í¨¹ýaddService£©£¬×¢²áµÄʱºòÐèÒªÖ¸¶¨Ò»¸öΨһµÄid£¨Õâ¸öidÆäʵ¾ÍÊÇÒ»¸ö×Ö·û´®£©¡£

ClientÒª¶ÔServer·¢³öÇëÇ󣬾ͱØÐëÖªµÀ·þÎñ¶ËµÄid¡£ClientÐèÒªÏȸù¾ÝServerµÄidͨ¹ýServerManagerÄõ½ServerµÄ±êʾ£¨Í¨¹ýgetService£©£¬È»ºóͨ¹ýÕâ¸ö±êʾÓëServer½øÐÐͨÐÅ¡£

Õû¸ö¹ý³ÌÈçÏÂͼËùʾ£º

Èç¹ûÉÏÃæÕâЩ½éÉÜÒѾ­ÈÃÄãһͷÎíË®£¬Çë²»Òª¹ý·Öµ£ÐÄ£¬ÏÂÃæ»áÏêϸ½²½âÕâÆäÖеÄϸ½Ú¡£

ÏÂÎÄ»áÒÔ×Ô϶øÉϵķ½Ê½À´½²½âBinder¿ò¼Ü¡£×Ô϶øÉÏδ±ØÊÇ×îºÃµÄ·½·¨£¬Ã¿¸öÈ˵Ä˼¿¼·½Ê½²»Ò»Ñù£¬Èç¹ûÄã¸üϲ»¶×ÔÉ϶øÏµÄÀí½â£¬ÄãÒ²°´ÕâÑùµÄ˳ÐòÀ´ÔĶÁ¡£

¶ÔÓڴ󲿷ÖÈËÀ´Ëµ£¬ÎÒÃÇ¿ÉÄÜÐèÒª·´¸´µÄ²éÔIJÅÄÜÍêÈ«Àí½â¡£

Çý¶¯²ã

Ô´Âë·¾¶£¨Õⲿ·Ö´úÂë²»ÔÚAOSPÖУ¬¶øÊÇλÓÚLinuxÄں˴úÂëÖУ©£º

/kernel/drivers/android/binder.c

/kernel/include/uapi/linux/android/binder.h

»òÕß

/kernel/drivers/staging/android/binder.c

/kernel/drivers/staging/android/uapi/binder.h

Binder»úÖÆµÄʵÏÖÖУ¬×îºËÐĵľÍÊÇBinderÇý¶¯¡£ BinderÊÇÒ»¸ömiscellaneousÀàÐ͵ÄÇý¶¯£¬±¾Éí²»¶ÔÓ¦ÈκÎÓ²¼þ£¬ËùÓеIJÙ×÷¶¼ÔÚÈí¼þ²ã¡£ binder_initº¯Êý¸ºÔðBinderÇý¶¯µÄ³õʼ»¯¹¤×÷£¬¸Ãº¯ÊýÖд󲿷ִúÂëÊÇÔÚͨ¹ýdebugfs_create_dirºÍdebugfs_create_fileº¯Êý´´½¨debugfs¶ÔÓ¦µÄÎļþ¡£ Èç¹ûÄÚºËÔÚ±àÒëʱ´ò¿ªÁËdebugfs£¬Ôòͨ¹ýadb shellÁ¬ÉÏÉ豸֮ºó£¬¿ÉÒÔÔÚÉ豸µÄÕâ¸ö·¾¶ÕÒµ½debugfs¶ÔÓ¦µÄÎļþ£º/sys/kernel/debug¡£BinderÇý¶¯Öд´½¨µÄdebugÎļþÈçÏÂËùʾ£º

# ls -l /sys/kernel/debug/binder/

total 0

-r--r--r-- 1 root root 0 1970-01-01 00:00 failed_transaction_log

drwxr-xr-x 2 root root 0 1970-05-09 01:19 proc

-r--r--r-- 1 root root 0 1970-01-01 00:00 state

-r--r--r-- 1 root root 0 1970-01-01 00:00 stats

-r--r--r-- 1 root root 0 1970-01-01 00:00 transaction_log

-r--r--r-- 1 root root 0 1970-01-01 00:00 transactions

ÕâЩÎļþÆäʵ¶¼ÔÚÄÚ´æÖеģ¬ÊµÊ±µÄ·´Ó¦Á˵±Ç°BinderµÄʹÓÃÇé¿ö£¬ÔÚʵ¼ÊµÄ¿ª·¢¹ý³ÌÖУ¬ÕâЩÐÅÏ¢¿ÉÒÔ°ïæ·ÖÎöÎÊÌâ¡£ÀýÈ磬¿ÉÒÔͨ¹ý²é¿´/sys/kernel/debug/binder/procĿ¼À´È·¶¨ÄÄЩ½ø³ÌÕýÔÚʹÓÃBinder£¬Í¨¹ý²é¿´transaction_logºÍtransactionsÎļþÀ´È·¶¨BinderͨÐŵÄÊý¾Ý¡£

binder_initº¯ÊýÖÐ×îÖ÷ÒªµÄ¹¤×÷ÆäʵÏÂÃæÕâÐУº

static struct miscdevice binder_miscdev = {

.minor = MISC_DYNAMIC_MINOR,

.name = "binder",

.fops = &binder_fops

};

¸ÃÐдúÂëÕæÕýÏòÄÚºËÖÐ×¢²áÁËBinderÉ豸¡£binder_miscdevµÄ¶¨ÒåÈçÏ£º

static const struct file_operations binder_fops = {

.owner = THIS_MODULE,

.poll = binder_poll,

.unlocked_ioctl = binder_ioctl,

.compat_ioctl = binder_ioctl,

.mmap = binder_mmap,

.open = binder_open,

.flush = binder_flush,

.release = binder_release,

};

ÕâÀïÖ¸¶¨ÁËBinderÉ豸µÄÃû³ÆÊÇ¡°binder¡±¡£ÕâÑù£¬ÔÚÓû§¿Õ¼ä±ã¿ÉÒÔͨ¹ý¶Ô/dev/binderÎļþ½øÐвÙ×÷À´Ê¹ÓÃBinder¡£

binder_miscdevͬʱҲָ¶¨Á˸ÃÉ豸µÄfops¡£fopsÊÇÁíÍâÒ»¸ö½á¹¹Ì壬Õâ¸ö½á¹¹Öаüº¬ÁËһϵÁеĺ¯ÊýÖ¸Õ룬Æä¶¨ÒåÈçÏ£º

static int binder_open(struct inode *nodp, struct file *filp)

{

struct binder_proc *proc;

// ´´½¨½ø³Ì¶ÔÓ¦µÄbinder_proc¶ÔÏó

proc = kzalloc(sizeof(*proc), GFP_KERNEL);

if (proc == NULL)

return -ENOMEM;

get_task_struct(current);

proc->tsk = current;

// ³õʼ»¯binder_proc

INIT_LIST_HEAD(&proc->todo);

init_waitqueue_head(&proc->wait);

proc->default_priority = task_nice(current);

// Ëø±£»¤

binder_lock(__func__);

binder_stats_created(BINDER_STAT_PROC);

// Ìí¼Óµ½È«¾ÖÁбíbinder_procsÖÐ

hlist_add_head(&proc->proc_node, &binder_procs);

proc->pid = current->group_leader->pid;

INIT_LIST_HEAD(&proc->delivered_death);

filp->private_data = proc;

binder_unlock(__func__);

return 0;

}

ÕâÀï³ýÁËownerÖ®Í⣬ÿһ¸ö×ֶζ¼ÊÇÒ»¸öº¯ÊýÖ¸Õ룬ÕâЩº¯ÊýÖ¸Õë¶ÔÓ¦ÁËÓû§¿Õ¼äÔÚʹÓÃBinderÉ豸ʱµÄ²Ù×÷¡£ÀýÈ磺binder_poll¶ÔÓ¦ÁËpollϵͳµ÷ÓõĴ¦Àí£¬binder_mmap¶ÔÓ¦ÁËmmapϵͳµ÷ÓõĴ¦Àí£¬ÆäËûÀàͬ¡£

ÕâÆäÖУ¬ÓÐÈý¸öº¯ÊýÓÈÎªÖØÒª£¬ËüÃÇÊÇ£ºbinder_open£¬binder_mmapºÍbinder_ioctl¡£ ÕâÊÇÒòΪ£¬ÐèҪʹÓÃBinderµÄ½ø³Ì£¬¼¸ºõ×ÜÊÇÏÈͨ¹ýbinder_open´ò¿ªBinderÉ豸£¬È»ºóͨ¹ýbinder_mmap½øÐÐÄÚ´æÓ³Éä¡£

ÔÚÕâÖ®ºó£¬Í¨¹ýbinder_ioctlÀ´½øÐÐʵ¼ÊµÄ²Ù×÷¡£Client¶ÔÓÚServer¶ËµÄÇëÇó£¬ÒÔ¼°Server¶ÔÓÚClientÇëÇó½á¹ûµÄ·µ»Ø£¬¶¼ÊÇͨ¹ýioctlÍê³ÉµÄ¡£

ÕâÀïÌáµ½µÄÁ÷³ÌÈçÏÂͼËùʾ£º

Ö÷Òª½á¹¹

BinderÇý¶¯Öаüº¬Á˺ܶàµÄ½á¹¹Ì塣ΪÁ˱ãÓÚÏÂÎĽ²½â£¬ÕâÀïÎÒÃÇÏȶÔÕâЩ½á¹¹Ìå×öһЩ½éÉÜ¡£

Çý¶¯ÖеĽṹÌå¿ÉÒÔ·ÖΪÁ½Àࣺ

Ò»ÀàÊÇÓëÓû§¿Õ¼ä¹²Óõģ¬ÕâЩ½á¹¹ÌåÔÚBinderͨÐÅЭÒé¹ý³ÌÖлáÓõ½¡£Òò´Ë£¬ÕâЩ½á¹¹Ì嶨ÒåÔÚbinder.hÖУ¬°üÀ¨£º

 

ÕâÆäÖУ¬binder_write_readºÍbinder_transaction_dataÕâÁ½¸ö½á¹¹Ìå×îÎªÖØÒª£¬ËüÃÇ´æ´¢ÁËIPCµ÷Óùý³ÌÖеÄÊý¾Ý¡£¹ØÓÚÕâÒ»µã£¬ÎÒÃÇÔÚÏÂÎÄÖлὲ½â¡£

BinderÇý¶¯ÖУ¬»¹ÓÐÒ»Àà½á¹¹ÌåÊǽö½öBinderÇý¶¯ÄÚ²¿ÊµÏÖ¹ý³ÌÖÐÐèÒªµÄ£¬ËüÃǶ¨ÒåÔÚbinder.cÖУ¬°üÀ¨£º

ÕâÀïÐèÒª¶ÁÕß¹Ø×¢µÄ½á¹¹ÌåÒѾ­ÓüӴÖ×öÁ˱ê×¢¡£

BinderЭÒé

BinderЭÒé¿ÉÒÔ·ÖΪ¿ØÖÆÐ­ÒéºÍÇý¶¯Ð­ÒéÁ½Àà¡£

¿ØÖÆÐ­ÒéÊǽø³Ìͨ¹ýioctl(¡°/dev/binder¡±) ÓëBinderÉ豸½øÐÐͨѶµÄЭÒ飬¸ÃЭÒé°üº¬ÒÔϼ¸ÖÖÃüÁ

BinderµÄÇý¶¯Ð­ÒéÃèÊöÁ˶ÔÓÚBinderÇý¶¯µÄ¾ßÌåʹÓùý³Ì¡£Çý¶¯Ð­ÒéÓÖ¿ÉÒÔ·ÖΪÁ½Àࣺ

Ò»ÀàÊÇbinder_driver_command_protocol£¬ÃèÊöÁ˽ø³Ì·¢Ë͸øBinderÇý¶¯µÄÃüÁî

Ò»ÀàÊÇbinder_driver_return_protocol£¬ÃèÊöÁËBinderÇý¶¯·¢Ë͸ø½ø³ÌµÄÃüÁî

binder_driver_command_protocol¹²°üº¬17¸öÃüÁ·Ö±ðÊÇ£º

binder_driver_return_protocol¹²°üº¬18¸öÃüÁ·Ö±ðÊÇ£º

µ¥¶À¿´ÉÏÃæµÄЭÒé¿ÉÄܺÜÄÑÀí½â£¬ÕâÀïÎÒÃÇÒÔÒ»´ÎBinderÇëÇó¹ý³ÌÀ´Ïêϸ¿´Ò»ÏÂBinderЭÒéÊÇÈçºÎͨÐŵģ¬¾Í±È½ÏºÃÀí½âÁË¡£

Õâ·ùͼµÄ˵Ã÷ÈçÏ£º

 

BinderÊÇC/S¼Ü¹¹µÄ£¬Í¨ÐŹý³ÌÇ£Éæµ½£ºClient£¬ServerÒÔ¼°BinderÇý¶¯Èý¸ö½ÇÉ«

Client¶ÔÓÚServerµÄÇëÇóÒÔ¼°Server¶ÔÓÚClient»Ø¸´¶¼ÐèҪͨ¹ýBinderÇý¶¯À´ÖÐתÊý¾Ý

BC_XXXÃüÁîÊǽø³Ì·¢Ë͸øÇý¶¯µÄÃüÁî

BR_XXXÃüÁîÊÇÇý¶¯·¢Ë͸ø½ø³ÌµÄÃüÁî

Õû¸öͨÐŹý³ÌÓÉBinderÇý¶¯¿ØÖÆ

ÕâÀïÔÙ²¹³ä˵Ã÷һϣ¬Í¨¹ýÉÏÃæµÄBinderЭÒéµÄ˵Ã÷ÖÐÎÒÃÇ¿´µ½£¬BinderЭÒéµÄͨÐŹý³ÌÖУ¬²»½ö½öÊÇ·¢ËÍÇëÇóºÍ½ÓÊÜÊý¾ÝÕâЩÃüÁͬʱ°üÀ¨Á˶ÔÓÚÒýÓüÆÊýµÄ¹ÜÀíºÍ¶ÔÓÚËÀÍö֪ͨµÄ¹ÜÀí£¨¸æÖªÒ»·½£¬Í¨Ñ¶µÄÁíÍâÒ»·½ÒѾ­ËÀÍö£©µÈ¹¦ÄÜ¡£

ÕâЩ¹¦ÄܵÄͨÐŹý³ÌºÍÉÏÃæÕâ·ùͼÊÇÀàËÆµÄ£ºÒ»·½·¢ËÍBC_XXX£¬È»ºóÓÉÇý¶¯¿ØÖÆÍ¨ÐŹý³Ì£¬½Ó×Å·¢ËͶÔÓ¦µÄBR_XXXÃüÁî¸øÍ¨ÐŵÄÁíÍâÒ»·½¡£ÒòΪÕâÖÖÏàËÆÐÔ£¬¶ÔÓÚÕâЩÄÚÈݾͲ»ÔÙ׸ÊöÁË¡£

ÔÚÓÐÁËÉÏÃæÕâЩ±³¾°ÖªÊ¶½éÉÜÖ®ºó£¬ÎÒÃǾͿÉÒÔ½øÈëµ½BinderÇý¶¯µÄÄÚ²¿ÊµÏÖÖÐÀ´Ò»Ì½¾¿¾¹ÁË¡£

PS£ºÉÏÃæ½éÉܵÄÕâЩ½á¹¹ÌåºÍЭÒ飬ÒòΪÄÚÈݽ϶࣬³õ´Î¿´Íê¼Ç²»×¡ÊǺÜÕý³£µÄ£¬ÔÚÏÂÎÄÏêϸ½²½âµÄʱºò£¬»Ø¹ýÍ·À´¶ÔÕÕÕâЩ±í¸ñÀ´Àí½âÊDZȽÏÓаïÖúµÄ¡£

´ò¿ªBinderÉ豸

Èκνø³ÌÔÚʹÓÃBinder֮ǰ£¬¶¼ÐèÒªÏÈͨ¹ýopen("/dev/binder")´ò¿ªBinderÉ豸¡£ÉÏÎÄÒѾ­Ìáµ½£¬Óû§¿Õ¼äµÄopenϵͳµ÷ÓöÔÓ¦ÁËÇý¶¯ÖеÄbinder_openº¯Êý¡£ÔÚÕâ¸öº¯Êý£¬BinderÇý¶¯»áΪµ÷ÓõĽø³Ì×öһЩ³õʼ»¯¹¤×÷¡£binder_openº¯Êý´úÂëÈçÏÂËùʾ£º

static int binder_open(struct inode *nodp, struct file *filp)

{

struct binder_proc *proc;

// ´´½¨½ø³Ì¶ÔÓ¦µÄbinder_proc¶ÔÏó

proc = kzalloc(sizeof(*proc), GFP_KERNEL);

if (proc == NULL)

return -ENOMEM;

get_task_struct(current);

proc->tsk = current;

// ³õʼ»¯binder_proc

INIT_LIST_HEAD(&proc->todo);

init_waitqueue_head(&proc->wait);

proc->default_priority = task_nice(current);

// Ëø±£»¤

binder_lock(__func__);

binder_stats_created(BINDER_STAT_PROC);

// Ìí¼Óµ½È«¾ÖÁбíbinder_procsÖÐ

hlist_add_head(&proc->proc_node, &binder_procs);

proc->pid = current->group_leader->pid;

INIT_LIST_HEAD(&proc->delivered_death);

filp->private_data = proc;

binder_unlock(__func__);

return 0;

}

ÔÚBinderÇý¶¯ÖУ¬Í¨¹ýbinder_procs¼Ç¼ÁËËùÓÐʹÓÃBinderµÄ½ø³Ì¡£Ã¿¸ö³õ´Î´ò¿ªBinderÉ豸µÄ½ø³Ì¶¼»á±»Ìí¼Óµ½Õâ¸öÁбíÖеġ£

ÁíÍ⣬Çë¶ÁÕ߻عËÒ»ÏÂÉÏÎĽéÉܵÄBinderÇý¶¯Öеö¹Ø¼ü½á¹¹Ì壺

1.binder_proc

2.binder_node

3.binder_thread

4.binder_ref

5.binder_buffer

ÔÚʵÏÖ¹ý³ÌÖУ¬ÎªÁ˱ãÓÚ²éÕÒ£¬ÕâЩ½á¹¹Ì廥ÏàÖ®¼ä¶¼ÁôÓÐ×ֶδ洢¹ØÁªµÄ½á¹¹¡£

ÏÂÃæÕâ·ùͼÃèÊöÁËÕâÀï˵µ½µÄÕâЩÄÚÈÝ£º

ÄÚ´æÓ³É䣨mmap£©

ÔÚ´ò¿ªBinderÉ豸֮ºó£¬½ø³Ì»¹»áͨ¹ýmmap½øÐÐÄÚ´æÓ³Éä¡£mmapµÄ×÷ÓÃÓÐÈçÏÂÁ½¸ö£º

ÉêÇëÒ»¿éÄÚ´æ¿Õ¼ä£¬ÓÃÀ´½ÓÊÕBinderͨÐŹý³ÌÖеÄÊý¾Ý

¶ÔÕâ¿éÄÚ´æ½øÐеØÖ·Ó³É䣬ÒԱ㽫À´·ÃÎÊ

binder_mmapº¯Êý¶ÔÓ¦ÁËmmapϵͳµ÷ÓõĴ¦Àí£¬Õâ¸öº¯ÊýÒ²ÊÇBinderÇý¶¯µÄ¾«»ªËùÔÚ£¨ÕâÀï˵µÄbinder_mmapº¯ÊýÒ²°üÀ¨ÆäÄÚ²¿µ÷ÓõÄbinder_update_page_rangeº¯Êý£¬¼ûÏÂÎÄ£©¡£

ǰÎÄÎÒÃÇ˵µ½£¬Ê¹ÓÃBinder»úÖÆ£¬Êý¾ÝÖ»ÐèÒª¾­ÀúÒ»´Î¿½±´¾Í¿ÉÒÔÁË£¬ÆäÔ­Àí¾ÍÔÚÕâ¸öº¯ÊýÖС£

binder_mmapÕâ¸öº¯ÊýÖУ¬»áÉêÇëÒ»¿éÎïÀíÄڴ棬ȻºóÔÚÓû§¿Õ¼äºÍÄں˿ռäͬʱ¶ÔÓ¦µ½Õâ¿éÄÚ´æÉÏ¡£ÔÚÕâÖ®ºó£¬µ±ÓÐClientÒª·¢ËÍÊý¾Ý¸øServerµÄʱºò£¬Ö»ÐèÒ»´Î£¬½«Client·¢Ë͹ýÀ´µÄÊý¾Ý¿½±´µ½Server¶ËµÄÄں˿ռäÖ¸¶¨µÄÄÚ´æµØÖ·¼´¿É£¬ÓÉÓÚÕâ¸öÄÚ´æµØÖ·ÔÚ·þÎñ¶ËÒѾ­Í¬Ê±Ó³Éäµ½Óû§¿Õ¼ä£¬Òò´ËÎÞÐèÔÙ×öÒ»´Î¸´ÖÆ£¬Server¼´¿ÉÖ±½Ó·ÃÎÊ£¬Õû¸ö¹ý³ÌÈçÏÂͼËùʾ£º

Õâ·ùͼµÄ˵Ã÷ÈçÏ£º

ServerÔÚÆô¶¯Ö®ºó£¬µ÷ÓöÔ/dev/binderÉ豸µ÷ÓÃmmap

ÄÚºËÖеÄbinder_mmapº¯Êý½øÐжÔÓ¦µÄ´¦Àí£ºÉêÇëÒ»¿éÎïÀíÄڴ棬ȻºóÔÚÓû§¿Õ¼äºÍÄں˿ռäͬʱ½øÐÐÓ³Éä

Clientͨ¹ýBINDER_WRITE_READÃüÁî·¢ËÍÇëÇó£¬Õâ¸öÇëÇó½«Ïȵ½Çý¶¯ÖУ¬Í¬Ê±ÐèÒª½«Êý¾Ý´ÓClient½ø³ÌµÄÓû§¿Õ¼ä¿½±´µ½Äں˿ռä

Çý¶¯Í¨¹ýBR_TRANSACTION֪ͨServerÓÐÈË·¢³öÇëÇó£¬Server½øÐд¦Àí¡£ÓÉÓÚÕâ¿éÄÚ´æÒ²ÔÚÓû§¿Õ¼ä½øÐÐÁËÓ³É䣬Òò´ËServer½ø³ÌµÄ´úÂë¿ÉÒÔÖ±½Ó·ÃÎÊ

Á˽âÔ­ÀíÖ®ºó£¬ÎÒÃÇÔÙÀ´¿´Ò»ÏÂBinderÇý¶¯µÄÏà¹ØÔ´Âë¡£Õâ¶Î´úÂëÓÐÁ½¸öº¯Êý£º

binder_mmapº¯Êý¶ÔÓ¦ÁËmmapµÄϵͳµ÷ÓõĴ¦Àí

binder_update_page_rangeº¯ÊýÕæÕýʵÏÖÁËÄÚ´æ·ÖÅäºÍµØÖ·Ó³Éä

static int binder_mmap(struct file *filp, struct vm_area_struct *vma)

{

int ret;

struct vm_struct *area;

struct binder_proc *proc = filp->private_data;

const char *failure_string;

struct binder_buffer *buffer;

...

// ÔÚÄں˿ռä»ñȡһ¿éµØÖ··¶Î§

area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP);

if (area == NULL) {

ret = -ENOMEM;

failure_string = "get_vm_area";

goto err_get_vm_area_failed;

}

proc->buffer = area->addr;

// ¼Ç¼Äں˿ռäÓëÓû§¿Õ¼äµÄµØÖ·Æ«ÒÆ

proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer;

mutex_unlock(&binder_mmap_lock);

...

proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL);

if (proc->pages == NULL) {

ret = -ENOMEM;

failure_string = "alloc page array";

goto err_alloc_pages_failed;

}

proc->buffer_size = vma->vm_end - vma->vm_start;

vma->vm_ops = &binder_vm_ops;

vma->vm_private_data = proc;

/* binder_update_page_range assumes preemption is disabled */

preempt_disable();

// ͨ¹ýÏÂÃæÕâ¸öº¯ÊýÕæÕýÍê³ÉÄÚ´æµÄÉêÇëºÍµØÖ·µÄÓ³Éä

// ³õ´ÎʹÓã¬ÏÈÉêÇëÒ»¸öPAGE_SIZE´óСµÄÄÚ´æ

ret = binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma);

...

}

static int binder_update_page_range(struct binder_proc *proc, int allocate,

void *start, void *end,

struct vm_area_struct *vma)

{

void *page_addr;

unsigned long user_page_addr;

struct vm_struct tmp_area;

struct page **page;

struct mm_struct *mm;

...

for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) {

int ret;

struct page **page_array_ptr;

page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE];

BUG_ON(*page);

// ÕæÕý½øÐÐÄÚ´æµÄ·ÖÅä

*page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);

if (*page == NULL) {

pr_err("%d: binder_alloc_buf failed for page at %p\n",

proc->pid, page_addr);

goto err_alloc_page_failed;

}

tmp_area.addr = page_addr;

tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */;

page_array_ptr = page;

// ÔÚÄÚºË¿Õ¼ä½øÐÐÄÚ´æÓ³Éä

ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);

if (ret) {

pr_err("%d: binder_alloc_buf failed to map page at %p in kernel\n",

proc->pid, page_addr);

goto err_map_kernel_failed;

}

user_page_addr =

(uintptr_t)page_addr + proc->user_buffer_offset;

// ÔÚÓû§¿Õ¼ä½øÐÐÄÚ´æÓ³Éä

ret = vm_insert_page(vma, user_page_addr, page[0]);

if (ret) {

pr_err("%d: binder_alloc_buf failed to map page at %lx in userspace\n",

proc->pid, user_page_addr);

goto err_vm_insert_page_failed;

}

/* vm_insert_page does not seem to increment the refcount */

}

if (mm) {

up_write(&mm->mmap_sem);

mmput(mm);

}

preempt_disable();

return 0;

...

 

ÔÚ¿ª·¢¹ý³ÌÖУ¬ÎÒÃÇ¿ÉÒÔͨ¹ýprocfs¿´µ½½ø³ÌÓ³ÉäµÄÕâ¿éÄÚ´æ¿Õ¼ä£º

½«AndroidÉ豸Á¬½Óµ½µçÄÔÉÏÖ®ºó£¬Í¨¹ýadb shell½øÈëµ½ÖÕ¶Ë

È»ºóÑ¡ÔñÒ»¸öʹÓÃÁËBinderµÄ½ø³Ì£¬ÀýÈçsystem_server£¨ÕâÊÇϵͳÖÐÒ»¸ö·Ç³£ÖØÒªµÄ½ø³Ì£¬ÏÂÒ»ÕÂÎÒÃÇ»áרÃŽ²½â£©£¬Í¨¹ý ps | grep system_serverÀ´È·¶¨½ø³ÌºÅ£¬ÀýÈçÊÇ1889

ͨ¹ý cat /proc/[pid]/maps | grep "/dev/binder" ¹ýÂ˳öÕâ¿éÄÚ´æµÄµØÖ·

ÔÚÎÒµÄNexus 6PÉÏ£¬¿ØÖÆÌ¨Êä³öÈçÏ£º

angler:/ # ps | grep system_server

system 1889 526 2353404 140016 SyS_epoll_ 72972eeaf4 S system_server

angler:/ # cat /proc/1889/maps | grep "/dev/binder"

7294761000-729485f000 r--p 00000000 00:0c 12593

PS£ºgrepÊÇͨ¹ýͨÅä·û½øÐÐÆ¥Åä¹ýÂ˵ÄÃüÁ¡°|¡±ÊÇUnixÉϵĹܵÀÃüÁî¡£¼´½«Ç°Ò»¸öÃüÁîµÄÊä³ö¸øÏÂÒ»¸öÃüÁî×÷ΪÊäÈë¡£Èç¹ûÕâÀïÎÒÃDz»¼Ó¡° | grep xxx¡±£¬ÄÇô½«¿´µ½Ç°Ò»¸öÃüÁîµÄÍêÕûÊä³ö¡£

ÄÚ´æµÄ¹ÜÀí

ÉÏÎÄÖУ¬ÎÒÃÇ¿´µ½binder_mmapµÄʱºò£¬»áÉêÇëÒ»¸öPAGE_SIZE(ͨ³£ÊÇ4K)µÄÄÚ´æ¡£¶øÊµ¼ÊʹÓùý³ÌÖУ¬Ò»¸öPAGE_SIZEµÄ´óСͨ³£ÊDz»¹»µÄ¡£

ÔÚÇý¶¯ÖУ¬»á¸ù¾Ýʵ¼ÊµÄʹÓÃÇé¿ö½øÐÐÄÚ´æµÄ·ÖÅä¡£ÓÐÄÚ´æµÄ·ÖÅ䣬µ±È»Ò²ÐèÒªÄÚ´æµÄÊÍ·Å¡£ÕâÀïÎÒÃǾÍÀ´¿´¿´BinderÇý¶¯ÖÐÊÇÈçºÎ½øÐÐÄÚ´æµÄ¹ÜÀíµÄ¡£

Ê×ÏÈ£¬ÎÒÃÇ»¹ÊÇ´ÓÒ»´ÎIPCÇëÇó˵Æð¡£

µ±Ò»¸öClientÏëÒª¶ÔServer·¢³öÇëÇóʱ£¬ËüÊ×ÏȽ«ÇëÇó·¢Ë͵½BinderÉ豸ÉÏ£¬ÓÉBinderÇý¶¯¸ù¾ÝÇëÇóµÄÐÅÏ¢ÕÒµ½¶ÔÓ¦µÄÄ¿±ê½Úµã£¬È»ºó½«ÇëÇóÊý¾Ý´«µÝ¹ýÈ¥¡£

½ø³Ìͨ¹ýioctlϵͳµ÷ÓÃÀ´·¢³öÇëÇó£ºioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)

PS£ºÕâÐдúÂëÀ´×ÔÓÚFramework²ãµÄIPCThreadStateÀà¡£ÔÚºóÎÄÖУ¬ÎÒÃǽ«¿´µ½£¬IPCThreadStateÀàרߺÔðÓëÇý¶¯½øÐÐͨÐÅ¡£

ÕâÀïµÄmProcess->mDriverFD¶ÔÓ¦ÁË´ò¿ªBinderÉ豸ʱµÄfd¡£BINDER_WRITE_READ¶ÔÓ¦Á˾ßÌåÒª×öµÄ²Ù×÷Â룬Õâ¸ö²Ù×÷Â뽫ÓÉBinderÇý¶¯½âÎö¡£bwr´æ´¢ÁËÇëÇóÊý¾Ý£¬ÆäÀàÐÍÊÇbinder_write_read¡£

binder_write_readÆäʵÊÇÒ»¸öÏà¶ÔÍâ²ãµÄÊý¾Ý½á¹¹£¬ÆäÄÚ²¿»á°üº¬Ò»¸öbinder_transaction_data½á¹¹µÄÊý¾Ý¡£binder_transaction_data°üº¬ÁË·¢³öÇëÇóÕߵıêʶ£¬ÇëÇóµÄÄ¿±ê¶ÔÏóÒÔ¼°ÇëÇóËùÐèÒªµÄ²ÎÊý¡£ËüÃǵĹØÏµÈçÏÂͼËùʾ£º

binder_ioctlº¯Êý¶ÔÓ¦ÁËioctlϵͳµ÷ÓõĴ¦Àí¡£Õâ¸öº¯ÊýµÄÂß¼­±È½Ï¼òµ¥£¬¾ÍÊǸù¾ÝioctlµÄÃüÁîÀ´È·¶¨½øÒ»²½´¦ÀíµÄÂß¼­£¬¾ßÌåÈçÏÂ:

Èç¹ûÃüÁîÊÇBINDER_WRITE_READ£¬²¢ÇÒ

Èç¹û bwr.write_size > 0£¬Ôòµ÷ÓÃbinder_thread_write

Èç¹û bwr.read_size > 0£¬Ôòµ÷ÓÃbinder_thread_read

Èç¹ûÃüÁîÊÇBINDER_SET_MAX_THREADS£¬ÔòÉèÖýø³ÌµÄmax_threads£¬¼´½ø³ÌÖ§³ÖµÄ×î´óÏß³ÌÊý

Èç¹ûÃüÁîÊÇBINDER_SET_CONTEXT_MGR£¬ÔòÉèÖõ±Ç°½ø³ÌΪServiceManager£¬¼ûÏÂÎÄ

Èç¹ûÃüÁîÊÇBINDER_THREAD_EXIT£¬Ôòµ÷ÓÃbinder_free_thread£¬ÊÍ·Åbinder_thread

Èç¹ûÃüÁîÊÇBINDER_VERSION£¬Ôò·µ»Øµ±Ç°µÄBinder°æ±¾ºÅ

ÕâÆäÖУ¬×î¹Ø¼üµÄ¾ÍÊÇbinder_thread_write·½·¨¡£µ±ClientÇëÇóServerµÄʱºò£¬±ã»á·¢ËÍÒ»¸öBINDER_WRITE_READÃüÁͬʱ¿ò¼Ü»á½«½«Êµ¼ÊµÄÊý¾Ý°ü×°ºÃ¡£´Ëʱ£¬binder_transaction_dataÖеÄcode½«ÊÇBC_TRANSACTION£¬Óɴ˱ã»áµ÷Óõ½binder_transaction·½·¨£¬Õâ¸ö·½·¨ÊǶÔÒ»´ÎBinderÊÂÎñµÄ´¦Àí£¬ÕâÆäÖлáµ÷ÓÃbinder_alloc_bufº¯ÊýΪ´Ë´ÎÊÂÎñÉêÇëÒ»¸ö»º´æ¡£ÕâÀïÌáµ½µ½µ÷ÓùØÏµÈçÏ£º

binder_update_page_rangeÕâ¸öº¯ÊýÔÚÉÏÎÄÖУ¬ÎÒÃÇÒѾ­¿´µ½¹ýÁË¡£Æä×÷ÓþÍÊÇ£º½øÐÐÄÚ´æ·ÖÅä²¢ÇÒÍê³ÉÄÚ´æµÄÓ³Éä¡£¶øbinder_alloc_bufº¯Êý£¬ÕýÈçÆäÃû³ÆÄÇÑùµÄ£ºÍê³É»º´æµÄ·ÖÅä¡£

ÔÚÇý¶¯ÖУ¬Í¨¹ýbinder_buffer½á¹¹ÌåÃèÊö»º´æ¡£Ò»´ÎBinderÊÂÎñ¾Í»á¶ÔÓ¦Ò»¸öbinder_buffer£¬Æä½á¹¹ÈçÏÂËùʾ£º

struct binder_buffer {

struct list_head entry;

struct rb_node rb_node;

unsigned free:1;

unsigned allow_user_free:1;

unsigned async_transaction:1;

unsigned debug_id:29;

struct binder_transaction *transaction;

struct binder_node *target_node;

size_t data_size;

size_t offsets_size;

uint8_t data[0];

};

¶øÔÚbinder_proc£¨ÃèÊöÁËʹÓÃBinderµÄ½ø³Ì£©ÖУ¬°üº¬Á˼¸¸ö×Ö¶ÎÓÃÀ´¹ÜÀí½ø³ÌÔÚBinder IPC¹ý³ÌÖлº´æ£¬ÈçÏ£º

struct binder_proc {

...

struct list_head buffers; // ½ø³ÌÓµÓеÄbufferÁбí

struct rb_root free_buffers; // ¿ÕÏÐbufferÁбí

struct rb_root allocated_buffers; // ÒÑʹÓõÄbufferÁбí

size_t free_async_space; // Ê£ÓàµÄÒì²½µ÷ÓõĿռä

size_t buffer_size; // »º´æµÄÉÏÏÞ

...

};

½ø³ÌÔÚmmapʱ£¬»áÉ趨֧³ÖµÄ×Ü»º´æ´óСµÄÉÏÏÞ£¨ÏÂÎĻὲµ½£©¡£¶ø½ø³Ìÿµ±ÊÕµ½BC_TRANSACTION£¬¾Í»áÅжÏÒÑʹÓûº´æ¼Ó±¾´ÎÉêÇëµÄºÍÓÐûÓг¬¹ýÉÏÏÞ¡£Èç¹ûûÓУ¬¾Í¿¼ÂǽøÐÐÄÚ´æµÄ·ÖÅä¡£

½ø³ÌµÄ¿ÕÏлº´æ¼Ç¼ÔÚbinder_procµÄfree_buffersÖУ¬ÕâÊÇÒ»¸öÒÔºìºÚÊ÷ÐÎʽ´æ´¢µÄ½á¹¹¡£Ã¿´Î³¢ÊÔ·ÖÅ仺´æµÄʱºò£¬»á´ÓÕâÀïÃæ°´´óС˳Ðò½øÐвéÕÒ£¬ÕÒµ½×î½Ó½üÐèÒªµÄÒ»¿é»º´æ¡£²éÕÒµÄÂß¼­ÈçÏ£º

while (n) {

buffer = rb_entry(n, struct binder_buffer, rb_node);

BUG_ON(!buffer->free);

buffer_size = binder_buffer_size(proc, buffer);

if (size < buffer_size) {

best_fit = n;

n = n->rb_left;

} else if (size > buffer_size)

n = n->rb_right;

else {

best_fit = n;

break;

}

}

ÕÒµ½Ö®ºó£¬»¹ÐèÒª¶Ôbinder_procÖеÄ×ֶνøÐÐÏàÓ¦µÄ¸üУº

rb_erase(best_fit, &proc->free_buffers);

buffer->free = 0;

binder_insert_allocated_buffer(proc, buffer);

if (buffer_size != size) {

struct binder_buffer *new_buffer = (void *)buffer->data + size;

list_add(&new_buffer->entry, &buffer->entry);

new_buffer->free = 1;

binder_insert_free_buffer(proc, new_buffer);

}

binder_debug(BINDER_DEBUG_BUFFER_ALLOC,

"%d: binder_alloc_buf size %zd got %p\n",

proc->pid, size, buffer);

buffer->data_size = data_size;

buffer->offsets_size = offsets_size;

buffer->async_transaction = is_async;

if (is_async) {

proc->free_async_space -= size + sizeof(struct binder_buffer);

binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,

"%d: binder_alloc_buf size %zd async free %zd\n",

proc->pid, size, proc->free_async_space);

}

ÏÂÃæÎÒÃÇÔÙÀ´¿´¿´ÄÚ´æµÄÊÍ·Å¡£

BC_FREE_BUFFERÃüÁîÊÇ֪ͨÇý¶¯½øÐÐÄÚ´æµÄÊÍ·Å£¬binder_free_bufº¯ÊýÊÇÕæÕýʵÏÖµÄÂß¼­£¬Õâ¸öº¯ÊýÓëbinder_alloc_bufÊǸպöÔÓ¦µÄ¡£ÔÚÕâ¸öº¯ÊýÖУ¬Ëù×öµÄÊÂÇé°üÀ¨£º

ÖØÐ¼ÆËã½ø³ÌµÄ¿ÕÏлº´æ´óС

ͨ¹ýbinder_update_page_rangeÊÍ·ÅÄÚ´æ

¸üÐÂbinder_procµÄbuffers£¬free_buffers£¬allocated_buffers×Ö¶Î

BinderÖеġ°ÃæÏò¶ÔÏó¡±

Binder»úÖÆµ­»¯Á˽ø³ÌµÄ±ß½ç£¬Ê¹µÃ¿çÔ½½ø³ÌÒ²Äܹ»µ÷Óõ½Ö¸¶¨·þÎñµÄ·½·¨£¬ÆäÔ­ÒòÊÇÒòΪBinder»úÖÆÔڵײ㴦ÀíÁËÔÚ½ø³Ì¼äµÄ¡°¶ÔÏó¡±´«µÝ¡£

ÔÚBinderÇý¶¯ÖУ¬²¢²»ÊÇÕæµÄ½«¶ÔÏóÔÚ½ø³Ì¼äÀ´»ØÐòÁл¯£¬¶øÊÇͨ¹ýÌØ¶¨µÄ±êʶÀ´½øÐжÔÏóµÄ´«µÝ¡£BinderÇý¶¯ÖУ¬Í¨¹ýflat_binder_objectÀ´ÃèÊöÐèÒª¿çÔ½½ø³Ì´«µÝµÄ¶ÔÏ󡣯䶍ÒåÈçÏ£º

struct flat_binder_object {

__u32 type;

__u32 flags;

union {

binder_uintptr_t binder; /* local object */

__u32 handle; /* remote object */

};

binder_uintptr_t cookie;

};

ÕâÆäÖУ¬typeÓÐÈçÏÂ5ÖÖÀàÐÍ¡£

enum {

BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),

BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),

BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),

BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),

BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),

};

µ±¶ÔÏ󴫵ݵ½BinderÇý¶¯ÖеÄʱºò£¬ÓÉÇý¶¯À´½øÐз­ÒëºÍ½âÊÍ£¬È»ºó´«µÝµ½½ÓÊյĽø³Ì¡£

ÀýÈçµ±Server°ÑBinderʵÌå´«µÝ¸øClientʱ£¬ÔÚ·¢ËÍÊý¾ÝÁ÷ÖУ¬flat_binder_objectÖеÄtypeÊÇBINDER_TYPE_BINDER£¬Í¬Ê±binder×Ö¶ÎÖ¸ÏòServer½ø³ÌÓû§¿Õ¼äµØÖ·¡£µ«Õâ¸öµØÖ·¶ÔÓÚClient½ø³ÌÊÇûÓÐÒâÒåµÄ£¨LinuxÖУ¬Ã¿¸ö½ø³ÌµÄµØÖ·¿Õ¼äÊÇ»¥Ïà¸ôÀëµÄ£©£¬Çý¶¯±ØÐë¶ÔÊý¾ÝÁ÷ÖеÄflat_binder_object×öÏàÓ¦µÄ·­Ò룺½«type¸Ã³ÉBINDER_TYPE_HANDLE£»ÎªÕâ¸öBinderÔÚ½ÓÊÕ½ø³ÌÖд´½¨Î»ÓÚÄÚºËÖеÄÒýÓò¢½«ÒýÓúÅÌîÈëhandleÖС£¶ÔÓÚ·¢ÉúÊý¾ÝÁ÷ÖÐÒýÓÃÀàÐ͵ÄBinderÒ²Òª×öͬÑùת»»¡£¾­¹ý´¦Àíºó½ÓÊÕ½ø³Ì´ÓÊý¾ÝÁ÷ÖÐÈ¡µÃµÄBinderÒýÓòÅÊÇÓÐЧµÄ£¬²Å¿ÉÒÔ½«ÆäÌîÈëÊý¾Ý°übinder_transaction_dataµÄtarget.handleÓò£¬ÏòBinderʵÌå·¢ËÍÇëÇó¡£

ÓÉÓÚÿ¸öÇëÇóºÍÇëÇóµÄ·µ»Ø¶¼»á¾­ÀúÄں˵ķ­Ò룬Òò´ËÕâ¸ö¹ý³Ì´Ó½ø³ÌµÄ½Ç¶ÈÀ´¿´ÊÇÍêȫ͸Ã÷µÄ¡£½ø³ÌÍêÈ«²»ÓøÐÖªÕâ¸ö¹ý³Ì£¬¾ÍºÃÏñ¶ÔÏóÕæµÄÔÚ½ø³Ì¼äÀ´»Ø´«µÝÒ»Ñù¡£

Çý¶¯²ãµÄÏ̹߳ÜÀí

ÉÏÎĶà´ÎÌáµ½£¬Binder±¾ÉíÊÇC/S¼Ü¹¹¡£ÓÉServerÌṩ·þÎñ£¬±»ClientʹÓ᣼ÈÈ»ÊÇC/S¼Ü¹¹£¬¾Í¿ÉÄÜ´æÔÚ¶à¸öClient»áͬʱ·ÃÎÊServerµÄÇé¿ö¡£ ÔÚÕâÖÖÇé¿öÏ£¬Èç¹ûServerÖ»ÓÐÒ»¸öÏ̴߳¦ÀíÏìÓ¦£¬¾Í»áµ¼Ö¿ͻ§¶ËµÄÇëÇó¿ÉÄÜÐèÒªÅŶӶøµ¼ÖÂÏìÓ¦¹ýÂýµÄÏÖÏó·¢Éú¡£½â¾öÕâ¸öÎÊÌâµÄ·½·¨¾ÍÊÇÒýÈë¶àÏ̡߳£

Binder»úÖÆµÄÉè¼Æ´Ó×îµ×²ã¨CÇý¶¯²ã£¬¾Í¿¼Âǵ½Á˶ÔÓÚ¶àÏ̵߳ÄÖ§³Ö¡£¾ßÌåÄÚÈÝÈçÏ£º

ʹÓÃBinderµÄ½ø³ÌÔÚÆô¶¯Ö®ºó£¬Í¨¹ýBINDER_SET_MAX_THREADS¸æÖªÇý¶¯ÆäÖ§³ÖµÄ×î´óÏß³ÌÊýÁ¿

Çý¶¯»á¶ÔÏ߳̽øÐйÜÀí¡£ÔÚbinder_proc½á¹¹ÖУ¬ÕâЩ×ֶμǼÁ˽ø³ÌÖÐÏ̵߳ÄÐÅÏ¢£ºmax_threads£¬requested_threads£¬requested_threads_started£¬ready_threads

binder_thread½á¹¹¶ÔÓ¦ÁËBinder½ø³ÌÖеÄÏß³Ì

Çý¶¯Í¨¹ýBR_SPAWN_LOOPERÃüÁî¸æÖª½ø³ÌÐèÒª´´½¨Ò»¸öеÄÏß³Ì

½ø³Ìͨ¹ýBC_ENTER_LOOPERÃüÁî¸æÖªÇý¶¯ÆäÖ÷Ïß³ÌÒѾ­ready

½ø³Ìͨ¹ýBC_REGISTER_LOOPERÃüÁî¸æÖªÇý¶¯Æä×ÓỊ̈߳¨·ÇÖ÷Ị̈߳©ÒѾ­ready

½ø³Ìͨ¹ýBC_EXIT_LOOPERÃüÁî¸æÖªÇý¶¯ÆäÏ߳̽«ÒªÍ˳ö

ÔÚÏß³ÌÍ˳öÖ®ºó£¬Í¨¹ýBINDER_THREAD_EXIT¸æÖªBinderÇý¶¯¡£Çý¶¯½«¶ÔÓ¦µÄbinder_thread¶ÔÏóÏú»Ù

ÔÙÁÄServiceManager

ÉÏÎÄÒѾ­Ëµ¹ý£¬Ã¿Ò»¸öBinder ServerÔÚÇý¶¯ÖлáÓÐÒ»¸öbinder_node½øÐжÔÓ¦¡£Í¬Ê±£¬BinderÇý¶¯»á¸ºÔðÔÚ½ø³Ì¼ä´«µÝ·þÎñ¶ÔÏ󣬲¢¸ºÔðµ×²ãµÄת»»¡£ÁíÍ⣬ÎÒÃÇÒ²Ìáµ½£¬Ã¿Ò»¸öBinder·þÎñ¶¼ÐèÒªÓÐÒ»¸öΨһµÄÃû³Æ¡£ÓÉServiceManagerÀ´¹ÜÀíÕâЩ·þÎñµÄ×¢²áºÍ²éÕÒ¡£

¶øÊµ¼ÊÉÏ£¬ÎªÁ˱ãÓÚʹÓã¬ServiceManager±¾ÉíҲʵÏÖΪһ¸öServer¶ÔÏó¡£Èκνø³ÌÔÚʹÓÃServiceManagerµÄʱºò£¬¶¼ÐèÒªÏÈÄõ½Ö¸ÏòËüµÄ±êʶ¡£È»ºóͨ¹ýÕâ¸ö±êʶÀ´Ê¹ÓÃServiceManager¡£

ÕâËÆºõÐγÉÁËÒ»¸ö»¥Ïàì¶ÜµÄÏÖÏó£º

ͨ¹ýServiceManagerÎÒÃDzÅÄÜÄõ½ServerµÄ±êʶ

ServiceManager±¾ÉíÒ²ÊÇÒ»¸öServer

½â¾öÕâ¸öì¶ÜµÄ°ì·¨ÆäʵҲºÜ¼òµ¥£ºBinder»úÖÆÎªServiceManagerÔ¤ÁôÁËÒ»¸öÌØÊâµÄλÖá£Õâ¸öλÖÃÊÇÔ¤Ïȶ¨ºÃµÄ£¬ÈκÎÏëҪʹÓÃServiceManagerµÄ½ø³ÌֻҪͨ¹ýÕâ¸öÌØ¶¨µÄλÖþͿÉÒÔ·ÃÎʵ½ServiceManagerÁË£¨¶ø²»ÓÃÔÙͨ¹ýServiceManagerµÄ½Ó¿Ú£©¡£

ÔÚBinderÇý¶¯ÖУ¬ÓÐÒ»¸öÈ«¾ÖµÄ±äÁ¿£º

static struct binder_node *binder_context_mgr_node;

Õâ¸ö±äÁ¿Ö¸ÏòµÄ¾ÍÊÇServiceManager¡£

µ±Óнø³Ìͨ¹ýioctl²¢Ö¸¶¨ÃüÁîΪBINDER_SET_CONTEXT_MGRµÄʱºò£¬Çý¶¯±»È϶¨Õâ¸ö½ø³ÌÊÇServiceManager£¬binder_ioctlº¯ÊýÖжÔÓ¦µÄ´¦ÀíÈçÏ£º

case BINDER_SET_CONTEXT_MGR:

if (binder_context_mgr_node != NULL) {

pr_err("BINDER_SET_CONTEXT_MGR already set\n");

ret = -EBUSY;

goto err;

}

ret = security_binder_set_context_mgr(proc->tsk);

if (ret < 0)

goto err;

if (uid_valid(binder_context_mgr_uid)) {

if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) {

pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n",

from_kuid(&init_user_ns, current->cred->euid),

from_kuid(&init_user_ns, binder_context_mgr_uid));

ret = -EPERM;

goto err;

}

} else

binder_context_mgr_uid = current->cred->euid;

binder_context_mgr_node = binder_new_node(proc, 0, 0);

if (binder_context_mgr_node == NULL) {

ret = -ENOMEM;

goto err;

}

binder_context_mgr_node->local_weak_refs++;

binder_context_mgr_node->local_strong_refs++;

binder_context_mgr_node->has_strong_ref = 1;

binder_context_mgr_node->has_weak_ref = 1;

break;

ServiceManagerÓ¦µ±ÒªÏÈÓÚËùÓÐBinder Server֮ǰÆô¶¯¡£ÔÚËüÆô¶¯Íê³É²¢¸æÖªBinderÇý¶¯Ö®ºó£¬Çý¶¯±ãÉ趨ºÃÁËÕâ¸öÌØ¶¨µÄ½Úµã¡£

ÔÚÕâÖ®ºó£¬µ±ÓÐÆäËûÄ£¿éÏëҪʹÓÃServerManagerµÄʱºò£¬Ö»Òª½«ÇëÇóÖ¸ÏòServiceManagerËùÔÚµÄλÖü´¿É¡£

ÔÚBinderÇý¶¯ÖУ¬Í¨¹ýhandle = 0Õâ¸öλÖÃÀ´·ÃÎÊServiceManager¡£ÀýÈ磬binder_transactionÖУ¬ÅжÏÈç¹ûtarget.handlerΪ0£¬ÔòÈÏΪÕâ¸öÇëÇóÊÇ·¢Ë͸øServiceManagerµÄ£¬Ïà¹Ø´úÂëÈçÏ£º

½áÊøÓï

±¾ÆªÎÄÕÂÖУ¬ÎÒÃǶÔBinder»úÖÆ×öÁËÕûÌå¼Ü¹¹ºÍ·Ö²ãµÄ½éÉÜ£¬Ò²Ïêϸ½²½âÁËBinder»úÖÆÖеÄÇý¶¯Ä£¿é¡£¶ÔÓÚÇý¶¯Ö®ÉϵÄÄ£¿é£¬»áÔÚ½ñºóµÄÎÄÕÂÖн²½â¡£

 

 

   
3042 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ