D-Link DNS-323 toolchain

An in-depth guide for DNS-323 hacking with patches, binaries, and helpful resources

14-05-2017

The D-Link DNS-323 is a two-bay NAS device that was first introduced around 2006. It allows users to store data on two internal hard drives, which can be configured in various RAID modes for data redundancy or storage optimization.

The device was designed for home and small office use, providing file-sharing capabilities across a local network or even over the internet.

The DNS-323 became popular among tech enthusiasts due to its Linux-based firmware and relatively open hardware design, which made it a prime candidate for hacking and customization.

A community quickly grew around hacking the DNS-323. Forums and websites dedicated to modifying its firmware gained popularity. Some users developed alternative firmwares or added new applications.

With some hacking or modification, users could enable Telnet or SSH access to the device, allowing them to log in remotely and interact with the NAS at the command line. This opened the door to installing custom software or making low-level modifications.

One of the most popular hacks was FunPlug, a script that allowed users to easily modify the DNS-323. By placing this script on the NAS, users could enable Telnet access, install packages, and add a variety of Linux tools and software to expand the device’s capabilities.

The Cross-Compilation Toolchain

Being an embedded system, a cross-compilation toolchain is needed in order to build applications. A cross-compilation toolchain is a set of tools used to build software for a platform (target system) that is different from the one on which the development is being done (host system). In other words, it’s used to compile code on one system (the host) to run on another system with a different architecture, operating system, or environment (the target).

The compiler translates source code into machine code for the target architecture. For example, if you’re developing on an x86 system and want to produce code for the DNS-323, you’ll need a compiler configured for the specific ARM architecture.

The assembler converts the assembly code (generated by the compiler) into machine code. The linker combines various object files produced by the compiler into a final executable or library that will run on the target system.

Makefile

ARCH:=arm
USE_UCLIBC_SNAPSHOT:=false
BUILD_WITH_LARGEFILE:=true
WGET:=wget --passive-ftp
OPTIMIZE_FOR_CPU=$(ARCH)
SOFT_FLOAT:=false
TARGET_OPTIMIZATION=-Os
TARGET_DEBUGGING= #-g
GCC_USE_SJLJ_EXCEPTIONS:=--enable-sjlj-exceptions
EXTRA_GCC_CONFIG_OPTIONS:=
ENABLE_LOCALE:=false
MULTILIB:=--enable-multilib
INSTALL_LIBSTDCPP:=true
INSTALL_LIBGCJ:=false
TARGETS+=host-sed kernel-headers uclibc-configured binutils gcc3_3 gdb

ifeq ($(SOFT_FLOAT),true)
SOFT_FLOAT_CONFIG_OPTION:=--without-float
TARGET_SOFT_FLOAT:=-msoft-float
ARCH_FPU_SUFFIX:=_nofpu
else
SOFT_FLOAT_CONFIG_OPTION:=
TARGET_SOFT_FLOAT:=
ARCH_FPU_SUFFIX:=
endif

ifeq ($(INSTALL_LIBGCJ),true)
INSTALL_LIBSTDCPP:=true
endif

ifeq ("$(strip $(ARCH))","cris")
BUILD_WITH_LARGEFILE:=false
endif

ifneq ($(BUILD_WITH_LARGEFILE),true)
DISABLE_LARGEFILE= --disable-largefile
endif
TARGET_CFLAGS=$(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)

