zoukankan      html  css  js  c++  java
  • 调试技术(/proc、/sys、/dev、strace)

    一、在/proc中实现文件

    当某个进程读取我们的/proc文件时,内核会分配一个内存页,即PAGE_SIZE字节的内存块。
    驱动程序可以将数据通过这个内存页返回到用户空间。

    第一种方法,不采用seq_file
    
    int write_proc(struct file *file, const char *buffer, size_t count, loff_t *ppos){
    
    }
    
    int read_proc(struct file *file, char *buffer, size_t count, loff_t *ppos){
    
    }
    
    static const struct file_operations proc_fops = {
    	.write = write_proc,
    	.read = read_proc
    };
    
    proc_create("name", 0660, NULL, &gt_upgrade_proc_fops);
    
    第二种方法,采用seq_file
    
    1.先实现seq_operations中的四个方法。
    static const struct seq_operations my_seq_ops = {
    	.start	= pfkey_seq_start,
    	.next	= pfkey_seq_next,
    	.stop	= pfkey_seq_stop,
    	.show	= pfkey_seq_show,
    };
    
    2.构造一个file_operation结构
    
    只要构造一个open函数即可,其他的均使用默认函数。
    static int my_seq_open(struct inode *inode, struct file *file)
    {
    	return seq_open(file, &my_seq_ops);
    }
    
    static const struct file_operations my_proc_ops = {
    	.open	 = my_seq_open,
    	.read	 = seq_read,
    	.llseek	 = seq_lseek,
    	.release = seq_release,
    };
    
    3.创建文件
    proc_create("name", 0, null, &pfkey_proc_ops);
    

    二、strace命令

    strace命令是一个功能非常强大的工具,它可以显示由用户空间程序发出的所有系统调用。
    它不仅可以显示调用,而且还能显示调用参数以及用符号形式表示的返回值。

    命令行选项:
    -t: 显示调用发生的时间;
    -T: 显示调用所花费的时间;
    -e: 限定被跟踪的调用类型;
    -o: 将输出重定向到一个文件中。

    strace可以跟踪一个正在运行的进程。

    三、设备文件的创建

    不要与在sysfs下创建访问节点相互混淆,这个仅仅是为了在/sys/class 目录下生成相应的文件,供uevent机制自动生成/dev下的设备文件;
    后面会介绍创建sysfs下访问节点的方法。

    static struct class *my_class;
    struct device* temp;
    my_class = class_create(THIS_MODULE, "class_name");
    temp = device_create(my_class, misc->parent, dev, misc, "%s", misc->name);
    
    根据创建的device就可以自动生成/dev目录下的设备文件
    
    #define class_create(owner, name)		{		//仅仅是个宏而已
      __class_create(owner, name, &__key);{
        __class_register(cls, key);{
          kset_register(&cp->subsys);{
            kobject_add_internal(&k->kobj);{
              create_dir(kobj);{
                sysfs_create_dir(kobj);
                populate_dir(kobj);{
                  sysfs_create_file(kobj, attr);
                }
              }
            }
          }
          add_class_attrs(class_get(cls));{
            class_create_file(cls, &cls->class_attrs[i]);{
              sysfs_create_file(&cls->p->subsys.kobj, &attr->attr);
            }
          }
        }
      }
    }
    device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);		//函数原型
    

    修改自动创建的设备节点的权限、所有者和所属组:
    修改system/core/rootdir/ueventd.rc文件即可,在其中加入将要创建的设备节点的相关属性。
    例:
    /dev/stpgps 0660 gps gps

    四、/sys下创建属性文件的方法:

    在已有的目录下创建属性文件:

    /************************************************************/
    该方法创建驱动的属性,一般存放在/sys/bus/platform/drivers/相应驱动/目录下面
    int driver_create_file(struct device_driver *drv, const struct driver_attribute *attr);
      sysfs_create_file(&drv->p->kobj, &attr->attr);
    	
    /************************************************************/
    该方法创建设备的属性,一般存放在/sys/devices/相应设备/目录下面。
    int device_create_file(struct device *dev, const struct device_attribute *attr);
      sysfs_create_file(&dev->kobj, &attr->attr);
    

    在/sys/目录下创建新的目录,并创建默认的属性文件:

    /************************************************************/
    ssize_t mtk_uart_attr_show(struct kobject *kobj, struct attribute *attr, char *buffer) 
    {
        struct mtuart_entry *entry = container_of(attr, struct mtuart_entry, attr);
        return entry->show(kobj, buffer);
    }
    
    ssize_t mtk_uart_attr_store(struct kobject *kobj, struct attribute *attr, const char *buffer, size_t size) 
    {
        struct mtuart_entry *entry = container_of(attr, struct mtuart_entry, attr);
        return entry->store(kobj, buffer, size);
    }
    
    struct sysfs_ops mtk_uart_sysfs_ops = {
        .show   = mtk_uart_attr_show,
        .store  = mtk_uart_attr_store,
    };
    
    struct mtuart_entry {
        struct attribute attr;
        ssize_t (*show)(struct kobject *kobj, char *page);
        ssize_t (*store)(struct kobject *kobj, const char *page, size_t size);
    };
    
    struct mtuart_entry conse_entry = {
        { .name = "conse", .mode = S_IRUGO | S_IWUSR },
        mtk_uart_conse_show,
        mtk_uart_conse_store,
    };
    
    ....
    
    struct attribute *mtk_uart_attributes[] = {
        &conse_entry.attr,  /*console setting*/
    #if defined(ENABLE_DEBUG)        
        &debug_entry.attr,
        &sysrq_entry.attr,
        &vffsz_entry.attr,
        &vff_en_entry.attr,
        &lsr_status_entry.attr,
        &history_entry.attr,
    #endif     
        NULL,
    };
    
    struct kobj_type mtk_uart_ktype = {
        .sysfs_ops = &mtk_uart_sysfs_ops,
        .default_attrs = mtk_uart_attributes,
    };
    
    struct mtuart_sysobj {
        struct kobject kobj;
        atomic_t sysrq;
        atomic_t vffLen[UART_NR*UART_VFIFO_NUM];
        atomic_t console_enable;
    } mtk_uart_sysobj = {
        .console_enable = ATOMIC_INIT(1),
    };
    
    struct mtuart_sysobj *obj = &mtk_uart_sysobj;
    obj->kobj.parent = kernel_kobj;
    kobject_init_and_add(&obj->kobj, &mtk_uart_ktype, NULL, "mtuart");{
      kobject_add_varg(kobj, parent, fmt, args);{
        kobject_add_internal(kobj);{
          create_dir(kobj);{
            sysfs_create_dir(kobj);
            populate_dir(kobj);{
              sysfs_create_file(kobj, attr);
            }
          }
        }
      }
    }
    	
    
  • 相关阅读:
    nagios安装配置
    Nagios:企业级系统监控方案
    使用Maven搭建Struts2+Spring3+Hibernate4的整合开发环境
    SecureCRT最佳配色方法+直接修改默认配置方法
    highcharts插件使用总结和开发中遇到的问题及解决办法
    关于Highcharts图表组件动态修改属性的方法(API)总结之Series
    Linux中环境变量文件及配置
    使用正则表达式匹配任意字符包括空格和换行符
    设置mysql远程连接root权限
    java读取文件夹下所有文件并替换文件每一行中指定的字符串
  • 原文地址:https://www.cnblogs.com/hei-da-mi/p/6066376.html
Copyright © 2011-2022 走看看