부제: Intel Core Ultra 5 235H (Arrow Lake)와 MicroOS, 공식 문서에 없는 길을 뚫다

1. 들어가는 글 (Intro: 절망 속의 빛)

최근 홈랩 인프라를 대대적으로 리모델링했다.
기존 Ryzen 5800G 데스크탑 3대를 처분하고, 공간 효율의 끝판왕인 미니 PC 5대 클러스터로 이사를 감행했다.
새로운 멤버는 Intel Core Ultra 5 235H (Arrow Lake-H) 4대와, AMD Ryzen 6800H 1대.

이번 프로젝트의 핵심은 단연 Arrow Lake (235H) 4대다.
이 녀석들에 탑재된 Arc 140T iGPU 자원을 SR-IOV로 뼛속까지 발라 먹는 것이 목표였다.
하지만 현실은 냉혹했다. 리눅스 메인라인 커널은 아직 이 최신 칩셋을 제대로 지원하지 않았고, 순정 드라이버로는 가상화는 커녕 화면 띄우기도 버거웠다.

그 암흑 속에서 우리의 구세주(Savior)가 등장했으니, 바로 strongtz/i915-sriov-dkms 프로젝트다.
참조: https://github.com/strongtz/i915-sriov-dkms
이 포스팅은 이 구세주를 영접하여 Host(Proxmox)와 Guest(MicroOS) 모두에서 DKMS로 커널 모듈을 직접 빌드(Build)하고, SR-IOV를 성공시키는 과정을 담은 삽질 기록이다.

2. 잠깐! 용어 정리 (SR-IOV가 왜 좋을까?)

기존 AMD 장비들에서는 ‘PCIe Passthrough’ 방식을 썼다. 이건 “GPU 1개 = VM 1개”라는 등가교환이다.
그런데 이 교환, 대가가 너무 가혹하다.

  • PCIe Passthrough (기존 방식)
    • 비효율의 끝판왕: GPU를 받은 VM이 아무것도 안 하고 놀고 있어도, 다른 VM은 그 GPU를 절대 못 쓴다.
    • Host의 실명(失明): 더 큰 문제는 Host(Proxmox)조차 GPU를 뺏긴다는 점이다.
      서버에 모니터와 키보드를 연결해도 Proxmox 콘솔은 안 보이고, GPU를 가져간 VM의 화면만 덩그러니 뜬다.
    • Host에 GPU가 없어지므로 VM에 virtIO나 virtGL 같은것도 사용할수 없다. 이 가상 디스플레이는 host의 GPU가 필요하다
    • 즉, 하나의 VM에 PCIe passthrough를 하면 다른 VM은 2D 가속 조차 못하고 CPU로 화면을 출력해야한다
    • 최악의 시나리오: 만약 네트워크가 끊겨서 SSH 접속이 안 된다? 물리 콘솔도 VM이 먹어버렸으니 할 수 있는 게 없다.
      울며 겨자 먹기로 전원 버튼을 눌러 강제 종료하는 수밖에.
  • SR-IOV (Single Root I/O Virtualization, 이번 목표)
    • 1:N 연결 (뻥튀기): 물리적인 하드웨어 하나를 마치 여러 개의 독립적인 장치인 것처럼 가상화하는 기술이다.
      235H의 그래픽(Arc 140T) 하나를 쪼개서, 여러 VM이 동시에 나눠 먹을 수 있다.
    • Host도 함께: 물론 Host도 화면을 띄울 수 있고, 여러 VM이 동시에 가속 기능을 누릴 수 있다. 평화가 찾아온다.
  • PF (Physical Function) & VF (Virtual Function)
    • PF: ‘진짜’ 물리 장치 본체. 호스트가 관리한다.
    • VF: PF에서 파생된 ‘가상’ 장치. 우리는 이걸 여러 개 복사해서 VM들에 뿌려줄 것이다.
      VM들은 이걸 진짜 GPU라고 믿고 행복하게 돌아간다.

