O que o Layout de memória do kernel virtual no dmesg implica?

19

Ao passar pela "Saída do dmesg" , pude ver uma lista de valores que não consigo entender corretamente.

Memory: 2047804k/2086248k available (3179k kernel code, 37232k reserved, 1935k data, 436k init, 1176944k highmem)
virtual kernel memory layout:
    fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)
    pkmap   : 0xff800000 - 0xffa00000   (2048 kB)
    vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)
    lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)
      .init : 0xc0906000 - 0xc0973000   ( 436 kB)
      .data : 0xc071ae6a - 0xc08feb78   (1935 kB)
      .text : 0xc0400000 - 0xc071ae6a   (3179 kB)

A partir dos valores, entendo que tenho 2 GB de RAM (memória física). Mas o resto das coisas parece ser números mágicos para mim.

Gostaria de saber sobre cada um (fixmap, pkmap, etc. etc.) em breve (se houver mais dúvidas, vou postar cada um como uma pergunta separada)?

Alguém poderia me explicar isso?

Sen
fonte

Respostas:

22

Primeiro, um sistema de 32 bits possui 0xffffffff( 4'294'967'295) endereços lineares para acessar um local físico no topo da RAM.
O kernel divide esses endereços no espaço do usuário e do kernel.

O espaço do usuário (memória alta) pode ser acessado pelo usuário e, se necessário, também pelo kernel.
O intervalo de endereços em notação hex e dec:

0x00000000 - 0xbfffffff
0 - 3'221'225'471

O espaço do kernel (pouca memória) pode ser acessado apenas pelo kernel.
O intervalo de endereços em notação hex e dec:

0xc0000000 - 0xffffffff
3'221'225'472 - 4'294'967'295

Como isso:

0x00000000             0xc0000000  0xffffffff 
    |                        |          |
    +------------------------+----------+
    |  User                  |  Kernel  |
    |  space                 |  space   |
    +------------------------+----------+

Assim, o layout da memória que você viu dmesgcorresponde ao mapeamento de endereços lineares no espaço do kernel.

Primeiro, as seqüências .text, .data e .init que fornecem a inicialização das próprias tabelas de páginas do kernel (traduzem linearmente em endereços físicos).

.text : 0xc0400000 - 0xc071ae6a   (3179 kB)

O intervalo em que o código do kernel reside.

.data : 0xc071ae6a - 0xc08feb78   (1935 kB)

O intervalo em que os segmentos de dados do kernel residem.

.init : 0xc0906000 - 0xc0973000   ( 436 kB)

O intervalo em que residem as tabelas de páginas iniciais do kernel.

(e outros 128 kB para algumas estruturas de dados dinâmicas.)

Esse espaço mínimo de endereço é grande o suficiente para instalar o kernel na RAM e inicializar suas estruturas de dados principais.

Seu tamanho usado é mostrado entre parênteses, por exemplo, o código do kernel:

0xc071ae6a - 0xc0400000 = 31AE6A

Em notação decimal, isso é 3'255'914(3179 kB).


Segundo, o uso do espaço do kernel após a inicialização

lowmem  : 0xc0000000 - 0xf77fe000   ( 887 MB)

O intervalo lowmem pode ser usado pelo kernel para acessar diretamente endereços físicos.
Esse não é o total de 1 GB, porque o kernel sempre exige pelo menos 128 MB de endereços lineares para implementar alocação de memória não contígua e endereços lineares mapeados para correção.

vmalloc : 0xf7ffe000 - 0xff7fe000   ( 120 MB)

A alocação de memória virtual pode alocar quadros de página com base em um esquema não contíguo. A principal vantagem desse esquema é evitar a fragmentação externa, usada para áreas de troca, módulos do kernel ou alocação de buffers para alguns dispositivos de E / S.

pkmap   : 0xff800000 - 0xffa00000   (2048 kB)

O mapeamento permanente do kernel permite que o kernel estabeleça mapeamentos duradouros de quadros de página de alta memória no espaço de endereço do kernel. Quando uma página HIGHMEM é mapeada usando kmap (), os endereços virtuais são atribuídos a partir daqui.

fixmap  : 0xffc57000 - 0xfffff000   (3744 kB)

Esses são endereços lineares mapeados para correção que podem se referir a qualquer endereço físico na RAM, e não apenas aos últimos 1 GB, como os endereços lowmem. Os endereços lineares com mapeamento de correção são um pouco mais eficientes do que seus colegas lowmem e pkmap. Existem descritores de tabela de páginas dedicados designados para mapeamento fixo, e os mapeamentos de páginas HIGHMEM usando kmap_atomic são alocados a partir daqui.


Se você quiser mergulhar mais fundo na toca do coelho:
Noções básicas sobre o kernel do Linux

abanar
fonte
Obrigado por esta ótima resposta. Eu gostaria de saber por que o mem baixa memória não está cheio de 1 GB e mais sobre a próxima parte da frase "porque o kernel sempre exige pelo menos 128 MB de endereços lineares para implementar alocação de memória não contígua e endereços lineares mapeados para correção".
Sen
O kernel precisa acessar o código de memória alta de tempos em tempos (as informações da BIOS e ACPI residem nos primeiros MB da RAM), ele não pode fazer isso diretamente (como a área de baixa memória), portanto, ele precisa mapear a memória baixa para endereços lineares de alta memória, os 128 MB são reservados apenas para esse fim. A área do vmalloc é geralmente mapeada temporariamente em algumas áreas de alta memória e o remapeamento de get é bastante rápido.
wag
Portanto, as páginas configuradas pelo kernel para a chamada do sistema virtual também fazem parte do fixmap ??? Eu me deparei com essa pergunta porque quero saber exatamente o que está na página com o endereço fffb5000, fffa1000 etc ... Estou ficando sobrecarregado no meu replay de registro de máquina virtual porque muitas CPUs virtuais acessam MUITA página ... como fazer Eu sei o que é exatamente nesse endereço ... grande resposta pela maneira :)
Deep Thought