You are on page 1of 38

Sumário

1. Introdução a História do Sistema Operacional UNIX..................................................... 4


2. UNIX Uma Visão Geral..................................................................................................... 8
2.1 Modularidade........................................................................................................... 8
2.2 Multitarefa (Multitasking)........................................................................................ 8
2.3 Multiusuário (Multiuser).......................................................................................... 9
2.4 Portabilidade........................................................................................................... 10
2.5 Conectividade e Comunicações............................................................................10
3. Estrutura do UNIX............................................................................................................ 12
4. Shell (Interpretador de Comandos).................................................................................14
5. Noções de Linha de Comando no UNIX.........................................................................16
6. Arquivos de Inicialização.................................................................................................18
7. Gerenciamento de Arquivos............................................................................................22
7.1 Atributos e Nomes de Arquivos.............................................................................22
8. Gerenciamento de Processos e Escalonamento no UNIX............................................22
8.1 Blocos de Controle de Processos (BCP)..............................................................22
8.2 Escalonamento de CPU..........................................................................................24
9. Memória e Gerenciamento...............................................................................................25
10. Deadlocks......................................................................................................................... 27
10.1 Condições para Ocorrências de Deadlocks..........................................................27
10.2 Algoritmo do Avestruz............................................................................................28
10.3 Algoritmo do Banqueiro.........................................................................................28
10.4 Tratamento de Deadlocks.......................................................................................29
10.5 Detectar e Recuperar..............................................................................................29
11. Threads no UNIX ............................................................................................................. 30
12. Kernel................................................................................................................................ 32
13. Dispositivos de E/S..........................................................................................................34
14. Comunicação Serial e Paralela.......................................................................................35
15. Configuração do TCP/IP..................................................................................................36
16. Serviços TCP/IP................................................................................................................
17. Procedimentos de boot e o Init.......................................................................................
18. Referências Bibliográficas..............................................................................................
2
1. Introdução a História do Sistema Operacional UNIX

Segundo Fernando Krahe1, as raízes do UNIX datam dos meados dos anos 60, quando a
AT&T, Honeywell, GE e o MIT embarcaram em um massivo projeto para desenvolvimento de um
utilitário de informação, chamado Multics (Multiplexed Information and Computing Service). O
sistema deveria ser multiusuário, com um sistema de arquivos de alta confiança, suporte a vários
tipos de aplicações, e a vários ambientes de programação e interfaces de usuário.

Multics era um sistema modular montado em uma bancada de processadores, memórias e


equipamentos de comunicação de alta velocidade. Pelo desenho, partes do computador poderiam
ser desligadas para manutenção sem que outras partes ou usuários fossem afetados. O objetivo
era prover serviço 24 horas por dia 365 dias por ano - um computador que poderia ser tornado
mais rápido adicionando mais partes.

Em 1969, o projeto estava muito atrasado em relação ao seu cronograma e a AT&T resolveu
abandona-lo. O projeto continuou no MIT. Neste mesmo ano, Ken Thompson e Dennis Ritchie
decidiram desenvolver algumas idéias do Multics, eles reescreveram todo o sistema operacional
para um computador bem menos potente, um DEC PDP-7, de 4 kbytes de memória. Thompson
terminou o trabalho no verão de 1969, foi utilizada a linguagem BCPL (conhecida popularmente
como Linguagem B “assembly”), que contava com funções básicas: editor de texto, montador (ou
assembler, que transforma linguagem assembly em linguagem de máquina) e interpretador de
comandos (um Shell) neste período o sistema era chamado de Unics (UNiplexed Information and
Computing Service), numa alusão ao Multics, e foi logo rebatizado como Unix.

A primeira versão do sistema “BELL LABs PDP-11” foi lançada em 1º Janeiro de 1970, data
considerada como a de nascimento do sistema Unix, o que explica porque todos os relógios dos
sistemas de exploração Unix começam a partir desta data.

O projeto cresceu e surgiu a necessidade de se usar um sistema operacional compatível


com diferentes plataformas de hardware, o que levou ao desenvolvimento de uma nova linguagem
de programação, que pudesse ser portada com facilidade, sem ou com pouquíssimas
modificações no source(código-fonte).

Em 1972, Dennis Ritchie e Brian W.Kernighan, participaram ativamente do desenvolvimento


da Linguagem C, (motivo pelo qual, é considerado como um dos seus inventores), a linguagem C
superava as limitações da linguagem B, assim, o conjunto do sistema UNIX foi inteiramente
reescrito em linguagem C em 1973 e batizado Unix Time-Sharing System (TSS).
1
Fonte: Fernando Krahe. Nivelamento UNIX
3

Em 1973 o UNIX foi reescrito em C, talvez o fato mais importante da história deste sistema
operacional. Isto significava que o UNIX poderia ser portado para novo hardware em meses, e que
mudanças eram fáceis. A linguagem C foi projetada para o sistema operacional UNIX, e portanto
há uma grande sinergia entre C e UNIX.

Como a lei impedia a empresa AT&T, e a Bell Labs, de comercializar outra coisa que não
equipamentos telefônicos ou telegráficos, tomo-se a decisão de distribuir os fontes de UNIX para
as universidades para fins educativos em 1973.

Em 1975 foi lançada a V6, que foi a primeira versão de UNIX amplamente disponível fora
dos domínios do Bell Labs, especialmente em universidades. Este foi o início da diversidade e
popularidade do UNIX. Nesta época na Universidade de Berkley os alunos começaram a fazer
modificações ao sistema.

Começaram a surgir novas versões, além da original da AT&T (rebatizada como System V);
a primeira foi desenvolvida na Universidade de Berkeley, denominado BSD (Berkeley Software
Distribution), liberada publicamente no final de 1977, precursor dos atuais e bem-sucedidos
BSD’s, (alguns anos depois com base no sistemas BSD surgiram novas “versões”, como o
freeBSD, netBSD e openBSD, que tinham o kernel baseado no sistema BSD).

Assim dois ramos de desenvolvimento das fontes se formaram:


 AT&T que ia tornar-se System V de UNIX System Labs (USL);
 BSD (Berkeley Software Developpement) desenvolvido pela Universidade de
Califórnia.
 Ainda em 1977 a AT&T deixou os fontes do UNIX à disposição das outras
empresas, de modo que um grande número de UNIX-like foram desenvolvidos:
 AIX, Unix comercial baseado no System V desenvolvido em fevereiro de 1990 pela
IBM;
 Sun Solaris, Unix comerciais baseado no System V e BSD desenvolvido pela Sun
Microsystems ;
 HP-UX, Unix comercial baseado em BSD desenvolvido a partir de 1986 pela
Hewlett Packard ;
 Ultrix, Unix comerciais desenvolvido pela Digital Equipment Corporation;
 IRIX, Unix comercial desenvolvido pela Silicon Graphics;
 Unixware, Unix comerciais desenvolvidos pela Novell;
 Unix SCO, Unix comercial baseado no System V desenvolvido a partir de 1979 pela
Santa Cruz Operações e Hewlett Packard;
 Tru64 UNIX, Unix comercial desenvolvido pela Compaq.
4
Em 1978 Berkley Software Distribuition lança a série 2.xBSD para PDP - 11 (a versão 2.11
foi lançada em 1992). Nesta versão saiu o csh. Neste ano também saiu a série 3BSD, que teve
uma importante contribuição, virtual memory.

