\documentclass[aspectratio=169,obeyspaces,spaces,hyphens]{beamer}
\usepackage{minted}
\usepackage{newunicodechar}
\usepackage{hyperref}

\mode<presentation>
\usetheme{Bootlin}

\title{A tour of the ARM architecture and its Linux support}
\authors{Thomas Petazzoni}
\email{thomas.petazzoni@bootlin.com}
\slidesurl{http://bootlin.com/pub/conferences/2017/lca/petazzoni-arm-introduction/}
\conference{Linux Conf Australia 2017}

\begin{document}

\begin{frame}{\insertconference}
  \begin{columns}
    \column{0.6\textwidth}
    \fontsize{19}{19}\selectfont
    A tour of the ARM architecture and its Linux support\\
    \vspace{1cm}
    \fontsize{15}{15}\selectfont
    Thomas Petazzoni \\
    Bootlin \\
    \normalsize
    {\em \insertemail}
    \column{0.4\textwidth}
    \includegraphics[width=0.8\textwidth]{chip.jpg}\\
    \includegraphics[width=0.8\textwidth]{rpi2.jpg}\\
  \end{columns}
\end{frame}

\begin{frame}{Thomas Petazzoni}
  \begin{columns}
    \column{0.6\textwidth}
    \begin{itemize}
    \item Thomas Petazzoni
    \item CTO and Embedded Linux engineer at Bootlin
      \begin{itemize}
      \item Embedded Linux {\bf expertise}
      \item {\bf Development}, consulting and training
      \item Strong open-source focus
      \item Linux kernel contributors, ARM SoC support, kernel
        maintainers
      \end{itemize}
      \onslide<2->{
      \item Since 2012: Linux kernel contributor, adding support for
        {\bf Marvell ARM} processors
      }
      \onslide<3->{
      \item Core contributor to the {\bf Buildroot} project, an embedded
        Linux build system
      }
      \onslide<4->{
      \item From {\bf Toulouse}, France
      }
    \end{itemize}
    \column{0.4\textwidth}
    \begin{center}
      \only<1>{\includegraphics[width=0.7\textwidth]{common/logo-square.pdf}}
      \only<2>{\includegraphics[width=0.7\textwidth]{armada.jpg}}
      \only<3>{\includegraphics[width=0.7\textwidth]{buildroot.png}}
      \only<4>{\includegraphics[width=0.7\textwidth]{toulouse.png}}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{Goal and agenda}
  \begin{itemize}
  \item ARM is everywhere: in your phone, your TV, your router, your
    set-top box, your IoT devices, etc.
    \pause
  \item {\bf Goal}
    \begin{itemize}
    \item ARM is significantly different from x86
    \item More and more Linux developers coming from x86 doing ARM development
    \item Number of misunderstandings
    \end{itemize}
    \pause
  \item {\bf Agenda}
    \begin{itemize}
    \item ARM: from the architecture to the board
    \item Software level: bootloader and Linux kernel support
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{ARM: architecture specification}
  \begin{columns}
    \column{0.6\textwidth}
  \begin{itemize}
  \item {\em ARM Holdings plc} writes the {\bf specification of the
      ARM architecture}
    \begin{itemize}
    \item Instruction-set, including multimedia/DSP oriented
      instructions
    \item MMU
    \item Interrupt and exception handling
    \item Caches
    \item Virtualization
    \item etc.
    \end{itemize}
  \item Over time, improvements of the architecture, with numerous
    versions: ARMv4, ARMv5, ARMv6, ARMv7, ARMv8
  \item Takes the form of voluminous documentation, named {\em ARM
      ARM}, i.e {\em ARM Architecture Reference Manual}
  \end{itemize}
  \column{0.4\textwidth}
  \frame{\includegraphics[width=0.8\textwidth]{arm-arm.png}}
  \end{columns}
\end{frame}

\begin{frame}{ARM cores: an actual implementation}
  \begin{itemize}
  \item {\em ARM Holdings plc} then creates {\bf IP cores} that
    implement the specification
  \item IP core = implementation in VHDL or Verilog of a block of
    hardware logic
  \item Examples:
    \begin{itemize}
    \item ARM926 = implementation of ARMv5
    \item ARM1176 = implementation of ARMv6
    \item Cortex-A15 = implementation of ARMv7-A
    \item Cortex-A53 = implementation of ARMv8-A
    \end{itemize}
  \item Multiple possible {\em implementations} for the same {\em
      architecture specification}
    \begin{itemize}
    \item Example: all of Cortex-A{5,7,8,9,12,15} implement the same
      ARMv7-A architecture (with some additions in some cases)
    \item Cortex-A5 is a low-power lower-performance implementation,
      Cortex-A15 is a very high-performance and more power hungry
      implementation.
    \item Difference in internal implementation: depth of the
      pipeline, out-of-order execution, size of caches, etc.
    \end{itemize}
  \item This is {\bf NOT} hardware: ARM does {\bf not sell silicon}
  \end{itemize}
\end{frame}

\begin{frame}{ARM System-on-Chip}
  \begin{columns}
    \column{0.6\textwidth}
  \begin{itemize}
  \item {\bf System-on-chip}: integrated circuit that integrates all
    components of a computer system
    \begin{itemize}
    \item CPU, but also peripherals: Ethernet, USB, UART, SPI, I2C,
      GPU, display, audio, etc.
    \item Integrated in a single chip: easier to use, more cost
      effective
    \end{itemize}
  \item {\bf SoC vendors}
    \begin{itemize}
    \item {\bf Buy an ARM core} from ARM
    \item Integrate {\bf other IP blocks}, either designed internally,
      or purchased from other vendors
    \item {\bf Create and sell silicon}
    \end{itemize}
  \item {\bf Large} spectrum of SoCs available, addressing very
    different markets: automotive, mobile, industrial, low-power,
    set-top box, etc.
  \end{itemize}
    \column{0.4\textwidth}
    \begin{center}
      \includegraphics[height=0.4\textheight]{soc.pdf}\\
      \includegraphics[height=0.4\textheight]{qualcomm-soc.jpg}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{SoC example: Freescale i.MX6 block diagram}
  \begin{center}
    \includegraphics[height=0.8\textheight]{freescale-imx6-block-diagram.jpg}
  \end{center}
\end{frame}

\begin{frame}{ARM hardware platform}
  \begin{columns}
    \column{0.6\textwidth}
  \begin{itemize}
  \item Even though an SoC is a full {\em system on a chip}, it is
    generally not self-sufficient
    \begin{itemize}
    \item RAM, NAND flash or eMMC, power circuitry
    \item Display panel and touchscreen
    \item WiFi and Bluetooth chip
    \item Ethernet PHY
    \item HDMI transceiver
    \item CAN transceiver
    \item Connectors
    \end{itemize}
  \item SoC connected to a wide variety of peripherals, through various
    {\bf busses}
  \item Laid out on a PCB, with components soldered on it.
  \end{itemize}
  \column{0.4\textwidth}
  \begin{center}
    \includegraphics[width=0.8\textwidth]{chip-block-diagram.png}\\
    \includegraphics[width=0.8\textwidth]{chip-schematics.png}
  \end{center}
  \end{columns}
\end{frame}

\begin{frame}{ARM: from the architecture to the board}
  \begin{center}
    \includegraphics[width=\textwidth]{from-spec-to-board.pdf}
  \end{center}
\end{frame}

\begin{frame}{Examples of ARM boards}
  \begin{columns}
    \column{0.5\textwidth}
    \begin{itemize}
      \onslide<1->{
      \item {\bf RaspberryPi 1}
        \begin{itemize}
        \item SoC: Broadcom 2835
        \item ARM core: ARM1176JZF (single)
        \item ARM architecture: ARMv6
        \end{itemize}
      }
      \onslide<2->{
      \item {\bf RaspberryPi 2}
        \begin{itemize}
        \item SoC: Broadcom 2836
        \item ARM core: Cortex-A7 (quad)
        \item ARM architecture: ARMv7-A
        \end{itemize}
      }
    \end{itemize}
    \column{0.5\textwidth}
    \begin{itemize}
      \onslide<3->{
      \item {\bf C.H.I.P}
        \begin{itemize}
        \item SoC: Allwinner R8
        \item ARM core: Cortex-A8 (single)
        \item ARM architecture: ARMv7-A
        \end{itemize}
      }
      \onslide<4->{
      \item {\bf ESPRESSOBin}
        \begin{itemize}
        \item SoC: Marvell Armada 3700
        \item ARM core: Cortex-A53 (dual)
        \item ARM architecture: ARMv8-A
        \end{itemize}
      }
    \end{itemize}
  \end{columns}
  \begin{center}
    \onslide<1->{
      \includegraphics[width=0.2\textwidth]{rpi1.jpg}
    }
    \onslide<2->{
      \includegraphics[width=0.2\textwidth]{rpi2-2.jpg}
    }
    \onslide<3->{
      \includegraphics[width=0.2\textwidth]{chip.jpg}
    }
    \onslide<4->{
      \includegraphics[width=0.2\textwidth]{espressobin.jpg}
    }
  \end{center}
\end{frame}

\begin{frame}{Software support for hardware layers}
  \begin{itemize}
  \item Asking {\em ``does Linux support ARM?''} {\bf doesn't make} a
    lot of sense
    \pause
  \item Three ``levels'' of hardware, three ``levels'' of software support
    \begin{enumerate}
    \item The {\bf ARM core}
    \item The {\bf SoC}
    \item The {\bf board}
    \end{enumerate}
    \pause
  \item All three levels are needed to support a given hardware
    platform.
  \item Also supporting a platform with just the serial port and
    Ethernet is very different from fully supporting a platform
    (graphics, audio, power management, etc.).
  \end{itemize}
\end{frame}

\begin{frame}{Three ARMv7 variants}
  \begin{enumerate}
  \item {\bf ARMv7-A}, where {\bf A} stands for {\bf Application}
    \begin{itemize}
    \item Full-featured variant designed for complex operating systems
      such as Linux.
    \item Has a memory management unit (MMU), caches, supports ARM and
      Thumb2 instruction sets, high performance, VFP and NEON
      instructions.
    \item Cores: Cortex-A8, Cortex-A15.
    \end{itemize}
    \pause
  \item {\bf ARMv7-M}, where {\bf M} stands for {\bf
      microcontroller}
    \begin{itemize}
    \item Much smaller variant: {\bf no MMU}, no caches until
      recently, supports only Thumb2, low performance but also low
      power.
    \item Cores: Cortex-M3, Cortex-M4, Cortex-M7.
    \item Generally runs bare metal code, or a small real-time
      operating system. Linux has support for them, but requires
      external RAM and flash.
    \end{itemize}
    \pause
  \item {\bf ARMv7-R}, where {\bf R} stands for {\bf
      real-time}
    \begin{itemize}
    \item Reduced version of the {\bf A} profile, with focus on {\em
        deterministic response}
    \item Widely used in storage devices (hard drive and SSD
      controllers)
    \item Typically doesn't run Linux.
    \end{itemize}
  \end{enumerate}
\end{frame}

\begin{frame}{ARMv8}
  \begin{itemize}
  \item Main feature: introduction of {\bf AArch64}, a new instruction
    set, with 64 bits support
    \begin{itemize}
    \item AArch64 support is optional: some ARMv8 cores do not support
      it.
    \end{itemize}
  \item Also supports a mode called {\em AArch32}, which offers
    backward compatibility with {\em ARMv7-A}
  \item ARMv8 cores: Cortex-A32 (32 bits only), Cortex-A53,
    Cortex-A57, Cortex-A72, etc.
  \end{itemize}
\end{frame}

\begin{frame}{From ARMv5 to ARMv8}
  \begin{center}
    \includegraphics[height=0.8\textheight]{V5_to_V8_Architecture.jpg}
  \end{center}
\end{frame}

\begin{frame}{Architecture licensees}
  \begin{itemize}
  \item Most SoC vendors buy {\em ARM cores} from ARM, i.e Cortex-A15
    or Cortex-A57.
  \item A few SoC vendors however have an {\bf architecture license}
  \item They pay a fee to be allowed to {\bf create a CPU core} that
    implements the same CPU architecture, but do not use the {\em ARM
      cores}
  \item Examples:
    \begin{itemize}
    \item Marvell Feroceon (ARMv5, used in Marvell Kirkwood), Marvell
      PJ4 (ARMv7, used in Marvell Armada 370/XP)
    \item Qualcomm Scorpion, Qualcomm Krait (ARMv7)
    \item Apple Swift (ARMv7, used in the A6), Cyclone (ARMv8, used in
      the A7)
    \item NVidia Denver (ARMv8)
    \item Cavium, Broadcom, AppliedMicro, Qualcomm, Samsung (ARMv8)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Architecture licensees: example}
  \begin{center}
    \includegraphics[width=\textwidth]{from-spec-to-board-architecture-license.pdf}
  \end{center}
\end{frame}

\begin{frame}{Lack of standardization}
  \begin{itemize}
  \item ARM architecture specified: {\bf instruction set is compatible}
    between all ARMv7 cores, between all ARMv8 cores
    \begin{itemize}
    \item Can run Linux userspace code built for ARMv7 on any ARMv7
      platform (provided it's not hardware related)
    \item A few optional features (e.g. NEON)
    \item Allows to run Ubuntu (built for ARMv7) on any ARMv7 platform
    \item However, Ubuntu (built for ARMv7) will not run on
      RaspberryPi 1 (ARMv6)
    \end{itemize}
    \pause
  \item However, {\bf almost no standardization} for the other hardware
    components: inside the SoC and on the board.
    \begin{itemize}
    \item Need specific handling at the bootloader and Linux kernel
      level for each SoC and board.
    \item On most ARM SoCs, the hardware inside the chip is
      memory-mapped. No dynamic discovery/enumeration capability.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{No standardization, but lot of HW re-use}
  \begin{itemize}
  \item Compatibility of processor cores: they comply with ARM
    specifications
  \item For the other hardware blocks, SoC vendors very often
    \begin{itemize}
    \item {\bf Purchase IP blocks} from third-party vendors: ARM, Cadence,
      Synopsys, Mentor Graphics, Imagination Technologies, etc.
    \item Extensively {\bf re-use IP blocks} between their different SoCs
    \end{itemize}
  \item Examples:
    \begin{itemize}
    \item Mentor Graphics MUSB (USB gadget controller) is used in TI,
      Allwinner and ST SoCs, but also on Blackfin and some MIPS
      processors
    \item The Marvell SPI controller is re-used in Marvell processors
      shipped over $\sim$15 years, from old ARMv5 Orions to modern ARMv8
      processors.
    \end{itemize}
  \item This allows to massively re-use drivers!
  \item Sometimes not that easy to figure out that two IP blocks in
    different SoCs are actually the same.
  \end{itemize}
\end{frame}

\begin{frame}{BIOS ?}
  \begin{itemize}
  \item In terms of booting process, no standardized {\em BIOS} or
    {\em firmware} like on x86 machines.
  \item Each ARM SoC comes with its own {\bf ROM code} that implements
    a SoC-specific boot mechanism.
  \item The early stages of the boot process are therefore specific to
    each SoC.
  \item In general: capable of loading a small amount of code from
    non-volatile storage (NAND, MMC, USB) into a SRAM internal to the
    processor.
    \begin{itemize}
    \item External DRAM not initialized yet.
    \end{itemize}
  \item Often also provides a recovery method, to {\em unbrick} the
    platform. Over USB, serial or sometimes Ethernet.
  \item Used to load a {\em first stage} bootloader into SRAM, which
    will itself initialize the DRAM and load/run a {\em second stage}
    into DRAM.
  \end{itemize}
\end{frame}

\begin{frame}{Bootloaders}
  \begin{itemize}
  \item Grub(2) typically {\bf not widely used} on ARM
    platforms
  \item {\bf U-Boot}, the de-facto standard, found on most
    development boards and community platforms.
  \item {\bf Barebox}, less widely used, but very interesting.
  \item Homemade bootloaders, especially when
    security/DRM are involved (phone, set-top boxes, etc.)
  \item Grub starts to gain some traction, especially on ARM64, for
    the server market
  \item RaspberryPi is a very special case, with some firmware executed on
    the GPU, and directly loading the Linux kernel.
  \end{itemize}
\end{frame}

\begin{frame}{Bootloaders (2)}
  \begin{itemize}
  \item First stage bootloader provided either by:
    \begin{itemize}
    \item A {\bf separate project}. Example: {\em AT91Bootstrap} for Atmel
      platforms.
    \item {\bf U-Boot/Barebox} itself. Concept of {\em SPL}: minimal
      version of the bootloader that fits in the constraints of the
      first stage.
    \end{itemize}
  \item Interaction with the bootloader typically over the {\bf serial
      port}
    \begin{itemize}
    \item U-Boot and Barebox offer a shell, with bootloader specific
      commands.
    \item Sometimes screen/keyboard interaction possible, but not the
      norm.
    \item Embedded without a serial port is weird!
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Booting process diagram}
  \begin{center}
    \includegraphics[width=\textwidth]{boot-process.pdf}
  \end{center}
\end{frame}

\begin{frame}{Describing hardware}
  \begin{itemize}
  \item On x86, most hardware can be dynamically discovered at run-time
    \begin{itemize}
    \item PCI and USB provide dynamic enumeration capabilities
    \item For the rest, ACPI provides tables describing hardware
    \item Thanks to this, the kernel doesn't need to know in advance
      the hardware it will run on
    \end{itemize}
  \item On ARM, no such mechanism exists at the hardware level
    \begin{itemize}
    \item In the old days (prior to $\sim$2011), the kernel code
      itself contained a description of all HW platforms it had to
      support
    \item In $\sim$2011, the ARM kernel developers switched to a different
      solution for HW description: {\bf Device Tree}
    \item Done together with an effort called {\bf multiplatform ARM
        kernel}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree}
  \begin{itemize}
  \item A {\bf tree of nodes} describing non-discoverable hardware
  \item Providing {\bf information} such as register addresses, interrupt
    lines, DMA channels, type of hardware, etc.
  \item Provided by the {\bf firmware} to the {\bf operating system}
  \item Operating system agnostic, {\bf not Linux specific}
    \begin{itemize}
    \item Can be used by bootloaders, BSDs, etc.
    \end{itemize}
  \item Originates from the PowerPC world, where it has been in use
    for many more years
  \item Source format written by developers (\code{dts}), compiled into a
    binary format understood by operating systems (\code{dtb})
    \begin{itemize}
    \item One \code{.dts} for each HW platform
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Device Tree example}
  \begin{columns}
    \column{0.5\textwidth}
  \begin{block}{sun5i.dtsi}
    \fontsize{6}{6}\selectfont
    \begin{minted}{perl}
