# Exercícios MT2

Questões de exames antigos de Laboratório de Computadores, com resolução.

Página: https://resumos.rgo.pt/cadeiras/lc/exercicios-mt2/

## Teclado e KBC

Significado de um break code

Teste de Recurso, 2024/25

No protocolo do teclado PS/2, o que representa um _break code_?

Solução

Um _break code_ representa a libertação de uma tecla.

Cada tecla gera um make code ao ser pressionada e um break code ao ser libertada. No protocolo PS/2, o break code obtém-se juntando o prefixo 0xF0 ao make code da tecla.

*   **A libertação de uma tecla..** O break code sinaliza que a tecla foi libertada, não pressionada.
*   **O código de uma tecla pressionada..** Esse é o make code, não o break code.
*   **O início de um novo scan code..** O break code termina a tecla, não inicia outra.
*   **Um erro de paridade..** O break code é um código válido, não um erro.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/teclado/#make-break-e-prefixos)

Objetivo de verificar o bit KBC\_OBF

Teste de Recurso, 2024/25

Ao ler dados devolvidos pelo KBC, qual é o objetivo principal de verificar o bit KBC\_OBF no registo de estado?

Solução

Verificar se o buffer de saída (OBF) contém dados para serem lidos.

O bit KBC\_OBF (Output Buffer Full) fica a 1 quando o KBC colocou um byte no buffer de saída, na porta 0x60. Só nesse caso a leitura tem dados válidos.

*   **Reiniciar o sinalizador OBF do registo de estado..** A leitura do buffer de saída limpa o OBF; não é esse o objetivo da verificação.
*   **Verificar se o buffer de saída contém dados para serem lidos..** OBF (Output Buffer Full) a 1 indica que há um byte pronto na porta 0x60.
*   **Reiniciar a porta KBC\_OUT\_BUF..** A porta não se reinicia; o bit apenas reflete o estado do buffer.
*   **Determinar se o buffer de entrada está pronto para aceitar novos dados..** Esse é o papel do bit IBF, não do OBF.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/teclado/#estado-do-i8042)

Bit KBC\_ST\_IBF antes de enviar um byte ao KBC

Teste 2, 2024/25

Antes de enviar um byte ao KBC, qual é o motivo principal de verificar o bit KBC\_ST\_IBF do registo de estado?

Solução

Confirmar que o buffer de entrada não está cheio (IBF a 0) antes de escrever na porta 0x60.

Se o bit IBF estiver a 1, o KBC ainda não consumiu o byte anterior e um novo byte escrito seria perdido. Por isso se espera que IBF fique a 0 antes de enviar.

*   **Garantir que o buffer de saída está pronto para dados..** O buffer de saída serve para ler dados do KBC, não para enviar.
*   **Verificar que o buffer de entrada não está cheio e o KBC pode receber um novo byte..** IBF (Input Buffer Full) a 1 significa que o KBC ainda não processou o byte anterior.
*   **Verificar se o buffer de entrada contém dados para ler..** Quem verifica se há dados para ler é o bit OBF.
*   **Repor o bit IBF antes de escrever dados..** O bit IBF é controlado pelo KBC, não pela escrita.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/teclado/#estado-do-i8042)

## Rato

Tamanho do pacote padrão do rato PS/2

Teste 2, 2024/25

Quantos bytes tem o pacote padrão de um rato PS/2?

Solução

O pacote padrão tem 3 bytes.

O primeiro byte traz os botões e os bits de sinal e overflow; os dois seguintes registam os deslocamentos X e Y em complemento para dois com 9 bits.

*   **Depende do rato..** O protocolo padrão do laboratório usa sempre 3 bytes.
*   **2..** Ficaria sem deslocamentos.
*   **3..** Botões + deslocamentos X e Y.
*   **4..** O quarto byte só surge com roda.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/rato/#anatomia-do-pacote)

Linha de IRQ do controlador do rato

Teste 2, 2024/25

Que linha de IRQ eleva o controlador do rato?

Solução

A linha de IRQ do rato é a 12.

O teclado usa a IRQ 1 e o rato a IRQ 12. A subscrição no Minix indica a linha (hook\_id) e o kernel devolve a máscara de notificação correspondente no payload.

*   **12..** O rato usa a IRQ 12.
*   **2..** A IRQ 2 é a cascata dos PICs.
*   **1..** A IRQ 1 é o teclado.
*   **15..** A IRQ 15 é o disco secundário.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/interrupcoes/#irq-vetor-e-rotina)

