当前位置:   article > 正文

Linux Kernel ccflags/Android 12 GKI_gki内核

gki内核

ccflags

Makefile笔记
外部模块头文件的检索:当编译的目标模块依赖多个头文件时,kbuild对头文件的搜索位置有这样的规定:

(1) 直接放置在 Makefile 同在的目录下,在编译时当前目录会被添加到头文件搜索目录。
(2) 放置在系统目录,这个系统目录是源代码目录中的 include,注意是源代码目录而不是系统目录的。
(3) 与通用的 Makefile 一样,使用 -I$ (DIR) 来指定,不同的是,编译选项的变量固定为 ccflag,当前 Makefile 是镶嵌到 Kbuild 系统中,ccflags-y += -I$(DIR)/include,kbuild就会将 $(DIR)/include 目录添加到编译时的头文件搜索目录中。一般使用"+="来进行追加赋值,各个Makefile中加的只影响自己的编译。

以源码中linux-source-4.15.0为例

模块A:
~/linux-source-4.15.0/linux-source-4.15.0/drivers/staging/most/hdm-usb/
hdm_usb.c Kconfig Makefile

模块B:
~linux-source-4.15.0/linux-source-4.15.0/drivers/staging/most/mostcore/
core.c  Kconfig  Makefile  mostcore.h
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

若模块A需要调用模块B中的函数,则需要在模块A中的Makefile使用到ccflag-y,在头文件中引用模块B函数定义的头文件

模块A:
Makefile
obj-$(CONFIG_HDM_USB) += hdm_usb.o

ccflags-y += -Idrivers/staging/most/mostcore/
ccflags-y += -Idrivers/staging/most/aim-network/

hdm_usb.c
#include "mostcore.h"

static void wq_clear_halt(struct work_struct *wq_obj){
    ...
	most_stop_enqueue(&mdev->iface, channel);
	most_resume_enqueue(&mdev->iface, channel);

模块B:
mostcore.h
void most_stop_enqueue(struct most_interface *iface, int channel_idx);
void most_resume_enqueue(struct most_interface *iface, int channel_idx);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

compile

如果ccflag的路径没有写对的话,去引用头文件则会报错,

fatal error: 'cam_sensor_io.h' file not found
  • 1

如果显示如下ld 链接的时候未定义的符号引用问题

ld.lld: error: undefined symbol: cam_sensor_power_up
  • 1

  因为在之前的高通平台上使用ccflags没有类似问题,起初是以为ccflags在内核版本变更上可能会有新特性,但没有找到类似的答案,接着就看了qcom camera kernel的变化,发现Android12下Makefile将camera编译成了camera.ko,
  尝试删除out/target/product/xxx/obj/kernel/msm-5.4/techpack/camera/drivers之前编译生成的产物,修改代码将camera目录下都使能obj-y编译后,则编译调用目前都还正常,obj-y生成built-in.o,Kbuild编译所有的obj-y文件,并调用”$(LD) -r”把所有这些文件合并到built-in.o文件。这个built-in.o会被上一级目录的Makefile使用,最终链接到vmlinux中,所以之前模块化后是没有链接到一起,所以导致报了ld的错误。看到都是ko的模块间调用可以使用EXPORT_SYMBOL 非static函数定义 + extern的方式,这个后续有时间我在尝试一下,需要注意模块间的加载顺序。

export CONFIG_SPECTRA_CAMERA=y

ifeq ($(CONFIG_SPECTRA_CAMERA),m)
$(info "SPECTRA CAMERA IS BUILT AS DLKM")
BOARD_VENDOR_KERNEL_MODULES +=  $(KERNEL_MODULES_OUT)/camera.ko
endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

那为什么Android12上会出现camera.ko这个的变化呢,主要是GKI的引入

后续这里有尝试了第二种方法,将我们的驱动以ko模块的方式编译,通过EXPORT_SYMBOL的方式传递接口

techpack/camera/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c
EXPORT_SYMBOL(cam_sensor_power_up);

drivers/ourdriver/ourdrvier.h
extern int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl);

Makefile 需要注意多个.o编译成一个模块
obj-m += xxx.o
xxx-objs := xxx1.o xxx2.o  or  xxx-y := xxx1.o xxx2.o
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

GKI

通用内核映像
  Android内核中运行的代码中有多达 50% 是树外代码(并非来自上游 Linux 和 AOSP 通用内核),供应商通过修改内核源代码并添加设备驱动程序,添加了对 SoC 和外围设备的支持。几乎所有设备都具有自定义内核。这就导致了内核碎片化问题。
  通用内核映像 (GKI) 项目通过统一核心内核并将 SoC 和板级支持从核心内核移至可加载模块中,解决了内核碎片化问题。GKI 内核为内核模块提供了稳定的内核模块接口 (KMI),因此模块和内核可以独立进行更新。

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/311730
推荐阅读
相关标签
  

闽ICP备14008679号