Linux에서 일반적으로 사용되는 기능 소개(3)


gettimeofday

gettimeofday현재 시간과 날짜의 정확한 값을 얻기 위해 UNIX 및 UNIX 유사 시스템에서 일반적으로 사용되는 함수입니다. <sys/time.h>헤더 파일에 있으며 다음을 사용하여 호출할 수 있습니다.

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

gettimeofday이 함수는 struct timeval *tv및 의 두 가지 매개변수를 허용합니다 struct timezone *tz. 얻은 시간 값을 저장하는 데 사용되는 구조에 대한 포인터 tv입니다 . 시간대 정보를 얻는 데 사용되는 구조에 대한 포인터 입니다 (최신 시스템에서는 이 매개변수가 더 이상 사용되지 않으며 전달될 수 있음 ).timevaltztimezoneNULL

timeval구조는 다음과 같이 정의됩니다.

struct timeval {
    
    
    time_t tv_sec;  // 秒数
    suseconds_t tv_usec;  // 微秒数
};

gettimeofday함수가 성공적으로 실행되면 현재 시간과 날짜 정보가 tv매개변수가 가리키는 구조체 에 저장됩니다 timeval.

gettimeofday다음은 현재 시간을 얻기 위해 함수를 사용하는 간단한 예 입니다 .

#include <stdio.h>
#include <sys/time.h>

int main() {
    
    
    struct timeval tv;
    if (gettimeofday(&tv, NULL) == 0) {
    
    
        printf("Current time: %ld seconds, %ld microseconds\n", tv.tv_sec, tv.tv_usec);
    } else {
    
    
        printf("Failed to get the current time.\n");
    }
    return 0;
}

gettimeofday성공하면 0이 반환되고 실패하면 -1이 반환됩니다 . 성공하면 tv.tv_sec및 필드에 액세스하여 tv.tv_usec초 및 마이크로초 값을 얻을 수 있습니다 .

이 기능이 마이크로초 수준의 시간 정확도를 제공한다는 점은 주목할 가치가 있지만 일부 새로운 시스템에서는 더 높은 정밀도의 타이밍 기능을 제공하는 gettimeofday와 같은 보다 현대적인 기능을 사용하는 것이 좋습니다 .clock_gettime

kmalloc

kmalloc커널 공간 메모리를 동적으로 할당하는 데 사용되는 Linux 커널의 함수입니다. 커널 코드 및 데이터에 사용할 수 있는 메모리 블록을 런타임에 할당하기 위해 커널에서 제공하는 메모리 할당 메커니즘입니다.

kmalloc함수의 프로토타입은 <linux/slab.h>헤더 파일에 정의되어 있으며 일반적인 사용법은 다음과 같습니다.

void* kmalloc(size_t size, gfp_t flags);
  • size매개변수는 할당할 메모리 블록의 크기(바이트)를 지정합니다.
  • flags매개변수는 메모리 할당 동작을 제어하는 ​​데 사용되는 플래그입니다. 다음 플래그 중 하나이거나 이들의 조합일 수 있습니다.
    • GFP_KERNEL: 일반 커널 메모리 할당을 나타냅니다.
    • GFP_ATOMIC: 원자 메모리 할당을 나타내며, 스핀 잠금으로 보호되는 인터럽트 컨텍스트 또는 중요 영역에 메모리를 할당하는 데 적합합니다.
    • GFP_DMA: DMA 연산에 사용할 수 있는 메모리 할당을 나타냅니다.
    • GFP_NOWAIT기타 플래그: 등과 GFP_HIGHUSER같은 특정 메모리 할당 동작을 지정하는 데 사용할 수 있는 다른 플래그가 있습니다.

kmalloc이 함수는 할당된 메모리 블록에 대한 포인터를 반환하거나 할당이 실패한 경우 반환합니다 NULL.

kmalloc할당된 메모리를 사용한 후에는 해당 kfree함수를 사용하여 메모리를 해제해야 메모리 누수를 방지할 수 있다는 점에 유의하세요 .

