草庐IT

android驱动开发从零到一

icedrunkard 2023-04-15 原文

目录

安卓驱动开发过程

机器介绍

本人是在win10里安装vmware workstation16软件,然后在vmware里创建了ubuntu18.04系统的虚拟机

安卓开发板用的是北京迅为的rk3568开发板

步骤

step1.下载android11源码
step2.编译android源码(make命令)
step3.编写驱动文件
step4.构建镜像(build.sh) (有两种加载驱动的方式)
step5.镜像烧写至rk3568开发板

step1:下载android11源码

源码非常大,为了确保下载后编译成功,请确保硬盘有300g的空间,可以下载谷歌的源码,也可以下载rk3568提供的源码

一、谷歌的源码下载:

1.设置git

ice@ubuntu:~/Android$ sudo apt-get install git
ice@ubuntu:~/Android$ git config --global user.name "abcd"
ice@ubuntu:~/Android$ git config --global user.email "abcd@xxx.com"

2.下载“源码的下载管理工具”

ice@ubuntu:~/Android$ git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo
ice@ubuntu:~/Android$ mkdir .repo
ice@ubuntu:~/Android$ mv git-repo .repo/repo #将“git-repo”移动到刚刚创建的“.repo”文件中,并将其名称改为“repo”
ice@ubuntu:~/Android$ cp .repo/repo/repo ./
ice@ubuntu:~/Android$ chmod u+x repo

3.开始下载

ice@ubuntu:~/Android$ ./repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-security-11.0.0_r55
ice@ubuntu:~/Android$ ./repo sync -j2

二、rk3568提供的源码下载:

本文用的rk3568开发板,使用的是供应商定制改动了一些内容的android11源代码,从百度网盘下载的
解压后的文件如图,基本和谷歌原版结构一致

链接: https://pan.baidu.com/s/16nucdvOIcBgCWMw7_aCyUQ?pwd=1dae
提取码: 1dae

step2:编译android源码(make命令)

1.编译的几个选项

ice@ubuntu:~/Android$ cd rk_android11.0_sdk
ice@ubuntu:~/Android/rk_android11.0_sdk$ source build/envsetup.sh
ice@ubuntu:~/Android/rk_android11.0_sdk$ lunch

有如下选项

我这里选择55
成功后提示

解释一下选择问题,无论是谷歌下载的源码还是rk3568提供的源码,都一样的解释

2.开始编译

ice@ubuntu:~/Android/rk_android11.0_sdk$ make -j12

这里的j12就是12个并行任务,你可以根据自己的cpu核数设定,之后就是等待编译成功

step3:编写驱动文件

驱动文件是c语言,文件是helloworld.c,内容如下

#include <linux/module.h>
#include <linux/kernel.h> 
static int helloworld_init(void)        
{
	printk("helloworld_init\r\n");
	return 0;
}
static void helloworld_exit(void)    
{
	printk("helloworld_exit\r\n");
}

module_init(helloworld_init);    
module_exit(helloworld_exit);   

step4:开始构建镜像(build.sh)

想使驱动在安卓系统中运行,有两种编译方式。
1.驱动编译到内核
2.驱动编译成内核模块

两种驱动编译方式

1.驱动编译到内核介绍:

构建内核镜像时,驱动c文件放在编译好的安卓源码里,放在其本身有的驱动一起的位置,本文是~/Android/rk_android11.0_sdk/kernel/drivers
文件夹里,所有驱动一起编译并构建镜像

2.驱动编译成内核模块介绍:

这种要先构建出不含我们自己写的驱动的镜像,把镜像烧写至开发板,之后才能加载ko文件。
请直接阅读"驱动编译到内核"部分的s4:构建内核镜像后,再阅读m2.驱动编译成内核模块实战部分。
步骤是编译出我们的驱动ko文件,把此驱动ko文件拷贝至开发板,在运行中的开发板里,通过insmod命令加载驱动。

m1.驱动编译到内核实战

s1.drivers文件夹内创建自己的驱动文件夹并写入驱动文件。

我是放在了drivers的字符设备下,即char文件夹下

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers$ mkdir char/helloworld

写入驱动c文件 helloworld.c

s2.构建镜像时的各模块的设置

构建内核镜像时,需要编译的模块,是从~/Android/rk_android11.0_sdk/kernel/Kconfig这个设置文件读取的,而这个Kconfig文件又汇总了,kernel内其他模块的Kconfig文件
所以,对于我们的hellworld驱动,也要加入Kconfig文件

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers$ cd char/helloworld
ice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers/char/helloworld$ touch Kconfig

helloworld文件夹的Kconfig文件中写入如下内容

config helloworld
        bool "hellworld support"
        default y
        help
                helloworld Kconfig

因为helloworld文件夹,在drivers/char文件夹内,要在char文件夹的Kconfig中引入helloworld文件夹的Kconfig文件

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers/char$ vi Kconfig 

文件内加入一行:

source "drivers/char/helloworld/Kconfig"



至此,构建内核镜像的所有设置,都在各级的Kconfig中写好了,下面使Kconfig生效。
进入kernel文件夹,制作总的config文件

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel$ make menuconfig




