#!/bin/sh set -ex # Our modules does not the PCI device yet. lspci -k # => 00:04.0 Class 00ff: 1234:11e8 lkmc_pci # Interrupt counts before we generate our interrupts. cat /proc/interrupts # Setup. insmod qemu_edu.ko /mknoddev.sh lkmc_pci # Shows that this module owns the PCI device. lspci -k # => 00:04.0 Class 00ff: 1234:11e8 lkmc_pci # Identifiction: just returns some fixed magic bytes. dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=0 | od -An -t x1 # => 010000ed # Negator. Sanity check that the hardware is getting updated. dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=1 | od -An -t x1 printf '\xF0\xF0\xF0\xF0' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=1 dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=1 | od -An -t x1 # => 0F0F0F0F # Factorial calculator. # Request interrupt when the computation is over. printf '\x80\x00\x00\x00' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=8 # factorial(0xC) = 0x1c8cfc00 printf '\x0C\x00\x00\x00' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=2 # => irq_handler .* # Yes, we should use the interrupt to notify poll, but lazy. sleep 1 dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=2 | od -An -t x1 dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=8 | od -An -t x1 # => 1c8cfc00 # Manual IRQ raising. printf '\x04\x03\x02\x01' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=24 # => irq_handler .* sleep 1 printf '\x08\x07\x06\x05' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=24 # => irq_handler .* sleep 1 # Teardown. rm /dev/lkmc_pci rmmod qemu_edu # Interrupt counts after we generate our interrupts. # Compare with before. cat /proc/interrupts