实现内核驱动程序模块

例子是从《Android系统源代码情景分析》第二章抄过来的,在学习的过程中还是遇到了不少的问题。

个人体会:在学习第二章之前应该把《Linux设备驱动程序》这本书至少前四章要读一遍,理解一些基础概念和背景知识,不过这本书还是略旧,比如sysfs就没有解释,多google吧。

本书第二章要理解透了再往下进行,因为这个简单的例子从下往上贯穿了Android系统各层,是理解后面各章的基础。

下面列出我遇到的问题和解决办法。

  • 三类文件系统接口的关系、作用分别是什么?

它实现了proc文件系统接口、传统的设备文件系统接口和devfs文件系统接口。

类Unix系统有一条基本的设计哲学:几乎所有的数据实体都被抽象成统一的接口——文件来看待。procfs、devfs和sysfs都是这种设计的体现。

/dev目录下每一个文件对应一个设备,通过操作这些文件可以实现与内核的交互,但devfs存在一些缺点,如命名不灵活,不能任意指定文件名,而且所有文件都在/dev/根目录下。进而演生出sysfs,它把实际连接到系统上的设备组织成一个分级的文件体系,比devfs更清晰更便于管理,sysfs挂载在/sys下面。

/proc文件系统中主要包含三大类内容:进程相关部分、系统信息部分和系统自信息部分。显然在本例中,procfs和sysfs部分的接口,作为入门第一个样例来说并不必要。

因此我打算只实现传统设备文件系统接口的部分,sysfs和procfs暂不实现。我认为依然可以完整地正常工作。

  • 编译问题

  • 在__freg_setup_dev函数中,对函数init_MUTEX的调用编译出错,这是因为该函数已经被启用,改成如下即可:
sema_init(&(dev->sem), 1);
  • 修改内核Kconfig文件。我编译的内核是3.4,需要在drivers/Kconfig中添加
source "drivers/freg/Kconfig"

而不是在arch/arm/Kconfig中。


  • 配置

  • 在Mac OSX,调用make menuconfig的时候出错,解决办法已经更新到《Android源码、内核编译》这篇博文里了。
  • 进入make menuconfig配置界面后,如果要设置Enable loadable module support,这块的交互有点坑爹。初次进入界面是这样的,Enable loadable module support没有被选中:

如果直接回车进入子菜单,发现前面是---,是不能被修改的:

我以为是自己的内核版本有问题,倒腾了半天才明白:应该在一级界面中先对Enable loadable module support按下Y,使之选中:

然后再回车进入才能看到并修改子项内容:

一万头草泥马崩腾而过,害老子研究半天……


  • 调试

  • 查看内核log

我把模块编译到内核中,起初却在/dev下面找不到freg文件,必须要调试代码看在哪一步出了错。freg.c源码多出调用printk函数写了日志,我在每条日志字串头部加了[freg]的字样,如下:

printk(KERN_ALERT"[freg]Initializing freg device.\n");

以便在浩瀚的内核日志中筛选出freg的日志。

  • 方法一:可以使用dmesg查看内核打印信息,再配合grep如下:
$ adb shell
$ dmesg | grep "\[freg\]"
[freg]Initializing freg device.
[freg]Succeeded to initialize freg device.
  • 方法二:可以在运行emulator的时候加-show-kernel参数:
$ emulator -kernel arch/arm/boot/zImage -show-kernel &
时间: 2024-10-12 09:17:44

实现内核驱动程序模块的相关文章

Linux内核驱动编程

Linux内核驱动编程 2015-02-12 驱动程序基础的东西这儿就不罗嗦了,百度上有更好的资料,此处我们只是注重实际用处. 下面我们开始写程序: 一.初步helloword程序 首先是来一个简单的hello. hello.c代码: 1 /****************************** 2 3 the first program 4 5 Hello World! 6 7 ******************************/ 8 9 #include <linux/mod

国嵌内核驱动进阶班-7-1(Ioctl设备控制)

ioctl 控制设备 除了读写设备之外,其他功能的实现需要ioctl.如串口的波特率的设定. 用户空间: ioctl的应用 api int ioctl(int fd, unsigned long cmd, ...) fd 文件描述符 cmd 发送的命令 ...依赖cmd命令 内核空间 api int (*ioctl)(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg) inode 文件的物理信息

Win10与VS2015搭建内核驱动开发环境遇到的问题

关于在Win10与vs2015环境下搭建内核驱动开发环境看这两篇文章: WIN10 + VS2015 + WDK10 + SDK10 + VM虚拟机驱动开发调试环境搭建 Win10下VS2015(WDK10)驱动开发环境配置 搭建过程中遇到的问题 本人环境介绍: 物理机win10企业版 10586.218 虚拟机win10专业版 10586.218 vs2015 update2 Windbg 10.0.10586.567 Windows Driver Kit 10.0.10586.0 Windo

linux 内核驱动--Platform Device和Platform_driver注册过程

linux 内核驱动--Platform Device和Platform_driver注册过程 从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Platform_driver . Linux 中大部分的设备驱动,都可以使用这套机制 , 设备用 Platform_device 表示,驱动用 Platform_driver 进行注册. Linux platform driver 机制和传统的 device driver 机制 ( 通过 driver_

Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2G 8. 选择网络地址转换 9.设置IO控制器 10. 选择默认磁盘类型 11.创建一个新的虚拟磁盘 12.设置磁盘大小 13.选择路径保存虚拟磁盘 14. 完成虚拟机创建 15.设置虚拟机 16.选择opensuse镜像 17.开启虚拟机 18.虚拟机启动 19.安装opensuse 20.安装程

教你一招如何开发平台无关的内核驱动

相信搞过内核驱动开发的人员都面临过这样的问题:为了让上层代码尽可能的不改变,需要底层驱动对上层提供的接口在各种形态上都要保持不变,但是底层的逻辑实现又不可避免的有差异,甚至有些时候在同一款产品形态上都会有很大差异,那么我们此时该如何设计驱动架构,使代码看起来既好看又易于维护呢?接下来我们来具体分析一下. 举一个例子,现在有两种规格的定时器,内部实现逻辑不一样,要操作的寄存器也有差别,那么我现在有三种产品形态,一种形态上使用feature1,一种形态上使用feature2,另一种形态上这两种fea

RedHat5.8 编译内核驱动

/******************************************************************* * RedHat5.8 编译内核驱动 * 说明: * 需要编译RedHat5.8的内核驱动,找了一下资料,并操作一下,并编译 * 一下IO驱动,能够正常运作. * * 2017-3-1 深圳 南山平山村 曾剑锋 ******************************************************************/ 一.参考文档:

Linux内核驱动注册方式泛谈

Linux驱动注册有多种方式,通常是以内核提供的表征数据结构封装后按照内核子系统提供的接口函数进行注册,还有一些是比较复杂的以链表方式进行维护.以下对几种驱动注册方式进行介绍: 一.子系统有专门的驱动注册函数: 例如RTC子系统,提供rtc_device_register注册接口函数. 例如: rtc_device_register(client->name,&client->dev, &rx8025_rtc_ops, THIS_MODULE); static struct r

Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" /> 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. watermark/2/text/a