Em 1979 saiu a V7 e o Unix foi portado para o novo VAX da Digital. Esta versão incluia C
K&R completo, uucp, Bourne Shell. O kernel tinha meramente 40 bytes! Esta foi a primeira versão
vendida comercialmente do sistema, mas usada principalmente por universidades. Em sua versão
7 de 1979, a evolução foi acompanhada de numerosas modificações notáveis como:
 a supressão do bridage ligado à dimensão dos arquivos,
 uma melhor mobilidade do sistema (funcionamento sobre numerosas plataformas
materiais),
 a adição de numerosos utilitários.

Em 1983 é lançado o System V da AT&T e o 4.2 BSD. O SV incluía o pacote IPC (shm, msg,
sem) para comunicação entre processos. Surgiram outras versões do SV com a inclusão de novas
características como sharedlibs no SVR4. O 4.2BSD foi talvez uma das mais importantes versões
do UNIX. O seu software de conexão de redes tornava muito fácil a tarefa de conectar
computadores UNIX a redes locais. Nessa versão é que foram integrados os softwares que
implementam TCP/IP e sockets.

A AT&T parou de disponibilizá-lo livremente, passou a ser disponibilizado por um preço


muito alto, é depois de algum tempo uma serie de universidades, empresas e grupos de
programadores, começaram a desenvolver uma serie de aplicativos para o Unix (desde jogos até
aplicações comerciais).

Tantas variedades de Unix surgindo a todo momento, com as mesmas características, mas
com tendências a se divergirem fez surgir então em 1985 o padrão POSIX (Portable Operating
System Interface for UniX), um conjunto de padrões definidos pelo IEEE(Institute of Electrical and
Electronics Engineers). POSIX assim é conhecido igualmente sob o nome IEEE P1003.

O POSIX não permitiu compatibilidade de rodar programas binários entre os vários Unix,
mas sim facilidade de portar um programa de um Unix para outros, através de compilação de
códigos-fonte em C.
Em 1988 foi lançado o SVR4. Este sistema era um merge de releazes anteriores do SV,
BSD e SunOs, uma implementação descendente de BSD. O 4.4BSD foi lançado em 1992 para
várias plataformas: HP 9000/300, Sparc, 386, DEC e outras, mas não em VAX. Entre as novas
características estão:
 Novo sistema de memória virtual baseado em Mach 2.5
 Suporte ISO/OSI (baseado em ISODE)
5
A Sun Microsystem também lançou a sua versão do UNIX a partir do BSD. Isto ocorreu até a
versão SunOs 4.x. A nova versão, SunOs 5.x está baseada no SVR4, embora tenha herdado
algumas características do SunOs 4.x. O novo sistema operacional da Sun, Solaris 2.x, é um SO
que engloba SunOs 5.x, Open Network Computing e Open Windows. É o solaris que provê o
pacote de compatibilidade entre os BSD/SunOs e o SVR4/SunOs 5.x.

A Microsoft também lançou uma versão do UNIX, chamada XENIX, que rodava em PCs.
Este sistema era inicialmente baseado na Versão 7, depois herdou características dos SIII e
depois do SV.

No início da década de 1990, a AT&T vendeu o código UNIX para a Novell. Em 1995, a
Novell vendeu parcialmente alguns dos direitos do código UNIX à Santa Cruz Operation. Em
2000, a Santa Cruz Operation vendeu o código UNIX para a Caldera Systems, que mudou seu
nome para SCO.

Atualmente, Unix (ou *nix) é o nome dado a uma grande família de Sistemas Operacionais
que partilham muitos dos conceitos dos Sistemas Unix originais, todos desenvolvidos sob a
plataforma de padrões como o POSIX e outros. Alguns dos Sistemas derivados do Unix são: BSD
(FreeBSD, OpenBSD e NetBSD), Solaris (anteriormente conhecido por SunOS), IRIX, AIX, HP-
UX, Tru64, Linux (nas suas centenas de distribuições), e até o Mac OS X (baseado em um kernel
Mach BSD chamado Darwin). Existem mais de quarenta sistemas operacionais *nix, rodando
desde celulares a supercomputadores, de relógios de pulso a sistemas de grande porte.
6

2. O Que é o UNIX?

O Unix é um sistema operacional multi-usuário e multi-tarefas, o que permite a um


computador executar simultaneamente vários programas para um ou vários usuários. Multitarefa
significa executar varias tarefas ou processos simultaneamente, porem, em um hardware
monoprocessado, o sistema multi-thread não funciona, mas os processos são executados
seqüencialmente de forma tão rápida que parecem estar sendo executados simultaneamente, O
Unix escalona sua execução e reserva-lhes recursos computacionais (intervalo de tempo de
processamento, espaço em memória RAM, espaço no disco rígido, etc.).

Hoje em dia, os sistemas Unix estão presentes nos meios profissionais e universitários
graças à sua grande estabilidade, ao seu nível de segurança elevado e ao respeito dos grandes
padrões, nomeadamente em matéria de rede.

O Unix apresenta também como característica o seu sistema de arquivos. Tudo neste
sistema operacional é considerado um arquivo, até mesmo os dispositivos de I/O são tratados
como arquivo pelo sistema. Além do conceito de arquivos, outros conceitos presentes no sistema
são: processos, shell, diretórios e path.

2.1 Modularidade

O UNIX é único em seu desenho modular, que permite usuários adicionar ou remover partes
para adaptá-lo às suas necessidades específicas. Os módulos se encaixam com conexões-
padrão. É possível tirar um módulo e substituí-lo por um outro ou expandir o sistema
acrescentando vários módulos. De uma certa maneira, o sistema UNIX de cada pessoa é único.

Muitos usários acrescentam ou eliminam módulos sempre que precisam, adaptando suas
implementações às suas necessidades. Geralmente, é possível remover um módulo, sem
prejudicar a operação do resto do sistema. Esta característica é muito útil nas implementações em
microcomputadores, onde as unidades de disco têm capacidade limitada. A remoção de arquivos
desnecessários abre espaço para mais arquivos de dados.

2.2 Multitarefa (Multitasking)

A capacidade de multitasking do UNIX permite que mais de uma tarefa seja realizada
simultaneamente. Esta é uma das principais características do UNIX. As tarefas que estão em
execução concorrem pelos recursos da máquina que são controlados pelo sistema. É possível,
7
portanto, que um programa que atualize um banco de dados seja rodando ao mesmo tempo que a
impressão de um relatório esteja sendo realizada e uma tela de terminal esteja sendo enviada.

O Unix é um sistema operacional de multitarefa preemptiva, ou seja, quando termina o


intervalo de tempo (chamado quantum), a execução do processo e suspensa, salva o seu
contexto (informações necessárias para a execução do processo), para que ele possa ser
retomado posteriormente, e coloca em execução o próximo processo da fila de espera, também
determina quando cada processo será executado, a duração de sua execução e a sua prioridade
sobre os outros. A multitarefa, permite que o usuário e o computador fiquem livres para realizarem
outras tarefas economizando tempo.

Em uma interface gráfica com um ambiente de janelas pode-se disparar cada tarefa em uma
janela shell. Já em um ambiente não gráfico, as tarefas que podem ser executadas sem a
intervenção do usuário são colocadas em background. Em foreground deixa-se as tarefas que
necessitam da intervenção do usuário, como a edição de um arquivo.