전체적으로 kmalloc커널 공간 메모리를 동적으로 할당하는 데 사용되는 Linux 커널의 기능으로, 런타임 시 메모리 블록을 할당하고 필요에 따라 다양한 할당 전략과 플래그를 선택할 수 있는 편리한 방법을 제공합니다.


dev_t

dev_tLinux 커널에서 장치 번호를 나타내는 데 사용되는 데이터 유형입니다. 장치 번호는 시스템에서 장치를 고유하게 식별하는 값입니다.

Linux 시스템에서 장치는 물리적 장치(예: 하드 디스크, 직렬 포트 등) 또는 가상 장치(예: 가상 파일 시스템, 의사 터미널 등)일 수 있습니다. 각 장치에는 커널 내에서 장치를 식별하고 액세스하는 데 사용되는 고유한 장치 번호가 할당됩니다.

dev_t유형 변수는 일반적으로 메이저 번호와 마이너 번호의 두 부분으로 구성됩니다. 주요 장치 번호는 장치 유형을 식별하는 반면, 보조 장치 번호는 동일한 장치 유형의 다른 인스턴스 또는 파티션을 식별합니다.

사용자 공간에서는 makedev매크로를 사용하여 주요 장치 번호와 보조 장치 번호를 단일 dev_t유형의 장치 번호로 결합할 수 있습니다. 예를 들어:

dev_t device = makedev(major_number, minor_number);

그런 다음 MAJORMINOR매크로를 사용하여 장치 번호에서 주 장치 번호와 부 장치 번호를 추출할 수 있습니다. 예를 들어:

unsigned int major = MAJOR(device);
unsigned int minor = MINOR(device);

커널 개발에서 dev_t유형 장치 번호는 장치를 고유하게 식별하고 작동하기 위해 장치 드라이버에서 자주 사용됩니다. 장치 번호는 장치 등록, 장치 파일 열기, 장치 작업 수행에 중요한 역할을 합니다.

Unsigned int 유형, 32 비트, 드라이버에서 장치 번호를 정의하는 데 사용됩니다. 상위 12 비트는 기본 장치 번호이고 하위 20 비트는 부 장치 번호입니다.

정리하면 dev_t리눅스 커널에서 장치 번호를 나타내는 데 사용되는 데이터 타입으로, 메이저 장치 번호(Major Device Number)와 마이너 장치 번호(Minor Device Number)로 구성되며, 시스템 내에서 장치를 고유하게 식별하는 데 사용된다.


alloc_chrdev_region

alloc_chrdev_region리눅스 커널에서 제공하는 기능으로 커널 내 문자 장치의 주요 장치 번호 범위를 동적으로 할당하는데 사용된다.

Linux 시스템에서 문자 장치는 /dev/tty문자 장치 파일(예:)을 통해 장치에 대한 액세스를 제공하는 특수 클래스의 장치입니다. 각 문자 장치에는 장치 유형을 식별하는 고유한 주요 번호가 있습니다.

alloc_chrdev_region함수의 프로토타입은 다음과 같습니다.

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, const char *name);
  • devdev_t할당된 장치 번호 범위를 받는 유형의 변수에 대한 포인터 입니다 .
  • firstminor할당할 장치 번호 범위의 첫 번째 부 장치 번호입니다.
  • count할당할 장치 번호 범위 내의 장치 개수입니다.
  • name에서 장치 정보를 표시하는 데 사용되는 선택적 장치 이름입니다 /proc/devices.

alloc_chrdev_region함수를 호출한 후 커널은 연속적인 장치 번호 범위를 할당하고 이를 dev포인터가 가리키는 변수에 저장합니다. 할당된 디바이스 번호 범위의 메이저 디바이스 번호는 MAJOR(*dev)에서 가져오고, 마이너 디바이스 번호는 MINOR(*dev)에서 가져옵니다.

이 함수는 자신이 지정한 첫 번째 마이너 장치 번호(보통 0)와 할당할 장치 수, 개수, 장치 이름을 전달해야 하며, 이 함수 호출 후 자동으로 할당된 장치 번호는 dev에 저장됩니다.
장치 번호의 동적 할당은 장치 번호를 수동으로 지정함으로써 발생하는 단점을 피할 수 있지만 장치 노드 생성 /dev방법을 .

