Merge pull request #150 from mdmillerii/persistent-2

Persistent 2
diff --git a/classes/image-overlay.bbclass b/classes/image-overlay.bbclass
new file mode 100644
index 0000000..1c6137d
--- /dev/null
+++ b/classes/image-overlay.bbclass
@@ -0,0 +1,18 @@
+
+INITRD_IMAGE ?= "core-image-minimal-initramfs"
+INITRD ?= "${DEPLOY_DIR_IMAGE}/${INITRD_IMAGE}-${MACHINE}.cpio.${INITRD_CTYPE}${uboot}"
+
+IMAGE_BASETYPE ?= "squashfs-xz"
+OVERLAY_BASETYPE ?= "ext4"
+
+IMAGE_TYPES_${PN} += "${IMAGE_BASETYPE}"
+
+IMAGE_TYPEDEP_overlay = "${IMAGE_BASETYPE} ${OVERLAY_BASETYPE}"
+IMAGE_TYPES_MASKED += "overlay"
+
+ROOTFS ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_BASENAME}-${MACHINE}.${IMAGE_BASETYPE}"
+
+do_generate_flash[depends] += "${INITRD_IMAGE}:do_rootfs"
+do_generate_flash[depends] += "${PN}:do_rootfs"
+
+addtask generate_flash after do_rootfs before do_build
diff --git a/classes/obmc-phosphor-image_types_uboot.bbclass b/classes/obmc-phosphor-image_types_uboot.bbclass
index 835e890..14e9289 100644
--- a/classes/obmc-phosphor-image_types_uboot.bbclass
+++ b/classes/obmc-phosphor-image_types_uboot.bbclass
@@ -4,44 +4,65 @@
 # the image load address and entry point. Override it here.
 
 oe_mkimage () {
-    mkimage -A ${UBOOT_ARCH} -O linux -T ramdisk -C $2 -n ${IMAGE_NAME} \
+    mkimage -A ${UBOOT_ARCH} -O linux -T ramdisk -C $2 -n ${IMAGE_BASENAME} \
         -a ${INITRD_IMAGE_LOADADDRESS} -e ${INITRD_IMAGE_ENTRYPOINT} \
         -d ${DEPLOY_DIR_IMAGE}/$1 ${DEPLOY_DIR_IMAGE}/$1.u-boot
 }
 
 INITRD_IMAGE_ENTRYPOINT ?= "0x40800000"
 INITRD_IMAGE_LOADADDRESS ?= "${INITRD_IMAGE_ENTRYPOINT}"
+INITRD_LINK_NAME = "${INITRD_IMAGE}-${MACHINE}${INITRAMFS_FSTYPE}"
 
 FLASH_IMAGE_NAME ?= "flash-${MACHINE}-${DATETIME}"
 FLASH_IMAGE_LINK ?= "flash-${MACHINE}"
 
 FLASH_UBOOT_OFFSET ?= "0"
 FLASH_KERNEL_OFFSET ?= "512"
-FLASH_ROOTFS_OFFSET ?= "3072"
+FLASH_INITRD_OFFSET ?= "3072"
+FLASH_ROFS_OFFSET ?= "4864"
+FLASH_RWFS_OFFSET ?= "28672"
+RWFS_SIZE ?= "4096"
 
