移植helloworld驱动模块到openwrt系统

一、OpenWRT中的驱动
   Openwrt源码中,所有扩展的软件包都在package目录下,自己添加的应用放在该目录下。
   所有扩展的内核驱动都在package/kernel目录下,自己添加的驱动放在该目录下。

二、添加驱动步骤
在package/kernel目录下添加一个helloworld文件夹
在helloworld添加一个Makefile文件。具体Makefile怎么写,我们先看两个kernel中自带的驱动的Makefile文件。
I2C驱动

#
# Copyright (C) 2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#   I2C驱动

#包含上两级目录配置
include $(TOPDIR)/rules.mk          # TOPDIR : /openwrt
include $(INCLUDE_DIR)/kernel.mk    # INCLUDE_DIR: /openwrt/include

PKG_NAME:=i2c-gpio-custom           #驱动名字
PKG_RELEASE:=2                      #Makefile的版本号

include $(INCLUDE_DIR)/package.mk   #包含上一级目录配置

# make menuconfig时在配置界面上显示的方式
define KernelPackage/i2c-gpio-custom
  SUBMENU:=I2C support                 #显示的子选项
  TITLE:=Custom GPIO-based I2C device  #显示的内容
  DEPENDS:=@GPIO_SUPPORT +kmod-i2c-core +kmod-i2c-gpio  #依赖于其他模块
  FILES:=$(PKG_BUILD_DIR)/i2c-gpio-custom.ko    #生成的目标文件
  KCONFIG:=
endef

define KernelPackage/i2c-gpio-custom/description
 Kernel module for register a custom i2c-gpio platform device. #帮助时显示的内容
endef

EXTRA_KCONFIG:= \
    CONFIG_I2C_GPIO_CUSTOM=m    #编译成模块

# 无需更改
EXTRA_CFLAGS:= \
    $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
    $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \

# 无需更改
MAKE_OPTS:= \
    ARCH="$(LINUX_KARCH)" \            #CPU架构 
    CROSS_COMPILE="$(TARGET_CROSS)" \  #交叉编译工具
    SUBDIRS="$(PKG_BUILD_DIR)" \
    EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
    $(EXTRA_KCONFIG)

#编译前的准备
define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/  #PKG_BUILD_DIR:编译时的目录,对应于驱动就是 build_dir/target-**/linux-**/
endef

#编译
define Build/Compile
    $(MAKE) -C "$(LINUX_DIR)" \
        $(MAKE_OPTS) \
        modules
endef

#完成前面定义后,必须使用 eval 函数实现各种定义, KernelPackage代表是内核驱动模块,Package表示应用程序
$(eval $(call KernelPackage,i2c-gpio-custom))


RTC驱动

#
# Copyright (C) 2006-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#   RTC驱动

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=rtc-rv5c386a
PKG_RELEASE:=1

include $(INCLUDE_DIR)/package.mk

define KernelPackage/rtc-rv5c386a
  SUBMENU:=Other modules
  DEPENDS:=@TARGET_brcm47xx
  TITLE:=Driver for RTC RV5C386A (used in WL-700gE and WL-HDD)
  AUTOLOAD:=$(call AutoLoad,70,rtc)
  FILES:=$(PKG_BUILD_DIR)/rtc.ko
endef

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

#有时候CROSS_COMPILE、ARCH、SUBDIRS、EXTRA_CFLAGS会被独立成一个变量,然后再去引用
define Build/Compile
    $(MAKE) -C "$(LINUX_DIR)" \
        CROSS_COMPILE="$(TARGET_CROSS)" \
        ARCH="$(LINUX_KARCH)" \
        SUBDIRS="$(PKG_BUILD_DIR)" \
        EXTRA_CFLAGS="$(BUILDFLAGS)" \
        modules
endef

$(eval $(call KernelPackage,rtc-rv5c386a))

 


根据上面的注释和解释,并对比两份Makefile,我们发现写的基本结构都是相似的,所以我们可以根据上面的模板来自行写一份。
以I2C为模板:

#
# Copyright (C) 2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=helloworld
PKG_RELEASE:=2

include $(INCLUDE_DIR)/package.mk

define KernelPackage/helloworld
  SUBMENU:=Other modules
  TITLE:=HelloWorld
  FILES:=$(PKG_BUILD_DIR)/helloworld.ko
  KCONFIG:=
endef

define KernelPackage/helloworld/description
 Kernel module for register helloworld.
endef

EXTRA_KCONFIG:= \
    CONFIG_HELLOWORLD=m

EXTRA_CFLAGS:= \
    $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(EXTRA_KCONFIG)))) \
    $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(EXTRA_KCONFIG)))) \

MAKE_OPTS:= \
    ARCH="$(LINUX_KARCH)" \
    CROSS_COMPILE="$(TARGET_CROSS)" \
    SUBDIRS="$(PKG_BUILD_DIR)" \
    EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \
    $(EXTRA_KCONFIG)

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Build/Compile
    $(MAKE) -C "$(LINUX_DIR)" \
        $(MAKE_OPTS) \
        modules
endef

$(eval $(call KernelPackage,helloworld))



基本上就是I2C改成helloworld就OK了!

3、在helloworld文件夹下再新建一个src文件夹,在src下新建一个Kconfig文件。文件内容:

# 该文件是make menuconfig显示界面会读取的文件
config HELLOWORLD
    tristate "HelloWorld driver"
    default n
    help
      This is an HelloWorld Driver!


再新建一个Makefile文件,内容为:

obj-${CONFIG_HELLOWORLD}    += helloworld.o


最后新建一个helloworld.c的驱动文件,内容为:

#include <linux/module.h>
#include <linux/kernel.h>

//insmod会执行该函数
static int __init helloworld_init(void)
{
    printk("helloworld driver init !\n");
    return 0;
}
//rmmod会执行该函数
static int __exit helloworld_exit(void)
{
    printk("helloworld driver exit !\n");
    return 0;
}

//声明出入口函数
module_init(helloworld_init);
module_exit(helloworld_exit);
MODULE_AUTHOR("YANG");
MODULE_LICENSE("GPL");


4、接下来就是编译了
先make menuconfig将驱动配置一下。

 

 

保存后执行
make package/kernel/helloworld/compile V=99

 

编译出来的驱动模块在openwrt/bin/ramips/packages/kernel/kmod-helloworld_4.4.7-2_ramips_24kec.ipk

 

 

拷贝ipk安装包并运行

运行lsmod命令可以查看当前模块:

lsmod

 

运行后重启板子或者vsftpd服务即可传输文件(其实直接用也行,要是不行就做这一步),传输完ipk安装包后进入到ipk安装包所在目录,使用opkg安装:

./bin/ar71xx/packages/base/kmod-helloworld_4.4.60-2_ar71xx.ipk

opkg install kmod-helloworld_4.4.60-2_ar71xx.ipk

 

然后分别运行以下两条命令安装和:

insmod helloworld.ko

lsmod

运行dmesg命令查看内核缓冲区即可看到打印内容

dmesg

卸载模块:

rmmod helloworld.ko

顺便提一下如果想要卸载刚才装的ipk安装包的软件,运行以下命令

opkg list_installed

查看安装软件的列表,然后运行opkg remove xxxx(xxxx为列表里的名字),原来ipk安装包的名字是无效的噢。

 

 

posted @   江南王小帅  阅读(166)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示