2.3 Multiusuário (Multiuser)

O Unix permite que vários usuários utilizem um mesmo computador simultaneamente,


geralmente por meio de terminais, semelhante ao Mainframe. Cada terminal é composto de um
monitor, um teclado e, eventualmente, um mouse. Vários terminais podem ser conectados ao
mesmo computador num sistema Unix. Há alguns anos eram usadas conexões seriais, mas
atualmente é mais comum o uso de redes locais, principalmente para o uso de terminais gráficos.

O Unix gerencia os pedidos que os usuários fazem, evitando a interferência de uns nos
outros. Cada usuário possui direitos de propriedade e permissões exclusivas sobre arquivos.
Quaisquer arquivos modificados pelo usuário conservarão esses direitos. Programas executados
por um usuário comum estarão limitados em termos de quais arquivos poderão acessar.

O sistema Unix possui dois tipos de usuários: o usuário root (também conhecido como
super-usuário), semelhante ao administrador do Windows, que possui a missão de administrar o
sistema, podendo manipular todos os recursos do sistema operacional; e os usuários comuns, que
possuem direitos limitados.

Para que o sistema opere adequadamente em modo multiusuário, existem alguns


mecanismos:
8
 Sistema de autenticação de usuário (o programa login, por exemplo, autentica o
usuário verificando uma base de dados, normalmente armazenada no arquivo
/etc/password);
 Sistema de permissões e propriedades sobre arquivos (os direitos anteriormente
citados);
 Proteção de memória, impede que um processo de usuário acesse dados ou
interfira com outro processo. Esse mecanismo é feito com a ajuda do hardware, que
divide o ambiente de processamento e memória em modo supervisor (ou modo
Unix 4 núcleo) e modo usuário.

2.4 Portabilidade

A portabilidade é a possibilidade dos softwares que operam em uma máquina operarem em


uma outra diferente. Há dois tipos de portabilidade a serem considerados:
 Portabilidade do sistema operacional
 Portabilidade dos aplicativos

Mais de 90% do programa Kernel está escrito em C e menos de 10% em linguagem de


máquina. Assim, na pior das hipóteses, apenas 10% do programa Kernel terá de ser reescrito ao
se deslocar o Kernel para uma máquina com arquitetura diferente. Os programas aplicativos
escritos em linguagem de nível mais alto, como C, são facilmente portáveis para vários sistemas
UNIX. Basta que sejam recompilados, exigindo, as vezes, poucas alterações.

O Unix Possui vários interpretadores de comandos (Shell) bem como um grande número de
comandos e numerosos utilitários (compiladores para numerosas linguagens, tratamentos de
texto, serviço de mensagens eletrônicas,etc). Também possui uma grande mobilidade, o que
permite sua instalação em quase todas as plataformas materiais.

2.5 Conectividade e comunicações

No UNIX temos dois tipos de comunicações, quais sejam, comunicação entre programas e
comunicação entre usuários. A comunicação entre programas é realizada através de mensagens,
semáforos ou memória compartilhada. Estes mecanismos, também conhecidos por IPC,
interprocess comunications, são extensões do System V.

A comunicação entre usuários pode se realizar de diversas maneiras, entre elas há o Mail,
que é um programa para enviar e receber mensagens eletrônicas, o Write, que escreve uma
mensagem no terminal de outra pessoa logada no sistema, o Wall, que escreve mensagens nos
9
terminais de todas as pessoas logadas no sistema, o Talk, que permite uma conversa em tempo
real.

Há também a comunicação entre os sistemas, tais como UUCP (UNIX to UNIX Copy
Protocol).
10
3. Estrutura do UNIX

Um sistema Unix é composto basicamente de duas partes:

 núcleo - o núcleo do sistema operacional, a parte que relaciona-se diretamente


com o hardware, e que executa num espaço de memória privilegiado, agenda
processos, gerencia a memória, controla o acesso a arquivos e a dispositivos de
hardware (estes, por meio dos controladores de disposito - drivers - e interrupções).
O acesso ao núcleo é feito por chamadas de sistema, que são funções fornecidas
pelo núcleo; essas funções são disponibilizadas para as aplicações por bibliotecas
de sistema C (libc).

 programas de sistema - são aplicações, que executam em espaços de memória


não privilegiados, e que fazem a interface entre o usuário e o núcleo. Consistem,
principalmente, de:
 Conjunto de bibliotecas C (libc)
 Shell - um ambiente que permite que o usuário digite comandos.
 Programas utilitários diversos - são programas usados para manipular arquivos,
controlar processos, etc.
 Ambiente gráfico (GUI) Graphics User Interface - eventualmente utiliza-se
também um ambiente gráfico para facilitar a interação do usuário com o sistema.

Em um sistema Unix, o espaço de memória utilizado pelo núcleo é denominado espaço do


núcleo ou supervisor (em inglês: Kernel Space); a área de memória para os outros programas é
denominada espaço do usuário (User Space).

Essa separação é um mecanismo de proteção que impede que programas comuns


interfiram com o sistema operacional.
11
Para um melhor entendimento, o sistema operacional UNIX pode ser representado pelas
quatro partes básicas, como ilustrado na figura2 abaixo:

 Kernel: é o núcleo do sistema operacional, controla o hardware traduzindo comandos


UNIX em instruções de hardware. O usuário não trabalha diretamente com o Kernel.

 Sistema de arquivos: é o modo do UNIX armazenar informações de qualquer tipo, como


por exemplo, gráficos, textos, etc.

 Shell: é um programa que atua como interface entre o Kernel e o usuário.

 Aplicativos: são programas que podem ser invocados pelo Shell para realizar diversas
tarefas

2
Fonte da ilustração: http://www.cenapad.unicamp.br/servicos/treinamentos/tutorial_unix/unix_tutor-4.html
12
4. Shell

O SHELL é um interpretador de comandos interativo e constitui a principal interface entre o


usuário e o sistema UNIX. Na SUN há dois tipos, que podem ser chamados pelo usuário: o "sh",
"csh", "tcsh", "bash", e outros. É a partir do SHELL que os processos podem ser chamados.

 SHELL possui variáveis que armazenam informações sobre o sistema. Elas devem ser
inicializadas logo no início da sessão. Algumas variáveis são:

 PATH: guarda o nome dos diretórios permitidos na busca de comandos;

 HOME: nome do diretório de entrada do usuário;

O intérpretador de comandos (Shell) é a interface entre o usuário e o sistema de exploração,


daí o seu nome inglês “Shell”, que significa “casca”.

Assim, encarregado de ser o intermediário entre o sistema de exploração e o usuário graças


às linhas de comandos escritas por este, a função do Shell consiste em ler a linha de comando,
interpretar o seu significado, executar o comando e seguidamente dar o resultado nas saídas.

O Shell é assim um arquivo executável, encarregado de interpretar os comandos, transmiti-


los ao sistema e devolver o resultado. Existem vários shells, sendo o mais corrente o sh (chamado
“Bourne shell”), bash (“Bourne again shell”), csh (“C Shell”), Tcsh (“Tenex C shell”), ksh (“Korn
shell”) e zsh (“Zero shell”). O seu nome corresponde geralmente ao nome do executável.

