6

Arm-Linux子系统的互相Notify - 江湖评谈

 1 year ago
source link: https://www.cnblogs.com/tangyanzhi1111/p/17109577.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Arm-Linux子系统的互相Notify

Linux下面不同的子系统一个个的组成了整个系统的运行环节,为了让这些子系统能够互相通讯,有一种叫做:notify chain(通知链)的东西。本篇看下。

所谓通知链,有通知,就有执行的地方。比如A子系统通知B子系统,麻烦你帮我执行一件事情。这时候,A子系统就会通知B子系统,把需要执行的事情信息同时传递给B子系统,让其帮助执行。

这个过程,首先是需要有执行的事情,所以就需要注册。当注册好了之后,A子系统通知B子系统,B子系统就会找到注册的那个事情进行执行。

这里以原子通知链(Atomic notifier chains)为例,它分别由注册通知链,卸载通知链,以及调用通知链三种函数:

1. int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *n);  
2. int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, struct notifier_block *n);  
3. int atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v);

还以上面的为例,假如A子系统需要通知B子系统你帮我完成一个事情。那么B子系统首先需要注册一个这个事情,通过函数:atomic_notifier_chain_register来完成。

当A子系统需要通知B子系统执行的时候,A子系统会调用atomic_notifier_call_chain来通知B子系统,你该做事了。

当A子系统不需要B子系统为它做事的时候,可以卸载掉这件事情:atomic_notifier_chain_unregister。

为什么会有卸载这个函数,因为所有的做事情的函数都在一个链表里面,当A子系统通知B子系统做事的时候,有可能会查找整个链表。当成百上千的子系统相互注册的时候,链表非常庞大,卸载这些事情(函数回调),可以很好的提高性能。

elf入口

当Arm32调用用户态的C Main的时候,堆栈里面的ret_from_fork就是通过原子调用链来执行的。

thread #1, stop reason = breakpoint 84.1
frame #0: 0x8010011c vmlinux`ret_from_fork at entry-common.S:142
frame #1: 0x801468b8 vmlinux`atomic_notifier_call_chain [inlined] __rcu_read_unlock at rcupdate.h:74:2
frame #2: 0x801468b4 vmlinux`atomic_notifier_call_chain [inlined] rcu_read_unlock at rcupdate.h:719:2
frame #3: 0x801468b4 vmlinux`atomic_notifier_call_chain(nh=<unavailable>, val=<unavailable>, v=<unavailable>) at notifier.c:199:2

另外一个需要注意的是Arm32的elf入口是通过读取内存异常的中断处理程序来调用用户态Glibc的_start函数入口。
而X64则是通过缺页异常来调用用户态Glibc的_start入口。

作者:江湖评谈
欢迎关注我,带你了解进阶技术。
image


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK