Chinaunix首页 | 论坛 | 博客
  • 博客访问: 525157
  • 博文数量: 51
  • 博客积分: 345
  • 博客等级: 民兵
  • 技术积分: 534
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-21 12:02
个人简介

文章分类

全部博文(51)

文章存档

2023年(2)

2022年(1)

2021年(7)

2020年(10)

2019年(2)

2016年(20)

2015年(5)

2014年(1)

2011年(3)

我的朋友

分类: LINUX

2016-06-03 17:52:21

Linux:3.4.69
内核启动流程的相关代码分散在不同initcall段中,i2c也分为不同阶段来完成初始化;

首先在postcore_initcall 段中初始化i2c bus类型:
struct bus_type i2c_bus_type = {
    .name        = "i2c",
    .match        = i2c_device_match,
    .probe        = i2c_device_probe,
    .remove        = i2c_device_remove,
    .shutdown    = i2c_device_shutdown,
    .pm        = &i2c_device_pm_ops,
};

static int __init i2c_init(void)
{
    int retval;

    retval = bus_register(&i2c_bus_type);    //注册i2c类型的bus;创建目录/sys/bus/i2c/, /sys/bus/i2c/devices, /sys/bus/i2c/drivers,  uevent, drivers_probe, drivers_autoprobe
    if (retval)
        return retval;
#ifdef CONFIG_I2C_COMPAT
    i2c_adapter_compat_class = class_compat_register("i2c-adapter");
    if (!i2c_adapter_compat_class) {
        retval = -ENOMEM;
        goto bus_err;
    }
#endif
    retval = i2c_add_driver(&dummy_driver);
    if (retval)
        goto class_err;
    return 0;
......
}

postcore_initcall(i2c_init);

接着是arch_initcall,
MACHINE_START(AVANTA_LP, "Marvell AvantaLP 88f66xx Board")
    .atag_offset    = BOOT_PARAMS_OFFSET,
    .map_io         = alp_map_io,
    .init_irq       = alp_irq_init,
    .timer          = &alp_timer,
    .handle_irq     = gic_handle_irq,
    .init_machine   = alp_board_init,
    .restart        = board_restart,
    .dma_zone_size    = SZ_64M,
MACHINE_END
#define MACHINE_START(_type,_name)            \
static const struct machine_desc __mach_desc_##_type    \
 __used                            \
 __attribute__((__section__(".arch.info.init"))) = {    \
    .nr        = MACH_TYPE_##_type,        \
    .name        = _name,

#define MACHINE_END                \
};

平台相关的i2c的调用流程:
alp_board_init-->alp_i2c_init

static void __init alp_i2c_init(void)
{
#ifdef CONFIG_I2C_MV64XXX
    if (mvUnitMapIsMine(I2C0) == MV_TRUE)
        platform_device_register(&alp_i2c0);

    if (mvCtrlSocUnitInfoNumGet(I2C_UNIT_ID) > 1 &&
        mvUnitMapIsMine(I2C1) == MV_TRUE)
        platform_device_register(&alp_i2c1);
#endif
}
可以看到这里注册了两个i2c设备;以alp_i2c0为例:
下面为i2c设备信息;

#define IRQ_GLOBAL_I2C0            34
#define IRQ_GLOBAL_I2C1            35

static struct mv64xxx_i2c_pdata alp_i2c_pdata = {
    .freq_m         = 8, /* assumes 166 MHz TCLK */
    .freq_n         = 3,
    .timeout        = 1000, /* Default timeout of 1 second */
};

static struct resource alp_i2c_0_resources[] = {
    {
        .name   = "i2c base",
        .start  = INTER_REGS_PHYS_BASE + MV_TWSI_SLAVE_REGS_OFFSET(0),
        .end    = INTER_REGS_PHYS_BASE + MV_TWSI_SLAVE_REGS_OFFSET(0) + 0x20 - 1,
        .flags  = IORESOURCE_MEM,
    },
    {
        .name   = "i2c irq",
        .start  = IRQ_GLOBAL_I2C0,
        .end    = IRQ_GLOBAL_I2C0,
        .flags  = IORESOURCE_IRQ,
    },
};

static struct platform_device alp_i2c0 = {
    .name           = MV64XXX_I2C_CTLR_NAME,    //"mv64xxx_i2c"
    .id             = 0,
    .num_resources  = ARRAY_SIZE(alp_i2c_0_resources),
    .resource       = alp_i2c_0_resources,
    .dev            = {
        .platform_data = &alp_i2c_pdata,
    },
};