Cada utilizador possui um shell por padrão, que será lançado quando da abertura de uma
janela de comando. Por padrão, o Shell está no ficheiro de configuração /etc/passwd no último
campo da linha que corresponde ao utilizador. É possível alterar o shell numa sessão, executando
muito simplesmente o ficheiro executável correspondente, por exemplo:
/bin/bash

Janela de comando (rápida)


O Shell inicia lendo a sua configuração global (num ficheiro do directório /etc/),
seguidamente lendo a configuração própria ao utilizador (num ficheiro escondido, cujo nome
13
começa por um ponto, situado no directório básico do utilizador, ou seja
/home/nom_de_l_utilisateur/.fichier_de_configuration), por último mostra a jenale de comando (em
inglês prompt) do seguinte modo:
machine:/repertoire/courant$

Por padrão, na maior parte dos shells, o prompt é composto pelo nome da máquina, seguido de
dois pontos (:), do directório corrente, seguidamente de um carácter que indica o tipo de utilizador
conectado :

 “$” indica que se trata de um utilizador normal;

 “#” indica que se trata do administrador, chamado “root”.


14
5. Noção de linha de comando no UNIX

Uma linha de comando é uma cadeia de caracteres constituída por uma comando,
correspondente a um arquivo executável do sistema ou um comando Shell, bem como os
argumentos (parâmetros) opcionais:
 ls -al /home/jf/
No comando acima, ls é o nome do comando, - Al e /home/jf/ são argumentos. Os
argumentos que começam por “-“ designam-se opções. Para cada comando existem geralmente
diversas opções que podem ser detalhadas escrevendo um dos comandos seguintes:
 commande --help
 commande -?
 man commande

Entrada/saída standard, quando da execução de um comando, um dossiê é criado. Este vai


então abrir três fluxos:
 stdin, chamado entrada standard, no qual o processo vai ler os dados de entrada. Por
defeito, stdin corresponde ao teclado; STDIN é identificado pelo número 0;
 stdout, chamado saída standard, no qual o processo vai escrever os dados de saída. Por
defeito, stdout corresponde ao monitor; STDOUT é identificado pelo número 1;
 stderr, chamado erro standard, no qual o processo vai escrever as mensagens de erro.
Por defeito stderr corresponde ao monitor. STDERR é identificado pelo número 2;
15
6. Arquivos de inicialização

No UNIX temos alguns arquivos que são executados todas as vezes que abrimos uma Shell,
ou quando inicializamos uma nova sessão. Estes arquivos são chamados de arquivos de
inicialização. Através deles, o usuário pode personalizar alguns comandos que mais utiliza,
colocando alguns 'apelidos' referentes a estes comandos, e/ou alterar o ambiente de trabalho da
sua própria conta.

Alguns exemplos de arquivos de inicialização são:


 C Shell: .login e .cshrc
 Bash: .bash_profile e .bashrc

Os arquivos, .login e .bash_profile são executados pelo Shell somente ao iniciar a sessão.
Estes arquivos devem conter comandos que precisam ser executados somente uma vez durante o
login. Os arquivos .cshrc e .bashrc são executados toda vez que uma nova cópia do Shell for
chamada.

Para exemplificar abaixo temos um arquivo .cshrc que contém 'apelidos' para alguns dos
comandos do UNIX. O usuário 'apelidou' o comando history de h. Assim, ao invés dele digitar
history, basta digitar h. Como esta alteração foi feita no arquivo .cshrc, este 'apelido' será válido
todas as vezes que ele abrir uma nova cópia do Shell.
 # /etc/cshrc
 # csh configuration for all shell invocations.
 limit coredumpsize 0k
 alias h history
 alias l ls -lF
 alias psa 'ps xua | more'
 set history = 100
 save history = 100

Após modificar os arquivos de inicialização, deve-se usar o comando source, para que as
modificações comecem a funcionar. Neste exemplo, temos:
 % source .cshrc

Devido a importância dos arquivos de inicialização, é aconselhável que antes de efetuar


qualquer modificação nos mesmos, faça uma cópia de segurança, para facilitar a reparação de
algum erro.

7. Gerenciamento de arquivos
16

O UNIX armazena toda informação em arquivos no disco rígido. Os arquivos no UNIX


possuem diferentes tipos: arquivo texto, diretório, executável, etc. Estes arquivos têm nome, nome
do proprietário, respectivo grupo a que pertence, permissões de manipulação, tamanho e data da
última modificação. Através do comando 'ls -laF' obtemos as informações sobre os arquivos da
pasta atual.
17
Para facilitar o gerenciamento de arquivos, o UNIX utiliza um sistema de diretórios com
nomes particulares, cada qual pode conter arquivos e subdiretórios próprios. Os diretórios do
UNIX apresentam uma hierarquia representada na forma de uma árvore invertida.
18
O diretório base do UNIX é chamado de root, sendo representado pelo símbolo '/'. Abaixo do
diretório root, o UNIX cria diversos subdiretórios com objetivos específicos, a seguir são listados
os diretórios mais importantes:

/ diretório raíz, root.

/etc contém arquivos de configuração do sistema.

/Bin contém os principais executáveis do sistema (binários).

/usr contém os programas instalados, aplicativos, documentação do sistema e dos


programas.

/dev contém informações sobre todos os dispositivos (devices) do sistema.

/home contém os diretórios de usuários.

/lib contém as bibliotecas do sistema.

/tmp contém todos os arquivos temporários.

/var contém os arquivos de informação variável, que são alterados com freqüência.

/sbin arquivos de sistema essenciais.

/boot contém arquivos de boot ou inicialização.

/lost+found arquivos recuperados.

/mnt diretório de acesso aos drives, ponto de montagem de partição temporária.

7.1 Atributos e Nomes de Arquivos

Conforme texto do IME-USP3, no UNIX cada arquivo (inclusive diretórios, que são
casos particulares de arquivos), conta com um conjunto de atributos de leitura, escrita e
execução, que são setáveis através do comando chmod, e podem ser exibidos pelo
comando:
s-I:
$ Is –I /Bin/cat
-rwxr-xr-x 1root root 16584 Dec 16 20:09 /bin/cat
19

A string –rwxr-xr-x representa os atributos do arquivo/Bin/cat. O primeiro caracter (-)


significa que se trata de um arquivo regular, em contraposição aos diretórios (d), device
special files (c) e links simbólicos (I). Os nove caracteres restantes informam as permissões
de leitura, escrita e execução desse arquivo relativas ao seu proprietário, ao seu grupo, e a
todos os demais. O proprietário e o grupo são informados logo à direita, e no caso são o
usuário root e o grupo root.

3
Unix: Conceitos e Comandos Básicos
Note que no UNIX não existem os atributos de arquivos ocultos(“hidden”) e do sistema
(“system”), suportados no MS-DOS. Não obstante, arquivos cujo primeiro caractere é ponto
(“.”) normalmente são omitidos pelo Is, a não ser que se utilize a opção –a (de “all”),
conforme comentamos no início.

Um atributo importantíssimo existente no UNIX é o chamado setuid, através do qual


um processo adquire ao ser executado os privilégios do owner do arquivo. Isso é
frequentemente utilizado por programas que são disparados por usuários não privilegiados
mas que por algum motivo necessitam dos privilégios do super-usuário, por exemplo:
$ Is –I /usr/sbin/pppd
-rwsr-xr-x 1root Bin 104876 Apr 27 1998 /usr/sbin/pppd

