\input{configpres} \section{Grundlagen} \title{Linux Fastboot} \maketitle \subsection{Motivation} \begin{frame} \frametitle{Motivation} \begin{itemize} \item Immer höhere Anforderungen an Energiesparfunktionen \item Laufzeit von Multimediageräten \item Automotiveanwendungen \pause \item \textbf{Lösung:} Im Ruhezustand ausschalten \pause \item \textbf{Aber:} Nutzer sind nicht gewohnt zu ''warten'' \end{itemize} \end{frame} \subsection{Theoretische Grundlagen} \begin{frame} \frametitle{Der erste Schritt: Anforderungsdefinition} \begin{itemize} \item Wo liegt die Obergrenze für die Bootzeit? \item Welche Funktionalität muß nach dieser Zeit zur Verfügung stehen? \item Geschwindigkeit vs. Flexibilität \end{itemize} \end{frame} \begin{frame} \frametitle{Bootprozeß} \includegraphics[height=0.7\textheight]{images/boot_overview.png} \end{frame} \begin{frame} \frametitle{Teilkomponenten des Bootprozesses} \begin{itemize} \item Hardware-Reset \item Bootloader \item Betriebssystem (Laden von Treibern, Einbinden des Dateisystems) \item Startskripte / Applikation \end{itemize} \end{frame} \begin{frame} \frametitle{Kritische Hardwarekomponenten} \begin{itemize} \item Netzteil \item Resetlogik \item Bootlogik / Bootreihenfolge \item Anbindung des Bootmediums \item Anbindung der benötigten Peripherie \end{itemize} \textbf{Wichtig: Die Hardware ist wesentlicher Bestandteil eines Fastbootkonzeptes!!} \end{frame} \begin{frame} \frametitle{Bootloader} \begin{itemize} \item ''Basiskonfiguration'' der CPU \item Aufsetzen der sogenannten ATAGs Struktur \item Flushen der Caches \item Ausschalten der MMU \end{itemize} \end{frame} \begin{frame} \frametitle{Der Linux Kernel} \begin{itemize} \item Viele Funktionen zur Bootzeitoptimierung \item Sehr flexibel \item Kompression \item Möglichkeiten zur Parallelisierung von Initialisierungen \item Ca. 150ms - 250ms bis zum Einbinden des Dateisystems \end{itemize} \end{frame} \begin{frame} \frametitle{Die Applikation} \begin{itemize} \item In bestehenden Systemen oft am meisten Optimierungspotential \item Startskripte \item Linking \end{itemize} \end{frame} \section{Optimierungen} \subsection{Bootloader} \begin{frame}[fragile] \frametitle{Bootloader-Optimierungen (U-Boot) 1} Entfernen von im Feld nicht benötigten Features: \begin{lstlisting} /* include/configs/boardname.h */ [...] #include #undef CONFIG_CMD_NET [...] \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Bootloader-Optimierungen (U-Boot) 2} Verifizieren des Kernel Images: \begin{verbatim} setenv verify n \end{verbatim} Keine Ausgaben der U-Boot Konsole: \begin{verbatim} setenv silent 1 \end{verbatim} Warten auf Nutzereingabe: \begin{verbatim} setenv bootdelay 0 \end{verbatim} \end{frame} \begin{frame} \frametitle{Bootloader-Optimierungen IPL} \begin{itemize} \item Ersetzen eines ''general purpose'' Bootloaders durch einen optimierten IPL \item IPL auch Grundlage für Updatekonzepte aus IPL und ''Rescue Kernel'' \end{itemize} \end{frame} \subsection{Kernel} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: Teilkomponenten} \begin{itemize} \item Konfiguration und Build \item Kompression \item Bootparameter \item Treiberinitialisierungen \item Rootfilesystem \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: Konfiguration} \begin{verbatim} General setup ---> Kernel compression mode --> \end{verbatim} \begin{itemize} \item LZO für Embeddedsysteme sehr interessant \item Kopieren vs. Dekomprimieren \item Für Speichermedien mit wahlfreiem Lesezugriff steht auch ''Execute in Place (XIP)'' zur Verfügung \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: Commandlineparameter} \begin{itemize} \item Delay Loop Calibration: ''lpj=''; Kann auf ARM9 Systemen > 100ms einsparen. \item Parameter zur Analyse der Laufzeit im Bootprozeß: ''initcall\_debug'', ''printk\_time=1'' \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: Delayloop} \begin{verbatim} ... Calibrating delay loop... 99.12 BogoMIPS (lpj=495616) ... \end{verbatim} \end{frame} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: initcall\_debug} \begin{verbatim} calling populate_rootfs+0x0/0x1f8 @ 1 initcall populate_rootfs+0x0/0x1f8 returned 0 after 281 usecs calling timer_init_sysfs+0x0/0x38 @ 1 initcall timer_init_sysfs+0x0/0x38 returned 0 after 590 usecs calling leds_init+0x0/0x3c @ 1 initcall leds_init+0x0/0x3c returned 0 after 488 usecs calling leds_init+0x0/0x50 @ 1 initcall leds_init+0x0/0x50 returned -19 after 1 usecs calling fpe_init+0x0/0x78 @ 1 \end{verbatim} \end{frame} \begin{frame}[fragile] \frametitle{Kerneloptimierungen: printk.time} \begin{verbatim} [ 0.800000] mice: PS/2 mouse device [ 0.810000] rtc-at91sam9 at91_rtt.0: [ 0.820000] rtc-at91sam9 at91_rtt.0: [ 0.830000] TCP cubic registered [ 0.830000] NET: Registered protocol [ 0.830000] rtc-at91sam9 at91_rtt.0: [ 2.610000] VFS: Mounted root (jffs2 [ 2.610000] Freeing init memory: 116K \end{verbatim} \end{frame} \subsection{Dateisystem} \begin{frame}[fragile] \frametitle{InitRAMFS} \begin{verbatim} dir /dev 755 0 0 nod /dev/console 644 0 0 c 5 1 nod /dev/loop0 644 0 0 b 7 0 dir /bin 755 1000 1000 slink /bin/sh busybox 777 0 0 file /bin/busybox initfs/busybox 755 0 0 [...] dir /proc 755 0 0 dir /sys 755 0 0 dir /mnt 755 0 0 \end{verbatim} \end{frame} \begin{frame} \frametitle{UbiFS} \begin{itemize} \item Für Linuxsysteme DAS Flashfilesystem der Wahl \item Geringe Mountzeit \item Power-Fail safe \item ... \end{itemize} \end{frame} \subsection{Applikation} \begin{frame} \frametitle{Optimierungen der Applikation} \begin{itemize} \item Analyse des Startprozesses mit bootchartd \item Ggf. direktes Starten der Applikation mit init= \item Dynamisches vs. statisches Linken \item Pre-Linking bei dynamisch gelinkten Applikationen \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Startskriptaufgaben in der Applikation} \begin{verbatim} ret = mount("sysfs", "/sys", "sysfs", 0, NULL); if(ret < 0) perror("Can't mount sysfs\n"); \end{verbatim} \end{frame} \begin{frame}[fragile] \frametitle{Dynamisches Linken} \begin{enumerate} \item DT\_RPATH Sektion des ELF Executables \item Pfade, die in LD\_LIBRARY\_PATH spezifiziert sind \item DT\_RUNPATH Sektion des ELF Executables \item Binärfile /etc/ld.so.cache \item Defaultpfade /lib und /usr/lib \end{enumerate} \end{frame} \begin{frame}[fragile] \frametitle{Dynamisches Linken: Analyse} \begin{verbatim} $ LD_DEBUG=libs ls 3082: find library=librt.so.1 [0]; searching 3082: search cache=/etc/ld.so.cache 3082: trying file=/lib/librt.so.1 \end{verbatim} \end{frame} \section{Beispiel} \subsection{Analyse des Testsystems} \begin{frame} \frametitle{Testsystem} \begin{itemize} \item ARM9 CPU der Atmel AT91 Serie \item Ausgangspunkt: Busybox Image der Angstrom Distribution \item Speichermedium: NAND-Flash \item Testapplikation: Toggeln eines GPIO über das SysFS GPIO-Interface \end{itemize} \end{frame} \begin{frame} \frametitle{Bootprozeß der AT91 Controller} \includegraphics[height=0.7\textheight]{images/boot_at91_overview.png} \end{frame} \begin{frame} \frametitle{Bootmodi der AT91 Familie} \begin{itemize} \item RomBOOT: Booten über eine interne Bootlogik \item Booten über CS0 des External Bus Interface \end{itemize} \end{frame} \begin{frame} \frametitle{AT91 RomBOOT} \includegraphics[height=0.7\textheight]{images/boot_at91_romboot.png} \end{frame} \begin{frame} \frametitle{Einschaltverhalten / Netzteil} \includegraphics[height=0.7\textheight]{images/at91_netzteil.png} \end{frame} \begin{frame} \frametitle{Resetverhalten} \includegraphics[height=0.7\textheight]{images/at91_reset.png} \end{frame} \begin{frame} \frametitle{RomBOOT} \includegraphics[height=0.7\textheight]{images/at91_romboot_measure.png} \end{frame} \begin{frame} \frametitle{Fazit / Hardwareoptimierungen} \begin{itemize} \item Internen Oszillator für Slowclock verwenden: > 1s Ersparnis \item Booten von CS0: ~100ms - 150ms Ersparnis \end{itemize} \end{frame} \subsection{Optimierung des Testsystems} \begin{frame} \frametitle{Bootzeitmessung mittels GPIO} \includegraphics[width=10cm]{images/gpio_measure.png} \end{frame} \begin{frame} \frametitle{Teilkomponenten der Bottzeitmessungen} \begin{itemize} \item Bootstrap bis U-Boot \item U-Boot bis Early-Boot-Code im Kernel (also inkl. Kopieren des Kernels ins RAM und entpacken des Kernels) \item Kernel bis Applikation (also inkl. Einbinden des Dateisystems) \end{itemize} \end{frame} \begin{frame} \frametitle{Initiales Bootverhalten} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 6,5s \\ \hline Kernel - Applikation & 4,5s \\ \hline \textbf{Gesamt} & \textbf{11s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{U-Boot ohne Netzwerkunterstützung} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 4,25s \\ \hline Kernel - Applikation & 4,5s \\ \hline \textbf{Gesamt} & \textbf{8,75s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{U-Boot verify=n} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 3,89s \\ \hline Kernel - Applikation & 4,5s \\ \hline \textbf{Gesamt} & \textbf{8,39s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{Kernel ''abspecken''} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 3,77s \\ \hline Kernel - Applikation & 4,33s \\ \hline \textbf{Gesamt} & \textbf{8,1s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{Analyse der Startskripte: Bootchartd} \includegraphics[height=0.85\textheight]{images/bootchart.png} \end{frame} \begin{frame} \frametitle{Optimieren der Startskripte} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 3,77s \\ \hline Kernel - Applikation & 3,61 \\ \hline \textbf{Gesamt} & \textbf{7,38s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{LZO komprimiertes InitRAMFS} Die Applikation wird direkt mit init= angestartet. \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Uboot & --- \\ \hline Uboot - Kernel & 3,79s \\ \hline Kernel - Applikation & 0,372s \\ \hline \textbf{Gesamt} & \textbf{4,162s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{Modifizierter AT91 Bootstrap} AT91 Bootstrap startet direkt Linux an. D.h. es wird ohne U-Boot gebootet. \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Kernel & 676ms \\ \hline Kernel - Applikation & 584ms \\ \hline \textbf{Gesamt} & \textbf{1,260s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{lpj=} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Kernel & 676ms \\ \hline Kernel - Applikation & 384ms \\ \hline \textbf{Gesamt} & \textbf{1,060s} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{Keine Ausgaben auf serielle Schnittstelle (quiet)} \begin{table}[!h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Kernel & 524ms \\ \hline Kernel - Applikation & 212ms \\ \hline \textbf{Gesamt} & \textbf{736ms} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{LZO komprimiertes Kernelimage} \begin{table}[h] \centering \begin{tabular}{ | c | c | } \hline Messpunkt & Zeit \\ \hline Bootstrap - Kernel & 444ms \\ \hline Kernel - Applikation & 212ms \\ \hline \textbf{Gesamt} & \textbf{656ms} \\ \hline \end{tabular} \end{table} \end{frame} \begin{frame} \frametitle{Bootverhalten nach den Optimierungen} \includegraphics[height=0.7\textheight]{images/at91_ipl_quiet_lpj_lzo.png} \end{frame} \begin{frame} \frametitle{Fazit} \begin{itemize} \item Linux bietet die optimale Plattform für jeden, der ein modernes Betriebssystem verwenden möchte, aber in weniger als 1s booten muß \item Bereits mit einfachen Optimierungen können mehrere Sekunden gespart werden \item Die Hardware ist wesentlicher Bestandteil eines Fastbootkonzeptes \item Konzept ist weitgehend plattformunabhängig \end{itemize} \end{frame} \input{tailpres}