WHDD Live ISO Boot CD (old)

From richud.com
Jump to navigation Jump to search


WHDD is created by Andrey Utkin. This is a small 'Live' image to run standalone.

Prebuilt WHDD Live ISO

For people who just want it without building themselves

Prebuilt ISO

Boot from Syslinux/PXELinux

Label WHDD V2
LINUX /memdisk iso
INITRD /whdd-live.iso

or separate (not in ISO)

Label WHDD V2
LINUX /bzImage
INITRD /initramfs

Build it yourself

Download Toolchain

This uses uClibc to create smaller C library files and hence a smaller output.

i386 uClibc toolchain

Create folders

Create directory structure somewhere;

mkdir -p patch source custom

Download Sources

cd source
git clone https://github.com/krieger-od/whdd
git clone git://git.busybox.net/busybox
curl https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.02.tar.xz | tar -Jx
svn co http://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools smartmontools
curl https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.14.5.tar.xz | tar -Jx
curl http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.9.tar.gz | tar -zx
curl http://invisible-island.net/datafiles/release/dialog.tar.gz | tar -zx

Dir structures

Initially you should just have folders custom, patch, source and the Makefile.

(Ignore other folders for the moment, this is after it has been built to give you an idea how it should look)

├── custom
│   ├── inittab
│   └── rcS
├── destdir
│   ├── bin
│   ├── etc
│   ├── include
│   ├── lib
│   ├── linuxrc -> bin/busybox
│   ├── sbin
│   ├── share
│   └── usr
├── initrd
│   ├── bin
│   ├── dev
│   ├── etc
│   ├── home
│   ├── init -> bin/busybox
│   ├── lib
│   ├── mnt
│   ├── opt
│   ├── proc
│   ├── sbin
│   ├── sys
│   ├── tmp
│   ├── usr
│   └── var
├── Makefile
├── output
│   ├── bzImage
│   ├── initramfs
│   └── isolinux
├── patch
│   ├── whdd-CMakeList.txt.patch
│   ├── whdd-libdevcheck-libdevcheck.c.patch
│   ├── whdd-sliding_window_renderer.c.patch
│   └── whdd-whole_space_renderer.c.patch
├── source
│   ├── busybox
│   ├── dialog-1.2-20140219
│   ├── linux-3.14
│   ├── ncurses-5.9
│   ├── smartmontools-code-3887-trunk
│   ├── syslinux
│   └── whdd
├── whdd-live.iso
└── whdd.qcow


Patches

These are needed after git pull at time of writing

busybox-shell_ash.c.patch

This makes busybox set LANG as a default ENV so UNICODE works, required by WHDD.

--- busybox/shell/ash.c.orig	2014-06-09 10:28:44.655083422 +0100
+++ busybox/shell/ash.c	2014-06-09 10:31:21.719083317 +0100
@@ -13025,6 +13025,7 @@
 			setvar2("HOSTNAME", uts.nodename);
 		}
 #endif