Sem os privilégios de super-usuário, um usuário comum não conseguiria configurar a


interface ppp e nem alterar a tabela de rotas do sistema, no momento em que se conecta ao
provedor internet. Assim, o pppd, ao ser executado, requisitará os privilégios do owner do
arquivo, que no caso é o superusuário, e dessa forma ele poderá realizar essas operações.

No UNIX via de regra são suportados nomes “longos” (até 64 ou às vezes até 256
caracteres), e o “.” Não é um separador entre o nome e a extensão do arquivo, mas um
caractere como os outros. Não obstante, a noção de “sufixo” é utilizada informalmente para
facilitar a identificação de alguns formatos de arquivos, por exemplo:
.tar Archive produzido com tar
.zip Archive comprimido produzido com zip
.Z Archive comprimido com compress
.gz Archive comprimido com gzip

Archives (o termo não tem correspondente em português) são concatenações de


vários arquivos ou de subárvores inteiras num único arquivo. Em UNIX, tipicamente são
produzidos com tar:
$ tar cvf /tmp/etc.tar / etc
20
$ tar tvf /tmp/etc.tar / etc
$ cd /tmp; tar xvf etc.tar

O primeiro comando irá criar o archive / tmp/etc.tar, composto por toda a


subárvore/etc. O segundo exibirá o conteúdo desse archive. O terceiro irá extrair todo o seu
conteúdo dentro do diretório /tmp, ou seja, recriará aquela mesma subárvore como uma
subárvore do diretório /tmp.
21

8. Gerenciamento de Processos e Escalonamento no Unix

Na visão mais simples, processo é uma instância de um programa em execução. Um


programa, para ser executado, necessita ser carregado na memória; a área de memória
utilizada é dividida em três partes: código (text), dados inicializados (data) e pilha (stack).

Por ser multitarefa, o Unix utiliza uma estrutura chamada tabela de processos, que
contém informações sobre cada processo, tais como: identificação do processo (PID), dono,
área de memória utilizada, estado (status).

Apenas um processo pode ocupar o processador em cada instante - o processo


encontra-se no estado "executando" (running). Os outros processos podem estar "prontos"
(ready), aguardando na fila de processos, ou então estão "dormindo" (asleep), esperando
alguma condição que permita sua execução. Um processo em execução pode ser retirado
do processador por duas razões:
 necessita acessar algum recurso, fazendo uma chamada de sistema - neste caso, após
sua retirada do processador, seu estado será alterado para "dormindo", até que o recurso
seja liberado pelo núcleo;
 o núcleo pode interromper o processo (preempção) - neste caso, o processo irá para a
fila de processos (estado "pronto"), aguardando nova oportunidade para executar - ou
porque a fatia de tempo esgotou-se, ou porque o núcleo necessita realizar alguma tarefa.

Existem quatro chamadas de sistema principais associadas a processos: fork, exec, exit e
wait;

 Fork é usada para criar um novo processo, que irá executar o mesmo código (programa)
do programa chamador (processo-pai);
 Exec irá determinar o código a ser executado pelo processo chamado (processo-filho);
 Exit termina o processo;
 Wait faz a sincronização entre a finalização do processo-filho e o processo-pai.

8.1 Blocos de Controle de Processos (BCP)

Os processos possuem um espaço de endereçamento que é divido em segmentos de


texto, de dados e de pilha. Os segmentos de dados e de pilha estão sempre no mesmo
espaço de endereçamento, podendo se expandir separadamente e, geralmente, em
22
direções opostas. Os de texto, às vezes estão em um espaço de endereçamento diferente
dos dados e pilha, e geralmente é somente de leitura.

A estrutura de texto registra quantos processos estão usando o segmento de texto,


incluindo um ponteiro para uma lista de suas estruturas de processo, e onde a tabela de
página para o segmento de texto pode ser encontrada no disco, em caso de swapping. A
estrutura de texto em si sempre está residente na memória principal. Os segmentos de
texto, dados e de pilha para os processos podem ser submetidos ao swapping. Quando os
segmentos são trazidos à memória, eles são paginados.

As tabelas de página gravam informações do mapeamento da memória virtual do


processo para a memória física. A estrutura de processo contém ponteiros para a tabela de
página, para uso quando o processo está residente na memória principal, ou o endereço do
processo no dispositivo de swap, quando o processo passa pelo swapping. De relevância
mais óbvia ao usuário comum, o diretório corrente e a tabela de arquivos abertos são
mantidos na estrutura de usuário.

Todo processo tem uma fase de usuário e uma fase de sistema. Boa parte do trabalho
é feito no modo usuário, mas, quando uma chamada ao sistema é feita, ela é realizada no
modo de sistema. As fases nunca executam ao mesmo tempo.

Quando um processo está executando em modo sistema, uma pilha de kernel para
esse processo é usada, em vez da pilha de usuário que pertence a esse processo. A pilha
de kernel e a estrutura de usuário juntas compõem o segmento de dados do sistema para o
processo.

A chamada ao sistema fork aloca uma nova estrutura de processo (com novo
identificador de processo) para o processo filho, e copia a estrutura de usuário. Não há a
necessidade de uma nova estrutura de texto, os processos compartilham seu texto.
Contadores e listas apropriados são simples segmentos de dados e de pilha do processo
filho. Já a chamada ao sistema vfork não copia os dados e a pilha para o novo processo, em
vez disso, o novo processo simplesmente compartilha a tabela de página do processo
anterior. Uma nova estrutura de usuário e de processo são criadas.

Quando o processo pai é grande, vfork pode gerar economias substanciais de tempo
de CPU do sistema. No entanto, é uma chamada ao sistema consideravelmente perigosa, já
que qualquer mudança na memória ocorre nos dois processos até que execve ocorra. A
chamada ao sistema execve não cria um novo processo ou uma nova estrutura de usuário.
23
O texto e os dados do processo são substituídos. Os arquivos abertos são preservados,
bem como a maioria das propriedades de tratamento de sinais.

8.2 Escalonamento de CPU

O escalonamento de CPU no UNIX foi criado para beneficiar os processos interativos.


Todo processo tem uma prioridade de escalonamento associada a ele. Os processos que
fazem I/O de disco ou outras tarefas importantes têm prioridades menores do que zero
(número maiores indicam prioridade menor) e não podem ser interrompidos por sinais. Os
processos de usuários comuns têm menos prioridades de executar que os processos de
sistema.

Quanto mais tempo de CPU um processo acumula, menor (ou mais positiva) se torna
a sua prioridade, e vice-versa. Assim, existe um feedback negativo no escalonamento de
CPU e é difícil para um único processo usar todo o tempo da CPU. O envelhecimento de
processos é usado para evitar paralisação.

Não existe preempção de um processo por outro dentro do kernel. Um processo pode
abandonar a CPU porque está esperando por I/O ou porque sua fatia de tempo expirou.
Quando um processo escolhe abandonar a CPU, ele é suspenso em um evento. A
experiência sugere que o escalonador UNIX tem melhor desempenho com jobs limitados por
I/O, como pode ser observado quando existem vários Jobs limitados por CPU em execução.

Os processos são representados por duas estruturas: a estrutura de processo e a


