[bootlin/training-materials updates] master: Boot time lab: filesystem optimizations (1ddf301a)

Michael Opdenacker michael.opdenacker at bootlin.com
Wed May 22 22:07:47 CEST 2019


Repository : https://github.com/bootlin/training-materials
On branch  : master
Link       : https://github.com/bootlin/training-materials/commit/1ddf301ae274beb280db5ec47dc80b447004dbe3

>---------------------------------------------------------------

commit 1ddf301ae274beb280db5ec47dc80b447004dbe3
Author: Michael Opdenacker <michael.opdenacker at bootlin.com>
Date:   Wed May 22 22:07:47 2019 +0200

    Boot time lab: filesystem optimizations
    
    Signed-off-by: Michael Opdenacker <michael.opdenacker at bootlin.com>


>---------------------------------------------------------------

1ddf301ae274beb280db5ec47dc80b447004dbe3
 lab-data/boot-time/solutions/busybox.config        |  16 ++-
 .../boot-time-filesystem-optimizations.tex         | 155 +++++++++++++++++++++
 .../boot-time-init-scripts.tex                     |   8 +-
 mk/boot-time.mk                                    |   1 +
 .../boot-time-init-scripts3.tex                    |  18 ++-
 5 files changed, 178 insertions(+), 20 deletions(-)

diff --git a/lab-data/boot-time/solutions/busybox.config b/lab-data/boot-time/solutions/busybox.config
index bf2165c1..1bf9d2e3 100644
--- a/lab-data/boot-time/solutions/busybox.config
+++ b/lab-data/boot-time/solutions/busybox.config
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Busybox version: 1.29.3
-# Wed May 22 11:38:17 2019
+# Wed May 22 18:00:52 2019
 #
 CONFIG_HAVE_DOT_CONFIG=y
 
@@ -222,7 +222,7 @@ CONFIG_GZIP_FAST=0
 # CONFIG_UNIX2DOS is not set
 # CONFIG_DU is not set
 # CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set
-# CONFIG_ECHO is not set
+CONFIG_ECHO=y
 # CONFIG_FEATURE_FANCY_ECHO is not set
 # CONFIG_ENV is not set
 # CONFIG_EXPAND is not set
@@ -630,7 +630,7 @@ CONFIG_DEFAULT_DEPMOD_FILE=""
 # CONFIG_MKSWAP is not set
 # CONFIG_FEATURE_MKSWAP_UUID is not set
 # CONFIG_MORE is not set
-# CONFIG_MOUNT is not set
+CONFIG_MOUNT=y
 # CONFIG_FEATURE_MOUNT_FAKE is not set
 # CONFIG_FEATURE_MOUNT_VERBOSE is not set
 # CONFIG_FEATURE_MOUNT_HELPERS is not set
@@ -672,8 +672,12 @@ CONFIG_DEFAULT_DEPMOD_FILE=""
 # CONFIG_FEATURE_UMOUNT_ALL is not set
 # CONFIG_UNSHARE is not set
 # CONFIG_WALL is not set
-# CONFIG_FEATURE_MOUNT_LOOP is not set
-# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set
+
+#
+# Common options for mount/umount
+#
+CONFIG_FEATURE_MOUNT_LOOP=y
+CONFIG_FEATURE_MOUNT_LOOP_CREATE=y
 # CONFIG_FEATURE_MTAB_SUPPORT is not set
 # CONFIG_VOLUMEID is not set
 # CONFIG_FEATURE_VOLUMEID_BCACHE is not set
@@ -1088,7 +1092,7 @@ CONFIG_HUSH_LOOPS=y
 # CONFIG_HUSH_LOCAL is not set
 # CONFIG_HUSH_RANDOM_SUPPORT is not set
 # CONFIG_HUSH_MODE_X is not set
-CONFIG_HUSH_ECHO=y
+# CONFIG_HUSH_ECHO is not set
 # CONFIG_HUSH_PRINTF is not set
 # CONFIG_HUSH_TEST is not set
 # CONFIG_HUSH_HELP is not set
