linux2.6.24以后的内核将对符号表进行清理,去除一些符号,主要是2.6.24中导出为
EXPORT_UNUSED_SYMBOL 或 EXPORT_UNUSED_SYMBOL_GPL的符号。
例如:fs/open.c中的sys_open系统调用在内核源代码中是这样导出的:
EXPORT_UNUSED_SYMBOL_GPL(sys_open); /* To be deleted for 2.6.25 */
而且,当在2.6.24内核中编写模块的时候,如果使用这些函数,将会出现如
WARNING: modpost: module abc.ko uses symbol 'sys_open' marked UNUSED之类的警告。
或者在更高内核版本中会出现:
WARNING: "sys_open" undefined!之类的警告。
归根结底就是在模块中使用系统调用会出现这类问题!
其实,kernel 2.4.x及以前导出syscall比较简单,但kernel
2.5.21以后由于安全原因无法再直接导出syscall,因为在module中使用syscall是非常危险而且没有必要的,这些应该是在用户空间中做的事,在正常的module编程中任何情况下都不应该使用syscall.
都已经在内核中了,不见得非要再用系统调用,一般情况下 filp_open() 配合 struct file 里的 read/write 即可实现sys_open、sys_write系统调用的功能。也可以在深入 VFS 或者实际文件系统来调用更底层的函数。
这里给出一个例子:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#define MY_FILE "/var/log.txt "
char buf[128];
struct file *file = NULL;
static int __init init(void)
{
mm_segment_t old_fs;
printk( "Hello, I 'm the module that intends to write messages to file.\n ");
if(file == NULL)
file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT,0644);
if (IS_ERR(file)) {
printk( "error occured while opening file %s, exiting...\n ",
MY_FILE);
return 0;
}
sprintf(buf, "%s ", "The Messages.");
old_fs = get_fs();
set_fs(KERNEL_DS);
file-> f_op-> write(file, (char *)buf, sizeof(buf), &file-> f_pos);
set_fs(old_fs);
return 0;
}
static void __exit fini(void)
{
if(file != NULL)
filp_close(file, NULL);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE( "GPL ");
|
阅读(3684) | 评论(0) | 转发(0) |