HOSTCC:=gcc
BASE_DIR:=$(shell pwd)
SOURCE_DIR:=$(BASE_DIR)/sources
DL_DIR:=$(SOURCE_DIR)/dl
PATCH_DIR=$(SOURCE_DIR)/patches
BUILD_DIR=$(BASE_DIR)/toolchain_$(ARCH)$(ARCH_FPU_SUFFIX)
STAGING_DIR=$(BUILD_DIR)
TOOL_BUILD_DIR=$(BASE_DIR)/toolchain_build_$(ARCH)$(ARCH_FPU_SUFFIX)
TARGET_PATH=$(STAGING_DIR)/bin:/bin:/sbin:/usr/bin:/usr/sbin
REAL_GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux-uclibc
GNU_TARGET_NAME=$(OPTIMIZE_FOR_CPU)-linux
KERNEL_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-
TARGET_CROSS=$(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-
TARGET_CC=$(TARGET_CROSS)gcc
STRIP=$(TARGET_CROSS)strip --remove-section=.comment --remove-section=.note

HOST_ARCH:=$(shell $(HOSTCC) -dumpmachine | sed -e s'/-.*//' \
	-e 's/sparc.*/sparc/' \
	-e 's/arm.*/arm/g' \
	-e 's/m68k.*/m68k/' \
	-e 's/ppc/powerpc/g' \
	-e 's/v850.*/v850/g' \
	-e 's/sh[234]/sh/' \
	-e 's/mips-.*/mips/' \
	-e 's/mipsel-.*/mipsel/' \
	-e 's/cris.*/cris/' \
	-e 's/i[3-9]86/i386/' \
	)
GNU_HOST_NAME:=$(HOST_ARCH)-pc-linux-gnu
TARGET_CONFIGURE_OPTS=PATH=$(TARGET_PATH) \
		AR=$(TARGET_CROSS)ar \
		AS=$(TARGET_CROSS)as \
		LD=$(TARGET_CROSS)ld \
		NM=$(TARGET_CROSS)nm \
		CC=$(TARGET_CROSS)gcc \
		GCC=$(TARGET_CROSS)gcc \
		CXX=$(TARGET_CROSS)g++ \
		RANLIB=$(TARGET_CROSS)ranlib

ifeq ($(ENABLE_LOCALE),true)
DISABLE_NLS:=
else
DISABLE_NLS:=--disable-nls
endif


all:   world

TARGETS_CLEAN:=$(patsubst %,%-clean,$(TARGETS))
TARGETS_SOURCE:=$(patsubst %,%-source,$(TARGETS))
TARGETS_DIRCLEAN:=$(patsubst %,%-dirclean,$(TARGETS))

world: $(DL_DIR) $(STAGING_DIR) $(TARGETS)

.PHONY: all world clean dirclean distclean source $(TARGETS) \
	$(TARGETS_CLEAN) $(TARGETS_DIRCLEAN) $(TARGETS_SOURCE)

include make/*.mk

$(DL_DIR):
	mkdir $(DL_DIR)

$(STAGING_DIR):
	rm -rf $(STAGING_DIR)
	mkdir -p $(BUILD_DIR)
	mkdir -p $(TOOL_BUILD_DIR)
	mkdir -p $(STAGING_DIR)/lib
	mkdir -p $(STAGING_DIR)/usr
	mkdir -p $(STAGING_DIR)/include
	ln -fs ../lib $(STAGING_DIR)/usr/lib

source: $(TARGETS_SOURCE)

clean: $(TARGETS_CLEAN)
	rm -rf $(STAGING_DIR)

dirclean: $(TARGETS_DIRCLEAN)
	rm -rf $(STAGING_DIR)

distclean:
	rm -rf $(DL_DIR) $(BUILD_DIR) $(TOOL_BUILD_DIR) $(LINUX_KERNEL)

sourceball:
	rm -rf $(BUILD_DIR)
	set -e; \
	cd ..; \
	rm -f toolchain.tar.bz2; \
	tar -cvf toolchain.tar toolchain; \
	bzip2 -9 toolchain.tar; \

make/binutils-uclibc.mk

BINUTILS_SITE:=http://kernel.org/pub/linux/devel/binutils
BINUTILS_SOURCE:=binutils-2.14.90.0.7.tar.gz
BINUTILS_DIR:=$(TOOL_BUILD_DIR)/binutils-2.14.90.0.7
BINUTILS_CAT:=gzcat

BINUTILS_DIR1:=$(TOOL_BUILD_DIR)/binutils-build

$(DL_DIR)/$(BINUTILS_SOURCE):
	$(WGET) -P $(DL_DIR) $(BINUTILS_SITE)/$(BINUTILS_SOURCE)

$(BINUTILS_DIR)/.unpacked: $(DL_DIR)/$(BINUTILS_SOURCE)
	mkdir -p $(TOOL_BUILD_DIR)
	mkdir -p $(DL_DIR)
	$(BINUTILS_CAT) $(DL_DIR)/$(BINUTILS_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(BINUTILS_DIR)/.unpacked

$(BINUTILS_DIR)/.patched: $(BINUTILS_DIR)/.unpacked
	$(SOURCE_DIR)/patch-kernel.sh $(BINUTILS_DIR) $(SOURCE_DIR) binutils-uclibc*.patch
	touch $(BINUTILS_DIR)/.patched

$(BINUTILS_DIR1)/.configured: $(BINUTILS_DIR)/.patched
	mkdir -p $(BINUTILS_DIR1)
	(cd $(BINUTILS_DIR1); \
		$(BINUTILS_DIR)/configure \
		--prefix=$(STAGING_DIR) \
		--build=$(GNU_HOST_NAME) \
		--host=$(GNU_HOST_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) );
	touch $(BINUTILS_DIR1)/.configured

$(BINUTILS_DIR1)/binutils/objdump: $(BINUTILS_DIR1)/.configured
	$(MAKE) $(JLEVEL) -C $(BINUTILS_DIR1) all

$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld: $(BINUTILS_DIR1)/binutils/objdump
	$(MAKE) $(JLEVEL) -C $(BINUTILS_DIR1) install

binutils-dependancies:
	@if [ ! -x /usr/bin/bison ] ; then \
		echo -e "\n\nYou must install 'bison' on your build machine\n"; \
		exit 1; \
	fi;
	@if [ ! -x /usr/bin/flex ] ; then \
		echo -e "\n\nYou must install 'flex' on your build machine\n"; \
		exit 1; \
	fi;
	@if [ ! -x /usr/bin/msgfmt && ! -x /usr/local/bin/msgfmt ] ; then \
		echo -e "\n\nYou must install 'gettext' on your build machine\n"; \
		exit 1; \
	fi;

binutils: binutils-dependancies $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/bin/ld

binutils-source: $(DL_DIR)/$(BINUTILS_SOURCE)

binutils-clean:
	rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
	-$(MAKE) -C $(BINUTILS_DIR1) clean

binutils-dirclean:
	rm -rf $(BINUTILS_DIR1)

BINUTILS_DIR2:=$(BUILD_DIR)/binutils-target
$(BINUTILS_DIR2)/.configured: $(BINUTILS_DIR)/.patched
	mkdir -p $(BINUTILS_DIR2)
	(cd $(BINUTILS_DIR2); \
		PATH=$(TARGET_PATH) \
		CFLAGS="$(TARGET_CFLAGS)" \
		CFLAGS_FOR_BUILD="-O2 -g" \
		$(BINUTILS_DIR)/configure \
		--prefix=/usr \
		--exec-prefix=/usr \
		--build=$(GNU_HOST_NAME) \
		--host=$(REAL_GNU_TARGET_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) );
	touch $(BINUTILS_DIR2)/.configured

$(BINUTILS_DIR2)/binutils/objdump: $(BINUTILS_DIR2)/.configured
	PATH=$(TARGET_PATH) \
	$(MAKE) $(JLEVEL) -C $(BINUTILS_DIR2) all

$(TARGET_DIR)/usr/bin/ld: $(BINUTILS_DIR2)/binutils/objdump
	PATH=$(TARGET_PATH) \
	$(MAKE) $(JLEVEL) DESTDIR=$(TARGET_DIR) \
		tooldir=/usr build_tooldir=/usr \
		-C $(BINUTILS_DIR2) install
	-$(STRIP) $(TARGET_DIR)/usr/$(REAL_GNU_TARGET_NAME)/bin/* > /dev/null 2>&1
	-$(STRIP) $(TARGET_DIR)/usr/bin/* > /dev/null 2>&1

binutils_target: $(GCC_DEPENDANCY) $(TARGET_DIR)/usr/bin/ld

binutils_target-clean:
	rm -f $(TARGET_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
	-$(MAKE) -C $(BINUTILS_DIR2) clean

binutils_target-dirclean:
	rm -rf $(BINUTILS_DIR2)

make/ccache.mk

CCACHE_SITE:=http://ccache.samba.org/ftp/ccache
CCACHE_SOURCE:=ccache-2.3.tar.gz
CCACHE_DIR1:=$(TOOL_BUILD_DIR)/ccache-2.3
CCACHE_DIR2:=$(BUILD_DIR)/ccache-2.3
CCACHE_CAT:=zcat
CCACHE_BINARY:=ccache
CCACHE_TARGET_BINARY:=usr/bin/ccache

$(DL_DIR)/$(CCACHE_SOURCE):
	$(WGET) -P $(DL_DIR) $(CCACHE_SITE)/$(CCACHE_SOURCE)

$(CCACHE_DIR1)/.unpacked: $(DL_DIR)/$(CCACHE_SOURCE)
	$(CCACHE_CAT) $(DL_DIR)/$(CCACHE_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(CCACHE_DIR1)/.unpacked

$(CCACHE_DIR1)/.patched: $(CCACHE_DIR1)/.unpacked
	$(SED) "s,getenv(\"CCACHE_PATH\"),\"$(STAGING_DIR)/usr/bin\",g" \
		$(CCACHE_DIR1)/execute.c
	$(SED) "s,getenv(\"CCACHE_DIR\"),\"$(CCACHE_DIR1)/cache\",g" \
		$(CCACHE_DIR1)/ccache.c
	mkdir -p $(CCACHE_DIR1)/cache
	touch $(CCACHE_DIR1)/.patched

$(CCACHE_DIR1)/.configured: $(CCACHE_DIR1)/.patched
	mkdir -p $(CCACHE_DIR1)
	(cd $(CCACHE_DIR1); rm -rf config.cache; \
		CC=$(HOSTCC) \
		$(CCACHE_DIR1)/configure \
		--target=$(GNU_HOST_NAME) \
		--host=$(GNU_HOST_NAME) \
		--build=$(GNU_HOST_NAME) \
		--prefix=/usr \
	);
	touch $(CCACHE_DIR1)/.configured

$(CCACHE_DIR1)/$(CCACHE_BINARY): $(CCACHE_DIR1)/.configured
	$(MAKE) CC=$(HOSTCC) -C $(CCACHE_DIR1)

$(STAGING_DIR)/$(CCACHE_TARGET_BINARY): $(CCACHE_DIR1)/$(CCACHE_BINARY)
	mkdir -p $(STAGING_DIR)/usr/bin;
	mkdir -p $(TOOL_BUILD_DIR)/.ccache;
	cp $(CCACHE_DIR1)/ccache $(STAGING_DIR)/usr/bin
	(cd $(STAGING_DIR)/usr/bin; \
		ln -fs $(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc $(OPTIMIZE_FOR_CPU)-linux-gcc; \
		ln -fs $(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc $(OPTIMIZE_FOR_CPU)-linux-cc; \
		ln -fs $(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc $(OPTIMIZE_FOR_CPU)-linux-uclibc-cc);
	[ -f $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc ] && \
		mv $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc $(STAGING_DIR)/usr/bin/
	(cd $(STAGING_DIR)/bin; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-cc; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-gcc; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-uclibc-cc; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-uclibc-gcc);
ifeq ($(INSTALL_LIBSTDCPP),true)
	[ -f $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-c++ ] && \
		mv $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-c++ $(STAGING_DIR)/usr/bin/
	[ -f $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-g++ ] && \
		mv $(STAGING_DIR)/bin/$(OPTIMIZE_FOR_CPU)-linux-uclibc-g++  $(STAGING_DIR)/usr/bin/
	(cd $(STAGING_DIR)/bin; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-c++; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-g++;\
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-uclibc-c++; \
		ln -fs ../usr/bin/ccache $(OPTIMIZE_FOR_CPU)-linux-uclibc-g++);
endif

ifeq ($(GCC_2_95_TOOLCHAIN),true)
ccache: gcc2_95 $(STAGING_DIR)/$(CCACHE_TARGET_BINARY)
else
ccache: gcc3_3 $(STAGING_DIR)/$(CCACHE_TARGET_BINARY)
endif

ccache-clean:
	$(MAKE) -C $(CCACHE_DIR1) uninstall
	-$(MAKE) -C $(CCACHE_DIR1) clean

ccache-dirclean:
	rm -rf $(CCACHE_DIR1)

$(CCACHE_DIR2)/.unpacked: $(DL_DIR)/$(CCACHE_SOURCE)
	$(CCACHE_CAT) $(DL_DIR)/$(CCACHE_SOURCE) | tar -C $(BUILD_DIR) -xvf -
	touch $(CCACHE_DIR2)/.unpacked

$(CCACHE_DIR2)/.patched: $(CCACHE_DIR2)/.unpacked
	touch $(CCACHE_DIR2)/.patched

$(CCACHE_DIR2)/.configured: $(CCACHE_DIR2)/.patched
	mkdir -p $(CCACHE_DIR2)
	(cd $(CCACHE_DIR2); rm -rf config.cache; \
		$(TARGET_CONFIGURE_OPTS) \
		$(CCACHE_DIR2)/configure \
		--target=$(GNU_TARGET_NAME) \
		--host=$(GNU_TARGET_NAME) \
		--build=$(GNU_HOST_NAME) \
		--prefix=/usr \
		--exec-prefix=/usr \
		--bindir=/usr/bin \
		--sbindir=/usr/sbin \
		--libexecdir=/usr/lib \
		--sysconfdir=/etc \
		--datadir=/usr/share \
		--localstatedir=/var \
		--mandir=/usr/man \
		--infodir=/usr/info \
		$(DISABLE_NLS) \
	);
	touch $(CCACHE_DIR2)/.configured

$(CCACHE_DIR2)/$(CCACHE_BINARY): $(CCACHE_DIR2)/.configured
	$(MAKE) -C $(CCACHE_DIR2)

$(TARGET_DIR)/$(CCACHE_TARGET_BINARY): $(CCACHE_DIR2)/$(CCACHE_BINARY)
	$(MAKE) DESTDIR=$(TARGET_DIR) -C $(CCACHE_DIR2) install
	rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \
		$(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc
	(cd $(TARGET_DIR)/bin; \
		ln -fs /usr/bin/ccache cc; \
		ln -fs /usr/bin/ccache gcc; \
		ln -fs /usr/bin/ccache c++; \
		ln -fs /usr/bin/ccache g++;)

ccache_target: uclibc $(TARGET_DIR)/$(CCACHE_TARGET_BINARY)

ccache_target-sources: $(DL_DIR)/$(CCACHE_SOURCE)

ccache_target-clean:
	$(MAKE) DESTDIR=$(TARGET_DIR) -C $(CCACHE_DIR2) uninstall
	-$(MAKE) -C $(CCACHE_DIR2) clean

ccache_target-dirclean:
	rm -rf $(CCACHE_DIR2)

make/elf2flt.mk

ELF2FLT_SITE:=http://www.uclibc.org/downloads/toolchain
ELF2FLT_SOURCE:=elf2flt-20030620.tar.bz2
ELF2FLT_DIR:=$(BUILD_DIR)/elf2flt

$(DL_DIR)/$(ELF2FLT_SOURCE):
	$(WGET) -P $(DL_DIR) $(ELF2FLT_SITE)/$(ELF2FLT_SOURCE)

$(ELF2FLT_DIR)/.unpacked: $(BUILD_DIR)/.setup $(DL_DIR)/$(ELF2FLT_SOURCE)
	bzcat $(DL_DIR)/$(ELF2FLT_SOURCE) | tar -C $(BUILD_DIR) -xvf -
	touch $(ELF2FLT_DIR)/.unpacked

$(ELF2FLT_DIR)/.configured: $(ELF2FLT_DIR)/.unpacked
	(cd $(BINUTILS_DIR1); rm -f include; cp -a $(BINUTILS_DIR)/include .)
	cp -a $(BINUTILS_DIR1)/bfd/bfd.h $(BINUTILS_DIR1)/include/
	(cd $(ELF2FLT_DIR); ./configure \
		--target=$(GNU_TARGET_NAME) --prefix=$(STAGING_DIR) \
		--with-libbfd=$(BINUTILS_DIR1)/bfd/libbfd.a \
		--with-libiberty=$(BINUTILS_DIR1)/libiberty/libiberty.a \
		--with-binutils-include-dir=$(BINUTILS_DIR1)/include \
		--with-bfd-include-dir=$(BINUTILS_DIR1)/bfd)
	touch $(ELF2FLT_DIR)/.configured

$(ELF2FLT_DIR)/elf2flt: $(ELF2FLT_DIR)/.configured
	$(MAKE) -C $(ELF2FLT_DIR)
	chmod a+x $(ELF2FLT_DIR)/ld-elf2flt

$(STAGING_DIR)/$(GNU_TARGET_NAME)/bin/elf2flt: $(ELF2FLT_DIR)/elf2flt
	cp $(ELF2FLT_DIR)/elf2flt $(STAGING_DIR)/bin/$(ARCH)-uclibc-elf2flt
	(cd $(STAGING_DIR)/$(GNU_TARGET_NAME)/bin; ln -f ../../bin/$(ARCH)-uclibc-elf2flt elf2flt)
	cp $(ELF2FLT_DIR)/flthdr $(STAGING_DIR)/bin/$(ARCH)-uclibc-flthdr
	(cd $(STAGING_DIR)/$(GNU_TARGET_NAME)/bin; ln -f ../../bin/$(ARCH)-uclibc-flthdr flthdr)
	if [ ! -f $(STAGING_DIR)/bin/$(ARCH)-uclibc-ld.real ] ; then \
		mv $(STAGING_DIR)/bin/$(ARCH)-uclibc-ld $(STAGING_DIR)/bin/$(ARCH)-uclibc-ld.real;\
	fi;
	cp $(ELF2FLT_DIR)/ld-elf2flt $(STAGING_DIR)/bin/$(ARCH)-uclibc-ld
	cp $(ELF2FLT_DIR)/elf2flt.ld $(STAGING_DIR)/lib

elf2flt: gcc_final $(STAGING_DIR)/$(GNU_TARGET_NAME)/bin/elf2flt

elf2flt-clean:
	rm -f $(STAGING_DIR)/sbin/elf2flt
	-$(MAKE) -C $(ELF2FLT_DIR) clean

elf2flt-dirclean:
	rm -rf $(ELF2FLT_DIR)

make/gcc-uclibc-3.3.mk

ifneq ($(GCC_2_95_TOOLCHAIN),true)

GCC_VERSION:=3.3.3
GCC_SITE:=http://gcc.skazkaforyou.com/releases/gcc-$(GCC_VERSION)

GCC_SOURCE:=gcc-$(GCC_VERSION).tar.bz2
GCC_DIR:=$(TOOL_BUILD_DIR)/gcc-$(GCC_VERSION)
GCC_CAT:=bzcat
GCC_STRIP_HOST_BINARIES:=true

ifeq ($(INSTALL_LIBGCJ),true)
TARGET_LANGUAGES:=c,c++,java
else
ifeq ($(INSTALL_LIBSTDCPP),true)
TARGET_LANGUAGES:=c,c++
else
TARGET_LANGUAGES:=c
endif
endif

GCC_BUILD_DIR1:=$(TOOL_BUILD_DIR)/gcc-3.3-initial

$(DL_DIR)/$(GCC_SOURCE):
	$(WGET) -P $(DL_DIR) $(GCC_SITE)/$(GCC_SOURCE)

$(GCC_DIR)/.unpacked: $(DL_DIR)/$(GCC_SOURCE)
	$(GCC_CAT) $(DL_DIR)/$(GCC_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(GCC_DIR)/.unpacked

$(GCC_DIR)/.patched: $(GCC_DIR)/.unpacked
	$(SOURCE_DIR)/patch-kernel.sh $(GCC_DIR) $(SOURCE_DIR) gcc3.3-mega.patch
	$(SOURCE_DIR)/patch-kernel.sh $(GCC_DIR) $(SOURCE_DIR) gcc-uclibc-3.3*.patch
ifeq ($(SOFT_FLOAT),true)
ifeq ("$(strip $(ARCH))","i386")
	$(SOURCE_DIR)/patch-kernel.sh $(GCC_DIR) $(SOURCE_DIR) i386-gcc-soft-float.patch
endif
endif
	touch $(GCC_DIR)/.patched

$(GCC_BUILD_DIR1)/.configured: $(GCC_DIR)/.patched
	mkdir -p $(GCC_BUILD_DIR1)
	-mkdir -p $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include
	(cd $(GCC_BUILD_DIR1); PATH=$(TARGET_PATH) \
		$(GCC_DIR)/configure \
		--prefix=$(STAGING_DIR) \
		--build=$(GNU_HOST_NAME) \
		--host=$(GNU_HOST_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		--enable-languages=c \
		--disable-shared \
		--includedir=$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include \
		--with-sysroot=$(TOOL_BUILD_DIR)/uClibc_dev/ \
		--disable-__cxa_atexit \
		--enable-target-optspace \
		--with-gnu-ld \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) \
		$(EXTRA_GCC_CONFIG_OPTIONS));
	touch $(GCC_BUILD_DIR1)/.configured

$(GCC_BUILD_DIR1)/.compiled: $(GCC_BUILD_DIR1)/.configured
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GCC_BUILD_DIR1) all-gcc
	touch $(GCC_BUILD_DIR1)/.compiled

$(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-gcc: $(GCC_BUILD_DIR1)/.compiled
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GCC_BUILD_DIR1) install-gcc

gcc3_3_initial: uclibc-configured binutils $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-gcc

gcc3_3_initial-clean:
	rm -rf $(GCC_BUILD_DIR1)
	rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)*

gcc3_3_initial-dirclean:
	rm -rf $(GCC_BUILD_DIR1)

GCC_BUILD_DIR2:=$(TOOL_BUILD_DIR)/gcc-3.3-final
$(GCC_BUILD_DIR2)/.configured: $(GCC_DIR)/.patched $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib/libc.a
	mkdir -p $(GCC_BUILD_DIR2)
	ln -sf include $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/sys-include
	(cd $(GCC_BUILD_DIR2); PATH=$(TARGET_PATH) \
		$(GCC_DIR)/configure \
		--prefix=$(STAGING_DIR) \
		--build=$(GNU_HOST_NAME) \
		--host=$(GNU_HOST_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		--enable-languages=$(TARGET_LANGUAGES) \
		--enable-shared \
		--with-gxx-include-dir=$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/include/c++ \
		--disable-__cxa_atexit \
		--enable-target-optspace \
		--with-gnu-ld \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) \
		$(GCC_USE_SJLJ_EXCEPTIONS) \
		$(EXTRA_GCC_CONFIG_OPTIONS));
	touch $(GCC_BUILD_DIR2)/.configured

$(GCC_BUILD_DIR2)/.compiled: $(GCC_BUILD_DIR2)/.configured
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GCC_BUILD_DIR2) all
	touch $(GCC_BUILD_DIR2)/.compiled

$(GCC_BUILD_DIR2)/.installed: $(GCC_BUILD_DIR2)/.compiled
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GCC_BUILD_DIR2) install
ifeq ($(GCC_STRIP_HOST_BINARIES),true)
	-strip --strip-all -R .note -R .comment $(STAGING_DIR)/bin/*
endif
	set -e; \
	(cd $(STAGING_DIR); \
		ln -sf $(REAL_GNU_TARGET_NAME) $(GNU_TARGET_NAME); \
		cd bin; \
		for app in $(REAL_GNU_TARGET_NAME)-* ; do \
			ln -sf $${app} \
		   	$(GNU_TARGET_NAME)$${app##$(REAL_GNU_TARGET_NAME)}; \
		done; \
	);
ifeq ($(SOFT_FLOAT),true)
	if [ ! -f $(STAGING_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs ] ; then \
		echo staging dir specs file is missing ; \
		/bin/false ; \
	fi;
	cp $(SOURCE_DIR)/specs-$(ARCH)-soft-float $(STAGING_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs
endif
	touch $(GCC_BUILD_DIR2)/.installed

gcc3_3: uclibc-configured binutils gcc3_3_initial $(LIBFLOAT_TARGET) uclibc \
	gdb $(GCC_BUILD_DIR2)/.installed $(GCC_TARGETS)

gcc3_3-source: $(DL_DIR)/$(GCC_SOURCE)

gcc3_3-clean:
	rm -rf $(GCC_BUILD_DIR2)
	rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)*

gcc3_3-dirclean:
	rm -rf $(GCC_BUILD_DIR2)

GCC_BUILD_DIR3:=$(BUILD_DIR)/gcc-3.3-target

$(GCC_BUILD_DIR3)/.configured: $(GCC_BUILD_DIR2)/.installed
	mkdir -p $(GCC_BUILD_DIR3)
	(cd $(GCC_BUILD_DIR3); PATH=$(TARGET_PATH) \
		$(GCC_DIR)/configure \
		--prefix=/usr \
		--build=$(GNU_HOST_NAME) \
		--host=$(REAL_GNU_TARGET_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		--enable-languages=$(TARGET_LANGUAGES) \
		--enable-shared \
		--with-gxx-include-dir=/usr/include/c++ \
		--disable-__cxa_atexit \
		--enable-target-optspace \
		--with-gnu-ld \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) \
		$(GCC_USE_SJLJ_EXCEPTIONS) \
		$(EXTRA_GCC_CONFIG_OPTIONS));
	touch $(GCC_BUILD_DIR3)/.configured

$(GCC_BUILD_DIR3)/.compiled: $(GCC_BUILD_DIR3)/.configured
	PATH=$(TARGET_PATH) \
	$(MAKE) $(JLEVEL) $(TARGET_GCC_ARGS) -C $(GCC_BUILD_DIR3) all
	touch $(GCC_BUILD_DIR3)/.compiled

$(TARGET_DIR)/usr/bin/gcc: $(GCC_BUILD_DIR3)/.compiled
	PATH=$(TARGET_PATH) \
	$(MAKE) $(JLEVEL) DESTDIR=$(TARGET_DIR) -C $(GCC_BUILD_DIR3) install
ifeq ($(SOFT_FLOAT),true)
	if [ ! -f $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs ] ; then \
		echo target dir specs file is missing ; \
		/bin/false ; \
	fi;
	cp $(SOURCE_DIR)/specs-$(ARCH)-soft-float $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs
	$(SED) "s/^1/0/;" $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs
else
	rm -f $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/specs
endif
	-(cd $(TARGET_DIR)/bin; find -type f | xargs $(STRIP) > /dev/null 2>&1)
	-(cd $(TARGET_DIR)/usr/bin; find -type f | xargs $(STRIP) > /dev/null 2>&1)
	-(cd $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION); $(STRIP) cc1 cc1plus collect2 > /dev/null 2>&1)
	-(cd $(TARGET_DIR)/usr/lib; $(STRIP) libstdc++.so.*.*.* > /dev/null 2>&1)
	-(cd $(TARGET_DIR)/lib; $(STRIP) libgcc_s.so.*.*.* > /dev/null 2>&1)
	rm -f $(TARGET_DIR)/usr/lib/*.la*
	cp -f $(STAGING_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/include/syslimits.h $(TARGET_DIR)/usr/lib/gcc-lib/$(REAL_GNU_TARGET_NAME)/$(GCC_VERSION)/include/

gcc3_3_target: uclibc_target binutils_target $(TARGET_DIR)/usr/bin/gcc

gcc3_3_target-clean:
	rm -rf $(GCC_BUILD_DIR3)
	rm -f $(TARGET_DIR)/bin/$(REAL_GNU_TARGET_NAME)*

gcc3_3_target-dirclean:
	rm -rf $(GCC_BUILD_DIR3)

endif

make/gdb-uclibc.mk

GDB_SITE:=http://ftp.gnu.org/gnu/gdb
GDB_SOURCE:=gdb-6.0.tar.bz2
GDB_DIR:=$(TOOL_BUILD_DIR)/gdb-6.0
GDB_CAT:=bzcat

GDB_BUILD_DIR1:=$(TOOL_BUILD_DIR)/gdb-build

$(DL_DIR)/$(GDB_SOURCE):
	$(WGET) -P $(DL_DIR) $(GDB_SITE)/$(GDB_SOURCE)

$(GDB_DIR)/.unpacked: $(DL_DIR)/$(GDB_SOURCE)
	mkdir -p $(TOOL_BUILD_DIR)
	mkdir -p $(DL_DIR)
	$(GDB_CAT) $(DL_DIR)/$(GDB_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(GDB_DIR)/.unpacked

$(GDB_DIR)/.patched: $(GDB_DIR)/.unpacked
	$(SOURCE_DIR)/patch-kernel.sh $(GDB_DIR) $(SOURCE_DIR) gdb-*.patch
	touch $(GDB_DIR)/.patched

$(GDB_BUILD_DIR1)/.configured: $(GDB_DIR)/.patched
	mkdir -p $(GDB_BUILD_DIR1)
	(cd $(GDB_BUILD_DIR1); PATH=$(TARGET_PATH) \
		$(GDB_DIR)/configure \
		--prefix=$(STAGING_DIR) \
		--build=$(GNU_HOST_NAME) \
		--host=$(GNU_HOST_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) );
	touch $(GDB_BUILD_DIR1)/.configured

$(GDB_BUILD_DIR1)/.compiled: $(GDB_BUILD_DIR1)/.configured
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GDB_BUILD_DIR1) all
	touch $(GDB_BUILD_DIR1)/.compiled

$(GDB_BUILD_DIR1)/.installed: $(GDB_BUILD_DIR1)/.compiled
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GDB_BUILD_DIR1) install
	touch $(GDB_BUILD_DIR1)/.installed

gdb: $(GDB_BUILD_DIR1)/.installed

gdb-source: $(DL_DIR)/$(GDB_SOURCE)

gdb-clean:
	rm -f $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
	-$(MAKE) -C $(GDB_BUILD_DIR1) clean

gdb-dirclean:
	rm -rf $(GDB_BUILD_DIR1)

GDB_BUILD_DIR2:=$(TOOL_BUILD_DIR)/gdb-target

$(GDB_BUILD_DIR2)/.configured: $(GDB_DIR)/.patched
	mkdir -p $(GDB_BUILD_DIR2)
	(cd $(GDB_BUILD_DIR2); \
		PATH=$(TARGET_PATH) \
		CFLAGS="$(TARGET_CFLAGS)" \
		$(GDB_DIR)/configure \
		--prefix=/usr \
		--exec-prefix=/usr \
		--build=$(GNU_HOST_NAME) \
		--host=$(REAL_GNU_TARGET_NAME) \
		--target=$(REAL_GNU_TARGET_NAME) \
		$(DISABLE_NLS) \
		$(MULTILIB) \
		$(SOFT_FLOAT_CONFIG_OPTION) );
	touch $(GDB_BUILD_DIR2)/.configured

$(GDB_BUILD_DIR2)/.compiled: $(GDB_BUILD_DIR2)/.configured
	PATH=$(TARGET_PATH) $(MAKE) $(JLEVEL) -C $(GDB_BUILD_DIR2) all
	touch $(GDB_BUILD_DIR2)/.compiled

$(GDB_BUILD_DIR2)/.installed: $(GDB_BUILD_DIR2)/.compiled
	PATH=$(TARGET_PATH) \
	$(MAKE) $(JLEVEL) DESTDIR=$(TARGET_DIR) \
		tooldir=/usr build_tooldir=/usr \
		-C $(GDB_BUILD_DIR2) install
	-$(STRIP) $(TARGET_DIR)/usr/$(REAL_GNU_TARGET_NAME)/bin/* > /dev/null 2>&1
	-$(STRIP) $(TARGET_DIR)/usr/bin/* > /dev/null 2>&1

gdb_target: $(GDB_BUILD_DIR2)/.installed

gdbserver:

gdb_target-clean:
	rm -f $(TARGET_DIR)/bin/$(REAL_GNU_TARGET_NAME)*
	-$(MAKE) -C $(GDB_BUILD_DIR2) clean

gdb_target-dirclean:
	rm -rf $(GDB_BUILD_DIR2)

make/kernel-headers.mk

ifneq ($(filter $(TARGETS),kernel-headers),)

LINUX_SITE:=http://ep09.pld-linux.org/~mmazur/linux-libc-headers/
LINUX_SOURCE:=linux-libc-headers-2.6.9.1.tar.bz2
LINUX_DIR:=$(TOOL_BUILD_DIR)/linux-libc-headers-2.6.9.1
LINUX_SOURCE_DIR=$(LINUX_DIR)

$(DL_DIR)/$(LINUX_SOURCE):
	$(WGET) -P $(DL_DIR) $(LINUX_SITE)/$(LINUX_SOURCE)

$(LINUX_DIR)/.unpacked: $(DL_DIR)/$(LINUX_SOURCE)
	mkdir -p $(TOOL_BUILD_DIR)
	bzcat $(DL_DIR)/$(LINUX_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(LINUX_DIR)/.unpacked

$(LINUX_DIR)/.configured: $(LINUX_DIR)/.unpacked
	rm -f $(LINUX_DIR)/include/asm
	@if [ "$(ARCH)" = "powerpc" ];then \
	    (cd $(LINUX_DIR)/include; ln -fs asm-ppc$(NOMMU) asm;) \
	elif [ "$(ARCH)" = "mips" ];then \
	    (cd $(LINUX_DIR)/include; ln -fs asm-mips$(NOMMU) asm;) \
	elif [ "$(ARCH)" = "mipsel" ];then \
	    (cd $(LINUX_DIR)/include; ln -fs asm-mips$(NOMMU) asm;) \
	elif [ "$(ARCH)" = "arm" ];then \
	    (cd $(LINUX_DIR)/include; ln -fs asm-arm$(NOMMU) asm; \
	     cd asm; \
	     if [ ! -L proc ] ; then \
	     ln -fs proc-armv proc; \
	     ln -fs arch-ebsa285 arch; fi); \
	elif [ "$(ARCH)" = "cris" ];then \
	    (cd $(LINUX_DIR)/include; ln -fs asm-cris asm;) \
	else \
	    (cd $(LINUX_DIR)/include; ln -fs asm-$(ARCH)$(NOMMU) asm;) \
	fi
	touch $(LINUX_DIR)/include/linux/autoconf.h;
	echo "#define UTS_RELEASE \"2.4.21\"" > $(LINUX_DIR)/include/linux/version.h;
	echo "#define LINUX_VERSION_CODE 132117" >> $(LINUX_DIR)/include/linux/version.h;
	echo "#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))" >> \
		$(LINUX_DIR)/include/linux/version.h;
	touch $(LINUX_DIR)/.configured

$(LINUX_KERNEL): $(LINUX_DIR)/.configured

kernel-headers: $(LINUX_DIR)/.configured

kernel-headers-source: $(DL_DIR)/$(LINUX_SOURCE)

kernel-headers-clean: clean
	rm -f $(LINUX_KERNEL)
	rm -rf $(LINUX_DIR)

kernel-headers-dirclean:
	rm -rf $(LINUX_DIR)

endif

make/libfloat.mk

LIBFLOAT_SOURCE:=libfloat_990616.orig.tar.gz
LIBFLOAT_PATCH:=libfloat_990616-3.diff.gz
LIBFLOAT_SITE:=http://ftp.debian.org/debian/pool/main/libf/libfloat
LIBFLOAT_CAT:=zcat
LIBFLOAT_DIR:=$(BUILD_DIR)/libfloat

LIBFLOAT_TARGET=
ifeq ($(strip $(SOFT_FLOAT)),true)
ifeq ("$(strip $(ARCH))","arm")
LIBFLOAT_TARGET+=$(STAGING_DIR)/lib/libfloat.so
endif
endif

$(DL_DIR)/$(LIBFLOAT_SOURCE):
	 $(WGET) -P $(DL_DIR) $(LIBFLOAT_SITE)/$(LIBFLOAT_SOURCE)

$(DL_DIR)/$(LIBFLOAT_PATCH):
	 $(WGET) -P $(DL_DIR) $(LIBFLOAT_SITE)/$(LIBFLOAT_PATCH)

libfloat-source: $(DL_DIR)/$(LIBFLOAT_SOURCE) $(DL_DIR)/$(LIBFLOAT_PATCH)

$(LIBFLOAT_DIR)/.unpacked: $(DL_DIR)/$(LIBFLOAT_SOURCE) $(DL_DIR)/$(LIBFLOAT_PATCH)
	$(LIBFLOAT_CAT) $(DL_DIR)/$(LIBFLOAT_SOURCE) | tar -C $(BUILD_DIR) -xvf -
	make -C $(LIBFLOAT_DIR) clean
	$(SOURCE_DIR)/patch-kernel.sh $(LIBFLOAT_DIR) $(DL_DIR) $(LIBFLOAT_PATCH)
	$(SOURCE_DIR)/patch-kernel.sh $(LIBFLOAT_DIR) $(SOURCE_DIR) libfloat.patch
	touch $(LIBFLOAT_DIR)/.unpacked

$(LIBFLOAT_DIR)/libfloat.so.1: $(LIBFLOAT_DIR)/.unpacked $(TARGET_CC)
	$(MAKE) CC=$(TARGET_CC) LD=$(TARGET_CROSS)ld -C $(LIBFLOAT_DIR)

$(STAGING_DIR)/lib/libfloat.so: $(LIBFLOAT_DIR)/libfloat.so.1
	cp -a $(LIBFLOAT_DIR)/libfloat.a $(STAGING_DIR)/lib/libfloat.a
	cp -a $(LIBFLOAT_DIR)/libfloat.so.1 $(STAGING_DIR)/lib/libfloat.so.1
	(cd $(STAGING_DIR)/lib ; ln -sf libfloat.so.1 libfloat.so)
	cp -a $(LIBFLOAT_DIR)/libfloat.a $(TARGET_DIR)/usr/lib/libfloat.a
	cp -a $(LIBFLOAT_DIR)/libfloat.so.1 $(TARGET_DIR)/lib/libfloat.so.1
	$(STRIP) $(TARGET_DIR)/lib/libfloat.so.1 > /dev/null 2>&1
	(cd $(TARGET_DIR)/lib ; ln -sf libfloat.so.1 libfloat.so)
	(cd $(TARGET_DIR)/usr/lib ; ln -sf /lib/libfloat.so libfloat.so)

libfloat: $(STAGING_DIR)/lib/libfloat.so

libfloat-clean:
	-$(MAKE) -C $(LIBFLOAT_DIR) clean

libfloat-dirclean:
	rm -rf $(LIBFLOAT_DIR)

make/sed.mk

SED_SOURCE:=sed-4.0.8.tar.gz
SED_SITE:=ftp://ftp.gnu.org/gnu/sed
SED_CAT:=zcat
SED_DIR1:=$(TOOL_BUILD_DIR)/sed-4.0.8
SED_DIR2:=$(BUILD_DIR)/sed-4.0.8
SED_BINARY:=sed/sed
SED_TARGET_BINARY:=bin/sed
ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true)
SED_CPPFLAGS=-D_FILE_OFFSET_BITS=64
endif
SED:=$(STAGING_DIR)/bin/sed -i -e

HOST_SED_TARGET=$(shell ./sources/sedcheck.sh)

$(DL_DIR)/$(SED_SOURCE):
	 $(WGET) -P $(DL_DIR) $(SED_SITE)/$(SED_SOURCE)

sed-source: $(DL_DIR)/$(SED_SOURCE)

$(SED_DIR1)/.unpacked: $(DL_DIR)/$(SED_SOURCE)
	mkdir -p $(TOOL_BUILD_DIR)
	mkdir -p $(DL_DIR)
	mkdir -p $(STAGING_DIR)/bin;
	$(SED_CAT) $(DL_DIR)/$(SED_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
	touch $(SED_DIR1)/.unpacked

$(SED_DIR1)/.configured: $(SED_DIR1)/.unpacked
	(cd $(SED_DIR1); rm -rf config.cache; \
		./configure \
		--prefix=$(STAGING_DIR) \
		--prefix=/usr \
	);
	touch  $(SED_DIR1)/.configured

$(SED_DIR1)/$(SED_BINARY): $(SED_DIR1)/.configured
	$(MAKE) -C $(SED_DIR1)

build-sed-host-binary: $(SED_DIR1)/$(SED_BINARY)
	@if [ -L $(STAGING_DIR)/$(SED_TARGET_BINARY) ] ; then \
		rm -f $(STAGING_DIR)/$(SED_TARGET_BINARY); fi;
	@if [ ! -f $(STAGING_DIR)/$(SED_TARGET_BINARY) -o $(STAGING_DIR)/$(SED_TARGET_BINARY) \
	-ot $(SED_DIR1)/$(SED_BINARY) ] ; then \
	    set -x; \
	    $(MAKE) DESTDIR=$(STAGING_DIR) -C $(SED_DIR1) install; \
	    mv $(STAGING_DIR)/usr/bin/sed $(STAGING_DIR)/bin/; \
	    rm -rf $(STAGING_DIR)/share/locale $(STAGING_DIR)/usr/info \
		    $(STAGING_DIR)/usr/man $(STAGING_DIR)/usr/share/doc; fi

use-sed-host-binary:
	@if [ -x /usr/bin/sed ]; then SED="/usr/bin/sed"; else \
	    if [ -x /bin/sed ]; then SED="/bin/sed"; fi; fi; \
	    mkdir -p $(STAGING_DIR)/bin; \
	    rm -f $(STAGING_DIR)/$(SED_TARGET_BINARY); \
	    ln -s $$SED $(STAGING_DIR)/$(SED_TARGET_BINARY)

host-sed: $(HOST_SED_TARGET)

host-sed-clean:
	$(MAKE) DESTDIR=$(STAGING_DIR) -C $(SED_DIR1) uninstall
	-sed -C $(SED_DIR1) clean

host-sed-dirclean:
	rm -rf $(SED_DIR1)

$(SED_DIR2)/.unpacked: $(DL_DIR)/$(SED_SOURCE)
	$(SED_CAT) $(DL_DIR)/$(SED_SOURCE) | tar -C $(BUILD_DIR) -xvf -
	touch $(SED_DIR2)/.unpacked

$(SED_DIR2)/.configured: $(SED_DIR2)/.unpacked
	(cd $(SED_DIR2); rm -rf config.cache; \
		$(TARGET_CONFIGURE_OPTS) \
		CFLAGS="$(TARGET_CFLAGS)" \
		CPPFLAGS="$(SED_CFLAGS)" \
		./configure \
		--target=$(GNU_TARGET_NAME) \
		--host=$(GNU_TARGET_NAME) \
		--build=$(GNU_HOST_NAME) \
		--prefix=/usr \
		--exec-prefix=/usr \
		--bindir=/usr/bin \
		--sbindir=/usr/sbin \
		--libexecdir=/usr/lib \
		--sysconfdir=/etc \
		--datadir=/usr/share \
		--localstatedir=/var \
		--mandir=/usr/man \
		--infodir=/usr/info \
		$(DISABLE_NLS) \
	);
	touch  $(SED_DIR2)/.configured

$(SED_DIR2)/$(SED_BINARY): $(SED_DIR2)/.configured
	$(MAKE) CC=$(TARGET_CC) -C $(SED_DIR2)

sed-target_binary: $(SED_DIR2)/$(SED_BINARY)
	@if [ -L $(TARGET_DIR)/$(SED_TARGET_BINARY) ] ; then \
		rm -f $(TARGET_DIR)/$(SED_TARGET_BINARY); fi;

	@if [ ! -f $(SED_DIR2)/$(SED_BINARY) -o $(TARGET_DIR)/$(SED_TARGET_BINARY) \
	-ot $(SED_DIR2)/$(SED_BINARY) ] ; then \
	    set -x; \
	    $(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR2) install; \
	    mv $(TARGET_DIR)/usr/bin/sed $(TARGET_DIR)/bin/; \
	    rm -rf $(TARGET_DIR)/share/locale $(TARGET_DIR)/usr/info \
		    $(TARGET_DIR)/usr/man $(TARGET_DIR)/usr/share/doc; fi

sed: uclibc sed-target_binary

sed-clean:
	$(MAKE) DESTDIR=$(TARGET_DIR) CC=$(TARGET_CC) -C $(SED_DIR2) uninstall
	-sed -C $(SED_DIR2) clean

sed-dirclean:
	rm -rf $(SED_DIR2)

make/uclibc.mk

ifeq ($(USE_UCLIBC_SNAPSHOT),true)
UCLIBC_DIR=$(TOOL_BUILD_DIR)/uClibc
UCLIBC_SOURCE=uClibc-snapshot.tar.bz2
UCLIBC_SITE:=http://www.uclibc.org/downloads/snapshots
else
UCLIBC_DIR:=$(TOOL_BUILD_DIR)/uClibc-0.9.28
UCLIBC_SOURCE:=uClibc-0.9.28.tar.bz2
UCLIBC_SITE:=https://uclibc.org/downloads/old-releases/
endif

UCLIBC_TARGET_ARCH:=$(shell echo $(ARCH) | sed -e s'/-.*//' \
                -e 's/i.86/i386/' \
		-e 's/sparc.*/sparc/' \
		-e 's/arm.*/arm/g' \
		-e 's/m68k.*/m68k/' \
		-e 's/ppc/powerpc/g' \
		-e 's/v850.*/v850/g' \
		-e 's/sh64/sh/' \
		-e 's/sh[234]/sh/' \
		-e 's/mips.*/mips/' \
		-e 's/mipsel.*/mips/' \
		-e 's/cris.*/cris/' \
)

$(DL_DIR)/$(UCLIBC_SOURCE):
	$(WGET) -P $(DL_DIR) $(UCLIBC_SITE)/$(UCLIBC_SOURCE)

$(UCLIBC_DIR)/.unpacked: $(DL_DIR)/$(UCLIBC_SOURCE)
ifeq ($(SOFT_FLOAT),true)
	if [ ! -f $(SOURCE_DIR)/specs-$(ARCH)-soft-float ] ; then \
		echo soft float configured but no specs file for this arch ; \
		/bin/false ; \
	fi;
endif
	bzcat $(DL_DIR)/$(UCLIBC_SOURCE) | tar -C $(TOOL_BUILD_DIR) -xvf -
ifeq ($(strip $(UCLIBC_TARGET_ARCH)),mips)
	$(SOURCE_DIR)/patch-kernel.sh $(UCLIBC_DIR) $(SOURCE_DIR) uClibc-ldso-0.9.24.patch
endif
	touch $(UCLIBC_DIR)/.unpacked

$(UCLIBC_DIR)/.configured: $(UCLIBC_DIR)/.unpacked $(LINUX_DIR)/.configured
	$(SED) 's,^CROSS=.*,CROSS=$(TARGET_CROSS),g' $(UCLIBC_DIR)/Rules.mak
ifeq ($(ENABLE_LOCALE),true)
	cp $(SOURCE_DIR)/uClibc.config-locale $(UCLIBC_DIR)/.config
else
	cp $(SOURCE_DIR)/uClibc.config $(UCLIBC_DIR)/.config
endif
	$(SED) 's,^.*TARGET_$(UCLIBC_TARGET_ARCH).*,TARGET_$(UCLIBC_TARGET_ARCH)=y,g' \
		$(UCLIBC_DIR)/.config
	$(SED) 's,^TARGET_ARCH.*,TARGET_ARCH=\"$(UCLIBC_TARGET_ARCH)\",g' $(UCLIBC_DIR)/.config
	$(SED) 's,^KERNEL_SOURCE=.*,KERNEL_SOURCE=\"$(LINUX_DIR)\",g' \
		$(UCLIBC_DIR)/.config
	$(SED) 's,^RUNTIME_PREFIX=.*,RUNTIME_PREFIX=\"/\",g' \
		$(UCLIBC_DIR)/.config
	$(SED) 's,^DEVEL_PREFIX=.*,DEVEL_PREFIX=\"/usr/\",g' \
		$(UCLIBC_DIR)/.config
	$(SED) 's,^SHARED_LIB_LOADER_PREFIX=.*,SHARED_LIB_LOADER_PREFIX=\"/lib\",g' \
		$(UCLIBC_DIR)/.config
ifeq ($(strip $(BUILD_WITH_LARGEFILE)),true)
	$(SED) 's,^.*UCLIBC_HAS_LFS.*,UCLIBC_HAS_LFS=y,g' $(UCLIBC_DIR)/.config
else
	$(SED) 's,^.*UCLIBC_HAS_LFS.*,UCLIBC_HAS_LFS=n,g' $(UCLIBC_DIR)/.config
endif
	$(SED) 's,.*UCLIBC_HAS_WCHAR.*,UCLIBC_HAS_WCHAR=y,g' $(UCLIBC_DIR)/.config
ifeq ($(strip $(SOFT_FLOAT)),true)
	$(SED) 's,.*HAS_FPU.*,HAS_FPU=n\nUCLIBC_HAS_FLOATS=y\nUCLIBC_HAS_SOFT_FLOAT=y,g' $(UCLIBC_DIR)/.config
endif
	mkdir -p $(TOOL_BUILD_DIR)/uClibc_dev/usr/include
	mkdir -p $(TOOL_BUILD_DIR)/uClibc_dev/usr/lib
	mkdir -p $(TOOL_BUILD_DIR)/uClibc_dev/lib
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(TOOL_BUILD_DIR)/uClibc_dev/ \
		DEVEL_PREFIX=/usr/ \
		RUNTIME_PREFIX=$(TOOL_BUILD_DIR)/uClibc_dev/ \
		HOSTCC="$(HOSTCC)" \
		pregen install_dev;
	touch $(UCLIBC_DIR)/.configured

$(UCLIBC_DIR)/lib/libc.a: $(UCLIBC_DIR)/.configured $(LIBFLOAT_TARGET)
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX= \
		DEVEL_PREFIX=$(REAL_GNU_TARGET_NAME)/ \
		RUNTIME_PREFIX=/ \
		HOSTCC="$(HOSTCC)" \
		all
ifeq ($(strip $(UCLIBC_TARGET_ARCH)),mips)
	$(MAKE) -C $(UCLIBC_DIR)/ldso-0.9.24 \
		PREFIX= \
		DEVEL_PREFIX=$(REAL_GNU_TARGET_NAME)/ \
		RUNTIME_PREFIX=/ \
		HOSTCC="$(HOSTCC)" \
		all shared
endif

$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib/libc.a: $(UCLIBC_DIR)/lib/libc.a
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(STAGING_DIR)/ \
		DEVEL_PREFIX=$(REAL_GNU_TARGET_NAME)/ \
		RUNTIME_PREFIX=$(REAL_GNU_TARGET_NAME)/ \
		install_runtime
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(STAGING_DIR)/ \
		DEVEL_PREFIX=$(REAL_GNU_TARGET_NAME)/ \
		RUNTIME_PREFIX=$(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/ \
		install_dev
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(STAGING_DIR) \
		HOSTCC="$(HOSTCC)" \
		utils install_utils
	$(MAKE) -C $(UCLIBC_DIR)/utils clean

ifneq ($(TARGET_DIR),)
$(TARGET_DIR)/lib/libc.so.0: $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib/libc.a
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(TARGET_DIR) \
		DEVEL_PREFIX=/usr/ \
		RUNTIME_PREFIX=/ \
		install_runtime

$(TARGET_DIR)/usr/bin/ldd: $(TARGET_DIR)/lib/libc.so.0
	$(MAKE) -C $(UCLIBC_DIR) $(TARGET_CONFIGURE_OPTS) \
		PREFIX=$(TARGET_DIR) utils install_utils

UCLIBC_TARGETS=$(TARGET_DIR)/lib/libc.so.0 $(TARGET_DIR)/usr/bin/ldd
endif

uclibc-configured: $(UCLIBC_DIR)/.configured

uclibc: $(STAGING_DIR)/bin/$(REAL_GNU_TARGET_NAME)-gcc $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib/libc.a \
	$(UCLIBC_TARGETS)

uclibc-source: $(DL_DIR)/$(UCLIBC_SOURCE)

uclibc-configured-source: uclibc-source

uclibc-clean:
	-$(MAKE) -C $(UCLIBC_DIR) clean
	rm -f $(UCLIBC_DIR)/.config

uclibc-dirclean:
	rm -rf $(UCLIBC_DIR)

$(TARGET_DIR)/usr/lib/libc.a: $(STAGING_DIR)/$(REAL_GNU_TARGET_NAME)/lib/libc.a
	$(MAKE) -C $(UCLIBC_DIR) \
		PREFIX=$(TARGET_DIR) \
		DEVEL_PREFIX=/usr/ \
		RUNTIME_PREFIX=/ \
		install_dev

uclibc_target: gcc3_3 uclibc $(TARGET_DIR)/usr/lib/libc.a

uclibc_target-clean:
	rm -f $(TARGET_DIR)/include

uclibc_target-dirclean:
	rm -f $(TARGET_DIR)/include

Patches

Custom Applications

The format of a “native” application is very simple.

After cross-compiling the binaries, it is sufficient to add shell scripts that will be invoked following the init script, the bootstrap or user actions in the web interface: install.sh, pre_inst.sh, remove.sh, rm_link.sh, start.sh, stop.sh.

The manifest for application is an XML file named imodule.xml containing a config tag, a nested apkg tag, and a list of items.

Busybox

BusyBox is a software utility that combines a wide range of Unix tools into a single, small executable file, often referred to as the “Swiss Army Knife of Embedded Linux”.

It provides minimalist versions of many common Unix commands like ls, cp, cat, and others, which are commonly found on larger Unix systems, but in a compact form that is ideal for environments with limited resources, such as embedded systems, routers, and network-attached storage devices.

Click here to download the cross-compiled busybox binary. - 935fe7062823d51cecb39aec69f1ddc6c0795054e03d510e6e368f079e54dc90

imodule.xml manifest:

<config>
	<apkg>
		<item>
			<procudt_id>0</procudt_id>
			<custom_id>8</custom_id>
			<model_id>1</model_id>
			<name>telnet</name>
			<show>telnet</show>
			<enable>1</enable>
			<version>busybox 1.20.2</version>
			<date>20120702</date>
			<path>/mnt/HD_a2/Nas_Prog/busybox</path>
			<ps_name>dont_check</ps_name>
			<url>NULL</url>
		</item>
	</apkg>
</config>

install and pre_inst scripts:

#!/bin/sh
export PATH=/mnt/HD_a2/Nas_Prog/busybox:${PATH}

start script:

#!/bin/sh
path=/mnt/HD_a2/Nas_Prog/busybox

if [ ! -e "/dev/ptmx" ]; then
	/mnt/HD_a2/Nas_Prog/busybox/mknod -m 0666 /dev/ptmx c 5 2 
fi

if [ ! -d "/dev/pts" ]; then
	mkdir -p /dev/pts
fi

mount | grep devpts 1>/dev/null 2>/dev/null

if [ $? -ne 0 ]; then
	mount -t devpts devpts /dev/pts
fi

/mnt/HD_a2/Nas_Prog/busybox/telnetd -l /mnt/HD_a2/Nas_Prog/busybox/sh

stop script:

#!/bin/sh
killall telnetd
sleep 1

Dropbear

Dropbear is a lightweight SSH server and client software designed specifically for embedded systems and devices with limited resources, such as routers, IoT devices, and network-attached storage.

It provides secure remote access, file transfer, and command execution, much like the more commonly known OpenSSH, but with a smaller footprint, making it ideal for environments where memory and processing power are constrained.

Click here to download the cross-compiled busybox binaries: dbclient - 74c0638115f03791f79c5e4a5d723a70fb4397542c20dfab7c8182caf3d697fc, dropbear - d50b5c31678089ffb4da29257bdbee199cf09d47ed0273f68e448c46d709b35f, dropbearconvert - ea0edea64af517b188fd65c3c1f39698f0e0bce897bd1551a0229fba153cb25c, dropbearkey - e0daa9d79c7487035bd4bd8f99b1c5d5487661c382ae5ba47ac73f99c6e852d4.

imodule.xml manifest:

<config>
	<apkg>
		<item>
			<procudt_id>0</procudt_id>
			<custom_id>8</custom_id>
			<model_id>1</model_id>
			<name>dropbear.SSH</name>
			<show>dropbear.SSH</show>
			<enable>0</enable>
			<version>2012.55</version>
			<date>20120224</date>
			<path>/mnt/HD_a2/Nas_Prog/dropbear</path>
			<ps_name>dont_check</ps_name>
			<url>NULL</url>
		</item>
	</apkg>
</config>

start script:

#!/bin/sh
path=/mnt/HD_a2/Nas_Prog/dropbear
if [ ! -e "/usr/bin/dbclient" ]; then
	ln -s ${path}/dbclient /usr/bin/dbclient
fi
if [ ! -e "/usr/bin/dropbear" ]; then
	ln -s ${path}/dropbear /usr/bin/dropbear
fi
if [ ! -e "/usr/bin/dropbearconvert" ]; then
	ln -s ${path}/dropbearconvert /usr/bin/dropbearconvert
fi
if [ ! -e "/usr/bin/dropbearkey" ]; then
	ln -s ${path}/dropbearkey /usr/bin/dropbearkey
fi
if [ ! -e "/dev/urandom" ]; then
	mknod /dev/urandom c 1 8
fi
if [ ! -e "/dev/ptmx" ]; then
	mknod -m 0666 /dev/ptmx c 5 2
fi
if [ ! -d "/dev/pts" ]; then
	mkdir -p /dev/pts
fi
mount | grep devpts 1>/dev/null 2>/dev/null
if [ $? -ne 0 ]; then
	mount -t devpts devpts /dev/pts
fi
if [ ! -e "/etc/dropbear_dsa_host_key" ]; then
	/usr/bin/dropbearkey -t dss -f /etc/dropbear_dsa_host_key
fi
if [ ! -e "/etc/dropbear_rsa_host_key" ]; then
	/usr/bin/dropbearkey -t rsa -f /etc/dropbear_rsa_host_key
fi
/usr/bin/dropbear -E 1>${path}/dropbear.log 2>&1 &

stop script:

#!/bin/sh
killall dbclient
sleep 1
killall dropbear
sleep 1
killall dropbearconvert
sleep 1
killall dropbearkey
sleep 1
rm -f /usr/bin/dbclient
rm -f /usr/bin/dropbear
rm -f /usr/bin/dropbearconvert
rm -f /usr/bin/dropbearkey

mlDonkey

MLDonkey is an open-source, multi-network P2P file-sharing application that supports a wide range of file-sharing protocols: eDonkey2000, BitTorrent, Overnet, Gnutella, Kademlia, FastTrack, Direct Connect, HTTP and FTP.

Originally developed as a client for the eDonkey2000 network, MLDonkey has since evolved to support multiple P2P protocols, allowing users to download and share files from various sources at the same time.

Click here to download the cross-compiled mlnet binary. - c5be956874f04fb2294165bee4612737ec9534ee3cb7c5ef6a02d678a285c34c

#!/bin/sh
export MLDONKEY_DIR="/mnt/HD_b2/BT"
export TMPDIR="/mnt/HD_b2/BT/temp"
MLNETBINDIR="/mnt/HD_a2/fun_plug.d/bin"
MLNETLOG="/mnt/HD_a2/fun_plug.d/log/mlnet.log"
if [ -n "$(pidof mlnet)" ]; then
	echo "mlnet is already runnning"
else
	if [ -e ${MLDONKEY_DIR}/mlnet.pid ]; then
		rm ${MLDONKEY_DIR}/mlnet.pid
	fi
	if [ -e ${MLDONKEY_DIR}/files.ini.tmp ]; then
		rm ${MLDONKEY_DIR}/files.ini.tmp
	fi
	${MLNETBINDIR}/mlnet > ${MLNETLOG} 2>&1 &
	chmod 777 ${MLDONKEY_DIR}/incoming/ 
	chmod 777 ${MLDONKEY_DIR}/incoming/*
fi