# $FreeWRT$
#-
# This file is part of the FreeWRT project. FreeWRT is copyrighted
# material, please see the LICENCE file in the top-level directory
# or at http://www.freewrt.org/license for details.

include $(TOPDIR)/rules.mk

LINUX_VERSION:=2.4.33.3
LINUX_RELEASE:=1
LINUX_KERNEL_MD5SUM:=ab5940e952c3e337128b9f97c51eab94

KERNEL:=unknown
ifneq (,$(findstring 2.4.,$(LINUX_VERSION)))
KERNEL:=2.4
endif
ifneq (,$(findstring 2.6.,$(LINUX_VERSION)))
KERNEL:=2.6
endif

ifeq ($(KERNEL),2.6)
LINUX_KMOD_SUFFIX=ko
else
LINUX_KMOD_SUFFIX=o
endif

MODULES_SUBDIR := lib/modules/$(LINUX_VERSION)
LINUX_BUILD_DIR := $(BUILD_DIR)/linux-$(KERNEL)-$(BOARD)
LINUX_DIR := $(LINUX_BUILD_DIR)/linux-$(LINUX_VERSION)
LINUX_KERNEL := $(LINUX_BUILD_DIR)/vmlinux
LINUX_TARGET_DIR := $(LINUX_BUILD_DIR)/root

IPKG_KERNEL := IPKG_TMP=$(BUILD_DIR)/tmp IPKG_INSTROOT=$(LINUX_TARGET_DIR) IPKG_CONF_DIR=$(LINUX_BUILD_DIR) $(SCRIPT_DIR)/ipkg -force-defaults -force-depends

LINUX_KARCH:=$(shell echo $(ARCH) | sed -e 's/i[3-9]86/i386/' \
	-e 's/mipsel/mips/' \
	-e 's/mipseb/mips/' \
	-e 's/powerpc/ppc/' \
	-e 's/sh[234]/sh/' \
	-e 's/armeb/arm/' \
)

KPKG_MAKEOPTS := IPKG="$(IPKG_KERNEL)" \
		BOARD="$(BOARD)" \
		KERNEL="$(KERNEL)" \
		TARGET_DIR="$(LINUX_TARGET_DIR)" \
		LINUX_BUILD_DIR="$(LINUX_BUILD_DIR)" \
		LINUX_DIR="$(LINUX_DIR)" \
		LINUX_VERSION="$(LINUX_VERSION)" \
		LINUX_RELEASE="$(LINUX_RELEASE)"

KMOD_BUILD_DIR := $(LINUX_BUILD_DIR)/linux-modules
MODULES_DIR := $(LINUX_BUILD_DIR)/modules/$(MODULES_SUBDIR)
TARGET_MODULES_DIR := $(LINUX_TARGET_DIR)/$(MODULES_SUBDIR)

KERNEL_IPKG:=$(LINUX_BUILD_DIR)/kernel_$(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)_$(ARCH).ipk
INSTALL_TARGETS := $(KERNEL_IPKG)
TARGETS := 


define KMOD_template
ifeq ($$(strip $(4)),)
KDEPEND_$(1):=m
else
KDEPEND_$(1):=$($(4))
endif

IDEPEND_$(1):=kernel ($(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)) $(foreach pkg,$(5),", $(pkg)")

PKG_$(1) := $(PACKAGE_DIR)/kmod-$(2)_$(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)_$(ARCH).ipk
I_$(1) := $(KMOD_BUILD_DIR)/ipkg/$(2)

ifeq ($$(KDEPEND_$(1)),m)
ifneq ($$(FWRT_PACKAGE_KMOD_$(1)),)
TARGETS += $$(PKG_$(1))
endif
ifeq ($$(FWRT_PACKAGE_KMOD_$(1)),y)
INSTALL_TARGETS += $$(PKG_$(1))
endif
endif

$$(PKG_$(1)): $(LINUX_DIR)/.modules-install
	rm -rf $$(I_$(1))
	$(SCRIPT_DIR)/make-ipkg-dir.sh $$(I_$(1)) ../control/kmod-$(2).control $(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE) $(ARCH)
	echo "Depends: $$(IDEPEND_$(1))" >> $$(I_$(1))/CONTROL/control
ifneq ($(strip $(3)),)
	mkdir -p $$(I_$(1))/lib/modules/$(LINUX_VERSION)
	$(CP) $(3) $$(I_$(1))/lib/modules/$(LINUX_VERSION)
