范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

LinuxAPI分析moduleinit与moduleexit

  【Linux API 分析】module_init与module_exit
  Linux版本:4.19 1、前言
  module_init  与 module_exit  用于我们驱动的加载,卸载,是我们驱动初始化/退出的入口函数。 module_init  :内核启动时或者动态插入模块时调用 module_exit  :驱动移除时调用
  下面主要分析一下这两个接口的底层实现。
  2、调用层次分析2.1 module_init #ifndef MODULE  /**   * module_init() - driver initialization entry point   * @x: function to be run at kernel boot time or module insertion   *   * module_init() will either be called during do_initcalls() (if   * builtin) or at module insertion time (if a module).  There can only   * be one per module.   */  #define module_init(x)  __initcall(x);    /**   * module_exit() - driver exit entry point   * @x: function to be run when driver is removed   *   * module_exit() will wrap the driver clean-up code   * with cleanup_module() when used with rmmod when   * the driver is a module.  If the driver is statically   * compiled into the kernel, module_exit() has no effect.   * There can only be one per module.   */  #define module_exit(x)  __exitcall(x);    #else /* MODULE */    /*   * In most cases loadable modules do not need custom   * initcall levels. There are still some valid cases where   * a driver may be needed early if built in, and does not   * matter when built as a loadable module. Like bus   * snooping debug drivers.   */  #define early_initcall(fn)      module_init(fn)  #define core_initcall(fn)       module_init(fn)  #define core_initcall_sync(fn)      module_init(fn)  #define postcore_initcall(fn)       module_init(fn)  #define postcore_initcall_sync(fn)  module_init(fn)  #define arch_initcall(fn)       module_init(fn)  #define subsys_initcall(fn)     module_init(fn)  #define subsys_initcall_sync(fn)    module_init(fn)  #define fs_initcall(fn)         module_init(fn)  #define fs_initcall_sync(fn)        module_init(fn)  #define rootfs_initcall(fn)     module_init(fn)  #define device_initcall(fn)     module_init(fn)  #define device_initcall_sync(fn)    module_init(fn)  #define late_initcall(fn)       module_init(fn)  #define late_initcall_sync(fn)      module_init(fn)    #define console_initcall(fn)        module_init(fn)  #define security_initcall(fn)       module_init(fn)    /* Each module must use one module_init(). */  #define module_init(initfn)                       static inline initcall_t __maybe_unused __inittest(void)              { return initfn; }                        int init_module(void) __copy(initfn) __attribute__((alias(#initfn)));    /* This is only required if you want to be unloadable. */  #define module_exit(exitfn)                       static inline exitcall_t __maybe_unused __exittest(void)              { return exitfn; }                        void cleanup_module(void) __copy(exitfn) __attribute__((alias(#exitfn)));    #endif
  2.2 __initcall #define __initcall(fn) device_initcall(fn)    #define __exitcall(fn)                            static exitcall_t __exitcall_##fn __exit_call = fn
  2.3 device_initcall #define pure_initcall(fn)       __define_initcall(fn, 0)        #define core_initcall(fn)       __define_initcall(fn, 1)    #define core_initcall_sync(fn)      __define_initcall(fn, 1s)    #define postcore_initcall(fn)       __define_initcall(fn, 2)    #define postcore_initcall_sync(fn)  __define_initcall(fn, 2s)    #define arch_initcall(fn)       __define_initcall(fn, 3)    #define arch_initcall_sync(fn)      __define_initcall(fn, 3s)    #define subsys_initcall(fn)     __define_initcall(fn, 4)    #define subsys_initcall_sync(fn)    __define_initcall(fn, 4s)    #define fs_initcall(fn)         __define_initcall(fn, 5)    #define fs_initcall_sync(fn)        __define_initcall(fn, 5s)    #define rootfs_initcall(fn)     __define_initcall(fn, rootfs)    #define device_initcall(fn)     __define_initcall(fn, 6)    #define device_initcall_sync(fn)    __define_initcall(fn, 6s)    #define late_initcall(fn)       __define_initcall(fn, 7)    #define late_initcall_sync(fn)      __define_initcall(fn, 7s)        #define __initcall(fn) device_initcall(fn)
  2.4 ___define_initcall #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS  #define ___define_initcall(fn, id, __sec)                 __ADDRESSABLE(fn)                         asm(".section   "" #__sec ".init", "a"   "       "__initcall_" #fn #id ":             "           ".long  " #fn " - .          "           ".previous                   ");  #else  #define ___define_initcall(fn, id, __sec)       static initcall_t __initcall_##fn##id __used           __attribute__((__section__(#__sec ".init"))) = fn;  #endif
  2.5、module_init调用顺序汇总 module_init      ---> __initcall          ---> device_initcall              ---> __define_initcall(include/linux/init.h)                  ---> ___define_initcall(/include/linux/init.h)
  综上,我们调用顺序: module_init(fn)---> initcall(fn) ---> device_initcall(fn) ---> define_initcall(fn, 6)
  3、源码分析
  通过上面了解,我们最后调用的是 ___define_initcall  的函数,下面我们主要分析该函数的意义。
  了解之前呢,我们先来学习一下 #  与 ##  的作用!
  3.1 # 与 ## 的作用
  符号
  作用
  举例
  ##
  "##"符号 可以是连接的意思
  例如  initcall_##fn##id 为 initcall_fnid那么,fn = test_init,id = 6时,  initcall_##fn##id为  initcall_test_init6
  #
  "#"符号 可以是字符串化的意思
  例如 #id 为 "id",id=6 时,#id 为"6"
  3.2 __define_initcall #define __define_initcall(fn, id)         static initcall_t __initcall_##fn##id __used         __attribute__((__section__(".initcall" #id ".init"))) = fn
  这里我们以 module_init(test_init)  为例,转换后的结果为:  static initcall_t __initcall_test_init6 __used __attribute__((__section__(".initcall6.init"))) = test_init
  通过 __attribute__(__section__)  设置函数属性,将 test_init  放在字段 .initcall6.init  中。
  该字段通过链接器链接起来,形成一个列表进行统一管理。  ......  __initcall6_start = .; KEEP(*(.initcall6.init)) KEEP(*(.initcall6s.init))   ......
  还记得 __define_initcall  的定义吗? #define pure_initcall(fn)       __define_initcall(fn, 0)      #define core_initcall(fn)       __define_initcall(fn, 1)   #define core_initcall_sync(fn)      __define_initcall(fn, 1s)   #define postcore_initcall(fn)       __define_initcall(fn, 2)   #define postcore_initcall_sync(fn)  __define_initcall(fn, 2s)   #define arch_initcall(fn)       __define_initcall(fn, 3)   #define arch_initcall_sync(fn)      __define_initcall(fn, 3s)   #define subsys_initcall(fn)     __define_initcall(fn, 4)   #define subsys_initcall_sync(fn)    __define_initcall(fn, 4s)   #define fs_initcall(fn)         __define_initcall(fn, 5)   #define fs_initcall_sync(fn)        __define_initcall(fn, 5s)   #define rootfs_initcall(fn)     __define_initcall(fn, rootfs)   #define device_initcall(fn)     __define_initcall(fn, 6)   #define device_initcall_sync(fn)    __define_initcall(fn, 6s)   #define late_initcall(fn)       __define_initcall(fn, 7)   #define late_initcall_sync(fn)      __define_initcall(fn, 7s)      #define __initcall(fn) device_initcall(fn)
  不同的宏定义,被赋予了不同的调用等级,最后将不同的驱动初始化函数统一汇总到 __initcallx_start  字段统一管理,形成一个有序的列表。
  这样,我们在内核中,按照顺序遍历这个列表,最后执行对应的模块初始化函数 fn  即可实现驱动的初始化。
  这篇内容主要分析 module_init 的调用以及作用,后续再详细分析内核是如何调用初始化函数的。

