From e9312e19bf63a2c2676f5d42d20a8e52d4526c99 Mon Sep 17 00:00:00 2001
From: Francis Lam <flam@alum.mit.edu>
Date: Sun, 25 Feb 2018 11:51:19 -0800
Subject: [PATCH] Cleanup of init to support server and desktop

Guarded linuxboot specific init entries
Removed Makefile entries into separate file (conflicts with srcing /etc/config)
Added CONFIG_BOOT_LOCAL/_REMOTE to control interface setup
Fixed CONFIG_TPM usage
---
 Makefile                      |   7 +-
 boards/librem13v2.config      |   1 +
 boards/qemu-coreboot.config   |   8 +-
 boards/qemu-coreboot.mk       |   5 ++
 boards/qemu-linuxboot.config  |  18 +----
 boards/qemu-linuxboot.mk      |  15 ++++
 boards/r630.config            |   1 +
 boards/s2600wf.config         |   1 +
 boards/winterfell.config      |   1 +
 boards/x220.config            |   1 +
 boards/x230.config            |   1 +
 config/busybox.config         |   6 +-
 initrd/bin/kexec-save-default |   4 +-
 initrd/bin/kexec-select-boot  |   6 +-
 initrd/bin/mount-usb          |   6 +-
 initrd/bin/usb-init           |   2 +-
 initrd/etc/functions          |   4 +-
 initrd/etc/motd               |   6 --
 initrd/etc/motd.coreboot      |   6 ++
 initrd/etc/motd.nerf          |   6 ++
 initrd/init                   | 141 ++++++++++++++++++++--------------
 21 files changed, 145 insertions(+), 101 deletions(-)
 create mode 100644 boards/qemu-coreboot.mk
 create mode 100644 boards/qemu-linuxboot.mk
 delete mode 100644 initrd/etc/motd
 create mode 100644 initrd/etc/motd.coreboot
 create mode 100644 initrd/etc/motd.nerf

diff --git a/Makefile b/Makefile
index a371f182..9f256997 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ log_dir		:= $(build)/log
 
 BOARD		?= qemu-coreboot
 CONFIG		:= $(pwd)/boards/$(BOARD).config
+BOARDMAKE	:= $(pwd)/boards/$(BOARD).mk
 
 ifneq "y" "$(shell [ -r '$(CONFIG)' ] && echo y)"
 $(error $(CONFIG): board configuration does not exist)
@@ -18,6 +19,10 @@ endif
 
 include $(CONFIG)
 
+ifneq "y" "$(shell [ ! -r '$(BOARDMAKE)' ] && echo y)"
+include $(BOARDMAKE)
+endif
+
 # Unless otherwise specified, we are building for heads
 CONFIG_HEADS	?= y
 
@@ -112,7 +117,7 @@ endif
 
 # helpful targets for common uses
 linux: $(build)/$(BOARD)/bzImage