-IMAGE_POSTPROCESS_COMMAND += "do_generate_flash"
+# $(( ${FLASH_SIZE} - ${FLASH_RWFS_OFFSET} ))
+
+# IMAGE_POSTPROCESS_COMMAND += "do_generate_flash"
 
 do_generate_flash() {
-       kernel="${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}"
-       uboot="${DEPLOY_DIR_IMAGE}/u-boot.${UBOOT_SUFFIX}"
-       rootfs="${DEPLOY_DIR_IMAGE}/${IMAGE_LINK_NAME}.cpio.${IMAGE_CTYPE}.u-boot"
-       if [ ! -f $kernel ]; then
-              bbfatal "Kernel file ${kernel} does not exist"
+       INITRD_CTYPE=${INITRAMFS_CTYPE}
+       ddir="${DEPLOY_DIR_IMAGE}"
+       kernel="${KERNEL_IMAGETYPE}"
+       uboot="u-boot.${UBOOT_SUFFIX}"
+       initrd="${INITRD_LINK_NAME}.cpio.${INITRD_CTYPE}"
+       uinitrd="${initrd}.u-boot"
+       rootfs="${IMAGE_LINK_NAME}.${IMAGE_BASETYPE}"
+       rwfs="rwfs.${OVERLAY_BASETYPE}"
+
+       if [ ! -f $ddir/$kernel ]; then
+              bbfatal "Kernel file ${ddir}/${kernel} does not exist"
        fi
-       if [ ! -f $uboot ]; then
-              bbfatal "U-boot file ${uboot} does not exist"
+       if [ ! -f $ddir/$uboot ]; then
+              bbfatal "U-boot file ${ddir}/${uboot} does not exist"
        fi
-       if [ ! -f $rootfs ]; then
-              bbfatal "Rootfs file ${rootfs} does not exist"
+       if [ ! -f $ddir/$initrd ]; then
+              bbfatal "initrd file ${ddir}/${initrd} does not exist"
+       fi
+       if [ ! -f $ddir/$rootfs ]; then
+              bbfatal "Rootfs file ${ddir}/${rootfs} does not exist"
        fi
 
-       dst="${DEPLOY_DIR_IMAGE}/${FLASH_IMAGE_NAME}"
+       oe_mkimage  "${initrd}" "${INITRD_CTYPE}" || bbfatal "oe_mkimage initrd"
+       dd if=/dev/zero of=${ddir}/${rwfs} bs=1k count=${RWFS_SIZE}
+       mkfs.${OVERLAY_BASETYPE} -b 4096 -F -O^huge_file ${ddir}/${rwfs} || bbfatal "mkfs rwfs"
+
+       dst="${ddir}/${FLASH_IMAGE_NAME}"
        rm -rf $dst
        dd if=/dev/zero of=${dst} bs=1k count=${FLASH_SIZE}
-       dd if=${uboot} of=${dst} bs=1k seek=${FLASH_UBOOT_OFFSET}
-       dd if=${kernel} of=${dst} bs=1k seek=${FLASH_KERNEL_OFFSET}
-       dd if=${rootfs} of=${dst} bs=1k seek=${FLASH_ROOTFS_OFFSET}
-       dstlink="${DEPLOY_DIR_IMAGE}/${FLASH_IMAGE_LINK}"
+       dd if=${ddir}/${uboot} of=${dst} bs=1k seek=${FLASH_UBOOT_OFFSET}
+       dd if=${ddir}/${kernel} of=${dst} bs=1k seek=${FLASH_KERNEL_OFFSET}
+       dd if=${ddir}/${uinitrd} of=${dst} bs=1k seek=${FLASH_INITRD_OFFSET}
+       dd if=${ddir}/${rootfs} of=${dst} bs=1k seek=${FLASH_ROFS_OFFSET}
+       dd if=${ddir}/${rwfs} of=${dst} bs=1k seek=${FLASH_RWFS_OFFSET}
+       dstlink="${ddir}/${FLASH_IMAGE_LINK}"
        rm -rf $dstlink
        ln -sf ${FLASH_IMAGE_NAME} $dstlink
 }
