Neste trabalho iremos implementar funções de controle de memória em um sistema operacional para uma arquitetura de memória fictícia.
Antes de começar a implementar as funções necessárias para controle de memória no seu sistema operacional, estude o código fonte do simulador de memória virtual disponível nestes links [vmm.c, vmm.h]. A documentação do seu trabalho deve conter respostas para todas as perguntas nos comentários do código fonte do simulador. Em particular, voce deve documentar como endereços virtuais são convertidos para endereços físicos pelo controlador.
Antes de começar a executar processos e fazer o controle da memória, seu sistema operacional tem a chance de inicializar variáveis e a memória do computador. Você deve colocar seu código de inicialização dentro de uma função os_init definida como abaixo:
void os_init(void);
Dentre as operações que precisam ser realizadas por os_init estão (1) a inicialização de uma estrutura de dados que identifica os quadros livres na memória física e (2) a inicialização do controlador de memória para execução do primeiro processo.
Após a execução da função os_init seu sistema operacional deve estar pronto para executar o primeiro processo (comumente chamado de init). Seu sistema operacional deve ser capaz de atender pedidos de alocação de memória realizados pelo processo bem como tratar falhas de páginas.
As operações realizadas por processos serão lidas de um arquivo e simuladas de acordo com a função main no simulador disponível neste link [main.c]. As linhas do arquivo podem conter quatro tipos de operação:
Note que as operações read e write são enviadas diretamente ao controlador de memória e utilizam a última tabela de páginas configurada pelo sistema operacional. Abaixo seguem alguns exemplos de arquivos de teste:
Arquivo 1:
# falha de segmentação em leitura de endereço não alocado: read 0x0
Arquivo 2:
alloc 0x0 # leitura de posição não inicializada (lixo): read 0x0 write 0x0 1 # lendo o valor 1 read 0x0 # falha de segmentação em escrita em endereço não alocado: write 0x2000 2
Arquivo 3:
# erro de alocação de memória: # (endereço não é múltiplo do tamanho dos quadros) alloc 0x40
Arquivo 4:
alloc 0x200 write 0x200 0x3 free 0x200 # segfault: read 0x200
Nesta parte do trabalho você deve implementar as funções os_alloc para alocar memória ao processo atual, os_free para liberar memória alocada por um processo, e os_pagefault para tratar falhas de página. Estas funções têm o seguinte cabeçalho:
void os_alloc(uint32_t virtaddr); void os_free(uint32_t virtaddr); void os_pagefault(uint32_t virtaddr, uint32_t perm, uint32_t pte);
Nas partes 3 e 4 você pode assumir que existem quadros livres para atender as requisições de alocação de memória. Você irá implementar memória virtual para contornar falta de quadros de memória na Parte 5.
Nesta parte do trabalho iremos dar suporte à execução de múltiplos processos compartilhando a memória. Cada processo deve ter seu próprio espaço de endereçamento virtual, independente dos espaços de endereçamento dos outros processos em execução. Para a criação de processos, o arquivo de entrada para o simulador suporta também o seguinte comando:
Seu sistema operacional deve implementar a função os_swap para trocar processos, com o seguinte cabeçalho:
void os_swap(uint32_t pid);
Sua função os_swap deverá implementar controle de processos. Em particular, seu sistema operacional precisa controlar onde está a tabela de páginas de cada processo. O arquivo de teste abaixo testa a execução de dois processos com espaços de endereçamento disjuntos:
swap 1 alloc 0x200 alloc 0x300 write 0x200 0x1 write 0x201 0x2 write 0x202 0x3 write 0x300 0x1 swap 2 alloc 0x200 write 0x200 0x10 write 0x201 0x20 write 0x202 0x30 swap 1 # lendo 0x1: read 0x200 read 0x201 read 0x202 read 0x300 swap 2 # lendo 0x10: read 0x200 # proximo acesso a memoria causa um segfault: read 0x300
Até este ponto assumimos que existia um quadro livre sempre que o sistema operacional precisava de um novo quadro de memória. Esse pode não ser o caso quando processos alocam muita memória.
Nesta parte do trabalho você irá estender seu sistema operacional com um sistema de memória virtual. Quando não houver quadros livres na memória principal, seu sistema operacional deverá liberar espaço na memória principal copiando páginas da memória principal no disco.
Proponha um mecanismo para controle de memória virtual na arquitetura simulada. Implemente seu mecanismo usando as funções dccvmm_dump_frame e dccvmm_load_frame disponíveis no controlador de memória. Seu mecanismo provavelmente precisará guardar informações sobre cada quadro da memória física, por exemplo, a qual processo um quadro está alocado.
Seu sistema operacional deve implementar uma política de reposição de páginas. Implemente pelo menos uma das seguintes políticas de reposição de página: reposição aleatória, round-robin, ou LRU (menos recentemente utilizada). Para simplificar, você pode assumir que sempre existe espaço no disco para o sistema de memória virtual.
Seu sistema operacional deve atender os seguintes requisitos:
O primeiro grupo que reportar cada erro no código do simulador ou inconsistência no enunciado receberá 2 pontos extras por erro reportado (máximo de 6 pontos extras por grupo).