点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客
原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!
5.5 IPIPE: Xenomai/Linux双核系统调用
5.5.1 IPIPE劫持系统调用的流程与场景
参考《5.1.2 内核层:ARM64 Linux系统调用的流程》,先回顾一下ARM64 Linux系统调用的过程:
第一步,从el0_sync跳转到el0_svc。
第二步,从el0_svc跳转到c函数el0_svc_handler
第三步,从el0_svc_handler调用el0_svc_common
第四步,el0_svc_common调用invoke_syscall
在第四步的el0_svc_common函数中,IPIPE是在调用invoke_syscall之前,调用ipipe_handle_syscall进行系统调用的劫持。下图展示的是Xenomai系统调用read的堆栈。
考虑所有因素,在ipipe_handle_syscall需要处理6种场景。在ipipe_handle_syscall函数中,设计了3个代码通路,来处理上述6中场景。
- 代码路径:为了处理这些场景,
ipipe_handle_syscall
设计了三条代码路径:- 快速路径(Fast Path):直接调用
ipipe_fastcall_hook
处理Xenomai系统调用。 - 慢速路径(Slow Path):通过
__ipipe_notify_syscall
和ipipe_syscall_hook
函数处理,根据当前运行的domain(head或root)调用相应的处理函数。 - 正常路径:对于Linux系统调用,直接返回给Linux内核处理。
- 快速路径(Fast Path):直接调用
ipipe_handle_syscall 6种场景的处理 | Xenomai系统调用 (系统调用号>=0x1000 0000) | Linux系统调用 (系统调用号<0x1000 0000) |
Xenomai实时线程 运行在Head domain | 场景1: | 场景2: __ipipe_notify_syscall |
Xenomai实时线程 运行在Root domain | 场景3: __ipipe_notify_syscall | 场景4: __ipipe_notify_syscall |
Linux线程 | 场景5: __ipipe_notify_syscall | 场景6: 正常返回给Linux处理 |
把上面的表格,对应到ipipe_handle_syscall函数的实现,就会发现代码的实现思路突然清楚了。 特别是场景6,一目了然,不需要展开。
在ipipe.rst中,代码通路ipipe_fastcall_hook又被称为快速处理路径(fast path),而__ipipe_notify_syscall又被称为慢速路径(slow path)。
为什么?
ipipe_fastcall_hook直接调用handle_head_syscall执行Xenomai的系统调用函数。
反观__ipipe_notify_syscall,逻辑比较复杂,用next/goto next反复调用ipipe_syscall_hook函数。在ipipe_syscall_hook函数中,如果当前是head domain则调用handle_head_syscall,如果当前是root domain则调用handle_root_syscall。
__ipipe_notify_syscall有个非常特殊的地方,在第一次调用ipipe_syscall_hook函数之前,总是把current domain改成head domain(第1229行)。这样在ipipe_syscall_hook函数中必然会调用handle_head_syscall。
本文总结:ipipe_handle_syscall劫持系统调用后,需要处理6中场景,分为3个代码路径进行处理:快速、慢速和正常路径!
接下来的章节会结合实例实际分析快速和慢速路径!
点击查看系列文章 =》 Interrupt Pipeline系列文章大纲-CSDN博客
原创不易,需要大家多多鼓励!您的关注、点赞、收藏就是我的创作动力!
标签:劫持,调用,handle,5.5,hook,syscall,ipipe,场景,IPIPE From: https://blog.csdn.net/aspirestro/article/details/144962718