diff --git a/classes/obmc-phosphor-initfs.bbclass b/classes/obmc-phosphor-initfs.bbclass
new file mode 100644
index 0000000..de7923e
--- /dev/null
+++ b/classes/obmc-phosphor-initfs.bbclass
@@ -0,0 +1,4 @@
+# Common code for recipes that implement Phosphor OpenBMC filesystem
+
+RPROVIDES_${PN} += "obmc-phosphor-initfs"
+PROVIDES += "obmc-phosphor-initfs"
diff --git a/common/recipes-bsp/u-boot/u-boot-fw-utils_2013.07.bb b/common/recipes-bsp/u-boot/u-boot-fw-utils_2013.07.bb
new file mode 100644
index 0000000..c8ae846
--- /dev/null
+++ b/common/recipes-bsp/u-boot/u-boot-fw-utils_2013.07.bb
@@ -0,0 +1,55 @@
+#require recipes-bsp/u-boot/u-boot.inc
+
+SUMMARY = "U-Boot bootloader fw_printenv/setenv utilities"
+SECTION = "bootloader"
+DEPENDS = "mtd-utils"
+
+LICENSE = "GPLv2+"
+LIC_FILES_CHKSUM = "file://COPYING;md5=1707d6db1d42237583f50183a5651ecb \
+                    file://README;beginline=1;endline=22;md5=78b195c11cb6ef63e6985140db7d7bab"
+
+# This revision corresponds to the tag "v2013.07"
+# We use the revision in order to avoid having to fetch it from the
+# repo during parse
+# SRCREV = "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c"
+SRCREV="${AUTOREV}"
+
+PV = "v2013.07+git${SRCPV}"
+
+UBRANCH = "v2013.07-aspeed-openbmc"
+SRC_URI = "git://git@github.com/openbmc/u-boot.git;branch=${UBRANCH};protocol=https"
+S = "${WORKDIR}/git"
+
+#INSANE_SKIP_${PN} = "already-stripped"
+#EXTRA_OEMAKE_class-target = 'CROSS_COMPILE=${TARGET_PREFIX} CC="${CC} ${CFLAGS} ${LDFLAGS}" V=1'
+#EXTRA_OEMAKE_class-cross = 'ARCH=${TARGET_ARCH} CC="${CC} ${CFLAGS} ${LDFLAGS}" V=1'
+EXTRA_OEMAKE = 'HOSTCC="${CC}" CC="${CC}" HOSTSTRIP="true"'
+
+inherit uboot-config
+
+do_compile () {
+	oe_runmake ${UBOOT_MACHINE}
+	oe_runmake env
+}
+
+do_install () {
+	install -d ${D}${base_sbindir}
+	install -d ${D}${sysconfdir}
+	install -m 755 ${S}/tools/env/fw_printenv ${D}${base_sbindir}/fw_printenv
+	ln -sf fw_printenv ${D}${base_sbindir}/fw_setenv
+	install -m 0644 ${S}/tools/env/fw_env.config ${D}${sysconfdir}/fw_env.config
+}
+
+#do_install_class-cross () {
+#	install -d ${D}${bindir_cross}
+#	install -m 755 ${S}/tools/env/fw_printenv ${D}${bindir_cross}/fw_printenv
+#	install -m 755 ${S}/tools/env/fw_printenv ${D}${bindir_cross}/fw_setenv
+#}
+
+#SYSROOT_PREPROCESS_FUNCS_class-cross = "uboot_fw_utils_cross"
+#uboot_fw_utils_cross() {
+#	sysroot_stage_dir ${D}${bindir_cross} ${SYSROOT_DESTDIR}${bindir_cross}
+#}
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+#BBCLASSEXTEND = "cross native"
diff --git a/common/recipes-core/images/core-image-minimal-initramfs.bbappend b/common/recipes-core/images/core-image-minimal-initramfs.bbappend
new file mode 100644
index 0000000..90a1c3f
--- /dev/null
+++ b/common/recipes-core/images/core-image-minimal-initramfs.bbappend
@@ -0,0 +1,3 @@
+PACKAGE_INSTALL_remove = "initramfs-live-boot initramfs-live-install initramfs-live-install-efi"
+PACKAGE_INSTALL += "obmc-phosphor-initfs"
+INITRAMFS_FSTYPES = "cpio.${INITRAMFS_CTYPE}"
diff --git a/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh
new file mode 100644
index 0000000..0dc4c35
--- /dev/null
+++ b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-init.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+rodir=run/initramfs/ro
+rwdir=run/initramfs/rw
+upper=$rwdir/cow
+work=$rwdir/work
+
+cd /
+mkdir -p sys proc dev run
+mount dev dev -tdevtmpfs
+mount sys sys -tsysfs
+mount proc proc -tproc
+if ! grep run proc/mounts
+then
+	mount tmpfs run -t tmpfs -o mode=755,nodev
+fi
+
+mkdir -p $rodir $rwdir
+
+cp -rp init shutdown update whitelist bin sbin usr lib etc var run/initramfs
+
+# To start a interactive shell with job control at this point, run
+# getty 38400 ttyS4
+
+findmtd() {
+	m=$(grep -xl "$1" /sys/class/mtd/*/name)
+	m=${m%/name}
+	m=${m##*/}
+	echo $m
+}
+
+env=$(findmtd u-boot-env)
+if test -n $env
+then
+	ln -s /dev/$env /run/mtd:u-boot-env
+	cp /run/mtd:u-boot-env /run/fw_env
+fi
+
+rofs=$(findmtd rofs)
+rwfs=$(findmtd rwfs)
+
+rofst=squashfs
+rwfst=ext4
+
+echo rofs = $rofs $rofst   rwfs = $rwfs $rwfst
+
+if grep -w debug-init-sh /proc/cmdline ||
+	! mount -o rw /dev/mtdblock${rwfs#mtd} $rwdir -t $rwfst
+then
+	echo Please mount the rw file system on $rwdir from this shell
+	while ! sulogin && ! test -f /takeover
+	do
+		echo getty failed, retrying
+	done
+fi
+
+# Touch /takeover in the above getty to become pid 1
+if test -e /takeover
+then
+	export PS1=init#\ 
+	exec /bin/sh
+fi
+
+mount -o ro /dev/mtdblock${rofs#mtd} $rodir -t $rofst
+
+rm -rf $work
+mkdir -p $upper
+mkdir -p $work
+
+mount -t overlay -o lowerdir=$rodir,upperdir=$upper,workdir=$work cow /root
+
+if ! chroot /root /bin/sh -c exit
+then
+	echo 'chroot test failed; invoking emergency shell.'
+	PS1=rescue#\  sulogin
+fi
+
+for f in sys dev proc run
+do
+	mount --move $f root/$f
+done
+
+# switch_root /root /sbin/init
+exec chroot /root /sbin/init
+
diff --git a/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh
new file mode 100644
index 0000000..cc076fd
--- /dev/null
+++ b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-shutdown.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+echo shutdown: "$@"
+
+export PS1=shutdown-sh#\ 
+# exec bin/sh
+
+if [ ! -e /proc/mounts ]
+then
+	mkdir -p /proc
+	mount  proc proc -tproc
+	umount_proc=1
+else
+	umount_proc=
+fi
+
+# remove an empty oldroot, that means we are not invoked from systemd-shutdown
+rmdir /oldroot 2>/dev/null
+
+set -x
+for f in $( awk '/oldroot/ { print $2 }' < /proc/mounts | sort -r )
+do
+	umount $f
+done
+set +x
+
+if test -s /run/fw_env -a -c /run/mtd:u-boot-env -a ! -e /image-u-boot-env &&
+	! cmp /run/mtd:u-boot-env /run/fw_env
+then
+	ln -s /run/fw_env /image-u-boot-env
+fi
+
+if test -x /update && ls image-* > /dev/null 2>&1
+then
+	exec /update ${1+"$@"}
+fi
+
+echo Remaining mounts:
+cat /proc/mounts
+
+test "umount_proc" && umount /proc && rmdir /proc
+
+
+
+# Execute the command systemd told us to ...
+if test -d /oldroot  && test "$1"
+then
+	if test "$1" == kexec
+	then
+		$1 -f -e
+	else
+		$1 -f
+	fi
+fi
+
+
+echo "Execute ${1-reboot} -f if all unounted ok, or exec /init"
+
+export PS1=shutdown-sh#\ 
+exec /bin/sh
diff --git a/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh
new file mode 100755
index 0000000..1122e83
--- /dev/null
+++ b/common/recipes-phosphor/obmc-phosphor-initfs/files/obmc-update.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+echo update: "$@"
+
+export PS1=update-sh#\ 
+# exec /bin/sh
+
+cd /
+if ! test -r /proc/mounts || ! test -f /proc/mounts
+then
+	mkdir -p /proc
+	mount -t proc proc proc
+fi
+if ! test -d /sys/class
+then
+	mkdir -p /sys
+	mount -t sysfs sys sys
+fi
+if ! test -c /dev/null
+then
+	mkdir -p /dev
+	mount -t devtmpfs dev dev
+fi
+while grep mtd /proc/mounts
+do
+	echo 1>&2 "Error: A mtd device is mounted."
+	sulogin
+	# exec /bin/sh
+done
+
+findmtd() {
+	m=$(grep -xl "$1" /sys/class/mtd/*/name)
+	m=${m%/name}
+	m=${m##*/}
+	echo $m
+}
+
+rofs=$(findmtd rofs)
+rwfs=$(findmtd rwfs)
+
+rofst=squahsfs
+rwfst=ext4
+
+if test -n "$rwfs" && test -s whitelist
+then
+
+	mkdir -p rw
+	mount /dev/mtdblock${rwfs#mtd} rw -oro -t $rwfst
+
+	while read f
+	do
+		if ! test -e rw/cow/$f
+		then
+			continue
+		fi
+		d="save/cow/$f"
+		mkdir -p "${d%/*}"
+		cp -rp rw/cow/$f "${d%/*}/"
+	done < whitelist
+
+	umount rw
+fi
+
+
+for f in image-*
+do
+	m=$(findmtd ${f#image-})
+	if test -z "$m"
+	then
+		echo 1>&2  "Unable to find mtd partiton for $f"
+		exec /bin/sh
+	fi
+done
+
+for f in image-*
+do
+	m=$(findmtd ${f#image-})
+	echo "Updating ${f#image-}"
+	# flasheraseall /dev/$m && dd if=$f of=/dev/$m
+	flashcp -v $f /dev/$m
+done
+
+
+if test -d save/cow
+then
+	mount /dev/mtdblock${rwfs#mtd} rw -o rw -t $rwfst
+	cp -rp save/cow/. rw/cow/
+	umount rw
+fi
+
+# Execute the command systemd told us to ...
+if test -d /oldroot && test -x "/sbin/$1" && test -f "/sbin/$1"
+then
+	if test "$1" == kexec
+	then
+		/sbin/$1 -f -e
+	else
+		/sbin/$1 -f
+	fi
+fi
+
+
+echo "Execute ${1-reboot} -f if all is ok"
+
+export PS1=update-sh#\ 
+exec /bin/sh
diff --git a/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist b/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist
new file mode 100644
index 0000000..80f9c81
--- /dev/null
+++ b/common/recipes-phosphor/obmc-phosphor-initfs/files/whitelist
@@ -0,0 +1,8 @@
+/etc/dropbear/dropbear_rsa_host_key
+/etc/systemd/network
+/etc/resolv.conf
+/etc/machine-id
+/etc/passwd
+/etc/group
+/etc/shadow
+/etc/gshadow
diff --git a/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb b/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb
new file mode 100644
index 0000000..68ee00d
--- /dev/null
+++ b/common/recipes-phosphor/obmc-phosphor-initfs/obmc-phosphor-init.bb
@@ -0,0 +1,23 @@
+SUMMARY = "Phosphor OpenBMC pre-init scripts"
+DESCRIPTION = "Phosphor OpenBMC filesytem mount reference implementation."
+PR = "r1"
+
+inherit obmc-phosphor-license
+inherit obmc-phosphor-initfs
+
+S = "${WORKDIR}"
+SRC_URI += "file://obmc-init.sh"
+SRC_URI += "file://obmc-shutdown.sh"
+SRC_URI += "file://obmc-update.sh"
+SRC_URI += "file://whitelist"
+
+do_install() {
+        install -m 0755 ${WORKDIR}/obmc-init.sh ${D}/init
+        install -m 0755 ${WORKDIR}/obmc-shutdown.sh ${D}/shutdown
+        install -m 0755 ${WORKDIR}/obmc-update.sh ${D}/update
+        install -m 0644 ${WORKDIR}/whitelist ${D}/whitelist
+        install -d ${D}/dev
+        mknod -m 622 ${D}/dev/console c 5 1
+}
+
+FILES_${PN} += " /init /shutdown /update /whitelist /dev "
diff --git a/conf/distro/openbmc-phosphor.conf b/conf/distro/openbmc-phosphor.conf
index b59715d..418a98e 100644
--- a/conf/distro/openbmc-phosphor.conf
+++ b/conf/distro/openbmc-phosphor.conf
@@ -7,6 +7,7 @@
 
 GCCVERSION ?= "4.9.3"
 IMAGE_FSTYPES += "cpio.gz"
+IMAGE_FSTYPES += "squashfs-xz"
 IMAGE_LINGUAS = "en-us"
 
 VIRTUAL-RUNTIME_keymaps = ""
diff --git a/conf/machine/include/obmc-bsp-common.inc b/conf/machine/include/obmc-bsp-common.inc
index d7a681c..fb6cc8c 100644
--- a/conf/machine/include/obmc-bsp-common.inc
+++ b/conf/machine/include/obmc-bsp-common.inc
@@ -13,6 +13,13 @@
 
 MACHINEOVERRIDES =. "openbmc:"
 
+IMAGE_FSTYPES += "overlay"
+IMAGE_INSTALL += "u-boot-fw-utils"
+
 IMAGE_CLASSES += "obmc-phosphor-image_types_uboot"
-IMAGE_CTYPE = "lzma"
-IMAGE_FSTYPES += "cpio.${IMAGE_CTYPE}.u-boot"
+IMAGE_CLASSES += "image-overlay"
+
+INITRAMFS_CTYPE ?= "lzma"
+INITRAMFS_FSTYPES += "cpio.${INITRAMFS_CTYPE}"
+
+