第一次接觸到openwrt,真是被毀三觀啊,不要說makefile,連源代碼在哪裏都找不到,知道嵌入式系統水深,沒想到邁出第一步就沒過了脖子。好在旁邊有人指點,直接在芯片廠商提供的既有代碼上做二次開發,項目進展倒也完全滿足了前期計劃的目標。但是哥奔的就是嵌入式,這麼好的學習機會怎容錯過?!
目標:在芯片廠商提供的開發包上添加自己的用戶態模塊和內核態模塊,以使我們自己開發的代碼與芯片廠商的代碼儘可能隔離。
添加模塊編譯
在網上找了一下,很多關於編譯Openwrt系統的資料,不過這些事情芯片廠商提供的開發包都已經辦得妥妥了,但是沒有找到系統介紹的資料,添加一個包的介紹有不多,其中有兩個很有參考價值:
http://blog.csdn.net/lj627889343/article/details/7997463
http://kamikaze.openwrt.org/docs/openwrt.html#x1-460002.1.2
詳細步驟如下:
在package目錄下創建模塊目錄my_module,內含:
Makefile 用於建立於OpenWRT的聯繫,成爲OpenWRT的一個包
src 包含自己的代碼
src/hello.c 源代碼
src/Makefile 源代碼的Makefile
後續將主要講解一下目前的系統Makefile的理解:
include $(TOPDIR)/rules.mk 必須包含
#include $(INCLUDE_DIR)/kernel.mk 內核模塊包含,目前不需要
PKG_NAME:=my_module 包名稱,在menuconfig顯示
PKG_VERSION:=0.0.1 包版本號
PKG_BASE_NAME:=my_module 包名稱,在build_dir下面創建PKG_BASE_NAME-PKG_VERSION目錄,用於存放源代碼
#PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_BASE_NAME)-$(PKG_VERSION) 指定代碼存放路徑
#PKG_RELEASE:=1
#PKG_SOURCE_URL:=http://localhost
PKG_BUILD_DEPENDS:=
PKG_BIN_DIR= 上面註釋了三項,是爲了不讓OpenWRT去下載代碼(而從本地拷貝代碼,見後面說明)
include $(INCLUDE_DIR)/package-version-override.mk 不知道幹嘛用,應該是一定要的
include $(INCLUDE_DIR)/package.mk 不知道幹嘛用,應該是一定要的
ifeq ($(DUMP),) 不知道幹嘛用
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell $(SH_FUNC) grep '^CONFIG_GPON_' $(TOPDIR)/.config | md5s)
endif
define Package/$(PKG_NAME) 用於設置menuconfig的選項
SECTION:=application 不知道幹嘛用,類似的選項有net/sys/driver...應該是linux系統的分類
CATEGORY:=teddy menuconfig頂級目錄
TITLE:=the first module by teddy 本包的目錄項說明(目錄項名稱即包名稱)
URL:=http://www.teddy.com/ 不知道幹嘛用,估計用處不大
MAINTAINER:=teddy 不知道幹嘛用,估計用處不大
DEPENDS:= 依賴的包,還不會用
MENU:=1 目錄項使能,如果如果基礎模塊可以設爲0
endef
define Package/$(PKG_NAME)/description 不知道幹嘛用,估計用處不大
Teddy's First Package On OpenWRT.
endef
define Package/$(PKG_NAME)/config 結合config/Config.in設置比較複雜的目錄項,可以不用
menu "detail configurations" 第一個選項,由開發人員自行設置
depends on PACKAGE_$(PKG_NAME)
source "$(SOURCE)/config/Config.in"
endmenu
$(call Package/$(PKG_NAME)/override_version) 第二個選項,由系統提供,應該是另外指定版本號
$(call Package/$(PKG_NAME)/override_source_path) 第三個選項,有系統提供,應該是另外指定代碼存放路徑的
endef
CONFIGURE_ARGS +=
ifeq ($(CONFIG_mips),y) 不知道幹嘛用
CONFIGURE_ARGS += --enable-add_drv_cflags="-fno-pic -mno-abicalls -mlong-calls -G 0"
endif
define Build/Prepare 這個很關鍵,在上面取消了從網絡下載,由這裏的語句將src的代碼拷到指定位置
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Clean 清除語句,沒用過
@- rm -Rf $(PKG_BUILD_DIR)/ipkg*
@- [ -e $(PKG_BUILD_DIR)/Makefile ] && $(MAKE) -C $(PKG_BUILD_DIR) clean
$(call Build/Clean/Default)
endef
define Package/$(PKG_NAME)/install 忘記幹嘛用的了,好像是用來創建目錄的,沒有這句會導致編譯不過
$(INSTALL_DIR) $(1)/$(PKG_BIN_DIR)
endef
$(eval $(call BuildPackage,$(PKG_NAME))) 必須
另外還可以創建
config/Config.in
用於細節定義,如
menu "macros"
config FIRST_MACRO 這裏的config值可以被Makefile使用,但是還沒有發現源代碼可以用
bool "first macro defined in my module"
default y
config SECOND_MACRO
bool "second macro defined in my module"
default y
endmenu
也可以在menuconfig顯示出來,懷疑config XXXX是宏定義,還沒有試過
上面描述的手段應該不是openwrt希望的方法,但是作爲一般開發應該已經夠用了。