/ {
        cpus {
                cpu0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a8";
                        reg = <0x0>;
                };
        };

        soc@01c00000 {
                compatible = "simple-bus";
                ranges;

                uart1: serial@01c28400 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28400 0x400>;
                        interrupts = <2>;
                        clocks = <&apb1_gates 17>;
                        status = "disabled";
                };

                uart3: serial@01c28c00 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28c00 0x400>;
                        interrupts = <4>;
                        clocks = <&apb1_gates 19>;
                        status = "disabled";
                };
                [...]
        };
};
    \end{minted}
  \end{block}
  \column{0.5\textwidth}
  \begin{block}{sun5i-r8-chip.dts}
    \fontsize{6}{6}\selectfont
    \begin{minted}{perl}
/ {
        model = "NextThing C.H.I.P.";
        compatible = "nextthing,chip", "allwinner,sun5i-r8",
                "allwinner,sun5i-a13";

        leds {
                compatible = "gpio-leds";

                status {
                        label = "chip:white:status";
                        gpios = <&axp_gpio 2 GPIO_ACTIVE_HIGH>;
                        default-state = "on";
                };
        };
};

[...]

&uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins_b>;
        status = "okay";
};
    \end{minted}
  \end{block}
  \end{columns}
\end{frame}

\begin{frame}{Device Tree: in practice}
  \begin{itemize}
  \item Used for almost {\bf all ARM platforms} in Linux, and all
    ARM64 ones
  \item Used for a few platforms in bootloaders such as U-Boot or
    Barebox
  \item Device Tree source code {\bf stored in the Linux kernel tree}
    \begin{itemize}
    \item Duplicated in U-Boot/Barebox source code as needed
    \item Plan for a {\em central} repository, but never occurred
    \end{itemize}
  \item Supposed to be {\bf OS-agnostic and therefore backward
      compatible}
    \begin{itemize}
    \item In practice, are changed quite often to accommodate Linux
      kernel changes
    \end{itemize}
  \item Loaded in memory by the bootloader, together with the Linux
    kernel image
  \item Parsed by the Linux kernel at boot time to know which hardware
    is available
  \end{itemize}
