linux驱动入口函数,你了解linux驱动的入口?
以module_init(Demo_init);为例
定义文件:
include\linux\init.h
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__secTIon__(".initcall" level ".init"))) = fn
展开为
staTIc initcall_t __initcall_Demo_init6 __attribute_used__ __attribute__((__secTIon__(".initcall6.init"))) = Demo_init;
typedef int (*initcall_t)(void);
这里
typedef int (init_fnc_t) (void); 定义一种函数类型
typedef int (*init_fnc_t) (void); 定义一种类型的函数指针
所以展开的宏定义就是定义名为__initcall_Demo_init6的函数指针
属性有两个:
1.
在gcc 3.4之前的编译器被展开成__attribute__((unused))来禁止编译器弹出有关函数没有被用到的的警告信息
在gcc 3.4之后被展开成__attribute__((used))功能一样
2.加载到段.initcall6.init,其地址为Demo_init的地址
段的分布顺序在链接脚本中有
编译内核后,会有vmlinux.lds的打印信息,里面有各段位置
__initcall_start = .;
*(.initcallearly.init) __early_initcall_end = .;
*(.initcall0.init)
*(.initcall0s.init)
*(.initcall1.init)
*(.initcall1s.init)
*(.initcall2.init)
*(.initcall2s.init)
*(.initcall3.init)
*(.initcall3s.init)
*(.initcall4.init)
*(.initcall4s.init)
*(.initcall5.init)
*(.initcall5s.init)
*(.initcallrootfs.init)
*(.initcall6.init)
*(.initcall6s.init)
*(.initcall7.init)
*(.initcall7s.init)
__initcall_end = .;
当insmod的时候,内核从initcall6.init段中读取到驱动入口地址,然后跳转到该地址去执行入口函数,
一般入口函数会进行注册驱动,例如
register_chrdev(unsigned int major, const char * name, const struct file_operaTIons * fops)
usb_register(struct usb_driver * driver)
spi_register_driver(struct spi_driver * sdrv)
等等注册函数,再依次调用相应设备结构体中的ioctl或者直接调用file_operations结构体
linux驱动入口函数,你了解linux驱动的入口?相关推荐
- linux使用shell函数扩充命令,Linux Shell系列教程之(十五) Shell函数简介 | Linux大学...
摘要 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高. 高级语言都支持函数,Shell也不例外.今天就为大家介绍下Shell中函数相关用法. 函数可以将一个复杂功能划 ...
- linux 创建线程函数吗,[笔记]linux下和windows下的 创建线程函数
linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include #define CreateThreadEx(tid,threadFun,args) ...
- linux驱动获取函数失败信息,linux驱动调试--段错误之栈信息分析
接着上一篇来分析一下Oops的栈 s3c2440平台 关于调试源码和整个Oops信息请参考上一篇博文,这里只再次贴出关于栈的信息 Stack: (0xc3a61e30 to 0xc3a62000) 1 ...
- Linux系统常用函数,浅谈linux下的一些常用函数的总结(必看篇)
1.exit()函数 exit(int n) 其实就是直接退出程序, 因为默认的标准程序入口为int main(int argc, char** argv),返回值是int型的. 一般在shell下 ...
- linux文件字节函数,各位大侠:linux/unix下有什么双字节的字符类型及其一整套处理函数? 高分送出,请帮帮小弟!!!!!!...
linux/unix下小弟需要操作双字节,相对单字节char 有什么双字节的字符类型及其一整套处理函数,如strstr(),strcpy(),strchr等功能相同的双字节操作函数,它用到什么头文件? ...
- linux用Lseek函数 拷贝文件,linux系统下lseek函数的详细用法
前面的文章里面,仔细讲了在linux系统对文件的读写操作以及文件管理,为今天要讲的内容作了铺垫(如果您是刚接触这方面的内容,可以先看我之前写的文章,有错误的地方,还望指出来,在这里先说一声谢谢).好了 ...
- linux c sync函数,怎么在Linux中调用fsync函数
Linux中如何调用fsync函数?针对这个问题,本文详细介绍了相应的分析和解决方法,希望能帮助更多想解决这个问题的伙伴找到更简单易行的方法. 功能描述: 将内存中所有已修改的文件数据同步到存储设备. ...
- linux中read函数的用法,Linux中read命令的简介及使用方法
Linux中read命令的简介及使用方法 发布时间:2020-08-17 16:40:04 来源:亿速云 阅读:107 作者:小新 这篇文章给大家分享的是有关Linux中read命令的简介及使用方法的 ...
- Linux中append函数的用法,linux C代码 open函数参数:O_APPEND问题求助
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 没有截图,直接上代码吧. 原代码是这样的: #include #include #include #include #include int main() ...
最新文章
- Upload Picture to application server
- 如何在ubuntu 12.04系统下开启nfs网络文件系统
- Touch Driver介绍
- linux新的API signalfd、timerfd、eventfd使用说明——eventfd
- 一篇英文文档中找出频数最多的10个单词
- php导出csv文件乱码问题解决方法
- Multi-thread--C++11中std::mutex的使用
- C++ 链表入门习题
- [xsy2282]cake
- 中国·哈尔滨国际友好城市冰雪汽车挑战赛开赛
- qq怎样发起临时会话(不加好友)
- 【面试常问】Redis的持久化机制是什么?各自的优缺点?
- 三星note10安装linux,三星Note10/Note10+新款Dex已支持Win10/macOS
- 修改计算机名无法共享打印机,打印机设置共享以及共享时无法连接,报错0X00000006解决方法...
- Linux 进程查看命令 ps top htop dstat
- NIO编程--聊天室Demo
- 【小程序】常见系统API | 页面分享 | 位置信息 | 本地存储
- 考研高危人群!你是否还在危险的边缘试探?
- 单链表的定义、特点、结构及其一些基本操作
- 自定义小部件Widget的探讨