No kernel do Linux de 64 bits, quanta memória é mapeada de forma contígua pelo kernel?
Examinei o Linux Kernel Development de Robert Love e outras fontes. E em todos os lugares ele menciona que em um sistema x86 de 32 bits o kernel possui o topo de 1 GB do espaço de endereço virtual, dos quais até 896 MB são mapeados de forma contígua na memória física (chamada ZONE_NORMAL) o resto é mapeado nos 128 MB restantes conforme necessário e não pode ser contíguo (ZONE_HIGHMEM).
Em 64 bits, o problema de não ter espaço de endereço virtual suficiente é eliminado. E o mapa de memória é descrito como,
0xffffffffffffffff +-----------+
| |
| | Kernelspace
| |
0xffff800000000000 +-----------+
| |
| |
| hole |
| |
| |
0x00007fffffffffff +-----------+
| |
| | Userspace
| |
0x0000000000000000 +———————————+
No entanto, não está claro, neste mapa, quanto do espaço do kernel deve ser fisicamente contíguo (conforme definido em ZONE_NORMAL). e quanto é mapeado conforme necessário.
ZONE_HIGHMEM no kernel de 64 bits é sempre 0? Uma vez que toda a memória está dentro do alcance do espaço de endereço virtual?
Mas a memória contígua fixa do kernel (que não é paginável) também precisaria ser pequena, uma vez que esse pedaço de memória física nunca estaria disponível para outros processos do usuário. Portanto, o kernel requereria o uso de memória que não precisa ser contígua (como ZONE_HIGHMEM), conforme necessário. Isso entra em conflito com o ZONE_HIGHMEM sendo vazio em kernels de 64 bits.
Portanto, estou confuso sobre quanto do espaço do kernel é fixo fisicamente contíguo e quanto é não contíguo no caso de kernels de 64 bits.
Respostas
Não há HIGHMEMno x86 de 64 bits - CONFIG_HIGHMEMdependeX86_32 .
Existem dois mapeamentos fixos de memória física em x86 de 64 bits :
ffff888000000000 | -119.5 TB | ffffc87fffffffff | 64 TB | direct mapping of all physical memory (page_offset_base)
e a área começando em
ffffffff80000000 | -2 GB | ffffffff9fffffff | 512 MB | kernel text mapping, mapped to physical address 0
(endereços negativos são deslocamentos do final do espaço de endereço).
Este último corresponde ao que você está pensando, pelo que eu posso dizer, e tende a ser pequeno; veja a linha “Memória” mostrada durante a inicialização:
Memory: 20144992K/20660008K available (14339K kernel code, 2406K rwdata, 8340K rodata, 2488K init, 5116K bss, 515016K reserved, 0K cma-reserved)
(pouco menos de 30 MiB) e qualquer memória bloqueada por módulos carregados posteriormente.