Prévia do material em texto
Legenda: Já caiu em P2 anterior. | Caiu no Teste 4 (também pode estar marcado como caiu em P1 anterior) | Caiu no Teste 5 | Pode ser interessante estudar - Foquem no Capítulo 4 e 5, pois ele disse que do 6 só vai cair uma questão, mas sugiro não deixar de estudá-lo. Os que não estão marcados em nada não quer dizer que não pode cair, então estudem da maneira como acharem melhor. Aula 13 - Sistema de Arquivos O sistema de arquivos é a parte do SO que gerencia os arquivos, visando separar a informação do processo (a info não é afetada pelo término ou criação do mesmo), com objetivo de persisti-la, sendo gerenciados pelo próprio SO. Visão do usuário – mudança de nomes e operações permitidas, interface. Visão do Implementador – Como é o armazenamento de arquivos e diretórios e o espaço é gerenciado no disco. Estrutura de Arquivos – Os arquivos podem ser organizados de três maneiras. Sequência de Bytes (Desestruturado): O arquivo é como uma sequência aleatória de números (bytes) que o sistema operacional não entende ou não se preocupa em entender, não tem conhecimento do conteúdo real do arquivo e ualquer interpretação do conteúdo é deixada para programas de usuário, então, os usuários têm total liberdade para armazenar qualquer tipo de informação nos arquivos, e o sistema operacional não impõe nenhuma restrição. Sequência de Registros de Tamanho Fixo: Neste modelo, um arquivo é uma sequência de registros, cada um com uma estrutura interna e tamanho fixo. As operações de leitura retornam registros e operações de escrita sobrepõem ou anexam registros. Esse modelo era comum em sistemas de computadores mais antigos. Árvore de Registros com Chaves (Estruturado): Nesse modelo, um arquivo consiste em uma árvore de registros, não necessariamente do mesmo tamanho, cada um com um campo chave em uma posição fixa. A árvore é ordenada pelo campo chave para permitir buscas rápidas por chaves específicas. Permite uma busca rápida e eficiente por registros específicos com base em suas chaves, sendo útil quando é necessário recuperar informações específicas de maneira eficaz.Usado em computadores de grande porte. Tipos de Arquivos - Os de diretórios e especiais de caracteres e de blocos você já conhece. (Resumo 1) - Arquivos Regulares: Esses arquivos contêm informações do usuário e podem ser tanto arquivos ASCII como arquivos binários. Métodos de Acesso em Arquivos de Acesso Aleatório Acesso Sequencial: Dados são lidos em ordem no arquivo, a partir do ínicio e continuam em sequência. Não é possível pular para partes específicas do arquivo ou ler os dados fora de ordem. Em sistemas de arquivos sequenciais, a operação "rewind" é necessária porque a leitura e gravação de dados ocorrem em uma sequência linear, e um ponteiro é usado para indicar a posição atual de leitura/gravação no arquivo. Quando a operação "rewind" é usada, o ponteiro é redefinido para o início do arquivo, ou seja, ele aponta para o endereço zero do arquivo. Isso permite que você comece a ler ou gravar dados a partir do início do arquivo novamente. Acesso Aleatório: É possível ler os dados em qualquer ordem, pular para qualquer parte do arquivo e acessar registros específicos com base em uma chave ou posição. A chamada seek permite estabelecer a posição atual no arquivo para leitura, a partir desse ponto, os dados podem ser lidos sequencialmente com a chamada read, mas agora a partir dessa nova posição. É possível ler um arquivo novamente acessando também o ‘byte 0’, que é a posição inicial do arquivo e não é afetado pelas operações de leitura ou gravação anteriores. Atributos em Arquivos Operações com Arquivos Create: Usada para criar um arquivo vazio, estabelecendo seus atributos iniciais. Delete: Remove um arquivo que não é mais necessário, liberando espaço no disco. Open: Permite que um processo acesse um arquivo, buscando seus atributos e endereços de disco para acesso posterior. Close: Fecha um arquivo após a conclusão de todas as operações, liberando espaço na tabela interna de arquivos. Read: Lê dados de um arquivo, geralmente da posição atual, especificando a quantidade de dados a ser lida e fornecendo um buffer. Write: Escreve dados em um arquivo, normalmente na posição atual. Se a posição for o final do arquivo, seu tamanho aumenta; se no meio, os dados existentes são sobrescritos. Append: Permite a adição de dados apenas no final de um arquivo. Seek: Reposiciona o ponteiro de arquivo para uma posição específica em arquivos de acesso aleatório, permitindo leitura ou escrita a partir desse ponto. Get attributes: Permite que os processos leiam os atributos de um arquivo, como data de modificação, para executar suas tarefas. Set attributes: Permite a modificação de atributos, como o modo de proteção, após a criação do arquivo. Rename: Renomeia um arquivo, e as características (tempo da última modificação ou de criação por ex) não são alteradas. É diferente de copiar o arquivo com um novo nome e excluindo o antigo, o que altera as características. Tipos de Diretório - Nivel único: um único diretório contém todos os arquivos, geralmente, usado em dispositivos embarcados simples, como câmeras digitais, pode se tornar caótico quando há muitos arquivos. Nivel hierárquico: Arquivos organizados em estrutura de árvore hierárquica, cada usuário tem o próprio diretório-raiz e hierarquia. Nomes de Caminhos - Absoluto: Começam no diretório-raiz e fornecem o caminho completo para um arquivo e começam com o separador de diretório (como / ou \). Relativo: São usados em relação ao diretório de trabalho atual, com o uso de '.' e '..'. Operações com Diretórios Create (Criar): Cria um novo diretório vazio. Essas entradas são adicionadas automaticamente. Delete (Excluir): Remove um diretório existente. Geralmente, somente diretórios vazios podem ser excluídos. Um diretório que contenha apenas as entradas "." e ".." é considerado vazio e pode ser excluído. Opendir (Abrir diretório): Abre um diretório para leitura. Isso permite que programas leiam o conteúdo do diretório, como listar os nomes de arquivos contidos nele. Antes de ler um diretório, ele deve ser aberto, semelhante à abertura de um arquivo. Closedir (Fechar diretório): Após a leitura de um diretório, ele deve ser fechado para liberar recursos internos do sistema, como espaço na tabela. É uma prática comum fechar o diretório após a leitura. Readdir (Ler entrada de diretório): Retorna a próxima entrada no diretório aberto. Essa chamada de sistema permite que os programas leiam as entradas de diretório em um formato padrão, independentemente da estrutura interna do diretório. Rename (Renomear): Permite que diretórios sejam renomeados da mesma maneira que os arquivos. Link (Ligação): A chamada de sistema de ligação (hard link) permite que um arquivo seja associado a mais de um diretório. Isso significa que o mesmo arquivo pode ser acessado por diferentes nomes de caminho. Essa operação cria uma relação direta com o arquivo original. Se você criar um hard link para um arquivo e, em seguida, excluir o arquivo original, o conteúdo ainda estará disponível por meio do hard link, pois estes estão associados ao mesmo i-node e bloco de dados do arquivo original, promovendo uma igualdade entre os arquivos, o que não ocorre na ligação simbólica, o que também evita sobrecarga extra na resolução de um link. Unlink (Desvincular): Remove uma entrada de diretório. Se o arquivo estiver presente em vários diretórios, apenas a entrada de diretório especificada é removida, enquanto as outras permanecem. No UNIX, a chamada de sistema para remover arquivos é, na verdade, chamada "unlink." Aulas 14, 15 e 16 – Sist. de Arq. Pt. 2 MBR (Master Boot Record) e Inicialização - É o "Setor 0" do disco, usado para inicializar o computador. Ele contém uma tabela de partição, que lista as informações sobre as partições no disco,como onde cada uma começa e termina. Uma das partições na tabela é marcada como "ativa", o que significa que é a partição usada para inicializar o sistema operacional executando seu primeiro bloco, após a bios ler o MBR. Ele encontra a partição ativa, executando seu 1º bloco, e o SO contido nele é carregado. O superbloco é uma estrutura de dados que armazena informações críticas sobre o sistema de arquivos (tamanho total, blocos livres e ocupados, localização de i-nodes, data e hora, etc). Ele também compõe o SA assim como os outros componentes do segundo bloco na parte debaixo da imagem abaixo: Alocação Contígua - Método de armazenar arquivos em disco aonde cada um é alocado em blocos consecutivos de disco, sendo armazenados de forma que cada arquivo comece em um novo bloco. Ex: em um disco com blocos de 1 KB, um arquivo de 50 KB ocuparia 50 blocos consecutivos. Vantagens: simplicidade de implementação e leitura eficiente, uma vez que um arquivo pode ser lido em uma única operação, reduzindo o tempo de busca e atrasos rotacionais. Desvantagens: Fragmentação externa do disco (como em segmentação pura), pois lacunas de blocos livres são deixadas quando arquivos são excluídos, ou seja, entre as unidades de alocação, e não dentro dos arquivos, e compactar o disco para eliminar essas lacunas é um processo demorado e custoso, sendo necessário manter uma lista de lacunas de blocos livres, o que traz complicação em relação a escolha da lacuna adequada, pois é necessário saber o tamanho do arquivo. Ainda é usada em CD- ROMs, pois os tamanhos dos arquivos são conhecidos antecipadamente e não mudam com o uso do sistema de arquivos, e em DVDs, essa alocação é usada em pedaços menores chamados de extensões, com limite de tamanho dos arquivos, sendo abandonada para discos magnéticos por conta da necessidade de especificar o tamanho final do arquivo ao criá-lo. Alocação por Lista Encadeada - Forma de armazenar arquivos em discos aonde cada arquivo é mantido como uma lista encadeada de blocos de disco, onde a primeira palavra de cada bloco atua como um ponteiro para o próximo bloco na sequência, e o restante é usado para armazenar os dados do arquivo. Nenhum espaço é perdido na fragmentação e é necessário armazenar apenas a entrada do 1º bloco. O acesso aleatório é lento, uma vez que para chegar a um determinado bloco, o sistema operacional precisa seguir a cadeia de ponteiros a partir do início, lendo cada bloco sequencialmente, gerando muitas leituras. A quantidade de dados que um bloco pode armazenar não é mais uma potência de dois, pois os ponteiros ocupam parte do bloco, o que pode prejudicar a otimização dos programas. Alocação por lista encadeada usando uma tabela na memória (FAT) - Usada para resolver as desvantagens da alocação anterior, utilizando uma tabela chamada FAT (File Allocation Table), que armazena informações sobre como os blocos de disco estão vinculados para cada arquivo. Como a tabela está totalmente na memória, o acesso aleatório é mais rápido, permitindo um acesso rápido aos blocos de disco e também todo o bloco fica disponível para armazenamento de dados para simplificar o acesso aos dados. Há a desvantagem que alocação de arquivos precisa estar presente na memória o tempo todo, o que pode ser impraticável em sistemas com discos grandes, devido à quantidade significativa de memória necessária. O valor que está em um bloco aponta para o próximo aonde o arquivo continua e por aí vai. O arquivo ocupa os blocos ocupa os blocos 4 -> 7 -> 2 -> 10 -> 12 (parando aonde há o -1). I-Nodes - Método de alocação aonde cada arquivo é associado a uma estrutura de dados chamada i-node (index-node ou nó-índice), que lista os atributos e os endereços de disco dos blocos do arquivo. O i-node contém informações sobre o arquivo, como seu nome, permissões, data de modificação e, mais importante, os endereços dos blocos no disco onde os dados do arquivo estão armazenados, permitindo encontrar todos os blocos de disco que compõem o arquivo. Vantagem: O i-node precisa estar na memória apenas quando o arquivo correspondente está aberto, então a memória ocupada é relativamente pequena, geralmente proporcional ao número máximo de arquivos que podem ser abertos simultaneamente. Desvantagem: Um arquivo pode crescer além do espaço disponível em seu i-node, sendo necessário usar um bloco dentro do i-node para armazenar mais endereços de disco (endereço de bloco de ponteiros), permitindo que o arquivo cresça além do tamanho inicialmente previsto. Ter duas cópias do i-node na tabela de i-nodes ao mesmo tempo, especialmente quando ambos estão sendo atualizados, pode levar a problemas sérios no sistema de arquivos, pois se ambos os processos que podem abrir um arquivo simultaneamente, atualizarem o arquivo ao mesmo tempo, podem ocorrer problemas de concorrência, e se um processo sobrescrever as alterações do i-node feitas pelo outro processo, os dados do arquivo e os blocos de disco associados podem ficar inconsistentes. Quando os i-nodes são gravados de volta no disco, a última cópia gravada irá substituir as alterações feitas pelo outro. Isso pode resultar em perda de dados, inconsistências no sistema de arquivos e corrupção de arquivos. Portanto, em vez de buscar uma nova cópia do i-node toda vez que um arquivo é aberto, os sistemas operacionais geralmente adotam abordagens de cache, aonde quando um arquivo é aberto, o SO carrega o i-node na memória e o mantém em um cache, então todos os processos compartilham a mesma cópia do i-node, e qualquer alteração feita por um processo será visível para outros processos que também estão acessando o mesmo arquivo. Implementação de Diretórios (Lidar com Armazenamento de Atributos) - Diretório com atributos na entrada de diretório: Atributos de um arquivo, como o proprietário, a data de criação e informações de proteção, são armazenados diretamente na entrada de diretório associada ao arquivo, com cada entrada de diretório contém um espaço para atributos fixos, pode levar à fragmentação do diretório quando os arquivos são excluídos, deixando lacunas de tamanhos variáveis. Diretório com atributos no i-node: Armazena os atributos dos arquivos nos próprios i-nodes, e a entrada de diretório contém apenas o nome do arquivo e um número de i-node, sendo mais eficiente em termos de espaço no diretório, pois os atributos não precisam ser armazenados repetidamente em cada entrada. Implementação de Diretórios (Nomes de arquivos longos) - Tamanhos fixos: Estabelecer um tamanho máximo para os nomes de arquivos, alocando espaço para nomes de tamanho fixo em cada entrada de diretório, mas pode desperdiçar espaço quando a maioria dos nomes de arquivos é curta. Heap de nomes: Mantém um "heap" no final de cada diretório, onde os nomes de arquivos são armazenados em ordem variável, de tal forma que cada entrada de diretório consiste em um cabeçalho de tamanho fixo que contém informações como o tamanho do nome do arquivo e um ponteiro para a posição do nome do arquivo no heap, e quando os arquivos são removidos, o espaço no heap pode ser reutilizado para acomodar os novos nomes de arquivos. Implementação de Diretórios (Busca por nomes de arquivos eficiente) - Hash Table: Uma tabela hash é usada para mapear nomes de arquivos em valores de dispersão (hash values), que são usados para localizar entradas no diretório, e se várias entradas tiverem o mesmo valor, formarão uma lista encadeada. Acelera a busca, mas envolve uma complexidade adicional de gerenciamento. Cache de Busca: Uma cache de busca é usada para armazenar nomes de arquivos recentemente pesquisados. Antes de iniciar uma busca, é checado se o nome do arquivo está na cache. É eficaz quando há um conjunto de arquivos frequentemente pesquisado. Arquivos Compartilhados - Usuários colaboram em um projeto e precisam compartilhararquivos, é comum que um arquivo compartilhado apareça em diferentes diretórios pertencentes a usuários distintos. Pode ocorrer a falta de visibilidade de alterações feitas por um usuário nos diretórios de outros. Para resolver isso, existem duas abordagens. Lista de blocos de disco: Nessa solução, os diretórios apontam apenas para uma pequena estrutura de dados associada ao arquivo, que contém a lista de blocos de disco, os atributos são armazenados no i-node, sendo usada no UNIX. Ligação de arquivos/Ligação Simbólica: Aqui, um usuário (A) cria um novo arquivo de ligação e o insere em seu diretório, então esse arquivo link contém apenas o caminho para o arquivo original de outro usuário (B), quando o usuário que criou o arquivo link (A) lê o arquivo de ligação, o sistema operacional o direciona para o arquivo real. Apenas o verdadeiro proprietário tem um ponteiro para o i-node, e os outros usuários possuem apenas nomes de caminhos. Ela exige um processamento extra, pois os caminhos precisam ser analisados e resolvidos para encontrar o arquivo real, resultando em mais acessos ao disco. Se mover o arquivo original, os arquivos de ligação são interrompidos. As ligações simbólicas apresentam maior flexibilidade e interoperabilidade dos que os hard links, pois podem ser usadas para criar atalhos e referências para facilitar a organização do sistema de arquivos, sem necessidade da assossiação direta ao i-node, ou apontar arquivos ou diretórios em diferentes sistemas de arquivos ou até mesmo em locais remotos por meio de URLs, e são mais eficientes quanto a espaço em disco. Sistema MS-DOS - É um sistema de arquivos FAT que é uma das estruturas de sistema de arquivos mais antigas. Cada diretório contém entradas de diretório que listam os nomes dos arquivos, atributos, data/hora de criação e tamanho. No entanto, o sistema de arquivos FAT usa um formato fixo de 32 bytes para cada entrada de diretório, incluindo atributos que indicam se um arquivo é somente leitura, precisa ser arquivado, está oculto ou é um arquivo de sistema. Existem três principais versões do sistema de arquivos FAT: FAT-12, FAT-16 e FAT-32: cada versão tem um tamanho de bloco diferente e suporta diferentes tamanhos máximos de partição. Tamanho máximo de uma partição: nº de entradas (endereços) possíveis * tamanho do bloco de dados. MS-DOS suporta, no máximo, 4 partições por disco = Tamanho máximo de uma partição * quantidade de partições (4 no caso). Sistema de Arquivos UNIX V7 - Cada diretório contém entradas de diretório para os arquivos e subdiretórios dentro dele (formato de árvore), aonde cada entrada consiste em um nome de arquivo (com até 14 caracteres) e o número do i-node associado a esse arquivo (usando 2 bytes). O i-node contém os atributos , incluindo um contador do número de entradas de diretório que apontam para esse i-node. Alocação arquivos pequenos – 10 primeiros endereços armazenados no i-node. Alocação arquivo maiores – i-node contém end. para blocos indiretos simples, duplos e triplos (que contém lista dos simples). A chamada open para abrir arquivos antes de ler ou gravar neles, ela não é essencial, mas sem ela, toda vez que você desejasse realizar uma operação de leitura ou gravação, precisaria especificar o nome do arquivo, tornando o código muito mais complexo, e teria que procurar o arquivo na árvore de diretórios a cada vez que quisesse acessá-lo. As tarefas para abrir um arquivo como verificação de permissões e alocação de recursos teriam de ser feitas manualmente, resultando em perda de eficiência. Para localizar um arquivo é realizada uma operação de leitura em disco a cada arquivo no caminho tanto para abrir o diretório quanto para o i-node. Ex: se o caminho tiver 5 separadores, etapas ou arquivos, serão necessárias 10 operações em disco. Aula 17 e 18 – Entrada/Saída E/S Mapeada na Memória – Abordagem usada em computadores mais antigos para comunicação entre o controlador e a CPU. No controlador, cada registrador usado no controle tem um número de porta de E/S associado, de 8 ou 16 bits, o conjunto de todas essas portas (bloco) formam o espaço E/S, de forma que apenas o SO poderá acessá-lo, e instruções especiais de E/S, como IN REG, PORT e OUT PORT, REG, são usadas para ler e escrever nos registradores de controle. Os registradores de controle são mapeados na memória (tendo um endereço de memória único). IN REG, PORT – Lê o número/endereço da porta E/S associada a um registrador de controle e o armazena no registrador da CPU, aonde PORT é o valor da porta. MOV REG, PORT – Lê o conteúdo da palavra no endereço da memória (porta) 4 e o coloca no registrador. OUT PORT, REG - Escreve o conteúdo do registrador da CPU na porta E/S com o número/endereço especificado. Vantagens - Simplifica o código do dispositivo pois não exige instruções especiais de E/S, permite que diferentes drivers de dispositivos sejam colocados em espaços de endereçamento diferentes, facilita o desenvolvimento em linguagens de alto nível, pois os registradores de controle são tratados como variáveis na memória. Desvantagens - Se os registradores de controle forem armazenados em cache, ele pode manter uma cópia desatualizada do conteúdo do registrador de controle, levando a comportamentos indesejados quando a CPU tenta interagir com o dispositivo. Para mitigar isso, o hardware precisa ser capaz de desabilitar seletivamente o cache para regiões da memória que tenham registradores de controle, adicionado complexidade ao hardware. Em sistemas com múltiplos barramentos, os dispositivos de E/S por estarem conectados em um barramento separado, podem não "ver" os endereços de memória quando esses endereços são enviados apenas para o barramento de memória. DMA (Acesso Direto na Memória) – Técnica que auxilia a melhora do desempenho em sistemas de multiprogramação, pois permite a CPU se dedique a atender outra tarefa mais importante, enquanto ocorre a operação E/S em paralelo, sem esperar para que ela finalize. Sem DMA, a CPU requisita dados de dispositivos de E/S um byte de cada vez, ocupando-a durante o processo. Com DMA, a CPU programa o controlador DMA para fazer a transferência desejada que é iniciada sem intervenção contínua da CPU. Transferência - CPU programa o controlador de DMA com os parâmetros da transferência e ela começa -> controlador emite uma solicitação de leitura para o dispositivo de E/S -> dispositivo de E/S lê dados de forma assíncrona e escreve diretamente na memória, sem a CPU intermediar cada byte -> o dispositivo de E/S confirma a finalização da escrita, caso tenha terminado, ao controlador de DMA -> controlador de DMA atualiza o endereço de memória e o contador de bytes em 0 para avisar a CPU o término da operação Modos de Operação - Modo Palavra a Palavra (Word-at-a-Time): Uma palavra (byte ou palavra) é transferida por vez. Modo Bloco (Burst Mode): Várias palavras são transferidas em uma sequência contínua. Tem maior eficiência, mas pode bloquear a CPU por um período mais longo. Modo Direto – Dispositivo transfere os dados diretamente pra memória. Modo Indireto – A transferência passada pelo DMA antes de chegar na memória. Interrupções Solicitação - Se não houver interrupção pendente, o controlador de interrupção processa imediatamente. Caso contrário, se outra interrupção estiver em andamento ou outra solicitação de maior prioridade estiver na linha de requisição, a interrupção atual é ignorada temporariamente. Tratamento – Controlador coloca um número, identifica qual dispositivo ou componente requer atenção da CPU, nas linhas de endereço de comunicação entre CPU, dispositivos E/S e memória. Então, um sinal é enviado a CPU para interrompê-la. Execução da Rotina de Tratamento - A CPU para sua atividade atual e inicia a execução da rotina de tratamento de interrupção, um vetor destas é usado para encontrar o endereçoda rotina correspondente. Salvamento de Estado - Hardware armazena informações essenciais, como o contador do programa (PC), para que o processo interrompido possa ser reiniciado do estado que parou. Interrupções Precisas - O contador de programa (PC - contém endereço da próxima instrução a ser buscada/executada) é salvo em local conhecido, isto é, uma área da memória ou registrador específica(o) em que o SO ou firmware saiba exatamente onde recuperá-lo e retomar a execução após o tratamento da interrupção. As instruções anteriores a do PC foram todas concluídas, e as posteriores nenhuma, e o estado da instrução apontada pelo PC é conhecido. Vantagens: Simplicidade de código no sistema operacional já que o estado da máquina está bem definido. Desvantagens: Aumenta a complexidade do design do chip e da área do chip, o que pode resultar em CPU mais lenta. Interrupções Imprecisas - Pode ocorrer instruções em diferentes estágios de conclusão, sem uma consecutividade, e é necessário salvar uma grande quantidade de estado interno na pilha para permitir ao sistema operacional entender o que está acontecendo. Geralmente causada por erros fatais. Desvantagens: os criadores de SO precisam descobrir quais instruções foram parcialmente executadas e até que ponto. Problemas com Interrupções em Pipelines e Superescalares - Em Pipelines Profundos: Interrupções podem ocorrer com instruções em vários estágios, tornando difícil determinar o estado exato. Superescalares: Instruções podem ser executadas fora de ordem, complicando ainda mais a determinação precisa do estado. Aula 19 – Entrada/Saída PT. 2 Príncipios do Software de E/S - Independência do Dispositivo, programas acessem qualquer dispositivo de E/S sem precisar serem modificados para cada dispositivo específico. Nomeação Uniforme, nome do dispositivo deve ser uma cadeia de caracteres. Tratamento de Erros, aonde os erros devem ser tratados o mais próximo possível do hardware. Utilização de Buffer, essencial quando os dados de um dispositivo não podem ser armazenados diretamente em seu destino final. Dispositivos Compartilhados são aqueles que podem ser compartilhados por vários usuários simultaneamente, como discos. Os dedicados são os que precisam ser dedicados a um único usuário até que a operação seja concluída, como impressoras. E/S Programada - Abordagem simples aonde a CPU realiza todas as operações de E/S e gerencia todas as etapas da mesma. O software do usuário monta a cadeia de caracteres em um buffer no espaço do usuário, o processo do usuário faz solicitação de escrita para a impressora, então o SO verifica se a impressora está disponível (busy-waiting), se sim, o sistema operacional copia o buffer para um vetor no espaço do núcleo para facilitar o acesso. Se não estiver, ele aguarda até que esteja. A CPU verifica a disponibilidade do dispositivo cada vez que um caractere é impresso. Isso é conhecido como "espera ocupada" (busy waiting) ou polling. . E/S Orientada a Interrupções - Abordagem aonde é utilizada interrupções para permitir que a CPU execute outras tarefas enquanto aguarda a conclusão da operação de E/S, o que não ocorre na E/S Programada. Quando a chamada de sistema para imprimir é feita, o buffer é copiado para o espaço do núcleo, e o primeiro caractere é enviado para a impressora quando ela está pronta, após o envio do caractere, é gerada uma interrupção que para o processo em execução, salvando seu estado, e executando a rotina de tratamento de interrupção da impressora, então, a CPU chama o escalonador, permitindo a execução de outros processos enquanto aguarda. Após isto, o processo original é retomado a partir do ponto onde foi interrompido. A E/S orientada a interrupções a CPU é notificada a cada transferência de dado entre o dispositivo de E/S e a memória, resultando em um grande número de interrupções, aumentando a carga na CPU. E/S usando DMA - Abordagem aonde há o uso do controlador do DMA, realize a transferência de dados para o dispositivo de E/S sem envolver a CPU principal, assumindo a função de E/S programada. Possui uma vantagem em relação a E/S de interrupções, pois reduz o número de interrupções, especialmente com grande volume de dados, em vez de uma interrupção por caractere, há apenas uma por buffer impresso. Se o controlador de DMA não atinge a velocidade máxima do dispositivo ou se a CPU não tem tarefas para realizar enquanto espera pela interrupção do DMA, a E/S orientada a interrupções ou programada pode ser mais eficiente. Camadas de Software de E/S – Há quatro camadas. Tratadores de Interrupção: Tem o objetivo de esconder as interrupções do sistema operacional, minimizando o conhecimento necessário sobre elas, pois estas são consideradas eventos indesejados na perspectiva da E/S programada. Sua lógica consiste em: Bloqueio do Driver que iniciou a operação E/S até que a operação finalize -> Interrupção ocorre e a rotina de tratamento de interrupção é executada -> Pode havear o desbloqueio do driver chamador, por meio de um up de semáforo ou ações específicas -> Série de passos como salvar registros, estabelecer pilha pra rotina de tratamento de interrupção, escolher qual processo executar em seguida por meio do contexto do MMU, carregar registros do novo processo são feitos. Requer um número considerável de instruções da CPU, depende fortemente da arquitetura e com o uso da memória virtual, a gestão da TLB e da cache da CPU pode ser necessária ao alternar entre modos núcleo e usuário. Drivers de Dispositivos: É o código específico do dispositivo E/S, geralmente fornecido pelo fabricante. Para acessar o hardware, os drivers normalmente fazem parte do núcleo do sistema operacional. Tem as funções de Aceitar solicitações abstratas de leitura/escrita e garantir sua execução, inicializar o dispositivo caso for preciso, gerenciar necessidades de energia, registrar eventos, verificar parâmetros de entrada, traduzir termos abstratos (gerais) para concretos (específicos do driver), conferir se um dispositivo está em uso, emitir comandos para o dispositivo, tratar interrupções e verificar ocorrência de erros. Drivers não fazem chamadas, mas interagem com o núcleo por meio de rotinas permitidas. Cada sistema operacional precisa de seus próprios drivers. Não é necessário reiniciar o USB toda vez que se adiciona um ao computador, pois o plug and play permite que o SO identifique e configure automaticamente hardware recém-conectado, e o USB suporta detecção dinâmica de dispositivos. Vantagens de Drivers no Espaço do Usuário - Ao executar drivers de dispositivo no espaço do usuário, eles são isolados do núcleo do sistema operacional. Isso significa que, se um driver tiver bugs ou falhas, esses problemas geralmente não afetarão diretamente o núcleo do sistema operacional. Além disso, esse isolamento ajuda a mitigar possíveis riscos de segurança associados a bugs ou explorações nos drivers, uma vez que seu impacto seria limitado ao espaço do usuário. Desenvolver e depurar drivers no espaço do usuário pode ser mais fácil, pois não requer privilégios de acesso ao núcleo do sistema operacional. Software do SO independente do dispositivo: Tem as funções de criar uma interface uniforme para os drivers, utilização de buffer, reportar erros aonde existem os erros de programação como fornecimento de parâmetros inválidos, ler de um dispositivo de saída, relatando o código de erro ao chamador, e os de E/S reais, que envolvem o funcionamento físico do dispositivo, como bloco de disco danificado, se for crítico, podem levar o sistema a exibir uma mensagem de erro e desligar, quando não houver outra opção. Se o driver não souber lidar, pode passar pro software. Alocação e Liberação de Dispositivos Dedicados: Alguns dispositivos só podem ser usados uma vez por processo, então o SO deve gerenciar isso, por meio das chamadas de sistema'open', aonde os processos executam-na diretamente nos arquivos especiais para os dispositivos, se este não estiver disponível, a chamada open falha, ou por meio de fila, aonde quando um processo chamador tenta adquirir um dispositivo indisponível, é bloqueado e colocado num a fila, quando o dispositivo está disponível, o primeiro na file adquire-o e continua. Tamanho de Bloco Independente de Dispositivo: O software deve apresentar um tamanho de bloco uniforme para as camadas superiores, tratando vários setores do disco como um único bloco lógico, ocultando também as diferenças entre as saídas dos tipos de dispositivos (de bloco e caractere). Aula 20 – Entrada/Saída – Discos RAID (Redundant Array of Inexpensive Disks) - Tecnologia para melhorar o desempenho e a confiabilidade dos discos, substituindo a abordagem de um único disco grande e caro. Ele nvolve instalar uma caixa cheia de discos (conjunto RAID) junto ao computador, e substitui a placa controladora de disco por um controlador RAID. Os dados são copiados para o RAID, que deve parecer como um único disco para o sistema operacional. Nivel 0 - Usa striping, isto é, dados são divididos em faixas e distribuídos alternadamente nos discos, sem redundância (se um disco falhar, pode haver perda de dados) e com baixa confiabilidade, é útil para grandes solicitações mas há a desvantagem para pequenas atualizações, pois requer a leitura e escrita de todas as faixas. Nivel 1 - Duplica todos os discos, escrevendo os dados nas faixas duas vezes, em dois discos diferentes, sendo um deles considerado espelho do outro, podendo haver a distribuição das leituras, melhorando o desempenho de leitura, e havendo redundância, pois se um disco falhar, os dados podem ser recuperados do disco espelhado. Nivel 2 - Fragmenta o conjunto de dados em unidades menores (palavras), e a distribui entre os discos, com cada disco responsável por uma posição específica na palavra bit a bit. Oferece alta taxa de transferência, mas exige sincronização dos discos e capacidade de correção de erros. Suporta a perda de um disco. Seu propósito é lidar não apenas com falhas de unidades (como o RAID nível 3), mas também com erros transitórios não detectados (erro que ocorre temporariamente e pode não ser detectado imediatamente). Se uma unidade no conjunto RAID nível 2 fornecer um único bit incorreto, o RAID nível 2 é capaz de corrigir esse erro. Nivel 3 - Há o cálculo do bit de paridade, que é um método simples para verificação de erro e que permite a reconstrução dos discos. Ela é calculada e armazenada em um disco dedicado, geralmente chamado de disco de paridade. Um bit de dados (1 ou 0) é adicionado ao final de cada bloco de dados, criando bits pares ou ímpares, então há o uso da operação lógica XOR (OU exclusivo). Ex: Se os bits de dados são 0,0,0,1 o bit de paridade é XOR (0,0,0,1) = 1. Se houver um erro em um único bit de dados em um dos discos do conjunto, o RAID nível 3 pode corrigir esse erro usando as informações armazenadas no disco de paridade. Se ocorrerem erros em mais de um bit dentro do mesmo bloco ou se houver erros em diferentes blocos simultaneamente, o RAID nível 3 pode não ser capaz de corrigir esses erros, uma vez que a paridade é usada para proteger apenas contra falhas em bits individuais referentes a paridade dentro de blocos específicos. Nivel 4 - É o mesmo que o RAID Nivel 0, mas agora há a implementação da paridade faixa- por-faixa, e não por palavra como no Nivel 3. Possui bom desempenho de leitura, mas pode ter gargalo para pequenas atualizações, pois a cada operação de modificação de um setor de dados, a atualização da paridade requer a leitura da antiga paridade, a leitura dos dados antigos e a escrita dos novos dados, requerendo operações de leitura e gravação adicionais no disco de paridade. Nivel 5 - Distribui bits de paridade uniformemente em todos os discos, elimina o gargalo do RAID Nível 4 para escritas, pois pequenas modificações não se concentram em um único disco, pois a paridade está distribuída em todos os discos. Isso permite que várias pequenas atualizações ocorram simultaneamente em discos diferentes. Nivel 6 - Adiciona mais um bloco de paridade uniformemente por disco. É um pouco mais caro em termos de escritas, mas sem penalidade de desempenho para leituras. Algoritmos de Escalonamento de Braço de Disco – Para o cálculo do tempo para cada algoritmo, se calcula a soma da distância (diferença) entre as solicitações, e depois há a multiplicação do resultado da soma pelo tempo de busca/posicionamento. A forma como é feita a soma é que muda e é determinada pelos princípios de cada algoritmo: First-Come, First-Served, Primeiro a Chegar Primeiro a Ser Servido (FCFS) - Usado caso o o driver do disco atender solicitações uma de cada vez, aonde a soma é feita com as distâncias (diferença) entre as solicitações subjacentes. Shortest Seek First (SSF) - Atende à solicitação mais próxima em seguida para minimizar o tempo de busca, a soma é realizada com as distâncias (diferenças) mais próximas do cilindro atual em sequência, sendo a primeira distância da soma entre o cilindro atual e o mais próximo. Elevator Algorithm - Mantém uma direção de movimento em uma determinada direção até que não haja mais solicitações nessa direção, momento em que o elevador inverte-a. A soma é feita com as distâncias (diferenças) entre os cilindros de valores mais altos, caso a direção seja inicialmente para cima, e mais baixos, caso ela seja inicialmente para baixo, o primeiro valor da soma é a distância do valor mais próximo do cilindro atual, a partir daí, vai para os valores mais altos. A sua versão modificada é chamada de C-SCAN, vai de uma extremidade, atendendo todas as suas requisições, para a outra, na mesma direção, para ver quais valores estão a extremidade esquerda ou direita, é necessário reordená-los. Ele vai do valor que o cilindro está para a direita, depois para a esquerda, começa do 0, e vai para os valores restantes. Esta versão é melhor que a original, pois possui maior previsibilidade e consistência nos tempos de resposta em comparação com o Elevador Original, pois sempre varre as solicitações na mesma direção, sem inverter a direção quando atende a última requisição na extremidade mais alta ou mais baixa, isso minimiza flutuações nos tempos de resposta, aumentando a velocidade. Além disso, uma solicitação de leitura/gravação não é atendida por quase duas varreduras completas de disco no algoritmo elevador, pois ele inverte a ordem quando atinge uma extremidade mais alta ou baixa, enquanto é no máximo uma varredura completa de disco no algoritmo modificado pois ele sempre as varre na mesma direção. Tratamento de Erros - Uma lista de setores defeituosos é escrita no disco, então os substitutos são alocados. A lista é gerada por testes prévios no controlador do disco. A substituição pode envolver remapeamento ou deslocamento dos setores, com a escolha dependendo das características específicas. O ECC (Código de Correção de Erros) pode corrigir alguns erros. Em casos excepcionais, reiniciar o controlador pode ser necessário para corrigir problemas persistentes. Em sistemas de tempo real, recalibrações podem causar interrupções no fluxo de bits, sendo inadequadas para aplicações como reprodução de vídeo ou gravação em tempo real. Armazenamento Estável - Método para garantir que os dados em um disco permaneçam consistentes mesmo em face de erros, falhas de hardware ou quedas de sistema, mesmo durante um procedimento de recuperação. É um subsistema de disco que, ao receber uma operação de escrita, garante que os dados sejam gravados corretamente ou que permaneçam inalterados. Um modelo é estabelecido para lidar com erros possíveis, considerando a detecção de erros por campos ECC. Algumas técnicas de armazenamentos estáveis utilizam técnicas de correçãode erros (ECC - Error-Correcting Code) para lidar com falhas nos dados armazenados. Se o ECC não reflete a corrupção real nos dados, pode haver confusão sobre a validade dos dados nos discos, pois se o ECC do bloco corrompido estiver incorreto, é possível detectar a corrupção e tentar recuperar os dados de uma maneira apropriada. No entanto, se o ECC estiver correto (mesmo que os dados estejam corrompidos), pode ser difícil determinar qual disco contém o bloco válido (seja o antigo ou o novo). Nesse caso, a recuperação torna-se problemática, pois não é possível discernir qual versão dos dados é a correta. Escritas Estáveis: Consiste em escrever um bloco na unidade, lê-lo de volta para verificação, repetindo até ser bem-sucedido. Em caso de falha consecutiva, o bloco é remapeado para um bloco reserva. O processo é repetido para outra unidade. Leituras Estáveis: Lê um bloco da unidade, tentando novamente se o ECC estiver incorreto. Se todas as tentativas falharem, lê o bloco correspondente da próxima unidade. Recuperação de Falhas: Após uma queda do sistema, um programa de recuperação compara blocos correspondentes em ambos os discos. Corrige blocos defeituosos e restaura estados antigos se necessário. O método utiliza dois discos idênticos, com blocos correspondentes em ambos trabalhando juntos para formar um bloco livre de erros. Aula 21 – Entrada/Saída – Relógios O tempo é geralmente representado pelo número de tiques de relógio desde uma data de referência, como 1º de janeiro de 1970 (UTC) para sistemas como o UNIX, ou 1º de janeiro de 1980 para o Windows. 2 Tipos de Relógio -> Um é ligado a rede elétrica e causa interrupção a cada ciclo de voltagem. O outro é composto por um oscilador de cristal, que gera um sinal periódico que é uma forma de onda elétrica que oscila de maneira regular e previsível, um contador e um registrador de apoio. Relógios Programáveis - Sua frequência de interrupção pode ser controlada pelo software, possuindo modos de operação, como disparo único e onda quadrada. O modo disparo único copia o valor do registrador de apoio no contador e decrementa o contador em cada pulso do cristal (sinal gerado pelo oscilador de cristal) até atingir zero. O modo onda quadrada automaticamente copia o registrador de apoio para o contador após atingir zero, repetindo o processo indefinidamente. Funções do Driver do Relógio - Manutenção no Horário do Dia: por incrementação no contador a cada tique de relógio. Evitar Execução Prolongada de Processos: inicializar o contador com o valor de quantum do processo e decrementá-lo a cada interrupção para que o escalonador execute outro. Contabilização do Uso da CPU: Um segundo temporizador é iniciado quando um processo começa e é lido quando ele é interrompido ou manter um ponteiro para a entrada do processo e incrementar um campo dele a cada tique de relógio. Gerar Avisos: O driver pode simular relógios que podem ser usados para gerar avisos após intervalo específico. Execução: SOs oferecem capacidade de obter um histograma do contador do programa para análise de desempenho. Então driver verifica se a execução está sendo obtida a cada tique, e caso precisa, atualiza o intervalo do contador. Interrupções vs. Polling – Interrupções: Quando um dispositivo requer atenção (por exemplo, tecla pressionada), ele envia uma interrupção, interrompendo imediatamente a execução normal do processador. Tem baixa latência, mas têm uma sobrecarga considerável, sendo ideal para situações em que a resposta de baixa latência é crucial. Polling: são verificações ativas, aonde o sistema periodicamente verifica ativamente se um dispositivo de E/S requer atenção. Elimina a sobrecarga das interrupções, mas o polling pode introduzir latência substancial por conta da checagem periódica, e pois caso um evento ocorra imediatamente após uma verificação, o sistema pode demorar quase um ciclo inteiro de verificação para responder. É preferível em situações onde a latência não é crítica, e a sobrecarga das interrupções é indesejada, ou quando eventos E/S são menos frequentes. Temporizadores por Software (Soft Timers) - Segundo relógio programável que pode ser ajustado para provocar interrupções no temporizador a qualquer frequência desejada por um programa específico. Se a frequência do temporizador específico da aplicação for muito alta, pode haver problemas, e a latência e sobrecarga associadas às interrupções convencionais podem se tornar significativas. Sempre que o núcleo está prestes a retornar ao modo do usuário, verifica se um temporizador por software expirou. Se sim, o evento associado é realizado sem a necessidade de chavear para o modo núcleo. Após o evento, o temporizador por software é reinicializado copiando o valor do relógio atual e adicionando o intervalo de tempo. Os temporizadores funcionam de maneira semelhante ao polling.