批量创建字符设备的设备节点

摘要

对于使用register_chrdev()去注册字符设备的driver,在insmod加载完driver后还需要通过mknod去创建对应的设备节点,否则应用程序或调用库无法去open设备。
但是,当一个driver需要创建非常多的设备节点时,通过在rc文件中去逐个mknod显然不合理。因此,较合理的做法就是通过程序或脚本去批量创建设备节点。

简单示例

  1. 头文件定义
  • 自定义一个结构体将设备节点名称、设备类别(字符设备、块设备)、主设备号、次设备号以及节点操作权限。
  • 自定义一个在/dev下要创建的目录(设备节点所在的二级目录),没有则不需要定义。

/*
** sample.h
*/
#ifndef __SAMPLE_H__
#define __SAMPLE_H__

static const struct device_struct {
	char *name;
	char type;
	int major;
	int minor;
	int mode;
} device_list[] = {
	{ "hello/hi0",   'c',  168,  0,  0660},
	{ "hello/hi1",   'c',  168,  1,  0660},
	...
	{ "hello/hi198", 'c',  168,  198,  0660},
	{ "hello/hi199", 'c',  168,  199,  0660},
	...
};

#define N_DEVICE_LIST (sizeof(device_list)/sizeof(device_list[0]))

static const char * const dir_list[] = {
	"hello",
	...
};
#define N_DIR_LIST (sizeof(dir_list)/sizeof(dir_list[0]))

#endif
  1. 源文件定义
  • 首先,进程将目录切换到/dev目录下
  • 然后,创建二级目录并设置操作权限
  • 创建设备ID,设置设备权限,是字符设备则追加S_IFCHR权限(若是块设备则为S_IFBLK)
  • 创建设备节点
  • 返回根目录,完成task

/*
** sample.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/kdev_t.h>
#include "sample.h"

#define TARGET_PATH "/dev"
#define UNUSED(a) (a)

int devastate(void)
{
	unsigned int i;
	char dev_name[64];

	/*
	 * chdir(const char *path) changes the current working directory of the calling process to the directory specified in path.
	 */
	if (chdir(TARGET_PATH)) {
		printf("change directory failed...");
		return -1;
	}

	/*
	 * mkdir(const char *pathname, mode_t mode) creates the directory named pathname with attributes specified by mode.
	 * chmod(const char *path, mode_t mode) changes the permissions of path file with attributes specified by mode.
	 */
	for (i = 0; i < N_DIR_LIST; i++) {
		if (mkdir(dir_list[i], 0755) < 0) {
			printf("mkdir failed...");
		} else {
			chmod(dir_list[i], 0755);
		}
	}

	/*
	 * MKDEV(ma,mi) generates a device ID use major and minor.
	 * mknod(const char *pathname, mode_t mode, dev_t dev) creates a filesystem node (file, device special file or named pipe)
	 * named pathname, with attributes specified by mode and dev.
	 */
	for (i = 0; i < N_DEVICE_LIST; i++) {
		unsigned int dev = MKDEV(device_list[i].major, device_list[i].minor);
		int mode = S_IFCHR | device_list[i].mode;
		if (mknod(device_list[i].name, mode, dev) < 0) {
			printf("mknodfailed...");
		} else {
			sprintf(dev_name, "%s/%s", TARGET_PATH, device_list[i].name);
			chmod(dev_name, mode);
		}
	}

	chdir("/");

	return 0;
}

int main(int argc, char **argv)
{
    UNUSED(argc);
    UNUSED(argv);

	return devastate();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值