platform_device_register-->platform_device_add    //add platform device to device hierarchy

int platform_device_add(struct platform_device *pdev)
{
    if (!pdev->dev.parent)
        pdev->dev.parent = &platform_bus;    //"platform", 

    pdev->dev.bus = &platform_bus_type;

    if (pdev->id != -1)
        dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);    //设备名 dev->kobj.name“mv64xxx_i2c.0
    else
        dev_set_name(&pdev->dev, "%s", pdev->name);
    for (i = 0; i < pdev->num_resources; i++) {
    /*检查分配resource是否合法*/
    }

    ret = device_add(&pdev->dev);
    if (ret == 0)
        return ret;
    ......
}

device_add    //add device to device hierarchy.

int device_add(struct device *dev)
{
      dev = get_device(dev);    //这样写的目的是增加设备引用计数

    if (!dev->p) {    //分配struct device_private    *p结构
        error = device_private_init(dev);
        if (error)
            goto done;
    }

    parent = get_device(dev->parent);    //同样是增加parent引用计数, “platform"
    kobj = get_device_parent(dev, parent);
    if (kobj)
        dev->kobj.parent = kobj;    //parent`s  kobj


    error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);    //创建/sys/devices/platform/mv64XXX_i2c.0节点
    if (error)
        goto Error;

    /*创建 /sys/devices/platform/mv64XXX_i2c.0/ 下的文件及链接 */


    if (dev->bus)
        blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
                         BUS_NOTIFY_ADD_DEVICE, dev);    //发送消息通知链

    kobject_uevent(&dev->kobj, KOBJ_ADD);    //uevent消息;

    bus_probe_device(dev);    //probe drivers for a new device
    if (parent)
        klist_add_tail(&dev->p->knode_parent,    //knode_parent建立device和parent的关联
                   &parent->p->klist_children);
}

自此平台相关i2c初始化已经完成了。

下面是内核本身对i2c设备操作所需要的驱动;主要是注册fops,与设备文件的读写,ioctl相关
drivers/i2c/i2c-dev.c


module_init(i2c_dev_init);

#define I2C_MAJOR    89

static const struct file_operations i2cdev_fops = {     //i2c设备的文件操作函数
    .owner        = THIS_MODULE,
    .llseek        = no_llseek,
    .read        = i2cdev_read,
    .write        = i2cdev_write,
    .unlocked_ioctl    = i2cdev_ioctl,
    .open        = i2cdev_open,
    .release    = i2cdev_release,
};

static int __init i2c_dev_init(void)
{
    res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);

    i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");    //创建设备类,/sys/class/i2c-dev/

    res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);    //注册消息通知链

    i2c_for_each_dev(NULL, i2cdev_attach_adapter);    //对i2c_bus_type总线上注册的设备调用i2cdev_attach_adapter, 此时还没有该类型总线设备;

}

接下来就是具体设备的i2c设备驱动;
我们是以Marvell平台为例:
路径: linux-3.4.69\drivers\i2c\busses\i2c-mv64xxx.c


static struct platform_driver mv64xxx_i2c_driver = {
    .probe    = mv64xxx_i2c_probe,
    .remove    = __devexit_p(mv64xxx_i2c_remove),
    .driver    = {
        .owner    = THIS_MODULE,
        .name    = MV64XXX_I2C_CTLR_NAME,      //#define MV64XXX_I2C_CTLR_NAME    "mv64xxx_i2c"
    },
};

module_platform_driver(mv64xxx_i2c_driver);
#define module_platform_driver(__platform_driver) \        //这个宏目的是对模块init和exit操作进行封装
    module_driver(__platform_driver, platform_driver_register, \
            platform_driver_unregister)
