前回記事:libdrm sixの完全解析 ~ ソースコードの完全解析(3)からの続きです。
この記事は次のブログ投稿を参照しています。
どうもありがとうございます!
この記事では引き続き、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 デバイス上のすべてのクライアント プロセスを取得することです。この機能については、後ほど機能を詳しく説明する際に詳しく解析していきます。まずはお互いのことを知り、印象を持ってみましょう。
残りのマクロ定義については、後続の記事で引き続き分析します。