出现了以上的图说明我们Kconfig设置成功了。
此时,会在kernel文件夹下生成一个汇总的.config隐藏文件
如图所示:

文件的内容如下:

这里 CONFIG_helloworld=y 是我们hellowold文件夹里的Kconfig里 default y设置出来的

s3. 根据设置,确定编译构建内核的步骤

构建内核镜像时,设置是记录在各级Kconfig文件,根据这些设置对应的编译步骤是记录在各级的Makefile中的。

helloworld文件夹中插入Makefile

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers/char/helloworld$ vi Makefile 

Makefile插入如下代码

obj-$(CONFIG_helloworld)        += helloworld.o # 此CONFIG_helloworld变量是来自于上一步中新生成的那个在kernel文件夹下的.config文件

即:

helloworld是在drivers/char文件夹下的,需要在char文件夹的Makefile中加入编译helloworld模块的操作步骤

obj-$(CONFIG_helloworld)        += helloworld/


至此Makefile是设置完成了。

s4:构建内核镜像

很简单,进入android源码文件夹,根据自己的需求制作所需的镜像。
最终构建镜像时,设置一下屏幕文件的参数,文件在以下文件夹中

rk3568 的屏幕文件是

我需要的是内核镜像,因为驱动是在内核镜像里的,当驱动更新时,需要把内核镜像更新。

安卓系统里不同的镜像的功能介绍参考一个短视频(10min):https://www.bilibili.com/video/BV1pv4y1K71W?p=2

开始build 构建镜像

ice@ubuntu:~/Android/rk_android11.0_sdk$ ./build.sh -CKA

内核镜像位置:

build.sh后面的参数含义

s5小结:

我们先在helloworld文件夹下,创建了3个文件:

接着我们把char文件加下的Kconfig文件和Makefile文件做了修改,使得helloworld能加入编译过程

最后我们是先使用make menuconfig 命令使所有Kconfig设置生效并生成.config文件

然后我们就开始构建镜像了

ice@ubuntu:~/Android/rk_android11.0_sdk$ ./build.sh -CKA # 此命令是内核镜像构建

生成的内核镜像路径在以下路径中

其他镜像的构建,请使用不同的参数,生成的img镜像也在别的路径中

m2.驱动编译成内核模块实战

s1.先建立一个文件夹放置驱动c文件和Makefile


helloworld2.c:

#include <linux/module.h>
#include <linux/kernel.h> 
static int helloworld_init(void)        
{
	printk("helloworld2_init\r\n");
	return 0;
}
static void helloworld_exit(void)    
{
	printk("helloworld2_exit\r\n");
}

module_init(helloworld_init);    
module_exit(helloworld_exit);  

Makefile:


obj-m += helloworld2.o
KDIR :=/home/ice/Android/rk_android11.0_sdk/kernel/  # 用的是安卓11源码的内核
PWD ?= $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) ARCH=arm64 $(KDIR).config modules  # 注意此处多了ARCH参数和 ".config"文件参数


.PHONY:clean
clean:
	make -C $(KDIR) M=$(PWD) clean

s2.生成Makefile所需的.config文件

进入kernel文件夹,制作总的config文件

ice@ubuntu:~/Android/rk_android11.0_sdk/kernel$ make menuconfig  # 此命令会在此文件夹下生成.config文件

成功后弹出以下界面:

退出此界面后,我们看看是否生成了我们需要的.config文件

生成了,下面开始编译ko文件

s3.编译ko文件(make命令)

s4.把ko文件传至开发板

此处请先确保开发板的安卓镜像已经烧写成功,否则需要阅读step5:烧写镜像至开发板部分

电脑usb连接 rk3568开发板,用MobaXterm客户端,通过com串口访问开发板控制台。

我是在开发板里新建了一个文件夹:

把驱动ko文件传至此文件夹,这个过程有点曲折,步骤如下:

1.我先是把helloworld2.ko文件放到了win10的任意文件夹内,我的是z:盘里了
2.通过adb push命令把文件传送至开发板的安卓系统里

传好的结果如下图

s5.加载驱动(insmod命令)

首先要进入root权限,运行 su 命令

其次进入ko文件所在文件夹,运行insmodrmmod命令加载和卸载驱动

step5:烧写镜像至开发板

烧写过程完全参照bilibili教程 (9min):

链接:
https://www.bilibili.com/video/BV1pv4y1K71W?p=4

烧写工具下载链接:

链接: https://pan.baidu.com/s/1m2H_s12ifb3EDIyoPG0hhQ?pwd=gdjh
提取码: gdjh

step6:查看驱动是否运行成功

电脑usb连接 rk3568开发板,用MobaXterm客户端,通过com串口访问开发板控制台,通过dmesg命令查看开发板启动时,我们的驱动是否运行成功。

这个过程参考视频链接 (4min):
https://www.bilibili.com/video/BV1744y1u779/?p=11

有关android驱动开发从零到一的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  6. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  7. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  8. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  9. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  10. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

随机推荐