Escrevendo um sistema operacional multitarefa para um processador sem MMU

9

Eu estive pensando em escrever um sistema operacional hobby para alguns dos processadores ARM. Existem muitos computadores de placa única populares com o ARM MPU, então eu simplesmente queria comprar um deles (escolhendo um com mais documentação aberta). Fiquei surpreso quando descobri que mesmo as placas com memória suficiente não têm MPUs com unidade de gerenciamento de memória.

Como eu sempre trabalhei com processadores i386 + e nunca mais nada (exceto algumas PICs de microchip), agora estou confuso e não tenho certeza se é possível escrever um sistema operacional em funcionamento cuja funcionalidade não seja limitada quando comparada aos sistemas operacionais escritos para MPUs com MMU.

Eu poderia pensar em algumas soluções para "substituir" ou "simular" a MMU e tenho algumas perguntas:

  • Nos processadores Intel nos modos de 16 e 32 bits, há uma maneira de usar segmentos e seletores de segmentos para usar diferentes blocos de memória em diferentes tarefas. Isso significa que eu poderia alterar o espaço da memória alterando o conteúdo dos registradores de segmento ao fazer uma alternância de tarefas no x86. Existem conceitos gerais para segmentação de memória que poderiam ser usados ​​na arquitetura ARM?
  • Ao carregar um arquivo de objeto vinculado em vez de executável, eu poderia usar as realocações (correções) ou posicionar o código independente para apontar tarefas em partes da memória da mesma maneira como se eu mapeasse a memória usando estruturas de paginação. Isso seria eficaz o suficiente?
  • Também li algo sobre as unidades de proteção de memória nos processadores ARM. Estes poderiam ser úteis?

Existem maneiras "usuais" de gerenciar tarefas em sistemas sem MMU?

user35443
fonte

Respostas:

16

Na verdade, não é tão difícil projetar um sistema operacional que não exija uma MMU. Existem algumas conveniências que você terá que dispensar, mas nada insuperável.

  • Como tarefas diferentes terão que ser carregadas em endereços diferentes, todo o seu código (exceto o kernel, a biblioteca padrão e qualquer outro código que faça parte do seu ambiente de tempo de execução básico) deve ser compilado como independente de posição. Isso significa saltos relativos e um endereço base para o acesso ao heap armazenado em um registro. Gastar um registro como um endereço base pode parecer caro se você estiver acostumado aos quatro registros gerais do x86-32, mas a maioria das arquiteturas modernas tem mais, e até o 8088 possui os registros do segmento precisamente para isso.
  • Uma arquitetura semelhante ao Unix precisa ser revisada, porque você não pode implementar fork. Tudo bem, a maioria dos sistemas operacionais não tem fork. (Você pode ter vfork.)
  • Você não pode pré-alocar grandes quantidades de espaço sem também alocar a memória correspondente. Isso significa que não há crescimento da pilha ou pilha em tempo real, alocando mais uma página por vez.

Se você possui uma MPU, suas tarefas ainda podem ser separadas umas das outras, como de costume nos sistemas operacionais multitarefa. Sem uma MPU, a separação de memória só pode ser cooperativa se você permitir que tarefas executem código arbitrário. Uma maneira de conseguir a separação de memória sem uma MPU é restringir as tarefas para usar apenas o código verificado em uma máquina virtual e implementar a proteção de memória no software como parte do mecanismo da VM.

O uClinux é um projeto baseado no kernel do Linux que roda em processadores (incluindo o ARM Cortex-M) sem uma MMU. Suas restrições à multitarefa são essencialmente as que descrevi acima.

Gilles 'SO- parar de ser mau'
fonte