【转】6.4.6 将驱动编译进Linux内核进行测试
原文网址:http://www.apkbus.com/android-98520-1-1.html
前面几节都是将Linux驱动编译成模块,然后动态装载进行测试。动态装载驱动模块不会随着Android系统的启动而自动装载,因此Android系统每次启动都必须使用insmod或modprobe命令装载Linux驱动模块。
对于嵌入式系统(包括嵌入式Android、嵌入式Linux等)一般都采用将Linux驱动编译进内核的方式。这样做虽然没有动态装载灵活,但Linux驱动会随着Android的启动而自动装载。一般在开发过程中为了测试和调试方便,会将Linux驱动以模块形式装载到Linux内核中。当Linux驱动通过最终测试后,会将Linux驱动编译进Linux内核再进行测试。
本节将介绍如何将word_count驱动编译进Linux内核,并分别在Android模拟器和S3C6410开发板上测试word_count驱动。
Linux内核源代码被设计成可装卸式结构。也就是说只需要修改配置文件,就可以使某个Linux驱动编译成模块(.ko文件),或编译进Linux内核,当然,也可以将该Linux驱动从Linux内核去除。核心的配置文件如下。
q .config:该文件位于Linux内核源代码的顶层目录,为隐藏文件。该文件用于配置Linux内核中的模块。在.config文件中可以对Linux驱动进行三方面的配置:编译成驱动模块(.ko文件)、编译进内核和从Linux内核去除。可以手工修改.config文件,也可以使用make menuconfig命令用菜单方式来设置.config文件。
q Kconfig:每一个想要连接进Linux内核的模块目录都有该文件。该文件主要用于定义make menuconfig命令显示的菜单(包括菜单项名称、帮助信息、选项类型、模块依赖等信息),除此之外,Kconfig文件还可以导入位于其他目录的Kconfig文件。make命令通过Kconfig文件的递归引用,可以找到Linux内核中的所有Kconfig文件,从而建立一个完整的配置菜单。
q Makefile:一般与Kconfig文件同时出现。每有一个Kconfig文件,就必要有一个Makefile文件。该文件用于指定如何编译Makefile文件所在目录的源代码。
现在还使用word_count驱动的例子来详细说明如何将一个Linux驱动加入Linux内核源代码树中。由于word_count驱动属于字符驱动,所以可以使用如下的步骤将word_count驱动加入Linux内核源代码树。
第1步:将word_count.c文件放入Linux内核源代码
将word_count.c文件放到<Linux内核目录>/drivers/char目录中。
第2步:修改Kconfig文件
打开/root/kernel/goldfish/drivers/char/Kconfig文件,找到endmenu,并在endmenu前面添加如下代码。
config WORD_COUNT
bool "word_count driver"
help
This is a word count driver. It can get a word count from /dev/wordcount
其中,config后面的字符串将作为Shell变量名的后半部分,前半部分是CONFIG_。也就是说,每一个具体的模块都会对应一个Shell变量来保存该模块的3个编译行为(生成.ko文件、编译进Linux内核或从Linux内核中去除)。word_count驱动模块的变量是CONFIG_WORD_COUNT。该变量的值会保存在.config文件中。
bool表示word_count驱动只能进行两项设置(被编译进内核与从Linux内核中去除),后面会介绍如何设置菜单项的三项设置。bool后面的字符串就是菜单项的文本。help用于设置菜单项的帮助信息。
第3步:修改Makefile文件
打开/root/kernel/goldfish/drivers/char/Makefile文件。该文件大多都是如图6-21所示的内容,随便找个位置插入如下内容。
<ignore_js_op>
▲图6-21 在Makefile文件中添加word_count驱动模块
obj-$(CONFIG_WORD_COUNT) += word_count.o
通过第2步的设置产生了一个CONFIG_WORD_COUNT变量,而在第3步中obj-后使用了该变量,而不是使用固定的值(y或m)。make命令在编译Linux内核时会将该变量替换成相应的值。
第4步:设置.config文件
.config文件可以通过手工配置,也可以通过make menuconfig命令在菜单中配置。在这里我们采用菜单配置的方法。现在进入Linux内核顶层目录(/root/kernel/goldfish)。然后执行make menuconfig命令显示配置菜单,并进入“Device Drivers”>“Character devices”子菜单,找到“word_count_driver”菜单项,按空格键将“word_count_driver”菜单项前设置成星号(*),如图6-22所示。然后退出配置界面并保存所做的修改。
按“h”键可以显示word_count驱动的帮助信息,如图6-23所示。
<ignore_js_op>
▲图6-22 配置word_count驱动模块
<ignore_js_op>
▲图6-23 word_count驱动的帮助信息
在配置完.config文件后,读者可以打开.config文件,并找到CONFIG_WORD_COUNT,会发现该变量的值已被设成“y”。
第5步:编译Linux内核
进入/root/kernel/goldfish目录,执行下面的命令编译Linux内核。
# make
如果读者以前编译过当前的Linux内核,并不需要担心编译的时间过长,因为make足够智能,它只会编译最新修改的模块及其依赖的模块。
当成功编译Linux内核后,读者可以到/root/kernel/goldfish/arch/arm/boot目录找到zImage文件,并使用Android模拟器运行这个内核。读者会发现,在/dev目录中有一个wordcount设备文件,而我们并没有运行build.sh脚本文件安装word_count驱动。这是因为Android模拟器在装载zImage内核文件时已自动装载了word_count驱动。不过在使用前面的例子测试word_count驱动时仍然需要执行下面的命令设置/dev/wordcount设备文件的访问权限。
# adb shell chmod 777 /dev/wordcount
如果读者不想将word_count.c复制到/root/kernel/goldfish/drivers/char目录,可以使用下面的命令在/root/kernel/goldfish/drivers/char目录建立一个符号链接。
# ln -s /root/drivers/ch06/word_count /root/kernel/ goldfish/drivers/ char/word_ count
将word_count目录加入Linux内核源代码树的步骤如下(在进行下面的步骤之前需要将上面步骤所做的设置注释掉)。
第1步:建立新的Kconfig文件
在word_count目录中建立一个Kconfig文件,并输入如下内容:
config WORD_COUNT
tristate "word_count driver"
default y
help
This is a word count driver. It can get a word count from /dev/wordcount
其中tristate表示三态类型(编译进内核、编译成模块,从Linux内核移除)。如果使用tristate代替bool,菜单项前面就变成尖括号。按“y”键,尖括号中显示星号(*),表示编译进内核。按“M”键,尖括号中显示M,表示编译成模块。按“N”键,尖括号在符号消失,表示word_count驱动被忽略。如果不断按“空格”键,这3种状态会循环切换。
default用来设置默认值。如果使用tristate,default可以设置y、m和n三个值,分别对应编译进内核、编译成模块和从Linux内核中移除。当模块第一次设置时会处于default设置的默认状态。
注意如果使用tristate,必须按照6.4.2节的方法打开“Enable loadable module support”选项,否则无法将驱动设为编译成模块状态(M状态),菜单项前面仍然是一对中括号。
第2步:修改Makefile文件
word_count目录中的Makefile文件目前的内容如下:
obj-m := word_count.o
在Makefile文件中已经将编译类型设为Linux驱动模块(obj-m表示编译成.ko文件)。但现在要将word_count驱动加入Linux内核源代码树中,因此需要使用CONFIG_WORD_COUNT变量来代替m,所以Makefile文件的内容需要按如下内容修改。
obj-$(CONFIG_WORD_COUNT) := word_count.o
修改Makefile文件后,如果还想使用前面几节的脚本文件测试word_count驱动,需要将.config文件中CONFIG_WORD_COUNT变量值设为m,如果.config文件中没有该变量,就添加一个CONFIG_WORD_COUNT变量。当然,也可以使用make menuconfig命令设置。
为了可以单独编译word_count驱动,也可以和Linux内核一同编译,我们可以采用如下形式重新编写Makefile文件。当CONFIG_WORD_COUNT变量未定义时,说明没有与Linux内核一同编译。
# 与Linux内核一同编译
ifdef CONFIG_WORD_COUNT
obj-$(CONFIG_WORD_COUNT) := word_count.o
else
# 单独编译
obj-m := word_count.o
endif
第3步:修改上层目录的Kconfig文件
为了能找到word_count目录中的Kconfig文件,需要在drivers/char/Kconfig文件中引用word_count目录中的Kconfig文件。现在打开/root/kernel/goldfish/drivers/char/Kconfig文件,在“endmenu”之前添加如下一行代码。
source "drivers/char/word_count/Kconfig"
第4步:修改上层目录的Makefile文件
在drivers/char/Makefile文件中添加如下一行,以便使make命令可以找到word_count目录中的Makefile文件。
obj-$(CONFIG_WORD_COUNT) += word_count/
接下来的工作就和前面介绍的五步中的第4步和第5步一样了。在进入如图6-24所示的设置界面时,可以按“M”键将word_count驱动模块编译成.ko文件。
<ignore_js_op>
▲图6-24 设置word_count驱动模块的编译类型
注意当修改Linux内核设置后重新编译内核,以前使用该Linux内核编译的Linux驱动模块可能由于格式错误无法安装,因此,在重新编译Linux内核后,需要重新编译Linux驱动模块。
如果想将word_count驱动模块编译进其他内核也可采用与上面类似的做法。
【转】6.4.6 将驱动编译进Linux内核进行测试的更多相关文章
- 将驱动编译进Linux内核
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 将MPLS编译进linux内核中
系统环境:linux kernel 2.6.35.(此环境是上一篇文章中将ubuntu内核替换后的环境) 编译过程如下: 1)首先需要下载patch文件:linux-kernel-v2.6.35-mp ...
- 编译安装linux内核步骤
编译安装linux内核步骤: 一.获取内核源码 源码网址:www.kernel.org 二.解压内核源码 首先以root帐号登录,然后进入/usr/src子目录.如果用户在安装Linux时,安装了内核 ...
- linux内核系列(一)编译安装Linux内核 2.6.18
1.配置环境 操作系统:CentOS 5.2 下载linux-2.6.18版本的内核,网址:http://www.kernel.org 说明:该编译文档适合2.6.18以上的Linux内核版本,只需所 ...
- 如何编译安装Linux内核
操作系统环境 VMware workstation15 Pro ubuntu18.04 LTS 待编译内核5.3.10版本 内核下载地址 kernel.org 环境配置 在正式编译前需要安装部分软件. ...
- 编译aarch64 Linux内核并基于qemu运行
核心流程 首先,本文主要讲述如何编译Linux内核并在qemu虚拟机上运行.这里针对的架构是aarch64. 本文的实验平台是Ubuntu 16.04. 为了达成目标,我们需要有qemu.buildr ...
- 编译x86_64 Linux内核并基于QEMU运行
编译并运行内核镜像 安装包准备 $ sudo apt install git $ sudo apt install build-essential kernel-package fakeroot li ...
- 编译最新linux内核(version 4.4.2)
环境:centos6.4 内核版本为2.6.32 目标:编译4.4.2内核,升级到 4.4.2 准备工作: 安装开发库和ncurses库 # yum groupinstall "Develo ...
- Android应用程序访问linux驱动第一步:实现并测试Linux驱动
一直都想亲自做一次使用android应用程序访问Linux内核驱动的尝试,但总是没能做到.最近抽出时间,下决心重新尝试一次.尝试的开始当然是先写一个Linux内核驱动了. 我希望写一个简单测驱动程序, ...
随机推荐
- yii基础知识-应用
应用是指请求处理中的执行上下文.它的主要任务是分析用户请求并将其分派到合适的控制器中以作进一步处理. 它同时作为服务中心,维护应用级别的配置.鉴于此,应用也叫做前端控制器. 应用由 入口脚本 创建为一 ...
- Check whether a given Binary Tree is Complete or not 解答
Question A complete binary tree is a binary tree in which every level, except possibly the last, is ...
- web应用,我们需要了解什么?
对于前端开发来说,web应用我们并不陌生.今天想要讨论一下,在开发一个web应用的时候,我们需要一些基本的知识储备.我们知道,一个web应用脱离不了(request)请求和响应(respons ...
- spring3 jsp页面使用<form:form modelAttribute="xxxx" action="xxxx">报错,附连接数据库的spring MVC annotation 案例
在写一个使用spring3 的form标签的例子时,一直报错,错误信息为:java.lang.IllegalStateException: Neither BindingResult nor plai ...
- 简易的C/S系统(实现两个数的和)
//Client:#include <string.h> #include <sys/socket.h> #include <stdio.h> #include & ...
- java RMI入门指南
感觉这篇文章不错,直接转了 RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体如今它强大的开发分布式网络应用的能力上,是纯J ...
- [Spring入门学习笔记][创建网站URL]
设计网站的URL 现代的Web站点都会设计一套拥有明确意义,方便用户记忆的URL,不论是域名还是路径,以天码营为例: http://tianmaying.com/courses表示网站下所有的课程列表 ...
- CLR via C# - 基础拾遗
编译器开关设置 IL代码质量 JIT本地代码质量 /optimize- /debug-(默认设置) 未优化 优化 /optimize- /debug+(full/pdbonly) 未优化 未优化 /o ...
- jquery 处理密码输入框(input type="password" ) 模仿placeholder
html <form method="post" action=""> <ul> <li> <span>邮箱&l ...
- JavaScript自我学习之解析与执行
如果想要学好JavaScript那么我们首先必须要知道浏览器JavaScript引擎是如何解释执行JavaScript代码的,作为一名菜鸟,从自己学习JavaScript的过程来说,真心觉得不了解这些 ...