动态模块编译
ctags 用法
- 创建文件 ------- ctags -R
一定要在顶层目录下1. ctags –R *
2. vi –t tag (请把tag替换为您欲查找的变量或函数名)
3. Ctrl + ] (跳转到要找的目标)
4. Ctrl + T (回跳)5. set tag=/path/tags(vi 底行模式下设置目标tags)
动态加载模块 ---- 每次不用再 make uImage 进入minicom 也不需要tftp 0x30008000 uImage
著需要修改完后 make demo.ko 再cp
- make menvconfig 对应模块设置为 M
- make modules 编译动态加载的驱动模块(与对应的.c 文件在同一目录下)
- insmod demoy.ko 动态加载驱动模块
lsmod 查看已经动态加载的驱动模块
- 运行模块
GPL:许可证
修改:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/module.h>
#define MAJOR_NUM 255
#define MINOR_NUM 0
#define DEV_NAME "demo"
#define DEV_NUM 1
static int open (struct inode * inode, struct file * file)
{
printk("demoy open ...\n");
return 0;
}
static ssize_t read (struct file * file, char __user * buf, size_t len, loff_t * offset)
{
printk("demoy read ...\n");
return 0;
}
static ssize_t write (struct file * file, const char __user * buf, size_t len, loff_t * offset)
{
printk("demoy write ...\n");
return 0;
}
static int close (struct inode * inode, struct file * file)
{
printk("demoy close ...\n");
return 0;
}
static struct file_operations fops =
{
.owner = THIS_MODULE,
.open = open,
.read = read,
.write = write,
.release = close
};
static struct cdev cdev;
static dev_t dev;
static int __init demo_init(void)
{
int ret =0;
dev = MKDEV(MAJOR_NUM, MINOR_NUM);
cdev_init(&cdev, &fops);
ret =cdev_add(&cdev, dev, DEV_NUM);
if(ret < 0)
goto err_cdev_add;
ret = register_chrdev_region(dev, DEV_NUM, DEV_NAME);
if(ret <0)
goto err_register_chrdev_region;
printk("demo_init ###############################\n");
return ret;
err_cdev_add:
cdev_del(&cdev);
printk("demoy_cdv add fail");
return ret;
err_register_chrdev_region:
unregister_chrdev_region(dev, DEV_NUM);
printk("demoy_register fail");
return ret;
}
static void __exit demo_exit(void)
{
unregister_chrdev_region(dev, DEV_NUM);
cdev_del(&cdev);
printk("demo_exit ###############################\n");
}
module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");