zoukankan      html  css  js  c++  java
  • Linux嵌入式 -- 内核

    1. 什么是proc文件系统?
    实例:通过 /proc/meminfo,查询当前内存使用情况。

    结论:proc文件系统是一种在用户态检查内核状态的机制。


    2.Proc文件分类


    特点
     每个文件都规定了严格的权限可读?可写?哪个用户可读?哪个用户可写?
     可以用文本编辑程序读取(more命令,cat命令,vi程序等等)
     不仅可以有文件,还可以有子目录。
     可以自己编写内核程序添加一个/proc目录下的文件。
     文件的内容都是动态创建的,并不存在于磁盘上,存在内存中。


    3. 功能函数

    内核描述
    struct proc_dir_entry{
    {
    。。 。。。。。。。。。。。。。。。。。
    read_proc_t  *read_proc;
    write_proc_t  *write_proc;
    。。。。。。。。。。。。。。。。。。。
    }

    创建文件
    struct proc_dir_entry* create_proc_entry (const char  *name,mode_t mode,struct proc_dir_entry *parent)
    功能:创建proc文件
    参数:
     name:要创建的文件名
     mode:要创建的文件的属性 默认0755
     parent:这个文件的父目录

    创建目录
    struct proc_dir_entry * proc_mkdir (const char *name,struct proc_dir_entry *parent)
    功能:创建proc目录
    参数:
     name:要创建的目录名

     parent:这个目录的父目录

    删除目录/文件
    void remove_proc_entry (const char *name,struct proc_dir_entry *parent)
    功能:删除proc目录或文件
    参数:
     name:要删除的文件或目录名
     parent:所在的父目录

    读写 为了能让用户读写添加的proc文件,需要挂接上读写回调函数: read_proc 和 write_proc

    读操作
    int read_func (char *buffer,char**stat,off_t off,int count,int *peof,void *data)
    参数:
     buffer:把要返回给用户的信息写在buffer里,最大不超过PAGE_SIZE
     stat:一般不使用
     off:偏移量
     count:用户要取的字节数
     peof:读到文件尾时,需要把*peof置1
     data:一般不使用

    写操作
    int write_func (struct file*file,const char *buffer,unsigned long count,void*data) //提供用户的写操作
    参数:
     file :该proc文件对应的file结构,一般忽略。
     buffer :待写的数据所在的位置
     count :待写数据的大小
     data :一般不使用

    4. 实现流程
    实现一个proc文件的流程:
    (1)调用create_proc_entry创建一个struct proc_dir_entry。
    (2)对创建的struct proc_dir_entry进行赋值:read_proc,mode,owner,size,write_proc 等等。


    5.实例一

    #include<linux/kernel.h>
    #include<linux/init.h>
    #include<linux/proc_fs.h>
    #define procfs_name "proctest"  // /proc目录下创建的文件名
    
    struct proc_dir_entry *Our_Proc_File;  //结构体,create_proc_entry返回一个指针给他
    
    int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data ) //回调函数,对应写操作
    {
    	int ret;
    	ret = sprintf(buffer, "HelloWorld!
    ");
    	return ret;
    }
    
    int proc_init()
    {
    	Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL);
    	if(Our_Proc_File == NULL)
    	{
    		remove_proc_entry(procfs_name, NULL);
    		printk(KERN_ALERT"Error: Could not init /proc/%s
    ", procfs_name);
    		return -ENOMEM;
    	}
    	Our_Proc_File->read_proc = procfile_read;  //回调函数
    	Our_Proc_File->mode = S_IFREG | S_IRUGO;
    	Our_Proc_File->uid = 0;
    	Our_Proc_File->gid = 0;
    	Our_Proc_File->size = 37;
    	printk("/proc/%s created 
    ", procfs_name);
    	return 0;
    }
    
    void proc_exit()
    {
    	remove_proc_entry(procfs_name, NULL);
    	printk(KERN_INFO"/proc/%s removed 
    ", procfs_name);
    }
    
    module_init(proc_init);
    module_exit(proc_exit);
    


    5. 实例二 (由1修改为 能够 echo xxx > /proc/proctest)

    #include<linux/kernel.h>
    #include<linux/init.h>
    #include<linux/proc_fs.h>
    #include<linux/uaccess.h>
    #define procfs_name "proctest"
    
    struct proc_dir_entry *Our_Proc_File;
    static char msg[255];  //输入保存数组
    
    int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data )
    {
    	//int ret;
    	//ret = sprintf(buffer, "HelloWorld!
    ");
    	
    	int len = strlen(msg);
    	if(offset >= len)
    		return 0;
    	if(buffer_length > len-offset)
    		buffer_length = len - offset;
    	memcpy(buffer+offset, msg+offset, buffer_length);
    	return offset+buffer_length;
    }
    
    int procfile_write(struct file *file, const char __user *buffer, unsigned long count, void *data)  //提供给用户输入信息,控制内核。
    {
    	unsigned long count2 = count;
    	if(count2 >= sizeof(msg))
    		count2 = sizeof(msg)-1;
    	if(copy_from_user(msg, buffer, count2))
    		return -EFAULT;
    	msg[count2] = '';
    	return count;	
    }
    
    int proc_init()
    {
    	Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL);
    	if(Our_Proc_File == NULL)
    	{
    		remove_proc_entry(procfs_name, NULL);
    		printk(KERN_ALERT"Error: Could not init /proc/%s
    ", procfs_name);
    		return -ENOMEM;
    	}
    	Our_Proc_File->read_proc = procfile_read;
    	Our_Proc_File->write_proc = procfile_write;
    	Our_Proc_File->mode = S_IFREG | S_IRUGO;
    	Our_Proc_File->uid = 0;
    	Our_Proc_File->gid = 0;
    	Our_Proc_File->size = 37;
    	printk("/proc/%s created 
    ", procfs_name);
    	return 0;
    }
    
    void proc_exit()
    {
    	remove_proc_entry(procfs_name, NULL);
    	printk(KERN_INFO"/proc/%s removed 
    ", procfs_name);
    }
    
    module_init(proc_init);
    module_exit(proc_exit);

    echo xxxx > /proc/proctest

    cat  /proc/proctest

    makefile

    ifneq ($(KERNELRELEASE),)
    
    obj-m :=proc.o
    
    else
    
    KDIR := /lib/modules/3.5.0-17-generic/build
    all: 
        make -C $(KDIR) M=$(PWD) modules
    clean:
        rm -f *.ok *.o *.mod.o *.mod.c *.symvers
    endif
    





  • 相关阅读:
    js 复杂研究
    js 页面 保持状态 的方法
    C# 向上取整数
    js 获取dom 为null 测试
    net core 下 接受文件 测试
    layui 源码解读(部分)
    js 定时器
    js addEventListener
    C# 获得对象的命名空间 ?.
    修改maven的默认jdk版本
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648229.html
Copyright © 2011-2022 走看看