首页
社区
课程
招聘
玩转Android10源码开发定制(11)内核篇之安卓内核模块开发编译
2021-1-7 11:50 12943

玩转Android10源码开发定制(11)内核篇之安卓内核模块开发编译

2021-1-7 11:50
12943

一、 开发前期准备

本文中使用的是linageOs源码中下载的oneplus3 安卓10内核源码进行研究测试。交叉编译链使用的是linageOs源码中的交叉编译链。

 

lineageOs源码中oneplus3内核源码位置路径:

1
/home/qiang/lineageOs/kernel/oneplus/msm8996

lineageOs源码中交叉编译目录位置路径:

1
/home/qiang/lineageOs/prebuilts/gcc/linux-x86

为了方便研究测试,不破坏lineageOs中的内核源码结构。我新建一个目录专门存放内核源码、内核模块源码。并将内核源码拷贝到该目录。

 

本文后续测试的内核源码目录路径:

1
home/qiang/myproject/kernel/oneplus3/msm8996

本文后续内核模块编写存放目录路径:

1
/home/qiang/myproject/kernel/oneplus3/modules

二、编译内核源码

  1. 找到oneplus3设备的内核源码配置

安卓源码中device/厂商/手机型号/BoardConfig.mk文件中配置了内核源码路径和编译配置文件。因此在device/oneplus/oneplus3/BoardConfig.mk中存放了相关的内核配置信息,如下所示:

1
2
3
4
5
6
7
BOARD_KERNEL_BASE := 0x80000000
BOARD_KERNEL_PAGESIZE := 4096
BOARD_KERNEL_TAGS_OFFSET := 0x02000000
BOARD_RAMDISK_OFFSET     := 0x02200000
BOARD_KERNEL_IMAGE_NAME := Image.gz-dtb
TARGET_KERNEL_SOURCE := kernel/oneplus/msm8996
TARGET_KERNEL_CONFIG := lineageos_oneplus3_defconfig

以上TARGET_KERNEL_CONFIG变量指定了oneplus3内核的编译配置文件名为:lineageos_oneplus3_defconfig

 

在内核源码中编译配置文件一般存放在路径arch/处理器平台/configs下面。由于一加3手机为arm64,所以在路径arch/arm64/configs下找到配置文件lineageos_oneplus3_defconfig。如下所示:

1
2
3
4
5
qiang@ubuntu:~/myproject/kernel/oneplus3/msm8996/arch/arm64/configs$ pwd
/home/qiang/myproject/kernel/oneplus3/msm8996/arch/arm64/configs
 
qiang@ubuntu:~/myproject/kernel/oneplus3/msm8996/arch/arm64/configs$ ls -la lineageos_oneplus3_defconfig
-rw-rw-r-- 1 qiang qiang 15001 1月   3 23:00 lineageos_oneplus3_defconfig
  1. 为编译配置添加内核可加载、卸载选项

由于编译内核模块的时候需要依赖于已经编译过的内核输出,并且内核需要配置为可加载才能正常编译内核模块。所以需要修改一下arch/arm64/configs/lineageos_oneplus3_defconfig,添加如下配置项。

1
2
3
4
# 开启内核模块可加载
CONFIG_MODULES=y
# 开启内核模块可卸载
CONFIG_MODULE_UNLOAD=y
  1. 配置编译内核源码脚本

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 设置编译平台为64位arm
export ARCH=arm64
export SUBARCH=arm64
# 配置arm64的交叉编译路径
export PATH=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH
# 配置32位arm的交叉编译路径
# 测试过程中32位的不设置居然编译不过
export PATH=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin:$PATH
 
# 设置64位交叉编译工具前缀
# 这个前缀其实就是交叉编译链路径/home/qiang/lineageOs/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin 下面的工具的公共前缀
export CROSS_COMPILE=aarch64-linux-android-
 
# 设置32位交叉编译工具前缀
# 这个前缀其实就是交叉编译链路径/home/qiang/lineageOs/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin 下面的工具的公共前缀
export CROSS_COMPILE_ARM32=arm-linux-androideabi-
 
# 通过make命令生成编译配置文件.config
# O=out指定输出目录  lineageos_oneplus3_defconfig:这个是oneplus3的内核编译配置
make  O=out lineageos_oneplus3_defconfig
 
#  执行内核编译
make -j2 O=out ARCH=arm64

以上脚本在终端难的一个一个的输入,我将上面的弄成一个make.sh文件,到时候直接执行。make.sh内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
 
