目录
- 安卓驱动开发过程
- 机器介绍
- 步骤
- step1:下载android11源码
- 一、谷歌的源码下载:
- 二、rk3568提供的源码下载:
- step2:编译android源码(make命令)
- 1.编译的几个选项
- 2.开始编译
- step3:编写驱动文件
- step4:开始构建镜像(build.sh)
- 两种驱动编译方式
- 1.驱动编译到内核介绍:
- 2.驱动编译成内核模块介绍:
- m1.驱动编译到内核实战
- s1.drivers文件夹内创建自己的驱动文件夹并写入驱动文件。
- s2.构建镜像时的各模块的设置
- s3. 根据设置,确定编译构建内核的步骤
- s4:构建内核镜像
- s5小结:
- m2.驱动编译成内核模块实战
- s1.先建立一个文件夹放置驱动c文件和Makefile
- s2.生成Makefile所需的.config文件
- s3.编译ko文件(make命令)
- s4.把ko文件传至开发板
- s5.加载驱动(insmod命令)
- step5:烧写镜像至开发板
- step6:查看驱动是否运行成功
安卓驱动开发过程
机器介绍
本人是在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 gitice@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-repoice@ubuntu:~/Android$ mkdir .repoice@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_r55ice@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_sdkice@ubuntu:~/Android/rk_android11.0_sdk$ source build/envsetup.shice@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 #include 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/helloworldice@ubuntu:~/Android/rk_android11.0_sdk/kernel/drivers/char/helloworld$ touch Kconfig
helloworld文件夹的Kconfig文件中写入如下内容
config helloworldbool "hellworld support"default yhelphelloworld 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 #include 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.oKDIR :=/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:cleanclean: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文件所在文件夹,运行insmod
和rmmod
命令加载和卸载驱动
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