2026년 2월 22일 일요일

리눅스 커널 내 Rust 코드 통합 - Part I

이번 시간에는 Linux kernel 내에 추가된 Rust framework의 architecture와 설계 방향을 파악해 보는 시간을 가져 보고자 한다. 😎

A Deep Dive into the Rust Architecture and Module Integration Design in the Linux Kernel

Part I. 목차
1. 리눅스 커널의 진화와 Rust-for-Linux의 도입 배경 및 설계 철학
2. linux/rust 디렉토리의 전체 아키텍쳐 및 계층 구조
3. C와 Rust 코드의 연결: FFI와 바인딩 메커니즘
4. 메모리 관리 및 동기화 아키텍쳐: 커널 제약의 극복
5. 사용자 커널 모듈의 연결 구조 및 생명주기
6. 외부 모듈(Out-of-tree)의 통합 메커니즘
7. 맺음말
8. References


기존에 C 언어로 linux kernel module을 만들었던 것을 떠올려 보면, Linux kernel code를 작성할 때에는 libc에서 제공하는 다양한 함수(printf, strcmp, exit, malloc, free 등)를 이용할 수도 없으며, thread를 만들기 위해 pthread를 사용할 수도 없었다. Linux kernel programming을 한다는 것은, kernel에서 자체적으로 구현되어 있는 환경(framework)을 사용해야만 한다는 뜻이기도 하다. 그렇다면, Rust로 구현한 kernel module의 경우는 어떨까 ? Rust로 사용자 영역에서 동작하는 application code를 작성하는 방식과 동일하게 kernel code를 만들면 되는 것일까 ? 대답은 당연히 "No"이다. 😋


1. 리눅스 커널의 진화와 Rust-for-Linux의 도입 배경 및 설계 철학

1991년 초기 릴리스 이후, 리눅스 커널은 철저하게 C 언어와 어셈블리어로 작성되며 현대 운영체제의 근간으로 자리 잡았다.1 수십 년간 커널의 규모와 복잡성이 기하급수적으로 증가하는 과정에서 C 언어는 하드웨어에 대한 정밀한 제어와 예측 가능한 높은 성능을 제공하는 핵심 도구로 기능해 왔다.2 1997년경 C++의 도입이 약 2주간 실험된 바 있으나, 컴파일러의 성숙도 부족과 객체 지향 패러다임이 초래하는 오버헤드 문제로 인해 즉각 폐기된 이후 커널 생태계에서 C 언어의 독점적 지위는 흔들리지 않았다.1 그러나 하드웨어의 발전과 더불어 시스템 소프트웨어의 복잡성이 심화됨에 따라, 버퍼 오버플로우(buffer overflow), 해제 후 사용(Use-After-Free, UAF), 데이터 레이스(data race)와 같은 C 언어 고유의 메모리 안전성 결함이 치명적인 보안 취약점의 근본 원인으로 지목되기 시작했다.2 안드로이드(Android)와 같은 플랫폼에서는 커널 내의 이러한 취약점이 권한 상승 및 보안 모델 우회로 직결되므로, 구글을 비롯한 기술 기업들은 메모리 안전성을 수학적으로 보장할 수 있는 새로운 시스템 프로그래밍 언어의 도입을 적극적으로 모색하게 되었다.2

이러한 역사적 배경 속에서 2020년 제안된 Rust-for-Linux 프로젝트는 가비지 컬렉터(Garbage Collector)의 런타임 오버헤드 없이도 컴파일 타임에 소유권(Ownership) 및 대여/빌림 검사기(Borrow Checker)를 통해 메모리 안전성을 보장하는 Rust 언어를 커널에 도입하려는 거대한 패러다임 전환을 시도했다.1 Rust는 2006년 처음 설계된 이래 C와 대등한 저수준 성능을 제공하면서도 현대적인 타입 시스템을 통해 동시성 버그와 메모리 오류를 원천적으로 차단하는 언어로 발전해 왔다.1 사실 커널 모듈을 Rust로 작성하려는 시도는 2013년 김태수(Taesoo Kim)님이 발표한 외부 로더블 커널 모듈(loadable kernel module) 데모 등에서 이미 그 가능성이 입증된 바 있으나, 메인라인 커널 자체에 언어를 통합하는 것은 완전히 다른 차원의 아키텍처적 도전을 요구했다.1

Rust-for-Linux 프로젝트의 기본 설계 철학은 기존의 수천만 줄에 달하는 C 코드를 모두 Rust로 재작성(rewrite)하는 비현실적인 목표를 추구하지 않는다.4 대신, 신규 디바이스 드라이버와 파일 시스템, 그리고 서브시스템을 안전한 Rust로 작성할 수 있도록 강력한 도구와 엄격한 추상화 계층을 제공하는 것을 목표로 삼는다.2 수년간의 논의와 개발 끝에, 2022년 말 리눅스 커널 6.1 버전에 최초의 Rust 인프라스트럭처가 메인라인에 병합되었으며, 2023년 6.8 버전에서는 아사히 리눅스(Asahi Linux) 프로젝트와 연계된 최초의 Rust 기반 네트워크 PHY 드라이버(AMCC QT2025)가 공식 포함되었다.1 나아가 2025년(12월) 일본 도쿄에서 열린 커널 메인테이너 서밋(Kernel Maintainer Summit)에서는 Rust가 더 이상 실험적(experimental) 기능이 아니며, 커널 개발을 위한 영구적인 시스템 언어로 채택되었음이 공식 선언되기에 이르렀다.1

[그림 1.1] Rust-For-Linux 주요 milestone [출처 - 참고문헌 61]

이러한 성공적인 안착의 이면에는 기존 C 인프라스트럭처와의 안전하고 효율적인 상호 운용성을 보장하기 위한 매우 정교하고 복잡한 아키텍처 설계가 자리 잡고 있다. 이번 posting에서는 linux/rust 디렉터리의 내부 구조, C 코드와의 결합 메커니즘, 메모리 관리 모델, 그리고 사용자 작성 모듈이 커널에 통합되는 전체 파이프라인을 심층적으로 분석한다. 😎

사용자 공간(Userspace)에서 동작하는 일반적인 Rust 애플리케이션과 리눅스 커널 공간(Kernelspace)에서 동작하는 Rust 모듈은 완전히 다른 실행 환경과 제약 조건을 가진다.9 따라서 커널 내부에 통합된 Rust 아키텍처는 이러한 커널 고유의 특성을 반영하여 설계되었다.

가장 핵심적인 제약 사항은 메모리 할당의 실패 가능성(Fallibility)과 원자적 컨텍스트(Atomic context)에서의 동작이다. 일반적인 사용자 공간의 Rust 표준 라이브러리(std)는 메모리 부족(Out Of Memory, OOM) 상황이 발생할 경우 즉시 프로그램의 실행을 중단(Abort)시키고 패닉(Panic)을 발생시킨다.10 그러나 운영체제 커널이 메모리 부족을 이유로 전체 시스템을 패닉 상태로 몰고 가는 것은 용납될 수 없으며, 모든 메모리 할당 실패는 안전하게 포착되어 호출자에게 오류 코드(예: -ENOMEM)로 반환되어야 한다.10 이로 인해 Rust-for-Linux는 표준 라이브러리인 std를 완전히 배제하고, 핵심 언어 기능만을 담은 core 크레이트와 커널 전용으로 재설계된 alloc 크레이트를 사용한다.12