3. 핵심 포인트: Guest도 드라이버 빌드가 필요함

많은 사람들이(나 포함) 오해하는 부분인데, SR-IOV 구성 시 Host뿐만 아니라 Guest VM 내부에서도 전용 드라이버(i915-sriov-dkms)를 사용해야 한다.
README.md에 명확하게 적혀있다.
You need to install this dkms module in both host and guest!
참조: Linux Guest Installation Steps (Ubuntu 25.04/Kernel 6.14)

  • 메인라인 커널의 순정 드라이버(i915xe)는 아직 최신 Arrow Lake의 VF를 제대로 제어하지 못한다.
  • 따라서 VM 내부에서도 커널 모듈을 직접 빌드해서 올려줘야 비로소 가속이 붙는다.

4. Part 1: Host 설정 (Proxmox VE)

Proxmox VE는 데비안(Debian) 기반이라, 다행히 strongtz 님의 공식 가이드를 거의 그대로 따라가면 된다. 영어가 가득한 README를 정독하느라 현기증 낼 필요 없이, **핵심만 추려낸 ‘4단계 요약’**으로 빠르게 넘어가자.

1) 빌드 도구 및 커널 헤더 준비

가장 먼저 요리 재료(헤더)와 도구(컴파일러)를 챙겨야 한다.
저는 fish shell을 사용하기 때문에 bash에서 작동하지 않을수 있다!!

apt update && apt install 'build-*' dkms sysfsutils intel-gpu-tools && apt install proxmox-headers-6.17 proxmox-kernel-6.17

2) 소스코드 다운로드 및 DKMS 준비

우리의 구세주(i915-sriov-dkms)를 깃허브에서 모셔온다.

mkdir ~/i519-sriov
wget -O ~/i519-sriov/i915-sriov-dkms_2025.12.10_amd64.deb "https://github.com/strongtz/i915-sriov-dkms/releases/download/2025.12.10/i915-sriov-dkms_2025.12.10_amd64.deb"

3) 모듈 빌드 및 설치 (Build & Install)

이제 DKMS를 통해 커널 모듈을 실제로 구워낸다. 이 단계에서 에러가 없어야 한다.
모든 CPU를 사용하다보니 다른 서비스들에 지연이 생겨서 build 할때 사용하는 CPU 코어 수를 제한했다.

MAKEFLAGS="-j8" dpkg -i ~/i519-sriov/i915-sriov-dkms_2025.12.10_amd64.deb 

4) Grub 수정 및 드라이버 로드 설정

설치한 드라이버가 부팅 시 제대로 작동하도록, 커널 파라미터(iommuguC 등)를 수정한다. (Arrow Lake ID 7d51 강제 인식 옵션도 여기에 포함된다.)

나는 proxmox 부팅 디스크를 zfs로 설정했다.
그래서 grub이 아닌 systemd boot를 사용한다.
추가로 zfs bootmenu도 사용중이다.

zfs bootmenu는 proxmox 업데이트 하면서 덮어써지기 때문에 zfs boot menu와 systemd boot 모두에 kernel parameter를 수정해준다.
만약 zfs boot menu에만 구성해주면 추후 systemd boot가 업데이트 되면서 sr iov가 꺼질수 있다.

먼저 zfs boot menu에 kernel parameter를 추가해준다.

zfs set org.zfsbootmenu:commandline=" intel_iommu=on i915.enable_guc=3 i915.max_vfs=7 module_blacklist=xe i915.force_probe=7d51,7dd1 " rpool

다음으로 systemd boot에 parameter를 적용해준다.

nano /etc/kernel/cmdline 
# intel_iommu=on i915.enable_guc=3 i915.max_vfs=7 module_blacklist=xe i915.force_probe=7d51,7dd1  
proxmox-boot-tool refresh

