Acesso à memória compartilhada do Linux I / O

2

Estou muito confuso sobre como o Linux gerencia a memória compartilhada de E / S para se comunicar com dispositivos que a usam.

Se eu entendi corretamente, o kernel do linux começa mapeado em 0x100000 (para evitar os dados do primeiro legado de megabytes e ser armazenado em locais de memória contígua) e depois de entrar no modo protegido:

  • em sistemas de 32 bits, há um mapeamento como este

O ZONE_NORMAL deve estar abaixo de 896 MB, então o mapeamento entre o kernel 1GB linear e o físico 896 MB é sempre possível. Vamos apenas ignorar o ZONE_DMA por enquanto (eu li que isso é apenas para sistemas legados, já que o PCI agora pode usar as transferências DMA em todos os lugares na memória)

  • em sistemas de 64 bits, o espaço de endereço linear do kernel deve começar em PAGE_OFFSET = 0xffff810000000000 e adiante

Em ambos os casos, se um endereço no espaço do kernel for maior que PAGE_OFFSET, deve se referir a um mapeamento ioremap (a ser resolvido através de paginação), se for menor que PAGE_OFFSET, pode ser resolvido com um simples NEW_ADDRESS = OLD_ADDRESS - PAGE_OFFSET . Está correto?

Pergunta bônus: quando o kernel está em funcionamento e a limpeza foi feita, ele ainda reside fisicamente de 0x100000 e adiante (dentro do primeiro GB)? Mesmo em sistemas de 64 bits?

    
por paulAl 28.03.2012 / 20:42

2 respostas

1

Nos PCs, os intervalos de E / S de mapeamento de memória de hardware são atribuídos pelo BIOS a endereços de memória física entre 3GiB e 4 GiB. Quando um driver solicita acesso à memória, o kernel o mapeia em algum lugar no espaço de endereço virtual do kernel.

Nenhuma de suas outras duas perguntas parece ter algo a ver com a memória compartilhada, mas:

In both cases, if an address in the kernel space is greater than PAGE_OFFSET, should refer to a ioremap mapping (to be resolved through pagination), if it's lower than PAGE_OFFSET it could be resolved with a simple NEW_ADDRESS = OLD_ADDRESS - PAGE_OFFSET. Is this correct?

Mentalmente, sim. O hardware usa as tabelas de páginas nos dois casos.

    
por 28.03.2012 / 21:37
0

Pense em sua pergunta, como o ioremap funciona ...

vaddr = ioremap (paddr_io_mapped_device, tamanho);

vaddr é retornado endereço virtual no espaço do kernel. O Kernel cria as entradas da tabela de páginas para o intervalo de endereços virtuais (vaddr, size) e as mapeia para o endereço físico paddr_io_shared_device. Então, se você acessar o intervalo de endereços virtuais, será tão bom quanto acessar o endereço físico dentro do diretório io_mapped.

Importante, o vaddr retornado é não cachable . Toda vez que você ler / escrever o intervalo de endereços, ele será lido / gravado no dispositivo io_mapped e não no cache.

    
por 05.09.2012 / 22:34