커널 드라이버와 커널 모듈의 차이점은 무엇입니까?


67

lspci -k3.2.0-29-generic 커널로 쿠분투에서 할 때 다음과 같은 것을 볼 수 있습니다.

01:00.0 VGA compatible controller: NVIDIA Corporation G86 [Quadro NVS 290] (rev a1)
    Subsystem: NVIDIA Corporation Device 0492
    Kernel driver in use: nvidia
    Kernel modules: nvidia_current, nouveau, nvidiafb

커널 드라이버가 nvidia커널 모듈은 nvidia_current, nouveau, nvidiafb.

이제 커널 드라이버와 커널 모듈의 차이점이 무엇인지 궁금했습니다.

답변:


78

커널 모듈은에서와 같이, 실행시 커널에 삽입 할 수있는 컴파일 된 코드의 비트입니다 insmodmodprobe.

드라이버는 일부 하드웨어 장치와 통신하기 위해 커널에서 실행되는 약간의 코드입니다. 하드웨어를 "구동"합니다. 컴퓨터의 모든 하드웨어 비트에는 관련 드라이버가 있습니다 .¹ 실행중인 커널의 대부분은 드라이버 코드입니다 .²

드라이버는 디스크의 커널 파일에 정적으로 빌드 될 수 있습니다. ³ 드라이버는 커널 모듈로 빌드되어 나중에 동적으로로드 될 수 있습니다. (그리고 언로드되었을 수도 있습니다.)

표준 관행은 드라이버를 정적으로 커널에 정적으로 연결하지 않고 가능한 한 커널 모듈로 드라이버를 빌드하는 것입니다. 그러나하지 말아야 할 좋은 이유가 있습니다.

  • 때때로 시스템 부팅을 돕기 위해 주어진 드라이버가 절대적으로 필요합니다. initrd 기능 으로 인해 상상할 수있는 횟수만큼 자주 발생하지 않습니다 .

  • 정적으로 빌드 된 드라이버는 임베디드 시스템 과 같이 정적으로 범위가 지정된 시스템에서 원하는 것일 수 있습니다 . 다시 말해, 어떤 드라이버가 항상 필요하며 이것이 변경되지 않을 것인지를 미리 알고 있다면 동적 커널 모듈을 사용하지 않아도됩니다.

  • 커널을 정적으로 빌드하고 Linux의 동적 모듈로드 기능을 비활성화하면 커널 코드의 런타임 수정을 방지 할 수 있습니다. 이는 유연성을 희생하면서 추가적인 보안과 안정성을 제공합니다.

모든 커널 모듈이 드라이버 인 것은 아닙니다. 예를 들어, Linux 커널에서 비교적 최신 기능 은 다른 프로세스 스케줄러를로드 할 수 있다는 것 입니다. 또 다른 예는보다 복잡한 유형의 하드웨어가 종종 기본 하드웨어와 무관하게 USB 스택의 특정 요소 를 구현 하는 USB HID 드라이버 와 같은 저수준 하드웨어 드라이버와 사용자 영역 사이에있는 여러 일반 계층을 가지고 있다는 것 입니다.


옆으로 :

  1. 이 광범위한 진술에 대한 한 가지 예외는 CPU 드라이버이며 "드라이버" 자체 는 없습니다 . 컴퓨터에 드라이버가없는 하드웨어가 포함되어있을 수도 있습니다.

  2. OS 커널의 나머지 코드는 메모리 관리 , IPC , 스케줄링 등과 같은 일반 서비스를 제공합니다 . 이러한 서비스는 기본적으로 이전에 연결된 예제와 같이 사용자 영역 응용 프로그램에 서비스를 제공하거나 드라이버 또는 기타 내부에서 사용되는 내부 서비스 일 수 있습니다. 커널 인프라.

  3. 부팅 프로세스 초기에 부트 로더/boot부팅 할 때 RAM에로드 된 것 중 하나 .


1
모듈은 파일 시스템, 네트워크 프로토콜, 방화벽 기능 등이 될 수 있습니다. 일부 하드웨어 (예 : WiFi 카드)에는 모듈 스택이 필요하며, 일부는 일반 인프라를 제공하고 다른 일부는 하드웨어 자체를 처리합니다.
vonbrand

1
이것은 좋은 일반적인 개요이지만 OP와 정확히 같은 질문이 있었고이 답변을 보았으며 여전히 "사용중인 드라이버"가 "모듈"과 다른 이유를 알지 못했습니다. 반면 @Jim Paris의 대답은 맞습니다. From man lspci: "-k 각 장치를 처리 하는 커널 드라이버 와 이를 처리 할 수있는 커널 모듈을 보여 줍니다." " 현재 / 실제로 장치를 처리 하는 드라이버 와 해당 장치 를 처리수있는 모든 모듈 표시"로 읽을 있습니다.
Binarus

Windows를 알고있는 경우 : 모듈은 DLL과 매우 유사합니다. 유닉스에서 모듈은 공유 객체와 비슷하지만 모듈은 커널 전용입니다. 동적으로 연결된 모듈에는 드라이버가 포함될 수 있습니다. 커널은 정적으로 링크 된 드라이버를 포함 할 수 있습니다. 커널은 동적으로로드되는 방법에 대한 특정 요구 사항이 있기 때문에 DLL (또는 .so)과 다릅니다.
robocat

18

lspci출력 에 대한 특정 질문에 대답하기 위해 "커널 드라이버"줄은 현재 드라이버가 카드에 바인딩되어있는 nvidia드라이버 ( 이 경우 독점 드라이버)를 나타냅니다. "커널 모듈"줄에는 이 카드에 바인딩 할 수있는 것으로 알려진 모든 드라이버가 나열됩니다 . 여기에서 독점 드라이버는 lspci드라이버와 파일 이름을 드라이버 자체에 코딩 한 이름과 찾은 방식으로 인해 다른 이름으로 표시 됩니다.


