QNX资源管理器

QNX相关历史文章:

  • QNX简介
  • QNX Neutrino微内核
  • QNX IPC机制
  • QNX进程管理器

1. Introduction

QNX Neutrino允许用户编写进程充当资源管理器,并且可以动态的启动和停止。这样的好处是可以降低系统在运行时的内存需求,并且可以灵活的应对定制化嵌入式系统中的各种设备。

资源管理器通常负责向各类设备提供接口,这些设备可能涉及管理实际的硬件设备(比如串口、并口、网卡或磁盘驱动器)或虚拟设备(比如/dev/null、网络文件系统、伪ttys等)

在其他操作系统中,这个功能通常与设备驱动程序相关联,与设备驱动程序不同的是资源管理器不需要与内核进行耦合,看起来更像是用户级程序。

2. What is a resource manager?

资源管理器是用户级的服务器程序,它接收来自其他程序的请求服务,并可选的与硬件进行通信。QNX Neutrino强大和灵活的本地IPC机制,可以让资源管理器与内核解耦合。

由于QNX Neutrino是一个分布式微内核操作系统,几乎所有非内核功能都由用户可安装的程序提供,因此客户端程序与资源管理器之间需要一个定义清晰与良好的接口,并对资源管理器的功能进行文档化。

在路径名空间映射中,进程管理器会将路径名和资源管理器进行映射绑定,比如串口可以由资源管理器devc-ser*管理,但是实际的路径名空间中名称为dev/ser1,可以通过打开dev/ser1来获取串口服务。

2.1 Why write a resource manager?

编写一个资源管理器有以下几个原因:

  • 客户端使用POSIX接口与资源管理器通信;
  • 可以减少接口类型的数量,当有很多服务器进程时,将服务器进程都编写成资源管理器,可以最大化减少客户端需要使用的接口数量;
  • 可以使用命令行工具与资源管理器通信,比如cat /proc/my_status,也可以使用命令去测试驱动程序;

2.2 The types of resource managers

一般可以将资源管理器分为两类:

  • 设备资源管理器
  • 文件系统资源管理器
  1. 设备资源管理器
    设备资源管理器只在文件系统中创建单个文件条目,每个条目都向进程管理器注册,每个名称通常代表一个设备。

  2. 文件系统资源管理器
    文件系统资源管理器会向进程管理器注册一个挂载点,挂载点是注册到进程管理器中的路径的一部分。路径的其他部分由文件系统资源管理器管理。比如挂载点是/mount,路径是/mount/home/thomasf,由进程管理器来标识/mount,而由文件系统管理器来标识home/thomasf

2.3 Communication via native IPC

当一个资源管理器绑定好对应的路径名后,它便可以收到客户端的请求信息了,比如io_openio_read等。
客户端程序与资源管理器之间的所有通信都是通过本机IPC消息传递完成的,它有许多独特的功能:

  • 定义良好的应用程序接口,客户端与资源管理器分工明确;
  • 资源管理器的接口简单,与OS交互也是通过本地IPC,不需要担心其他模块的影响;
  • 网络传递,底层原生IPC机制本质是网络分布式的,程序可以无缝的访问网络中其他节点的资源;

所有QNX Neutrino的设备驱动程序和文件系统都是作为资源管理器实现的,这意味着“原生”QNX Neutrino设备驱动程序或文件系统能做的一切,用户编写的资源管理器也能做到。

3. Resource manager architecture

资源管理器的核心如下:

initialize the dispatch interface
register the pathname with the process manager
DO forever
    receive a message
    SWITCH on the type of message
        CASE io_open:
            perform io_open processing
            ENDCASE
        CASE io_read:
            perform io_read processing
            ENDCASE
        CASE io_write:
            perform io_write processing
            ENDCASE
        .   // etc. handle all other messages
        .   // that may occur, performing
        .   // processing as appropriate
    ENDSWITCH
ENDDO

资源管理器架构包括三部分:

  1. 创建一个通道,以便客户端程序可以连接到资源管理器上,并发送消息;
  2. 资源管理器需要向进程管理器注册路径名,以便能在对该特定的路径名请求打开时,能解析到该资源管理器;
  3. 接收并处理消息;
    每个资源管理器都需要消息处理功能(上文代码中的switch/case部分),QNX Neutrino提供了一组库函数来方便的处理这个功能,当然也能处理其他关键功能。

3.1 Message types

资源管理器会收到两种类型的消息:

  • connect messages,客户端在操作路径名时(比如io_open)时会发送连接消息,这可能会涉及到权限检查(客户端是否有打开设备的权限),并为该请求设置上下文;
  • I/O messages,基于上下文(客户端和资源管理器之间创建的)来发送I/O消息,比如io_read

3.2 The resource manager shared library

QNX Neutrino提供了一下共享库,可以让资源管理器编写变得相对简单一点。

  1. 自动默认消息处理
    当资源管理器不想处理某些消息时,可以使用默认的动作,目前有两个级别的默认动作:
  • 给客户端返回ENOSYS,表明不支持特定功能;
  • iofunc_*()共享库,允许资源管理器自动处理多种功能;
    由于资源管理器接收的大量消息都处理一组公共属性,iofunc_*共享库允许资源管理器自动处理stat()chmod()chown()lseek()等函数,无需再编写额外代码。有三个主要的结构需要考虑:
  • context,保存每次打开时使用的数据,例如文件中的当前位置(lseek()偏移量);
  • attributes structure,保存每个设备的数据,例如设备所有者的用户和组ID、最后修改时间等;
  • mount structure,对于文件系统管理器来说,需要mount structure,包含对整个挂载设备都可全局访问的数据项;


    QNX资源管理器_第1张图片
    A resource manager is responsible for three data structures

当有多个客户端程序在特定资源上打开多种设备时,数据结构如下图:


QNX资源管理器_第2张图片
Multiple clients opening various devices

iofunc_*()默认函数的运行假设是:使用了context块和attribute结构的默认定义,这是一个可靠的假设,原因有二:

  • 默认的context和attribute结构为大多数应用程序提供了足够的信息;
  • 如果默认结构没有包含足够的信息,它们可以封装在自定义的结构中;
    在自定义数据结构时,需要把attribute的结构放在前边,以便iofunc_attr_t *()函数能使用,如下图:
    QNX资源管理器_第3张图片
    图片.png
  1. 资源管理器共享库提供了跟踪open()/dup()/close()消息的默认处理函数,并且只对最后一个close执行操作;

  2. 多线程处理
    QNX Neutrino提供多线程,可以基于这个来构造资源管理器,多个线程等待消息并同时处理它们。资源管理器共享库不仅可以跟踪创建的线程数量和等待线程的数量,还负责维护最佳的线程数量。

  3. dispatch功能
    操作系统提供一套`dispatch*函数集,可用于:

  • 给需要多种消息类型的资源管理器和客户端提供一个公共阻塞点;
  • 给没有绑定到资源管理器的消息类型提供灵活的接口;
  • 在线程中将阻塞和处理代码解耦合;
  1. Combine messages
    QNX支持将IO消息或connect消息组合成一个消息,从而进行一些类似原子性的操作。比如通过将io_lseekio_read消息组合成一个消息,资源管理器在收到这个消息时,readblock()函数就会允许线程去原子性的执行lseek()read()操作。

Summary

你可能感兴趣的:(QNX资源管理器)