Sistema operacional baseado em x86 construído do zero para fins de aprendizado
int 64 que exigiu descritores de portão para escalada de privilégiosPara construir o sistema operacional (assumindo o GCC, NASM instalado),
makePara correr sob qemu
make qemuPara executar (assumindo bochs, bochs-sdl instalado),
make runPara correr sob Qemu com suporte de depuração (GDB)
make qemu_gdb(Anexe o GDB, comandos necessários já fornecidos no arquivo .gdbinit no diretor de nível superior)
O BIOS inicia o processador no modo real de 16 bits, o GRUB inicia o modo protegido de 32 bits. A imagem do elfo do kernel é fornecida com o cabeçalho MultiBoot, conforme a especificação do GRUB, se o GRUB encontrar esse cabeçalho nos primeiros 512 bytes de imagem, ele carrega o ELF no local 0x100000, a memória mais baixa pertence ao BIOS e outros mapeamentos de hardware/io como VGA. Código de inicialização, executa do ponto de _start do kernel e ((Nota BSS já é zero inicializado pelo GRUB),
O alocador de memória de estratégia first-fit simples, aloca a memória do espaço do kernel, durante free , também gerencia a compactação de blocos livres adjacentes.
Para os usuários, são fornecidos Malloc/Free, que usam o sistema sbrk usado internamente para aumentar a quebra do sistema (se necessário). O kernel é necessário configurações de tabela de página necessárias e retornos aumenta o limite de quebra do sistema.
Isso é dividido no mapeamento da memória espacial do kernel e nos mapeamentos de memória espacial do usuário. Os mapeamentos espaciais do kernel permanecem constantes e fazem parte de cada espaço de endereço do processo, apenas vinculado não clonado, pois as alterações de um processo no espaço do kernel também devem ser visíveis de outros processos.
Os mapeamentos de espaço do usuário depende da chamada exec , e todo processo possui seu próprio kernel e pilha de usuários.
Durante o comutador de contexto, o registro do CR3 é carregado com o endereço base atual da página do processo e que também invalida internamente o TLB (Buffer de Lookaside de tradução).
Os aplicativos de espaço do usuário são armazenados no initramfs , um arquivar formato CPIO no formato ELF padrão. Durante exec Kernel, encontra e analisa a imagem do ELF, configura suas tabelas de página de acordo. O processo Init apenas inicia shell e depois fica lá para sempre.
O Scheduler é executado em nome do processo de execução atualmente, principalmente em dois casos,
Os segmentos de código/dados do modo de kernel são separados do que o código do usuário/segmentos de dados com níveis de privilégio programados de acordo. Ao retornar da exceção, o hardware aparece CS (segmento de código) e SS (segmento de pilha) da pilha para retornar ao nível de privilégio mais baixo.
Programamos essa estrutura de pilha de acordo com a criação de novas tarefas,
/* Task will start in CPL = 3, i.e. user mode */
task -> irqf -> cs = ( SEG_UCODE << 3 ) | DPL_USER ;
task -> irqf -> ds = ( SEG_UDATA << 3 ) | DPL_USER ;
task -> irqf -> eflags = 0x200 ;
task -> irqf -> ss = ( SEG_UDATA << 3 ) | DPL_USER ;O hardware x86 possui suporte interno para troca de tarefas, basicamente mudando da pilha de usuários para a pilha do kernel junto com outros parâmetros de segmentação. Para isso, todas as tarefas precisam configurar com seu próprio TSS, que é modificado durante a troca de contexto. Não usaremos a troca de tarefas de hardware, mas faremos o mesmo no próprio software. De qualquer forma, precisamos configurar pelo menos um TSS, que possui o modo kernel válido SS (segmento de pilha) e ESP (STack Pointer) para a tarefa atual.
Perguntas frequentes aleatórias
Sinta -se à vontade para bifurcar e enviar solicitação de mesclagem