Valores de ACK e NACK do rato

Teste 2, 2024/25

Quando enviamos um comando ao controlador do rato, este devolve códigos de sucesso e de falha. Quais são os valores de ACK e de NACK?

Solução

ACK = 0xFA e NACK = 0xFE.

Após um comando bem-sucedido o rato responde 0xFA (ACK); se falhar, responde 0xFE (NACK), caso em que o driver deve reenviar o byte ou o comando.

*   **ACK = 0xEF; NACK = 0xFE..** Valores trocados.
*   **ACK = 0xFE; NACK = 0xFA..** ACK e NACK invertidos.
*   **ACK = 0xFA; NACK = 0xFE..** ACK é 0xFA e NACK é 0xFE.
*   **ACK = 0xFA; NACK = 0xEF..** O NACK é 0xFE.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/rato/#enviar-um-comando)

Bit de sincronização do pacote do rato

Teste de Recurso, 2024/25

Que bit é utilizado para sincronizar os pacotes do rato?

Solução

O bit 3 do primeiro byte, que deve estar sempre a 1.

Como o driver pode subscrever interrupções a meio de um pacote, o bit 3 do primeiro byte (sempre 1) permite detetar o início de um novo pacote e descartar bytes inválidos.

*   **Bit 0 do primeiro byte = 1..** O bit 0 é o botão esquerdo.
*   **Bit 3 do primeiro byte = 1..** O bit 3 do primeiro byte está sempre a 1 e marca o início do pacote.
*   **Bit 7 do segundo byte = 1..** O bit 7 é o sinal do deslocamento Y.
*   **Bit 5 do terceiro byte = 0..** O bit 5 é o botão do meio.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/rato/#montagem-e-sincroniza%C3%A7%C3%A3o)

## Vídeo

Escrever um píxel RGB em modo VBE 0x115

Teste 2, 2024/25

Queremos definir um píxel com uma cor RGB, usando o modo VBE 0x115, na posição $(x,y)$. Como deve proceder o _device driver_?

Solução

Fazer `memcpy` dos 3 bytes da cor para o endereço base da VRAM mais $x \cdot 3 + y \cdot \text{BytesPerScanLine}$.

No modo 0x115 há 3 bytes por píxel (24 bits de cor direta). Num frame buffer linear, o píxel $(x,y)$ começa no byte $x \cdot 3 + y \cdot \text{BytesPerScanLine}$.

*   **Copiar os 3 bytes, um de cada vez, para a memória gráfica mapeada com um offset de $x + y \cdot \text{BytesPerColumn}$..** Esse offset baralha píxeis e bytes por píxel.
*   **Copiar os 3 bytes, um de cada vez, para a memória gráfica mapeada com um offset de $x \cdot 3 + y \cdot \text{BytesPerScanLine}$..** Copiar byte a byte não é eficiente; usa-se memcpy.
*   **Fazer memcpy dos 3 bytes para a memória gráfica mapeada com um offset de $x \cdot 3 + y \cdot \text{BytesPerScanLine}$..** Offset = $x \cdot 3 + y \cdot \text{BytesPerScanLine}$, com memcpy dos 3 bytes.
*   **Fazer memcpy dos 3 bytes para a memória gráfica mapeada com um offset de $x + y \cdot \text{BytesPerColumn}$..** Falta multiplicar $x$ pelos bytes por píxel.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/video/#calcular-o-endere%C3%A7o-de-um-p%C3%ADxel)

Modo gráfico predefinido do Minix no Lab 5

Teste 2, 2024/25

Qual é o modo gráfico predefinido da versão de Minix usada no Lab 5?

Solução

O modo predefinido é o 0x115.

O modo 0x115 é direct color com 1024x768 e 24 bits por píxel (8:8:8), o modo que as funções de vídeo do LCF assumem por omissão nos laboratórios.

*   **0x115..** Resolução 1024x768, 24 bits de cor.
*   **0x03..** É o modo de texto.
*   **0x030..** Não é um modo VBE.standard.
*   **0x105..** É modo indexado de 8 bits.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/video/#modo-e-informa%C3%A7%C3%A3o-vbe)

Para que serve o double buffering

Teste 2, 2024/25

Em programação gráfica, para que serve o _double buffering_?