estrutura de usuário. O escalonamento de CPU é um algoritmo com prioridades calculadas
dinamicamente, que se reduz ao Round-Robin, em casos extremos.

O escalonamento Round-Robin é realizado pelo mecanismo de timeout, que informa


ao driver de interrupção de clock para chamar uma sub-rotina do kernel apor um intervalo
específico. A sub-rotina a ser chamada nesse caso causa o reescalonamento e, em seguida,
submete novamente um timeout para si mesma.
24

9. MEMÓRIA E GERENCIAMENTO

As primeiras versões do Unix utilizavam basicamente a técnica de swapping para o


gerenciamento de memória. Apenas a partir da versão 3BSD, o Unix passou a utilizar
paginação por demanda. Atualmente, a grande maioria das versões do Unix, tanto BSD
como System V, implementa gerenciamento de memória virtual por paginação com
swapping.

O espaço de endereçamento dos processos no Unix é dividido em três segmentos:


texto, dados e pilha. O segmento de texto corresponde à área onde está o código
executável dos programas, sendo uma área protegida contra gravação. O segmento de
texto é estático e pode ser compartilhado por vários processos, utilizando o esquema de
memória compartilhada. O segmento de dados corresponde às variáveis do programa, como
tipos numéricos, vetores e strings. A área de dados é dinâmica, podendo aumentar ou
diminuir durante a execução do programa. A pilha armazena informações de controle do
ambiente do processo, como parâmetros passados a um procedimento ou system call. A
área de pilha cresce dinamicamente do endereço virtual mais alto para o mais baixo.

O Unix implementa o esquema de paginação por demanda como política de busca de


páginas. Nesse esquema, páginas do processo são trazidas do disco para a memória
principal apenas quando são referenciadas. O sistema mantém uma lista de páginas livres
com todos os frames disponíveis na memória e gerencia os frames de todos os processos
em uma lista de páginas em uso. Quando um processo faz referência a uma página que não
se encontra na lista de páginas em uso, ocorre um page fault. O sistema identifica se a
página está na memória através do bit de validade. Nesse caso, a gerência de memória
retira uma página da lista de páginas livres e transfere para a lista de páginas em uso. Como
pode ser observado, o Unix utiliza uma política global de substituição de páginas.

O sistema implementa uma variação do algoritmo FIFO (First In First Out) circular
como política de substituição de páginas. Esse algoritmo, conhecido como Two-Handed
Clock, utiliza dois ponteiros, ao contrário do FIFO circular, que implementa apenas um. O
primeiro ponteiro fica à frente do segundo um certo número de frames na lista de páginas
em uso. Enquanto o primeiro ponteiro desliga o bit de referência das páginas, o segundo
verifica o seu estado. Se o bit de referencia continuar desligado, significa que a página não
25
foi referenciada desde o momento em que o primeiro ponteiro desligou o bit, fazendo com
que essa página seja selecionada.

Apesar de estarem liberadas para outros processos, as páginas selecionadas


permanecem um certo tempo intactas na lista de páginas livres. Dessa forma, é possível
que as páginas retornem aos processos de onde foram retiradas, eliminando-se a
necessidade de acesso a disco. O deamon page também é responsável por implementar a
política de substituição de páginas.

Em casos onde o sistema não consegue manter um número suficiente de páginas


livres o mecanismo de swapping é ativado. Nesse caso, o daemon swapper seleciona,
inicialmente os processos que estão a mais tempo inativos. Em seguida, o swapper
seleciona dentre os quatro processos quem mais consomem memória principal aquele que
estiver a mais tempo inativo. Esse mecanismo é repetido até que a lista de páginas livres
retorne ao seu tamanho normal.

Para controlar todas as páginas e listas na memória principal, a gerência de memória


mantêm uma estrutura de mapeamento dos frames na memória (core map), com
informações sobre todas as páginas livres e em uso. O core map fica residente na parte não
paginável da memória principal, juntamente com o kernel do sistema.
26

10. Deadlocks

Deadlock é "Uma ocorrência em que cada processo do conjunto esta esperando por
um evento que somente outro processo pertencente ao conjunto poderá fazer acontecer."
Ressalta que a maior parte das situações de deadlock envolve a espera por recursos e que,
pela definição, nenhum processo do conjunto poderá evitar que todos os processos do
conjunto fiquem eternamente bloqueados.

10.1 Condições para Ocorrência de Deadlocks

 Exclusão Mútua, se nenhum recurso for atribuído exclusivamente a um único processo,


nunca haverá deadlock. O princípio é evitar alocar um recurso quando ele não for
absolutamente necessário e tentar assegurar que o menor número possível de processos
possa de fato requisitar o recurso. Exemplo: O uso de spool permitindo que somente um
recurso da impressora seja usado por processo.

 Condição de posse e espera, basta requerer que todos os processos solicitem os seus
recursos antes de iniciar a execução. No entanto, um processo nunca tem que esperar
por aquilo que precisa. Um dos problemas é não poder não saber quantos e quais
recursos vão precisar no início da execução e também reter recursos que outros
processos poderiam estar usando.

 Nenhuma preempção, seria tomar o recurso a força, contudo é uma solução pouco
promissora, de certa forma inviável.

 Espera circular, pode ser eliminado de várias maneiras, uma delas é ter uma regra que
diz que um processo é intitulado somente para um único recurso em qualquer momento,
ou atribuir uma ordem para chamada para aquele recurso. 1.2.6. Impedimento do
Impasse. Anteriormente o deadlock não foi evitado pela imposição de regras arbitrárias
aos processos, mas pela análise cuidadosa de cada solicitação de recurso para ver se
ele poderia ser concedido seguramente.
27
Para evitar dinamicamente o deadlock podem-se adotar algumas soluções:
 Alocação individual de recursos - à medida que processo necessita;
 Escalonamento cuidadoso – impões um alto custo e conhecimento prévio dos
recursos que serão utilizados;
 Algoritmos:

10.2 Algoritmo do Avestruz

Este "Algoritmo do Avestruz" é uma forma humorística do autor Tanenbaum para


comentar a abordagem dos sistemas UNIX, que simplesmente ignoram o problema,
em razão da baixíssima probabilidade de ocorrer tal situação3.

10.3 Algoritmo do Banqueiro

O algoritmo do banqueiro (algoritmo de Dijkstra), considera cada requisição no


momento em que ela ocorre, verificando se essa requisição leva a um estado seguro;
Se sim, a requisição é atendida, se não o atendimento é adiado para outro momento;
Premissas adotadas por um banqueiro para garantir ou não crédito (recursos) para
seus clientes (processos). Nem todos os clientes (processos) precisam de toda a linha
de credito (recursos) disponível para eles.

3
Fonte da Ilustração: http://www.inf.ufrgs.br/gppd/disc/inf01151/trabalhos/sem2000-2/deadlock/deadlock.htm
28
Vantagens e desvantagens do algoritmo do banqueiro: - Pouco utilizado, pois é
difícil saber quais recursos serão necessários; - O número de processos é dinâmico e
pode variar constantemente, tornando o algoritmo custoso; - Na teoria o algoritmo é
ótimo.

10.4 Tratamento de Deadlocks

 Ignorar o problema: algoritmo da avestruz (Tanenbaum).

 Detectar e recuperar.

 Evitar (avoidance: solução dinãmica).

 Prevenir (prevention: solução estática).