고마워-도움이되었습니다. 내가 발행 한 경우 man lspci-정확히 당신이 쓴 것을 말합니다.
Binarus

5

이 멋진 튜토리얼 에 따르면 :

... 한 유형의 모듈은 장치 드라이버이며 커널은 시스템에 연결된 하드웨어에 액세스 할 수 있습니다.

따라서 트리를 그리려고하면 "확장 된"모듈에서 상속하고 "하드웨어에 액세스하는"사이에보다 구체적인 특성을 갖는 "장치 드라이버"가 있습니다.


이것은 부분적으로 만 정확합니다. 드라이버는 계층 구조에서 클래스의 객체입니다 (예, 대부분의 최신 운영 체제 인 Linux의 내부 디자인은 객체 지향). 그러나 상기 드라이버는 모듈 (런타임에로드 가능)이거나 커널로 컴파일 될 수 있습니다. 코드와 현명한 대안 사이에는 차이가 없습니다.
vonbrand

4

커널 모듈은 장치 드라이버가 아닐 수도 있습니다.

"커널 드라이버 (Kernel driver)"는 잘 정의 된 용어는 아니지만 한 번 봅시다.

이것은 어떤 하드웨어도 구동하지 않으므로 "장치 드라이버"로 합리적으로 고려할 수없는 커널 모듈입니다.

#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");

static int myinit(void)
{
    printk(KERN_INFO "hello init\n");
    return 0;
}

static void myexit(void)
{
    printk(KERN_INFO "hello exit\n");
}

module_init(myinit)
module_exit(myexit)

빌드 후 다음과 함께 사용할 수 있습니다.

insmod hello.ko

그리고로 인쇄 hello init됩니다 dmesg.

그러나 장치 드라이버는 아니지만 커널 디버깅 / 성능 정보를 노출하는 모듈과 같이 실제로 유용한 커널 모듈이 있습니다.

장치 드라이버는 일반적으로 커널 모듈이기도합니다.

"장치 드라이버"인 무언가의 예는 구동하기 위해 하드웨어가 필요하고 하드웨어 설명이 복잡하기 때문에 생성하기가 조금 더 어렵다.

그러나 QEMU 또는 기타 에뮬레이터를 사용하여 실제 또는 단순화 된 하드웨어의 소프트웨어 모델을 구성 할 수 있습니다. 이는 하드웨어와 대화하는 방법을 배우는 좋은 방법입니다. 다음은 최소 PCI 장치 드라이버의 간단한 예입니다. https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/hello.c

x86에서 하드웨어와 대화하는 것은 다음과 같습니다.

사용자 공간과 커널 공간의 차이점은 무엇입니까?에 설명 된대로 이러한 작업은 일반적으로 사용자 영역에서 수행 할 수 없습니다 . 그러나 몇 가지 예외가 있습니다 : https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .

그런 다음 커널은보다 높은 수준의 API를 제공하여 이러한 하드웨어 상호 작용을보다 쉽고 휴대하기 쉽게 만듭니다.

  • request_irq 인터럽트 처리
  • ioreadX 및 IO 메모리 매핑
  • PCI 및 USB와 같은 널리 사용되는 프로토콜을위한 더 높은 수준의 인터페이스

0

내 대답은 짐과 함께 갈 것이다. 커널 드라이버는 하드웨어를 구동하도록 설계된 프로그램 (커널 모듈)입니다. lspci 출력에 따르면 nvidia는 loaded장치 의 모듈 이므로 커널 드라이버 입니다. 이와 함께 사용 가능한 다른 커널 모듈도 제공됩니다.

나는 리눅스의 명령을 나열하고 드라이버는 제거 할 것을 추가 할 것입니다 lsmodrmmod각각. 목록 모듈이라고 말하고 모듈을 제거하십시오.


0

모든 드라이버는 모듈입니다. 모든 모듈이 드라이버 인 것은 아닙니다.

런타임에 모듈을 삽입 할 수 있습니다. 커널과 함께 모듈 / 드라이버를 정적으로 컴파일 할 수 있습니다.

일반적인 모듈 초기화

module_init(init_fn);
init_fn()
{
   /* some code */
}

동일한 모듈을 드라이버로 만들 수 있습니다

module_init(init_fn);
init_fn()
{
   device_register(&device);
   /* some code */
}

8
드라이버는 항상 모듈이 아니며 기본 커널 이미지에 포함될 수 있습니다.
Gilles

3
@Prabagaran : "모든 드라이버는 모듈입니다. 모든 모듈은 드라이버가 아닙니다." 이것은 모순입니다. 수학적으로 말하면 D-> M 및 M->! D입니다. 이것은 D와! D를 허용합니다.
Francesco Turco

2
"모든 드라이버는 모듈입니다. 모든 모듈이 드라이버는 아닙니다"를 의미합니다.
Renan

4
@Renan : 맞습니다.하지만이 답변에 대한 편집 기록을 보면 누군가가 이미 실수를 수정하려고 시도했으며 저자가 실수를 되돌 렸습니다. 일반적으로 나는 오류를 수정하고 계속 진행하기 위해 편집 할 것이지만이 경우에는 잘못되어 혼란 스럽기 때문에 -1했습니다.
Caleb

내가 기억하는 것처럼 (한동안 바보짓을하지 않았다)로드 가능한 모듈로 빌드 할 수없는 드라이버가 있습니다. 모듈로만 처리 할 수있는 다른 사람들을 기억하는 것 같습니다.
vonbrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.