整个内核

alias armmake="make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-"

# config
armmake menuconfig

# build
armmake UIMAGE_LOADADDR=0x8000 uImage
armmake modules
sudo armmake INSTALL_MOD_PATH=/home/istin/Repos/rootfs/bh-squashfs-root/lib/modules modules_install

模块

KERN_DIR = /opt/local/library/adi-linux-xilinx-2019-r1
obj-m += zynq_sirq_test.o

all:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=`pwd` modules
cp:
	cp *.ko /
.PHONY: clean
clean:
	make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C $(KERN_DIR) M=`pwd` modules clean

用于测试中断的内核模块示例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/irqchip/arm-gic.h>
#include <linux/interrupt.h>
#include <linux/cpu.h>
#include <linux/smp.h>
#include <asm/uaccess.h>

#define IRQTEST_MAX     1
#define IRQTEST_MAJOR   200
#define IRQTEST_DEV     MKDEV(IRQTEST_MAJOR, 0);
#define IRQTEST_NAME    "irqtest"
#define IRQTEST_COUNT   1

static struct cdev *pcdev;
static struct class *test_class;

static dev_t dev_id;
char kbuf[20];

static int irqtest_open(struct inode *inode, struct file *file) {
    return 0;
}

/* Write anything to /dev/irqtest_dev to trigger a interrupt to CPU1 */
static ssize_t irqtest_write(struct file* file, const char __user *ubuf, size_t count, loff_t *ppos) {
    gic_raise_softirq(cpumask_of(1), 5);
    return count;
}

static const struct file_operations iqrtest_fops = {
    .owner = THIS_MODULE,
    .write = irqtest_write,
    .open = irqtest_open,
};

static void ipi_kick_14(void) {
    printk("IPI kick 14 triggered\\n");
}

static void ipi_kick_15(void) {
    printk("IPI kick 15 triggered\\n");
}

static int __init irqtest_init(void) {
    int ret = 0;
    ret = alloc_chrdev_region(&dev_id, 0, IRQTEST_COUNT, IRQTEST_NAME);
    printk(KERN_INFO "irqtest: major = %d, minor = %d.\\n", MAJOR(dev_id), MINOR(dev_id));
    pcdev = cdev_alloc();
    pcdev->owner = THIS_MODULE;
    pcdev->ops = &iqrtest_fops;
    cdev_add(pcdev, dev_id, IRQTEST_COUNT);
    test_class = class_create(THIS_MODULE, "Shaloc_class");
    device_create(test_class, NULL, dev_id, NULL, "irqtest_dev");
    set_ipi_handler(14, ipi_kick_14, "sgi14handler");
    return 0;
}

static void __exit irqtest_exit(void) {
    clear_ipi_handler(14);
    device_destroy(test_class, dev_id);
    class_destroy(test_class);
    cdev_del(pcdev);
    unregister_chrdev_region(dev_id, IRQTEST_COUNT);
}

module_init(irqtest_init);
module_exit(irqtest_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Shaloc");

目前所使用的platform_device模式驱动(最终应该也就是使用这个驱动了)