diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/README.plan9 | 18 | ||||
-rw-r--r-- | doc/README.srio-pcie-boot-corenet | 34 | ||||
-rw-r--r-- | doc/README.trace | 361 | ||||
-rw-r--r-- | doc/device-tree-bindings/exynos/dwmmc.txt | 54 | ||||
-rw-r--r-- | doc/device-tree-bindings/input/cros-ec-keyb.txt | 79 | ||||
-rw-r--r-- | doc/device-tree-bindings/misc/cros-ec.txt | 38 | ||||
-rw-r--r-- | doc/mkimage.1 | 73 | ||||
-rw-r--r-- | doc/uImage.FIT/sign-configs.its | 45 | ||||
-rw-r--r-- | doc/uImage.FIT/sign-images.its | 42 | ||||
-rw-r--r-- | doc/uImage.FIT/signature.txt | 382 | ||||
-rw-r--r-- | doc/uImage.FIT/verified-boot.txt | 104 |
11 files changed, 1213 insertions, 17 deletions
diff --git a/doc/README.plan9 b/doc/README.plan9 new file mode 100644 index 0000000000..2d3d0e0cf6 --- /dev/null +++ b/doc/README.plan9 @@ -0,0 +1,18 @@ +Plan 9 from Bell Labs kernel images require additional setup to pass +configuration information to the kernel. An environment variable named +confaddr must be defined with the same value as CONFADDR (see mem.h). +Use of this facility is optional, but should be preferable to manual +configuration. + +When booting an image, arguments supplied to the bootm command will be +copied to CONFADDR. If no arguments are specified, the contents of the +bootargs environment variable will be copied. + +If no command line arguments or bootargs are defined, CONFADDR is left +uninitialized to permit manual configuration. For example, PC-style +configuration could be simulated by issuing a fatload in bootcmd: + + # setenv bootcmd fatload mmc 0 $confaddr plan9.ini; ...; bootm + +Steven Stallion +June 2013 diff --git a/doc/README.srio-pcie-boot-corenet b/doc/README.srio-pcie-boot-corenet index cd7e7ee9b3..2b1f76b8d0 100644 --- a/doc/README.srio-pcie-boot-corenet +++ b/doc/README.srio-pcie-boot-corenet @@ -21,13 +21,13 @@ Environment of the SRIO or PCIE boot: e) Slave's RCW should configure the SerDes for SRIO or PCIE boot port, set the boot location to SRIO or PCIE, and holdoff all the cores. - ---------- ----------- ----------- - | | | | | | - | | | | | | + ----------- ----------- ----------- + | | | | | | + | | | | | | | NorFlash|<----->| Master |SRIO or PCIE | Slave |<---->[EEPROM] - | | | |<===========>| | - | | | | | | - ---------- ----------- ----------- + | | | |<===========>| | + | | | | | | + ----------- ----------- ----------- The example based on P4080DS platform: Two P4080DS platforms can be used to implement the boot from SRIO or PCIE. @@ -87,26 +87,32 @@ How to use this feature: Please refer to the examples given above. 2. U-Boot image's compilation. - For master, U-Boot image should be generated normally. + For master, U-Boot image should be generated normally. - For example, master U-Boot image used on P4080DS should be compiled with + For example, master U-Boot image used on P4080DS should be compiled with make P4080DS_config. - For slave, U-Boot image should be generated specifically by + For slave, U-Boot image should be generated specifically by make xxxx_SRIO_PCIE_BOOT_config. - For example, slave U-Boot image used on P4080DS should be compiled with + For example, slave U-Boot image used on P4080DS should be compiled with make P4080DS_SRIO_PCIE_BOOT_config. 3. Necessary modifications based on a specific environment. - For a specific environment, the addresses of the slave's U-Boot image, - UCode, ENV stored in master's NorFlash, and any other configurations - can be modified in the file: - include/configs/corenet_ds.h. + For a specific environment, the addresses of the slave's U-Boot image, + UCode, ENV stored in master's NorFlash, and any other configurations + can be modified in the file: + include/configs/corenet_ds.h. 4. Set and save the environment variable "bootmaster" with "SRIO1", "SRIO2" or "PCIE1", "PCIE2", "PCIE3" for master, and then restart it in order to perform the role as a master for boot from SRIO or PCIE. + +NOTE: When the Slave's ENV parameters are stored in Master's NorFlash, + it can fetch them through PCIE or SRIO interface. But the ENV + parameters can not be modified by "saveenv" or other commands under + the Slave's u-boot environment, because the Slave can not erase, + write Master's NorFlash by PCIE or SRIO link. diff --git a/doc/README.trace b/doc/README.trace new file mode 100644 index 0000000000..b535c06566 --- /dev/null +++ b/doc/README.trace @@ -0,0 +1,361 @@ +# +# Copyright (c) 2013 The Chromium OS Authors. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundatio; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +Tracing in U-Boot +================= + +U-Boot supports a simple tracing feature which allows a record of excecution +to be collected and sent to a host machine for analysis. At present the +main use for this is to profile boot time. + + +Overview +-------- + +The trace feature uses GCC's instrument-functions feature to trace all +function entry/exit points. These are then recorded in a memory buffer. +The memory buffer can be saved to the host over a network link using +tftpput or by writing to an attached memory device such as MMC. + +On the host, the file is first converted with a tool called 'proftool', +which extracts useful information from it. The resulting trace output +resembles that emitted by Linux's ftrace feature, so can be visually +displayed by pytimechart. + + +Quick-start using Sandbox +------------------------- + +Sandbox is a build of U-Boot that can run under Linux so it is a convenient +way of trying out tracing before you use it on your actual board. To do +this, follow these steps: + +Add the following to include/configs/sandbox.h (if not already there) + +#define CONFIG_TRACE +#define CONFIG_CMD_TRACE +#define CONFIG_TRACE_BUFFER_SIZE (16 << 20) +#define CONFIG_TRACE_EARLY_SIZE (8 << 20) +#define CONFIG_TRACE_EARLY +#define CONFIG_TRACE_EARLY_ADDR 0x00100000 + +Build sandbox U-Boot with tracing enabled: + +$ make FTRACE=1 O=sandbox sandbox_config +$ make FTRACE=1 O=sandbox + +Run sandbox, wait for a bit of trace information to appear, and then capture +a trace: + +$ ./sandbox/u-boot + + +U-Boot 2013.04-rc2-00100-ga72fcef (Apr 17 2013 - 19:25:24) + +DRAM: 128 MiB +trace: enabled +Using default environment + +In: serial +Out: serial +Err: serial +=>trace stats + 671,406 function sites + 69,712 function calls + 0 untracked function calls + 73,373 traced function calls + 16 maximum observed call depth + 15 call depth limit + 66,491 calls not traced due to depth +=>trace stats + 671,406 function sites + 1,279,450 function calls + 0 untracked function calls + 950,490 traced function calls (333217 dropped due to overflow) + 16 maximum observed call depth + 15 call depth limit + 1,275,767 calls not traced due to depth +=>trace calls 0 e00000 +Call list dumped to 00000000, size 0xae0a40 +=>print +baudrate=115200 +profbase=0 +profoffset=ae0a40 +profsize=e00000 +stderr=serial +stdin=serial +stdout=serial + +Environment size: 117/8188 bytes +=>sb save host 0 trace 0 ${profoffset} +11405888 bytes written in 10 ms (1.1 GiB/s) +=>reset + + +Then run proftool to convert the trace information to ftrace format. + +$ ./sandbox/tools/proftool -m sandbox/System.map -p trace dump-ftrace >trace.txt + +Finally run pytimechart to display it: + +$ pytimechart trace.txt + +Using this tool you can zoom and pan across the trace, with the function +calls on the left and little marks representing the start and end of each +function. + + +CONFIG Options +-------------- + +- CONFIG_TRACE + Enables the trace feature in U-Boot. + +- CONFIG_CMD_TRACE + Enables the trace command. + +- CONFIG_TRACE_BUFFER_SIZE + Size of trace buffer to allocate for U-Boot. This buffer is + used after relocation, as a place to put function tracing + information. The address of the buffer is determined by + the relocation code. + +- CONFIG_TRACE_EARLY + Define this to start tracing early, before relocation. + +- CONFIG_TRACE_EARLY_SIZE + Size of 'early' trace buffer. Before U-Boot has relocated + it doesn't have a proper trace buffer. On many boards + you can define an area of memory to use for the trace + buffer until the 'real' trace buffer is available after + relocation. The contents of this buffer are then copied to + the real buffer. + +- CONFIG_TRACE_EARLY_ADDR + Address of early trace buffer + + +Building U-Boot with Tracing Enabled +------------------------------------ + +Pass 'FTRACE=1' to the U-Boot Makefile to actually instrument the code. +This is kept as a separate option so that it is easy to enable/disable +instrumenting from the command line instead of having to change board +config files. + + +Collecting Trace Data +--------------------- + +When you run U-Boot on your board it will collect trace data up to the +limit of the trace buffer size you have specified. Once that is exhausted +no more data will be collected. + +Collecting trace data has an affect on execution time/performance. You +will notice this particularly with trvial functions - the overhead of +recording their execution may even exceed their normal execution time. +In practice this doesn't matter much so long as you are aware of the +effect. Once you have done your optimisations, turn off tracing before +doing end-to-end timing. + +The best time to start tracing is right at the beginning of U-Boot. The +best time to stop tracing is right at the end. In practice it is hard +to achieve these ideals. + +This implementation enables tracing early in board_init_f(). This means +that it captures most of the board init process, missing only the +early architecture-specific init. However, it also misses the entire +SPL stage if there is one. + +U-Boot typically ends with a 'bootm' command which loads and runs an +OS. There is useful trace data in the execution of that bootm +command. Therefore this implementation provides a way to collect trace +data after bootm has finished processing, but just before it jumps to +the OS. In practical terms, U-Boot runs the 'fakegocmd' environment +variable at this point. This variable should have a short script which +collects the trace data and writes it somewhere. + +Trace data collection relies on a microsecond timer, accesed through +timer_get_us(). So the first think you should do is make sure that +this produces sensible results for your board. Suitable sources for +this timer include high resolution timers, PWMs or profile timers if +available. Most modern SOCs have a suitable timer for this. Make sure +that you mark this timer (and anything it calls) with +__attribute__((no_instrument_function)) so that the trace library can +use it without causing an infinite loop. + + +Commands +-------- + +The trace command has variable sub-commands: + +- stats + Display tracing statistics + +- pause + Pause tracing + +- resume + Resume tracing + +- funclist [<addr> <size>] + Dump a list of functions into the buffer + +- calls [<addr> <size>] + Dump function call trace into buffer + +If the address and size are not given, these are obtained from environment +variables (see below). In any case the environment variables are updated +after the command runs. + + +Environment Variables +--------------------- + +The following are used: + +- profbase + Base address of trace output buffer + +- profoffset + Offset of first unwritten byte in trace output buffer + +- profsize + Size of trace output buffer + +All of these are set by the 'trace calls' command. + +These variables keep track of the amount of data written to the trace +output buffer by the 'trace' command. The trace commands which write data +to the output buffer can use these to specify the buffer to write to, and +update profoffset each time. This allows successive commands to append data +to the same buffer, for example: + + trace funclist 10000 e00000 + trace calls + +(the latter command appends more data to the buffer). + + +- fakegocmd + Specifies commands to run just before booting the OS. This + is a useful time to write the trace data to the host for + processing. + + +Writing Out Trace Data +---------------------- + +Once the trace data is in an output buffer in memory there are various ways +to transmit it to the host. Notably you can use tftput to send the data +over a network link: + +fakegocmd=trace pause; usb start; set autoload n; bootp; + trace calls 10000000 1000000; + tftpput ${profbase} ${profoffset} 192.168.1.4:/tftpboot/calls + +This starts up USB (to talk to an attached USB Ethernet dongle), writes +a trace log to address 10000000 and sends it to a host machine using +TFTP. After this, U-Boot will boot the OS normally, albeit a little +later. + + +Converting Trace Output Data +---------------------------- + +The trace output data is kept in a binary format which is not documented +here. To convert it into something useful, you can use proftool. + +This tool must be given the U-Boot map file and the trace data received +from running that U-Boot. It produces a text output file. + +Options + -m <map_file> + Specify U-Boot map file + + -p <trace_file> + Specifiy profile/trace file + +Commands: + +- dump-ftrace + Write a text dump of the file in Linux ftrace format to stdout + + +Viewing the Trace Data +---------------------- + +You can use pytimechart for this (sudo apt-get pytimechart might work on +your Debian-style machine, and use your favourite search engine to obtain +documentation). It expects the file to have a .txt extension. The program +has terse user interface but is very convenient for viewing U-Boot +profile information. + + +Workflow Suggestions +-------------------- + +The following suggestions may be helpful if you are trying to reduce boot +time: + +1. Enable CONFIG_BOOTSTAGE and CONFIG_BOOTSTAGE_REPORT. This should get +you are helpful overall snapshot of the boot time. + +2. Build U-Boot with tracing and run it. Note the difference in boot time +(it is common for tracing to add 10% to the time) + +3. Collect the trace information as descibed above. Use this to find where +all the time is being spent. + +4. Take a look at that code and see if you can optimise it. Perhaps it is +possible to speed up the initialisation of a device, or remove an unused +feature. + +5. Rebuild, run and collect again. Compare your results. + +6. Keep going until you run out of steam, or your boot is fast enough. + + +Configuring Trace +----------------- + +There are a few parameters in the code that you may want to consider. +There is a function call depth limit (set to 15 by default). When the +stack depth goes above this then no tracing information is recorded. +The maximum depth reached is recorded and displayed by the 'trace stats' +command. + + +Future Work +----------- + +Tracing could be a little tidier in some areas, for example providing +run-time configuration options for trace. + +Some other features that might be useful: + +- Trace filter to select which functions are recorded +- Sample-based profiling using a timer interrupt +- Better control over trace depth +- Compression of trace information + + +Simon Glass <sjg@chromium.org> +April 2013 diff --git a/doc/device-tree-bindings/exynos/dwmmc.txt b/doc/device-tree-bindings/exynos/dwmmc.txt new file mode 100644 index 0000000000..566da3b636 --- /dev/null +++ b/doc/device-tree-bindings/exynos/dwmmc.txt @@ -0,0 +1,54 @@ +* Exynos 5250 DWC_mobile_storage + +The Exynos 5250 provides DWC_mobile_storage interface which supports +. Embedded Multimedia Cards (EMMC-version 4.5) +. Secure Digital memory (SD mem-version 2.0) +. Secure Digital I/O (SDIO-version 3.0) +. Consumer Electronics Advanced Transport Architecture (CE-ATA-version 1.1) + +The Exynos 5250 DWC_mobile_storage provides four channels. +SOC specific and Board specific properties are channel specific. + +Required SoC Specific Properties: + +- compatible: should be + - samsung,exynos5250-dwmmc: for exynos5250 platforms + +- reg: physical base address of the controller and length of memory mapped + region. + +- interrupts: The interrupt number to the cpu. + +Required Board Specific Properties: + +- #address-cells: should be 1. +- #size-cells: should be 0. +- samsung,bus-width: The width of the bus used to interface the devices + supported by DWC_mobile_storage (SD-MMC/EMMC/SDIO). + . Typically the bus width is 4 or 8. +- samsung,timing: The timing values to be written into the + Drv/sample clock selection register of corresponding channel. + . It is comprised of 3 values corresponding to the 3 fileds + 'SelClk_sample', 'SelClk_drv' and 'DIVRATIO' of CLKSEL register. + . SelClk_sample: Select sample clock among 8 shifted clocks. + . SelClk_drv: Select drv clock among 8 shifted clocks. + . DIVRATIO: Clock Divide ratio select. + . The above 3 values are used by the clock phase shifter. + +Example: + +mmc@12200000 { + samsung,bus-width = <8>; + samsung,timing = <1 3 3>; + samsung,removable = <1>; +} +In the above example, + . The bus width is 8 + . Timing is comprised of 3 values as explained below + 1 - SelClk_sample + 3 - SelClk_drv + 3 - DIVRATIO + . The 'removable' flag indicates whether the the particilar device + cannot be removed (always present) or it is a removable device. + 1 - Indicates that the device is removable. + 0 - Indicates that the device cannot be removed. diff --git a/doc/device-tree-bindings/input/cros-ec-keyb.txt b/doc/device-tree-bindings/input/cros-ec-keyb.txt new file mode 100644 index 0000000000..3118276078 --- /dev/null +++ b/doc/device-tree-bindings/input/cros-ec-keyb.txt @@ -0,0 +1,79 @@ +CROS_EC Keyboard + +The CROS_EC (Matrix Keyboard Protocol) allows communcation with a secondary +micro used for keyboard, and possible other features. + +The CROS_EC keyboard uses this protocol to receive key scans and produce input +in U-Boot. + +Required properties : +- compatible : "google,cros-ec-keyb" +- google,key-rows : Number of key rows +- google,key-columns : Number of key columns + +Optional properties, in addition to those specified by the shared +matrix-keyboard bindings: + +- linux,fn-keymap: a second keymap, same specification as the + matrix-keyboard-controller spec but to be used when the KEY_FN modifier + key is pressed. +- google,repeat-delay-ms : delay in milliseconds before repeat starts +- google,repeat-rate-ms : delay between each subsequent key press +- google,ghost-filter : enable ghost filtering for this device + +Example, taken from daisy: + +cros-ec-keyb { + compatible = "google,cros-ec-keyb"; + google,key-rows = <8>; + google,key-columns = <13>; + google,ghost-filter; + google,repeat-delay-ms = <240>; + google,repeat-rate-ms = <30>; + /* + * Keymap entries take the form of 0xRRCCKKKK where + * RR=Row CC=Column KKKK=Key Code + * The values below are for a US keyboard layout and + * are taken from the Linux driver. Note that the + * 102ND key is not used for US keyboards. + */ + linux,keymap = < + /* CAPSLCK F1 B F10 */ + 0x0001003a 0x0002003c 0x00030030 0x00040044 + /* N = R_ALT ESC */ + 0x00060031 0x0008000d 0x000a0064 0x01010001 + /* F4 G F7 H */ + 0x0102003e 0x01030022 0x01040041 0x01060023 + /* ' F9 BKSPACE L_CTRL */ + 0x01080028 0x01090043 0x010b000e 0x0200001d + /* TAB F3 T F6 */ + 0x0201000f 0x0202003d 0x02030014 0x02040040 + /* ] Y 102ND [ */ + 0x0205001b 0x02060015 0x02070056 0x0208001a + /* F8 GRAVE F2 5 */ + 0x02090042 0x03010029 0x0302003c 0x03030006 + /* F5 6 - \ */ + 0x0304003f 0x03060007 0x0308000c 0x030b002b + /* R_CTRL A D F */ + 0x04000061 0x0401001e 0x04020020 0x04030021 + /* S K J ; */ + 0x0404001f 0x04050025 0x04060024 0x04080027 + /* L ENTER Z C */ + 0x04090026 0x040b001c 0x0501002c 0x0502002e + /* V X , M */ + 0x0503002f 0x0504002d 0x05050033 0x05060032 + /* L_SHIFT / . SPACE */ + 0x0507002a 0x05080035 0x05090034 0x050B0039 + /* 1 3 4 2 */ + 0x06010002 0x06020004 0x06030005 0x06040003 + /* 8 7 0 9 */ + 0x06050009 0x06060008 0x0608000b 0x0609000a + /* L_ALT DOWN RIGHT Q */ + 0x060a0038 0x060b006c 0x060c006a 0x07010010 + /* E R W I */ + 0x07020012 0x07030013 0x07040011 0x07050017 + /* U R_SHIFT P O */ + 0x07060016 0x07070036 0x07080019 0x07090018 + /* UP LEFT */ + 0x070b0067 0x070c0069>; +}; diff --git a/doc/device-tree-bindings/misc/cros-ec.txt b/doc/device-tree-bindings/misc/cros-ec.txt new file mode 100644 index 0000000000..07ea7cdeac --- /dev/null +++ b/doc/device-tree-bindings/misc/cros-ec.txt @@ -0,0 +1,38 @@ +Chrome OS CROS_EC Binding +====================== + +The device tree node which describes the operation of the CROS_EC interface +is as follows: + +Required properties : +- compatible = "google,cros-ec" + +Optional properties : +- spi-max-frequency : Sets the maximum frequency (in Hz) for SPI bus + operation +- i2c-max-frequency : Sets the maximum frequency (in Hz) for I2C bus + operation +- ec-interrupt : Selects the EC interrupt, defined as a GPIO according + to the platform +- optimise-flash-write : Boolean property - if present then flash blocks + containing all 0xff will not be written, since we assume that the EC + uses that pattern for erased blocks + +The CROS_EC node should appear as a subnode of the interrupt that connects it +to the EC (e.g. i2c, spi, lpc). The reg property (as usual) will indicate +the unit address on that bus. + + +Example +======= + + spi@131b0000 { + cros-ec@0 { + reg = <0>; + compatible = "google,cros-ec"; + spi-max-frequency = <5000000>; + ec-interrupt = <&gpio 174 1>; + optimise-flash-write; + status = "disabled"; + }; + }; diff --git a/doc/mkimage.1 b/doc/mkimage.1 index 39652c82d0..14374da88a 100644 --- a/doc/mkimage.1 +++ b/doc/mkimage.1 @@ -4,7 +4,17 @@ mkimage \- Generate image for U-Boot .SH SYNOPSIS .B mkimage -.RB [\fIoptions\fP] +.RB "\-l [" "uimage file name" "]" + +.B mkimage +.RB [\fIoptions\fP] " \-f [" "image tree source file" "]" " [" "uimage file name" "]" + +.B mkimage +.RB [\fIoptions\fP] " \-F [" "uimage file name" "]" + +.B mkimage +.RB [\fIoptions\fP] " (legacy mode)" + .SH "DESCRIPTION" The .B mkimage @@ -26,7 +36,8 @@ etc. The new .I FIT (Flattened Image Tree) format allows for more flexibility in handling images of various types and also -enhances integrity protection of images with stronger checksums. +enhances integrity protection of images with stronger checksums. It also +supports verified boot. .SH "OPTIONS" @@ -67,6 +78,10 @@ Set load address with a hex number. Set entry point with a hex number. .TP +.BI "\-l" +List the contents of an image. + +.TP .BI "\-n [" "image name" "]" Set image name to 'image name'. @@ -82,6 +97,12 @@ Set XIP (execute in place) flag. .B Create FIT image: .TP +.BI "\-c [" "comment" "]" +Specifies a comment to be added when signing. This is typically a useful +message which describes how the image was signed or some other useful +information. + +.TP .BI "\-D [" "dtc options" "]" Provide special options to the device tree compiler that is used to create the image. @@ -91,6 +112,33 @@ create the image. Image tree source file that describes the structure and contents of the FIT image. +.TP +.BI "\-F" +Indicates that an existing FIT image should be modified. No dtc +compilation is performed and the -f flag should not be given. +This can be used to sign images with additional keys after initial image +creation. + +.TP +.BI "\-k [" "key_directory" "]" +Specifies the directory containing keys to use for signing. This directory +should contain a private key file <name>.key for use with signing and a +certificate <name>.crt (containing the public key) for use with verification. + +.TP +.BI "\-K [" "key_destination" "]" +Specifies a compiled device tree binary file (typically .dtb) to write +public key information into. When a private key is used to sign an image, +the corresponding public key is written into this file for for run-time +verification. Typically the file here is the device tree binary used by +CONFIG_OF_CONTROL in U-Boot. + +.TP +.BI "\-r +Specifies that keys used to sign the FIT are required. This means that they +must be verified for the image to boot. Without this option, the verification +will be optional (useful for testing but not for release). + .SH EXAMPLES List image information: @@ -109,10 +157,29 @@ Create FIT image with compressed PowerPC Linux kernel: .nf .B mkimage -f kernel.its kernel.itb .fi +.P +Create FIT image with compressed kernel and sign it with keys in the +/public/signing-keys directory. Add corresponding public keys into u-boot.dtb, +skipping those for which keys cannot be found. Also add a comment. +.nf +.B mkimage -f kernel.its -k /public/signing-keys -K u-boot.dtb \\\\ +-c "Kernel 3.8 image for production devices" kernel.itb +.fi + +.P +Update an existing FIT image, signing it with additional keys. +Add corresponding public keys into u-boot.dtb. This will resign all images +with keys that are available in the new directory. Images that request signing +with unavailable keys are skipped. +.nf +.B mkimage -F -k /secret/signing-keys -K u-boot.dtb \\\\ +-c "Kernel 3.8 image for production devices" kernel.itb +.fi .SH HOMEPAGE http://www.denx.de/wiki/U-Boot/WebHome .PP .SH AUTHOR This manual page was written by Nobuhiro Iwamatsu <iwamatsu@nigauri.org> -and Wolfgang Denk <wd@denx.de> +and Wolfgang Denk <wd@denx.de>. It was updated for image signing by +Simon Glass <sjg@chromium.org>. diff --git a/doc/uImage.FIT/sign-configs.its b/doc/uImage.FIT/sign-configs.its new file mode 100644 index 0000000000..3c17f040de --- /dev/null +++ b/doc/uImage.FIT/sign-configs.its @@ -0,0 +1,45 @@ +/dts-v1/; + +/ { + description = "Chrome OS kernel image with one or more FDT blobs"; + #address-cells = <1>; + + images { + kernel@1 { + data = /incbin/("test-kernel.bin"); + type = "kernel_noload"; + arch = "sandbox"; + os = "linux"; + compression = "lzo"; + load = <0x4>; + entry = <0x8>; + kernel-version = <1>; + hash@1 { + algo = "sha1"; + }; + }; + fdt@1 { + description = "snow"; + data = /incbin/("sandbox-kernel.dtb"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + fdt-version = <1>; + hash@1 { + algo = "sha1"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + signature@1 { + algo = "sha1,rsa2048"; + key-name-hint = "dev"; + sign-images = "fdt", "kernel"; + }; + }; + }; +}; diff --git a/doc/uImage.FIT/sign-images.its b/doc/uImage.FIT/sign-images.its new file mode 100644 index 0000000000..f69326a39b --- /dev/null +++ b/doc/uImage.FIT/sign-images.its @@ -0,0 +1,42 @@ +/dts-v1/; + +/ { + description = "Chrome OS kernel image with one or more FDT blobs"; + #address-cells = <1>; + + images { + kernel@1 { + data = /incbin/("test-kernel.bin"); + type = "kernel_noload"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x4>; + entry = <0x8>; + kernel-version = <1>; + signature@1 { + algo = "sha1,rsa2048"; + key-name-hint = "dev"; + }; + }; + fdt@1 { + description = "snow"; + data = /incbin/("sandbox-kernel.dtb"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + fdt-version = <1>; + signature@1 { + algo = "sha1,rsa2048"; + key-name-hint = "dev"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + }; +}; diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt new file mode 100644 index 0000000000..bc9f3fa6e1 --- /dev/null +++ b/doc/uImage.FIT/signature.txt @@ -0,0 +1,382 @@ +U-Boot FIT Signature Verification +================================= + +Introduction +------------ +FIT supports hashing of images so that these hashes can be checked on +loading. This protects against corruption of the image. However it does not +prevent the substitution of one image for another. + +The signature feature allows the hash to be signed with a private key such +that it can be verified using a public key later. Provided that the private +key is kept secret and the public key is stored in a non-volatile place, +any image can be verified in this way. + +See verified-boot.txt for more general information on verified boot. + + +Concepts +-------- +Some familiarity with public key cryptography is assumed in this section. + +The procedure for signing is as follows: + + - hash an image in the FIT + - sign the hash with a private key to produce a signature + - store the resulting signature in the FIT + +The procedure for verification is: + + - read the FIT + - obtain the public key + - extract the signature from the FIT + - hash the image from the FIT + - verify (with the public key) that the extracted signature matches the + hash + +The signing is generally performed by mkimage, as part of making a firmware +image for the device. The verification is normally done in U-Boot on the +device. + + +Algorithms +---------- +In principle any suitable algorithm can be used to sign and verify a hash. +At present only one class of algorithms is supported: SHA1 hashing with RSA. +This works by hashing the image to produce a 20-byte hash. + +While it is acceptable to bring in large cryptographic libraries such as +openssl on the host side (e.g. mkimage), it is not desirable for U-Boot. +For the run-time verification side, it is important to keep code and data +size as small as possible. + +For this reason the RSA image verification uses pre-processed public keys +which can be used with a very small amount of code - just some extraction +of data from the FDT and exponentiation mod n. Code size impact is a little +under 5KB on Tegra Seaboard, for example. + +It is relatively straightforward to add new algorithms if required. If +another RSA variant is needed, then it can be added to the table in +image-sig.c. If another algorithm is needed (such as DSA) then it can be +placed alongside rsa.c, and its functions added to the table in image-sig.c +also. + + +Creating an RSA key and certificate +----------------------------------- +To create a new public key, size 2048 bits: + +$ openssl genrsa -F4 -out keys/dev.key 2048 + +To create a certificate for this: + +$ openssl req -batch -new -x509 -key keys/dev.key -out keys/dev.crt + +If you like you can look at the public key also: + +$ openssl rsa -in keys/dev.key -pubout + + +Device Tree Bindings +-------------------- +The following properties are required in the FIT's signature node(s) to +allow thes signer to operate. These should be added to the .its file. +Signature nodes sit at the same level as hash nodes and are called +signature@1, signature@2, etc. + +- algo: Algorithm name (e.g. "sha1,rs2048") + +- key-name-hint: Name of key to use for signing. The keys will normally be in +a single directory (parameter -k to mkimage). For a given key <name>, its +private key is stored in <name>.key and the certificate is stored in +<name>.crt. + +When the image is signed, the following properties are added (mandatory): + +- value: The signature data (e.g. 256 bytes for 2048-bit RSA) + +When the image is signed, the following properties are optional: + +- timestamp: Time when image was signed (standard Unix time_t format) + +- signer-name: Name of the signer (e.g. "mkimage") + +- signer-version: Version string of the signer (e.g. "2013.01") + +- comment: Additional information about the signer or image + +For config bindings (see Signed Configurations below), the following +additional properties are optional: + +- sign-images: A list of images to sign, each being a property of the conf +node that contains then. The default is "kernel,fdt" which means that these +two images will be looked up in the config and signed if present. + +For config bindings, these properties are added by the signer: + +- hashed-nodes: A list of nodes which were hashed by the signer. Each is + a string - the full path to node. A typical value might be: + + hashed-nodes = "/", "/configurations/conf@1", "/images/kernel@1", + "/images/kernel@1/hash@1", "/images/fdt@1", + "/images/fdt@1/hash@1"; + +- hashed-strings: The start and size of the string region of the FIT that + was hashed + +Example: See sign-images.its for an example image tree source file and +sign-configs.its for config signing. + + +Public Key Storage +------------------ +In order to verify an image that has been signed with a public key we need to +have a trusted public key. This cannot be stored in the signed image, since +it would be easy to alter. For this implementation we choose to store the +public key in U-Boot's control FDT (using CONFIG_OF_CONTROL). + +Public keys should be stored as sub-nodes in a /signature node. Required +properties are: + +- algo: Algorithm name (e.g. "sha1,rs2048") + +Optional properties are: + +- key-name-hint: Name of key used for signing. This is only a hint since it +is possible for the name to be changed. Verification can proceed by checking +all available signing keys until one matches. + +- required: If present this indicates that the key must be verified for the +image / configuration to be considered valid. Only required keys are +normally verified by the FIT image booting algorithm. Valid values are +"image" to force verification of all images, and "conf" to force verfication +of the selected configuration (which then relies on hashes in the images to +verify those). + +Each signing algorithm has its own additional properties. + +For RSA the following are mandatory: + +- rsa,num-bits: Number of key bits (e.g. 2048) +- rsa,modulus: Modulus (N) as a big-endian multi-word integer +- rsa,r-squared: (2^num-bits)^2 as a big-endian multi-word integer +- rsa,n0-inverse: -1 / modulus[0] mod 2^32 + + +Signed Configurations +--------------------- +While signing images is useful, it does not provide complete protection +against several types of attack. For example, it it possible to create a +FIT with the same signed images, but with the configuration changed such +that a different one is selected (mix and match attack). It is also possible +to substitute a signed image from an older FIT version into a newer FIT +(roll-back attack). + +As an example, consider this FIT: + +/ { + images { + kernel@1 { + data = <data for kernel1> + signature@1 { + algo = "sha1,rsa2048"; + value = <...kernel signature 1...> + }; + }; + kernel@2 { + data = <data for kernel2> + signature@1 { + algo = "sha1,rsa2048"; + value = <...kernel signature 2...> + }; + }; + fdt@1 { + data = <data for fdt1>; + signature@1 { + algo = "sha1,rsa2048"; + vaue = <...fdt signature 1...> + }; + }; + fdt@2 { + data = <data for fdt2>; + signature@1 { + algo = "sha1,rsa2048"; + vaue = <...fdt signature 2...> + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + conf@1 { + kernel = "kernel@2"; + fdt = "fdt@2"; + }; + }; +}; + +Since both kernels are signed it is easy for an attacker to add a new +configuration 3 with kernel 1 and fdt 2: + + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + conf@1 { + kernel = "kernel@2"; + fdt = "fdt@2"; + }; + conf@3 { + kernel = "kernel@1"; + fdt = "fdt@2"; + }; + }; + +With signed images, nothing protects against this. Whether it gains an +advantage for the attacker is debatable, but it is not secure. + +To solved this problem, we support signed configurations. In this case it +is the configurations that are signed, not the image. Each image has its +own hash, and we include the hash in the configuration signature. + +So the above example is adjusted to look like this: + +/ { + images { + kernel@1 { + data = <data for kernel1> + hash@1 { + algo = "sha1"; + value = <...kernel hash 1...> + }; + }; + kernel@2 { + data = <data for kernel2> + hash@1 { + algo = "sha1"; + value = <...kernel hash 2...> + }; + }; + fdt@1 { + data = <data for fdt1>; + hash@1 { + algo = "sha1"; + value = <...fdt hash 1...> + }; + }; + fdt@2 { + data = <data for fdt2>; + hash@1 { + algo = "sha1"; + value = <...fdt hash 2...> + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + signature@1 { + algo = "sha1,rsa2048"; + value = <...conf 1 signature...>; + }; + }; + conf@2 { + kernel = "kernel@2"; + fdt = "fdt@2"; + signature@1 { + algo = "sha1,rsa2048"; + value = <...conf 1 signature...>; + }; + }; + }; +}; + + +You can see that we have added hashes for all images (since they are no +longer signed), and a signature to each configuration. In the above example, +mkimage will sign configurations/conf@1, the kernel and fdt that are +pointed to by the configuration (/images/kernel@1, /images/kernel@1/hash@1, +/images/fdt@1, /images/fdt@1/hash@1) and the root structure of the image +(so that it isn't possible to add or remove root nodes). The signature is +written into /configurations/conf@1/signature@1/value. It can easily be +verified later even if the FIT has been signed with other keys in the +meantime. + + +Verification +------------ +FITs are verified when loaded. After the configuration is selected a list +of required images is produced. If there are 'required' public keys, then +each image must be verified against those keys. This means that every image +that might be used by the target needs to be signed with 'required' keys. + +This happens automatically as part of a bootm command when FITs are used. + + +Enabling FIT Verification +------------------------- +In addition to the options to enable FIT itself, the following CONFIGs must +be enabled: + +CONFIG_FIT_SIGNATURE - enable signing and verfication in FITs +CONFIG_RSA - enable RSA algorithm for signing + + +Testing +------- +An easy way to test signing and verfication is to use the test script +provided in test/vboot/vboot_test.sh. This uses sandbox (a special version +of U-Boot which runs under Linux) to show the operation of a 'bootm' +command loading and verifying images. + +A sample run is show below: + +$ make O=sandbox sandbox_config +$ make O=sandbox +$ O=sandbox ./test/vboot/vboot_test.sh +Simple Verified Boot Test +========================= + +Please see doc/uImage.FIT/verified-boot.txt for more information + +Build keys +Build FIT with signed images +Test Verified Boot Run: unsigned signatures:: OK +Sign images +Test Verified Boot Run: signed images: OK +Build FIT with signed configuration +Test Verified Boot Run: unsigned config: OK +Sign images +Test Verified Boot Run: signed config: OK + +Test passed + + +Future Work +----------- +- Roll-back protection using a TPM is done using the tpm command. This can +be scripted, but we might consider a default way of doing this, built into +bootm. + + +Possible Future Work +-------------------- +- Add support for other RSA/SHA variants, such as rsa4096,sha512. +- Other algorithms besides RSA +- More sandbox tests for failure modes +- Passwords for keys/certificates +- Perhaps implement OAEP +- Enhance bootm to permit scripted signature verification (so that a script +can verify an image but not actually boot it) + + +Simon Glass +sjg@chromium.org +1-1-13 diff --git a/doc/uImage.FIT/verified-boot.txt b/doc/uImage.FIT/verified-boot.txt new file mode 100644 index 0000000000..3c83fbc2c1 --- /dev/null +++ b/doc/uImage.FIT/verified-boot.txt @@ -0,0 +1,104 @@ +U-Boot Verified Boot +==================== + +Introduction +------------ +Verified boot here means the verification of all software loaded into a +machine during the boot process to ensure that it is authorised and correct +for that machine. + +Verified boot extends from the moment of system reset to as far as you wish +into the boot process. An example might be loading U-Boot from read-only +memory, then loading a signed kernel, then using the kernel's dm-verity +driver to mount a signed root filesystem. + +A key point is that it is possible to field-upgrade the software on machines +which use verified boot. Since the machine will only run software that has +been correctly signed, it is safe to read software from an updatable medium. +It is also possible to add a secondary signed firmware image, in read-write +memory, so that firmware can easily be upgraded in a secure manner. + + +Signing +------- +Verified boot uses cryptographic algorithms to 'sign' software images. +Images are signed using a private key known only to the signer, but can +be verified using a public key. As its name suggests the public key can be +made available without risk to the verification process. The private and +public keys are mathematically related. For more information on how this +works look up "public key cryptography" and "RSA" (a particular algorithm). + +The signing and verification process looks something like this: + + + Signing Verification + ======= ============ + + +--------------+ * + | RSA key pair | * +---------------+ + | .key .crt | * | Public key in | + +--------------+ +------> public key ----->| trusted place | + | | * +---------------+ + | | * | + v | * v + +---------+ | * +--------------+ + | |----------+ * | | + | signer | * | U-Boot | + | |----------+ * | signature |--> yes/no + +---------+ | * | verification | + ^ | * | | + | | * +--------------+ + | | * ^ + +----------+ | * | + | Software | +----> signed image -------------+ + | image | * + +----------+ * + + +The signature algorithm relies only on the public key to do its work. Using +this key it checks the signature that it finds in the image. If it verifies +then we know that the image is OK. + +The public key from the signer allows us to verify and therefore trust +software from updatable memory. + +It is critical that the public key be secure and cannot be tampered with. +It can be stored in read-only memory, or perhaps protected by other on-chip +crypto provided by some modern SOCs. If the public key can ben changed, then +the verification is worthless. + + +Chaining Images +--------------- +The above method works for a signer providing images to a run-time U-Boot. +It is also possible to extend this scheme to a second level, like this: + +1. Master private key is used by the signer to sign a first-stage image. +2. Master public key is placed in read-only memory. +2. Secondary private key is created and used to sign second-stage images. +3. Secondary public key is placed in first stage images +4. We use the master public key to verify the first-stage image. We then +use the secondary public key in the first-stage image to verify the second- +state image. +5. This chaining process can go on indefinitely. It is recommended to use a +different key at each stage, so that a compromise in one place will not +affect the whole change. + + +Flattened Image Tree (FIT) +-------------------------- +The FIT format is alreay widely used in U-Boot. It is a flattened device +tree (FDT) in a particular format, with images contained within. FITs +include hashes to verify images, so it is relatively straightforward to +add signatures as well. + +The public key can be stored in U-Boot's CONFIG_OF_CONTROL device tree in +a standard place. Then when a FIT it loaded it can be verified using that +public key. Multiple keys and multiple signatures are supported. + +See signature.txt for more information. + + +Simon Glass +sjg@chromium.org +1-1-13 |