diff options
| author | Manuel Traut <manut@linutronix.de> | 2019-01-10 13:40:28 +0100 |
|---|---|---|
| committer | John Ogness <john.ogness@linutronix.de> | 2019-01-28 19:57:21 +0106 |
| commit | b2647cbe2fbc104c8240203a11889aabb5928c23 (patch) | |
| tree | e430dac4353602c7f0f3f091ba0684b8c99eaa3c | |
| parent | 26ab0f47bc9f52687f4790ae2de0ce0ad49716c2 (diff) | |
Device Tree: initial version
This is the initial version of a Device Tree Presentation.
The Presentation includes Background, Scope and Advantages
of Device Tree usage as well as a short explanation of the
Syntax and Usage.
It ends with information about current developments and
references to further information.
Also an excercise for the attendees is defined.
Signed-off-by: Manuel Traut <manut@linutronix.de>
| -rw-r--r-- | images/device-tree-syntax.jpg | bin | 0 -> 121823 bytes | |||
| -rw-r--r-- | kernel-devel/Kconfig | 1 | ||||
| -rw-r--r-- | kernel-devel/dts/Kconfig | 5 | ||||
| -rw-r--r-- | kernel-devel/dts/Makefile | 1 | ||||
| -rw-r--r-- | kernel-devel/dts/pres_devicetree_en.tex | 460 |
5 files changed, 467 insertions, 0 deletions
diff --git a/images/device-tree-syntax.jpg b/images/device-tree-syntax.jpg Binary files differnew file mode 100644 index 0000000..7c708c2 --- /dev/null +++ b/images/device-tree-syntax.jpg diff --git a/kernel-devel/Kconfig b/kernel-devel/Kconfig index bad3308..62d0fe9 100644 --- a/kernel-devel/Kconfig +++ b/kernel-devel/Kconfig @@ -14,4 +14,5 @@ if KERNEL source "kernel-devel/module-basics/Kconfig" source "kernel-devel/uio-driver/Kconfig" source "kernel-devel/kernel-perf/Kconfig" + source "kernel-devel/dts/Kconfig" endif diff --git a/kernel-devel/dts/Kconfig b/kernel-devel/dts/Kconfig new file mode 100644 index 0000000..ea068aa --- /dev/null +++ b/kernel-devel/dts/Kconfig @@ -0,0 +1,5 @@ +config KERNEL_DTS + bool "Kernel Devicetree papers" + default y + help + Papers about kernel DTS diff --git a/kernel-devel/dts/Makefile b/kernel-devel/dts/Makefile new file mode 100644 index 0000000..c7250ca --- /dev/null +++ b/kernel-devel/dts/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_KERNEL_DTS) += pres_devicetree_en.pdf diff --git a/kernel-devel/dts/pres_devicetree_en.tex b/kernel-devel/dts/pres_devicetree_en.tex new file mode 100644 index 0000000..6b6ba5a --- /dev/null +++ b/kernel-devel/dts/pres_devicetree_en.tex @@ -0,0 +1,460 @@ +\input{configpres} + +\title{Device Tree} +\maketitle + +\subsection{Device Tree} + +\begin{frame} +\frametitle{Overview} +\tableofcontents +\end{frame} + +\subsubsection{Background, Scope, Advantages} +\begin{frame} +\frametitle{Open Firmware (OF)} +\begin{itemize} +\item Designed by Sun in the late 1980's +\item Popular on PowerPCs +\item Similar to BIOS or EFI +\item Integrated shell +\item Supports FCode: platform/architecture independent bytecode +\begin{itemize} +\item Boot-time diagnostics +\item Configuration code +\item Device drivers +\end{itemize} +\item Defines a standard way to describe the hardware of a system (Device Tree) +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Device Tree (DT)} +\begin{itemize} +\item HW initialization was hardcoded in C before. +\pause +\item Derived from the device tree format used by OF. +\pause +\item DT spec \url{https://www.devicetree.org/specifications/} +\pause +\item DT spec is implemented by Linux, FreeBSD, zephyr, u-boot, Android. +\pause +\item Human readable source files: .dts and .dtsi +\pause +\item DT compile (dtc) transfers between source and binary (.dtb). +\pause +\item The binary format is called Flattened Device Tree (FDT). +\pause +\item FDT is passed to the kernel, kernel transfers it into an Expandable Device Tree (EDT). +\pause +\item EDT snippets are passed to 'matching' probe functions. +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{DT and Linux} +\begin{description} +\item[1995] sparc/prom/tree.c written by David S. Miller +\pause +\item[2002] ppc64/kernel/prom.c Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner (IBM) +\pause +\item[2005] powerpc/kernel/prom.c copied from ppc64 to powerpc +\pause +\item[2007] Stephen Rothwell started to merge code from different architectures into drivers/of/base.c +\pause +\item[2009] 98 dts files in v2.6.30 (arm64, microblaze, powerpc) +\pause +\item[2011] Grant Likely added OF/DTS support for ARM (32-bit) +\pause +\item[2012] 165 dts files in v3.2 (+x86, +openrisc, +arm) +\pause +\item[2014] 648 dts files in v3.16 (+metag +c6x +arc +xtensa +mips) +\pause +\item[2016] 1199 dts files in v4.9 (+nios2 +h8300 +cris +sh) +\pause +\item[2018] 1612 dts files in v4.20 (-cris -metag +nds32) +\pause +\item[2019] there are still some board files (e.g. arch/arm/mach-omap1/board-nokia770.c) +\end{description} +\pause +DTS as a part of OF became the quasi standard for describing non-iteratable +hardware layouts to the Linux kernel. +\end{frame} + +\begin{frame} +\frametitle{DT Scope} +Split HW specific information from Kernel binary +\begin{itemize} +\item The number and type of CPUs +\item Base addresses and size of RAM +\item Busses and bridges +\item Peripheral device connections +\item Interrupt controllers and IRQ line connections +\item Pin multiplexing +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Advantages} +\begin{itemize} +\item Single kernel can support multiple SoCs +\item Smaller amount of board support code +\item Xilinx FPGA tools do DTS generation +\item U-Boot can inspect and modify FDT before booting +\end{itemize} +\end{frame} + +\subsubsection{Syntax} +\begin{frame}[fragile] +\frametitle{The .dts Syntax} +\includegraphics[width=8cm]{images/device-tree-syntax.jpg} +\\ \tiny Source: http://wiki.dreamrunner.org +\normalsize \\ \url{https://git.kernel.org/pub/scm/utils/dtc/dtc.git/plain/Documentation/dts-format.txt} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Example .dts snippet} +\begin{lstlisting} +hello@1 { + compatible = "virtual,hello", "virtio,hello"; + index = <1>; +}; +\end{lstlisting} +\begin{description} +\item[Label] None defined +\item[Node name] hello +\item[Unit address] 1 +\item[Property 1] + \begin{description} + \item[Name] compatible + \item[Type] String Array + \item[Value] ["virtual,hello", "virtio,hello"] + \end{description} +\item[Property 2] + \begin{description} + \item[Name] index + \item[Type] 32bit Array including 1 Value + \item[Value] 1 + \end{description} +\end{description} +\end{frame} + +\begin{frame}[fragile] +\frametitle{The compatible property} +\begin{lstlisting} +rtc@58 { + compatible = "maxim,ds1338","microchip,mc1338"; +}; +\end{lstlisting} +\begin{itemize} +\item List of strings +\item Needed for each node representing a device +\item Used by the kernel to find a proper device driver +\item First string is the Devicename: "<manufacturer>,<model>" +\item Next strings are compatible devices. +\item Used to allow reuse of existing drivers, but allowing exact name. +\item Use manufacturer names from Documentation/devicetree/bindings/vendor-prefixes.txt +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Addressing} +\begin{lstlisting} +#address-cells = <1>; +#size-cells = <0>; +cpu@0 { + compatible = "arm,cortex-a9"; + reg = <0>; +}; +\end{lstlisting} + +\begin{itemize} +\item \#address-cells and \#size-cells in the parent node define the format of + 'reg' of the child nodes. +\item in the above example reg uses 1 address cell and no size cell +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Overwrite values by label} +\begin{lstlisting} +$ cat mynode.dtsi +/ { + soc { + pic_3: pic@100 { + reg = <0x100 0x20 >; + }; + }; +}; +\end{lstlisting} + +\begin{lstlisting} +$ cat my.dts +#include "my.dtsi" +&pic_3 { + reg = <0x200 0x30 >; +}; +\end{lstlisting} + +\begin{lstlisting} +$ dtc -O dts my.dts +/dts-v1/; +/ { + soc { + pic_3: pic@100 { + reg = <0x200 0x30>; + }; + }; +}; +\end{lstlisting} +\end{frame} + + +\begin{frame} +\frametitle{More complex example} +If deeper understanding is required, + +\url{https://elinux.org/Device_Tree_Usage} + +is a good entry point. Also + +\url{https://elinux.org/Device_Tree_Linux} + +explains some Linux specific details. +\end{frame} + +\begin{frame}[fragile] +\frametitle{Bindings} +The format of all device/bus specific properties are documented: + +Documentation/devicetree/bindings +\end{frame} + +\subsubsection{Usage} + +\begin{frame}[fragile] +\frametitle{Building a DT binary (FDT)} +Out-of-tree with the Device Tree Compiler + +Build a FDT by given DTS +\begin{lstlisting} +$ dtc -o my.dtb my.dts +\end{lstlisting} + +The Device Tree Compilier is also able to convert a FDT binary back to the +human-readable DTS format: +\begin{lstlisting} +$ dtc -o my.dts my.dtb +\end{lstlisting} +OR in-tree using the Kernel Buildsystem (see next slide) +\end{frame} + +\begin{frame}[fragile] +\frametitle{Add a new ARM64 board platform to the kernel} +\begin{lstlisting} +diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms +--- a/arch/arm64/Kconfig.platforms ++++ b/arch/arm64/Kconfig.platforms +@@ -318,4 +318,9 @@ config ARCH_ZYNQMP ++config ARCH_MYNEWBOARD ++ bool "My New Board" ++ help ++ This enables support for my new board ++ +\end{lstlisting} +\begin{lstlisting} +diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile +--- a/arch/arm64/boot/dts/arm/Makefile ++++ b/arch/arm64/boot/dts/arm/Makefile +@@ -5,3 +5,4 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += \ + dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb ++dtb-$(CONFIG_ARCH_MYNEWBOARD) += my-new.dtb +\end{lstlisting} +\begin{lstlisting} +diff --git a/arch/arm64/boot/dts/arm/my-new.dts b/arch/arm64/boot/dts/arm/my-new.dts +new file mode 100644 +--- /dev/null ++++ b/arch/arm64/boot/dts/arm/my-new.dts +@@ -0,0 +1,16 @@ ++/* ARM64 MY BOARD Platform +[..] +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Passing FDT to the kernel} +\begin{itemize} +\item statically linked into the kernel +\begin{lstlisting} +# CONFIG_ARM_APPENDED_DTB and CONFIG_ARM_ATAG_DTB_COMPAT +# needs to be enabled +$ cat arch/arm64/boot/Image arch/arm64/boot/dts/arm/my.dtb \ + >> arch/arm/boot/zImage-dtb +\end{lstlisting} +\pause +\item passed to the kernel at boot time\\ +The bootloader passes the DTB address through r2 +\begin{description} +\item[U-Boot command] boot[mz] <kernel img addr> - <dtb addr> +\item[Barebox variables] bootm.image, bootm.oftree +\end{description} +\pause +\item FIT image - topic for its own, more details in this presentation:\\ + \url{https://elinux.org/images/f/f4/Elc2013_Fernandes.pdf} +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{QEMU and FDT} +Dump dtb +\begin{lstlisting} +$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic -m 512 -smp 2 \ + -device virtio-net-device,netdev=unet \ + -device ivshmem-doorbell,vectors=1,chardev=chid1 \ + -chardev socket,path=/tmp/ivshmem_socket,id=chid1 \ + -kernel /scratch/linux-arm64/arch/arm64/boot/Image \ + -append "console=ttyAMA0 ip=dhcp root=/dev/nfs nfsroot=10.0.2.2:/nfs/debian,nfsvers=3 rw" \ + -machine dumpdtb=my.dtb +\end{lstlisting} +Virtio and ivshmem devices are iteratable. +So they are not dumped into the dtb. + +Starting Qemu with a dtb: +\begin{lstlisting} +$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -nographic \ + -device virtio-net-device,netdev=unet \ + -device ivshmem-doorbell,vectors=1,chardev=chid1 \ + -chardev socket,path=/tmp/ivshmem_socket,id=chid1 \ + -kernel /scratch/linux-arm64/arch/arm64/boot/Image \ + -dtb /tmp/my.dtb +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Match a driver and DT node} +DTS snippet +\begin{lstlisting} +hello@1 { + compatible = "virtual,hello"; +}; +\end{lstlisting} +driver source +\begin{lstlisting} +static int hello_probe(struct platform_device *pdev) { + return 0; +} +static const struct of_device_id hello_match[] = { + { .compatible = "virtual,hello", }, { } +}; +static struct platform_driver hello_driver = { + .driver = { .name = "hello", + .owner = THIS_MODULE, + .of_match_table = hello_match, }, + .probe = hello_probe, +}; +static int __init hello_init(void) { + return platform_driver_register(&hello_driver); +} +module_init(hello_init); +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Reading properties in drivers} +DTS snippet +\begin{lstlisting} +hello@1 { + compatible = "virtual,hello"; + index = <1>; +}; +\end{lstlisting} +driver source +\begin{lstlisting} +static int hello_probe(struct platform_device *pdev) { + int ret; + u32 value; + ret = of_property_read_u32(pdev->dev.of_node, "index", &value); + if (ret < 0) + pr_err("no index specified\n"); + return ret; +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Reading DT/OF properties from userspace} +\begin{lstlisting} +$ tree /proc/device-tree +$ cat /proc/device-tree/compatible +OR +$ tree /sys/firmware/devicetree/base +$ cat /sys/firmware/devicetree/base/compatible +\end{lstlisting} +rebuilding DT from user-space: +\begin{lstlisting} +$ dtc -I fs /sys/firmware/devicetree/base -o my.dts +$ dtc -I fs /sys/firmware/devicetree/base -o my.dtb +\end{lstlisting} +\end{frame} + +\subsubsection{Linux internals} + +\begin{frame} +\frametitle{Source locations} +\begin{description} +\item[DTS files] arch/*/boot/dts/* +\item[Kernel framework] drivers/of/* +\item[Userspace components] 'scripts/dtc' are imported from + \url{https://git.kernel.org/cgit/utils/dtc/dtc.git} +\item[Docs] Documentation/devicetree +\end{description} +\end{frame} + +\subsubsection{Future} +\begin{frame} +\frametitle{Current development} +Device Tree Overlays +\begin{itemize} +\item Needed to support shields. +\item Supported by u-boot, but currently not by the kernel. +\item Status Plumbers Conference '18 \url{https://elinux.org/images/8/86/Overlay_frank.pdf} +\end{itemize} +Device Tree Schema +\begin{itemize} +\item \url{https://elinux.org/images/6/67/Hkg18-120-devicetreeschema-grantlikely-180404144834.pdf} +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Further information} +\begin{itemize} +\item elinux.org Device Tree wiki\\ + \url{https://elinux.org/Device_Tree_Reference} +\item Thomas Petazzoni - Device Tree for Dummies | ELC 2014\\ + \url{https://www.youtube.com/watch?v=uzBwHFjJ0vU}\\ + \url{https://elinux.org/images/f/f9/Petazzoni-device-tree-dummies_0.pdf} +\item \url{https://elinux.org/Device_tree_future} +\item Read 'Documentation/devicetree/bindings/submitting-patches.txt' if you + consider sending sth. related to DT upstream. +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Excercise} +\begin{itemize} +\item Extend the hello module to become a platform driver including a + of match table. +\item Dump the DTB via Qemu and convert it to DTS format. +\item Add a proper node to the DTS + to trigger the probe function of the hello module. +\item Convert the DTS to DTB format and use it to start Qemu. +\item Check that the hello module is loaded automatically + and its probe function was called. +\item Add multiple hello nodes to the Device Tree. + Check how often the init and probe functions are called. +\item Extend the hello module to read a property from the hello DTS node. +\item Add this property to the DTS and check if it's read. +\end{itemize} +\end{frame} + +\input{tailpres} |
