netlink_uevent_kernel.c
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#define TAG "HELLO# "
struct device *dev = NULL;
struct device_driver *drv = NULL;
static int my_bus_match(struct device *_dev, struct device_driver *_drv)
{
printk(TAG "%s called\n", __func__);
return !strcmp(dev_name(dev), drv->name);
}
static int my_bus_probe(struct device *dev)
{
printk(TAG "%s called\n", __func__);
printk(TAG "hello drv_%s, dev_%s, Happy Marriage!\n", dev->driver->name, dev_name(dev));
return 0;
}
static void my_bus_remove(struct device *dev)
{
printk(TAG "%s called\n", __func__);
}
struct bus_type my_bus_type = {
.name = "my-bus",
.match = my_bus_match,
.probe = my_bus_probe,
.remove = my_bus_remove,
};
static int netlink_uevent_init(void)
{
char *env[] = {"蓝牙先生", NULL};
printk(TAG "%s called\n", __func__);
/* register bus */
bus_register(&my_bus_type);
/* register device */
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
dev->init_name = "netlink_uevent";
dev->bus = &my_bus_type;
device_register(dev);
dev = get_device(dev);
/* register driver */
drv = kzalloc(sizeof(*drv), GFP_KERNEL);
drv->name = "netlink_uevent";
drv->bus = &my_bus_type;
driver_register(drv);
kobject_uevent_env(&dev->kobj, KOBJ_ONLINE, env);
return 0;
}
static void netlink_uevent_exit(void)
{
printk(TAG "%s called\n", __func__);
/* unregister driver */
driver_unregister(drv);
/* unregister device */
device_unregister(dev);
/* unregister bus */
bus_unregister(&my_bus_type);
/* free resource */
kfree(dev);
kfree(drv);
}
module_init(netlink_uevent_init);
module_exit(netlink_uevent_exit);
MODULE_LICENSE("GPL");
netlink_uevent_app.c
#include <stdio.h>
#include <linux/netlink.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <linux/socket.h>
#include <string.h>
int main(int argc, char *argv[])
{
ssize_t len = 0;
int fd = 0;
int efd = 0;
int ret = 0;
char buf[512];
struct sockaddr_nl addr = {
.nl_family=AF_NETLINK,
.nl_pid = 0,
.nl_groups = 1
};
struct epoll_event event = {
.events = EPOLLIN,
};
struct iovec iov = {
.iov_base = &buf[0],
.iov_len = sizeof(buf)
};
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
};
fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
efd = epoll_create1(EPOLL_CLOEXEC);
ret = epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event);
while(1)
{
printf("detecting uevent...\n");
ret = epoll_wait(efd, &event, 6, -1);
len = recvmsg(fd, &msg, 0);
for(int i = 0; i < len; i += strlen(&buf[i]) + 1)
{
printf("%s ", &buf[i]);
}
printf("\n");
}
return 0;
}
效果