Miniprojeto de Sistemas Operacionais (Tecnologia em ADS — IFSC Campus São José).
Driver de caractere para Linux que simula um hardware entregando 1 byte. O fluxo
imita um hardware real: uma interrupção (IRQ) dispara o tratamento dividido em
top half (rápido) → tasklet / bottom half (lê o byte de /host/hw_byte.txt),
e um processo de usuário recebe o byte por read() bloqueante. Outro processo dispara
a interrupção via ioctl().
Integrantes: Luis Renato Freitas de Almeida · Nicolas Arthur Raulino Oliveira
Tudo é feito a partir desta pasta, no host:
./iniciar.sh demo # sobe a UML e roda a demonstração completa automaticamente
# ou
./iniciar.sh # sobe a UML pronta; dentro dela rode: sh demo.shO iniciar.sh liga a UML já montando /proc, /sys e o /host — você cai direto em
/host/mod_fakehw. Para sair da UML: poweroff -f.
insmod fakehw.ko # carrega o driver (cria /dev/fakehw)
./leitor 3 & # Processo B: bloqueia esperando o byte
./disparador 1 # Processo A: dispara a interrupção -> leitor recebe
printf 'Z' > /host/hw_byte.txt # troca o "byte do hardware"
./disparador 1 # agora o leitor recebe 'Z'
dmesg | grep fakehw # log: top half -> bottom half -> read
rmmod fakehw # remove o driverO fakehw é um driver de caractere que simula um hardware entregando 1 byte. O fluxo
é o caminho clássico de tratamento de interrupção do Linux, dividido em duas metades:
disparador --ioctl(FAKEHW_FIRE)--> driver levanta a IRQ
|
[TOP HALF] (rápido, IRQ desabilitada)
só agenda a tasklet
|
[BOTTOM HALF / tasklet] (faz o trabalho pesado)
lê 1 byte de /host/hw_byte.txt e acorda quem espera
|
leitor --read()--> (bloqueado/dormindo) <-- recebe o byte; driver zera o "registrador"
disparador(processo A) chamaioctl()→ o driver dispara a IRQ viageneric_handle_irq_safe().- top half (
fakehw_top_half) roda na hora, com IRQ desabilitada, então só agenda a tasklet e retorna — tem que ser curto. - tasklet / bottom half (
fakehw_tasklet_fn) roda em seguida, lê 1 byte do arquivo do host, guarda numa variável global e acorda a wait queue. leitor(processo B) estava bloqueado emread(); acorda, recebe o byte, e o driver zera o registrador (simula um hardware que se consome a cada leitura).
Detalhe: o enunciado pede IRQ 5, mas na UML a 5 é do
mconsole(ocupada). O driver tenta a 5 e, se ocupada, cai numa linha livre (ex.: 13). Vejamod_fakehw/RELATORIO.md.
A UML é só um executável (lab_driver_uml/linux-6.6.34/linux) que "boota" usando a imagem
rootfs.ext2 como disco. O desafio é que os mount (inclusive o do /host, que dá acesso
aos arquivos do projeto) precisam rodar dentro da UML. A solução:
reinstalar_setup.shgrava, dentro da imagemrootfs.ext2(usandodebugfs, sem precisar montá-la), dois scripts de boot com o caminho absoluto desta máquina:/auto_setup.sh— monta/proc,/syse o/host, e abre o shell em/host/mod_fakehw;/auto_demo.sh— faz o mesmo e ainda roda a demonstração automática.
iniciar.shliga a UML pedindo que ela use um desses scripts comoinit(o primeiro processo). Assim tudo é montado no boot, sem você digitar nada../iniciar.sh demousa oauto_demo;./iniciar.shusa oauto_setup.preparar.shé o passo único numa máquina nova: descompacta o kernel/rootfs (.gz) e chama oreinstalar_setup.shpara gravar o caminho daquela máquina.
Por que o caminho fica "gravado"? Porque o
/hostaponta para uma pasta absoluta do host. Se você mover o projeto, rode./reinstalar_setup.shde novo para atualizar o caminho. Os scripts usam caminho relativo para oubda=(o disco), então funcionam mesmo em pastas com espaço/acento (ex.: "Área de trabalho").
iniciar.sh # (host) sobe a UML com /host já montado
preparar.sh # (host) 1x em máquina nova: descompacta .gz + grava o setup
reinstalar_setup.sh # (host) regrava o setup na rootfs se você mover a pasta
mod_fakehw/ # cópia de entrega: fonte + docs (RELATORIO, APRESENTACAO, DIAGRAMA)
lab_driver_uml/
mod_fakehw/ # o que aparece em /host/mod_fakehw dentro da UML
fakehw.c / .h # driver (módulo de kernel)
leitor.c # Processo B (consumidor, read bloqueante)
disparador.c # Processo A (gera a interrupção via ioctl)
Makefile, demo.sh
Não versionado (1,6 GB, ver
.gitignore): o kernel-sourcelab_driver_uml/linux-6.6.34/. Não é necessário para rodar (só para recompilar), por isso fica fora do repositório.
Para portabilidade, o repositório já inclui uma versão compactada do necessário para rodar (o GitHub recusa arquivos > 100 MB, então não dá para subi-los crus):
lab_driver_uml/linux.gz— kernel da UML (83 MB → 38 MB)lab_driver_uml/rootfs.ext2.gz— sistema de arquivos (128 MB → 3,6 MB)lab_driver_uml/mod_fakehw/{fakehw.ko,leitor,disparador}— binários já compilados (assim não é preciso o kernel-source de 1,6 GB para rodar)
Passos em uma máquina nova:
git clone <url-do-repo> tarefa-driver
cd tarefa-driver
./preparar.sh # descompacta o kernel/rootfs e grava o setup na rootfs
./iniciar.sh demo # roda a demonstraçãoO
preparar.shprecisa dedebugfs(pacotee2fsprogs) para gravar o setup na rootfs. Sem ele, use olab_driver_uml/run_uml.she monte o/hostna mão (o própriopreparar.shmostra o comando).
mod_fakehw/RELATORIO.md— relatório com fluxo detalhado e resultados.mod_fakehw/APRESENTACAO.md— roteiro de apresentação e perguntas prováveis.mod_fakehw/DIAGRAMA.md— diagramas (sequência, fluxograma, ciclo de vida).mod_fakehw/saida_teste_uml.txt— saída real capturada de um teste completo.