-cpio: $(build/$(BOARD)/initrd.cpio.xz
+cpio: $(build)/$(BOARD)/initrd.cpio.xz
 
 # Disable all built in rules
 .SUFFIXES:
diff --git a/boards/librem13v2.config b/boards/librem13v2.config
index eaf3df45..0b7eb675 100644
--- a/boards/librem13v2.config
+++ b/boards/librem13v2.config
@@ -24,3 +24,4 @@ CONFIG_BOOT_KERNEL_ADD="intel_iommu=on"
 CONFIG_BOOT_KERNEL_REMOVE="quiet"
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_LOCAL=y
diff --git a/boards/qemu-coreboot.config b/boards/qemu-coreboot.config
index cedc4fcc..6a768af8 100644
--- a/boards/qemu-coreboot.config
+++ b/boards/qemu-coreboot.config
@@ -24,10 +24,4 @@ CONFIG_LINUX_USB=y
 CONFIG_LINUX_E1000=y
 
 CONFIG_BOOTSCRIPT=/bin/generic-init
-CONFIG_TPM=n
-
-run: coreboot.intermediate
-run: $(build)/$(BOARD)/coreboot.rom
-	qemu-system-x86_64 \
-		--machine q35 \
-		--bios $< \
+CONFIG_BOOT_LOCAL=y
diff --git a/boards/qemu-coreboot.mk b/boards/qemu-coreboot.mk
new file mode 100644
index 00000000..b1c1732c
--- /dev/null
+++ b/boards/qemu-coreboot.mk
@@ -0,0 +1,5 @@
+run: coreboot.intermediate
+run: $(build)/$(BOARD)/coreboot.rom
+	qemu-system-x86_64 \
+		--machine q35 \
+		--bios $< \
diff --git a/boards/qemu-linuxboot.config b/boards/qemu-linuxboot.config
index 7e4461f6..b3adcb79 100644
--- a/boards/qemu-linuxboot.config
+++ b/boards/qemu-linuxboot.config
@@ -34,19 +34,5 @@ CONFIG_BOOT_REQ_HASH=n
 CONFIG_BOOT_REQ_ROLLBACK=n
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
-
-# You can ssh into the qemu instance by running
-# ssh -p 5555 root@localhost
-# The LinuxBoot firmware should set its ip address to 10.0.2.15
-# or run udhcpc to get a qemu address
-
-run: linuxboot.intermediate
-	qemu-system-x86_64 \
-		-machine q35,smm=on  \
-		-global ICH9-LPC.disable_s3=1 \
-		-global driver=cfi.pflash01,property=secure,value=on \
-		-redir tcp:5555::22 \
-		--serial $(or $(SERIAL),/dev/tty) \
-		-drive if=pflash,format=raw,unit=0,file=$(build)/$(BOARD)/linuxboot.rom
-	stty sane
-
+CONFIG_BOOT_REMOTE=y
+CONFIG_BOOT_RECOVERY_SERIAL="/dev/tty0"
diff --git a/boards/qemu-linuxboot.mk b/boards/qemu-linuxboot.mk
new file mode 100644
index 00000000..3eb1b16e
--- /dev/null
+++ b/boards/qemu-linuxboot.mk
@@ -0,0 +1,15 @@
+# You can ssh into the qemu instance by running
+# ssh -p 5555 root@localhost
+# The LinuxBoot firmware should set its ip address to 10.0.2.15
+# or run udhcpc to get a qemu address
+
+run: linuxboot.intermediate
+	qemu-system-x86_64 \
+		-machine q35,smm=on  \
+		-global ICH9-LPC.disable_s3=1 \
+		-global driver=cfi.pflash01,property=secure,value=on \
+		-redir tcp:5555::22 \
+		--serial $(or $(SERIAL),/dev/tty) \
+		-drive if=pflash,format=raw,unit=0,file=$(build)/$(BOARD)/linuxboot.rom
+	stty sane
+
diff --git a/boards/r630.config b/boards/r630.config
index b112818a..aa2b7b64 100644
--- a/boards/r630.config
+++ b/boards/r630.config
@@ -30,3 +30,4 @@ CONFIG_BOOT_REQ_HASH=n
 CONFIG_BOOT_REQ_ROLLBACK=n
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_REMOTE=y
diff --git a/boards/s2600wf.config b/boards/s2600wf.config
index e40203b2..7d943b4b 100644
--- a/boards/s2600wf.config
+++ b/boards/s2600wf.config
@@ -41,3 +41,4 @@ CONFIG_BOOT_REQ_HASH=n
 CONFIG_BOOT_REQ_ROLLBACK=n
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_REMOTE=y
diff --git a/boards/winterfell.config b/boards/winterfell.config
index d946bdfc..5e8f968b 100644
--- a/boards/winterfell.config
+++ b/boards/winterfell.config
@@ -42,6 +42,7 @@ CONFIG_BOOT_REQ_HASH=n
 CONFIG_BOOT_REQ_ROLLBACK=n
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_REMOTE=y
 
 $(build)/$(BOARD)/linuxboot.rom: linuxboot.intermediate
 
diff --git a/boards/x220.config b/boards/x220.config
index b485bfba..be53424c 100644
--- a/boards/x220.config
+++ b/boards/x220.config
@@ -30,3 +30,4 @@ CONFIG_BOOT_KERNEL_ADD="intel_iommu=on"
 CONFIG_BOOT_KERNEL_REMOVE="quiet"
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_LOCAL=y
diff --git a/boards/x230.config b/boards/x230.config
index 228699d2..9baf2e90 100644
--- a/boards/x230.config
+++ b/boards/x230.config
@@ -30,3 +30,4 @@ CONFIG_BOOT_KERNEL_ADD="intel_iommu=on"
 CONFIG_BOOT_KERNEL_REMOVE="quiet"
 CONFIG_BOOT_DEV="/dev/sda1"
 CONFIG_USB_BOOT_DEV="/dev/sdb1"
+CONFIG_BOOT_LOCAL=y
diff --git a/config/busybox.config b/config/busybox.config
index ffef2bcf..cfc4c578 100644
--- a/config/busybox.config
+++ b/config/busybox.config
@@ -470,9 +470,9 @@ CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y
 # CONFIG_BOOTCHARTD is not set
 # CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
 # CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
-CONFIG_HALT=y
-CONFIG_POWEROFF=y
-CONFIG_REBOOT=y
+# CONFIG_HALT is not set
+# CONFIG_POWEROFF is not set
+# CONFIG_REBOOT is not set
 # CONFIG_FEATURE_CALL_TELINIT is not set
 CONFIG_TELINIT_PATH=""
 # CONFIG_INIT is not set
diff --git a/initrd/bin/kexec-save-default b/initrd/bin/kexec-save-default
index 0bbaa100..1668bef4 100755
--- a/initrd/bin/kexec-save-default
+++ b/initrd/bin/kexec-save-default
@@ -45,7 +45,7 @@ fi
 KEY_DEVICES="$paramsdir/kexec_key_devices.txt"
 KEY_LVM="$paramsdir/kexec_key_lvm.txt"
 save_key="n"
-if [ "$CONFIG_TPM" = "y" ]; then
+if [ ! -z "$CONFIG_TPM" ]; then
 	if [ ! -r "$KEY_DEVICES" ]; then
 		read \
 			-n 1 \
@@ -131,7 +131,7 @@ fi
 
 # sign and auto-roll config counter
 extparam=
-if [ "$CONFIG_TPM" = "y" ]; then
+if [ ! -z "$CONFIG_TPM" ]; then
 	extparam=-u
 fi
 kexec-sign-config -p $paramsdir $extparam \
diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot
index 64e57173..6085d1d5 100755
--- a/initrd/bin/kexec-select-boot
+++ b/initrd/bin/kexec-select-boot
@@ -232,7 +232,7 @@ do_boot()
 		die "!!! Missing required boot hashes"
 	fi
 
-	if [ "$CONFIG_TPM" = "y" \
+	if [ ! -z "$CONFIG_TPM" \
 		-a -r "$TMP_KEY_DEVICES" ]; then
 		INITRD=`kexec-boot -b "$bootdir" -e "$option" -i` \
 		|| die "!!! Failed to extract the initrd from boot option"
@@ -262,7 +262,7 @@ while true; do
 	TMP_KEY_DEVICES="/tmp/kexec/kexec_key_devices.txt"
 	TMP_KEY_LVM="/tmp/kexec/kexec_key_lvm.txt"
 
-	if [ "$CONFIG_TPM" = "y" \
+	if [ ! -z "$CONFIG_TPM" \
 		-a ! -r "$TMP_KEY_DEVICES" ]; then
 		# Extend PCR4 as soon as possible
 		tpm extend -ix 4 -ic generic \
@@ -274,7 +274,7 @@ while true; do
 		scan_options
 	fi
 
-	if [ "$CONFIG_TPM" = "y" ]; then
+	if [ ! -z "$CONFIG_TPM" ]; then
 		# Optionally enforce device file hashes
 		if [ -r "$TMP_HASH_FILE" ]; then
 			valid_global_hash="n"
diff --git a/initrd/bin/mount-usb b/initrd/bin/mount-usb
index dd89bfe9..634f3311 100755
--- a/initrd/bin/mount-usb
+++ b/initrd/bin/mount-usb
@@ -8,15 +8,15 @@ if ! lsmod | grep -q ehci_hcd; then
 fi
 if ! lsmod | grep -q ehci_pci; then
 	insmod /lib/modules/ehci-pci.ko \
-	|| die "ehci_pci: module load failed"
+  || die "ehci_pci: module load failed"
 fi
 if ! lsmod | grep -q xhci_hcd; then
 	insmod /lib/modules/xhci-hcd.ko \
-	|| die "ehci_hcd: module load failed"
+	|| die "xhci_hcd: module load failed"
 fi
 if ! lsmod | grep -q xhci_pci; then
 	insmod /lib/modules/xhci-pci.ko \
-	|| die "ehci_pci: module load failed"
+	|| die "xhci_pci: module load failed"
 fi
 if ! lsmod | grep -q usb_storage; then
 	insmod /lib/modules/usb-storage.ko \
diff --git a/initrd/bin/usb-init b/initrd/bin/usb-init
index 5ddfdff1..82fa4244 100755
--- a/initrd/bin/usb-init
+++ b/initrd/bin/usb-init
@@ -4,7 +4,7 @@
 . /etc/functions
 . /etc/config
 
-if [ "$CONFIG_TPM" = "y" ]; then
+if [ ! -z "$CONFIG_TPM" ]; then
 	# Extend PCR4 as soon as possible
 	tpm extend -ix 4 -ic usb
 fi
diff --git a/initrd/etc/functions b/initrd/etc/functions
index f9a6dc09..7ab1043f 100755
--- a/initrd/etc/functions
+++ b/initrd/etc/functions
@@ -17,7 +17,7 @@ recovery() {
 	# but recreate the directory so that new tools can use it.
 	rm -rf /tmp/secret
 	mkdir -p /tmp/secret
-	if [ "$CONFIG_TPM" = y ]; then
+	if [ ! -z "$CONFIG_TPM" ]; then
 		tpm extend -ix 4 -ic recovery
 	fi
 	echo >&2 "!!!!! Starting recovery shell"
@@ -42,7 +42,7 @@ confirm_totp()
 		date=`date "+%Y-%m-%d %H:%M:%S"`
 		seconds=`date "+%s"`
 		half=`expr \( $seconds % 60 \) / 30`
-		if [ "$CONFIG_TPM" != y ]; then
+		if [ -z "$CONFIG_TPM" ]; then
 			TOTP="NO TPM"
 		elif [ "$half" != "$last_half" ]; then
 			last_half=$half;
diff --git a/initrd/etc/motd b/initrd/etc/motd
deleted file mode 100644
index c7748bb7..00000000
--- a/initrd/etc/motd
+++ /dev/null
@@ -1,6 +0,0 @@
- _   _                _          __  _   _ _____ ____  _____ 
-| | | | ___  __ _  __| |___     / / | \ | | ____|  _ \|  ___|
-| |_| |/ _ \/ _` |/ _` / __|   / /  |  \| |  _| | |_) | |_   
-|  _  |  __/ (_| | (_| \__ \  / /   | |\  | |___|  _ <|  _|  
-|_| |_|\___|\__,_|\__,_|___/ /_/    |_| \_|_____|_| \_\_|    
-                                                             
diff --git a/initrd/etc/motd.coreboot b/initrd/etc/motd.coreboot
new file mode 100644
index 00000000..4606e763
--- /dev/null
+++ b/initrd/etc/motd.coreboot
@@ -0,0 +1,6 @@
+  _   _                _          __   ____               _                 _   
+ | | | | ___  __ _  __| |___     / /  / ___|___  _ __ ___| |__   ___   ___ | |_ 
+ | |_| |/ _ \/ _` |/ _` / __|   / /  | |   / _ \| '__/ _ \ '_ \ / _ \ / _ \| __|
+ |  _  |  __/ (_| | (_| \__ \  / /   | |__| (_) | | |  __/ |_) | (_) | (_) | |_ 
+ |_| |_|\___|\__,_|\__,_|___/ /_/     \____\___/|_|  \___|_.__/ \___/ \___/ \__|
+                                                                               
diff --git a/initrd/etc/motd.nerf b/initrd/etc/motd.nerf
new file mode 100644
index 00000000..d9f7933b
--- /dev/null
+++ b/initrd/etc/motd.nerf
@@ -0,0 +1,6 @@
+  _   _                _          __  _   _ _____ ____  _____ 
+ | | | | ___  __ _  __| |___     / / | \ | | ____|  _ \|  ___|
+ | |_| |/ _ \/ _` |/ _` / __|   / /  |  \| |  _| | |_) | |_   
+ |  _  |  __/ (_| | (_| \__ \  / /   | |\  | |___|  _ <|  _|  
+ |_| |_|\___|\__,_|\__,_|___/ /_/    |_| \_|_____|_| \_\_|    
+
diff --git a/initrd/init b/initrd/init
index 217e2690..05b5c7a7 100755
--- a/initrd/init
+++ b/initrd/init
@@ -16,43 +16,10 @@ mkdir /proc /sys /dev /tmp /boot /media 2>&- 1>&-
 mount /dev 2>/dev/ttyprintk
 mount /proc 2>/dev/ttyprintk
 mount /sys 2>/dev/ttyprintk
-mount /sys/firmware/efi/efivars
-
-# Setup the pty psudeo filesystem
-mkdir /dev/pts
-mount /dev/pts 2>/dev/ttyprintk
-
-if [ ! -r /dev/ptmx ]; then
-	ln -s /dev/pts/ptmx /dev/ptmx
-fi
-
-# bring up the ethernet; maybe should do DHCP?
-ifconfig lo 127.0.0.1
-
-insmod /lib/modules/e1000.ko
-ifconfig eth0 10.0.2.15  # qemu
-ifconfig eth0 > /dev/ttyprintk
-
-# Setup the ssh server, allow root logins and log to stderr
-if [ ! -d /etc/dropbear ]; then
-	mkdir /etc/dropbear
-fi
-dropbear -B -R 2>/dev/ttyprintk
 
 # Recovery shells will erase anything from here
 mkdir -p /tmp/secret
 
-# Now it is safe to print a banner
-if [ -r /etc/motd ]; then
-	cat /etc/motd
-	cat /etc/motd > /dev/tty0
-fi
-
-ifconfig eth0 | head -1 > /dev/tty0
-
-# For now we just start a shell
-exec /bin/ash
-
 # Load the date from the hardware clock, setting it in local time
 hwclock -l -s
 
@@ -60,6 +27,25 @@ hwclock -l -s
 . /etc/functions
 . /etc/config
 
+# Configure linuxboot environment
+if [ ! -z "$CONFIG_LINUXBOOT" ]; then
+	mount /sys/firmware/efi/efivars
+
+	# Setup the pty psudeo filesystem
+	mkdir /dev/pts
+	mount /dev/pts 2>/dev/ttyprintk
+
+	if [ ! -r /dev/ptmx ]; then
+		ln -s /dev/pts/ptmx /dev/ptmx
+	fi
+fi
+
+# Setup recovery serial shell
+if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then
+	stty -F "$CONFIG_BOOT_RECOVERY_SERIAL" 115200
+	/bin/sh < "$CONFIG_BOOT_RECOVERY_SERIAL" > "$CONFIG_BOOT_RECOVERY_SERIAL" 2>&1 &
+fi
+
 # Add our boot devices into the /etc/fstab, if they are defined
 # in the configuration file.
 if [ ! -z "$CONFIG_BOOT_DEV" ]; then
@@ -69,35 +55,76 @@ if [ ! -z "$CONFIG_USB_BOOT_DEV" ]; then
 	echo >> /etc/fstab "$CONFIG_USB_BOOT_DEV /media auto defaults,ro 0 0"
 fi
 
-if [ ! -x "$CONFIG_BOOTSCRIPT" ]; then
-	recovery 'Boot script missing?  Entering recovery shell'
-	# just in case...
-	tpm extend -ix 4 -ic recovery
-	exec /bin/ash
+# Now it is safe to print a banner
+if [ ! -z "$CONFIG_LINUXBOOT" ]; then
+	MOTD=/etc/motd.nerf
+else
+	MOTD=/etc/motd.coreboot
+fi
+if [ -r "$MOTD" ]; then
+	cat "$MOTD"
+	if [ ! -z "$CONFIG_BOOT_RECOVERY_SERIAL" ]; then
+		cat "$MOTD" > "$CONFIG_BOOT_RECOVERY_SERIAL"
+	fi
 fi
 
-# If the user has been holding down r, enter a recovery shell
-# otherwise immediately start the configured boot script.
-# We don't print a prompt, since this is a near instant timeout.
-read \
-	-t 0.1 \
-	-n 1 \
-	boot_option
-echo
+# Setup remote attestation interface
+if [ ! -z "$CONFIG_BOOT_REMOTE" ]; then
+  # bring up the ethernet; maybe should do DHCP?
+	ifconfig lo 127.0.0.1
 
-if [ "$boot_option" = "r" ]; then
-	# Start an interactive shell
-	recovery 'User requested recovery shell'
-	# just in case...
-	tpm extend -ix 4 -ic recovery
-	exec /bin/ash
+	if [ -f /lib/modules/e1000.ko ]; then
+		insmod /lib/modules/e1000.ko
+		ifconfig eth0 10.0.2.15  # qemu
+		ifconfig eth0 > /dev/ttyprintk
+
+		# Setup the ssh server, allow root logins and log to stderr
+		if [ ! -d /etc/dropbear ]; then
+			mkdir /etc/dropbear
+		fi
+		dropbear -B -R 2>/dev/ttyprintk
+
+		ifconfig eth0 | head -1 > "$CONFIG_BOOT_RECOVERY_SERIAL"
+	fi
 fi
 
-echo '***** Normal boot:' $CONFIG_BOOTSCRIPT
-exec "$CONFIG_BOOTSCRIPT"
+# Setup local attestation interface
+if [ ! -z "$CONFIG_BOOT_LOCAL" ]; then
+	if [ ! -x "$CONFIG_BOOTSCRIPT" ]; then
+		recovery 'Boot script missing?  Entering recovery shell'
+		# just in case...
+		if [ ! -z "$CONFIG_TPM" ]; then
+			tpm extend -ix 4 -ic recovery
+		fi
+		exec /bin/ash
+	fi
 
-# We should never reach here, but just in case...
-recovery 'Boot script failure?  Entering recovery shell'
+	# If the user has been holding down r, enter a recovery shell
+	# otherwise immediately start the configured boot script.
+	# We don't print a prompt, since this is a near instant timeout.
+	read \
+		-t 0.1 \
+		-n 1 \
+		boot_option
+	echo
+
+	if [ "$boot_option" = "r" ]; then
+		# Start an interactive shell
+		recovery 'User requested recovery shell'
+		# just in case...
+		if [ ! -z "$CONFIG_TPM" ]; then
+			tpm extend -ix 4 -ic recovery
+		fi
+		exec /bin/ash
+	fi
+
+	echo '***** Normal boot:' $CONFIG_BOOTSCRIPT
+	exec "$CONFIG_BOOTSCRIPT"
+fi
+
+recovery 'Entering recovery shell'
 # belts and suspenders, just in case...
-tpm extend -ix 4 -ic recovery
+if [ ! -z "$CONFIG_TPM" ]; then
+	tpm extend -ix 4 -ic recovery
+fi
 exec /bin/ash