Copy Link
Add to Bookmark
Report

GERENCIA DE PROCESSOS EM LINUX

Death Knights Issue 0

eZine's profile picture
Published in 
Death Knights
 · 2 years ago

by SaTaNfAcE

Y0z d00dz!!! Bem vamos ao q interressa!!!

Bem, nessa matehria eu irei falar um pouco da "parte logica" do linux, pra ser mais claro, nessa matehria escrevi sobre como o Linux gerencia seus processos, sobre o boot do sistema e sobre a gerencia de processos pelo Kernel!!! Eh iss0 aih espero q a matehria seja util!!!!

Consideracoes Iniciais

Para explicarmos como o Linux gerencia processos, faremos consideracoes iniciais sobre o codigo fonte do kernel do Linux (onde encontramos a implementacao da Gerencia de Processos) e a inicializacao "boot" do sistema.

Nos tentaremos explicar, de uma maneira ordenada o codigo fonte do Linux, tentando conseguir um bom entendimento sobre como o codigo fonte esta situado e como as caracteristicas mais relevantes do UNIX foram implementadas. O objetivo e ajuda-lo a se familiarizar com o projeto geral do Linux. Entao, vamos comecar por onde o Linux comeca: seu sistema de boot.

Um bom entendimento da linguagem C e necessario para entender este material, assim como familiaridade com conceitos de UNIX e arquitetura dos PCs. Porem, nenhum ccdigo C aparecera neste material, mas referencias de onde podem ser encontrados.

Qualquer referencia "pathname" a arquivos tem como ponto de partida a arvore principal de fontes, usualmente /usr/src/linux. A maioria das informacoes reportadas aqui tem como referencia o codigo fonte do Linux versao 1.0. Referencias a versoes posteriores conterao o simbolo.

Caso o simbolo nao estiver presente, significa que nao houveram modificacoes apos as versoes 1.0.9-1.1.76.

Ocasionalmente um paragrafo como este ocorrera no texto. Indicando onde poderam ser obtidas mais informacces sobre o assunto corrente (geralmente o codigo fonte).

Inicializacao ("boot" do sistema)

Quando o PC e ligado, o processador 80x86 encontra-se em modo real e executa o codigo contido no endereco 0xFFFF0, que corresponde a um endereco ROM-BIOS. O BIOS do PC realiza alguns testes no sistema e inicializa o vetor de interrupcoes no endereco fisico 0. Depois disto ele carrega o primeiro setor do device bootavel em 0x7C00, e passa a execucao para este endereco. O device e, usualmente, o disquete ou o disco rigido. A descricao anterior e um tanto simplificada, mas e tudo que se necessita para entender o trabalho inicial do kernel.

A primeirissima parte do kernel Linux esta escrito em linguagem assembly 8086 (boot/bootsect.S). Quando e executado, ele se move para o endereco absoluto 0x90000, carrega os proximos 2 kBytes de codigo do device de boot ate o endereco 0x90200, e o resto do kernel para o endereco 0x10000. A mensagem "Loading..." e apresentada durante o carregamento do sistema. O controle e, entao passado para o codigo contido em boot/Setup.S, outro codigo assembly de modo real.

A parte de "setup" identifica algumas caracteristicas do sistema (hardware) e o tipo da placa VGA. Se requerido, pede ao usuario para escolher o modo do video da console. E, entao, move todo o sistema do endereco 0x10000 para o endereco 0x1000, passa para o modo protegido e passa o controle para o resto do sistema (endereco 0x1000).

O proximo passo e a descompressso do kernel. O codigo em 0x1000 vem de zBoot/head.S que inicializa os registradores e invoca decompress_kernel(), o qual e composto por zBoot/inflate.c, zBoot/unzip.c e zBoot/misc.c. O dado "descompresso" vai para o endereco 0x100000 (1 Mega), e esta e a principal razao do por que o Linux nao pode rodar com menos de 2 Megas de RAM.

O encapsulamento do kernel em um arquivo gzip e realizado por Makefile e utilitarios no diretorio zBoot. Sao arquivos interessantes para se dar uma olhada.

O codigo "descompresso" e executado a partir do endereco 0x1010000 , onde todo o setup 32-bit esta lotado: IDT, GDT e LDT sao carregados, o processador e o co-processador sao identificados, a rotina start_kernel e invocada. Os arquivos fonte das operacoes acima estao em boot/head.S. Este, talvez, seja o codigo mais dificil em todo o kernel do Linux.

Note que se algum erro ocorrer durante alguns dos passos precedentes, o computador ira travar. O sistema operacional nao pode manipular erros enquanto nao estiver totalmente operante.

