Linux DRM - 코어 초기화와 드라이버 등록

How Linux DRM comes up: drm_core_init registers major number 226, and a driver such as vkms creates its /dev/dri nodes through drm_dev_init and drm_dev_register in Linux v6.19.
October 27, 2026

Linux DRM - 코어 초기화와 드라이버 등록

Reqruies
  • Kernel: Linux v6.19 소스 기준
  • 선행 글: Linux DRM 1편 구조와 전체 그림

Introduction

편주제
1편구조와 전체 그림
1편에서 DRM의 구조(drm_driver → drm_device → drm_minor → drm_file)와 장치 노드를 봤습니다. 이 글에서는 그 구조가 코드에서 어떻게 만들어지는지를 두 단계로 따라갑니다. 부팅 때 DRM core가 주 번호 226을 예약하는 것, 그리고 드라이버(여기서는 가상 드라이버 vkms)가 장치를 만들고 /dev/dri/card0, renderD128을 등록하는 것입니다.

Code Flow 1: DRM Core Initialization

DRM은 커널이 부팅될 때 한 번 초기화됩니다. 여기서 앞서 본 주 번호 226이 등록됩니다.
drivers/gpu/drm/drm_drv.c - drm_core_init() (L1236-1272)
c
drm_sysfs_init()이 /sys/class/drm 클래스를 만들고, register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops)가 /proc/devices의 226 drm 줄을 만듭니다. 이 시점에는 어떤 장치도 없습니다. 주 번호 226 전체를 DRM이 예약하고, 모든 open()을 받는 "stub" 파일 연산 하나를 등록한 것뿐입니다.

Code Flow 2: The Driver Registers the Device

이제 드라이버가 나설 차례입니다. vkms로 보겠습니다. 먼저 드라이버가 정의한 drm_driver입니다.
drivers/gpu/drm/vkms/vkms_drv.c - vkms_driver (L92-102)
c
DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM, 그리고 DEFINE_DRM_GEM_FOPS로 만든 fops가 전부입니다. 이 드라이버를 등록하는 함수는 vkms_create()입니다.
drivers/gpu/drm/vkms/vkms_drv.c - vkms_create() (L159-220)
c
드라이버 등록 흐름 (vkms 기준)
Mermaid
sequenceDiagram participant D as 드라이버 (vkms_create) participant C as DRM core participant S as sysfs · devtmpfs · udev D->>C: devm_drm_dev_alloc(&vkms_driver) C->>C: drm_dev_init()<br/>drm_minor_alloc(RENDER, PRIMARY)<br/>drm_gem_init() D->>C: drm_vblank_init() D->>C: vkms_modeset_init()<br/>(plane · CRTC · connector 등록) D->>C: drm_dev_register() C->>C: drm_minor_register(RENDER)<br/>drm_minor_register(PRIMARY) C->>S: device_add(minor->kdev) S-->>S: /dev/dri/card0 (226:0)<br/>/dev/dri/renderD128 (226:128)

Step 1: Allocation and Initialization (drm_dev_init)

devm_drm_dev_alloc()은 내부의 devm_drm_dev_init()을 거쳐 drm_dev_init()을 부릅니다. 여기서 driver_features를 보고 minor를 만들고, GEM을 초기화합니다.
drivers/gpu/drm/drm_drv.c - drm_dev_init() (L701-796)
c
DRIVER_RENDER가 있으면 render minor를, 항상 primary minor를 만듭니다. minor 하나를 만드는 drm_minor_alloc()은 번호를 뽑고(xa_alloc) sysfs용 struct device(kdev)까지 준비합니다.
drivers/gpu/drm/drm_drv.c - drm_minor_alloc() (L142-172)
c

Step 2: Registration (drm_dev_register)

드라이버가 KMS 객체까지 준비하고 나면 drm_dev_register()를 부릅니다. 이 순간부터 유저가 장치를 열 수 있습니다.
drivers/gpu/drm/drm_drv.c - drm_dev_register() (L1056-1126)
c
drm_minor_register()가 device_add()로 sysfs에 등록하고, minor 번호 표(xa_store)를 채웁니다. 나중에 open()이 이 표로 minor를 찾습니다.
drivers/gpu/drm/drm_drv.c - drm_minor_register() (L174-212)
c

Code Locations

단계함수위치 (Linux v6.19)
부팅: DRM core 초기화 (주 번호 226 등록)drm_core_init()drivers/gpu/drm/drm_drv.c
부팅: stub open (fops 교체)drm_stub_open()drivers/gpu/drm/drm_drv.c
드라이버: 장치 할당과 minor 생성drm_dev_init()drivers/gpu/drm/drm_drv.c
드라이버: minor 번호와 sysfs 장치drm_minor_alloc()drivers/gpu/drm/drm_drv.c
드라이버: card%d / renderD%d 이름drm_sysfs_minor_alloc()drivers/gpu/drm/drm_sysfs.c
드라이버: 등록 (/dev/dri 노드 생성)drm_dev_register()drivers/gpu/drm/drm_drv.c
드라이버: minor를 sysfs에 등록drm_minor_register()drivers/gpu/drm/drm_drv.c

Summary

이 Post 에서 확인한 것은 다음과 같습니다.
  • core 초기화: drm_core_init()이 주 번호 226을 등록하고, 모든 open()을 받는 stub fops를 둡니다.
  • 드라이버 등록: devm_drm_dev_alloc() → drm_dev_init()(minor 번호 할당) → drm_dev_register() → drm_minor_register() → device_add()로 /dev/dri/card0, renderD128이 생깁니다.
노드가 생겼으니 이제 유저가 쓸 차례입니다. 다음에는 open()과 ioctl()이 커널 안에서 어떻게 처리되는지 봅니다.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.