5) 부팅할 때 자동으로 VFs를 활성화 해준다.

지금까지는 SR-IOV를 사용할 수 있는 i915 module을 빌드하고, 이 module을 사용하도록 설정해주었다.
이번에는 부팅할 때 자동으로 SR-IOV를 활성화 해주는 작업을 진행한다.

이것을 위해서 sysfsutils를 설치했다.

# 먼저 장치 ID를 확인한다. 
root@pve1:~#lspci | grep VGA

결과는 이런식으로 나온다.
00:02.0 VGA compatible controller: Intel Corporation Arrow Lake-P [Intel Graphics]
가장 앞의 00:02.0가 중요하다.

echo "devices/pci0000:00/0000:00:02.0/sriov_numvfs = 7" >> /etc/sysfs.conf
cat /etc/sysfs.conf

결과는 이렇게 나오면 정상이다.

#
# /etc/sysfs.conf - Configuration file for setting sysfs attributes.
#
# The sysfs mount directory is automatically prepended to the attribute paths.
# The attribute paths support glob(7) wildcard patterns.
#
# Syntax:
# attribute = value
# mode attribute = 0600 # (any valid argument for chmod)
# owner attribute = root:wheel # (any valid argument for chown)
#
# Examples:
#
# Always use the powersave CPU frequency governor
# devices/system/cpu/cpu0/cpufreq/scaling_governor = powersave
#
# Use userspace CPU frequency governor and set initial speed
# devices/system/cpu/cpu0/cpufreq/scaling_governor = userspace
# devices/system/cpu/cpu0/cpufreq/scaling_setspeed = 600000
#
# Set permissions of suspend control file
# mode power/state = 0660
# owner power/state = root:power
devices/pci0000:00/0000:00:02.0/sriov_numvfs = 7

6) 재부팅 및 확인

기도하는 마음으로 재부팅 후, 아래 명령어로 2 VFs가 보이는지 확인하자.

cat /sys/module/i915/parameters/max_vfs
cat /sys/bus/pci/devices/0000:00:02.0/sriov_numvfs
cat /sys/bus/pci/devices/0000:00:02.0/sriov_totalvfs
lspci -nn | grep VGA

실행 결과

7
7
7
00:02.0 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.1 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.2 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.3 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.4 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.5 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.6 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]
00:02.7 VGA compatible controller [0300]: Intel Corporation Arrow Lake-P [Intel Graphics] [8086:7d51]

5. Part 2: VM Hardware (Proxmox VE)

vm -> Harware -> Machine

Machine은 q35에 vIOMMU는 None으로 설정한다.

vm -> Hardware -> Add -> PCI Device

Raw device에서 추가 된 iGPU를 선택한다. .0으로 끝나는 장치는 PF(Physical Function)이므로 실수로도 연결하지 않도록 한다.

All Funcitons는 비활성화: 이걸 설정하면 상위 Funtion, PF(Physical Funtion)이 VM으로 들어가버릴수 있다.
Primary GPU 비활성화: 메인 출력이 이 GPU로 출력된다. console을 못볼 수 있다.
ROM-Bar 비활성화: VF이기 때문에 활성화 시에 문제가 될수 있다.
PCI-Express 활성화: 비활성화 하면 PCIe가 아닌 PCI 장치로 인식 된다.

6. Part 3: openSUSE microOS (Guest OS)

공식 깃허브 가이드의 apt 명령어를 zypper와 MicroOS 환경에 맞게 치환한 내용이다.

1) 빌드 의존성 패키지 설치

데비안의 build-essential에 대응하는 패키지들이다. MicroOS에서는 패턴(pattern)으로 설치하면 깔끔하다.

opensuse tumbleweed는 매일 매일 업데이트가 있다.
그래서 지금 linux kernel header를 설치하면 부팅 된 커널 버전에 맞는 headers가 설치 되지 않는다.
따라서 업데이트를 하고 설치를 진행한다.

