Libdrm完全解析7 - 完全ソースコード解析(4)

前回記事:libdrm sixの完全解析 ~ ソースコードの完全解析(3)からの続きです。

この記事は次のブログ投稿を参照しています。

DRMドライバー開発(VKMS)

どうもありがとうございます!

この記事では引き続き、include/drm/drm.h での実際の関数マクロ定義について説明します。

5. DRM_IOCTL_GET_MAP

5 番目のマクロは DRM_IOCTL_GET_MAP で、対応するコードは次のとおりです。

#define DRM_IOCTL_GET_MAP               DRM_IOWR(0x04, struct drm_map)

前の記事の _IOWR(type,nr,size) の最終定義と組み合わせると、次のコードが得られます。

#define DRM_IOCTL_GET_MAP		( ((3)  << 30) | (('d') << 8) | ((0x04)   << 0) | ((sizeof(struct drm_map)) << 16) )

struct drm_map は同じファイル (include/drm/drm.h) で定義されており、コードは次のとおりです。

/*
 * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
 * argument type.
 *
 * \sa drmAddMap().
 */
struct drm_map {
	unsigned long offset;	 /**< Requested physical address (0 for SAREA)*/
	unsigned long size;	 /**< Requested physical size (bytes) */
	enum drm_map_type type;	 /**< Type of memory to map */
	enum drm_map_flags flags;	 /**< Flags */
	void *handle;		 /**< User-space: "Handle" to pass to mmap() */
				 /**< Kernel-space: kernel-virtual address */
	int mtrr;		 /**< MTRR slot used */
	/*   Private data */
};

drm_map_type と drm_map_flags の定義は次のように一番上にあります。

/*
 * Type of memory to map.
 */
enum drm_map_type {
	_DRM_FRAME_BUFFER = 0,	  /**< WC (no caching), no core dump */
	_DRM_REGISTERS = 1,	  /**< no caching, no core dump */
	_DRM_SHM = 2,		  /**< shared, cached */
	_DRM_AGP = 3,		  /**< AGP/GART */
	_DRM_SCATTER_GATHER = 4,  /**< Scatter/gather memory for PCI DMA */
	_DRM_CONSISTENT = 5	  /**< Consistent memory for PCI DMA */
};

/*
 * Memory mapping flags.
 */
enum drm_map_flags {
	_DRM_RESTRICTED = 0x01,	     /**< Cannot be mapped to user-virtual */
	_DRM_READ_ONLY = 0x02,
	_DRM_LOCKED = 0x04,	     /**< shared, cached, locked */
	_DRM_KERNEL = 0x08,	     /**< kernel requires access */
	_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
	_DRM_CONTAINS_LOCK = 0x20,   /**< SHM page that contains lock */
	_DRM_REMOVABLE = 0x40,	     /**< Removable mapping */
	_DRM_DRIVER = 0x80	     /**< Managed by driver */
};

drm_map 構造体の各メンバーの意味コード コメントは明確に記述されているため、ここで繰り返す必要はありません。

DRM_IOCTL_GET_MAP に対応するユーザー空間 API は、drmGetMap() です。この関数は xf86drm.c にもあり、コードは次のとおりです。

drm_public int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
                         drmMapType *type, drmMapFlags *flags,
                         drm_handle_t *handle, int *mtrr)
{
    drm_map_t map;

    memclear(map);
    map.offset = idx;
    if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
        return -errno;
    *offset = map.offset;
    *size   = map.size;
    *type   = (drmMapType)map.type;
    *flags  = (drmMapFlags)map.flags;
    *handle = (unsigned long)map.handle;
    *mtrr   = map.mtrr;
    return 0;
}

この関数の役割は、メモリ マップ (マップ) に関する情報を取得することです。この機能については、後ほど機能を詳しく説明する際に詳しく解析していきます。まずはお互いのことを知り、印象を持ってみましょう。

6. DRM_IOCTL_GET_CLIENT

6 番目のマクロは DRM_IOCTL_GET_CLIENT で、対応するコードは次のとおりです。

#define DRM_IOCTL_GET_CLIENT            DRM_IOWR(0x05, struct drm_client)

前の記事の _IOWR(type,nr,size) の最終定義と組み合わせると、次のコードが得られます。

#define DRM_IOCTL_GET_CLIENT		( ((3)  << 30) | (('d') << 8) | ((0x05)   << 0) | ((sizeof(struct drm_client)) << 16) )

struct drm_client は同じファイル (include/drm/drm.h) で定義されており、コードは次のとおりです。

/*
 * DRM_IOCTL_GET_CLIENT ioctl argument type.
 */
struct drm_client {
	int idx;		/**< Which client desired? */
	int auth;		/**< Is client authenticated? */
	unsigned long pid;	/**< Process ID */
	unsigned long uid;	/**< User ID */
	unsigned long magic;	/**< Magic */
	unsigned long iocs;	/**< Ioctl count */
};

drm_client 構造体の各メンバーの意味コード コメントは明確に記述されているため、ここで繰り返す必要はありません。

DRM_IOCTL_GET_CLIENT に対応するユーザー空間 API は drmGetClient() です。この関数は xf86drm.c にもあり、コードは次のとおりです。

drm_public int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
                            unsigned long *magic, unsigned long *iocs)
{
    drm_client_t client;

    memclear(client);
    client.idx = idx;
    if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
        return -errno;
    *auth      = client.auth;
    *pid       = client.pid;
    *uid       = client.uid;
    *magic     = client.magic;
    *iocs      = client.iocs;
    return 0;
}

この関数の機能は、現在の DRM デバイス上のすべてのクライアント プロセスを取得することです。この機能については、後ほど機能を詳しく説明する際に詳しく解析していきます。まずはお互いのことを知り、印象を持ってみましょう。

残りのマクロ定義については、後続の記事で引き続き分析します。

おすすめ

転載: blog.csdn.net/phmatthaus/article/details/132468240