# 切换到内核源码根目录去
cd ./msm8996
make mrproper
make clean
export ARCH=arm64
export SUBARCH=arm64
export PATH=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:$PATH
export PATH=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin:$PATH
export CROSS_COMPILE=aarch64-linux-android-
export CROSS_COMPILE_ARM32=arm-linux-androideabi-
make -j2 O=out lineageos_oneplus3_defconfig
make -j2  O=out ARCH=arm64

在终端执行make.sh之后就可以看到编译内核了,如下所示:

1
2
3
4
5
6
7
qiang@ubuntu:~/myproject/kernel/oneplus3$ ./make.sh
make[1]: Entering directory '/home/qiang/myproject/kernel/oneplus3/msm8996/out'
  GEN     ./Makefile
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf

编译完成之后,可以在目录/home/qiang/myproject/kernel/oneplus3/msm8996/out下面找到编译产生的文件和内核镜像。

三、编写helloworld模块

此处编写一个简单的HelloWorld模块进行研究测试。

  1. 创建helloworld.c模块源文件

    文件代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/sched.h>
    static int __init hello_init(void){
     printk(KERN_ALERT "Hello World!\n");
     return 0;
    }
    static void __exit hello_exit(void){
     printk(KERN_ALERT "See You,Hello World!\n");
    }
    module_init(hello_init);
    module_exit(hello_exit);
  2. 创建模块编译配置文件Makefile

Makefile如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 设置内核源码编译的输出目录
KERNEL_OUT=/home/qiang/myproject/kernel/oneplus3/msm8996/out
# 设置arm64交叉编译链工具路径
TOOLCHAIN=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
# 设置arm32交叉编译链工具路径
TOOLCHAIN32=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-
# 设置模块
obj-m := helloworld.o
# 编译命令配置
all:
    make ARCH=arm64 CROSS_COMPILE_ARM32=$(TOOLCHAIN32)  CROSS_COMPILE=$(TOOLCHAIN) -C $(KERNEL_OUT) M=$(shell pwd)  modules
# 清理编译命令
clean:
    make -C $(KERNEL_OUT) M=$(shell pwd) clean
  1. 在helloworld模块目录执行make命令进行编译

编译如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
qiang@ubuntu:~/myproject/kernel/oneplus3/modules/helloworldmodule$ pwd
/home/qiang/myproject/kernel/oneplus3/modules/helloworldmodule
 
qiang@ubuntu:~/myproject/kernel/oneplus3/modules/helloworldmodule$ ls -la
total 16
drwxrwxr-x 2 qiang qiang 4096 1月   5 21:18 .
drwxrwxr-x 6 qiang qiang 4096 1月   5 21:17 ..
-rw-rw-r-- 1 qiang qiang  310 1月   5 21:06 helloworld.c
-rw-rw-r-- 1 qiang qiang  498 1月   5 21:08 Makefile
 
qiang@ubuntu:~/myproject/kernel/oneplus3/modules/helloworldmodule$ make
make ARCH=arm64 CROSS_COMPILE_ARM32=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-  CROSS_COMPILE=/home/qiang/lineageOs/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- -C /home/qiang/myproject/kernel/oneplus3/msm8996/out M=/home/qiang/myproject/kernel/oneplus3/modules/helloworldmodule  modules
make[1]: Entering directory '/home/qiang/myproject/kernel/oneplus3/msm8996/out'
  CC [M]  /home/qiang/myproject/kernel/oneplus3/modules/helloworldmodule/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/qiang/myproject/kernel/oneplus3/modules/helloworldmodule/helloworld.mod.o
  LD [M]  /home/qiang/myproject/kernel/oneplus3/modules/helloworldmodule/helloworld.ko
make[1]: Leaving directory '/home/qiang/myproject/kernel/oneplus3/msm8996/out'

模块编译好之后就可以 adb push到手机,使用insmod加载模块进行测试验证了。
以后就可以通过写内核系统hook模块进行系统调用内核层拦截、写netfileter hook模块进行网络管控等等操作。

 

点我阅读原文


[培训]《安卓高级研修班(网课)》月薪三万计划

最后于 2021-4-12 22:07 被蟑螂一号编辑 ,原因:
收藏
点赞4
打赏
分享
最新回复 (5)
雪    币: 1867
活跃值: (3698)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
virjar 1 2021-1-7 12:17
2
0
雪    币: 1974
活跃值: (2325)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
对你何止爱 2021-1-7 14:28
3
0
雪    币: 6569
活跃值: (3823)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
LowRebSwrd 4 2021-1-7 15:16
4
0
雪    币: 187
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Ruinv6 2021-7-26 13:42
5
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
红豆牛奶冰 2022-11-9 11:28
6
0
游客
登录 | 注册 方可回帖
返回