简介

英特尔管理引擎(Intel ME)是位于某些英特尔芯片组内部的隔离和受保护的计算资源(协处理器)。英特尔 ME 提供对计算机/IT 管理和安全功能的支持。实际的功能集取决于英特尔芯片组 SKU。

英特尔管理引擎接口(Intel MEI,以前称为 HECI)是主机和英特尔 ME 之间的接口。此接口作为 PCI 设备暴露给主机,实际上可能会暴露多个 PCI 设备。英特尔 MEI 驱动程序负责主机应用程序和英特尔 ME 功能之间的通信通道。

每个英特尔 ME 功能或英特尔 ME 客户端都由唯一的 GUID 寻址,并且每个客户端都有自己的协议。该协议是基于消息的,具有标头和有效负载,最大字节数取决于客户端在连接时所公布的最大值。

英特尔 MEI 驱动程序

该驱动程序公开一个字符设备,设备节点为 /dev/meiX。

当 /dev/meiX 打开时,应用程序会保持与英特尔 ME 功能的通信。通过调用 MEI_CONNECT_CLIENT_IOCTL 来执行与特定功能的绑定,该调用传递所需的 GUID。可以同时打开的英特尔 ME 功能实例的数量取决于英特尔 ME 功能,但大多数功能只允许单个实例。

该驱动程序对于在固件功能和主机应用程序之间传递的数据是透明的。

由于某些英特尔 ME 功能可以更改系统配置,因此默认情况下,驱动程序只允许特权用户访问它。

通过调用 close(fd) 来终止会话。

用于与英特尔 AMTHI 客户端通信的应用程序代码片段

为了支持虚拟化或沙箱,受信任的监管者可以使用 MEI_CONNECT_CLIENT_IOCTL_VTAG 来创建具有英特尔 ME 功能的虚拟通道。并非所有功能都支持虚拟通道,此类客户端将返回 EOPNOTSUPP。

struct mei_connect_client_data data;
fd = open(MEI_DEVICE);

data.d.in_client_uuid = AMTHI_GUID;

ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);

printf("Ver=%d, MaxLen=%ld\n",
       data.d.in_client_uuid.protocol_version,
       data.d.in_client_uuid.max_msg_length);

[...]

write(fd, amthi_req_data, amthi_req_data_len);

[...]

read(fd, &amthi_res_data, amthi_res_data_len);

[...]
close(fd);

用户空间 API

IOCTL:

英特尔 MEI 驱动程序支持以下 IOCTL 命令

IOCTL_MEI_CONNECT_CLIENT

连接到固件功能/客户端。

Usage:

struct mei_connect_client_data client_data;

ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &client_data);

Inputs:

struct mei_connect_client_data - contain the following
Input field:

        in_client_uuid -        GUID of the FW Feature that needs
                                to connect to.
 Outputs:
        out_client_properties - Client Properties: MTU and Protocol Version.

 Error returns:

        ENOTTY  No such client (i.e. wrong GUID) or connection is not allowed.
        EINVAL  Wrong IOCTL Number
        ENODEV  Device or Connection is not initialized or ready.
        ENOMEM  Unable to allocate memory to client internal data.
        EFAULT  Fatal Error (e.g. Unable to access user input data)
        EBUSY   Connection Already Open
注意:

客户端属性中的 max_msg_length (MTU) 描述了可以发送或接收的最大数据量。(例如,如果 MTU=2K,则可以发送最大 2k 字节的请求,并接收最大 2k 字节的响应)。

IOCTL_MEI_CONNECT_CLIENT_VTAG:

Usage:

struct mei_connect_client_data_vtag client_data_vtag;

ioctl(fd, IOCTL_MEI_CONNECT_CLIENT_VTAG, &client_data_vtag);

Inputs:

struct mei_connect_client_data_vtag - contain the following
Input field:

        in_client_uuid -  GUID of the FW Feature that needs
                          to connect to.
        vtag - virtual tag [1, 255]

 Outputs:
        out_client_properties - Client Properties: MTU and Protocol Version.

 Error returns:

        ENOTTY No such client (i.e. wrong GUID) or connection is not allowed.
        EINVAL Wrong IOCTL Number or tag == 0
        ENODEV Device or Connection is not initialized or ready.
        ENOMEM Unable to allocate memory to client internal data.
        EFAULT Fatal Error (e.g. Unable to access user input data)
        EBUSY  Connection Already Open
        EOPNOTSUPP Vtag is not supported

IOCTL_MEI_NOTIFY_SET

启用或禁用事件通知。

Usage:

        uint32_t enable;

        ioctl(fd, IOCTL_MEI_NOTIFY_SET, &enable);


        uint32_t enable = 1;
        or
        uint32_t enable[disable] = 0;

Error returns:


        EINVAL  Wrong IOCTL Number
        ENODEV  Device  is not initialized or the client not connected
        ENOMEM  Unable to allocate memory to client internal data.
        EFAULT  Fatal Error (e.g. Unable to access user input data)
        EOPNOTSUPP if the device doesn't support the feature
注意:

必须连接客户端才能启用通知事件

IOCTL_MEI_NOTIFY_GET

检索事件

Usage:
        uint32_t event;
        ioctl(fd, IOCTL_MEI_NOTIFY_GET, &event);

Outputs:
        1 - if an event is pending
        0 - if there is no even pending

Error returns:
        EINVAL  Wrong IOCTL Number
        ENODEV  Device is not initialized or the client not connected
        ENOMEM  Unable to allocate memory to client internal data.
        EFAULT  Fatal Error (e.g. Unable to access user input data)
        EOPNOTSUPP if the device doesn't support the feature
注意:

必须连接客户端并且必须启用事件通知才能接收事件

支持的芯片组

82X38/X48 Express 及更新版本

linux-mei@linux.intel.com