折叠屏再突破三星GalaxyZFold4ZFlip4品鉴会落地北京北京商报讯9月1日,三星携旗下第四代折叠屏手机三星GalaxyZFold4ZFlip4,以及智能穿戴新品三星GalaxyWatch5系列与三星GalaxyBuds2Pro旗舰耳机亮27寸2K显示器限时699元秒杀这款27英寸的2K显示器目前京东售价699元,可以说非常具有性价比,喜欢的朋友不要错过。这款显示器采用了27英寸的屏幕尺寸,能够为用户提供更为宽广的视野。分辨率则是采用了2K的屏幕折叠屏再突破三星GalaxyZFold4ZFlip4品鉴会落地北京9月1日,三星携旗下第四代折叠屏手机三星GalaxyZFold4ZFlip4,以及智能穿戴新品三星GalaxyWatch5系列与三星GalaxyBuds2Pro旗舰耳机亮相北京品鉴比亚迪五菱有压力了!奇瑞逆袭成功,QQ小蚂蚁爆火汽车元宇宙从奇瑞控股获悉,今年8月,集团新能源乘用车销量为26,148辆,18月总销量为157,576辆,同比增长238,同期市占率超过了广汽埃安。今年以来,奇瑞新能源推出了无界P被字节百度抢了饭碗,庆余年背后的阅文不再做网文公司文刘东峰2017年,阅文集团副总裁,时任原创内容总经理杨晨曾感慨道无敌,真的太过寂寞。彼时,在阅文的影响下,中国的网文结束了混乱的野蛮生长期,开始进入了付费阅读时代。背靠斗破苍穹择目前拍照最出色的四款手机,影像实力不输小单反,拍照爱好者必备如果你对手机拍照有着较高的要求的话,强烈建议考虑这是看机型,影像实力直追小单反喜欢拍照的朋友千万不要错过,这几款机型绝对是目前最佳选择。第一款OPPOFindX5Pro这款手机是今北极冰壳下,可能藏着另一个中东全球变暖,冰川融化,北极这位被地球雪藏了270万年的冰美人,正在一步步掀开神秘面纱从人类舞台的边缘走到聚光灯下,同时也正在能源航道生态环境等方面酝酿巨大的变局。这也给当今发展提出了闭眼买就行,这3款手机不仅性能强悍,价格还很良心闭眼买就行,这3款手机不仅性能强悍,价格还很良心第一款iQOO103999起搭载台积电工艺的骁龙8,发热量功耗控制的比较好,性能释放激进,玩王者荣耀可以接近满帧运行。4700mAh江苏旧将闪耀中超,昔日飞翼已造10球,武汉三镇乐开花2020赛季,江苏队在赛会制的联赛中力克广州队,夺得了队史的首座联赛冠军。然而大喜过后就是大悲,因为苏宁集团无力再运营球队,因此在2021新赛季开打前,卫冕冠军江苏队就宣布解散。队13GB40W闪充,发布仅两个月跌至1339元,荣耀新机沦为标准千元机流畅性是用户们判断一款手机好不好用的重要标准,因为手机一旦不流畅出现卡顿的现象,那么使用体验将会非常差,这也是为什么苹果手机即使售价不菲,购买得人依然络绎不绝的原因,不过其实如今的国之重器中国天眼(FAST)高质量开放运行取得重大进展2022年1月5日,中国科学院在中科院国家天文台举行新闻发布会,发布中国天眼(FAST)高质量开放运行取得的系列重要科学成果,其中包括FAST中性氢谱线测量取得重大进展获得迄今为止
欲望太多会迷失本性有欲望没有错,错的是欲望之火迅猛地燃烧,一发不可收拾。每个人的心中都有一团欲望之火,我们既不能让这团火熄灭,也不能让它烧得太过猛烈。因为欲望之火熄灭,意味着人不思进取,没有斗志,没缄默不言人长居于野,不复能言。若于世上,不可多言,看不惯亦不能言,久而久之,缄默不言。生来渺小,人微言轻,淡然处之,超脱世事。琴棋书画皆小道,谈古论今枉费心。浩宇宽广,透过现象找规律。查遗水韵绍兴绍兴印象看完小时候语文课本中就存在的钱塘江大潮后,我们便驱车前往绍兴。开始了绍兴之旅鲁迅故里百草园中草半荒,三味书屋味更浓若将绍兴比喻成一部漂在水上的书,那么,鲁迅故里无疑就是全书遇到农村自酿酒别着急买,极有可能是坑,建议大家弄懂再喝前两天老家的表妹结婚,我特意回了一次老家,已经许久没有回去了,家里已经有了很大的改变,之前的小土房都变成了一排排整齐的水泥房,之前到处都是土的地方,也被改造成了一个小广场,有很多老燃油车主注意了,家用车车船税有调整,网友建议推广现阶段,汽车已成功进入千家万户。在传统燃油汽车备受青睐的时代,在新能源汽车的强势攻击下进一步满足了我们对低成本高车载配置的追求。特别是在燃油汽车遇到芯片短缺原材料价格上涨等问题后,美媒组三队8人交易震动联盟,奥尼尔转发,勇士获得4号位完美答案今年NBA联盟有诸多豪门球队都过的很不如意,即便是去年的总冠军勇士队,如今也因为板凳席球员的状态问题,位居西部第12名。而湖人和篮网这些身处大城市的球队更是过得水深火热,篮网历经主对比国外发言人我国三位女发言人真的错了吗?为什么会在短短时间内,就有三位中国女发言人被大家批判呢,首先是李少莉,因妆容服饰过于精致,用了两件奢侈品牌的配饰,就被当做了网爆的开端,引起一股风波。李少莉妆容精致接着换成朴素的张李少莉事件都在等结果,听听小区阿姨怎么说最近网上热议的那个精致耳钉姐,火了这么久,大家都在静等她的调查结果!结果没出来前,还是那句话,清者自清,浊者自浊!说回大家热议的核心问题,想要知道什么样的结果呢?无非就是想知道她的明明人老珠黄,非要尬演少女,这些女星我都替她羞有人说得体,在中年演员身上真的是难得的品质。比如说袁泉,在我的前半生中,她饰演的职场女高官唐晶,穿着一身利落的西装,走起路来都带风。不会花里胡哨,虽然有女二的玛丽苏恋爱戏码,但是永你扎发好看还是披发好看?从这3点分析照做,想不美都难秋日生活打卡季有人说,美丽是一个储存罐,只要在每个细节上努力,就一定会看到成效。在生命鲜活青春美好的年岁,我们又怎能让美丽缺席呢?塑造更优秀美好的自己,那就从头开始吧!先解开被发型运动鞋大衣秋冬最时髦洋气搭配,不挑年纪不挑身材大衣一直是秋冬季的首选,无论是时尚感还是保暖度,它都名列前茅。往期文章为大家分享了许多挑选大衣以及大衣与内搭之间的搭配技巧,但大家千万不要忘了,穿搭是要看整体的。想要穿搭整体完整和