O Unix tenta evitar situações de deadlock, mas não as elimina completamente.

10.5 Detectar e Recuperar

Detectar deadlock consiste em um algoritmo que basicamente testa se há alguma


ordem de terminação dos processos e solicitação de recursos.

Recuperar a situação:

 preempção de recursos;

 roll-back de processos;

 terminação de processos.
29

11. Threads no UNIX

Conforme Miguel Pimenta Monteiro4, somente ha pouco tempo a especificação POSIX


da API do Unix definiu uma interface standard para a criação e terminação de threads. Esta
interface é geralmente implementada como uma biblioteca (libpthreads.a), podendo ou não
ser diretamente suportada pelo kernel do sistema operacional. Existem versões do Unix em
que os threads são diretamente implementados no kernel e escalonados
independentemente são os (kernel level threads), enquanto que em outras versões o que o
kernel vê são apenas processos, “existindo” os threads unicamente na biblioteca de suporte,
e escalonados para execução apenas na “fatia de tempo” dos respectivos processos são os
(user level threads).

Quando um programa começa a executar na função main() constitui um novo


processo e pode considerar-se que contém já um thread. Novos threads são criados através
da chamada de um serviço e começam a executar numa função que faz parte do código do
programas.

Cada novo thread é representado por um identificador (thread identifier ou tid) de tipo
pthread_t. É necessário passar o endereço de uma variável desse tipo, como primeiro
parâmetro de pthread_create(), para receber o respectivo tid. O segundo parâmetro serve
para indicar uma série de atributos e propriedades que o novo thread deverá ter, se fornecer
o valor NULL, o novo thread terá as propriedades por padrão, adequadas na maior parte dos
casos. O terceiro parâmetro informa a função de início do thread. É uma função que deve
existir com o seguinte protótipo:

4
Fonte: Miguel Pimenta Monteiro - Sistemas Operativos
30
 void * nome_da_função(void *arg).

A função aceita um apontador genérico como parâmetro, que serve para passar
qualquer informação, e retorna também um apontador genérico, em vez de um simples
código de terminação. Se o valor de retorno for usado, é necessário que aponte para algo
que não deixe de existir quando o thread termina. Finalmente o quarto parâmetro é o valor
do apontador a ser passado à função de inicio, como seu parâmetro. Uma vez criado o novo
thread ele passa a executar concorrentemente com o principal e com outros que porventura
sejam criados.

Quando um thread termina pode retornar um apontador para uma área de memória
que contenha qualquer tipo de resultado. Essa área de memória deve sobreviver o thread,
ou seja, não pode ser nenhuma variável local, porque essas deixam de existir quando o
thread termina.

Por padrão, quando um thread termina, o seu valor de retorno (o apontador genérico)
não é destruído, ficando retido em memória até que algum outro thread execute um
pthread_join() sobre ele. É possível criar threads que não são joinable e que por isso,
quando terminam, libertam todos os seus recursos, incluindo o valor de retorno. No entanto
não é possível esperar por esses threads com pthread_join().

Quando se cria um novo thread é possível especificar uma série de atributos e


propriedades passando-os a pthread_create() através de uma variável do tipo
pthread_attr_t. Essa variável terá de ser previamente inicializada com o serviço
pthread_attr_init() e depois modificada através da chamada de serviços específicos para
cada atributo5.

5
Fonte da ilustração: https://computing.llnl.gov/tutorials/pthreads/
31
12. Kernel

Conforme texto do IME-USP6, o Kernel do Unix (e de virtualmente qualquer outro


sistema operacional) possui um papel de que convém ter noções, a fim de se poder
compreender melhor o funcionamento do sistema, realizar diagnósticos e procedimentos
administrativos como adição de componentes de hardware. Algum conhecimento do papel
do Kernel é importante também para se ter uma noção mais clara do uso de arquivos
especiais e do diretório /proc.

O Kernel ordinariamente reside no filesystem como um outro arquivo qualquer. No


Linux, ele é em geral o arquivo /vnlinuz ou /boot/vmlinuz, ou ainda /boot/vmlinuz-2.0.36.
Ele é um programa, ainda que um pouco diferente dos programas de aplicaçãocom o
/Bin/Is. O Kernel é carregado e posto em execução no boot da máquina, e a sua execução
somente se encerra com o shutdown.

De forma simplificada, o seu papel é num primeiro momento reconhecer o hardware e


inicializar os respectivos drivers. Em seguida ele entra num estado administrativo onde
funciona como intermediário entre as aplicações e o hardware. Por exemplo, quando uma
aplicação necessita alocar mais memória, ela solicita isso ao Kernel. É o Kernel que distribui
o tempo de CPU aos vários processos ativos. É ele que habitualmente realiza a entrada e
saída de dados nas diferentes portas de comunicação.

É por isso que a adição de hardware novo a uma máquina pode requerer a
substituição ou ao menos a reconfiguração do Kernel. Os Kernels mais recentes do Linux
oferecem vários mecanismos de configuração que os tornam sobremaneira flexíveis, a
ponto de ser rara a necessidade de substituição do Kernel. Os dois mecanismos
fundamentais de se configurar a operação do Kernel são a passagem de parâmetros no
momento do boot (realizada pelo LILO) e a carga de módulos, feita manualmente ou por
mecanismos automáticos como o Kerneld.

O diálogo entre as aplicações e o Kernel realiza-se fundamentalmente através dos


system calls, que são serviços que o Kernel oferece, como por exemplo read(2). Os device
special files são maneiras de se referir ao Kernel os dispositivos físicos ou lógicos com que
se pretende operar, por exemplo a primeira porta serial ou a segunda unidade de fita, ou o
disco principal do sistema. Neles, o importante não é o nome, mas sim os números de
dispositivos ou mais precisamente o major e o minor device numbers. Device special files
são criados através do comando mknod, ou através de interfaces mais amigáveis, como o
comando MAKEDEV.

6
Fonte: Unix: Conceitos e Comandos Básicos
32

Os sistemas Unix-Like mais recentes oferecem um outro mecanismo de comunicação


com o Kernel, que é o filesystem /proc. As entradas desse filesystem são pseudo-arquivos
cujo conteúdo reflete o estado atual de inúmeras estruturas de dados internas do Kernel.
Assim, um programa de aplicação passa a poder comunicar-se com o Kernel através dos
mecanismos ordinários de leitura e escrita de arquivos.

Em muitos casos a comunicação entre as aplicações e o Kernel é intermediada por


bibliotecas, principalmente a libc. Elas oferecem serviços de mais alto nível que os system
calls do Kernel, tornando mais simples o trabalho de programação.
33
13. Dispositivos de E/S

Processos num sistema UNIX habitualmente possuem três dispositivos de I/O


“padrões”, a “saída padrão”, a “entrada padrão” e a “saída de erros”. O Unix permite que
esses dispositivos (e outros) sejam definidos no momento da execução, podendo escolher o
console, um “pipe” (pipe é um canal de comunicação FIFO(fist in, first out - primeiro a entrar,
primeiro a sair) em modo simplex que pode ser usado para comunicação unidirecional entre
processos. Uma implementação é geralmente integrada no subsistema de entrada e saída
I/O de um sistema operacional), a impressora, um circuito virtual de rede conectando duas
máquinas, uma linha física serial ou outras coisas.

