12.添加OpenWrt包概述
本次实验的目的
掌握如何添加自己的驱动程序和应用程序
了解OpenWrt中Makefile的约定
12.1 简介
OpenWrt是一个比较完善的嵌入式Linux开发平台,有超过4000个无线路由器应用软件包。 我们可以在其基础上缩小软件包,扩大其应用范围。 在OpenWrt中减少软件包是非常方便的,按照OpenWrt协议就可以非常简单地完成。 添加的软件包可以是可下载的开源软件或自行开发的软件。 为了添加软件包,需要在package目录下创建一个目录,用于包含软件包的各种信息以及OpenWrt构建相关的文件。 然后创建一个Makefile来建立与OpenWrt的关系。 Makefile需要遵守OpenWrt协议。 另外,您可以创建一个patches目录来保存补丁文件,并对下载的源代码进行适当的更改。
12.2 Makefile句型
我们先介绍一下Makefile的基本约定。
12.2.1 导入文件
OpenWrt 使用三个 makefile 子文件,即:
包括 $(TOPDIR)/rules.mk
包括 $(INCLUDE_DIR)/kernel.mkin 包括 $(INCLUDE_DIR)/package.mk
这些 makefile 子文件确定了软件包如何以及如何添加到 OpenWrt 中。 $(TOPDIR)/rules.mk 通常位于 Makefile 的开头,当软件包为内核时,$(INCLUDE_DIR)/kernel.mk 文件必不可少,$(INCLUDE_DIR)/package.mk 通常位于软件包基本信息已完成重新引入。
12.2.2 编译软件包的基本信息
软件包的信息以PKG_开头,其含义和作用如下:
PKG_NAME代表包名,在menuconfig和ipkg中都可以看到。 PKG_VERSION 表示软件包版本号。
PKG_RELEASE代表Makefile的版本号。
PKG_SOURCE 表示源代码的文件名。
PKG_SOURCE_URL表示源代码的下载网站位置。 @SF 表示 sourceforge 网站,@GNU 表示 GNU 网站,@GNOME、@KERNEL。
PKG_MD5SUM代表源代码文件的验证码。 用于验证包是否正确下载。 PKG_CAT表示源代码文件的解压方式。 包括zcat、bzcat、unzip等。PKG_BUILD_DIR表示包编译目录。 它的父目录是$(BUILD_DIR)。 如果没有指定,
默认为 $(BUILD_DIR)/$(PKG_NAME)/$(PKG_VERSION)。
12.2.3 编译包定义
应用程序和内核驱动程序模块的定义不同。 应用软件包使用Package,内核驱动模块使用KernelPackage。
1)。 应用编译包定义
应用程序的编译包以Package/开头,后跟软件名称。 Package定义中的软件名称可以与软件包名称不同,但可以进行多个定义。 下面$(PKG_NAME)的使用只是一种标识,并不是$(PKG_NAME)的真正使用嵌入式系统软件教程,如Package/$(PKG_NAME)。
SECTION表示包的类型,保留。
CATEGORY是分类的意思,可以在makemenuconfig的菜单下找到。
TITLE 用于对包的简短描述。
描述用于包的详细描述,已被弃用。 如果使用DEscriptION,会提示“errorDEscriptION:=isobsolete, usePackage/PKG_NAME/description”。
URL 表示包的下载位置。
MAINTAINER 的意思是维护者、选项。
DEPENDS 表示与其他软件的依赖关系。 即在编译或安装其他软件时,需要进行解释。 如果有多个依赖项,每个依赖项需要用空格分隔。 在依赖之前使用+号表示默认显示,即未选中对象时才会显示,使用@表示默认不显示,即仅在之后显示选择依赖对象。
用户空间应用程序包中的内核驱动程序模块没有 AUTOLOAD 参数。 如果需要在启动时手动运行应用软件,则需要在/etc/init.d中添加相应的脚本文件。 脚本文件需要 START 参数来指示启动时的优先级。 如果在启动过程开始后关闭,则需要进一步设置STOP参数。
如果 STOP 参数存在,则其值必须小于 START。 脚本文件需要两个函数,start()和stop(),start()是执行程序,stop()是关闭程序。 关闭程序通常需要执行killall命令。 根据/etc/rc.d/S10boot规定,加载内核驱动模块的优先级为10,对于需要使用自己设计的内核驱动模块的程序来说,START的值必须小于10。 从/etc/rc.d/S40network也可知,使用网络通信的程序的START值必须小于40。
包/$(PKG_NAME)/conffiles
此包安装的配置文件,每行一个。 如果文件末尾使用/,则表示为目录。 用于备份配置文件指令,在执行sysupgrade命令时会用到。
包/$(PKG_NAME)/描述
封装的详细描述,取代了上面提到的DEscriptION的详细描述。
构建/准备
编译规划的方式,无需描述从网上下载的软件包。 对于非从网上下载或自行开发的软件包,必须说明编译方法。 通常的规划方式是:
定义构建/准备
mkdir -p $(PKG_BUILD_DIR)
$(CP)./src/*$(PKG_BUILD_DIR)/
恩德夫
按照OpenWrt的习惯,通常自己设计的程序都放在src目录下。 构建/配置
Automake中需要./configure,所以这种配置方式主要是针对需要配置的软件包而设计的,对于自行开发的软件包这里可能不再赘述。 如果需要使用这个定义嵌入式系统软件教程,请参考dropbear。 Build/Compile编译方法,如果没有特殊说明,可以不定义。 如果没有定义,将使用默认的编译方法Build/Compile/Default。
自行开发的软件包可以考虑使用以下定义。
定义构建/编译
$(MAKE)-C$(PKG_BUILD_DIR)\
$(TARGET_CONFIGURE_OPTS)CFLAGS="$(TARGET_CFLAGS)
-I$(LINUX_DIR)/包括”
结尾
包/$(PKG_NAME)/安装
软件包的安装方法包括一系列将编译好的文件复制到指定位置。 调用时会带一个参数,该参数是嵌入式系统的镜像文件系统目录,所以$(1)表示嵌入式系统的镜像目录。 通常可以采用以下方式:
定义包/$(PKG_NAME)/install
$(INSTALL_DIR)$(1)/usr/bin
$(INSTALL_BIN)$(PKG_BUILD_DIR)/$(PKG_NAME)$(1)/usr/bin/endef
INSTALL_DIR 和 INSTALL_BIN 是在 $(TOPDIR)/rules.mk 文件中定义的,因此此 Makefile 必须导入 $(TOPDIR)/rules.mk 文件。
INSTALL_DIR:=install-d-m0755 表示创建一个用户可以读、写、执行的目录,其他用户也可以读、执行。
INSTALL_BIN:=install-m0755表示编译后的文件存放在镜像文件目录下。
如果用户空间的应用软件需要在启动时手动运行,则需要在安装方法描述中减少手动脚本文件安装和配置文件安装方法。 例如:
定义包/mountd/安装
$(INSTALL_DIR)$(1)/sbin/$(1)/etc/config/$(1)/etc/init.d/$(INSTALL_BIN)$(PKG_BUILD_DIR)/mountd$(1)/sbin/$( INSTALL_DATA)./files/mountd.config$(1)/etc/config/mountd$(INSTALL_BIN)./files/mountd.init$(1)/etc/init.d/mountdendef
安装文件放在files子目录下,不要与源代码文件目录src混在一起,以增强可读性。
使用清晰的文件扩展名可以更轻松地安装和识别文件。
包/$(PKG_NAME)/preinst
软件包安装的预处理方式采用脚本语言,因此第一行定义需要如下格式#!/bin/sh
调用时带入的参数是嵌入式系统的图像目录。
包/$(PKG_NAME)/postinst
该软件包的安装后处理方法采用脚本语言。
包/$(PKG_NAME)/prerm
该软件包删除了预处理方法并使用脚本语言。
包裹/$(PKG_NAME)/postrm
删除软件包后的处理方法采用脚本语言。
2)。 内核驱动模块包定义
Linux分为内核空间和用户空间。 开发者开发的内核部分可以直接添加到Linux Kernel程序中,也可以生成内核模块以便在需要时方便地插入到内核中。 OpenWrt 通常希望开发人员生成内核模块并在 Linux 启动后手动加载它们或使用 insmod 命令手动加载它们。 内核模块以KernelPackage开始,其他与通常的应用软件包基本相同。
在内核驱动模块定义中降低:
SUBMENU 指示子菜单的位置。 在$(INCLUDE)/kernel.mk中,CATEGORY被定义为内核模块的kernelmodules,因此menuconfig中内核模块的主菜单是kernelmodules,然后还有一个子菜单$(SUBMENU)。 在子菜单下,您可以看到名为 kmod-$(PKG_NAME) 的项目。
DEFAULT表示直接编译进内核或者形成内核模块,y表示直接编译进内核,m表示形成内核模块。
AUTOLOAD表示手动放入内核,通常表示为:
自动加载:=$(callAutoLoad,$(优先级),$(AUTOLOAD_MODS))
AutoLoad的第一个参数$(PRIORITY)是优先级,01是最高优先级,99是最后加载。 手动加载可以在/etc/modules.d目录下看到,第二个参数$(AUTOLOAD_MODS)模块名称,每个模块名称之间用空格字符分隔。 可以同时加载多个内核模块。
开发过程中最好不要使用手动加载,严格调试后再使用,这样可以减少调试的工作量。
12.2.4 用法定义
完成上述定义后,必须使用eval函数来实现各种定义。 其格式为:
对于常见的应用程序包
$(eval $(callPackage,$(PKG_NAME)))
或用于内核驱动程序模块
$(eval $(callKernelPackage,$(PKG_NAME)))
如果一个软件包有多个程序,例如:一个应用程序有自己的内核驱动模块,该模块使用
PKG_NAME 需要灵活。 可以设计多个评估函数。 它也可以被视为多个包。
如果你听到这个感觉比较晦涩的话,没关系,把这个当作一个小指南,旁边学习一下就明白意思了,你可以回头看一下这个小指南,暂时不做存在。
注:如果你完全不懂Makefile或者不熟悉,可以参考我们提供的“附录:Makefile学习”文件夹中的文件进行学习!