嵌入式linux系统 mdev,嵌入式linux之mdev机制分析

一、mdev分析

1、作用

首先我们先说明它的作用是什么,然后分析为什么能产生这种作用。在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需的设备节点即/dev/xxx。同时可以设置一些脚本,并执行,脚本可以设置一下设备节点的读写权限,或者进行挂载等。mdev是udev的简化版本,它也是通过读取内核信息来创建设备文件

以前的按键驱动程序,入口函数,为什么创建类呢,为什么在类下创建设备节点呢?是为了让mdev根据这些信息来创建设备节点。

按键驱动程序中我们这么做:

sixthdrv_class = class_create(THIS_MODULE, "sixth_drv");

sixthdrv_class_dev = device_create(sixthdrv_class, NULL, MKDEV(major, 0), NULL, "buttons");最后产生 /dev/buttons设备节点。

2、函数调用流程

device_create—>device_create_vargs—>device_register—>device_add—>kobject_uevent (&dev->kobj, KOBJ_ADD) —>kobject_uevent_env (kobj, action, NULL) —>

// action_string = "add";

const char *action_string = kobject_actions[action];

/* environment buffer */

env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);

/* 设置环境变量 */

retval = add_uevent_var(env, "ACTION=%s", action_string);

retval = add_uevent_var(env, "DEVPATH=%s", devpath);

retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);

/* 调用应用程序: 比如mdev,启动脚本 echo /sbin/mdev > /proc/sys/kernel/hotplug 设置了uevent_helper为“/sbin/mdev“*/

argv [0] = uevent_helper;

argv [1] = (char *)subsystem;

argv [2] = NULL;

retval = call_usermodehelper(argv[0], argv,env->envp, UMH_WAIT_EXEC);

调用了busybox文件系统中的 mdev.c

修改内核,添加参数打印:

3f288ee285423cc6e29fa526842ca321.png

uevent_helper = /sbin/mdev

envp[0] = HOME=/

envp[1] = PATH=/sbin:/bin:/usr/sbin:/usr/bin

envp[2] = ACTION=add

envp[3] = DEVPATH=/class/sixth_drv/buttons

envp[4] = SUBSYSTEM=sixth_drv

envp[5] = SEQNUM=720

envp[6] = MAJOR=252

envp[7] = MINOR=0

3、分析busybox mdev.c

mdev_main

temp = /sys/class/sixth_drv/buttons

make_device(temp, 0);

/* 确定设备文件名,类型,主次设备号 */

device_name = bb_basename(path); = "buttons"

'c' == > 字符设备节点

根据"/sys/class/sixth_drv/buttons/dev"的内容确定主次设备号