endif
ifneq ($(6),)
	mkdir -p $$(I_$(1))/etc/modules.d
	for module in $(7); do \
		echo $$$$module >> $$(I_$(1))/etc/modules.d/$(6)-$(2); \
	done
	echo "#!/bin/sh" >> $$(I_$(1))/CONTROL/postinst
	echo "if [ -z \"\$$$${IPKG_INSTROOT}\" ]; then" >> $$(I_$(1))/CONTROL/postinst
	echo ". /etc/functions.sh" >> $$(I_$(1))/CONTROL/postinst
	echo "load_modules /etc/modules.d/$(6)-$(2)" >> $$(I_$(1))/CONTROL/postinst
	echo "fi" >> $$(I_$(1))/CONTROL/postinst
	chmod 0755 $$(I_$(1))/CONTROL/postinst
endif
	$(8)
	$(IPKG_BUILD) $$(I_$(1)) $(PACKAGE_DIR) $(MAKE_TRACE)
endef

# include kernel configuration, first try model specific if exist
# otherwise use generic root filesystem specific for this board

# squashfs with mini-fo overlay
ifeq ($(FWRT_TARGET_ROOTFS_SQUASHFS_OVERLAY),y)
MODELCONFIG:=$(shell test -f $(MODEL)/config/config.squashfs_overlay && echo y 2>/dev/null)
ifneq ($(strip $(MODELCONFIG)),)
include $(MODEL)/config/config.squashfs_overlay
else
include $(FS)/config/config.squashfs_overlay
endif
endif

# jffs2
ifeq ($(FWRT_TARGET_ROOTFS_JFFS2),y)
MODELCONFIG:=$(shell test -f $(MODEL)/config/config.jffs2 && echo y 2>/dev/null)
ifneq ($(strip $(MODELCONFIG)),)
include $(MODEL)/config/config.jffs2 
else
include $(FS)/config/config.jffs2
endif
endif


include $(TOPDIR)/mk/netfilter.mk
include $(TOPDIR)/mk/modules-$(KERNEL).mk

LINUX_SOURCE:=linux-$(LINUX_VERSION).tar.bz2
LINUX_SITE=http://www.us.kernel.org/pub/linux/kernel/v$(KERNEL) \
           http://www.us.kernel.org/pub/linux/kernel/v$(KERNEL) \
           http://www.kernel.org/pub/linux/kernel/v$(KERNEL) \
           http://www.de.kernel.org/pub/linux/kernel/v$(KERNEL)

KERNEL_IDIR:=$(LINUX_BUILD_DIR)/kernel-ipkg

$(TARGETS): $(PACKAGE_DIR)

$(PACKAGE_DIR):
	@mkdir -p $(PACKAGE_DIR)
	
$(DL_DIR)/$(LINUX_SOURCE):
	-mkdir -p $(DL_DIR)
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-download
	$(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_SOURCE) $(LINUX_KERNEL_MD5SUM) $(LINUX_SITE) $(MAKE_TRACE)

$(LINUX_DIR)/.unpacked: $(DL_DIR)/$(LINUX_SOURCE)
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-prepare
	-mkdir -p $(LINUX_BUILD_DIR)
	bzcat $(DL_DIR)/$(LINUX_SOURCE) | (cd $(LINUX_BUILD_DIR); tar xf - )
	rm -f $(BUILD_DIR)/linux
	ln -s $(LINUX_BUILD_DIR)/linux-$(LINUX_VERSION) $(BUILD_DIR)/linux
	touch $@