#define module_driver(__driver, __register, __unregister, ...) \
static int __init __driver##_init(void) \
{ \
    return __register(&(__driver) , ##__VA_ARGS__); \
} \
module_init(__driver##_init); \
static void __exit __driver##_exit(void) \
{ \
    __unregister(&(__driver) , ##__VA_ARGS__); \
} \
module_exit(__driver##_exit);


platform_driver_register     //为平台层的设备注册驱动

int platform_driver_register(struct platform_driver *drv)
{
    drv->driver.bus = &platform_bus_type;
    if (drv->probe)
        drv->driver.probe = platform_drv_probe;
    if (drv->remove)
        drv->driver.remove = platform_drv_remove;
    if (drv->shutdown)
        drv->driver.shutdown = platform_drv_shutdown;

    return driver_register(&drv->driver);
}

driver_register     //将driver与bus上对应设备相关联

int driver_register(struct device_driver *drv)
{
    int ret;
    struct device_driver *other;

    BUG_ON(!drv->bus->p);

    if ((drv->bus->probe && drv->probe) ||
        (drv->bus->remove && drv->remove) ||
        (drv->bus->shutdown && drv->shutdown))
        printk(KERN_WARNING "Driver '%s' needs updating - please use "
            "bus_type methods\n", drv->name);

    other = driver_find(drv->name, drv->bus);    //检查驱动是否已经注册过了,若注册了则other非NULL;
    if (other) {
        printk(KERN_ERR "Error: Driver '%s' is already registered, "
            "aborting...\n", drv->name);
        return -EBUSY;
    }

    ret = bus_add_driver(drv);    //add the driver to the bus
    if (ret)
        return ret;
    ret = driver_add_groups(drv, drv->groups);
    if (ret)
        bus_remove_driver(drv);
    return ret;
}


bus_add_driver     //

int bus_add_driver(struct device_driver *drv)
{
    。。。。。。
    bus = bus_get(drv->bus);

    priv = kzalloc(sizeof(*priv), GFP_KERNEL);    //驱动私有信息
    if (!priv) {
        error = -ENOMEM;
        goto out_put_bus;
    }
    klist_init(&priv->klist_devices, NULL, NULL);
    priv->driver = drv;
    drv->p = priv;    //priv与driver关联
    priv->kobj.kset = bus->p->drivers_kset;    //驱动kobject与bus的kset

    error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,    //在/sys/bus/platform/drivers/下创建目录
                     "%s", drv->name);
    if (error)
        goto out_unregister;

    if (drv->bus->p->drivers_autoprobe) {    //drivers_autoprobe默认为1
        error = driver_attach(drv);
        if (error)
            goto out_unregister;
    }
    klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);    //driver的klist_node结构,添加到bus对应的klist_drivers列表;
    module_add_driver(drv->owner, drv);
    。。。。。。
}

driver_attach     //try to bind driver to devices. 遍历bus上所有设备,查找到合法设备,关联driver并执行probe;

int driver_attach(struct device_driver *drv)
{
    return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);    //每个设备调用__driver_attach
}
static int __driver_attach(struct device *dev, void *data)
{
    if (!driver_match_device(drv, dev))    //调用platform_match,检查设备id 是否在驱动支持的id列表内;通过设备ID或者设备name来检测;
        return 0;

    if (dev->parent)    /* Needed for USB */
        device_lock(dev->parent);
    device_lock(dev);
    if (!dev->driver)    //driver为NULL, 说明没有加载过驱动
        driver_probe_device(drv, dev);
    device_unlock(dev);
    if (dev->parent)
        device_unlock(dev->parent);

    return 0;
}


driver_probe_device-->really_probe  //真正的probe动作

static int really_probe(struct device *dev, struct device_driver *drv)
{
    。。。。。。
    dev->driver = drv;    //设备关联驱动
    if (driver_sysfs_add(dev)) {    //生成sys下目录
        printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
            __func__, dev_name(dev));
        goto probe_failed;
    }

    if (dev->bus->probe) {   //bus无probe
        ret = dev->bus->probe(dev);
        if (ret)
            goto probe_failed;
    } else if (drv->probe) {
        ret = drv->probe(dev);    //调用驱动probe,这里是 mv64xxx_i2c_probe
        if (ret)
            goto probe_failed;
    }

    driver_bound(dev);     //设备关联到driver的klist_devices;

    。。。。。。
}


再来看一下设备驱动真实的probe过程:
mv64xxx_i2c_probe

