我正在花时间研究Linux内核源代码,并找到了混乱的根源。在头文件/usr/src/linux-headers-3.2.0-4-common/include/linux/fs.h
中存在以下内容;
2183 static inline void unregister_chrdev(unsigned int major, const char *name)
2184 {
2185 __unregister_chrdev(major, 0, 256, name);
2186 }
除了__unregister_chrdev()
和/proc/kallsyms
之外,我找不到Module.symvers
的任何定义。
foo@bar:/usr/src$ cat /proc/kallsyms | grep "__unregister_chrdev$"
ffffffff810fd400 T __unregister_chrdev
foo@bar:/usr/src$
foo@bar:/usr/src$ grep -R '__unregister_chrdev' *
linux-headers-3.2.0-4-amd64/Module.symvers:0x6bc3fbc0 __unregister_chrdev vmlinux EXPORT_SYMBOL
linux-headers-3.2.0-4-common/include/linux/fs.h:extern void __unregister_chrdev(unsigned int major, unsigned int baseminor,
linux-headers-3.2.0-4-common/include/linux/fs.h: __unregister_chrdev(major, 0, 256, name);
foo@bar:/usr/src$
据我所知,内联函数将用函数中定义的内容替换自身的调用,但在这种情况下,内容本身就是对新函数的调用。这是否意味着我可以直接以某种方式调用__unregister_chrdev(major, 0, 256, name)
而不会改变任何重要内容?这里发生了什么?
答案 0 :(得分:1)
内部函数或其原型的名称可能会更改。
你应该总是打电话给外部人员。
优化版本会将此视为宏,并有效地调用内部函数。
答案 1 :(得分:0)
char_dev.c http://lxr.free-electrons.com/source/fs/char_dev.c#L331
/ ** * __unregister_chrdev - 取消注册并销毁cdev
取消注册并销毁占据
@major,@ baseminor和@count。这个功能撤消了什么
void __unregister_chrdev(unsigned int major,unsigned int baseminor, unsigned int count,const char * name)
{
struct char_device_struct *cd;
cd = __unregister_chrdev_region(major, baseminor, count);
if (cd && cd->cdev)
cdev_del(cd->cdev);
kfree(cd);
}
内联函数通常位于头文件中,因为编译器只能内联源代码而不是目标代码。内联由编译器完成,而不是链接器,它必须在源代码而不是目标文件上完成。
gcc可以自由地忽略对内联函数的任何此类请求,以及没有关键字的内联函数。 https://www.kernel.org/doc/local/inline.html