Solução

Utilizar dois buffers para evitar flickering/tearing, desenhando numa imagem oculta antes de a apresentar no ecrã.

Se se desenhasse diretamente na VRAM visível, o utilizador veria o desenho a meio. Com double buffering, desenha-se no buffer secundário e copia-se para o visível (ou troca-se) durante o vertical retrace.

*   **Eliminar artefactos visuais..** Desenha-se numa imagem oculta e só depois se apresenta, evitando flickering e tearing.
*   **Evitar cores trocadas..** Não é esse o objetivo.
*   **Poupar tempo de processamento..** Usa mais memória, não poupa tempo.
*   **Guardar cópias das imagens..** O segundo buffer não é uma cópia de segurança.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/video/#double-buffering-e-tearing)

Memória ocupada por um frame aRGB

Teste 2, 2024/25

Quanto memória ocupa um frame de $100 \times 100$ píxeis, com componentes de cor aRGB (8:8:8:8)?

Solução

$100 \cdot 100 \cdot 4 = 40\,000$ bytes (40 kB).

O formato (8:)8:8:8 usa 32 bits por píxel, ou seja, 4 bytes. Um frame de $100 \times 100$ píxeis ocupa, portanto, $10\,000 \times 4 = 40\,000$ bytes.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/video/#mapear-mem%C3%B3ria-f%C3%ADsica)

Significado de cada caráter no XPM

Teste 2, 2024/25

No formato XPM usado no Lab 5, o que representa cada caráter do mapa da imagem?

Solução

Cada caráter representa um índice da tabela de cores.

Num XPM, as primeiras strings definem a correspondência caráter → cor (por exemplo `"s"` para uma cor, `"c"` para outra) e as strings seguintes usam esses caracteres para desenhar a imagem píxel a píxel.

*   **A velocidade de um sprite..** O XPM não guarda velocidades.
*   **Um índice de cor..** Cada caráter aponta para uma entrada da tabela de cores.
*   **Um endereço de memória..** O XPM é um formato de alto nível, independente de endereços.
*   **A posição de um píxel..** A posição é dada pela posição do caráter na string.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/video/#xpm-e-sprites)

## Interrupções e Minix

Significado da flag IRQ\_REENABLE

Teste de Recurso, 2024/25

No contexto da subscrição de notificações de interrupção no Minix, qual é o significado da flag IRQ\_REENABLE?

Solução

Permite ao kernel desmascarar (reenable) automaticamente a linha de IRQ associada ao hook\_id usado na subscrição.

Em `sys_irqsetpolicy(irq_line, IRQ_REENABLE, &hook_id)`, a flag IRQ\_REENABLE instrui o kernel a desmascarar a linha de IRQ no PIC, para que as interrupções desse dispositivo cheguem ao processador.

*   **Permite remover a subscrição mais tarde..** A remoção faz-se com outra chamada, não com esta flag.
*   **Permite ao Device Driver incluído no Minix tratar a IRQ quando a subscrição é removida..** A flag atua durante a subscrição, não depois dela.
*   **Eleva a prioridade do handler de interrupção..** A flag não altera prioridades.
*   **Permite ao kernel desmascarar automaticamente interrupções na linha de IRQ associada ao hook\_id indicado..** IRQ\_REENABLE faz o kernel reativar a linha de IRQ no PIC.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/interrupcoes/#hook-e-m%C3%A1scara-de-notifica%C3%A7%C3%A3o)

Comportamento de driver\_receive no Minix

Teste de Recurso, 2024/25

Qual é o comportamento da chamada ao sistema `driver_receive` no Minix?

Solução

Bloqueia até receber uma mensagem (por exemplo, uma notificação de interrupção), permitindo ao kernel trocar de contexto enquanto isso.

O ciclo de eventos dos drivers em Minix usa `driver_receive(ANY, &msg, &status)`: a chamada bloqueia o processo até o kernel entregar uma mensagem, seja uma notificação de IRQ (HARDWARE) ou um pedido de outro processo.

*   **Bloqueia até receber uma mensagem de pedido de serviço, permitindo trocas de contexto..** O processo fica bloqueado até chegar uma notificação ou mensagem.
*   **Devolve um erro se não houver notificações pendentes..** Nesse caso, bloqueia em vez de falhar.
*   **Faz polling ao PIC para obter interrupções de periféricos..** driver\_receive não faz polling; recebe mensagens do kernel.
*   **Bloqueia até receber uma interrupção de software..** Recebe notificações de interrupções de hardware, não de software.

