Linux 커널에서 메모리 블록을 어떻게 예약 할 수 있습니까?


25

OS 개입없이 단독으로 예약 된 메모리 블록이 필요한 장치가 있습니다. 메모리 블록이 예약되어 있다고 BIOS 또는 OS에 알리는 방법이 있습니까?

이 장치를 openSUSE 시스템에서 사용하고 있습니다.

답변:


23

당신이 요구하는 것을 DMA라고합니다. 이 메모리를 예약하려면 드라이버를 작성해야합니다.

예, OS가 개입하기를 원하지 않으며 드라이버가 OS의 일부가된다는 것을 알고 있지만 드라이버 예약이 없으면 커널은 모든 메모리가 속한 것으로 생각합니다. (아론의 대답에 따라 메모리 블록을 무시하도록 커널에 지시하지 않는 한).

Rubini, Corbet 및 Kroah-Hartmann 의 " Linux 장치 드라이버, 3 / e " 15 장 (PDF)에서 DMA 및 관련 주제를 다룹니다.

이것의 HTML 버전을 원한다면, 온라인의 다른 곳 에서이 장의 두 번째 버전을 발견 했습니다 . 커널 2.4가 처음 등장했을 때, 2 판은 10 년이 넘었습니다. 그 이후로 커널의 메모리 관리 서브 시스템에 대한 많은 작업이 있었으므로 더 이상 적용되지 않을 수 있습니다.


DMA를 사용하여 사용할 물리적 주소를 선택할 수 있습니까? 커널이 연속적인 메모리 블록을 제공합니까? 항상 사용할 수 있습니까?
Nathan Fellman

1
귀하의 질문은 제가 지적한 PDF의 442 페이지에서 시작됩니다.
워렌 영

24

OS가 완전히 무시하도록하려면 ""를 사용하여 메모리 홀을 만들어야합니다 memmap. 이 참조를 참조 하십시오 . 예를 들어, 2GB 장벽에서 512M을 원하면 memmap=512M$2G커널 명령 줄에 " "를 넣을 수 있습니다 .

dmesg장치를 밟지 않도록 훔칠 연속 구멍을 찾기 위해 점검해야 합니다. 이는 마더 보드 + 카드에만 해당됩니다.

권장되는 방법 은 아닙니다 . 올바르게 수행하는 방법에 대한 Warren Young의 답변 (커널 드라이버 + DMA)을 참조하십시오. 나는 당신이 요구 한 정확한 질문에 대답하고 있습니다. 당신이 최종 사용자를 위해 이것을 만들 계획 이라면, 당신이 그들에게 이것을하면 그들이 당신 을 미워할 것입니다 ... 나를 믿으십시오. 이것이 내가이 대답을 알고있는 유일한 이유입니다.


편집 : grub2 w / grubby (예 : CentOS 7)를 사용하는 경우 $를 이스케이프해야합니다 . \전에 하나 있어야합니다 $. 예:

$ sudo -v
$ sudo grubby --update-kernel=ALL --args=memmap='128M\\$0x57EF0000'
$ sudo grubby --info $(sudo grubby --default-kernel) | grep memmap
args="ro crashkernel=auto ... memmap=128M\$0x57EF0000"

1
귀하의 답변이 내 질문에 직접 답변하지만 Warren의 답변은 더 나은 방법으로 보입니다. :-)
Nathan Fellman

1
@WarrenYoung 나는 당신이 그것으로 무엇을 해야할지 전혀 모른다. uint8_t *ptr = 0x8000000예를 들어 " "를 추측 할까요? 아니면 그건 segfault ... 어, 난 정말 모르겠어요. 나는 제대로 설계되지 않은 PCI 카드의 최종 사용자 였기 때문에 4G 마크 아래에 버퍼를 수동으로 할당 한 다음 드라이버에게 해당 공간이 어디에 있는지 알려 주어야하기 때문에 대답을 알았습니다. 유저 랜드에서는 불가능할 수도 있습니다.
Aaron D. Marasco

2
미소를 위해서, 나는 이것에 대해 조금 더 깊이 살펴 보았고, 그것은 당신이 필요로하는 것처럼 보입니다 MMAP_FIXED | MMAP_ANON. 여기에 재생할 커스텀 DMA 장치가 없으면 실제로 OP가 원하는 것을 수행 할 수 있는지 말할 수 없지만 CentOS 상자 memmap=8M$512M는 GRUB에서 말했 을 때 512MB에서 8MB 블록을 행복하게주었습니다 . 내가 두려워 할 수도 있기 때문에 루트 액세스가 필요하지 않습니다. 그러나 이것이 옳은 일을하더라도 인터럽트 등을 처리하기 위해 드라이버가 필요할 것이라고 생각합니다.
Warren Young

3
@ AaronD.Marasco : 아니요. mmap()'d 사용자 페이지에서 페이지를보기 전에'd 페이지가 제로화되었습니다. 보안을 위해 수행되었으므로 한 프로세스에서 다른 프로세스로 데이터가 유출되지 않습니다. 드라이버를로드 할 때 DMA 버퍼의 내용을 보존해야 할 수도 있으므로 드라이버를 사용해야하는 또 다른 이유입니다. 어쨌든 임의로 mmap()요청한 호출은 memmap커널 부팅 옵션이 없어도 적어도 요청한 위치에 아무도 메모리를 사용하지 않는 한 성공합니다 . 부팅 옵션은 의심 할 여지없이 성공 가능성을 높여 주지만 꼭 필요한 것은 아닙니다.
워렌 영

1
@ AaronD.Marasco 흠, 알았어. 흥미 롭군 그 링크에 감사드립니다. 잘 읽어보세요.
Woodrow Barlow

5

ARM 기반 Linux에서 커널에서 메모리 블록을 예약하기 reserved-memory위해 장치 트리 (dts) 파일에서 노드를 사용할 수도 있습니다 . 커널 문서 ( 여기 참조 )에는 예가 있습니다.

memory {
    reg = <0x40000000 0x40000000>;
};

reserved-memory {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges;

    /* global autoconfigured region for contiguous allocations */
    linux,cma {
        compatible = "shared-dma-pool";
        reusable;
        size = <0x4000000>;
        alignment = <0x2000>;
        linux,cma-default;
    };

    display_reserved: framebuffer@78000000 {
        reg = <0x78000000 0x800000>;
    };

    multimedia_reserved: multimedia@77000000 {
        compatible = "acme,multimedia-memory";
        reg = <0x77000000 0x4000000>;
    };
};

0

먼저이 명령을 입력하여 현재 설정을 확인하십시오.

sysctl vm.min_free_kbytes

설정 값을 변경하려면을 편집하십시오 /etc/sysctl.conf. 줄을 찾으십시오.

vm.min_free_kbytes=12888

존재하지 않는 경우 원하는 값과 함께 작성하십시오. 다음 값이 허용됩니다.

8192
12288
16384
20480

8M은 매우 보수적입니다. 16M에 편안하게 앉을 수 있습니다. 값을 변경 한 후이를 실행하면 재부팅 할 필요가 없습니다.

sudo sysctl -p

2
게시물을 비우지 마십시오. 이를 삭제하거나 중재자가 제거하도록 플래그를 지정하십시오.
jasonwryan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.