diff --git a/labs/boot-time-filesystem-optimizations/boot-time-filesystem-optimizations.tex b/labs/boot-time-filesystem-optimizations/boot-time-filesystem-optimizations.tex
new file mode 100644
index 00000000..d770199f
--- /dev/null
+++ b/labs/boot-time-filesystem-optimizations/boot-time-filesystem-optimizations.tex
@@ -0,0 +1,155 @@
+\subchapter{Filesystem optimizations}{See what best filesystem options
+are in terms of boot time}
+
+During this lab, we will compare 3 ways of accessing the root filesystem
+
+\begin{itemize}
+\item Booting from an {\em ext4} filesystem
+\item Booting from a {\em SquashFS} filesystem
+\item Booting from an {\em initramfs}
+\end{itemize}
+
+\section{Tests with ext4 and Squashfs}
+
+First, recompile your kernel with {\em SquashFS} support, and update it
+on the SD card.
+
+Write the size of the \code{zImage} file in the first row of the below table:
+
+\begin{tabular}{| l | l |}
+  \hline
+  Type & zImage size (bytes) \\
+  \hline
+  \hline
+  zImage without initramfs & \\
+  \hline
+  zImage with initramfs & \\
+  \hline
+\end{tabular}
+
+Go to \code{~/boot-time-labs/rootfs}. You should have a \code{rootfs}
+subdirectory where your root filesystem archive has been extracted.
+
+Boot your system with \code{grabserial} and start filling the
+table below:
+
+\begin{tabular}{| l | l | l | r |}
+  \hline
+  Filesystem & Time for \code{Run /playvideo} & Time for \code{First frame decoded} & Time difference\\
+  \hline
+  \hline
+  ext4 & & & \\
+  \hline
+  SquashFS & & & \\
+  \hline
+  Initramfs & & & \\
+  \hline
+\end{tabular}
+
+For {\em SquashFS}, you will have to create an image and copy it to the
+raw partition:
+
+\begin{verbatim}
+sudo apt install squashfs-tools
+cd ~/boot-time-labs/rootfs
+mksquashfs rootfs/ rootfs.sqfs -noappend
+sudo dd if=rootfs.sqfs of=/dev/mmcblk0p2
+\end{verbatim}
+
+Then remove the SD card and boot the board with it as usual, and record
+measurements.
+
+Note that we also made tests with {\em ext2}, but they were very close
+to {\em ext4} ones, at least for very small filesystems like this one.
+So we decided to skip this filesystem here, to save time.
+
+\section{Initramfs tests}
+
+Booting from an {\em initramfs} is completely different. The strong
+advantage here is that the root filesystem will be extracted from an
+archive inside the kernel binary. So instead of several reads from the
+MMC, we will just have one reading (though bigger) the kernel binary.
+This can work well with small root filesystems as ours.
+
+Booting the kernel should be faster too, as we won't need the MMC and
+filesystem drivers at all. So, let's configure the kernel accordingly.
+
+To switch to an initramfs, there are a few things to do though:
+\begin{itemize}
+\item In an initramfs, you cannot have the kernel mount the {\em
+devtmpfs} filesystem mounted automatically on \code{/dev}. We'll mount
+it from our \code{playvideo} script.
+So:
+   \begin{itemize}
+   \item Modify the Busybox configuration to add support for the
+   \code{mount} command (found in \code{Linux System Utilities}), without
+    any additional option.
+   \item Add the following line to the \code{/playvideo} file:\\
+   \code{mount -t devtmpfs nodev /dev}
+   \item Run \code{make} to update your root filesystem and then
+   extract it again in your \code{rootfs} directory.
+   \end{itemize}
+\item Go to the U-Boot command line on your board, and modify the
+kernel parameters:\\
+   \code{setenv bootargs console=ttyO0,115200n8 rdinit=/playvideo}\\
+   \code{root=} and \code{rootwait} are ignored when there is an
+   Initramfs and \code{init} is replaced by \code{rdinit=}.
+   Don't forget to run \code{saveenv}.
+\end{itemize}
+
+Go to \code{~/boot-time-labs/kernel/linux} and run the Linux
+configuration interface:
+
+\begin{itemize}
+  \item In \code{General setup}
+  \begin{itemize}
+     \item Fill \code{Initramfs source file(s)} with
+\code{../../rootfs/rootfs} (or the correct path to the directory
+containing your root filesystem)
+     \item Make sure you set \code{CONFIG_INITRAMFS_COMPRESSION_NONE=y}
+	   to avoid wasting space compressing the initramfs twice.
+  \end{itemize}
+  \item Disable \code{Enable the block layer}
+  \item Disable \code{MMC/SD/SDIO card support}
+  \item We won't have to disable block filesystems as they are no longer
+compiled when block support is disabled.
+\end{itemize}
+
+Rebuild your kernel binary:
+\begin{verbatim}
+make -j8 zImage
+\end{verbatim}
+
+Copy the new kernel image to your SD card and then boot the board. You
+will see that there is a new issue though: the messages from \code{echo}
+and \code{ffmpeg} don't go through. That's probably because
+\code{/dev/console} doesn't exit yet when the script is started.
+
+So, let's fix it in our script. We are redirecting the important
+messages to \code{/dev/console}:
+
+\begin{verbatim}
+#!/bin/sh
+mount -t devtmpfs nodev /dev
+if ! [ -e /dev/video0 ]
+then
+   echo "Waiting for /dev/video0 to be ready..." > /dev/console
+   while ! [ -e /dev/video0 ]
+   do
+       sleep 0.001
+   done
+fi
+echo "Starting ffmpeg" > /dev/console
+ffmpeg -t 10 -f video4linux2 -video_size 544x288 -input_format mjpeg -i /dev/video0 -pix_fmt rgb565le -f fbdev /dev/fb0 2> /dev/console
+/bin/sh
+\end{verbatim}
+
+Now, you should be able to extrat the measures and write them down in
+the table above. If your tests run the same way ours did, the
+initramfs approach should win by a few tens of milliseconds.
+
+Also measure the size of your \code{zImage} file at write it in the
+table at the top of this chapter, to compare with your initial kernel.
+
+Let's choose this solution with an initramfs. There are still many things we can
+accelerate during the execution of the bootloader and execution.
diff --git a/labs/boot-time-init-scripts/boot-time-init-scripts.tex b/labs/boot-time-init-scripts/boot-time-init-scripts.tex
index 9cfc04a1..a3f8b857 100644
--- a/labs/boot-time-init-scripts/boot-time-init-scripts.tex
+++ b/labs/boot-time-init-scripts/boot-time-init-scripts.tex
@@ -323,16 +323,16 @@ Just select the below options, based on what we have in our
 	   if you don't select \code{ash}. Otherwise, compiling
            \code{hush} will fail. 
      \item Select the \code{hush} shell