unregister_chrdev_region할당된 디바이스 번호 범위 사용을 마친 후에는 해당 범위를 해제하는 기능을 이용해야 합니다 . 예를 들어:

unregister_chrdev_region(*dev, count);

alloc_chrdev_region함수 unregister_chrdev_region는 일반적으로 문자 장치 드라이버의 초기화 및 정리 단계에서 장치 번호 범위를 할당하고 해제하는 데 사용됩니다.

정리하면, 리눅스 커널에서 캐릭터 디바이스의 주요 디바이스 번호 범위를 동적으로 할당alloc_chrdev_region 하는데 사용되는 함수로 , 디바이스 번호 범위를 할당하여 캐릭터 디바이스 등록 및 사용 시 편리한 방법을 제공한다.

장치 번호를 할당하는 방법에는 정적 및 동적의 두 가지 방법이 있습니다. 정적할당 ( register_chrdev_region()기능)이란 해당 디바이스의 메이저 디바이스 번호를 미리 알고 있을 때, 파라미터 함수를 통해 첫 번째 디바이스 번호(보통 마이너 디바이스 번호는 0임)를 지정하고, 일정 개수만큼 할당하는 시스템을 적용하는 것을 말한다. 장치 번호. 동적 할당 ( alloc_chrdev_region())이란 첫 번째 마이너 디바이스 번호(보통 0, 메이저 디바이스 번호를 미리 알 수 없음)와 파라미터를 통해 할당할 디바이스 개수만 설정하여 시스템이 필요한 디바이스 번호를 동적으로 할당하는 것을 의미한다. 기능을 통해 unregister_chrdev_region()할당된(정적이든 동적이든) 장치 번호를 해제합니다 .

cdev

정적 메모리 정의 초기화:

struct cdev my_cdev;
cdev_init(&my_cdev, &fops);
my_cdev.owner = THIS_MODULE;

동적 메모리 정의 초기화:

struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &fops;
my_cdev->owner = THIS_MODULE;
int cdev_add(struct cdev *, dev_t, unsigned);  
 注册字符设备,传入 cdev 结构的指针,起始设备编号,
 以及设备编号范围。cdev_del() 函数来释放 cdev 占用的内存。

kstrtoul

kstrtoul문자열을 부호 없는 긴 정수( )로 변환하기 위해 Linux 커널에서 제공되는 함수입니다 unsigned long.

함수 프로토타입은 다음과 같습니다.

int kstrtoul(const char *s, unsigned int base, unsigned long *res);
  • s변환할 문자열입니다.
  • base0x문자열이 나타내는 값의 밑을 지정하는 기본 숫자로, 2에서 36 사이의 값일 수 있으며, 0은 문자열 접두사(예: 16진수) 를 기준으로 기본이 자동으로 결정됨을 의미합니다.
  • resunsigned long변환된 결과를 수신하는 데 사용되는 형식 변수에 대한 포인터 입니다 .

이 함수는 s문자열을 unsigned long으로 구문 분석하고 결과를 res포인터가 가리키는 변수에 저장합니다. 변환이 성공하면 함수는 0을 반환하고, 변환이 실패하면 해당 오류 코드가 반환됩니다.

kstrtoul함수는 사용자 공간에서 전달된 매개변수나 구성 항목을 구문 분석하기 위해 커널에서 널리 사용됩니다. 커널에서 처리하고 사용하기 위해 문자열을 unsigned long으로 변환하는 안전하고 안정적인 방법을 제공합니다.

요약하면 kstrtoul문자열을 부호 없는 긴 정수로 변환하는 데 사용되는 Linux 커널의 함수이며, 사용자 공간에서 전달되는 매개변수나 구성 항목을 구문 분석하는 데 자주 사용됩니다. 문자열을 숫자로 변환하는 안전하고 안정적인 방법을 제공합니다.

추천

출처blog.csdn.net/qq_44710568/article/details/131953418