Usuários de MS-DOS talvez já tenham feito coisas como C>DIR>PRN, para imprimir a
saída de um comando. Essa sintaxe foi herdada do UNIX daí a semelhança $ Is –I>dev/lp1.
Naturalmente tanto no MS-DOS quanto no Unix existem formas mais apropriadas para se
imprimir algo, mas no momento esse exemplo convém. Shell do estilo “Bourne” (sh,
ksh,bash) permitem redirecionamento da saída de erros através da seguinte sintaxe:
$ rm /bin/Is 2>/tmp/error
O “2” deve-se a que, internamente, a saída de erros corresponde ao descritor 2 (o 0 é
a entrada padrão e o 1 é a saída padrão). A entrada pode ser redirecionada de forma
semelhante:
$ wc </tmp/error
Os shells Unix oferecem um recurso para a ligação da saída padrão de um processo
com a entrada padrão de outro, chamado pipe:
$ Is|wc

No exemplo a saída do Is está sendo usada como entrada do wc. Note que o shell
dispara os dois processos ao mesmo tempo. Se o primeiro estiver produzindo saída numa
taxa superior à que o segundo lê, o sistema operacional paralizará o primeiro sempre que o
buffer que armazena o tráfego estiver cheio. Isso significa, por exemplo, que um pipe pode
ser usado mesmo quando o volume total da saída do primeiro processo é
extraordinariamente grande, por exemplo quando se tenta localizar informações de arquivos
deletados através de um dump de todos os setores do disco.
34
14. Comunicação Serial e Paralela

O Unix apresenta as portas de comunicação seriais e paralelas na forma de arquivos


especiais. Já vimos um exemplo de seu uso no item redirecionamento da Entrada e da
Saída, em que fizemos a impressão da saída de um comando.

Na comunicação entre dois computadores, utiliza-se frequentemente portas seriais, e


às vezes também as paralelas. Em muitos casos, quando a distância entre os dois é grande,
haverá uso de modems e eventualmente também de uma linha telefônica. Através de três
exemplos práticos pode-se ter um bom panorama do uso de comunicação serial no UNIX.
Como os procedimentos variam um pouco dependendo das plataformas em uso, só é
possível indicá-los de forma genérica:
a) Adição de um terminal
 Conectar a serial do terminal com a da máquina UNIX;
 Disparar no Unix a variante do getty disponível;
 Logar no terminal;
 Transferir arquivos se o terminal oferecer esse recurso.

b) Conexão a um sistema remoto


 Disparar algum emulador de terminal disponível;
 Selecionar a serial em que o modem está conectado;
 Configurar o modo de operação da serial (velocidade, bits);
 Configurar o modem através de comandos AT, se necessário;
 Instruir o modem para discar, com ATD
 Aguardar a negociação;
 Logar.

c) Estabelecimento de um link ppp


 Executar a conexão ao sistema remoto como indicada acima;
 Iniciar o ppp no sistema remoto;
 Disparar o pppd localmente;

Em PCs, os conectores externos das portas seriais são conectores DB-9 ou DB-25
macho, e os das paralelas são DB-25 fêmea.
35
15. Configuração do TCP/IP

Numa rede TCP/IP, a cada máquina está associado um número IP, que é um inteiro de
32 bits, normalmente escrito na forma de octetos, como 192.168.0.5. A cada máquina está
associado em um nome, como por exemplo marte ou pimenta.

A atribuição tanto do número quanto do nome é feita durante o processo de boot, a


partir da especificação deles feita através da edição manual de arquivos de configuração
e/ou de uso de aplicativos de gerenciamento do sistema específicos de cada plataforma.

Na verdade, o número IP não está associado à máquina, mas a uma determinada


interface dela. Via de regra, a interface envolvida é a ethernet. Tanto para exibir quanto para
setar manualmente o número IP de uma interface usa-se o comando ifconfig. Por exemplo, o
comando: $ ifconfig –a, irá listar todas as interfaces com informações de cada uma. A
interface ethernet costuma chamar-se le0 (Solaris) ou eth0 (Linux). Além do ethernet, é
comum usar-se portas seriais para criar interfaces TCP/IP, principalmente para criar links
com linhas telefônicas. As placas ethernet costuma oferecer dois ou mais tipos de
conectores. Ela pode ou não descobrir automaticamente qual está em uso. Em caso
negativo, você deverá informá-la, o que habitualmente é feito através de um software de
configuração que acompanha a placa.

O passo seguinte é a configuração das rotas. Através delas a máquina sabe por onde
enviar datagramas a fim de que eles cheguem em seus destinos. Equivale de certa forma à
sinalização do tráfego urbano, com placas indicativas da direção a tomar para atingir cada
destino (Ponte do Limão à esquerda, ou Avenida dos Bandeirantes em frente, etc).

Cada rota envolve um destino, uma máscara, um gateway e uma interface. Pode-se
exibir todas elas através do comando netstat: $ netstat –r

Destination Gateway Genmask Iface


192.168.1.0 * 255.255.255.0 eth0
127.0.0.0* 255.0.0.0 Io
Default 192.168.1.1 0.0.0.0 eth0

Suponha que você deseja atingir a máquina 192.168.1.7. A aplicação da tabela de


rotas indica, através de uma operação e bit a bit entre 192.168.1.7 e a máscara
255.255.255.0, que deve ser usada a primeira rota. Como não ha gateway, a comunicação
será feita diretamente através do ethernet.
36
Se o destino agora for 200.136.35.65, as duas primeiras rotas não nos servirão
(experimente aplicar o e como no caso anterior). Portanto será usada a rota default, e como
ela especifica um gateway, a comunicação terá que ser feita através dele. Assim toda vez
que se pretender enviar alguma informação para o 200.136.35.65, esta será enviada antes
para o gateway 192.168.1.1, na esperança de que este consiga roteá-la para o seu destino.
37

/
.Miguel Pimenta Monteiro6, somente ha pouco tempo a especificação POSIX da API do
Unix definiu uma interface standard para a criação e terminação de threads. Esta interface é
geralmente implementada como uma biblioteca (libpthreads.a), podendo ou não ser
diretamente suportada pelo kernel do sistema operacional. Existem versões do Unix em que
os threads são diretamente implementados no kernel e escalonados independentemente
são os (kernel level threads), enquanto que em outras versões o que o kernel vê são apenas
processos, “existindo” os threads unicamente na biblioteca de suporte, e escalonados para
execução apenas na “fatia de tempo” dos respectivos processos são os (user level threads).

6
Fonte: Miguel Pimenta Monteiro - Sistemas Operativos
38

11. Referências Bibliográficas

Krahe, F. Nivelamento UNIX. Disponível em:


< http://www.pop-rs.rnp.br/ovni/unix/Welcome.html>. Acesso em 25/10/2010

Malanovicz, A. V. at all. Deadlock (Tanenbaum X Silberschatz) Disponível em:


<http://www.inf.ufrgs.br/gppd/disc/inf01151/trabalhos/sem200-2/deadlock/deadlock.htm> Acesso
em 27/10/2010

Monteiro, MP. Sistemas Operativos. Disponível em:


< http://paginas.fe.up.pt/~pfs/aulas/so2001/ap/cap4.pdf>. Acesso em 27/10/2010