O que você está pedindo é chamado DMA. Você precisa escrever um driver para reservar esta memória.
Sim, eu sei que você disse que não queria que o sistema operacional intervenha, e um driver se torna parte do sistema operacional, mas, na ausência de uma reserva de driver, o kernel acredita que toda a memória pertence a ele. (A menos que você diga ao kernel para ignorar o bloco de memória, de acordo com a resposta de Aaron).
O capítulo 15 (PDF) de " Linux Device Drivers, 3 / e " de Rubini, Corbet e Kroah-Hartmann aborda o DMA e tópicos relacionados.
Se você quiser uma versão em HTML disso, encontrei a versão da segunda edição do capítulo online em outros lugares. Cuidado que a 2ª edição tem mais de uma década, tendo sido lançada quando o kernel 2.4 era novo. Tem havido muito trabalho no subsistema de gerenciamento de memória do kernel desde os dias, portanto ele pode não se aplicar muito bem.
Se você deseja que o sistema operacional o ignore totalmente , é necessário fazer um furo na memória usando "
memmap
." Veja esta referência . Por exemplo, se você quiser 512M na barreira de 2GB, poderá "memmap=512M$2G
" colocar na linha de comando do kernel.Você precisará verificar o seu
dmesg
para encontrar um buraco contíguo para roubar, para não pisar em nenhum dispositivo; Isso é específico para sua placa-mãe + placas.Esta não é a maneira recomendada de fazer as coisas - consulte a resposta de Warren Young para saber como fazê-lo corretamente (drivers do kernel + DMA). Estou respondendo a pergunta exata que você fez. Se você planeja fazer isso para os usuários finais, eles o odiarão se você fizer isso com eles ... confie em mim, essa é a única razão pela qual eu soube essa resposta.
Edit: Se você estiver usando o grub2 w / grubby (por exemplo, CentOS 7), você precisa se livrar do $ . Deve haver um único
\
antes$
. Exemplo:fonte
uint8_t *ptr = 0x8000000
" com o meu exemplo? Ou isso pode falhar ... Não sei mesmo. Novamente, eu sabia a resposta porque era um usuário final de uma placa PCI mal projetada, na qual tive que alocar manualmente um buffer abaixo da marca 4G e depois informar ao driver onde estava esse espaço; pode não ser possível na terra do usuário.MMAP_FIXED | MMAP_ANON
. Sem um dispositivo DMA personalizado para brincar, não posso dizer se ele realmente faz o que o OP queria, mas minha caixa do CentOS felizmente me deu um bloco de 8 MB a 512 MB quando faleimemmap=8M$512M
no GRUB. Nem sequer requer acesso root, como eu temia. Mas mesmo que isso faça a coisa certa, ainda acho que você provavelmente precisará de um driver para lidar com interrupções e coisas do tipo.mmap()
as páginas são zeradas antes que o código da terra do usuário as veja. Isso é feito por segurança, para que os dados não vazem de um processo para o outro. Outro motivo para usar um driver, pois pode ser necessário preservar o conteúdo do buffer DMA no momento do carregamento do driver. Ah, a propósito, ammap()
chamada localizada arbitrariamente é bem- sucedida mesmo sem amemmap
opção de inicialização do kernel, pelo menos enquanto ninguém estiver usando a memória localizada onde você pediu. A opção de inicialização sem dúvida aumenta as chances de sucesso, mas não é estritamente necessária.Para reservar um bloco de memória do kernel no Linux baseado em ARM, você também pode usar um
reserved-memory
nó no arquivo da árvore de dispositivos (dts). Na documentação do kernel (veja aqui ), há um exemplo:fonte
Primeiro, digite este comando para verificar sua configuração atual:
Para alterar o valor definido, edite
/etc/sysctl.conf
. Procure a linha:Se não existir, crie-o (junto com o valor desejado). Os seguintes valores são aceitáveis:
8M é extremamente conservador; pode sentar-se confortavelmente em 16M. Depois de alterar o valor, execute isso e nenhuma reinicialização é necessária:
fonte