fish

sudo transactional-update shell -d
zypper dup --details --allow-downgrade --allow-name-change --allow-vendor-change -y
zypper in -t pattern devel_kernel
zypper in dkms

2)빌드 전 필수 준비: 정확한 타겟 커널 추출하기

opensuse microOS는 tumbleweed 기반이다.
너무 자주 업데이트 된다.

당연히 부팅된 커널 버전과 설치 되는 kernel-devel(headers)의 버전이 다르기 때문에 dkms install을 수행하면 headers가 없다고 나온다.
따라서 dkms install 할 kernel 버전을 지정하고 설치해야 한다.

지정하기 위해서 kernel 버전을 확인한다.
기존에 kernel-devel을 설치하지 않았다면, 최신의 kernel-devel 하나만 설치되어 있을것이다.

ll /lib/modules/

실행 결과

> ll /lib/modules/
total 0
drwxr-xr-x 1 root root 688 Jan 23 19:27 6.18.5-1.0.2.sr20260101-default/

이 폴더 이름을 잘 기억해둬야 한다.

3) DKMS 빌드 및 설치

소스코드를 받고 빌드할 때도 위에서 추출한 타겟 커널 버전을 명시해 준다.

Bash

cd /root
git clone https://github.com/strongtz/i915-sriov-dkms.git
dkms add /root/i915-sriov-dkms
# 타겟 커널 버전($TARGET_KERNEL)을 콕 집어서 빌드
MAKEFLAGS="-j6" dkms install i915-sriov-dkms/2025.12.10 -k 6.18.5-1.0.2.sr20260101-default

4) 마무리 설정: kernel parameter

최신 커널이 xe 드라이버를 먼저 잡지 않도록 블랙리스트 처리하고, Arrow Lake ID(7d51)를 강제로 인식시켜 주면 끝이다.

  • /etc/default/grub 수정: module_blacklist=xe i915.force_probe=7d51 i915.enable_guc=3 
  • (참고: 로그에 Found meteorlake라고 떠도 정상이다. 아키텍처가 같아서 드라이버가 같은 계열로 인식할 뿐이다.)
nano /etc/default/grub
# GRUB_CMDLINE_LINUX_DEFAULT 뒤에 module_blacklist=xe i915.enable_guc=3 를 추가해준다.
dracut --force --regenerate-all # initramfs
update-bootloader --refresh
exit #transactional-update shell에서 빠져나온다.
reboot

5) VM에서 intel iGPU 인식을 확인한다.

# error나 oops가 없는지 확인한다.
sudo dmesg | grep -iE "i915|xe|guc|huc"
# Kernel driver in use: i915 가 맞는지 확인한다. 일치해야 한다. 
sudo lspci -nnkv -s  01:00.0


# i915로 link 된 card가 존재하는지 확인한다.
ls -l /sys/class/drm/card*/device/driver
# 예를 들어 이런 결과가 포함되어야 한다.
# /sys/class/drm/card0/device/driver -> ../../../../bus/pci/drivers/i915/

# render와 card가 존재하는지 확인한다.
ll /dev/dri/

sudo dmesg 
# 터미널 검색에서 oops가 없는지 확인한다. 없어야 한다.
# oops는 kernel panic이다. 없어야 한다!!

7. 결론

설정 후 재부팅하니 vainfo가 정상적으로 출력되고, Plex에서 트랜스코딩 가속도 시원하게 작동한다.

Intel Core Ultra 5 (Arrow Lake)와 MicroOS 조합으로 홈랩을 구성하려는 분들에게 이 레시피가 도움이 되길 바란다.


답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다


Ads Blocker Image Powered by Code Help Pro

광고 차단 감지됨!

닫기를 누르면 이용하실 수 있지만, 광고 차단은 해제해주시면 좋겠습니다.
Powered By
100% Free SEO Tools - Tool Kits PRO