kernel中__init等宏总结

关于__init__initdata__exit__exitdata及类似的宏

打开Linux Kernel源代码树中的文件:include/init.h,可以看到有下面的宏定议:

#define __init  __attribute__ ((__section__ (".init.text")))  __cold
#define __initdata    __attribute__ (( __section__ (".init.data")))
#define __exitdata   __attribute__ (( __section__ (".exit.data")))
#define __exit_call  __attribute_used__ __attribute__ (( __section__ (".exitcall.exit")))
#define __init_refok  oninline __attribute__ ((__section__ (".text.init.refok")))
#define __initdata_refok __attribute__ ((__section__ (".data.init.refok")))
#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok")))

.........

#ifdef MODULE
#define __exit  __attribute__ (( __section__ (".exit.text"))) __cold
#else
#define __exit __attribute_used__ __attribute__ ((__section__ (".exit.text"))) __cold
#endif

__init__initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链接脚本来指导ld完成的。
对编译成module的代码和数据来说,当模块加载时,__init属性的函数就被执行;
对静态编入内核的代码和数据来说,当内核引导时,do_basic_setup()函数调用do_initcalls()函数,后者负责所有.init节函数的执行。

关于__attribute__

要了解Linux Kernel代码的分段信息,需要了解一下gcc的__attribute__的编绎属性或定义的函数或数,__attribute__主要用于改变所声明据的特性,它有很多子项,用于改变作用对象的特性。比如对函数,noline将禁止进行内联扩展、noreturn表示没有返回值、pure表明函数除返回值外,不会通过其它(如全局变量、指针)对函数外部产生任何影响。但这里对代码段起作用是子项section。

__attribute__的section子项的使用格式为:

__attribute__((section("section_name")))

其作或用是将作用的函数数据放入指定名为”section_name”输入段。

这里还要注意一下两个概念:输入段和输出段

输入段和输出段是相对于要生成最终的elf或binary时的Link过程说的,Link过程的输入大都是由源代码编绎生成的目标文件.o,那么这些.o文件中包含的段相对link过程来说就是输入段,而Link的输出一般是可执行文件elf或库等,这些输出文件中也包含有段,这些输出文件中的段就叫做输出段。输入段和输出段本来没有什么必然的联系,是互相独立,只是在Link过程中,Link程序会根据一定的规则(这些规则其实来源于Link Script),将不同的输入段重新组合到不同的输出段中,即使是段的名字,输入段和输出段可以完全不同。

其用法举例如下:

int  var __attribute__((se
kthread_create和kernel_thread都是用于创建内核线程的函数。 kthread_create是一个相对正式的创建函数,它会创建一个kthread_create_info结构体,并将其挂接到kthread_create_list链表上。然后,通过调用wake_up_process(kthreadd_task)来唤醒内核线程kthreadd,使其开始运行内核线程。 而kernel_thread函数则可以用于创建内核线程,但在执行函数里面必须使用daemonize来释放资源并将线程挂到init进程下,并且还需要使用completion来等待整个过程的完成。为了简化操作,定义了kthread_create函数,它能够自动完成这些步骤。创建的线程不会立即运行,而是等待调度器将其加入运行队列。 总结来说,kthread_create是一种较为正式的创建内核线程的方式,而kernel_thread则是更底层的创建函数,需要手动处理一些资源释放和线程挂载的操作。使用kthread_create可以简化线程创建的过程,并将线程挂在kthread线程下。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [2021-04-10 Linux内核线程 kernel_thread、kthread_create、 kthread_run kthread_should_stop()](https://blog.csdn.net/qq_37858386/article/details/115573565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [kthread_create与kernel_thread的区别](https://blog.csdn.net/conceptcon/article/details/9177339)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [基于内核线程的创建、使用和退出以及延时的补充说明介绍](https://download.csdn.net/download/weixin_38686041/13781487)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值