\end{frame}

\begin{frame}{Linux kernel}
  \begin{itemize}
  \item Support for the ARM core is generally done by ARM engineers
    themselves
    \begin{itemize}
    \item MMU, caches, virtualization, etc.
    \item In \code{arch/arm} and \code{arch/arm64}
    \item Generally in Linux upstream even before actual ARM SoCs with
      this core are available
    \end{itemize}
  \item Support for the ARM SoC and HW platform is a different story
    \begin{itemize}
    \item Requires drivers for each and every HW block, inside the SoC
      and on the board, in \code{drivers/}
    \item Requires Device Tree descriptions, in
      \code{arch/arm(64)/boot/dts}
    \item Sometimes supported only in vendor forks, sometimes
      supported in the upstream Linux kernel
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Linux kernel: typical support for an SoC}
  \begin{itemize}
  \item Core drivers
    \begin{itemize}
    \item Clock controllers (\code{drivers/clk}), reset controller
      (\code{drivers/reset}), pin-muxing controllers
      (\code{drivers/pinctrl}), interrupt controller
      (\code{drivers/irqchip}), timers (\code{drivers/clocksource}),
      GPIO controllers (\code{drivers/gpio})
      \end{itemize}
  \item Peripheral drivers
    \begin{itemize}
    \item Bus controllers: I2C (\code{drivers/i2c}), SPI
      (\code{drivers/spi}), USB (\code{drivers/usb}), PCI
      (\code{drivers/pci})
    \item Display controller (\code{drivers/gpu/drm}), camera interface
      (\code{drivers/media}), touchscreen or other input devices
      (\code{drivers/input}), Ethernet controller (\code{drivers/net})
    \end{itemize}
  \item Platform code
    \begin{itemize}
    \item On ARM, minimal amount of platform code in
      \code{arch/arm/mach-<foo>} for power management and SMP support
    \item On ARM64, no platform code at all, power management and SMP
      activities handled using {\em PSCI}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Linux kernel: from vendor to upstream}
  \begin{itemize}
  \item Most vendors {\bf fork the Linux kernel}, and add support for
    their SoC to their own fork
  \item Leads to kernel forks with sometimes {\bf millions of added
      lines} for SoC support
    \begin{itemize}
    \item Users {\bf cannot easily change/upgrade} their kernel version
    \item Generally of {\bf poor quality}
    \item Situation got somewhat worse with Android
    \end{itemize}
  \item Some vendors engage with the {\bf upstream} Linux kernel
    community, and submit patches
    \begin{itemize}
    \item More and more vendors taking this direction
    \item Mileage may vary depending on the vendor, and sometimes the SoC family
    \end{itemize}
  \item The {\bf community} also significantly contributes to upstream Linux
    kernel support for ARM SoCs
    \begin{itemize}
    \item Example: Allwinner support is fully community-contributed,
      no involvement from the vendor
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Linux kernel: going multiplatform}
  \begin{itemize}
  \item Originally, on ARM, a compiled kernel image could only boot on
    a reduced set of platforms, all using the same SoC
    \begin{itemize}
    \item Lot of compile-time conditionals
    \end{itemize}
  \item Wish to have a behavior more similar to {\em x86}, with one
    single binary kernel that works for all platforms
  \item Effort started around making the ARM kernel {\bf multiplatform}
    \begin{itemize}
    \item Handle more things at runtime rather than at compile time
    \item Part of a larger cleanup effort: switch to Device Tree,
      addition of numerous driver subsystems
    \end{itemize}
  \item One can now build a single kernel for ARMv4/v5, a single
    kernel for ARMv6/v7, and a single kernel for ARMv8.
    \begin{itemize}
    \item \code{make ARCH=arm multi_v7_defconfig}
    \item And it works!
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Root filesystem}
  \begin{columns}
    \column{0.7\textwidth}
    \begin{itemize}
      \onslide<1->{
      \item Regular desktop-style {\bf distributions}: Debian, Ubuntu, Raspbian,
        Fedora, etc.
      }
      \onslide<2->{
      \item {\bf Specialized} systems: Android, Tizen, etc.
      }
      \onslide<3->{
      \item Embedded Linux {\bf build systems}
        \begin{itemize}
        \item Widely used for embedded systems
        \item Produce a Linux root filesystem through cross-compilation
        \item Allows a much more customized and stripped down system than
          a full-blown distribution
        \item Examples: OpenEmbedded/Yocto, Buildroot, OpenWRT, etc.
        \end{itemize}
      }
    \end{itemize}
    \column{0.3\textwidth}
    \only<1>{
      \includegraphics[width=0.5\textwidth]{ubuntu.png}\\
      \includegraphics[width=0.5\textwidth]{raspbian.png}
    }
    \only<2>{
      \includegraphics[width=0.5\textwidth]{android.png}\\
      \includegraphics[width=0.5\textwidth]{tizen.png}
    }
    \only<3>{
      \includegraphics[width=0.5\textwidth]{yocto.png}\\
      \includegraphics[width=0.5\textwidth]{buildroot.png}
    }
  \end{columns}
\end{frame}

\questionslide

\end{document}
