designs: eMMC storage proposal

Propose a storage design for eMMC flash module.

Change-Id: If694e8d1eac64ec9a84dfd9ca8fcefaf9f5ebc6f
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/designs/emmc-storage-design.md b/designs/emmc-storage-design.md
new file mode 100644
index 0000000..a18d70d
--- /dev/null
+++ b/designs/emmc-storage-design.md
@@ -0,0 +1,138 @@
+# eMMC Storage Design
+
+Author: Adriana Kobylak < anoo! >
+
+Primary assignee: Adriana Kobylak
+
+Other contributors: Joel Stanley < shenki! >
+
+Created: 2019-06-20
+
+## Problem Description
+Proposal to define the storage design for an eMMC device. This includes
+filesystem type, partitioning, volume management, boot options and
+initialization, etc.
+
+## Background and References
+OpenBMC currently supports raw flash such as the SPI NOR found in the systems
+based on AST2400 and AST2500, but there is no design for managed NAND.
+
+## Requirements
+- Security: Ability to enforce read-only, verification of official/signed
+  images for production.
+
+- Updatable: Ensure that the filesystem design allows for an effective and
+  simple update mechanism to be implemented.
+
+- Simplicity: Make the system easy to understand, so that it is easy to
+  develop, test, use, and recover.
+
+- Code reuse: Try to use something that already exists instead of re-inventing
+  the wheel.
+
+## Proposed Design
+- Store U-Boot and the Linux kernel in a separate SPI NOR flash device, since
+  SOCs such as the AST2500 do not support executing U-Boot from an eMMC. In
+  addition, having the Linux kernel on the NOR saves from requiring U-Boot
+  support for the eMMC. The U-Boot and kernel are less than 10MB in size, so a
+  fairly small chip such as a 32MB one would suffice. Therefore, in order to
+  support two firmware versions, the kernel for each version would need to be
+  stored in the NOR. A second NOR device could be added as redundancy in case
+  U-Boot or the kernel failed to run.
+
+  Format the NOR as it is currently done for a system that supports UBI: a fixed
+  MTD partition for U-Boot, one for its environment, and a UBI volume spanning
+  the remaining of the flash. Store the dual kernel volumes in the UBI partition.
+  This approach allows the re-use of the existing code update interfaces, since
+  the static approach does not currently support storing two kernel images.
+  Selection of the desired kernel image would be done with the existing U-Boot
+  environment approach.
+
+  The AST2600 supports executing U-Boot from the eMMC, so that provides the
+  flexibility of just having the eMMC chip on a system, or still have U-Boot in
+  a separate chip for recovery in cases where the eMMC goes bad.
+
+- Filesystem: ext4. This is a stable and widely used filesystem for eMMC. See
+  the Alternatives section below for additional options.
+
+- Volume management: LVM. This allows for dynamic partition/removal, similar to
+  the current UBI implementation. LVM support increases the size of the kernel
+  by ~100kB, but the increase in size is worth the ability of being able to
+  resize the partition if needed. In addition, UBI volume management works in a
+  similar way, so it would not be complex to implement LVM management in the
+  code update application.
+
+- Partitioning: Model the full eMMC as a single device containing logical
+  volumes, instead of fixed-size partitions. This provides flexibility for cases
+  where the contents of a partition outgrow its size. This also means that other
+  firmware images, such as BIOS and PSU, would be stored in volume in the single
+  eMMC device.
+
+- Initramfs: Use an initramfs, which is the default in OpenBMC, to boot the
+  rootfs from a logical volume. An initramfs allows for flexibility if
+  additional boot actions are needed, such as mounting overlays. It also
+  provides a point of departure (environment) to provision and format the eMMC
+  volume(s). To boot the rootfs, the initramfs would search for the desired
+  rootfs volume to be mounted, instead of using the U-Boot environments. Exact
+  details on how the volumes will be named and how the initramfs would determine
+  which one to use are still being developed, and the proposal will be updated
+  for review once that is done.
+
+- Mount points: For firmware images such as BIOS that currently reside in
+  separate SPI NOR modules, the logical volume in the eMMC would be mounted in
+  the same paths as to prevent changes to the applications that rely on that
+  data.
+
+- Code update: Support multiple versions on flash, default to two like the
+  current UBI implementation.
+
+- Provisioning: The eMMC vendor would be provided with an OpenBMC image that can
+  be flashed into the eMMC. The image must have the BMC rootfs, and optionally
+  any additional partitions that the system owner decides to have. Then the
+  vendor would deliver the BMC cards with the eMMC already flashed to
+  manufacturing. At this stage, the system can be code updated to a newer
+  version of firmware. If a use case existed where systems with blank eMMCs
+  would be provided to developers for example, a method of flashing the eMMC
+  from the NOR could be developed, such as adding a rootfs to the NOR.
+  This provisioning is needed since, unlike a NOR chip, the eMMC cannot be
+  removed from the board and flashed by a standard flash programmer.
+
+## Alternatives Considered
+- Filesystem: f2fs (Flash-Friendly File System). The f2fs is an up-and-coming
+  filesystem, and therefore it may be seen as less mature and stable than the
+  ext4 filesystem, although it is unknown how any of the two would perform in an
+  OpenBMC environment. Plans are still in place to try it out to compare the two
+  for OpenBMC.
+
+- No initramfs: It may be possible to boot the rootfs by passing the UUID of the
+  logical volume to the kernel, although a pre-init script[1] will likely still
+  be needed. Therefore, having an initramfs would offer a more standard
+  implementation for initialization.
+
+- Static partitioning for the eMMC: This would avoid the kernel memory overhead
+  to cache the extents mapping the LVM volume where the rootfs resides, but this
+  is probably not significant. In addition, having static partitioning requires
+  committing to a fixed size, without the ability to be able to resize in the
+  future if more space is needed for that partition.
+
+- Static partitioning for the NOR: Static MTD partitions could be created to
+  store the kernel images, but additional work would be required to introduce a
+  new method to select the desired kernel image, because the static layout does
+  not currently have dual image support.
+
+## Impacts
+This design would impact the OpenBMC build process and code update
+internal implementations but should not affect the external interfaces.
+
+- openbmc/linux: Kernel changes to support the eMMC chip and its filesystem.
+- openbmc/openbmc: Changes to create an eMMC image.
+- openbmc/openpower-pnor-code-mgmt: Changes to support updating the new
+  filesystem.
+- openbmc/phosphor-bmc-code-mgmt: Changes to support updating the new
+  filesystem.
+
+## Testing
+Verify OpenBMC functionality in a system containing an eMMC. This system could
+be added to the CI pool.
+
+[1]: https://github.com/openbmc/openbmc/blob/master/meta-phosphor/recipes-phosphor/preinit-mounts/preinit-mounts/init