$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-patch
	[ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches $(MAKE_TRACE)
	[ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches $(MAKE_TRACE)
	[ -d $(MODEL)/patches ] && $(PATCH) $(LINUX_DIR) $(MODEL)/patches $(MAKE_TRACE)
ifeq ($(FWRT_TARGET_ROOTFS_SQUASHFS_OVERLAY),y)
ifneq ($(strip $(MODELCONFIG)),)
	$(CP) $(MODEL)/config/config.squashfs_overlay $(LINUX_DIR)/.config
else
	$(CP) $(FS)/config/config.squashfs_overlay $(LINUX_DIR)/.config
endif
endif
ifeq ($(FWRT_TARGET_ROOTFS_JFFS2),y)
ifneq ($(strip $(MODELCONFIG)),)
	$(CP) $(MODEL)/config/config.jffs2 $(LINUX_DIR)/.config
else
	$(CP) $(FS)/config/config.jffs2 $(LINUX_DIR)/.config
endif
endif
	touch $@

ifeq ($(KERNEL),2.4)
$(LINUX_DIR)/.configured: $(LINUX_DIR)/.patched
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-configure
	$(SED) "s,^CROSS_COMPILE.*,CROSS_COMPILE=$(KERNEL_CROSS),g;" \
	  $(LINUX_DIR)/Makefile  \
	  $(LINUX_DIR)/arch/*/Makefile
	$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_KARCH) oldconfig include/linux/compile.h include/linux/version.h $(MAKE_TRACE)
	$(MAKE) -C $(LINUX_DIR) CROSS_COMPILE="$(KERNEL_CROSS)" ARCH=$(LINUX_KARCH) dep $(MAKE_TRACE)
	touch $@
else
$(LINUX_DIR)/.configured: $(LINUX_DIR)/.patched
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-configure
	$(MAKE) -C $(LINUX_DIR) CROSS_COMPILE="$(KERNEL_CROSS)" ARCH=$(LINUX_KARCH) oldconfig prepare scripts $(MAKE_TRACE)
	touch $@
endif

$(LINUX_DIR)/vmlinux: $(LINUX_DIR)/.configured
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-compile
	$(MAKE) -C $(LINUX_DIR) CROSS_COMPILE="$(KERNEL_CROSS)" ARCH=$(LINUX_KARCH) PATH=$(TARGET_PATH) $(MAKE_TRACE)

$(LINUX_KERNEL): $(LINUX_DIR)/vmlinux
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-kernel-strip
	$(TARGET_CROSS)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S $< $@ $(MAKE_TRACE)
	touch -c $(LINUX_KERNEL)

$(LINUX_DIR)/.modules-compile:
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-modules-compile
	$(MAKE) -C "$(LINUX_DIR)" CROSS_COMPILE="$(KERNEL_CROSS)" ARCH=$(LINUX_KARCH) PATH="$(TARGET_PATH)" modules $(MAKE_TRACE)
	touch $@

$(LINUX_DIR)/.modules-install: $(LINUX_DIR)/.modules-compile
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-modules-install
	rm -rf $(LINUX_BUILD_DIR)/modules
	$(MAKE) -C "$(LINUX_DIR)" CROSS_COMPILE="$(KERNEL_CROSS)" DEPMOD=true INSTALL_MOD_PATH=$(LINUX_BUILD_DIR)/modules modules_install $(MAKE_TRACE)
	touch $@

$(LINUX_DIR)/.linux-compile: $(LINUX_KERNEL) $(LINUX_DIR)/.modules-install
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-create-packages
	@$(MAKE) $(KERNEL_IPKG) $(TARGETS) $(MAKE_TRACE)
	ln -sf $(LINUX_BUILD_DIR)/linux-$(LINUX_VERSION) $(BUILD_DIR)/linux $(MAKE_TRACE)
	touch $@

$(KERNEL_IPKG):
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-create-kernel-package
	rm -rf $(KERNEL_IDIR)
	mkdir -p $(KERNEL_IDIR)/etc
	$(SCRIPT_DIR)/make-ipkg-dir.sh $(KERNEL_IDIR) ../control/kernel.control $(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE) $(ARCH)
	if [ -f ./config/$(BOARD).modules ]; then \
		cp ./config/$(BOARD).modules $(KERNEL_IDIR)/etc/modules; \
	fi
	$(IPKG_BUILD) $(KERNEL_IDIR) $(LINUX_BUILD_DIR) $(MAKE_TRACE)

prepare: 
	-mkdir -p $(PACKAGE_DIR)

compile: prepare $(LINUX_DIR)/.linux-compile

install: compile
	$(MAKE) $(KPKG_MAKEOPTS) $(LINUX_KERNEL) $(MAKE_TRACE)
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-modules-install
	@rm -rf $(LINUX_BUILD_DIR)/root*
	@$(CP) $(BUILD_DIR)/root $(LINUX_BUILD_DIR)/
	echo -e 'dest root /\noption offline_root $(LINUX_BUILD_DIR)/root' > $(LINUX_BUILD_DIR)/ipkg.conf
	$(IPKG_KERNEL) install $(INSTALL_TARGETS) $(MAKE_TRACE)

rebuild:
	@$(TRACE) target/linux/$(BOARD)-$(KERNEL)-rebuild
	rm -rf $(LINUX_BUILD_DIR)/linux-$(LINUX_VERSION)
	rm -f $(TARGETS)
	$(MAKE) compile $(MAKE_TRACE)

clean:
	rm -rf $(LINUX_BUILD_DIR)
	rm -f $(TARGETS)