+		setvar("LANG", "en_US.UTF-8" , VEXPORT);
 		p = lookupvar("PWD");
 		if (p) {
 			if (*p != '/' || stat(p, &st1) || stat(".", &st2)

whdd-CMakeList.txt.patch

This fixes being unable to specify the ncurses/tinfo location.

--- whdd/CMakeLists.txt.orig	2014-03-31 14:59:10.892772605 +0100
+++ whdd/CMakeLists.txt	2014-03-31 14:18:36.592791777 +0100
@@ -103,13 +103,15 @@
 else (${STATIC})
 
   set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
-  include_directories(${DIALOG_INCLUDE_DIRS})
+  set(CMAKE_PREFIX_PATH ${DIALOG_INCLUDE_DIRS} ${NCURSES_INCLUDE_DIRS} ${CMAKE_PREFIX_PATH})
+  include_directories(${DIALOG_INCLUDE_DIRS} ${NCURSES_INCLUDE_DIRS}/include)
   find_package(DIALOG REQUIRED)
   find_library(MENUW_LIBRARY menuw)
   find_library(NCURSESW_LIBRARY ncursesw)
+  find_library(TINFO_LIBRARY tinfo)
   if(DIALOG_FOUND AND MENUW_LIBRARY AND NCURSESW_LIBRARY)
     target_link_libraries(whdd
-      ${DIALOG_LIBRARIES} ${MENUW_LIBRARY} ${NCURSESW_LIBRARY} rt pthread)
+      ${DIALOG_LIBRARIES} ${MENUW_LIBRARY} ${NCURSESW_LIBRARY} ${TINFO_LIBRARY} rt pthread)
   else()
     message(FATAL_ERROR "Dialog or menuw library not found!")
   endif(DIALOG_FOUND AND MENUW_LIBRARY AND NCURSESW_LIBRARY)

whdd-libdevcheck-libdevcheck.c.patch

Fixes compile bug due to mistake in the struct definition location.

--- whdd/libdevcheck/libdevcheck.c.orig	2014-03-28 11:41:57.689498488 +0000
+++ whdd/libdevcheck/libdevcheck.c	2014-03-28 11:43:14.409501446 +0000
@@ -25,9 +25,9 @@
     dc_log_set_callback(dc_log_default_func, NULL);
     dc_log_set_level(DC_LOG_INFO);
 
+    struct timespec dummy;
 #ifdef HAVE_CLOCK_MONOTONIC_RAW
     /* determine best available clock */
-    struct timespec dummy;
     DC_BEST_CLOCK = CLOCK_MONOTONIC_RAW;
     r = clock_gettime(DC_BEST_CLOCK, &dummy);
     if (r) {

whdd-sliding_window_renderer.c.patch

This stops 'any key' exciting the program when screen blanking comes on so you don't get to see the result.

--- whdd/cui/sliding_window_renderer.c.orig	2014-04-29 11:56:16.403280499 +0100
+++ whdd/cui/sliding_window_renderer.c	2014-04-29 11:55:14.947281000 +0100
@@ -268,10 +268,13 @@
         wprintw(priv->summary, "Aborted.\n");
     else
         wprintw(priv->summary, "Completed.\n");
-    wprintw(priv->summary, "Press any key");
+    wprintw(priv->summary, "Press m for Menu");
     wrefresh(priv->summary);
     beep();
-    getch();
+    int c;
+	do {
+    	c = getchar();
+	} while (c != 'm');
     delwin(priv->legend);
     delwin(priv->access_time_stats);
     delwin(priv->vis);

whdd-whole_space_renderer.c.patch

This stops 'any key' exciting the program when screen blanking comes on so you don't get to see the result.

--- whdd/cui/whole_space_renderer.c.orig	2014-05-12 07:52:06.196851216 +0100
+++ whdd/cui/whole_space_renderer.c	2014-05-12 07:52:11.216851198 +0100
@@ -385,10 +385,13 @@
         wprintw(priv->summary, "Aborted.\n");
     else
         wprintw(priv->summary, "Completed.\n");
-    wprintw(priv->summary, "Press any key");
+    wprintw(priv->summary, "Press m for Menu");
     wrefresh(priv->summary);
     beep();
-    getch();
+    int c;
+	do {
+    	c = getchar();
+	} while (c != 'm');
     delwin(priv->legend);
     delwin(priv->vis);
     delwin(priv->avg_speed);

Makefile

This should be one level below the folder structure's created, see the dir layout

  • Change TCHAIN to where your toolchain is, buildroot ones have hard coded paths, x-tools (crosstools-ng doesn't?)
#####################################################
#
# Makefile -- Top level WHDD Live Makefile	#####
#
# 2014 Richud.com					#####
#
#####################################################
### REMEMBER TOOLCHAIN IS HARDCODED PATHS! ###
## sudo apt-get install byacc flex texinfo groff mklibs ##

########################
#0) Root path of system
########################
ROOT := $(shell pwd)

##################################################
#1) source path, all the extracted program sources 
##################################################
SOURCE := $(ROOT)/source

##########################################################
#2) DESTDIR path for build process, makes 'install' target
##########################################################
DESTDIR := $(ROOT)/destdir

##################################################
#3) folder to create stripped/cleaned initrd image
##################################################
INITRD :=  $(ROOT)/initrd

##############################################################
#4) custom folder for initial run file and misc component bits
##############################################################
CUST :=  $(ROOT)/custom
PATCH = $(ROOT)/patch

######################################################################################
#5) custom folder for output of kernel and ramdisk images (bzImage/initramfs)
######################################################################################
OUTPUT :=  $(ROOT)/output

############################
#6) toolchain and compiler
############################
TCHAIN = /home/rich/x-tools/i386-unknown-linux-uclibc/bin
HOST = i386-unknown-linux-uclibc

#compiler
export CC = $(HOST)-gcc

#stripper
STRIP := $(TCHAIN)/$(HOST)-strip

#path
export PATH+=:$(TCHAIN)

#work out source locations
SOURCEDIRS := $(foreach d, $(wildcard $(SOURCE)/*), echo $(notdir $(d)))

#programs to make, if not here they wont build at all as they are referenced below to find their path
PROGS = ncurses busybox dialog smartmontools whdd

#auto create variables for paths e.g. var generated pigz = pigz-2.3.1
 $(foreach d, $(PROGS) linux, $(eval $(subst -,,$(d))_PATH = $(filter $(d)%,$(SOURCEDIRS))))

#FLAGS
export CFLAGS = -D_GNU_SOURCE -O3 -m32 -march=i386
export CXXFLAGS = -D_GNU_SOURCE -O3 -m32 -march=i386
export LDFLAGS = -L$(SOURCE)/$(ncurses_PATH)/lib -L$(SOURCE)/$(dialog_PATH) -Wl,-rpath,/lib -Wl,--as-needed
export CPPFLAGS = -I$(SOURCE)/$(ncurses_PATH)/include

#laying down filesystem structure for initrd image
DIRS = \
dev/shm dev/pts \
etc/opt etc/init.d \
home \
mnt \
opt \
proc \
sys \
tmp \
usr/root usr/local usr/share/terminfo/l \
var/tmp var/run var/opt var/cache var/lib/misc var/lib/nfs var/local var/log


###################################
## END OF GENERAL CONFIG SECTION ##
###################################

all: progs linux system iso

progs: $(PROGS)

busybox :
	cd "$(SOURCE)/$(busybox_PATH)/" ;\
	for i in $$(ls "$(PATCH)/busybox"*\.patch); do patch -N -p1 < "$$i" &>/dev/null; done ;\
	make defconfig ;\
	sed -i \
	-e "/# Archival Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Debian Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Finding Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Linux Ext2 FS Progs/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Linux Module Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Filesystem\/Volume identification/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Miscellaneous Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Networking Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Common options for /,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Print Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Mail Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Process Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# System Logging Utilities/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_SHA/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	.config ;\
	yes "" | make oldconfig ;\
	make CFLAGS="$(CFLAGS) $(CPPFLAGS)" CROSS_COMPILE=$(HOST)- CONFIG_PREFIX=$(DESTDIR) -j4 install

dialog :
	cd "$(SOURCE)/$(dialog_PATH)" ;\
	./configure --host=$(HOST) --prefix= --with-shared --with-ncursesw --enable-widec --disable-rc-file --with-curses-dir="$(SOURCE)/$(ncurses_PATH)" ;\
	make -j4 && make DESTDIR=$(DESTDIR) install 

linux :
	cd "$(SOURCE)/$(linux_PATH)" ;\
	make mrproper && make i386_defconfig ;\
	sed -i \
	-e "/# IO Schedulers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Power management/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PCI host controller drivers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PC-card bridges/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Networking options/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Core Netfilter/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Xtables/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# IP: Netfilter/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# IPv6: Netfilter/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Queueing/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Classification/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Network testing/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Packet Radio protocols/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Misc devices/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# IEEE 1394/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Distributed Switch/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# MII PHY device drivers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# USB Network Adapters/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Enable WiMAX/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Serial drivers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Non-8250 serial/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PCMCIA character/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PC SMBus host/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Enable PHYLIB/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# ACPI drivers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Texas Instruments/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Watchdog/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# USB-based Watchdog/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PPS support/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PTP clock/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Enable PHYLIB/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Sonics Silicon/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Multifunction/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Frame buffer hardware/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# LED/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# iptables/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Microsoft/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# PHY Subsystem/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Firmware/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# File systems/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# CD-ROM/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Memory Debugging/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Debug Lockups/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Lock Debugging/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# RCU Debugging/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Runtime Testing/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Security options/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Crypto core/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Authenticated Encryption/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Block modes/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Hash modes/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Digest/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Ciphers/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/# Random Number/,/^$$/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_QUOTA/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_.*NOTIFY/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_LOGO/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_AGP/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_DRM/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_FB/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_SND/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_SOUND/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_INPUT_JOYSTICK/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_INPUT_TABLET/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_INPUT_TOUCHSCREEN/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_INPUT_MISC/s/\([A-Z0-9_]*\)=.*/# \1 is not set/" \
	-e "/CONFIG_SATA/s/# \([A-Z0-9_]*\) is not set/\1=y/" \
	-e "/CONFIG_ACPI/s/# \(CONFIG_ACPI\) is not set/\1=y/" \
	-e "/CONFIG_PATA/s/# \([A-Z0-9_]*\) is not set/\1=y/" \
	-e "s/CONFIG_DEFAULT_HOSTNAME=\"(none)\"/CONFIG_DEFAULT_HOSTNAME=\"WHDD Live\"/" \
	.config ;\
	yes "" | make oldconfig ;\
	make CFLAGS="$(CFLAGS) $(CPPFLAGS)" CROSS_COMPILE=$(HOST)- ARCH=i386 -j8 all ;\
	cp "arch/x86/boot/bzImage" $(OUTPUT)

ncurses :
	cd "$(SOURCE)/$(ncurses_PATH)" ;\
	./configure --host=$(HOST) --prefix= --datadir=/usr/share --with-termlib=tinfo --enable-widec --with-shared \
	--without-gpm --without-manpages --without-progs ;\
	make -j4 && make DESTDIR=$(DESTDIR) install 

smartmontools :
	#using SVN
	cd "$(SOURCE)/$(smartmontools_PATH)/smartmontools" ;\
	./autogen.sh ;\
	./configure --host=$(HOST) --prefix= ;\
	make -j4 && make DESTDIR=$(DESTDIR) install 

whdd :
	cd "$(SOURCE)/$(whdd_PATH)" ;\
	for i in $$(ls "$(PATCH)/whdd"*\.patch); do patch -N -p1 < "$$i" &>/dev/null; done ;\
	cmake \
	-DCMAKE_C_COMPILER="$(TCHAIN)/$(HOST)-gcc" \
	-DCMAKE_CXX_COMPILER="$(TCHAIN)/$(HOST)-g++" \
	-DDIALOG_INCLUDE_DIRS="$(SOURCE)/$(dialog_PATH)" \
	-DNCURSES_INCLUDE_DIRS="$(SOURCE)/$(ncurses_PATH)" \
	-DCMAKE_SYSTEM_NAME="Linux" \
	-DCMAKE_FIND_ROOT_PATH="$(TCHAIN)" \
	-DCLI=ON \
	-DCMAKE_INSTALL_PREFIX:PATH= . \
	&& make && make DESTDIR="$(DESTDIR)" install

clean :
	for i in $$(ls -d $(SOURCE)/*); do cd "$$i"; make clean; done
	rm -rf $(DESTDIR)

distclean :
	for i in $$(ls -d $(SOURCE)/*); do cd "$$i"; make distclean; done
	rm -rf $(DESTDIR)

system : 
	#delete initrd build folder 
	$(shell rm -rf "$(INITRD)")
	
	#(re)create folder structure
	$(foreach d,$(DIRS),$(shell mkdir -p $(INITRD)/$(d)))

	#copy ALL files over
	cp -aR $(DESTDIR)/. $(INITRD)/

	#copy custom bits
	cp -a $(CUST)/* $(INITRD)/etc/
	mv $(INITRD)/etc/rcS $(INITRD)/etc/init.d/

	###############
	#cleanup/shrink
	###############

	#uneeded terminals
	rm -rf "$(INITRD)/usr/share/terminfo" && mkdir -p "$(INITRD)/usr/share/terminfo/l"
	cp -a "$(DESTDIR)/usr/share/terminfo/l/linux" "$(INITRD)/usr/share/terminfo/l/"

	#undeeded executables
	rm -rf "$(INITRD)/sbin/smartd" "$(INITRD)/bin/dialog"

	#minimalise target libs linker - ld- needs fixing!! 21 stripped
	cd "$(TCHAIN)/../i386-unknown-linux-uclibc/lib" ;\
	mklibs -d $(INITRD)/lib -D \
	-L "$(SOURCE)/$(ncurses_PATH)/lib" -L "$(SOURCE)/$(dialog_PATH)" -L "$(TCHAIN)/../i386-unknown-linux-uclibc/lib" \
	--ldlib ld-uClibc.so.0 --target $(HOST) $$(find "$(DESTDIR)/bin" "$(DESTDIR)/sbin" -type f -perm /a+x)
	mv "$(INITRD)/ld-uClibc.so.0" "$(INITRD)/lib"

	#fix initd default to initramfs default
	mv $(INITRD)/linuxrc $(INITRD)/init

	#make sure these user customisable files are executable
	cd $(INITRD) && chmod 755 etc/*.sh etc/inittab etc/init.d/rcS

	#cleanup unneeded files
	cd $(INITRD) && rm -rf man share include info lib/*.a lib/*.la

	#strip Executable and Linkable Format files, but not kernel modules if present
	find $(INITRD) -type f ! -iname "*.ko" -exec $(STRIP) {} \; 2> /dev/null

	#reset ownership, cpio archive it and lzma compress initramfs
	cd "$(INITRD)" && find ./ -print | cpio --owner 0.0 --quiet -H newc -o | lzma -9 -z -k -c > $(OUTPUT)/initramfs

iso :
	#generate ISO
	mkdir -p "$(OUTPUT)/isolinux"
	echo "DEFAULT WHDD \n\
	LABEL WHDD \n\
	LINUX /bzImage \n\
	INITRD /initramfs" > "$(OUTPUT)/isolinux/isolinux.cfg"
	find "$(SOURCE)" -name ldlinux.c32 -o -name isolinux.bin -exec cp -a {} "$(OUTPUT)/isolinux" \;
	mkisofs -o "whdd-live.iso" \
	-b "isolinux/isolinux.bin" -c "isolinux/boot.cat" \
	-no-emul-boot -boot-load-size 4 -boot-info-table -R -J -l -V "WHDD Live" "$(OUTPUT)"

/custom folder contents

inittab

::sysinit:/etc/init.d/rcS
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
tty1::respawn:/bin/sh
tty2::respawn:/bin/sh

rcS

#!/bin/sh
#################################
# WHDD	by Andrey Utkin		#
#  Live ISO by Richud.com 2014  #
#################################

#mount system virtual file systems
mount -t proc proc /proc
mount -t sysfs none /sys

#UNIX98 pseudoterminal support
mount -t devpts devpts /dev/pts

#hotplug support with bb mdev
mdev -s
echo /sbin/mdev > /proc/sys/kernel/hotplug

#stop all but EMERG kernel messages to console
echo 1 4 1 7 > /proc/sys/kernel/printk

#startup whdd
/sbin/whdd

Build It

Assuming you have all the files extracted and laid out correctly, just run 'make'.

  • make = build everything i.e. create kernel 'bzImage', programs and system archive 'initramfs' , iso
  • make xxxxx = build program xxxxx (to 'destdir/')
  • make linux = just build (compile) kernel ('output/bzImage')
  • make progs = just build (compile) all the progs ('destdir/')
  • make system = clean/strip/cpio archive programs ('output/initramfs')
  • make iso = create ISO from bzImage and initramfs

Test It (with QEmu)

  • create a 50Mb test 'hard drive' image

qemu-img create -f qcow whdd.qcow 50M

  • fire it up

qemu-system-x86_64 -kernel output/bzImage -initrd output/initramfs -hda whdd.qcow

Selecting the QEMU disk

WHDD screenshot 1.gif

Main menu

WHDD screenshot 3.gif

Show hard drive SMART data

WHDD screenshot 2.gif

Running the 'read test' should produce something like this after a couple of seconds;

WHDD screenshot.gif

Comments

blog comments powered by Disqus