Linux设备驱动 ----helloworld.ko

毕业已经好多年了,从单片机到毕业后的安卓开发,虽然在上面工作了很多时间,但是总感觉自己缺点什么。总的来说对知识的储备其实不是那么充足,对一些深层次的东西理解也不是很透彻,当然自己也缺少一股冲劲与恒心。所以现在想在CSDN 上中记录对基础知识的一些巩固,对程序员而言真的是需要多看多写,才能对自己有所提高,不然到最后可能还是那个水平,废话可能有点多了........下面进入正题

最简单的驱动编译,注册--helloworld. 对于第一个自己的小程序大家都能都习惯于用helloworld 命名

helloworld.c 代码解析 
Makefile 
编译运行 
签名相关

 


helloworld.c

#include 
#include 
#include 

static int __init hello_init(void)
{
   printk(KERN_INFO "%s: Hello World init!\n", __func__);

   return 0;
}

static void __exit hello_exit(void)
{
  printk(KERN_INFO "%s: Hello World exit!\n", __func__);
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("StevenTao");

  代码很简单,一共就2个函数,hello_init和hello_exit,看字面意思大概就能看出来是什么意思了,注意的地方是,在Linux驱动中,入口是函数是定义在modile_init函数中的,也就是当我们insmod驱动的时候会调用到hello_init函数,然后打印出一条“Hello World init!”的log,当卸载驱动的时候会调用到hello_exit函数,然后打印出一条“Hello World exit!”的log。

Makefile

obj-m := helloworld.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
module:
	make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
	make -C $(KERNEL_DIR) M=$(PWD) clean

写的比较简单,为了便于理解,其实就是当在Linux下输入make的时候,会执行到“make -C $(KERNEL_DIR) M=$(PWD) modules” 执行make clean的时候会执行到对应的clean命令,想要进一步理解的可以自己深入学习下Makefile ,写得更规范

-C (KERNELDIR)指定了内核源码的位置,其中保存有内核的顶层makefile文件。M=(KERNELDIR)指定了内核源码的位置,其中保存有内核的顶层makefile文件。M=(PWD)指定了模块源码的位置 modules目标指向obj-m变量中设定的模块。
 

 

编译运行

steven@CH3UU0008:~/work/pie_master/kernel/msm-4.4/drivers/steven$ make
make -C /lib/modules/4.4.0-62-generic/build M=/home/platform/steven/work/pie_master/kernel/msm-4.4/drivers/steven modules
make[1]: Entering directory `/usr/src/linux-headers-4.4.0-62-generic'
  CC [M]  /home/platform/steven/work/pie_master/kernel/msm-4.4/drivers/steven/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: modpost: missing MODULE_LICENSE() in /home/platform/steven/work/pie_master/kernel/msm-4.4/drivers/steven/helloworld.o
see include/linux/module.h for more information
  CC      /home/platform/steven/work/pie_master/kernel/msm-4.4/drivers/steven/helloworld.mod.o
  LD [M]  /home/platform/steven/work/pie_master/kernel/msm-4.4/drivers/steven/helloworld.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.4.0-62-generic'

生成helloworld.ko驱动模块,然后把驱动加载到系统,但是在 Android 9.0 kernel 4.4 的环境中安装 ko 会发生下面的错误,应该是 ko 的签名存在问题。我们需要知道签过名的 ko 去安装就可以

在out 目录下全局搜这个ko 文件,发现有两个,一个是没签名的一个是签名的

steven@CH3UU0008:~/work/pie_master/out/target/product/hon660$ find . -name helloworld.ko
./dlkm/lib/modules/helloworld.ko
./obj/kernel/msm-4.4/drivers/steven/helloworld.ko

签过名的ko 存在 dlkm 目录下,所以这个才是我们需要的

insmod helloworld.ko
rmmod helloworld.ko
modinfo helloworld.ko

查看运行结果:

Linux设备驱动 ----helloworld.ko_第1张图片

insmod ko 时打出了 hello_init  的log, rmmod ko 时打出了 hello_exit 的log.

签名相关问题

qualcomm  source code kernel 签名默认使用的是kernel module 的私钥,不是 honeywell 的私钥,所以没签名的ko 安装到手机会提示签名问题。我们需要做下面的一些修改使用签过名的ko 安装才可以。

  • device/qcom/common / dlkm/AndroidKernelModule.mk

MODSECKEY := $(KERNEL_OUT)/certs/signing_key.pem

修改成下面

KMOD_SIG_KEY=`cat $(KERNEL_OUT)/.config | grep CONFIG_MODULE_SIG_KEY | cut -d'=' -f2 | sed 's/\"//g'`
           MODSECKEY := $(ANDROID_BUILD_TOP)/kernel/msm-4.4/$(KMOD_SIG_KEY)

  • 将 kernel 私钥 放到 kernel\msm-4.4\certs,以供签名使用
  • 在 config 添加 MODULE_SIG_KEY

kernel/msm-4.4/arch/arm64/configs/hon660-perf_defconfig

第一个最基本的 kernel  ko driver 到这里就介绍完了,当然你也可以之际将驱动文件编译到 zimage (boot.img),在 Makefile 中将 obj-m 修改为 obj-y 就可以。

是不是很简单,就是很久不接触底层生疏了

 

你可能感兴趣的:(Kernel)