fuchsia devfs分析

devfs设备文件系统,主要负责fuchsia中管理的设备在本地文件系统中文件节点的呈现。其文件路径为“/dev”。
1.devfs目录构建

devfs随着devmgr进程的启动而初始化。通过“devmgr::devfs_init”函数,初始化一个devfs目录,主要两点:
  1.class目录树的创建(包含所有ddk/protodefs.h文件中定义的不带“PF_NOPUB”flag的协议);
  2.devfs的rpc“基础设施”搭建(创建一对channel,在其中一端等待,另一端保存在全局变量g_devfs_root中,并按需传递给需要访问devfs的进程)

devmgr中还会直接发布(devfs_publish)misc、sys和test三个目录到dev目录下。
devfs_publish函数在发布设备到相应目录下之后还会通过ipc通知该目录的watcher。

接着,devmgr通过调用devmgr_vfs_init函数,安装/dev、/svc和/system目录到devmgr进程的namespace中。

最后,在驱动程序的循环加载中发布设备到相应目录。

2.devfs的rpc处理

DcIostate继承自AsyncLoopOwnedRpcHandler类,用于devfs的rpc请求处理。
在devmgr::devfs_init中会调用DcIostate::Create方法,实例化DcIostate类,并设置为在devfs的本地端channel上等待。
当其他进程通过获取的devfs远端channel向devfs发送message时,DcIostate::HandleRpc会被调用,进而会调用DcIostate::DevfsFidlHandler对message进行处理。
目前支持的操作码包括:
fuchsia_io_NodeCloneOrdinal :克隆指定patch的node节点;msg中会传入一个client的handle,devfs会在此handle上等待后续消息处理
fuchsia_io_NodeDescribeOrdinal :获取node info
fuchsia_io_DirectoryOpenOrdinal :open node节点,最终会调用ddk框架中设备的open方法
fuchsia_io_NodeGetAttrOrdinal : 获取node的attr
fuchsia_io_DirectoryRewindOrdinal :Rewind,读取的目录路径回到根目录
fuchsia_io_DirectoryReadDirentsOrdinal :读
fuchsia_io_DirectoryWatchOrdinal :添加监控(watcher)
fuchsia_io_DirectoryAdminQueryFilesystemOrdinal :获取文件系统信息(返回“devfs”)
fuchsia_io_NodeIoctlOrdinal :遗留,不支持

需要注意的是,devfs只是提供设备句柄的clone、open以及其他一些属性的获取,而真正跟驱动设备的交互则是在设备的devhost中(open的时候会将client端的handle传给设备devhost以建立数据通道)。也就是devfs只是管理与设备控制面的东西,而真正与设备驱动的数据面交互,则在devhost中

3.部分源码注释::
devmgr的main函数{
devmgr::devfs_init //入口;根据传入的device,初始化一个devfs目录(主要两点:class目录树的创建;devfs的rpc基础设施搭建)
    root_devnode = std::make_unique<Devnode>("");
    root_devnode->ino = 1;
    prepopulate_protocol_dirs
        devfs_mkdir(root_devnode.get(), "class") //创建class目录(目录关联的device为null),ino为2
        【devfs_mkdir(class_devnode.get(), info.name)】//循环在class目录下创建所有不带“PF_NOPUB”flag的protocol节点;TODO:为什么只看到几个?!
    zx::channel::create //两个channel句柄:h0、h1
    DcIostate::Create(root_devnode.get(), dispatcher, &h0) //DcIostate类继承自AsyncLoopOwnedRpcHandler,实现devfs的rpc处理
        std::make_unique<DcIostate>(dn)
        ios->set_channel(std::move(*ipc)); //设置等待对象为channel——h0
        DcIostate::BeginWait //开始在channel上等待
    g_devfs_root = std::move(h1); //全局变量保存devfs的通信句柄
    
devfs_publish //调用三次,分别发布misc、sys、test
    devfs_mknode
   【proto_dir //获取设备对应的protocolID(代表设备发布的协议,并在class目录下创建相应文件节点)
    devfs_lookup //这里查找、并从“000”~“999”中选出一个唯一的子node名字
    devfs_mknode //创建子node节点,并将原设备的link属性设置为此class子node节点
    】//如果是misc、sys及test的根设备会跳过这段
    devfs_advertise 
        devfs_notify //向watcher发送fuchsia_io_WATCH_EVENT_ADDED,通知其已经添加了设备节点(class和dev节点) //TODO:watcher在哪里添加?

devmgr_vfs_init
    fdio_ns_get_installed //获取安装的根目录“/”
    fdio_ns_bind //安装/dev、/svc和/system目录

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值