start_kernel() reside em init/main.c. Tode de agora em diante esta codificado em linguagem C, exceto gerencia de interrupcoes e chamadas de sistemas (Bem, a maior parte das macros possuem codigos assembly embutidos, tambem).

Depois dos procedimentos com todas as questoes iniciais, start_kernel() inicializa todas as partes do kernel, especificamente:

  • Inicializa a memoria e chama paging_init().
  • Inicializa os traps, canais IRQ e scheduling.
  • Se requerido, aloja um profiling buffer.
  • Inicializa todos device drives e buffers de discos, bem como outras partes menores.
  • Regula o delay loop (calcula o numero "BogoMips").

Checa se a interrupcao 16 esta trabalhando com o co-processador.

Finalmente, o kernel esta pronto para move_to_user_mode(), em seguida fork (bifurca) o processo de inicializacao, cujos ccdigos estao no mesmo arquivo fonte. E o processo numero 0, tambem chamado idle task (tarefa preguicosa), se mantem rodando em um loop infinito. O processo de inicializacao tenta executar /etc/init, ou /bin/init, ou /sbin/init.

Se nenhum deles tem sucesso, o codigo se desvia para "/bin/sh /etc/rc" e cria um root shell no primeiro terminal (console). Este codigo e remanescente do Linux 0.01, quando o S.O. era feito para um kernel stand-alone, e nao havia processo de login.

Depois de exec() o programa de inicializacao de um dos lugares padrao (deve haver um deles), o kernel nao tem controle direto sobre o fluxo do programa. Sua funcao, de agora em diante, e prover processos atraves de chamadas ao sistema (system calls), assim como prover eventos para servicos assincronos (como uma interrupcao do hardware). A multitarefa esta inicializada, e inicializara o gerenciamento de acesso a multiusuarios, atraves do fork() e processos de login.

Estando o kernel carregado e provendo servico, vamos prosseguir dando uma olhada nesses servicos ("system calls").

Gerencia de processo pelo kernel

Do ponto de vista do kernel, um processo e uma entrada na tabela de processos. Nada mais.

A tabela de processos, entao, e uma das mais importantes estruturas de dados no sistema, conjuntamente com a tabela de gerenciamento de memoria e o buffer cache. O item individual na tabela de processos e a estrutura task_struct, definida em include/linux/sched.h. Com a task_struct, tanto informacoes de baixo quanto de alto nivel, sao mantidas * variando da copia de alguns registradores de hardware ate o inode do diretorio de trabalho para o processo.

A tabela de processos e tanto um array quanto uma lista duplamente ligada, como uma arvore. A implementacao fisica e um array estatico de ponteiros, cujo tamanho e NR_TASKS, uma constante definida em include/linux/tasks.h, e cada estrutura reside em uma pagina de memoria reservada. A estrutura da lista esta entre os ponteiros next_task e prev_task, a estrutura em arvore e um tanto complexa, e nao sera descrita aqui. Voce pode desejar mudar NR_TASKS do seu valor default (que e 128), mas esteja certo de que ha dependencias, e sera necessario recompilar todos os arquivos fonte envolvidos.

Depois do boot, o kernel esta sempre trabalhando em um dos processos, e a variavel global "current", um ponteiro para um item da task_struct, e usado para guardar o processo que esta rodando. A variavel "current" so e mudada pelo scheduler, em kernel/sch ed.c. Quando, porem, todos os processos necessitarem estar looked, a macro for_each_task e usada. Isto e consideravelmente mais rapido que uma procura seq¸encial no array.

Um processo esta sempre rodando em ou em "modo usuario" ou em "modo kernel". O corpo principal de um programa de usuario e executado em modo usuario e chamadas a sistema sao executados em modo kernel. A pilha usada pelos processos netes dois modos de execucao sao diferentes * um seguimento de pilha convencional e usado para o modo usuario, enquanto uma pilha de tamanho fixo (uma pagina, cujo processo e dono) e usada no modo kernel. A pagina de pilha para o modo kernel nunca e swapped out, porque ela pode estar disponivel sempre que um system call e introduzido.

Chamadas a sistema (System calls), no kernel do Linux, sao como funcoes da linguagem C, seu nome "oficial" esta prefixado por "sys_". Uma chamada a sistema de nome, por exemplo, burnout invoca a funcao de kernel sys_burnout().

O mecanismo de chamadas a sistema (System calls) esta descrito no capitulo 3 do Linux Kernel Hackers' Guide (http://www.redhat.com:8080/HyperNews/get/khg.html). Uma olhada em for_each_task e SET_LINKS, em include/linux/sched.h pode ajudar a entender a lista e a estrutura de arvore da tabela de processos.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT