Sumário
• Estruturas de suporte à paginação
• Entrada de tabela de páginas
• Visão geral da tradução de um endereço virtual
• Gestão de memória no csoker
– Layout do espaço de endereçamento linear
– Layout da memória física
– Alocação/libertação de page frames
– Construção do espaço de endereçamento sistema
(
build_system_address_space
)
– Construção do espaço de endereçamento utilizador (
build_address_space
)
– Libertação de espaço de endereçamento (
free_address_space
)
Estruturas de dados de suporte à paginação
Directoria de tabelas de páginas
(page directory)
CR3
Entrada
directoria
0
1023
Entrada
tabela de
páginas
0
1023
Memória física
(page frames)
Endereço virtual linear
22
31 21 12 11 0
Entrada de tabela de páginas
0
11
12
31
20 bits mais significativos do endereço da page frame
R
P
/
W
S
/
U
0
0
A
D
0
0
Available
P
– Present (indica que a página está associada a uma page frame)
R/W
– Read/Write (indica se a página pode ser modificada)
S/U
– Superviser/User (indique que a página pode ser usada em user mode)
0
– bits reservados (já utilizados em versões mais recentes do CPU)
Bits alterados automaticamente pela MMU:
A
– Acessed (indica que a página for acedida)
D
– Dirty (indica que a página foi modificada
Endereço virtual Segmentado/Paginado
Selector Offset
Endereço Virtual Segmentado
Tabela de Descritores (GDT,LDT) + Endereço Base 0 31 0 15 0 Descritor de Segmento
Directoria de tabelas de páginas (page directory) CR3 Entrada directoria 0 102 3 Entrada tabela de páginas 0 102 3 Memória física (page frames)
Endereço virtual linear
22 21 12 11
Page frame
Espaço de endereçamento virtual
0x0
0xC0000000 KERNEL_VSTART
0x1000 User Start Address (USER_START)
0xC0100000 Kernel code
0xC00A0000 UMA
Identity mapping
to physical memory
O espaço de endereçamento dos processos acessível em código utilizador é sempre contíguo,
com início em USER_START (0x1000)
System address
space
User address
space
Layout da memória física
Kernel code
0x0
0xA0000 UMA
0x1000
0x100000 +Kernel size
0x100000
Reservada pelo
BIOS
Livre
Upper memory area
Livre
Gestão da memória física
1
2
1
2
3
1
1
1
head_free_pages
Espaços de Endereçamento
typedef struct phys_mem_desc {
page_frame_t page_pool[PHYS_PAGES]; page_frame_t * head_free_pages;
unsigned int num_free_pages; /* free pages counter */ } phys_mem_desc_t;
A memória física é descrita por uma pela estrutura
phys_mem_desc_t phys_mem. O campo
page_poolcontém um
array de descritores de page frames que permitem ligar em lista page frames não utilizadas, e manter um contador
de espaços de endereçamento que referenciam page frames ocupadas.
typedef union page_frame { union page_frame * next; U32 nrefs; } page_frame_t;
Gestão de memória física (2) –
alocar e libertar page
frames
Descrição: liberta page frame
Entradas: endereço físico da page frame a libertar Retorna: nada
void free_page(phys_address pa) {
page_frame_t * frame endereço virtual (no espaço de endereçamento sistema) de pa decrementa contador de referências de frame
se (contador de referências de pa == 0)
insere pa à cabeça da lista de page frames livres incrementa contador de page frames livres
fim se
}
Descrição: aloca page frame Entradas: não tem
Retorna: endereço virtual (no espaço de endereçamento sistema – acima de KERNEL_VSTART) char * page_frame_alloc() {
se lista descritores de page frames livres vazia
panic("Memory exausted");
senão
page_frame_t * frame page frame retirada à cabeça da lista contador de referências de frame = 1
decrementa contador de page frames livres
fim se
retorna: endereço virtual correspondente a frame ocupada
Gestão de memória física (3)
–
funções de alocação complementares
Descrição: aloca page frame iniciada com zeros
Entradas: não tem
Retorna:
endereço virtual (no espaço de endereçamento sistema – acima de KERNEL_VSTART)
char * page_frame_alloc_zero() {
char * mem page_frame_alloc();
fill_zero(mem, PAGE_SIZE);
retorna: mem;
}
Descrição: retorna page directory a usar na definição de espaço de endereçamento de código utilizador
Entradas: não tem
Retorna:
endereço virtual de page directory no espaço de endereçamento sistema (acima de
KERNEL_VSTART)
page_table_t create_user_page_dir() {
page_table_t page_dir page_frame_alloc();
memcpy(page_dir, kernel_page_dir, PAGE_SIZE);
retorna: page_dir;
Construção do espaço de endereçamento
sistema-build_system_address_space
page_table_t build_system_address_space(U32 imagestart, U32 size, int delayload) {
U32 start_address KERNEL_VSTART
// endereço inicial do novo espaço de
endereçamento
U32 end_address KERNEL_VSTART + PHYS_MEM -1 // limite do espaço de endereçamento
U32 pcurr PADDR(start_address); // endereço corrente na memória física
page_table_t pd alloc_page_frame_zero() // nova page directory
para cada entrada
i
de pd que define o espaço de endereçamento sistema
page_table_t pt alloc_page_frame_zero() // nova page table
pd[i] { pageframe = PADDR(pt); flags = supervisor, present, read/write }
para cada entrada j ocupada em pt
pd[i] { pageframe = pcurr; flags = user,present,read/write }
fim para
pcurr pcurr + PGSIZE
fim para
retorno: pd
}
Descrição:
mapeia linearmente a memória física a partir do endereço virtual KERNEL_VSTART (e ao mesmo tempo o espaço de endereçamento do kernel)Entradas:
não temConstrução do espaço de endereçamento-
build_address_space
int build_address_space(address_space_t *mem, int delayload) {
U32 start_address USER_START // endereço inicial do novo espaço de endereçamento U32 end_address start_address + mem->size-1 // dimensão do novo espaço de endereçamento U32 scurr mem->image_sector // sector inicial da imagem
page_table_t pd create_user_page_dir() //cópia da page directory template (kernel_page_dir)
para cada entrada i de pd que define o novo espaço de endereçamento
page_table_t pt alloc_page_frame_zero() // nova page table
pd[i] { pageframe = PADDR(pt), flags = user, present, read/write }
para cada entrada j ocupada em pt
se (demand paging) // delayload == 1
char *vpn alloc_page_frame_zero() // nova page frame
ler sectores a partir de scurr para page frame referida em vpn
pd[i] { pageframe = PADDR(vpn), flags = user,present,read/write }
senão
pd[i] { pageframe = 0, flags = user,read/write }
fim se fim para
scurr += Sectores por página
fim para
mem->page_dir =pd retorno: sucesso
}
Descrição: constrói o espaço de endereçamento de processo utilizador
Entradas:
mem – adress_space parcialmente preenchido (já com size e sector inicial) delayload – indica se se usa demand paging na alocação de page framesSaídas: mem - adress space já com endereço físico da página directoria
Liberta espaço de endereçamento –
free_address_space
void free_address_space(address_space_t *as) {
U32 start_address = USER_START // endereço inicial do novo espaço de endereçamento a libertar U32 end_address = USER_START + as->size-1 // limite do espaço de endereçamento
page_table_t pd page directory cópia da page directory template (kernel_page_dir)
para cada entrada i de pd que define o espaço de endereçamento sistema
page_table_t pt page table referida pela entrada i de pd
para cada entrada j ocupada em pt
free_page(page frame da entrada j) // libertar page frame
fim para
free_page(page frame que contem pt) fim para
free_page(page frame que contem pd) }
Descrição: liberta um espaço de endereçamento identificado por uma page directory e uma dimensão Entradas: espaço de endereçamento as