또한, 커널 코드는 스핀락(Spinlock)을 획득한 상태와 같이 스레드가 슬립(Sleep)할 수 없는 원자적 컨텍스트에서 빈번하게 실행된다.10 이러한 상태에서는 메모리 할당 자체가 엄격히 금지되므로, 객체의 할당과 초기화를 분리하는 설계가 필수적이다.10 Rust-for-Linux 아키텍처는 이를 해결하기 위해 UniqueArc와 같은 커스텀 스마트 포인터와 pin-init 패턴을 도입하여, 안전한 락 획득 상태에서도 컴파일러가 메모리 레이아웃을 검증할 수 있도록 강제한다.10

세 번째 철학은 "직접적인 FFI(Foreign Function Interface) 호출의 차단과 안전한 추상화의 의무화"이다.11 C 언어와 상호작용하기 위해 생성된 수많은 원시 포인터(*mut)들을 드라이버 개발자가 직접 다루게 방치한다면, Rust를 도입한 의미가 퇴색된다.17 따라서 아키텍처는 C 언어의 불안전한 API를 감싸는(Safe Abstraction) 계층을 중앙집중식으로 제공하며, 사용자 모듈은 반드시 이 추상화된 인터페이스만을 호출해야 한다.11


2. linux/rust 디렉터리의 전체적 아키텍처 및 계층 구조

리눅스 커널 소스 트리의 루트에 존재하는 linux/rust 디렉터리는 커널 내 Rust 생태계의 심장부이다.4 이 디렉터리는 단순히 Rust 언어로 작성된 드라이버들을 모아둔 공간이 아니라, C로 작성된 커널 코어와 안전한 Rust 모듈 사이를 매개하는 인프라, 바인딩 자동화 도구, 헬퍼(helper) 함수, 그리고 고수준 추상화 계층을 모두 포함하는 거대한 프레임워크를 구성한다.4 이 디렉터리의 내부 아키텍처는 크게 원시 계층, 추상화 계층, 그리고 절차적 매크로 계층으로 세분화된다.


[그림 2.1] linux rust/ 디렉토리 내용

2.1 C-Rust 바인딩 및 헬퍼 계층 (bindings/ 및 helpers/)

이 계층은 C 언어로 작성된 리눅스 커널의 데이터 구조와 함수 시그니처를 Rust의 세계로 투영하는 역할을 담당한다. 커널은 수백만 줄의 C 헤더로 구성되어 있으므로 이를 수동으로 변환하는 것은 불가능하다.11 따라서 bindings/ 폴더 내의 코드들은 bindgen 도구를 통해 빌드 타임에 동적으로 생성된다.3

그러나 매크로와 인라인 함수는 컴파일러의 전처리 단계에서 확장되거나 링킹 타임에 심볼이 사라지므로 bindgen만으로는 해결할 수 없는 사각지대를 만든다.11 이를 보완하기 위해 helpers/ 디렉터리가 존재하며, 이곳에는 C 파일(helpers.c 등)이 위치하여 Rust가 호출할 수 있는 명시적인 C 래퍼(wrapper) 함수를 강제로 컴파일하고 심볼을 익스포트(export)한다.20 이 과정의 기술적 디테일은 이어지는 3장에서 상세히 다루게 된다.

2.2 핵심 추상화 계층: kernel 크레이트 (kernel/)

linux/rust/kernel 디렉터리는 Rust-for-Linux 아키텍처의 가장 중요한 구성 요소인 kernel 크레이트의 소스 코드를 담고 있다.14 사용자가 작성하는 모든 Rust 커널 모듈은 core 라이브러리와 더불어 이 kernel 크레이트에 절대적으로 의존한다.14 kernel 크레이트의 근본적인 목적은 앞서 설명한 bindings/ 계층의 불안전한(Unsafe) C API들을 Rust의 소유권 모델과 타입 시스템에 맞게 완전히 재해석하여, 컴파일 타임에 모든 메모리 안전성을 검증할 수 있는 '안전한(Safe)' API로 제공하는 것이다.11

해당 크레이트는 커널의 다양한 서브시스템을 모듈 형태로 세분화하여 구조화하고 있으며, 사용자가 드라이버를 작성할 때 필요로 하는 거의 모든 운영체제 원시 기능들을 포괄한다.14

[표 2.1] kernel 크레이트 정리

서브모듈 명칭

주요 제공 기능 및 역할

대응되는 C 커널 인프라

kernel::sync

Mutex, SpinLock, CondVar, Arc 등의 동기화 원시 타입과 락 가드(Lock Guard) 객체 제공. 원자적 참조 카운팅 및 락 의존성 추적(lockdep) 연동. 11

struct mutex, spinlock_t, refcount_t, lock_class_key

kernel::alloc_

커널 전용 힙(Heap) 메모리 할당 인프라. KBox, KVBox, KVec과 같은 스마트 포인터와 메모리 할당 플래그(GFP_KERNEL 등) 처리. 할당 실패를 Result로 반환. 11

kmalloc, vmalloc, kvmalloc, kfree

kernel::device

커널의 드라이버 모델에 속하는 일반 디바이스 객체에 대한 라이프타임 관리. 객체 참조 카운팅(ARef) 연동. 14

struct device, kref

kernel::driver

PCI, Platform, USB, I2C, Amba 등 다양한 하드웨어 버스 프로토콜과 통신하기 위한 드라이버 등록 매크로 및 제네릭 지원. 14

struct pci_driver, struct i2c_driver 등

kernel::fs

가상 파일 시스템(VFS) 계층과의 연동, 파일 디스크립터 처리, 디렉터리 구조(dcache) 관리 및 상태 동기화. 14

struct file, struct dentry, struct inode

kernel::net

네트워크 디바이스 및 PHY 드라이버 작성을 위한 추상화. module_phy_driver와 같은 매크로 제공. 14

struct phy_driver, struct net_device

kernel::error

커널 내부에서 발생하는 수많은 정수형 오류 코드(-EINVAL, -ENOMEM 등)를 Rust의 Error 타입으로 추상화하여 Result<T, Error> 형태로 반환. 11

<uapi/linux/errno.h>의 매크로들


사용자(드라이버 개발자)는 C API를 직접 호출하는 대신, 반드시 이 kernel 크레이트가 제공하는 인터페이스를 통해 시스템 자원에 접근해야 한다.14 예를 들어, 태스크의 현재 유효 사용자 ID를 가져오고 싶다면, C 함수의 포인터를 직접 호출하는 것이 아니라 kernel::task 모듈이나 kernel::cred 모듈에서 안전하게 래핑된 메서드를 호출해야 한다.14 이는 모듈 개발자가 시스템의 상태를 손상시키는 것을 방지하는 아키텍처적 방어막으로 작용한다.

2.3 절차적 매크로 계층 (macros/)

