lspci -k
3.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
.
이제 커널 드라이버와 커널 모듈의 차이점이 무엇인지 궁금했습니다.
답변
커널 모듈은에서와 같이, 실행시 커널에 삽입 할 수있는 컴파일 된 코드의 비트입니다 insmod
나 modprobe
.
드라이버는 일부 하드웨어 장치와 통신하기 위해 커널에서 실행되는 약간의 코드입니다. 하드웨어를 “구동”합니다. 컴퓨터의 모든 하드웨어 비트에는 관련 드라이버가 있습니다 .¹ 실행중인 커널의 대부분은 드라이버 코드입니다 .²
드라이버는 디스크의 커널 파일에 정적으로 빌드 될 수 있습니다. ³ 드라이버는 커널 모듈로 빌드되어 나중에 동적으로로드 될 수 있습니다. (그리고 언로드되었을 수도 있습니다.)
표준 관행은 드라이버를 정적으로 커널에 정적으로 연결하지 않고 가능한 한 커널 모듈로 드라이버를 빌드하는 것입니다. 그러나하지 말아야 할 좋은 이유가 있습니다.
-
때때로 시스템 부팅을 돕기 위해 주어진 드라이버가 절대적으로 필요합니다. initrd 기능 으로 인해 상상할 수있는 횟수만큼 자주 발생하지 않습니다 .
-
정적으로 빌드 된 드라이버는 임베디드 시스템 과 같이 정적으로 범위가 지정된 시스템에서 원하는 것일 수 있습니다 . 다시 말해, 어떤 드라이버가 항상 필요하며 이것이 변경되지 않을 것인지를 미리 알고 있다면 동적 커널 모듈을 사용하지 않아도됩니다.
-
커널을 정적으로 빌드하고 Linux의 동적 모듈로드 기능을 비활성화하면 커널 코드의 런타임 수정을 방지 할 수 있습니다. 이는 유연성을 희생하면서 추가적인 보안과 안정성을 제공합니다.
모든 커널 모듈이 드라이버 인 것은 아닙니다. 예를 들어, Linux 커널에서 비교적 최신 기능 은 다른 프로세스 스케줄러를로드 할 수 있다는 것 입니다. 또 다른 예는보다 복잡한 유형의 하드웨어가 종종 기본 하드웨어와 무관하게 USB 스택의 특정 요소 를 구현 하는 USB HID 드라이버 와 같은 저수준 하드웨어 드라이버와 사용자 영역 사이에있는 여러 일반 계층을 가지고 있다는 것 입니다.
옆으로 :
답변
lspci
출력 에 대한 특정 질문에 대답하기 위해 “커널 드라이버”줄은 현재 드라이버가 카드에 바인딩되어있는 nvidia
드라이버 ( 이 경우 독점 드라이버)를 나타냅니다. “커널 모듈”줄에는 이 카드에 바인딩 할 수있는 것으로 알려진 모든 드라이버가 나열됩니다 . 여기에서 독점 드라이버는 lspci
드라이버와 파일 이름을 드라이버 자체에 코딩 한 이름과 찾은 방식으로 인해 다른 이름으로 표시 됩니다.
답변
이 멋진 튜토리얼 에 따르면 :
… 한 유형의 모듈은 장치 드라이버이며 커널은 시스템에 연결된 하드웨어에 액세스 할 수 있습니다.
따라서 트리를 그리려고하면 “확장 된”모듈에서 상속하고 “하드웨어에 액세스하는”사이에보다 구체적인 특성을 갖는 “장치 드라이버”가 있습니다.
답변
커널 모듈은 장치 드라이버가 아닐 수도 있습니다.
“커널 드라이버 (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에서 하드웨어와 대화하는 것은 다음과 같습니다.
in
및out
지침 (예 : https://stackoverflow.com/questions/3215878/what-are-in-out-instructions-in-x86-used-for/33444273#33444273- CPU에 핸들러를 등록하여 인터럽트 처리
사용자 공간과 커널 공간의 차이점은 무엇입니까?에 설명 된대로 이러한 작업은 일반적으로 사용자 영역에서 수행 할 수 없습니다 . 그러나 몇 가지 예외가 있습니다 : https://stackoverflow.com/questions/7986260/linux-interrupt-handling-in-user-space .
그런 다음 커널은보다 높은 수준의 API를 제공하여 이러한 하드웨어 상호 작용을보다 쉽고 휴대하기 쉽게 만듭니다.
request_irq
인터럽트 처리ioreadX
및 IO 메모리 매핑- PCI 및 USB와 같은 널리 사용되는 프로토콜을위한 더 높은 수준의 인터페이스
답변
내 대답은 짐과 함께 갈 것이다. 커널 드라이버는 하드웨어를 구동하도록 설계된 프로그램 (커널 모듈)입니다. lspci 출력에 따르면 nvidia는 loaded
장치 의 모듈 이므로 커널 드라이버 입니다. 이와 함께 사용 가능한 다른 커널 모듈도 제공됩니다.
나는 리눅스의 명령을 나열하고 드라이버는 제거 할 것을 추가 할 것입니다 lsmod
및 rmmod
각각. 목록 모듈이라고 말하고 모듈을 제거하십시오.
답변
모든 드라이버는 모듈입니다. 모든 모듈이 드라이버 인 것은 아닙니다.
런타임에 모듈을 삽입 할 수 있습니다. 커널과 함께 모듈 / 드라이버를 정적으로 컴파일 할 수 있습니다.
일반적인 모듈 초기화
module_init(init_fn);
init_fn()
{
/* some code */
}
동일한 모듈을 드라이버로 만들 수 있습니다
module_init(init_fn);
init_fn()
{
device_register(&device);
/* some code */
}