@hiro, você quer dizer "HIGHMEM" é "endereço virtual do kernel" como descrito por ldd3. Eu concordo com você. é confuso, o ldd3 definiu "LOWMEM" "HIGHMEM", também definiu "endereço virtual do kernel" "" endereço lógico do kernel ". eles são a mesma coisa, mas tem nome diferente. essa é a "beleza" do software, depende muito da descrição-linguagem.
Steve
Respostas:
69
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.
Isso é antigo e não tenho certeza de que você esteja por aqui. Mas quero perguntar uma coisa: os 128 MB reservados no espaço do kernel (para acesso de alta memória), são todas as referências da área de memória do espaço do usuário? Portanto, um processo do kernel pode acessar qualquer espaço do usuário consultando esta área, certo?
Amumu
1
Por que está sempre em 1/4? Ou seja, por que não poderia dividir 5/1 ou algo assim?
mgalgs
O que exatamente "pode acessar diretamente" significa aqui? Quero dizer, o próprio kernel não é acessado através do mecanismo de memória virtual?
Telnet #
1
Acredito que o que você diz sobre memória alta / baixa está errado: acredito que em um sistema puro de 32 bits, o kernel pode acessar diretamente os 3 GB completos de espaço do usuário (o kernel pode acessar o espaço do kernel e o espaço do usuário). No entanto, quando você tem um kernel PAE, as coisas ficam mais complexas, agora você tem mais de 3 GB de RAM, cada processo pode ter 3 GB e você não pode acessar todo o espaço do usuário diretamente. É aqui que entra o mem alto e os 128 MB de memória no espaço do kernel. Com um kernel de 64 bits, ele fica mais simples novamente, sem problemas, pois todo o espaço do usuário é acessível a partir do kernel.
ctrl-alt-delor
2
@mgalgs ¼, 2/4 e ¾ eram apenas um conjunto de opções padrão que foram expostas. Desde 2007, também é possível selecionar 5/16 e 15/32. Se você souber editar qual linha #define, poderá escolher uma divisão quase arbitrária.
jørgensen
28
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 kmapprimeiro, para obter um ponteiro de uma estrutura de dados da página ( struct page). A chamada kmapfunciona se a página está com memória alta ou baixa. Também há kmap_atomicrestriçõ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 kmapnovamente.
Obrigado Gilles pela resposta. Mas ainda não sou capaz de entender todo o conceito. Você poderia ser um pouco mais simples sem reduzir as informações contidas nele?
Sen
17
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.
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.
Respostas:
Em uma arquitetura de 32 bits, o intervalo do espaço de endereço para endereçar a RAM é:
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:
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:
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.fonte
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 chamadakmap
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 obtidokmap
é um recurso: ele usa espaço de endereço. Depois de terminar, você deve ligarkunmap
(oukunmap_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ê ligarkmap
novamente.fonte
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:
fonte
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.
fonte
Tanto quanto me lembro, "High Memory" é usado para o espaço do aplicativo e "Low Memory" para o kernel.
A vantagem é que aplicativos (espaço do usuário) não podem acessar a memória do espaço do kernel.
fonte
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.
fonte