linux/rust/macros 디렉터리는 컴파일 타임에 Rust 코드를 동적으로 생성하고 분석하는 절차적 매크로(Procedural Macros)들을 포함한다.19 리눅스 커널 드라이버는 모듈의 메타데이터(이름, 라이선스, 저자) 등록부터, KUnit 테스트 프레임워크 연동, 그리고 복잡한 디바이스 테이블(ID Table) 생성에 이르기까지 다량의 상용구(Boilerplate) 코드를 요구한다.14

이 계층에서 제공하는 대표적인 매크로인 module!은 사용자 모듈의 진입점을 정의하며, #[vtable] 속성 매크로는 Rust의 트레이트 구현체를 C 언어의 함수 포인터 구조체(예: file_operations)로 안전하게 매핑한다.25 또한 #[kunit_tests] 매크로는 모듈 내부에 작성된 Rust 테스트 함수들을 수집하여 커널의 화이트박스 테스트 도구인 KUnit에 자동으로 등록하는 역할을 수행한다.19 이 매크로 계층 덕분에 사용자 모듈 개발자는 C 언어의 복잡한 등록 절차를 몰라도 선언적(Declarative)인 형태로 드라이버를 작성할 수 있게 된다.

[그림 2.2] Rust driver 아키텍쳐 개요(1) [출처 - 참고문헌 60]


3. C와 Rust 코드의 연결: FFI와 바인딩 메커니즘

사용자가 작성한 Rust 기반 커널 모듈이 동작하려면 본질적으로 기존 커널의 C 인프라가 제공하는 서브루틴을 실행해야 한다. 메모리 페이지의 할당, 인터럽트 처리, I/O 포트 매핑 등은 여전히 C 언어 영역의 커널 코어에서 처리되기 때문이다. 따라서 linux/rust 코드가 C 코드와 어떤 형태로 연결되는지를 명확히 이해하는 것은 상호 운용성(Interoperability) 아키텍처의 핵심이다.

이 연결은 FFI(Foreign Function Interface)를 기반으로 하며, 자동화된 바인딩 도구인 bindgen과 보조적인 C 래퍼(Helper)의 결합을 통해 이루어진다.11

3.1 bindgen과 bindings_helper.h의 동작 원리

Rust-for-Linux 빌드 시스템에서 C와 Rust를 이어주는 1차적인 메커니즘은 bindgen이다.3 bindgen은 내부적으로 libclang을 사용하여 C 소스 코드의 추상 구문 트리(AST)를 파싱하고, 이에 상응하는 Rust 데이터 타입과 extern "C" 함수 시그니처를 자동으로 생성한다.18

이 과정의 진입점 역할을 하는 것이 rust/bindings/bindings_helper.h 파일이다.11 이 단일 C 헤더 파일에는 Rust 크레이트 내부에서 접근해야 하는 커널의 모든 핵심 C 헤더들(예: <linux/fs.h>, <linux/pci.h>, <linux/sched.h>)이 #include 지시어를 통해 나열되어 있다.31 커널을 컴파일할 때 Kbuild 시스템은 bindgen을 호출하여 이 bindings_helper.h를 분석하도록 명령하며, GCC나 Clang을 통해 빌드할 때 사용하는 것과 완벽히 동일한 컴파일러 플래그(예: 전처리기 매크로, 인클루드 경로)를 bindgen에 주입한다.32

파싱이 완료되면 bindgen은 rust/bindings/bindings_generated.rs라는 거대한 Rust 소스 파일을 출력한다.11 이 파일 내부에는 C의 구조체를 매핑한 #[repr(C)] 구조체 선언과, 수많은 원시 포인터(*mut c_void 등)를 인자로 받는 불안전한(Unsafe) C 함수 선언들이 가득 들어차 있게 된다.17

3.2 인라인 함수 및 복잡한 매크로의 한계와 helpers.c를 통한 극복

bindgen은 뛰어난 도구이지만 컴파일러의 전처리기를 완벽하게 모사하지는 못하며, 링킹 과정의 특성상 본질적인 한계에 직면한다.11 특히 리눅스 커널에서 광범위하게 사용되는 두 가지 요소가 문제를 일으킨다.

