《Linux设备驱动开发详解》读书笔记(2)

时间:2022-04-07 17:56:38

第一章,    内核模块

代码module_init(),module_exit(), request_module(),module_param(),module_param_array()。EXPORT_SYMBOL()导出符号。使用try_module_get()和module_put()管理模块的使用计数。

属性__init表示代码放入section(.init.text)。__initdata表示初始化完成后,数据内存释放。

工具insmod, rmmod, modprobe, lsmod, modinfo,

接口 /proc/modules, /sys/module/xxx。在insmod时可以输入module_param()定义的参数。在/sys/module/xxx/paramerts下面可以看到参数。/proc/kallsyms可以看到符号表。

在Makefile中,obj-m定义了模块编译的输出。

第二章,    文件系统与设备文件

打开open(char *fn, int flag, mode_t mode)。flag表示打开方式,mode表示访问权限。

文件系统目录:bin, sbin, dev, etc. lib, mnt, opt, proc, tmp, usr, var, sys 。/proc存放运行时的内核和进程信息(CPU,硬盘分区,内存信息等)。/sys新设备的记录,比如总线、驱动、设备等都有对应的节点。

VFS inode文件系统的基本单位,包括mode, uid, gid, size, a_time,c_time等。i_rdev表示设备编号(12位主编号,20位次编号)。块设备有i_bdev,字符设备有i_cdev,指针指向设备。/proc/devices可以查看编号。

目前udev在用户空间工作,使用netlink获取设备创建的信息。

/sys目录下包含block, bus, dev, devices, class, fs,kernel, power, firmwar等。Bus下面又有drivers,devices等。在include/linux/device.h中,定义了bus_type(match(),uevent(),probe(),remove(),online(),offline()等),device_driver(probe(),remove()) device等数据结构(*bus,*driver)。其中bus_type中的match()负责将设备和驱动绑定。绑定后,xxx_driver的probe()函数就会执行。而attribute将会成为sysfs中的一个文件。

目前udev与systemd合并。内核发现了新设备后,通过netlink发送uevent,而用户空间的udev程序捕捉到uevent,根据规则,进行匹配。管理程序为udevadm或者mdev(用于busybox)。Android中使用netlinkmanager.cpp来做这件事。

第三章,    字符设备驱动

数据结构cdev,成员file_ops,file_ops中的private_data一般指向dev。加载时,通过register_chrdev_region()或者alloc_xxx()获取设备号,然后cdev_init()初始化,cdev_add()添加设备。IOR/W等宏用于创建ioctl的命令(MAGIC + cmd)。

使用container_of()可以从struct member的指针找到struct指针。