zoukankan      html  css  js  c++  java
  • (五) proc文件系统

    proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取proc文件时,proc文件系统是动态从系统内核读出所需信息并提交的。主要目录结构如下:

    apm 高级电源管理信息

    cmdline 内核命令行

    Cpuinfo 关于Cpu信息

    Devices 可以用到的设备(块设备/字符设备)

    Dma 使用的DMA通道

    Filesystems 支持的文件系统

    Interrupts 中断的使用

    Ioports I/O端口的使用

    Kcore 内核核心印象

    Kmsg 内核消息

    Ksyms 内核符号表

    Loadavg 负载均衡

    Locks 内核锁

    Meminfo 内存信息

    Misc 杂项

    Modules 加载模块列表

    Mounts 加载的文件系统

    Partitions 系统识别的分区表

    Rtc 实时时钟

    Slabinfo Slab池信息

    Stat 全面统计状态表

    Swaps 对换空间的利用情况

    Version 内核版本

    Uptime 系统正常运行时间

    外,在/proc下还有三个很重要的目录:net,scsi和sys。 Sys目录是可写的,可以通过它来访问或修改内核的参数(见下一部分),而net和scsi则依赖于内核配置。例如,如果系统不支持scsi,则scsi 目录不存在。

     

    重点:

    除了以上介绍的这些,还有的是一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程都有对应的一个目录在/proc下,以进程的 PID号为目录名,它们是读取进程信息的接口,这个里面有很多虚拟文件表示进程的信息。而self目录则是读取进程本身的信息接口,是一个link。这些信息在程序调试的时候很有,尤其是性能测试的时候,有些时候尤其在嵌入式开发领域,可用赢家资源较少,这就要求程序的性能至关重要。

     

    在每一个进程子目录下主要包括以下文件

    1>  cmdline — 启动当前进程的完整命令,但僵尸进程目录中的此文件不包含任何信息    eg: $more /proc/2674/cmdline

    2> cwd — 指向当前进程运行目录的一个符号链接

    3> environ — 当前进程的环境变量列表,彼此间用空字符(NULL)隔开;变量用大写字母表示,其值用小写字母表示;

    4> exe — 指向启动当前进程的可执行文件(完整路径)的符号链接,通过/proc/N/exe可以启动当前进程的一个拷贝;

    5> fd — 这是个目录,包含当前进程打开的每一个文件的文件描述符(file descriptor),这些文件描述符是指向实际文件的一个符号链接;

    6> limits — 当前进程所使用的每一个受限资源的软限制、硬限制和管理单元;此文件仅可由实际启动当前进程的UID用户读取;(2.6.24以后的内核版本支持此功能);

    7> maps — 当前进程关联到的每个可执行文件和库文件在内存中的映射区域及其访问权限所组成的列表;

    8> mem — 当前进程所占用的内存空间,由open、read和lseek等系统调用使用,不能被用户读取;

    9> root — 指向当前进程运行根目录的符号链接;在Unix和Linux系统上,通常采用chroot命令使每个进程运行于独立的根目录;

    10> stat — 当前进程的状态信息,包含一系统格式化后的数据列,可读性差,通常由ps命令使用;

    11> statm — 当前进程占用内存的状态信息,通常以“页面”(page)表示;

    12> status — 与stat所提供信息类似,但可读性较好,如下所示,每行表示一个属性信息;其详细介绍请参见 proc的man手册页;

    13> task — 目录文件,包含由当前进程所运行的每一个线程的相关信息,每个线程的相关信息文件均保存在一个由线程号(tid)命名的目录中,这类似于其内容类似于每个进程目录中的内容;(内核2.6版本以后支持此功能).

     

    一个虚拟设备驱动访问的例子来自博客http://blog.chinaunix.net/uid-26390723-id-3143694.html

     

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/errno.h>
    #include <linux/proc_fs.h>
    #include <asm/uaccess.h>
    
    #define     MAX_BUFFER_SIZE     256
    #define     AXP192_PROC_FILE    "driver/axp192"
    
    static u8 buff[MAX_BUFFER_SIZE];
    static struct proc_dir_entry *axp192_proc_file;
    static int index;
    
    static void axp192_write(int index, u8 reg_val)
    {
        buff[index] = reg_val;
    }
    
    static void axp192_read(int index, u8 *reg_val)
    {
        *reg_val = buff[index];
    }
    
    static ssize_t axp192_proc_read(struct file *filp,
            char *buffer, size_t length, loff_t *offset)
    {
        u8 reg_val;
    
        if ((index < 0) || (index > MAX_BUFFER_SIZE))
            return 0;
    
        axp192_read(index, &reg_val);
        printk(KERN_INFO "register 0x%x: 0x%x
    ", index, reg_val);
        return 0;
    }
    
    static ssize_t axp192_proc_write(struct file *filp,
            const char *buff, size_t len, loff_t *off)
    {
        u8 reg_val;
        char messages[256], vol[256];
    
        if (len > 256)
            len = 256;
    
        if (copy_from_user(messages, buff, len))
            return -EFAULT;
    
        if ('-' == messages[0]) {
            /* set the register index */
            memcpy(vol, messages+1, len-1);
            index = (u8) simple_strtoul(vol, NULL, 16);
        } else {
            /* set the register value */
            reg_val = (u8)simple_strtoul(messages, NULL, 16);
            axp192_write(index, reg_val & 0xFF);
        }
    
        return len;
    }
    
    static struct file_operations axp192_proc_ops = 
    {
        .read = axp192_proc_read,
        .write = axp192_proc_write,
    };
    
    static void create_axp192_proc_file(void)
    {
        printk("setup proc control interface
    ");
        axp192_proc_file = create_proc_entry(AXP192_PROC_FILE, 0644, NULL); //注册设备驱动路径
        
        if (axp192_proc_file)   //设置设备驱动程序回调函数
        {
            axp192_proc_file->proc_fops = &axp192_proc_ops; 
        }
        else    
            printk(KERN_INFO "proc file create failed!
    ");
    }
    
    static void remove_axp192_proc_file(void)
    {
       
    
    
    static int __init axp192_init(void)
    {
        printk("---AXP192_init
    ");
        create_axp192_proc_file();
        return 0;
    }

      在虚拟机中insmod成功后,在/proc/driver下将会生成名为axp192的文件。

      对其进行读写操作

      1> echo "-0x21" > axp192 

         cat axp192


      2> echo "0x78" > axp192  

         cat axp192

      3>  执行 $dmesg -c 查看内核输出信息,步骤1没有设置值 步骤2设置了。

  • 相关阅读:
    截取字符串
    VC++ PathFindFileName函数,由文件路径获得文件名
    获取GetOpenFileName多选文件名
    WideCharToMultiByte和MultiByteToWideChar函数的用法(转载)
    map set iterator not incrementable 解决办法
    定义c/c++全局变量/常量几种方法的区别(转载)
    如何禁止同IP站点查询和同IP站点查询的原理分析 Robots.txt屏蔽BINGBOT
    JavaScript 文件操作方法详解
    nginx日志配置
    php的strip_tags,htmlspecialchars,htmlentities,stripslashes,addslashes解释
  • 原文地址:https://www.cnblogs.com/wolfrickwang/p/3268164.html
Copyright © 2011-2022 走看看