첫째, C 언어의 함수형 매크로이다. bindgen은 단순한 상수 매크로(#define NAME 3)는 Rust의 상수로 변환할 수 있으나, 다른 매크로를 연쇄적으로 호출하거나 제어 흐름을 포함하는 복잡한 매크로는 해석하지 못한다.21 둘째, __always_inline으로 선언된 인라인 함수들이다. 커널의 컨텍스트 스위칭이나 락 관련 함수들은 성능 극대화를 위해 C 헤더 내에 인라인으로 구현되어 있다.11 컴파일이 완료된 후 오브젝트 파일 레벨에서는 이 함수들의 심볼(Symbol)이 링커 테이블에 존재하지 않으므로, Rust 쪽에서 extern "C"를 통해 심볼을 링킹하려고 시도하면 '심볼을 찾을 수 없음(Unknown symbol)' 오류가 발생한다.11

이러한 아키텍처적 결함을 극복하기 위해 linux/rust/helpers.c (또는 각 서브시스템별 헬퍼 C 파일들)가 도입되었다.20 이 파일은 C 컴파일러에 의해 빌드되는 순수한 C 파일로서, 커널의 매크로나 인라인 함수를 내부에서 호출하는 실제 함수(Wrapper)를 정의하여 심볼을 강제로 생성하고 익스포트(EXPORT_SYMBOL_GPL)한다.20

예를 들어, 커널의 인라인 함수인 mutex_lock()을 Rust에서 사용하고자 할 때, helpers.c는 다음과 같은 래퍼를 정의한다 22:

void rust_helper_mutex_lock(struct mutex *lock) {
    mutex_lock(lock);
}
EXPORT_SYMBOL_GPL(rust_helper_mutex_lock);

이렇게 생성된 rust_helper_mutex_lock 심볼은 앞서 설명한 bindgen을 거쳐 Rust에서 접근 가능한 함수로 변환되며, 최종적으로 kernel::sync::Mutex 내부의 unsafe 블록 안에서 호출된다.22 태스크의 유효 권한을 확인하는 task_euid()와 같은 인라인 함수 역시 rust_helper_task_euid() 형태로 C 계층에서 래핑되어 Rust로 전달된다.27 즉, Rust 코드가 C 인라인 함수에 직접 접근하는 것이 불가능한 구조적 모순을, C 래퍼 함수를 브릿지로 삼는 우회 경로를 통해 우아하게 해결한 것이다.20

3.3 안전성 보장을 위한 Abstraction Wrapping 메커니즘

bindings_generated.rs와 헬퍼 함수들을 통해 C 코드와의 물리적 연결은 완성되었으나, 논리적 연결은 아직 불완전하다. 생성된 바인딩 함수들은 모두 unsafe이며, C 포인터의 유효성이나 메모리 수명을 보장하지 않기 때문이다.12

이 지점에서 앞서 언급한 kernel 크레이트가 핵심적인 역할을 수행한다. kernel 크레이트 내부의 코드는 이 불안전한 C 바인딩을 은닉(Encapsulation)하고, Rust의 타입 시스템을 활용하여 안전성을 부여하는 다음과 같은 세 가지 주요 래핑 메커니즘을 적용한다.11

  1. 에러 타입의 관용적 변환: C 함수는 성공 시 0, 실패 시 -ENOMEM, -EINVAL과 같은 음수 정수를 반환하는 것이 일반적이다. kernel 크레이트는 이를 감싸 반환값을 Rust의 Result<T, kernel::error::Error> 열거형(Enum)으로 자동 변환한다.11 이를 통해 사용자 모듈은 ? 연산자를 사용하여 안전하고 직관적으로 예외 처리를 수행할 수 있다.35

  2. RAII 기반의 자원 수명 관리: C에서 kmalloc()으로 메모리를 할당하거나 mutex_lock()으로 락을 획득하면, 반드시 프로그래머가 명시적으로 kfree()나 mutex_unlock()을 호출해야 하며, 이를 누락할 시 리소스 누수가 발생한다. Rust에서는 이를 스마트 포인터나 가드(Guard) 객체로 감싼 뒤, 해당 객체의 Drop 트레이트 내부에 C 해제 함수를 매핑한다.11 객체가 스코프를 벗어나면 컴파일러가 자동으로 Drop을 호출하므로 자원 누수가 원천적으로 차단된다.

  3. 포인터 소유권 및 생명주기(Lifetime) 강제: C의 *mut 포인터는 수명에 대한 개념이 없다. 추상화 계층은 이를 &'a T 또는 &'a mut T로 변환하여, 해당 포인터가 가리키는 C 구조체가 유효한 메모리 범위를 넘어서 사용되지 않도록 Rust 컴파일러의 차용 검사기(Borrow Checker)에 수명 정보를 명시적으로 제공한다.11

이러한 완벽한 래핑 과정 덕분에, 사용자가 작성하는 커널 모듈 코드는 단 하나의 unsafe 블록 없이도 리눅스 커널의 핵심 기능들을 완벽하게 제어할 수 있게 된다.17

[그림 3.1] Rust driver 아키텍쳐 개요(2) [출처 - 참고문헌 61]


4. 메모리 관리 및 동기화 아키텍처: 커널 제약의 극복

운영체제 커널이라는 특수한 환경은 사용자 공간 프로그램과는 전혀 다른 형태의 메모리 관리 및 동기화 기법을 요구한다. Rust-for-Linux는 이러한 커널의 요구사항을 수용하면서도 메모리 안전성을 잃지 않기 위해, 표준 Rust에 존재하지 않는 매우 독창적인 포인터 타입과 설계 패턴들을 구현해냈다.

4.1 자기 참조 구조체와 Pinning 메커니즘

리눅스 커널의 C 코드 설계에서 가장 빈번하게 등장하면서도 치명적인 취약점을 내포한 패턴은 데이터 구조 내부에 자신을 가리키는 포인터를 포함하는 '자기 참조 구조체(Self-referential struct)'이다.11 가장 대표적인 예가 이중 연결 리스트인 list_head나 락의 상태를 추적하는 mutex, 대기열을 관리하는 wait_queue_head 등이다.37

C 언어 개발자들은 이러한 구조체를 힙이나 스택에 할당한 후, 해당 메모리 위치를 절대 이동시키지 않는다는 암묵적인 규칙 하에 코드를 작성한다.11 예를 들어 연결 리스트의 노드 위치가 이동하면, 해당 노드를 가리키던 이전 노드의 next 포인터는 허공(또는 엉뚱한 메모리)을 가리키게 되어 즉각적인 시스템 패닉이나 심각한 해킹 취약점을 유발한다.11 반면, Rust 언어는 변수의 소유권을 넘기거나 함수에 인자로 전달할 때, 값을 메모리상에서 자유롭게 복사하고 이동(Move)시키는 것을 기본 동작으로 삼는다.11 만약 사용자가 작성한 Rust 모듈 내부에서 커널의 list_head를 포함하는 구조체를 이동시키면, 커널 전체의 메모리 무결성이 붕괴된다.11

이를 아키텍처 레벨에서 근본적으로 해결하기 위해 도입된 개념이 Pin<T> 타입과 구조적 고정(Structural Pinning) 메커니즘이다.11 Pin은 어떤 포인터(예: Box, Arc, &mut)를 감싸는 래퍼(Wrapper) 타입으로, 이 포인터가 가리키는 실제 데이터가 메모리 상에서 절대 이동하지 않음(Immovable)을 컴파일러가 강제하도록 만든다.11 linux/rust 커널 크레이트는 동기화 원시 타입(예: Mutex, SpinLock)이나 연결 리스트와 같이 자기 참조 구조를 내포한 C 객체와 상호작용할 때, 해당 객체들이 반드시 Pin에 감싸진 상태로만 인스턴스화되고 전달되도록 API 시그니처를 설계했다.11 이를 통해 안전한 Rust 모듈 코드 내에서는 컴파일러의 허가 없이 커널 구조체를 임의로 재배치하는 것이 불가능해진다.

4.2 in-place 초기화 설계: pin-init 패턴

Pin 메커니즘을 도입하여 객체의 위치가 이동하지 않도록 고정하는 데는 성공했으나, 컴파일러의 관점에서는 또 다른 논리적 모순이 발생한다. Rust에서 객체를 Pin<Box<T>>의 형태로 힙 영역에 고정시키기 위해서는, 필연적으로 스택(Stack) 영역에 먼저 구조체 인스턴스를 초기화한 다음, 그 값을 힙으로 복사하며 이동(move) 시키는 과정을 거쳐야 한다.16 이 "최초의 이동" 과정조차도 자기 참조 구조체에게는 치명적일 수 있으며, 더 큰 문제는 커널 구조체의 크기이다. 디바이스의 상태나 파일 시스템의 메타데이터를 담고 있는 커널 구조체는 종종 수 킬로바이트(KB) 이상의 방대한 크기를 가지는데, 리눅스 커널의 스레드 스택은 고작 8KB ~ 16KB 수준으로 매우 제한적이다. 스택에서 먼저 구조체를 초기화하려는 시도는 즉각적인 스택 오버플로우(Stack Overflow)를 유발한다.16

이 문제를 아키텍처 차원에서 해결하기 위해 linux/rust 프레임워크는 pin-init (in-place initialization) 이라는 독보적인 매크로 기반 설계 패턴을 고안해 냈다.11 pin-init 패턴은 객체를 스택에 임시로 생성하지 않고, 객체가 최종적으로 거주할 메모리 위치(예: 할당된 힙 영역)에 직접 값을 기록(in-place)하여 초기화하는 정교한 시스템이다.16

사용자 모듈을 작성할 때, 이동 불가능한 C 구조체를 래핑하는 구조체를 정의한다면 반드시 #[pin_data] 속성 매크로를 사용하여 선언해야 한다.11 그리고 객체를 인스턴스화할 때는 일반적인 구조체 초기화 문법 대신 pin_init! 혹은 try_pin_init! 매크로를 사용하며, 필드 할당 연산자로 : 대신 <-를 사용한다.16


#[pin_data]
struct Foo {
    #[pin]
    a: Mutex<usize>,
    b: u32,
}

let foo = pin_init!(Foo {
    a <- new_mutex!(42, "Foo::a"),
    b: 24,
});

위의 코드에서 보듯, pin_init! 매크로는 실제 객체를 생성하는 것이 아니라 객체를 지정된 위치에 초기화할 수 있는 추상화된 이니셜라이저(impl PinInit<Foo>)를 반환한다.11 이후 Box::pin_init(foo)와 같이 스마트 포인터에 전달되면, 해당 스마트 포인터가 확보한 메모리 주소에 구조체 필드들이 직접 안전하게 기록된다.16 이 설계를 통해 모듈 개발자는 스택 오버플로우의 위험성이나 자기 참조 파괴의 우려 없이 거대한 커널 객체들을 안전하게 생성할 수 있다.16

4.3 커널 맞춤형 스마트 포인터 인프라: Arc, UniqueArc, ARef

커널 환경은 다중 프로세서(SMP) 동시성 처리가 기본이므로 데이터 구조체의 공유 소유권 관리가 필수적이다. 사용자 공간 Rust에서는 공유 소유권을 위해 주로 std::sync::Arc를 사용하지만, 커널의 요구사항을 만족시키기 위해 linux/rust/kernel은 완전히 자체적인 스마트 포인터 생태계를 바닥부터 다시 설계했다.10


[표 4.1] 커널 맟춤형 스마트 포인터 정리

스마트 포인터 명칭

역할 및 기능 메커니즘

대응되는 커널 개념 및 특징

Arc<T>

힙에 할당된 T 타입 객체의 스레드 안전한 다중 소유권 제공. 커널의 자체적인 Arc 구현체임. 10

refcount_t를 활용하여 원자적 참조 증가/감소 구현. LKMM(리눅스 커널 메모리 모델) 준수. 카운트 오버플로우 발생 시 객체를 안전하게 Leak 시킴으로써 시스템 패닉 방지. 10

UniqueArc<T>

Arc의 참조 카운트가 정확히 1임이 보장된 객체. 따라서 가리키는 데이터에 대해 &mut T (가변 참조)를 안전하게 제공할 수 있음. 10

원자적 컨텍스트 진입 전(예: 락 획득 전) 메모리를 미리 할당하고, 이후 락을 보유한 상태에서 데이터를 안전하게 초기화하는 분리 패턴에 활용됨. 10

ARef<T>

외부에서 카운트되는 객체에 대한 안전한 참조. 14

파일 시스템의 inode나 디바이스 모델의 struct device 등, 이미 자체적으로 참조 카운팅(kref_get/kref_put)을 수행하는 C 언어 객체 전용. 24


특히 ARef (Always-RefCounted)의 설계는 C와 Rust를 결합하는 아키텍처의 백미라 할 수 있다. 리눅스 커널 내부에는 파일 디스크립터나 네트워크 소켓 등 객체 자체 내부에 참조 카운트 정보(kref)를 직접 들고 다니는 설계 패턴(Intrusive Reference Counting)이 매우 흔하게 사용된다.24 이러한 C 객체를 Rust 공간으로 가져올 때, 일반적인 Arc로 감싸게 되면 Rust 쪽의 카운터와 C 쪽의 카운터가 분리되어 이중 카운팅(Double Counting) 오버헤드가 발생하며 논리적 불일치 위험도 커진다.24

ARef<T>는 AlwaysRefCounted (또는 최신 패치에서 RefCounted, Ownable로 진화) 트레이트가 구현된 타입에 대해서만 작동한다.24 사용자가 ARef::clone()을 호출하여 참조를 복사할 때, ARef는 내부적으로 새로운 메모리를 할당하는 것이 아니라 해당 C 객체에 귀속된 C 언어 참조 증가 함수(예: kref_get)를 직접 호출한다.24 반대로 ARef 객체가 스코프를 벗어나 Drop 될 때는 C 언어 참조 감소 함수(예: kref_put)를 호출한다.24 이를 통해 사용자 모듈 코드는 Rust의 안전하고 관용적인 소유권 관리 문법을 그대로 유지하면서도, 그 이면에서는 오버헤드 없이 C 커널의 생명주기 관리 서브시스템과 완벽히 동기화되어 동작하게 된다.24

추가적으로, 동기화 아키텍처와 관련하여 LockedBy라는 인터페이스가 주목할 만하다.11 종종 데이터 객체 자체를 락(예: Mutex)으로 감쌀 수 없고, 상위 디렉터리나 컨테이너 구조체가 가진 락을 획득해야만 하위 데이터에 접근할 수 있는 복잡한 직렬화 구조가 커널에 존재한다.11 LockedBy 인터페이스는 Rust의 강력한 라이프타임 시스템을 활용하여, 호출자가 상위 객체의 락을 획득하여 발급받은 가드(Guard) 객체의 레퍼런스를 제시(Evidence)하지 않으면 하위 데이터에 접근할 수 없도록 컴파일 타임에 강제한다.11 이는 동기화 버그를 런타임이 아닌 컴파일 단계에서 포착하는 Rust-for-Linux의 설계 철학을 극명하게 보여준다.


5. 사용자 커널 모듈의 연결 구조 및 생명주기

사용자가 Rust를 이용해 외부 디바이스 드라이버나 커널 모듈을 개발할 경우, 사용자가 작성한 구조체와 코드가 어떻게 커널 로더 서브시스템에 인식되고 구동되는지를 이해하는 것이 실무적으로 가장 중요하다. 이 연결 과정은 강력한 매크로 인프라스트럭처와 트레이트 기반의 객체 지향적 설계로 이루어져 있다.

5.1 module! 매크로: 커널 진입점과 C ABI 브릿지

C 언어로 커널 모듈을 개발할 때는 module_init() 및 module_exit() 매크로를 사용하여 모듈이 적재(insmod)되고 해제(rmmod)될 때 호출될 함수를 명시해야 한다.47 반면, Rust 기반 커널 모듈은 소스 코드 최상단에 module! 이라는 단일 매크로를 선언하는 것으로 진입점을 구성한다.9


module! {
    type: MyDeviceDriverModule,
    name: "my_device_driver_module",
    authors:,
    description: "My device driver requires firmware",
    license: "GPL",
}

이 module! 매크로는 단순한 정보 제공용이 아니라, 절차적 매크로(Procedural Macro)를 통해 컴파일 타임에 방대한 코드를 동적으로 생성(Expansion)하는 핵심 빌드 엔진이다.28 이 과정의 메커니즘은 두 갈래로 나뉜다.

  1. 커널 메타데이터 섹션 주입: 매크로는 파라미터로 입력된 name, license, authors 등의 속성 값을 파싱하여 바이너리의 .modinfo ELF 섹션에 이 메타데이터들을 바이너리 형식으로 포맷팅해 주입한다.29 이는 C 언어의 MODULE_LICENSE()나 MODULE_AUTHOR()가 수행하는 역할과 완벽히 동일하며, modprobe나 initramfs와 같은 사용자 공간 도구들이 모듈 정보를 정상적으로 읽어들일 수 있게 보장한다.29

  2. C 초기화/정리 심볼 자동 생성: 운영체제 커널의 모듈 적재 시스템은 모듈 바이너리를 파싱하여 표준화된 init_module 및 cleanup_module C 함수 심볼을 찾아 호출한다.47 module! 매크로는 사용자가 정의한 Rust 구조체(MyDeviceDriverModule)가 구현한 트레이트의 메서드들을 기반으로, C ABI(Application Binary Interface) 사양에 맞춘 extern "C" 형태의 init_module과 cleanup_module 함수 래퍼를 자동으로 코딩하여 바이너리에 노출시킨다.30 결과적으로 C 언어로 짜여진 리눅스 커널의 로더 서브시스템은 새로 들어온 이 모듈이 C로 컴파일되었는지, Rust로 컴파일되었는지 전혀 알지 못한 채 완벽하게 초기화 루틴을 구동할 수 있다.30

5.2 Module 및 InPlaceModule 트레이트와 자원 해제(Drop)

module! 매크로의 type 필드에 지정되는 구조체는 반드시 커널 크레이트가 제공하는 kernel::Module 또는 kernel::InPlaceModule 트레이트 중 하나를 구현해야 한다.14 이것이 모듈의 생명주기를 관장하는 핵심 인터페이스이다.


[표 5.1] 커널 Module 트레이트 정리

트레이트 명칭

초기화 메서드 시그니처

설계 의도 및 적용 사례

kernel::Module

fn init(module: &'static ThisModule) -> Result<Self> 29

비교적 단순한 구조의 드라이버를 위한 트레이트. 반환된 모듈 인스턴스는 내부적으로 힙 영역에 박싱(Boxing)되어 라이프타임 내내 관리된다. 14

kernel::InPlaceModule

fn init(module: &'static ThisModule) -> impl PinInit<Self, Error> 54

복잡한 자기 참조 구조를 지니거나 커다란 디바이스 구조체를 포함하는 모듈을 위한 트레이트. 모듈 로딩 시 메모리를 동적으로 할당하고 제자리에 고정(Pin)시키는 pin-init 패턴을 컴파일러가 강제한다. 25


사용자 모듈 코드는 이 init 함수 구현부 내에서 앞서 설명한 kernel 크레이트의 서브시스템 API들을 활용해 비즈니스 로직을 수행한다. 디바이스의 Major/Minor 번호를 할당받거나, MiscDevice로 하드웨어를 등록하고, IRQ 인터럽트 핸들러를 연결하는 등의 작업이 여기서 이루어진다.25

더욱 놀라운 것은 모듈이 언로드(rmmod)될 때 수행되는 자원 해제 과정이다. 기존 C 언어에서는 개발자가 cleanup_module() 내부에 하드웨어 등록 해제, 메모리 반환, 락 파기 등의 해제 코드를 역순으로 일일이 작성해야 했고, 이 과정의 실수로 인해 수많은 커널 패닉이 발생해 왔다.9 반면 Rust 기반 사용자 모듈은 명시적인 exit 함수를 구현할 필요가 없다. 대신 모듈 구조체 내부의 필드들이 가진 Drop 트레이트의 자동 소멸 기능에 전적으로 의존한다.11 즉, 사용자가 생성한 모듈 객체가 메모리에서 해제되는 시점에, 내부에 포함된 디바이스 등록 객체(예: MiscDeviceRegistration)가 스코프를 벗어나며 자신의 Drop 로직을 자동으로 구동시킨다.11 이 Drop 구현체 내부에서 C 언어의 misc_deregister 등 해제 API가 안전하게 호출되어 운영체제에 자원을 반환한다.25 이는 사용자의 실수로 인한 자원 누수를 원천 차단하는 가장 강력하고 우아한 아키텍처적 장치이다.

[코드 5.1] rust kernel module 예제 코드


6. 외부 모듈(Out-of-tree)의 통합 메커니즘

사용자가 작성한 커널 모듈 코드가 컴파일을 거쳐 최종적인 커널 오브젝트(.ko) 파일로 빌드되고 커널에 적재되기까지의 과정은 기존 리눅스 커널의 빌드 인프라스트럭처인 Kbuild 시스템을 정교하게 확장하여 달성된다.55 앞서 언급했듯이, 일반적인 Rust 프로그래머에게 익숙한 패키지 관리자인 Cargo는 커널 링킹에 적합하지 않기 때문에 사용되지 않으며, rustc 컴파일러가 커널 Makefile에 의해 직접 제어된다.19

6.1 Kbuild 기반의 빌드 절차

커널 소스 트리 외부에 독립된 디렉터리를 만들고(Out-of-tree), 그곳에 Rust 모듈을 작성했다고 가정해 보자. 빌드를 구동하기 위해서는 모듈 디렉터리 내에 단 몇 줄의 간단한 Makefile을 작성한 뒤, 커널의 소스 트리를 가리키며 빌드를 지시해야 한다.53

[코드 6.1] rust kernel module Makefile 예제 코드


$ make -C <path_to_kernel_dir> M=$PWD 53

명령을 입력하면 다음과 같은 단계로 빌드 파이프라인이 전개된다.

  1. 설정 확인 및 도구 툴체인 점검: 커널 소스 트리의 Kbuild 시스템이 활성화되며, 컴파일된 커널이 CONFIG_RUST=y로 설정되어 있는지 검사한다.19 이 과정에서 시스템에 설치된 rustc 컴파일러와 C 바인딩 생성을 위한 bindgen, 그리고 LLVM/Clang 인프라의 버전을 점검한다 (make rustavailable 호출).12

  2. 크레이트 의존성 컴파일: Kbuild 시스템은 백그라운드에서 표준 라이브러리 없이 재정의된 커널 맞춤형 core 크레이트와 alloc 크레이트를 먼저 빌드한다.12 이후 C 헤더를 파싱한 bindings_generated.rs와 이를 감싼 추상화 크레이트인 kernel 크레이트의 인터페이스를 로드한다.11

  3. 오브젝트 파일 생성 및 링킹: Makefile에 지정된 obj-m := my_module.o 지시어에 따라, rustc가 사용자의 Rust 소스 코드를 crate_type="staticlib" 혹은 정적 라이브러리 아카이브(rlib, .a)의 형태로 컴파일한다.53 이후 링커가 구동되어 사용자의 모듈 바이너리와, 앞서 설명했던 C 매크로/인라인 우회용 helpers.c의 오브젝트 파일들을 한데 묶어(Linking) 최종적인 아키텍처 의존적 모듈 파일인 my_module.ko를 생성해 낸다.53

이렇게 생성된 .ko (Kernel Object) 파일은 기존 C 모듈과 완벽하게 동일한 구조를 가지므로, 개발자는 insmod my_module.ko를 통해 커널 공간으로 코드를 안전하게 주입할 수 있다.49


7. 맺음말

Rust-for-Linux 시스템의 설계 방향과 전체 아키텍처는 단순히 새로운 문법의 언어를 커널에 이식하는 단차원적인 작업이 아니다. 3천만 줄 이상의 방대한 C 기반 인프라를 파괴하지 않으면서도, 메모리 안전성과 현대적 타입 시스템의 이점을 커널 드라이버 계층에 빈틈없이 주입하기 위해 고안된 고도의 하이브리드 아키텍처이다.

앞서 정리한 바와 같이, linux/rust 내부 구조는 bindgen과 helpers.c를 통해 C-Rust 간의 물리적 통신로를 뚫는 원시 바인딩 레이어와, 여기서 발생한 *mut 원시 포인터의 치명적 위험성을 Rust의 소유권(Ownership) 및 라이프타임 모델 안에 완벽히 은닉해 버리는 kernel 크레이트라는 추상화 레이어로 정교하게 이분화되어 있다.11 이러한 통합 과정에서, 커널 생태계 특유의 원자적 동작과 이동 불가능한 자기 참조 구조체들을 안전하게 처리하기 위해 Pin 기반의 in-place 초기화(pin-init) 패턴이나, 이중 카운팅 오버헤드를 제거한 지능적인 ARef 스마트 포인터와 같은 독창적인 기술적 돌파구들이 새롭게 구현되었다.16 또한, 사용자가 설계한 외부 커널 모듈은 강력한 절차적 매크로인 module!을 통해 리눅스 표준 C ABI 심볼(init_module, cleanup_module)로 자동으로 그 형태를 바꾸어 Kbuild 시스템에 녹아들며 29, 모든 자원 관리는 트레이트의 Drop 시멘틱을 통해 누수 없이 런타임에 안전하게 해제된다.11

물론 이 거대한 통합 실험에는 아직 해결해야 할 도전 과제들이 남아있다. 첫째로, 배열 경계 검사(Boundary Checks) 등 Rust의 런타임 검사가 유발하는 오버헤드로 인해, 메모리 집약적인 고성능 워크로드 환경에서는 캐시나 TLB 성능이 C 코드에 비해 일부분 하락할 수 있다는 우려가 존재하며, 이를 극복하기 위한 최적화 및 관용구 개발이 필수적이다.59 둘째로, 메인라인 리눅스는 전통적으로 GCC 컴파일러 생태계를 중심으로 구축되어 있으나, 현재의 Rust 인프라는 LLVM/Clang에 강하게 종속되어 툴체인의 파편화 문제를 안고 있다.3 이 문제를 해결하기 위해 현재 GCC 기반의 Rust 프론트엔드인 gccrs 프로젝트가 커널 빌드를 최우선 목표로 활발히 개발 중이며, 향후 컴파일러 인프라가 통합될 가능성이 높다.5

결론적으로, 리눅스 커널의 그래픽 서브시스템(DRM) 메인테이너들이 향후 새로운 드라이버 작성 시 C 언어를 배제하고 Rust를 필수 요구사항으로 지정할 계획을 발표한 것에서 볼 수 있듯이 8, Rust-for-Linux 아키텍처는 단순한 실험 단계를 훌쩍 뛰어넘었다. 컴파일 타임의 강력한 안전성 검증 파이프라인과 런타임의 Zero-Cost 추상화를 통해 매끄럽고 유기적으로 결합된 이 하이브리드 설계 구조는, 다가오는 시대의 고성능 하드웨어 제어 및 운영체제 시스템 프로그래밍 분야에서 새로운 사실상 표준(De facto standard)으로 확고히 자리 잡을 것이다.

_________________________________________________________

지금까지 최신 Linux kernel(6.1 이후 버젼)에 추가된 Rust code의 주요 아키텍쳐와 설계 방향에 대하여 살펴 보았다. 이어지는 posting(Part II)에서는 Rust kernel module을 만든 후, 실제 target board에서 돌려 보는 내용을 소개해 보고자 한다. 😎

To be continued...


8. References

  1. Rust for Linux - Wikipedia, 2월 22, 2026에 액세스, https://en.wikipedia.org/wiki/Rust_for_Linux

  2. Rust in the Linux kernel - Google Online Security Blog, 2월 22, 2026에 액세스, https://security.googleblog.com/2021/04/rust-in-linux-kernel.html

  3. Rust for Linux: Inside the Kernel's New Memory-Safe Architecture ..., 2월 22, 2026에 액세스, https://nixfaq.org/2025/02/rust-for-linux-inside-the-kernels-new-memory-safe-architecture.html

  4. Rust for Linux Brief Introduction - Rust Magazine, 2월 22, 2026에 액세스, https://rustmagazine.org/issue-1/rust-for-linux-brief-introduction/

  5. Rust for Linux, 2월 22, 2026에 액세스, https://rust-for-linux.com/

  6. Linux kernel driver development in Rust: examples and best practices - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/rust/comments/16x21gw/linux_kernel_driver_development_in_rust_examples/

  7. "Rust in the kernel is no longer experimental — it is now a core part of the kernel and is here to stay." : r/linux - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/linux/comments/1piuk59/rust_in_the_kernel_is_no_longer_experimental_it/

  8. Rust boosted by permanent adoption for Linux kernel code - DevClass.com, 2월 22, 2026에 액세스, https://www.devclass.com/development/2025/12/15/rust-boosted-by-permanent-adoption-for-linux-kernel-code/1725322

  9. LF - Writing Linux Kernel Modules in Rust, 2월 22, 2026에 액세스, https://events.linuxfoundation.org/wp-content/uploads/2022/10/Wedson-Almeida-Filho-LF-Writing-Linux-Kernel-Modules-in-Rust.pdf

  10. Arc in the Linux kernel, 2월 22, 2026에 액세스, https://rust-for-linux.com/arc-in-the-linux-kernel

  11. How to write Rust in the kernel: part 3 - LWN.net, 2월 22, 2026에 액세스, https://lwn.net/Articles/1026694/

  12. Quick Start - The Linux Kernel documentation, 2월 22, 2026에 액세스, https://docs.kernel.org/rust/quick-start.html

  13. lib.rs - source - kernel, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/6.12/src/kernel/lib.rs.html

  14. kernel - Rust, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/kernel/index.html

  15. Mentorship Series - Rust for Linux: Code Documentation & Tests, 2월 22, 2026에 액세스, https://events.linuxfoundation.org/wp-content/uploads/2022/04/2022-04-20-Linux-Foundation-LF-Live-Mentorship-Series-Rust-for-Linux-Code-Documentation-Tests.pdf

  16. pin_init - Rust - kernel, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/pin_init/

  17. An Empirical Study of Rust-for-Linux: The Success, Dissatisfaction, and Compromise, 2월 22, 2026에 액세스, https://www.usenix.org/publications/loginonline/empirical-study-rust-linux-success-dissatisfaction-and-compromise

  18. Notes on the Research Paper: Rust Adoption in the Linux Kernel - Zenn, 2월 22, 2026에 액세스, https://zenn.dev/su8/articles/7291385a521b62?locale=en

  19. How to write Rust in the kernel: part 1 - LWN.net, 2월 22, 2026에 액세스, https://lwn.net/Articles/1024202/

  20. rust-for-linux: how to add rust api's for any type of driver - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/rust/comments/yq66qz/rustforlinux_how_to_add_rust_apis_for_any_type_of/

  21. Improving bindgen for the kernel - LWN.net, 2월 22, 2026에 액세스, https://lwn.net/Articles/992693/

  22. Loading Out of Tree Rust in Linux - SPR by Supernetworks, 2월 22, 2026에 액세스, https://www.supernetworks.org/pages/blog/loading-your-own-rust-kernel-modules

  23. kernel - Rust, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/

  24. ARef in kernel::prelude - Rust, 2월 22, 2026에 액세스, https://rust-for-linux.github.io/docs/kernel/prelude/struct.ARef.html

  25. Building a Linux Kernel Driver using Rust, 2월 22, 2026에 액세스, https://rust-exercises.ferrous-systems.com/latest/book/building-linux-kernel-driver

  26. Rust in the Linux. Ramfs in Rust | by Altimetrik Poland Tech Blog | Medium, 2월 22, 2026에 액세스, https://altimetrikpoland.medium.com/rust-in-the-linux-e724ab4f1bad

  27. linux/rust/helpers/task.c at master · torvalds/linux - GitHub, 2월 22, 2026에 액세스, https://github.com/torvalds/linux/blob/master/rust/helpers/task.c

  28. The Rust Macro System: Part 1 — An Introduction to Attribute Macros | by Alfred Weirich | Medium, 2월 22, 2026에 액세스, https://medium.com/@alfred.weirich/the-rust-macro-system-part-1-an-introduction-to-attribute-macros-73c963fd63ea

  29. module in macros - Rust - kernel, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/macros/macro.module.html

  30. Writing FreeBSD Kernel Modules in Rust - Fox IT, 2월 22, 2026에 액세스, https://www.fox-it.com/be/writing-freebsd-kernel-modules-in-rust/

  31. Some question when using bindgen to binding kernel c header file, 2월 22, 2026에 액세스, https://users.rust-lang.org/t/some-question-when-using-bindgen-to-binding-kernel-c-header-file/103956

  32. Some question when using bindgen to binding kernel c header file - #2 by nerditation - help, 2월 22, 2026에 액세스, https://users.rust-lang.org/t/some-question-when-using-bindgen-to-binding-kernel-c-header-file/103956/2

  33. Create a wrapper.h Header - The bindgen User Guide, 2월 22, 2026에 액세스, https://rust-lang.github.io/rust-bindgen/tutorial-2.html

  34. A little C with your Rust - The Embedded Rust Book, 2월 22, 2026에 액세스, https://docs.rust-embedded.org/book/interoperability/c-with-rust.html

  35. How to Create Safe FFI Bindings in Rust - OneUptime, 2월 22, 2026에 액세스, https://oneuptime.com/blog/post/2026-01-30-rust-safe-ffi-bindings/view

  36. Best practices to design a C API that can be ergonomically used in Rust, 2월 22, 2026에 액세스, https://users.rust-lang.org/t/best-practices-to-design-a-c-api-that-can-be-ergonomically-used-in-rust/133151

  37. The Safe Pinned Initialization Problem - Rust for Linux, 2월 22, 2026에 액세스, https://rust-for-linux.com/the-safe-pinned-initialization-problem

  38. Rust for Linux Workshop: The perils of pinning - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/rust/comments/xftp8j/rust_for_linux_workshop_the_perils_of_pinning/

  39. Rust support - LWN.net, 2월 22, 2026에 액세스, https://lwn.net/Articles/894258/

  40. std::pin - Rust Documentation, 2월 22, 2026에 액세스, https://doc.rust-lang.org/std/pin/index.html

  41. Module init - Adding support for the Rust language to the Linux kernel., 2월 22, 2026에 액세스, https://rust-for-linux.github.io/docs/pinned-init/kernel/init/

  42. pin_init - Rust - Docs.rs, 2월 22, 2026에 액세스, https://docs.rs/pin-init

  43. [Blog] Safe pinned initialization - language design - Rust Internals, 2월 22, 2026에 액세스, https://internals.rust-lang.org/t/blog-safe-pinned-initialization/17404

  44. Rust Smart Pointers Explained: Ownership, Memory, and Safety - DEV Community, 2월 22, 2026에 액세스, https://dev.to/leapcell/rust-smart-pointers-explained-ownership-memory-and-safety-1ek3

  45. How to Use Smart Pointers in Rust - OneUptime, 2월 22, 2026에 액세스, https://oneuptime.com/blog/post/2026-01-25-rust-smart-pointers/view

  46. rust: add `Ownable` trait and `Owned` type - LWN.net, 2월 22, 2026에 액세스, https://lwn.net/Articles/1059656/

  47. linux kernel - Multiple definitions of init_module and cleanup_module - Stack Overflow, 2월 22, 2026에 액세스, https://stackoverflow.com/questions/37291686/multiple-definitions-of-init-module-and-cleanup-module

  48. Where does it call init_module() & cleanup_module() in new kernel module? - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/kernel/comments/p4b3yt/where_does_it_call_init_module_cleanup_module_in/

  49. Kernel Module init and cleanup functions - BISS, 2월 22, 2026에 액세스, https://bosphorusiss.com/resources/kernel-module-init-and-cleanup-functions/

  50. When does mod->init be assigned - Stack Overflow, 2월 22, 2026에 액세스, https://stackoverflow.com/questions/68152475/when-does-mod-init-be-assigned

  51. Macro expansion - Rust Compiler Development Guide, 2월 22, 2026에 액세스, https://rustc-dev-guide.rust-lang.org/macro-expansion.html

  52. Macro expansion - Guide to Rustc Development, 2월 22, 2026에 액세스, https://longfangsong.github.io/rustc-dev-guide-cn/macro-expansion.html

  53. linux-kernel-module-rust/NOTES.md at master - GitHub, 2월 22, 2026에 액세스, https://github.com/fishinabarrel/linux-kernel-module-rust/blob/master/NOTES.md

  54. InPlaceModule in kernel - Rust, 2월 22, 2026에 액세스, https://rust.docs.kernel.org/kernel/trait.InPlaceModule.html

  55. Linux Kernel Makefiles, 2월 22, 2026에 액세스, https://docs.kernel.org/kbuild/makefiles.html

  56. makefiles.rst - The Linux Kernel Archives, 2월 22, 2026에 액세스, https://www.kernel.org/doc/Documentation/kbuild/makefiles.rst

  57. Building External Modules - The Linux Kernel documentation, 2월 22, 2026에 액세스, https://docs.kernel.org/kbuild/modules.html

  58. Building a kernel module from several source files which one of them has the same name as the module - Stack Overflow, 2월 22, 2026에 액세스, https://stackoverflow.com/questions/13606075/building-a-kernel-module-from-several-source-files-which-one-of-them-has-the-sam

  59. An Empirical Study of Rust-for-Linux: The Success, Dissatisfaction, and Compromise - Reddit, 2월 22, 2026에 액세스, https://www.reddit.com/r/rust/comments/1e0lotn/an_empirical_study_of_rustforlinux_the_success/

  60. Rust in the Linux Kernel: Analyzing Rust Implementations of Device Drivers, Fabian Garber, BSc

  61. https://www.usenix.org/system/files/atc24-li-hongyu.pdf


Slowboot