Estou interessado na diferença entre Highmem e Lowmem:
- Por que existe essa diferenciação?
- O que ganhamos ao fazer isso?
- Quais recursos cada um possui?
Estou interessado na diferença entre Highmem e Lowmem:
Respostas:
Em uma arquitetura de 32 bits, o intervalo do espaço de endereço para endereçar a RAM é:
0x00000000 - 0xffffffff
ou 4'294'967'295
(4 GB).
O kernel do linux divide isso em 3/1 (também pode ser 2/2 ou 1/3 1 ) no espaço do usuário (memória alta) e no espaço do kernel (memória baixa), respectivamente.
O intervalo de espaço do usuário:
0x00000000 - 0xbfffffff
Todo processo de usuário recém-gerado obtém um endereço (intervalo) dentro dessa área. Os processos do usuário geralmente não são confiáveis e, portanto, são proibidos de acessar o espaço do kernel. Além disso, eles são considerados não urgentes, como regra geral, o kernel tenta adiar a alocação de memória para esses processos.
O intervalo de espaço do kernel:
0xc0000000 - 0xffffffff
Um processo de kernel obtém seu endereço (intervalo) aqui. O kernel pode acessar diretamente esses 1 GB de endereços (bem, não os 1 GB completos, existem 128 MB reservados para acesso de memória alta).
Os processos gerados no espaço do kernel são confiáveis, urgentes e assumidos sem erros; a solicitação de memória é processada instantaneamente.
Todo processo do kernel também pode acessar o intervalo de espaço do usuário, se desejar. E para conseguir isso, o kernel mapeia um endereço do espaço do usuário (a memória alta) para o espaço do kernel (a memória baixa), os 128 MB mencionados acima são especialmente reservados para isso.
1 Se a divisão é 3/1, 2/2 ou 1/3, é controlada pela CONFIG_VMSPLIT_...
opção; você provavelmente pode conferir abaixo /boot/config*
para ver qual opção foi selecionada para o seu kernel.
A primeira referência a que se recorrer é o Linux Device Drivers (disponível on-line e em livro), particularmente o capítulo 15, que possui uma seção sobre o tópico.
Em um mundo ideal, todo componente do sistema seria capaz de mapear toda a memória necessária para acessar. E esse é o caso dos processos no Linux e na maioria dos sistemas operacionais: um processo de 32 bits pode acessar apenas menos de 2 ^ 32 bytes de memória virtual (na verdade, cerca de 3 GB em uma arquitetura típica de 32 bits do Linux). Fica difícil para o kernel, que precisa ser capaz de mapear a memória completa do processo cuja chamada de sistema está sendo executada, além de toda a memória física, além de qualquer outro dispositivo de hardware mapeado na memória.
Portanto, quando um kernel de 32 bits precisa mapear mais de 4 GB de memória, ele deve ser compilado com alto suporte de memória. Memória alta é a memória que não é permanentemente mapeada no espaço de endereço do kernel. (Pouca memória é o oposto: ela é sempre mapeada, para que você possa acessá-la no kernel simplesmente desreferenciando um ponteiro.)
Quando você acessa memória alta a partir do código do kernel, é necessário chamar kmap
primeiro, para obter um ponteiro de uma estrutura de dados da página ( struct page
). A chamada kmap
funciona se a página está com memória alta ou baixa. Também há kmap_atomic
restrições adicionais, mas que são mais eficientes em máquinas com multiprocessadores porque usam travas de granulação mais fina. O ponteiro obtido kmap
é um recurso: ele usa espaço de endereço. Depois de terminar, você deve ligar kunmap
(ou kunmap_atomic
) para liberar esse recurso; o ponteiro não será mais válido e o conteúdo da página não poderá ser acessado até você ligar kmap
novamente.
Isso é relevante para o kernel do Linux; Não tenho certeza de como qualquer kernel do Unix lida com isso.
A Memória alta é o segmento de memória que os programas de espaço do usuário podem endereçar. Não pode tocar em Pouca memória.
Pouca memória é o segmento de memória que o kernel do Linux pode endereçar diretamente. Se o kernel precisar acessar o High Memory, ele deverá mapeá-lo primeiro em seu próprio espaço de endereço.
Houve um patch introduzido recentemente que permite controlar onde o segmento está. A desvantagem é que você pode retirar a memória endereçável do espaço do usuário, para que o kernel possa ter mais memória que não precisa mapear antes de usar.
Recursos adicionais:
HIGHMEM é uma variedade de espaço de memória do kernel, mas NÃO é a memória que você acessa, mas é um lugar onde você coloca o que deseja acessar.
Um típico mapa de memória virtual Linux de 32 bits é como:
0x00000000-0xbfffffff: processo do usuário (3 GB)
0xc0000000-0xffffffff: espaço no kernel (1 GB)
(Vetor específico da CPU e tudo o que é ignorado aqui).
O Linux divide o espaço do kernel de 1 GB em 2 partes, LOWMEM e HIGHMEM. A divisão varia de instalação para instalação.
Se uma instalação escolher, digamos, 512 MB-512 MB para os itens LOW e HIGH, o LOWMEM de 512 MB (0xc0000000-0xdfffffff) será mapeado estaticamente no momento da inicialização do kernel; geralmente, os primeiros tantos bytes da memória física são usados para que os endereços físicos e virtuais nesse intervalo tenham um deslocamento constante de, digamos, 0xc0000000.
Por outro lado, os últimos 512 MB (HIGHMEM) não têm mapeamento estático (embora você possa deixar as páginas semi-permanentemente mapeadas lá, mas você deve fazê-lo explicitamente no código do driver). Em vez disso, as páginas são temporariamente mapeadas e não mapeadas aqui, para que os endereços físicos e virtuais nesse intervalo não tenham um mapeamento consistente. Os usos típicos do HIGHMEM incluem buffers de dados únicos.
Muitas pessoas disseram que a pouca memória é para o sistema operacional. Isso geralmente é verdade, mas não precisa ser. Memória alta e pouca memória são apenas duas partes do espaço de memória, mas no sistema Linux, pouca memória é apenas para o kernel e alta memória para os processos do usuário.
De acordo com o "Livro dos dinossauros (conceitos de sistema operacional)", podemos colocar o sistema operacional em pouca memória ou alta memória. O principal fator que afeta essa decisão é a localização do vetor de interrupção. Como o vetor de interrupção geralmente está com pouca memória, os programadores geralmente também colocam o sistema operacional em pouca memória.