modules-y += linux

linux_version := 4.9.80
linux_dir := linux-$(linux_version)
linux_tar := linux-$(linux_version).tar.xz
linux_url := https://cdn.kernel.org/pub/linux/kernel/v4.x/$(linux_tar)

linux-4.9.38_hash := 76d789d87dd51d2fd58c095727171984fa4a992f5e25b9e3eb1e5fd5cd129074
linux-4.9.80_hash := 9e2e83ccc0afc3f23340ed5e58a35d8c6300a7c58aa98ca913848de41226477b

linux_hash := $(linux-$(linux_version)_hash)

# input file in the heads config/ dir
# Allow board config to specialize Linux configuration if necessary
linux_kconfig := $(or $(CONFIG_LINUX_CONFIG),config/linux.config)

# Output directory for the Linux kernel build is based on the
# configuration file name, not the board name
linux_board_dir := $(build)/$(linux_dir)/$(notdir $(basename $(linux_kconfig)))

# temp file in the build dir to show that we have run make oldconfig
linux_config_file := $(notdir $(basename $(linux_kconfig))/.config-$(BOARD))

linux_configure := \
	$(MAKE) \
		CROSS_COMPILE="$(CROSS)" \
		O="$(linux_board_dir)" \
		KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
		oldconfig \

linux_output += $(build)/$(BOARD)/bzImage

# linux.intermediate: $(linux_output)
#linux_output += $(build)/$(BOARD)/modules.cpio


# qemu
linux_modules-$(CONFIG_LINUX_E1000)	+= drivers/net/ethernet/intel/e1000/e1000.ko

# x230 and winterfell
linux_modules-$(CONFIG_LINUX_E1000E)	+= drivers/net/ethernet/intel/e1000e/e1000e.ko

# Dell R630 ethernet and RAID controller
linux_modules-$(CONFIG_LINUX_IGB)	+= drivers/net/ethernet/intel/igb/igb.ko
linux_modules-$(CONFIG_LINUX_MEGARAID)	+= drivers/scsi/megaraid/megaraid_mm.ko
linux_modules-$(CONFIG_LINUX_MEGARAID)	+= drivers/scsi/megaraid/megaraid_sas.ko
linux_modules-$(CONFIG_LINUX_MEGARAID)	+= drivers/scsi/megaraid/megaraid_mbox.ko

# Intel s2600wf scsi controller
linux_modules-$(CONFIG_LINUX_SCSI_GDTH)	+= drivers/scsi/gdth.ko
linux_modules-$(CONFIG_LINUX_ATA)	+= drivers/ata/libata.ko
linux_modules-$(CONFIG_LINUX_AHCI)	+= drivers/ata/ahci.ko
#linux_modules-$(CONFIG_LINUX_AHCI)	+= drivers/ata/ahci_platform.ko
linux_modules-$(CONFIG_LINUX_AHCI)	+= drivers/ata/libahci.ko
#linux_modules-$(CONFIG_LINUX_AHCI)	+= drivers/ata/libahci_platform.ko

# Solarflare network card
linux_modules-$(CONFIG_LINUX_SFC)	+= drivers/net/ethernet/sfc/sfc.ko
linux_modules-$(CONFIG_LINUX_SFC)	+= drivers/net/mdio.ko

# Mellanox ConnectX-3 (winterfell)
linux_modules-$(CONFIG_LINUX_MLX4)	+= drivers/net/ethernet/mellanox/mlx4/mlx4_core.ko
linux_modules-$(CONFIG_LINUX_MLX4)	+= drivers/net/ethernet/mellanox/mlx4/mlx4_en.ko

# USB modules for both types of controllers
# older boards also need ohci and uhci
linux_modules-$(CONFIG_LINUX_USB_COMPANION_CONTROLLER)	+= drivers/usb/host/uhci-hcd.ko
linux_modules-$(CONFIG_LINUX_USB_COMPANION_CONTROLLER)	+= drivers/usb/host/ohci-hcd.ko
linux_modules-$(CONFIG_LINUX_USB_COMPANION_CONTROLLER)	+= drivers/usb/host/ohci-pci.ko
linux_modules-$(CONFIG_LINUX_USB)	+= drivers/usb/host/ehci-hcd.ko
linux_modules-$(CONFIG_LINUX_USB)	+= drivers/usb/host/ehci-pci.ko
linux_modules-$(CONFIG_LINUX_USB)	+= drivers/usb/host/xhci-hcd.ko
linux_modules-$(CONFIG_LINUX_USB)	+= drivers/usb/host/xhci-pci.ko
linux_modules-$(CONFIG_LINUX_USB)	+= drivers/usb/storage/usb-storage.ko

EXTRA_FLAGS := -fdebug-prefix-map=$(pwd)=heads -gno-record-gcc-switches

linux_target := \
	O="$(linux_board_dir)" \
	KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
	CROSS_COMPILE="$(CROSS)" \
	AFLAGS_KERNEL="$(EXTRA_FLAGS)" \
	CFLAGS_KERNEL="$(EXTRA_FLAGS)" \
	CFLAGS_MODULE="$(EXTRA_FLAGS)" \
	KBUILD_BUILD_USER="$(GIT_HASH)" \
	KBUILD_BUILD_HOST=linuxboot \
	KBUILD_BUILD_TIMESTAMP="1970-00-00" \
	KBUILD_BUILD_VERSION=0 \
	$(MAKE_JOBS) \

# We cross compile linux now
linux_depends := musl-cross

#
# Linux kernel module installation
#
# This is special cases since we have to do a special strip operation on
# the kernel modules to make them fit into the ROM image.
#
module_initrd_dir	:= $(shell mktemp -d)
module_initrd_lib_dir	:= $(module_initrd_dir)/lib/modules
FOO := $(shell mkdir -p "$(module_initrd_lib_dir)")

define linux_module =

# Each module depends on building the Linux kernel
$(linux_board_dir)/$1: linux.intermediate # $(build)/$(BOARD)/bzImage

# The cpio file will depend on every module
$(build)/$(BOARD)/modules.cpio: $(module_initrd_lib_dir)/$(notdir $1)

# Strip the modules when we install them so that they will be extra small
$(module_initrd_lib_dir)/$(notdir $1): $(linux_board_dir)/$1
	$(call do,INSTALL-MODULE,$1, \
		$(CROSS)strip \
			--preserve-dates \
			--strip-debug \
			-o "$$@" \
			"$$<" \
	)
endef

$(call map,linux_module,$(linux_modules-y))

# We can't rebuild the module initrd until the kernel has been rebuilt
$(build)/$(BOARD)/modules.cpio: linux.intermediate
	$(call do-cpio,$@,$(module_initrd_dir))
	@$(RM) -rf "$(module_initrd_dir)"


# The output of the linux.intermediate is the bzImage in the
# linus build directory.  We need to copy it into our board
# specific directory for ease of locating it later.
$(linux_board_dir)/arch/x86/boot/bzImage: linux.intermediate
$(build)/$(BOARD)/bzImage: $(linux_board_dir)/arch/x86/boot/bzImage
	$(call do-copy,$<,$@)


# menuconfig target allows us to easily reconfigure this Linux kernel
linux.menuconfig:
	$(MAKE) \
		-C "$(build)/$(linux_dir)" \
		O="$(linux_board_dir)" \
		KCONFIG_CONFIG="$(pwd)/$(linux_kconfig)" \
		menuconfig \