Linux原始驱动模型实现bus,driver,device实验

mydevice.c代码

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include "devinfo.h"

extern struct bus_type mybus;

struct devinfo mydev_info = 
{
	.name = "testfs",
	.interrupt = 2333,
	.addr = 0x40001000,
};


void mydev_release(struct device *dev)
{
	
}


struct device mydev = {
	.bus = &mybus,
	.init_name = "fsdev_drv",
	.platform_data = (void*)&mydev_info,
	.release = mydev_release,
};

static int __init dev_init(void)
{
		int	ret;
		
		printk("-------------%s--------------\n",__FUNCTION__);

		//注册device
		ret = device_register(&mydev);
		
		if(ret != 0)
		{
			printk("device_register Error!\n");
			return ret;
		}
		
		return 0;
}


static void __exit dev_exit(void)
{
		device_unregister(&mydev);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");

mydrv.c代码

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include "devinfo.h"

extern struct bus_type mybus;

struct devinfo* pdev_info;

int mydrv_probe (struct device *dev)
{
	printk("-------------%s--------------\n",__FUNCTION__);

	pdev_info = (struct devinfo*)dev->platform_data;

	printk("name = %s , interrupt = %d , addr = %x \n",pdev_info->name,pdev_info->interrupt,pdev_info->addr);
	
	return 0;
}

int mydrv_remove (struct device *dev)
{
	printk("-------------%s--------------\n",__FUNCTION__);
	
	return 0;
}


struct device_driver mydrv = {
	.name = "fsdev_drv",	
	.bus = &mybus,
	.probe = mydrv_probe,
	.remove = mydrv_remove,
};

static int __init drv_init(void)
{
		int	ret;
		
		printk("-------------%s--------------\n",__FUNCTION__);

		//注册driver到bus
		ret = driver_register(&mydrv);
		
		if(ret != 0)
		{
			printk("device_register Error!\n");
			return ret;
		}
		
		return 0;
}

static void __exit drv_exit(void)
{
		driver_unregister(&mydrv);
}

module_init(drv_init);
module_exit(drv_exit);
MODULE_LICENSE("GPL");

mybus.c代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>

int match_mybus (struct device *dev, struct device_driver *drv)
{
	//如果匹配成功,match方法一定要返回一个1,失败返回0
	if(!strncmp(dev->kobj.name,drv->name,strlen(dev->kobj.name)))
	{
		printk("__KERNEL__:match success!\n");
		return 1;
	}
	else
	{
		printk("__KERNEL__:match fales!\n");
		return 0;
	}

	return 0;
}


struct bus_type mybus = {
	.name = "mybus",
	.match = match_mybus,
};

EXPORT_SYMBOL(mybus);

static int __init bus_init(void)
{
	int ret;
	
	printk("-------------%s--------------\n",__FUNCTION__);
		
	ret = bus_register(&mybus);

	if(ret != 0)
	{
		printk("bus_register Error!\n");
		return ret;
	}

	return 0;
}

void __exit bus_exit(void)
{
	bus_unregister(&mybus);
}


module_init(bus_init);
module_exit(bus_exit);
MODULE_LICENSE("GPL");

Makefile代码

ROOTFS_DIR = /home/linux/Level11

#APP_NAME = key_test

CROSS_COMPILE = arm-none-linux-gnueabi-
CC = $(CROSS_COMPILE)gcc

ifeq ($(KERNELRELEASE), )

KERNEL_DIR = /home/linux/Level10/day6/linux-5.4.79
CUR_DIR = $(shell pwd)

all :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
		#$(CC) $(APP_NAME).c -o $(APP_NAME)

clean :
		make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
		#rm $(APP_NAME) ./1/$(APP_NAME)
		clear

install:
		#cp -raf  *.ko  $(APP_NAME)   ./1/
		cp -raf  *.ko  ./1/
		
else
obj-m += mybus.o
obj-m += mydevice.o
obj-m += mydrv.o
endif

效果展示

[root@farsight ]# insmod mybus.ko
[ 6434.898865] -------------bus_init--------------
[root@farsight ]# insmod mydevice.ko
[ 6441.025897] -------------dev_init--------------
[root@farsight ]# insmod mydrv.ko
[ 6448.787408] -------------drv_init--------------
[ 6448.790507] __KERNEL__:match success!
[ 6448.794198] -------------mydrv_probe--------------
[ 6448.798960] name = testfs , interrupt = 2333 , addr = 40001000
[root@farsight ]# lsmod
mydrv 16384 0 - Live 0xbf00a000 (O)
mydevice 16384 0 - Live 0xbf005000 (O)
mybus 16384 2 mydrv,mydevice, Live 0xbf000000 (O)
[root@farsight ]# rmmod mydrv
[ 9234.532167] -------------mydrv_remove--------------