首页 > 代码库 > Linux 内核编程 or 内核模块编程的文件读写与信号传输问题

Linux 内核编程 or 内核模块编程的文件读写与信号传输问题

    Linux内核编程时,内核代码执行只能直接访问内存上的数据,硬盘上的文件系统必须通过间接的方式才能被内核读写。一般内核操作文件读写的方式有三种:1.通过/proc/文件作为桥梁完成硬盘文件系统与内核的交互;2.通过ioctl方式实现交互;3.直接利用虚拟文件系统的函数vfs_read()、vfs_write()读写文件。三种方式的具体实现方法网上有很多详细教程,可以参考。这里对三种方法做出比较。

    proc机制是一种很老的文件读写方式,通用性好,实现也算成熟,使用时需要自己实现内核上层的读写函数,不算复杂,但稍显繁琐,一大优势是用户空间程序可以实时通过/proc向内核层发送信号指令,/proc/文件被用户空间程序写入文字的瞬间,内核读函数自动被触发调用,可以实现对内核模式、参数的控制目的。下面是一段可被触发的内核读函数代码,里面有对信号的判断:

static int proc_signal_write(struct file *file, const char __user *buffer,
                unsigned long count, void *data)
{
        char procfs_buffer[PROCFS_BUF_MAX_SIZE];        
	
	if(count>PROCFS_BUF_MAX_SIZE)
		count = PROCFS_BUF_MAX_SIZE;

        if (copy_from_user(procfs_buffer, buffer, count)) 
        {
                return -EFAULT;
        }
	
	if(procfs_buffer[0]=='0')
		signal = 0;

	if(procfs_buffer[0]=='1')
		signal = 1;

	if(procfs_buffer[0]=='2')
	{
		delete_WhiteList(WLhead);
		WLend = WLhead;
	}

        return count;
}

    ioctl机制和 Windows 下的内核通信机制很相似,也可以实现信号的传输与控制,实现代码较多,编写起来比较繁琐,但使用起来比较方便,不再多说。

    虚拟文件系统方法,是三种方法中,文件读写最简单、最方便的,核心代码函数使用就像普通用户空间程序的读写函数,但是该方法无法实现用户空间命令对内核空间的触发或控制信号传输,使用上要注意,虚拟文件系统与硬盘上的文件系统在内存映射时需要做转换,一段使用例子如下:

struct file *fp;
mm_segment_t fs;
loff_t pos;

fp = filp_open("/usr/error_log",O_WRONLY | O_APPEND| O_CREAT,0644);
if(IS_ERR(fp))
{
	printk("create file error\n");
	return ;
}

fs = get_fs();
set_fs(KERNEL_DS);

pos = 0;
		
vfs_write(fp, "   ", 3, &pos);
vfs_write(fp, hash_val, strlen(hash_val), &pos);
vfs_write(fp, "   ", 3, &pos);	
vfs_write(fp, hash_name, strlen(hash_name), &pos);
vfs_write(fp, "\n", 1, &pos);	

filp_close(fp,NULL);
set_fs(fs);