Linux 可加载模块 探索
来源:互联网 发布:免费的域名 编辑:程序博客网 时间:2024/05/16 12:33
因为没有环境的原因,现在的这些东西只能算是记忆了。本来想在windows下装个虚拟机的,可惜电脑磁盘空间不够了。
先开始写,先记一下今天为了写Linux下的输入法程序,而无意间搜到的一篇很好的博客:http://blog.csdn.net/absurd/article/details/1497463,此文是李先静老师的一篇关于学习方法的博客,很有感触,我想关于学习,我走过了很多误区,以前只会看,看得很多很泛而且很多东西还是质量很差的文章,结果自己的技术积累很低,实践能力也没跟上,接下来的目标:1,要多看源码,2,要多写程序,3,还是要多写。
这次要把内核模块的数据结构理解一下,以及模块的加载过程。
首先是模块的加载,模块的加载过程需要“用户空间应该程序来帮助"(这一点还需要自己去验证,说法是来自《深入Linux内核架构》),所以先从系统调用开始。跟模块相关的系统调用接口有两个一个初始化,另一个是删除的。
函数原型:
asmlinkage long sys_init_module(void __user *umod, unsigned long len,const char __user *uargs);
asmlinkage long sys_delete_module(const char __user *name_user,unsigned int flags);
一开始就上内核树上去搜索这两个函数的定义了,但看来看去也只看到了sys_init_module的原型就是没找到定义,只好静下来把syscalls.h 和 module.c 认真认真的看了遍,结果发现内核是以宏的形式实现了这两个函数:
SYSCALL_DEFINE3(init_module, void __user *, umod,unsigned long, len, const char __user *, uargs)
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,unsigned int, flags)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(SyS##name))));
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
一开始想不明白为什么系统调用的接口要写的这么复杂,用了这么些预处理宏,我想肯定不是内核开发者为show 自己的水平吧,一阵谷歌,在RedHat Bug 跟踪网站上找到这么些写原来是要处理一个系统安全漏洞,网站的地址忘记记录了,大概的意思是系统的ABI规定,64位的系统,用户空间向内核空间传递32位数据时要将其符号扩展到64位,如果没有这么做就导致内存访问异常的内存空间导致系统crash了,这个Bug出在Mips,Spack等处理器上。既然问题很明确那就是将用户空间的参数先转换成64位,然后再去调用接口函数,那么为什么还要这么弄出这么多宏呢,原来内核开发者的目标是不仅要解决问题,而且还要finish it in art。所以就有了这么多这么漂亮的代码了。
这里还有一个地方我没搞明白,就是这些系统接口都能看到 asmlinkage 的连接声明,我猜大概是为了在防止在用户空间用C++编译器编译代码,导致ABI不兼容吧,因为Linux系统规定的系统调用的参数都要放在栈上。关于ABI,要花点时间去弄明白,先Mark一下。
sys_init_module,先检查模块,然后上篇中介绍的数据从用户空间拷贝的内核空间,接着调用load_module。这些代码还没细看,先写这些了。
先开始写,先记一下今天为了写Linux下的输入法程序,而无意间搜到的一篇很好的博客:http://blog.csdn.net/absurd/article/details/1497463,此文是李先静老师的一篇关于学习方法的博客,很有感触,我想关于学习,我走过了很多误区,以前只会看,看得很多很泛而且很多东西还是质量很差的文章,结果自己的技术积累很低,实践能力也没跟上,接下来的目标:1,要多看源码,2,要多写程序,3,还是要多写。
这次要把内核模块的数据结构理解一下,以及模块的加载过程。
首先是模块的加载,模块的加载过程需要“用户空间应该程序来帮助"(这一点还需要自己去验证,说法是来自《深入Linux内核架构》),所以先从系统调用开始。跟模块相关的系统调用接口有两个一个初始化,另一个是删除的。
函数原型:
asmlinkage long sys_init_module(void __user *umod, unsigned long len,const char __user *uargs);
asmlinkage long sys_delete_module(const char __user *name_user,unsigned int flags);
一开始就上内核树上去搜索这两个函数的定义了,但看来看去也只看到了sys_init_module的原型就是没找到定义,只好静下来把syscalls.h 和 module.c 认真认真的看了遍,结果发现内核是以宏的形式实现了这两个函数:
SYSCALL_DEFINE3(init_module, void __user *, umod,unsigned long, len, const char __user *, uargs)
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,unsigned int, flags)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(SyS##name))));
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
__MAP(x,__SC_TEST,__VA_ARGS__); \
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
一开始想不明白为什么系统调用的接口要写的这么复杂,用了这么些预处理宏,我想肯定不是内核开发者为show 自己的水平吧,一阵谷歌,在RedHat Bug 跟踪网站上找到这么些写原来是要处理一个系统安全漏洞,网站的地址忘记记录了,大概的意思是系统的ABI规定,64位的系统,用户空间向内核空间传递32位数据时要将其符号扩展到64位,如果没有这么做就导致内存访问异常的内存空间导致系统crash了,这个Bug出在Mips,Spack等处理器上。既然问题很明确那就是将用户空间的参数先转换成64位,然后再去调用接口函数,那么为什么还要这么弄出这么多宏呢,原来内核开发者的目标是不仅要解决问题,而且还要finish it in art。所以就有了这么多这么漂亮的代码了。
这里还有一个地方我没搞明白,就是这些系统接口都能看到 asmlinkage 的连接声明,我猜大概是为了在防止在用户空间用C++编译器编译代码,导致ABI不兼容吧,因为Linux系统规定的系统调用的参数都要放在栈上。关于ABI,要花点时间去弄明白,先Mark一下。
sys_init_module,先检查模块,然后上篇中介绍的数据从用户空间拷贝的内核空间,接着调用load_module。这些代码还没细看,先写这些了。
0 0
- Linux 可加载模块 探索
- Linux 可加载模块 探索
- Linux Kernel 可加载模块
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux可加载内核模块(LKM)
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux 可加载内核模块剖析
- Linux可加载内核模块(LKM)
- leetcode - Copy List with Random Pointer题解
- 优秀程序员必备的23条好习惯
- Java内存模型深度解析:顺序一致性
- 如何将一个HTML页面嵌套在另一个页面中
- Parallel.Invoke中Cancel
- Linux 可加载模块 探索
- 关键字球、标签云
- Java内存模型深度解析:重排序
- CentOS-7下安装MySQL5.6.22
- 收藏的命令
- 在PB中用OLE存取blob类型数据
- centos环境变量添加方法
- Java内存模型深度解析:基础部分
- Cocos2d-x 3.x 中解决 无法打开包括文件:“json/document.h”: No such file or directory 的问题