Polling vs interrupções em chamadas ao kernel

Teste de Recurso, 2024/25

Para ler scancodes do teclado, pode escolher-se polling ou interrupções. Qual das duas abordagens espera que faça mais chamadas `sys_inb()` ao kernel?

Solução

O polling faz muito mais chamadas `sys_inb()`.

Em polling, o programa lê o registo de estado do KBC repetidamente até o bit OBF indicar dados, gastando uma chamada ao kernel por verificação. Com interrupções, só se acede ao KBC quando há realmente um byte novo, pelo que o número de chamadas é muito menor.

*   **Fazem sempre o mesmo número de chamadas..** O número de chamadas difere muito.
*   **O número de chamadas é aleatório..** Polling verifica em ciclo, de forma previsível.
*   **Polling..** Em polling lê-se o registo de estado em ciclo, gastando muitas chamadas.
*   **Interrupções..** Com interrupções só se lê quando há dados.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/falar-com-hardware/#polling-e-timeout)

## Eventos

Função de uma fila de eventos

Teste 2, 2024/25

Num design orientado a eventos, qual é o objetivo de uma fila de eventos (_event queue_)?

Solução

Fornecer buffering: os eventos aguardam na fila e o seu tratamento pode ocorrer assincronamente, em ordem FIFO.

Quando chegam várias interrupções seguidas, o handler não pode tratá-las todas de imediato. A fila de eventos guarda os pedidos por ordem de chegada e o ciclo principal vai despachando cada um para o handler respetivo.

*   **Registar todos os eventos passados e os handlers correspondentes..** A fila não é um registo histórico.
*   **Mapear tipos de eventos em handlers..** Esse mapeamento é feito por outra estrutura.
*   **Agendar os eventos por ordem first in, first out..** A fila garante ordem FIFO, mas o objetivo é o buffering.
*   **Fornecer buffering para que o tratamento de um evento possa ocorrer assincronamente em relação à sua ocorrência..** Os eventos acumulam-se na fila e são tratados depois, em ordem.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/projeto/#filas-ordem-e-ritmo)

Vantagem do design orientado a eventos num driver

Teste de Recurso, 2024/25

Qual é a principal vantagem de usar um design orientado a eventos na programação de device drivers em Minix?

Solução

Reagir eficientemente a eventos assíncronos, sem polling contínuo, melhorando o desempenho e o consumo de CPU.

Em vez de verificar dispositivos em ciclo (polling), o driver bloqueia em `driver_receive` e só acorda quando o kernel lhe entrega uma notificação. O CPU fica livre para outros processos entre eventos.

*   **Reduz a necessidade de interrupções..** As interrupções continuam a ser necessárias.
*   **Permite reagir eficientemente a eventos assíncronos, melhorando o desempenho e o consumo de CPU..** O processo bloqueia em vez de fazer polling contínuo.
*   **Garante que todos os dispositivos são tratados por ordem de chegada..** A ordem não é a vantagem principal.
*   **Permite usar polling de forma mais intensiva..** O objetivo é justement evitar polling intensivo.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/projeto/#programa%C3%A7%C3%A3o-por-eventos)

## Memória e tipos em C

Tamanho de uma union em C

Teste de Recurso, 2024/25

Considera uma `union` com um campo `char[10]`, um campo `int` e um campo `short`, numa arquitetura de 32 bits. Qual é o tamanho em memória de uma variável deste tipo?

Solução

12 bytes.

Numa union, todos os membros começam no mesmo endereço e o tamanho total é o do maior membro, arredondado ao alinhamento. Em 32 bits, `char[10]` ocupa 10 bytes mas o alinhamento de 4 bytes obriga a arredondar para 12.

*   **10 bytes..** O tamanho tem de respecter o alinhamento da arquitetura.
*   **12 bytes..** O maior membro (char\[10\]) arredonda a 12 por alinhamento a 4 bytes.
*   **4 bytes..** Seria o tamanho se só houvesse o int.
*   **8 bytes..** Nenhum membro chega a 8 bytes.

[Voltar à explicação](https://resumos.rgo.pt/cadeiras/lc/memoria-funcoes/#calcular-o-tamanho-com-alinhamento)