static int __devinit
mv64xxx_i2c_probe(struct platform_device *pd)
{
    struct mv64xxx_i2c_data        *drv_data;    //设备对应驱动的私有信息
    struct mv64xxx_i2c_pdata    *pdata = pd->dev.platform_data;    //平台相关数据

    drv_data = kzalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL);
    if (!drv_data)
        return -ENOMEM;
   
    if (mv64xxx_i2c_map_regs(pd, drv_data)) {    //寄存器地址映射
        rc = -ENODEV;
        goto exit_kfree;
    }

    strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
        sizeof(drv_data->adapter.name));    //"mv64xxx_i2c adapter"

    /*初始化wait队列和自旋锁*/
    init_waitqueue_head(&drv_data->waitq);
    spin_lock_init(&drv_data->lock);


    /*私有数据初始化*/

    drv_data->freq_m = pdata->freq_m;
    drv_data->freq_n = pdata->freq_n;
    drv_data->irq = platform_get_irq(pd, 0);
    if (drv_data->irq < 0) {
        rc = -ENXIO;
        goto exit_unmap_regs;
    }
    drv_data->adapter.dev.parent = &pd->dev;    //parent为mv64xxx_i2c.0
    drv_data->adapter.algo = &mv64xxx_i2c_algo;
    drv_data->adapter.owner = THIS_MODULE;
    drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
    drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
    drv_data->adapter.nr = pd->id;    //i2c-%d
    platform_set_drvdata(pd, drv_data);    //pdev->dev->p->driver_data = drv_data;  设备私有信息中的驱动数据赋值;
    i2c_set_adapdata(&drv_data->adapter, drv_data);


    mv64xxx_i2c_hw_init(drv_data);    //硬件初始化

    if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,    /*注册中断处理函数,  若没有出错的话继续执行 else if*/
            MV64XXX_I2C_CTLR_NAME, drv_data)) {
        dev_err(&drv_data->adapter.dev,
            "mv64xxx: Can't register intr handler irq: %d\n",
            drv_data->irq);
        rc = -EINVAL;
        goto exit_unmap_regs;
    } else if ((rc = i2c_add_numbered_adapter(&drv_data->adapter)) != 0) {
        dev_err(&drv_data->adapter.dev,
            "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
        goto exit_free_irq;
    }
    。。。。。。
}
i2c_add_numbered_adapter -->i2c_register_adapter
static int i2c_register_adapter(struct i2c_adapter *adap)
{
    /*合法性检查*/
    ......
    dev_set_name(&adap->dev, "i2c-%d", adap->nr);
    adap->dev.bus = &i2c_bus_type;     //bus为  i2c
    adap->dev.type = &i2c_adapter_type;
    res = device_register(&adap->dev);    //注册设备, /sys/devices/platform/mv64xxx_i2c.0/i2c-0/    在device_add中,会调用i2c相关的bus通知链;即调用i2cdev_attach_adapter;    该设备会加入到i2c bus的bus->p->klist_drivers 
    if (res)
        goto out_list;

    
}

通知链处理函数
static int i2cdev_attach_adapter(struct device *dev, void *dummy)
{
    adap = to_i2c_adapter(dev);

    i2c_dev = get_free_i2c_dev(adap);    //每个i2c_dev代表一个i2c适配器
    if (IS_ERR(i2c_dev))
        return PTR_ERR(i2c_dev);

    /* register this i2c device with the driver core */
    i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,    //i2c-dev类i2c_dev_class,“i2c-dev”,最后还是会调用device_add
                     MKDEV(I2C_MAJOR, adap->nr), NULL,
                     "i2c-%d", adap->nr);
    ......
}

device_add会增加i2c_dev_class相关文件:
device_add-->get_device_parent-->class_dir_create_and_add //create a new class-directory at the parent device;  /sys/devices/platform/mv64xxx_i2c.0/i2c-0/i2c-dev

还创建了dev文件显示设备号:

   device_add

   if (MAJOR(dev->devt)) {
        error = device_create_file(dev, &devt_attr);
        if (error)
            goto ueventattrError;

        error = device_create_sys_dev_entry(dev);
        if (error)
            goto devtattrError;

        devtmpfs_create_node(dev);
    }
cat  /sys/devices/platform/mv64xxx_i2c.0/ i2c-0/i2c-dev/i2c-0/dev 

89:0


sys下相关文件
#ONT/system/shell>cat /proc/interrupts                                                     
           CPU0       CPU1       
 29:    3929395    3665693       GIC  twd
 34:     268898          0       GIC  mv64xxx_i2c
 35:          0          0       GIC  mv64xxx_i2c
 41:         16          0       GIC  alp_clk_evt
 44:       2668          0       GIC  serial
 48:          0          0       GIC  xhci-hcd:usb3
 49:          0          0       GIC  ehci_hcd:usb2
 50:          0          0       GIC  ehci_hcd:usb1
 54:          2          0       GIC  mv_xor.0
#ONT/system/shell>pwd
/sys/bus/i2c
#ONT/system/shell>ls -l
total 0
drwxr-xr-x    2 root     root             0 Jan  1 00:16 devices
drwxr-xr-x    3 root     root             0 Jan  1 00:16 drivers
-rw-r--r--    1 root     root          4096 Jan  1 00:16 drivers_autoprobe
--w-------    1 root     root          4096 Jan  1 00:16 drivers_probe
--w-------    1 root     root          4096 Jan  1 00:16 uevent