mknod(device_name, mode | type, makedev(major, minor)

最后mdev调用了mknod创建设备节点,从而在/dev下产生/dev/buttons设备节点。到此知道了原来/dev下的设备节点是这么创建的!

如何在设备创建的时候执行一些脚本呢?比如修改设备节点权限,自动挂接U盘等。

需要添加/etc/mdev.conf配置文件。mdev.c会解析此配置文件,一旦匹配到设备,则可以执行一些脚本命令。

代码分析:

int mdev_main(int argc UNUSED_PARAM, char **argv)

{

//mdev -s:mdev -s is to be run during boot to scan /sys and populate /dev.

if (argv[1] && strcmp(argv[1], "-s") == 0){}

snprintf(temp, PATH_MAX, "/sys%s", env_path);

//static void make_device(char *path, int delete)

make_device(temp, /*delete:*/ 0);

{

/* Determine device name, type, major and minor */

device_name = (char*) bb_basename(path);

mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST

}

}

3.1 mdev.conf的格式:

:[ ]

device regex:正则表达式,表示哪一个设备

uid: owner

gid: 组ID

octal permissions:以八进制表示的属性

@:创建设备节点之后执行命令

$:删除设备节点之前执行命令

*: 创建设备节点之后 和 删除设备节点之前 执行命令

command:要执行的命令

3.2 写mdev.conf

1.

leds 0:0 777

led1 0:0 777

led2 0:0 777

led3 0:0 777

2.

leds?[123]? 0:0 777

3.

leds?[123]? 0:0 777 @ echo create /dev/$MDEV > /dev/console

4.

leds?[123]? 0:0 777 * if [ $ACTION = "add" ]; then echo create /dev/$MDEV > /dev/console; else echo remove /dev/$MDEV > /dev/console; fi

5.

leds?[123]? 0:0 777 * /bin/add_remove_led.sh

把命令写入一个脚本:

add_remove_led.sh

#!/bin/sh

if [ $ACTION = "add" ];

then

echo create /dev/$MDEV > /dev/console;

else

echo remove /dev/$MDEV > /dev/console;

fi

6. U盘自动加载

sda[1-9]+ 0:0 777 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt; else umount /mnt; fi

7.

sda[1-9]+ 0:0 777 * /bin/add_remove_udisk.sh

add_remove_udisk.sh

#!/bin/sh

if [ $ACTION = "add" ];

then

mount /dev/$MDEV /mnt;

else

umount /mnt;

fi

二、扩展etc配置分析

1、busybox文件目录中/doc/mdev.txt中写到

Here's a typical code snippet from the initscript:

[0] mount -t proc proc /proc

[1] mount -t sysfs sysfs /sys

[2] echo /sbin/mdev >/proc/sys/kernel/hotplug

[3] mdev -s

Of course, a more "full" setup wouldentail executing this before the previous

code snippet:

[4] mount -t tmpfs -o size=64k,mode=0755 tmpfs/dev

[5] mkdir /dev/pts

[6] mount -t devpts devpts /dev/pts

所以在/etc/init.d/rcS配置如下

#!/bin/sh

ifconfig eth0 192.168.1.17

mount -a

mkdir /dev/pts #使用内存文件系统,减少对flash的读写

mount -t devpts devpts /devpts #/dev/pts用来支持外部网络链接(telnet:远程访问摄像头)的虚拟终端

echo /sbin/mdev > /proc/sys/kernel/hotplug #设置内核,当有设备插拔时调用/bin/mdev程序

mdev -s #在/dev目录下生成内核支持的所有设备的节点

2、在busybox文件目录中/doc/mdev.txt还有如下关键说明

The simple explanation here is that

[1] youneed to have /sys mounted before executing mdev.

[4]make sure /dev is a tmpfs filesystem (assuming you're running out of flash).

Thenyou want to [5] create the /dev/pts mount point and finally [6] mount thedevpts filesystem on it

所以要修改/etc/fstab来自动挂载文件系统,修改etc/init.d/rcS加入要自动运行的命令。

#device mount-point type options dump fsck order

proc /proc proc defaults 0 0

tmpfs/tmp tmpfs defaults 0 0

sysfs /sys sysfs defaults 0 0

tmpfs/dev tmpfs defaults 0 0

3.linux虚拟文件系统

1、linux有几种虚拟的文件系统类型(只存在于内核,在物理内存不存在,不过我们可以用挂载的方式将它在物理内存上进行映射,如mount-t proc proc /proc;将cpu,mem等信息挂载在硬盘中),比如proc,sysfs,tmpfs,root.2、proc是内核用的文件系统,用于显示内核信息及改变内核参数;3、sysfs文件系统用来管理和显示各种设备的运行参数及设备的层次结构。//能减少对flash的对写4、tmpfs:能解决临时的设备(/dev)或文件(/tmp)访问速度慢的缺点。

4./etc/fstab 的用途

/etc/fstab是设定分割区分 mount目录相关的档案,开机时会依这个档案的內容 mount 档案系統,mount档案系統的命令为:

linux# mount -av

会依 /etc/fstab的內容 mount 进"除了 root 以外的所有档案系統"。

root 是在开机时由核心所 mount 进來的。root 先由核心mount 成 read-only,然后由使用者手动remount 成 read-write。

5./etc/inittab

init根据/etc/inittab配置文件来执行相应的脚本进行系统初始化,如设置键盘、字体,装载模块,设置网络;

init 是在核心 mount 进 root 后,第一個执行的程式 (第一个 process)

开机后执行上述文件的过程:

开机==>mount -t root root /root (此句内核自动执行)==> /etc/fstab ==>/etc/inittab ==> 执行/etc/rc.d/目录下的脚本(包括/etc/init.d/rcS)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值