-     \item Keep only \code{Support if/then/elif/else/fi},
+     \item Keep only \code{Support if/then/elif/else/fi} and
            \code{Support for, while and until loops},
-           \code{echo builtin} and \code{test builtin}.
   \end{itemize}
   \item In \code{Coreutils}:
   \begin{itemize}
      \item Support for the \code{sleep} command, with support for fractional arguments.
+     \item Support for the \code{echo} command, without additional options.
      \item Support for the \code{sync} command, without further options.
            We need this utility if we make changes to the root filesystem.
-     \item Enable \code{test as [}
+     \item Enable \code{test} and \code{test as [}
      \item Disable \code{Extend test to 64 bit}
   \end{itemize}
 \end{itemize}
@@ -362,7 +362,7 @@ If everything works, it's time to boot the system again through
   Step & Duration & Description \\
   \hline
   \hline
-  Init scripts & & Between \code{Run /sbin/init} and \code{Starting ffmpeg} \\
+  Init scripts & & Between \code{Run /playvideo as init process} and \code{Starting ffmpeg} \\
   \hline
   Application & & Between \code{Starting ffmpeg} and \code{First frame decoded} \\
   \hline
diff --git a/mk/boot-time.mk b/mk/boot-time.mk
index c6f06ade..ad3681cf 100644
--- a/mk/boot-time.mk
+++ b/mk/boot-time.mk
@@ -37,6 +37,7 @@ BOOT_TIME_LABS = boot-time-goals \
 		boot-time-toolchain \
 		boot-time-application \
 		boot-time-init-scripts \
+		boot-time-filesystem-optimizations \
 		boot-time-kernel \
 		boot-time-bootloader \
 		boot-time-results
diff --git a/slides/boot-time-init-scripts3/boot-time-init-scripts3.tex b/slides/boot-time-init-scripts3/boot-time-init-scripts3.tex
index ada91766..e8d96ab6 100644
--- a/slides/boot-time-init-scripts3/boot-time-init-scripts3.tex
+++ b/slides/boot-time-init-scripts3/boot-time-init-scripts3.tex
@@ -41,21 +41,19 @@ application and then switch to the final root filesystem with
 \end{frame}
 
 \begin{frame}
-\frametitle{Do not compress your initramfs (1)}
+\frametitle{Do not compress your initramfs}
 \begin{itemize}
 \item If you ship your initramfs inside a compressed kernel image, don't compress
       it \\
       (enable \code{CONFIG_INITRAMFS_COMPRESSION_NONE}).
 \item Otherwise, your initramfs data will be compressed twice, and
-      the kernel will be slightly bigger and will take a little more time to uncompress.
+      the kernel will be bigger and will take a little more time to load
+      and uncompress.
+\item Example on Linux 5.1 with a 2 MB initramfs uncompressed archive
+      on Beagle Bone Black: this allowed to reduce the kernel from 4.8 MB to 4.6 MB
+      and save about 120 ms of boot time.
+\item Older examples:
 \end{itemize}
-\end{frame}
-
-\begin{frame}
-\frametitle{Do not compress your initramfs (2)}
-Tests on Linux 3.13-rc4, measuring the penalty of having a
-\code{gzip} compressed initramfs in a \code{gzip} compressed kernel. \\
-\vfill{}
 \scriptsize
 Beagle Bone Black (ARM, TI AM3359, 1 GHz)
 \begin{tabular}{| l || c | c | c | c | c | }
@@ -129,6 +127,6 @@ and even create an animation!
       geometric shapes on the framebuffer!
 \item Example: {\small \url{https://bootlin.com/pub/code/fb/anim.c}}.
       On a 400 MHz ARM9 system: starts drawing in 10 ms \\
-      size: 24 KB, compiled statically).
+      Size: 24 KB, compiled statically.
 \end{itemize}
 \end{frame}




More information about the training-materials-updates mailing list