#ONT/system/shell>pwd
/sys/devices/platform/mv64xxx_i2c.0
#ONT/system/shell>
#ONT/system/shell>ls
driver     i2c-0      modalias   subsystem  uevent

#ONT/system/shell>cat i2c-0/name
mv64xxx_i2c adapter
#ONT/system/shell>ls i2c-0/i2c-dev
i2c-0
#ONT/system/shell>ls i2c-0/i2c-dev/i2c-0
dev        device     name       subsystem  uevent
#ONT/system/shell>cat  i2c-0/i2c-dev/i2c-0/name
mv64xxx_i2c adapter

#ONT/system/shell>pwd
/sys/bus/platform
#ONT/system/shell>
#ONT/system/shell>
#ONT/system/shell>
#ONT/system/shell>ls -l
total 0
drwxr-xr-x    2 root     root             0 Jan  1 05:15 devices
drwxr-xr-x   18 root     root             0 Jan  1 00:19 drivers
-rw-r--r--    1 root     root          4096 Jan  1 05:15 drivers_autoprobe
--w-------    1 root     root          4096 Jan  1 05:15 drivers_probe
--w-------    1 root     root          4096 Jan  1 05:15 uevent

#ONT/system/shell>ls -l devices
total 0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 alarmtimer -> ../../../devices/platform/alarmtimer
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 alp-temp.0 -> ../../../devices/platform/alp-temp.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 arm-pmu.0 -> ../../../devices/platform/arm-pmu.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 armada-nand.0 -> ../../../devices/platform/armada-nand.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 ehci_marvell.0 -> ../../../devices/platform/ehci_marvell.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 ehci_marvell.1 -> ../../../devices/platform/ehci_marvell.1
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv64xxx_i2c.0 -> ../../../devices/platform/mv64xxx_i2c.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv64xxx_i2c.1 -> ../../../devices/platform/mv64xxx_i2c.1
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_gpio.0 -> ../../../devices/platform/mv_gpio.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_pex.0 -> ../../../devices/platform/mv_pex.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_pp2_port.0 -> ../../../devices/platform/mv_pp2_port.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_pp2_port.1 -> ../../../devices/platform/mv_pp2_port.1
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_pp2_port.2 -> ../../../devices/platform/mv_pp2_port.2
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_pp2_port.3 -> ../../../devices/platform/mv_pp2_port.3
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_switch.0 -> ../../../devices/platform/mv_switch.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor.0 -> ../../../devices/platform/mv_xor.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor.1 -> ../../../devices/platform/mv_xor.1
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor.2 -> ../../../devices/platform/mv_xor.2
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor.3 -> ../../../devices/platform/mv_xor.3
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor_shared.0 -> ../../../devices/platform/mv_xor_shared.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mv_xor_shared.1 -> ../../../devices/platform/mv_xor_shared.1
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 mvsdio -> ../../../devices/platform/mvsdio
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 orion_wdt -> ../../../devices/platform/orion_wdt
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 pon -> ../../../devices/platform/pon
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 pp2 -> ../../../devices/platform/pp2
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 rtc-mv -> ../../../devices/platform/rtc-mv
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 serial8250 -> ../../../devices/platform/serial8250
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 serial8250.0 -> ../../../devices/platform/serial8250.0
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 tpm -> ../../../devices/platform/tpm
lrwxrwxrwx    1 root     root             0 Jan  1 05:15 xhci-hcd -> ../../../devices/platform/xhci-hcd
#ONT/system/shell>ls -l drivers
total 0
drwxr-xr-x    2 root     root             0 Jan  1 05:16 alarmtimer
drwxr-xr-x    2 root     root             0 Jan  1 05:16 arm-pmu
drwxr-xr-x    2 root     root             0 Jan  1 05:16 armada-nand
drwxr-xr-x    2 root     root             0 Jan  1 05:16 dw-apb-uart
drwxr-xr-x    2 root     root             0 Jan  1 05:16 ehci_marvell
drwxr-xr-x    2 root     root             0 Jan  1 00:19 mv64xxx_i2c
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_gpio
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_pex
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_pp2_port
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_switch
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_xor
drwxr-xr-x    2 root     root             0 Jan  1 05:16 mv_xor_shared
drwxr-xr-x    2 root     root             0 Jan  1 05:16 orion_wdt
drwxr-xr-x    2 root     root             0 Jan  1 05:16 physmap-flash
drwxr-xr-x    2 root     root             0 Jan  1 05:16 serial8250
drwxr-xr-x    2 root     root             0 Jan  1 05:16 xhci-hcd

 



阅读(11244) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~