+%
+% 13 image types
+%
+
+\section{Image types}
+There used to be one image type for coreboot, as described above. Since this paper was written (2004) there have been many changes. First, the name
+was changed to coreboot, for many reasons. Second, Cache As Ram support (CAR)
+was added for many AMD CPUs, which both simplified and complicated things. Simplification came with the removal of romcc; complication came with the addition of new ways to build.
+
+There are two big additions to the build process and, furthermore, more than two new CONFIG variables to control them.
+
+\begin{itemize}
+\item \begin{verbatim}CONFIG_USE_DCACHE_RAM\end{verbatim}
+
+Set to \texttt{1} to use Cache As Ram (CAR). Defaults to \texttt{0}
+
+\end{itemize}
+
+Before going over the new image types, derived from v3, we will quickly review the standard v2 image types. We are hoping this review will
+aid comprehension.
+
+A coreboot rom file consists of one or more \textit{images}. All images consist of a part that runs in ROM, and a part that runs in RAM. The RAM can be in compressed form and is decompressed when needed by the ROM code. The main function of the ROM code is to get memory working. Both ROM and RAM consist of a very small amount of assembly code and mostly C code.
+
+\subsection{romcc images (from emulation/qemu)}
+ROMCC images are so-called because C code for the ROM part is compiled with romcc. romcc is an optimizing C compiler which compiles one, and only
+one file; to get more than one file, one must include the C code via include statements. The main ROM code .c file is usually called auto.c.
+\subsubsection{How it is built}
+Romcc compiles auto.c to produce auto.inc. auto.inc is included in the main crt0.S, which is then preprocessed to produce crt0.s. The inclusion of files into crt0.S is controlled by the CONFIG\_CRT0\_INCLUDES variable. crt0.s is then assembled.
+
+File for the ram part are compiled in a conventional manner.
+
+The final step is linking. The use of named sections is used very heavily in coreboot to control where different bits of code go. The reset vector must go in the top 16 bytes. The start portion of the ROM code must go in the top 64K bytes, since most chipsets only enable this much ROM at startup time. Here is a quick look at a typical image:
+\begin{verbatim}
+ [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
+ [ 0] NULL 00000000 000000 000000 00 0 0 0
+ [ 1] .ram PROGBITS ffff0000 001000 005893 00 WA 0 0 1
+ [ 2] .rom PROGBITS ffff5893 006893 00029d 00 AX 0 0 16
+ [ 3] .reset PROGBITS fffffff0 006ff0 000010 00 A 0 0 1
+ [ 4] .id PROGBITS ffffffd1 006fd1 00001f 00 A 0 0 1
+ [ 5] .shstrtab STRTAB 00000000 007000 000030 00 0 0 1
+ [ 6] .symtab SYMTAB 00000000 007170 000c30 10 7 37 4
+ [ 7] .strtab STRTAB 00000000 007da0 000bfd 00 0 0 1
+\end{verbatim}
+
+The only sections that get loaded into a ROM are the Allocated ones. We can see the .ram, .rom, .reset and .id sections.
+\subsubsection{layout}
+As we mentioned, the ROM file consists of multiple images. In the basic file, there are two full coreboot rom images. The build sequence for each is the same, and in fact the ldscript.ld files are almost identical. The only difference is in a few makefile variables, generated by the config tool.
+
+\begin{itemize}
+\item CONFIG\_PAYLOAD\_SIZE. Each image may have a different payload size.
+\item CONFIG\_ROMBASE Each image must have a different base in rom.
+\item CONFIG\_RESET Unclear what this is used for.
+\item CONFIG\_EXCEPTION\_VECTORS where an optional IDT might go.
+\item CONFIG\_USE\_OPTION\_TABLE if set, an option table section will be linked in.
+\item CONFIG\_ROM\_PAYLOAD\_START This is the soon-to-be-deprecated way of locating a payload. cbfs eliminates this.
+\item CONFIG\_USE\_FALLBACK\_IMAGE Whether this is a fallback or normal image
+\item CONFIG\_ROM\_SECTION\_SIZE Essentially, the payload size. Soon to be deprecated.
+\item CONFIG\_ROM\_IMAGE\_SIZE Size of this image (i.e. fallback or normal image)
+\item CONFIG\_ROM\_SIZE Total size of the ROM
+\item CONFIG\_XIP\_RAM\_BASE The start of eXecute In Place code. XIP allows for not copying code to ram, but just running it from ROM.
+\end{itemize}
+
+Each image (normal or fallback) is built completely independently and does not get linked to the other. They are assembled into one ROM image by the (soon to be deprecated) buildrom tool, or by the cbfs tool.
+
+\subsubsection{boot sequence}
+We boot and start at fffffff0. We then jump to the entry point at \_start. \_start does some machine init and an lgdt and jumps to \_\_protected\_start, at which point we are in protected mode. The code does a bit more machine setup and then starts executing the romcc code.
+
+If fallback has been built in, some setup needs to be done. On some machines, it is extensive. Full rom decoding must be enabled. This may in turn require additional PCI setup to enable decoding to be enabled (!). To decided which image to use, hardware registers (cold boot on the Opteron) or CMOS are checked. Finally, once the image to use has been decided, a jmp is performed, viz:
+\begin{verbatim}
+ /* This is the primary cpu how should I boot? */
+ else if (do_normal_boot()) {
+ goto normal_image;
+ }
+ else {
+ goto fallback_image;
+ }
+ normal_image:
+ __asm__ volatile ("jmp __normal_image"
+ : /* outputs */
+ : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
+ );
+
+ fallback_image:
+#if CONFIG_HAVE_FAILOVER_BOOT==1
+ __asm__ volatile ("jmp __fallback_image"
+ : /* outputs */
+ : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
+ )
+#endif
+ ;
+\end{verbatim}
+How does the fallback image get the symbol for normal entry? Via magic in the ldscript.ld -- remember, the images are not linked to each other.
+Finally, we can see this in the Config.lb for most mainboards:
+\begin{verbatim}
+if CONFIG_USE_FALLBACK_IMAGE
+ mainboardinit cpu/x86/16bit/reset16.inc
+ ldscript /cpu/x86/16bit/reset16.lds
+else
+ mainboardinit cpu/x86/32bit/reset32.inc
+ ldscript /cpu/x86/32bit/reset32.lds
+end
+\end{verbatim}
+What does this mean? the non-fallback image has a 32-bit entry point; fallback has a 16-bit entry point. The reason for this is that some code from fallback always runs, so as to pick fallback or normal; but the normal is always called from 32-bit code.
+\subsection{car images (from lippert/roadrunner-lx)}
+CAR images in their simplest form are modified romcc images. The file is usually cache\_as\_ram\_auto.c. C inclusion is still used. The main difference is in the build sequence. The compiler command line is a very slight changed: instead of using romcc to generate an auto.inc include file, gcc us used. Then, two perl scripts are used to rename the .text and .data sections to .rom.text and .rom.data respectively.
+\subsubsection{How it is built}
+The build is almost identical to the romcc build. Since the auto.inc file exists, it can be included as before. The crt0\_includes.h file has one addition: a file that enables CAR, in this case it is \textit{src/cpu/amd/model\_lx/cache\_as\_ram.inc}.
+\subsubsection{layout}
+No significant change from romcc code.
+\subsubsection{boot sequence}
+No significant change from romcc code, except that the CAR code has to set up a stack.
+
+\subsection{car + CONFIG\_USE\_INIT images (new emulation/qemu}
+This type of image makes more use of the C compiler. In this type of image, in fact,
+seperate compilation is possible but is not always used. Oddly enough, this option is only used in PPC boards. That said, we need to move to this way of building. Including C code is poor style.
+\subsubsection{How it is built}
+There is a make variable, INIT-OBJECTS, that for all our other targets is empty. In this type of build, INIT-OBJECTS is a list of C files that are created from the config tool initobject command. Again, with INIT-OBJECTS we can finally stop including .c files and go with seperate compilation.
+\subsubsection{layout}
+No significant change from romcc code.
+\subsubsection{boot sequence}
+No significant change from romcc code, except that the CAR code has to set up a stack.
+
+\subsubsection{layout}
+No significant change from romcc code.
+\subsubsection{boot sequence}
+No significant change from romcc code, except that the CAR code has to set up a stack.
+\subsection{failover}
+Failover is the newest way to lay out a ROM. The choice of which image to run is removed from the fallback image and moved into a small, standalone piece of code. The code is simple enough to show here:
+\begin{verbatim}
+static unsigned long main(unsigned long bist)
+{
+ if (do_normal_boot())
+ goto normal_image;
+ else
+ goto fallback_image;
+
+normal_image:
+ __asm__ __volatile__("jmp __normal_image" : : "a" (bist) : );
+
+cpu_reset:
+ __asm__ __volatile__("jmp __cpu_reset" : : "a" (bist) : );
+
+fallback_image:
+ return bist;
+}
+
+\end{verbatim}
+Some motherboards have a more complex bus structure (e.g. Opteron). In those cases, the failover can be more complex, as it requires some hardware initialization to work correctly. As of this writing (April 2009), these boards have their own failover:
+\begin{quote}
+./src/mainboard/iei/nova4899r/failover.c
+./src/mainboard/emulation/qemu-x86/failover.c
+./src/mainboard/supermicro/x6dhr\_ig/failover.c
+./src/mainboard/supermicro/x6dai\_g/failover.c
+./src/mainboard/supermicro/x6dhe\_g2/failover.c
+./src/mainboard/supermicro/x6dhr\_ig2/failover.c
+./src/mainboard/supermicro/x6dhe\_g/failover.c
+./src/mainboard/dell/s1850/failover.c
+./src/mainboard/intel/xe7501devkit/failover.c
+./src/mainboard/intel/jarrell/failover.c
+./src/mainboard/olpc/btest/failover.c
+./src/mainboard/olpc/rev\_a/failover.c
+./src/mainboard/via/epia-m/failover.c
+\end{quote}
+Here is one of the more complicated ones:
+\begin{verbatim}
+static unsigned long main(unsigned long bist)
+{
+ /* Did just the cpu reset? */
+ if (memory_initialized()) {
+ if (last_boot_normal()) {
+ goto normal_image;
+ } else {
+ goto cpu_reset;
+ }
+ }
+
+ /* This is the primary cpu how should I boot? */
+ else if (do_normal_boot()) {
+ goto normal_image;
+ }
+ else {
+ goto fallback_image;
+ }
+ normal_image:
+ asm volatile ("jmp __normal_image"
+ : /* outputs */
+ : "a" (bist) /* inputs */
+ : /* clobbers */
+ );
+ cpu_reset:
+ asm volatile ("jmp __cpu_reset"
+ : /* outputs */
+ : "a"(bist) /* inputs */
+ : /* clobbers */
+ );
+ fallback_image:
+ return bist;
+}
+
+\end{verbatim}
+They're not that different, in fact. So why are there different copies all over the tree? Simple: code inclusion. Most of the failover.c are different because they include different bits of code. Here is a key reason for killing C code inclusion in the tree.
+\subsubsection{How it is built}
+There two additional config variables:
+\begin{itemize}
+\item HAVE\_FAILOVER\_IMAGE Has to be defined when certain files are included.
+\item USE\_FAILOVER\_IMAGE Enables the use of the failover image
+\end{itemize}
+Confusingly enough, almost all the uses of these two variables are either nested or both required to be set, e.g.
+The fallback and normal builds are the same. The target config has a new clause that looks like this:
+\begin{verbatim}
+romimage "failover"
+ option CONFIG_USE_FAILOVER_IMAGE=1
+ option CONFIG_USE_FALLBACK_IMAGE=0
+ option CONFIG_ROM_IMAGE_SIZE=CONFIG_FAILOVER_SIZE
+ option CONFIG_XIP_ROM_SIZE=CONFIG_FAILOVER_SIZE
+ option COREBOOT_EXTRA_VERSION="\$(shell cat ../../VERSION)\_Failover"
+end
+\end{verbatim}
+This new section uses some constructs not yet discussed in detail. XIP\_ROM\_SIZE just refers to the
+fact that the failover code is eXecute In Place, i.e. not copied to RAM. Of course, the ROM part of normal/fallback is as well, so the usage of XIP here is somewhat confusing. Finally, the USE\_FAILOVER\_IMAGE variable is set, which changes code compilation in a few places. If we just consider non-mainbard files, there are:
+\begin{verbatim}
+src/cpu/amd/car/cache_as_ram.inc
+src/arch/i386/Config.lb
+\end{verbatim}
+For the cache\_as\_ram.inc file, the changes relate to the fact that failover code sets up CAR, so that fallback code need not.
+
+For the Config.lb, several aspects of build change.
+When USE\_FAILOVER\_IMAGE, entry into both normal and fallback bios images is via a 32-bit entry point (when not defined, entry into fallback is a 16-entry point at the power-on reset vector).
+\subsubsection{layout}
+Failover.c becomes the new bootblock at the top of memory. It calls either normal or fallback. The address of normal and fallback is determined by ldscript magic.
+\subsubsection{boot sequence}
+failover.c tests a few variables and the calls the normal or fallback payload depending on those variables; usually they are CMOS settings.
+\subsection{Proposed new image forat}
+The new image format will use seperate compilation -- no C code included! -- on all files.
+
+The new design has a few key goals:
+\begin{itemize}
+\item Always use a bootblock (currently called failover).
+The name failover.c, being utterly obscure, will not be used; instead, we will name the file bootblock.c. Instead of having a different copy for each mainboard, we can have just one copy.
+\item Always use seperate compilation
+\item Always use printk etc. in the ROM code
+\item (longer term) from the bootblock, always use cbfs to locate the normal/fallback etc. code. This code will be XIP.
+\end{itemize}