Android设备节点

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第1章Android设备节点的创建

在编写linux设备驱动程序的时候,很多时候都是利用mknod命令来手动创建设备节点的,带上名字和主次设备号就可以在/dev目录下生成设备节点。同样Android沿用了linux内核,很多设备驱动的节点是又是什么时候创建的呢?

在kernel自解压模块加载完成之后,会去运行android第一个应用程序init。在init.c的

在之前解析init.rc脚本的时候,service会被放在service_list的链表里。接下来就是要执行

Android的服务不是选项不是disabled并且带core和main的选项的服务都是需要开机自动加载的服务。而ueventd是由system/core/init/ueventd.c编译而成的。

System/core/init/ueventd.c

int ueventd_main(int argc, char **argv)

{

……

ueventd_parse_config_file("/ueventd.rc");

……

snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);

ueventd_parse_config_file(tmp);

……

device_init();

……

while(1) {

ufd.revents = 0;

nr = poll(&ufd, 1, -1);

if (nr <= 0)

continue;

if (ufd.revents == POLLIN)

handle_device_fd();

}

}

Ueventd的main函数做的事情比较多,首先是要解析根文件系统下的ueventd.rc以及ueventd.

就是parse_line_device。

然后通过device_init给设备添加创建NETLINK套接字。

System/core/init/ueventd.c

int ueventd_main(int argc, char **argv)

{

……

ueventd_parse_config_file("/ueventd.rc");

……

snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);

ueventd_parse_config_file(tmp);

……

device_init();

……

while(1) {

ufd.revents = 0;

nr = poll(&ufd, 1, -1);

if (nr <= 0)

continue;

if (ufd.revents == POLLIN)

handle_device_fd();

}

}

通过轮询的方式查看设备的uevent的变化,在设备注册产生kobject_uevent。在设备处理时候调用了handle_device_fd()。

接收的uevent的小心不能超过1024个字节,如果超出就算溢出将不会处理。如果接收的uevent有效,解析这个uevent会根据设备的类型来解析。之后handle_device_event会处理设备的event。而handle_firmware_event则是和某些设备需要firmware回去处理firmware的加载。

如果event的subsystem为block,说明是个块设备,就会交由handle_block_device_event去处理。或者subsystem是platform设备的话,则有handle_platform_device_event来处理。如果两者都不是的话,说明是一个普通设备,handle_generic_device_event会来处理。块设备和

if (!strncmp(uevent->subsystem, "usb", 3)) {

if (!strcmp(uevent->subsystem, "usb")) {

/* This imitates the file system that would be created

* if we were using devfs instead.

* Minors are broken up into groups of 128, starting at "001"

*/

int bus_id = uevent->minor / 128 + 1;

int device_id = uevent->minor % 128 + 1;

/* build directories */

mkdir("/dev/bus", 0755);

mkdir("/dev/bus/usb", 0755);

snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);

mkdir(devpath, 0755);

snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);

} else {

/* ignore other USB events */

return;

}

……

else if (!strncmp(uevent->subsystem, "graphics", 8)) {

base = "/dev/graphics/";

mkdir(base, 0755);

} else if (!strncmp(uevent->subsystem, "drm", 3)) {

base = "/dev/dri/";

mkdir(base, 0755);

} else if (!strncmp(uevent->subsystem, "oncrpc", 6)) {

base = "/dev/oncrpc/";

mkdir(base, 0755);

} else if (!strncmp(uevent->subsystem, "adsp", 4)) {

base = "/dev/adsp/";

……

handle_device(uevent->action, devpath, uevent->path, 0,

uevent->major, uevent->minor, links);

}

首先得到设备的名字,然后是创建一些设备的子目录,如果uevent->subsystem是usb,就需要创建一个/dev/bus/usb的目录。如果是uevent->subsystem是graphic的话,就需要创建一个/dev/graphics的目录,按照这样依次比较下去,创建设备类所需要的子目录。

相关文档
最新文档