답변:
당신이 요구하는 것을 DMA라고합니다. 이 메모리를 예약하려면 드라이버를 작성해야합니다.
예, OS가 개입하기를 원하지 않으며 드라이버가 OS의 일부가된다는 것을 알고 있지만 드라이버 예약이 없으면 커널은 모든 메모리가 속한 것으로 생각합니다. (아론의 대답에 따라 메모리 블록을 무시하도록 커널에 지시하지 않는 한).
Rubini, Corbet 및 Kroah-Hartmann 의 " Linux 장치 드라이버, 3 / e " 15 장 (PDF)에서 DMA 및 관련 주제를 다룹니다.
이것의 HTML 버전을 원한다면, 온라인의 다른 곳 에서이 장의 두 번째 버전을 발견 했습니다 . 커널 2.4가 처음 등장했을 때, 2 판은 10 년이 넘었습니다. 그 이후로 커널의 메모리 관리 서브 시스템에 대한 많은 작업이 있었으므로 더 이상 적용되지 않을 수 있습니다.
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"
uint8_t *ptr = 0x8000000
예를 들어 " "를 추측 할까요? 아니면 그건 segfault ... 어, 난 정말 모르겠어요. 나는 제대로 설계되지 않은 PCI 카드의 최종 사용자 였기 때문에 4G 마크 아래에 버퍼를 수동으로 할당 한 다음 드라이버에게 해당 공간이 어디에 있는지 알려 주어야하기 때문에 대답을 알았습니다. 유저 랜드에서는 불가능할 수도 있습니다.
MMAP_FIXED | MMAP_ANON
. 여기에 재생할 커스텀 DMA 장치가 없으면 실제로 OP가 원하는 것을 수행 할 수 있는지 말할 수 없지만 CentOS 상자 memmap=8M$512M
는 GRUB에서 말했 을 때 512MB에서 8MB 블록을 행복하게주었습니다 . 내가 두려워 할 수도 있기 때문에 루트 액세스가 필요하지 않습니다. 그러나 이것이 옳은 일을하더라도 인터럽트 등을 처리하기 위해 드라이버가 필요할 것이라고 생각합니다.
mmap()
'd 사용자 페이지에서 페이지를보기 전에'd 페이지가 제로화되었습니다. 보안을 위해 수행되었으므로 한 프로세스에서 다른 프로세스로 데이터가 유출되지 않습니다. 드라이버를로드 할 때 DMA 버퍼의 내용을 보존해야 할 수도 있으므로 드라이버를 사용해야하는 또 다른 이유입니다. 어쨌든 임의로 mmap()
요청한 호출은 memmap
커널 부팅 옵션이 없어도 적어도 요청한 위치에 아무도 메모리를 사용하지 않는 한 성공합니다 . 부팅 옵션은 의심 할 여지없이 성공 가능성을 높여 주지만 꼭 필요한 것은 아닙니다.
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>;
};
};
먼저이 명령을 입력하여 현재 설정을 확인하십시오.
sysctl vm.min_free_kbytes
설정 값을 변경하려면을 편집하십시오 /etc/sysctl.conf
. 줄을 찾으십시오.
vm.min_free_kbytes=12888
존재하지 않는 경우 원하는 값과 함께 작성하십시오. 다음 값이 허용됩니다.
8192
12288
16384
20480
8M은 매우 보수적입니다. 16M에 편안하게 앉을 수 있습니다. 값을 변경 한 후이를 실행하면 재부팅 할 필요가 없습니다.
sudo sysctl -p