Omapboot

= OMAPBOOT =

Overview
OMAPBOOT is an Open Source project that consists of 2 device utilities, a Linux host executable and a device bootloader. As its name implies, OMAPBOOT is a package aiming at booting an OMAP platform. OMAPBOOT was originally created by Brian Swetland (Google) to boot OMAP4 boards. It supported peripheral boot over USB for OMAP4 and had the ability to download a small second stage (i.e. aboot) into internal RAM and then load an executable binary like u-boot or a kernel binary into external RAM and execute it.

Active development on OMAPBOOT began in the fall of 2011 and was released into TI mainline in February 2012 with support for OMAP5430. Thereafter support for 5432 was added as well.

OMAPBOOT:
 * Provides ANDROID FASTBOOT support
 * With the help of ROM MMC APIs, GPT partitions can be created on the eMMC. This enables the user to flash bootloader, kernel and file system binaries to the target.
 * Running “./usbboot -f” on the host console, will cause the USBBOOT host tool to download a small binary into SRAM. Once in SRAM, the downloaded binary can configure: the board MUX settings, clocks, EMIF, DDR, GPMC, SERIAL, I2C, PMIC, DISPLAY, check battery charge and enable BATTERY charging if needed, can enter into command line and parse user commands, perform memory tests, boot experimental kernels, and support FASTBOOT mode, which provides the user with a capability of flashing binaries to the target.
 * Boot capability: OMAPBOOT supports booting and omap-android linux kernel without the use of a secondary bootloader (example: u-boot)

Advantages of supporting OMAPBOOT:
 * Easy to use and extend for newer silicon versions and/or revisions.
 * Does not use a GPL license.
 * Slim, efficient, lightweight and fast, focuses on doing the bare minimum needed to boot.
 * U-boot first stage = 33K and second stage = 233K, when built for OMAP5.
 * Omapboot first stage = 26K and second stage = 29K, when built for OMAP5.
 * With recent speed optimizations, measured boot time from bootloader to kernel ~210ms for omapboot.

Modules
The 2 device utilities, host executable and the device bootloader are modules of OMAPBOOT. They are USBBOOT, ABOOT, IBOOT and EBOOT.


 * USBBOOT: This is a Linux utility which runs on the host system and connects to the target through the USB bus.
 * ABOOT: This is a utility which runs on the target side in SRAM. It has the capability to load and execute a secondary loader or kernel in the target SDRAM.
 * IBOOT: This is a utility which runs on the target side to interface with the fastboot utility running on the host side.
 * EBOOT: This is an embedded bootloader to boot up the target. It will load the kernel, which will eventually boot the Android OS.


 * Note that in a secure environment, the embedded bootloader and the device utilities must be properly signed or it will fail to execute.

USBBOOT

 * The first utility is called USBBOOT. As the name suggests, it deals with USB bus.
 * USBBOOT typically runs in a Linux environment (also referred to as "host" in other parts of this document)
 * The USBBOOT utility is mainly used while booting OMAP in a peripheral boot mode, in this case over USB.
 * USBBOOT uses a small binary to set up the OMAP and flash it. This binary is IBOOT. For GP boards, the IBOOT is built into the USBBOOT binary. For HS/HD boards, the signed IBOOT.IFT should be placed in the same folder as the USBBOOT binary for flashing.


 * USBBOOT is the only module that runs on the host side. Typical invocation is: ./usbboot
 * When invoked, USBBOOT will look for a target over the USB bus.
 * When the target is located, handshaking takes place and USBBOOT will load one of the 2 modules, ABOOT or IBOOT, depending upon the option used. As an example, if ./usbboot -f (the -f option is used to indicate that the user wants to enter into FASTBOOT mode) is entered on the host console, USBBOOT will load IBOOT in the target since this is the module dealing with processing FASTBOOT commands. Once the module is loaded, the target will execute it.

IBOOT

 * IBOOT is the utility interfacing with FASTBOOT. Entering ./usbboot -f on the host will load and execute IBOOT in the target.
 * After IBOOT initializes the target, it will wait for a FASTBOOT command from the host. Once the user enters a FASTBOOT command on the host, IBOOT will parse the command and take action accordingly i.e. boot an experimental kernel, flash/erase a partition, create the partition table on storage device, read back user variables, etc.

ABOOT

 * ABOOT: Today, ABOOT only deals with booting and testing Android kernel.
 * After a minimal initialization to bring the target is a state supporting a kernel boot, ABOOT receives the image over the USB bus sent by the USBBOOT utility and executes it. It expects a traditional boot.img format and checks for the "ANDROID" magic in the loaded object header. The checking is intentionally light to allow easy modifications. It could be therefore be used to load and execute any other kernel or executable. The interesting point is that the image is loaded in main memory and executed there so the process is non-destructive. This is to say that a subsequent reset will just erase the image content from SDRAM and bring back the target to the previous state. This feature is used to boot experimental kernels, without the need of flashing it to internal storage. A word of caution, though, if it's guaranteed that ABOOT will never modify the target internal storage, an experimental kernel may do just that.

ABOOT or IBOOT?

 * It is not necessary to remember which utility does what. The USBBOOT host utility will pick the right one automatically based on the command entered by the user. There is a possibility that IBOOT and ABOOT may merge in the future.

EBOOT

 * EBOOT is the only bootloader in the OMAPBOOT package.
 * It is intended to be flashed into a storage device of the target. Storage devices like eMMC, SD and SATA are supported.
 * At power ON, the EBOOT bootloader (signed for HS and unsigned for GP) is copied from the storage device into memory by ROM and begins executing.
 * The bootloader sets up board muxes, prcm, pmic, SMARTIOs, DDR, console UART, storage device, etc.
 * It checks for a key press (in the case of OMAP5 SEVM, the check is to see if volume up/down keys are pressed, in the case of OMAP5 UEVM, the check is to see if the button is pressed) to decide whether to enter into FASTBOOT mode or not.
 * If no key press is detected, it continues booting. The contents of the kernel and ramdisk is loaded into main memory, after which we jump on it and begin executing it.
 * The bootloader is dead once kernel begins executing.

Source directory structure
Aside from the cross-compiler, everything needed to build the package is under the OMAPBOOT directory located here
 * On the first level are the files common to all targets and hosts: Makefile, initialization sequence files, etc. Code files at this level are common to all target types.
 * Code in these files is as generic as possible. Ideally, the code could be re-used with a CPUs other than OMAP.

The HOST directory structure: All source files to build the host tool USBBOOT are under OMAPBOOT/host. Today, since the only host supported is Linux, all files in this directory are Linux source files. Host Include Common OMAP4 OMAP5 Tools makefile bin2c mkheader – used to append the CH and/or GP header to the generated target binaries. usbboot usb_linux – Host side USB driver to access the USB bus on the host machine.

OMAPBOOT/build contains files required by the build process The BUILD directory structure: Host executable make Target executable make Rules make GET GIT INFO

The OMAPBOOT/out is dynamically created during the build process.
 * It contains all the compiled objects and executables under subdirectories organized by target names.

Under OMAPBOOT/libc are small standard library files containing functions like printf, etc... The LIBC directory structure: printf raise string functions utils

The ARCH directory structure:

All source files containing code common to all OMAP targets are under OMAPBOOT/arch/common COMMON: Common to both omap4 and omap5 like gpio, rom apis like usb, mmc, watchdog, i2c, serial, etc.

All source files containing code common to all omap4 targets are under OMAPBOOT/arch/omap4 OMAP4 BOARD: Board specific code for a particular target CONFIGS: These files contains #define which should be unique to a target Other OMAP4 specific source like clocks, sdram, gpmc, smartios, pmic, EMIF, etc.

All source files containing code common to all omap5 targets are under OMAPBOOT/arch/omap5 OMAP5 BOARD: Board specific code for a particular target CONFIGS: These files contains #define which should be unique to a target Other OMAP5 specific source like clocks, sdram, gpmc, smartios, pmic, EMIF, etc.

The INCLUDE directory: INCLUDE LIBC COMMON: All header files common to omap4 and omap5 are under OMAPBOOT/include/common Common processor functions, OMAP ROM API prototypes, etc.      OMAP4: All header files common to 2 or more omap4 targets are under OMAPBOOT/include/omap4 GPIOS, SMARTIOS, CLOCKS, REGISTER DEFINES, etc.      OMAP5: All header files common to 2 or more omap5 targets are under OMAPBOOT/include/omap5 GPIOS, SMARTIOS, CLOCKS, REGISTER DEFINES, etc.

The main OMAPBOOT/ contains files common to all targets like fastboot, crc32, booti, device_tree, etc. IBOOT and EBOOT have their own subdirectory under the OMAPBOOT main directory IBOOT/ iboot.c     start.S EBOOT/ eboot.c     start.S

The "ops" structures

 * struct board_specific_functions: contains function pointers to BOARD specific functions


 * struct processor_specific_functions: contains function pointers to PROCESSOR specific functions


 * struct storage_specific_functions: contains function pointers to STORAGE specific functions

At boot up, we first initialized boot_ops and then init board_ops, proc_ops and storage_ops. boot_ops is used all over the place to access the underlying BOARD, PROCESSOR and STORAGE apis.
 * struct bootloader_ops: contains member structures for BOARD (board_ops), PROCESSOR (proc_ops) and STORAGE (storage_ops)

BOARDS should only define the functions they need. If something is not required, don't define it in the BOARD file and it will not be compiled and never executed. This helps reduce the overall code footprint. Since BOARD files carry code specific to a product, it can define functionality based only on what the product supports or needs.

If a user wants to switch between STORAGE devices, it can be done using STORAGE_OPS. Example, switching between eMMC and SATA.


 * PROC   - OMAP4/5, or any other processor
 * BOARD  - Product specific board file
 * STORAGE - Storage specific like eMMC, SD, SATA, etc.
 * COMMON - Fastboot, functions to boot kernel, etc.

How to clone and build
git clone git://git.omapzoom.org/repo/omapboot.git

Building p-master or p-master-dev
git checkout -b p-master remotes/origin/p-master    OR     git checkout -b p-master-dev remotes/origin/p-master-dev cd omapboot make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap5 BOARD=omap5evm clean make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap5 BOARD=omap5evm

This will generate an omap5evm directory under out/ i.e. omapboot/out/omap5evm/ Copy the usbboot and iboot.ift to a directory from where you want to use it

cp omapboot/out/omap5evm/usbboot emmc_binaries/ cp omapboot/out/omap5evm/iboot.ift emmc_binaries/

To build for OMAP5 Micro EVM: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap5 BOARD=omap5uevm

The resulting binaries will be located at omapboot/out/omap5uevm/

To build for PANDA: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap4 BOARD=panda

The resulting binaries will be located at omapboot/out/panda/

To build for Blaze: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap4 BOARD=blaze

The resulting binaries will be located at omapboot/out/blaze

To build for Blaze Tablet: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap4 BOARD=blaze_tablet

The resulting binaries will be located at omapboot/out/blaze_tablet

To build ALL supported targets: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm clean make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MAKEALL

Dual stage
Example for omap5 SEVM: make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap5 BOARD=omap5evm clean make CROSS_COMPILE= /icecream/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- ARCH=arm MACH=omap5 BOARD=omap5evm SPLIT=1

This will generate an omap5evm directory under out/ i.e. omapboot/out/omap5evm/ Copy the usbboot, iboot.ift and sboot.bin to a directory from where you want to use it

cp omapboot/out/omap5evm/usbboot emmc_binaries/ cp omapboot/out/omap5evm/iboot.ift emmc_binaries/ cp omapboot/out/omap5evm/sboot.bin emmc_binaries/

For the dual stage boot, copy the MLO (eboot.ift) and sboot.bin from omapboot/out/omap5evm/ Flash the MLO to your xloader partition and the sboot.bin to the bootloader partition.

How to sign for HS/EMU/HD devices
These instructions are valid for omap5 only:

Which version of msheild-lite to use?
To know which version of mshield-lite to use, please check the omap5 DB config that you are using. Go to the config for any one of the omap5 DBs that you're interested in testing and then look for the commit id mentioned in the mshieldlite_commit_id file. This is the commit that the dailybuild folks used to generate the bootloader that they packaged with the DB on Jenkins.

git clone ssh://@android.dal.design.ti.com:29418/repo/omap-mshield-lite.git omap-mshield-lite cd omap-mshield-lite git checkout v2.0.8 ./generate_MLO OMAP5430 ES1.0 ../omapboot/out/ /eboot.bin mv MLO ../omapboot/out/ /omap5evm_HS_ES1.0_MLO ./generate_ULO OMAP5430 ES1.0 ../omapboot/out/ /iboot.bin mv ULO ../omapboot/out/ /iboot.ift

For GP boards: mv ../omapboot/out/ /MLO ../omapboot/out/ /omap5evm_GP_ES1.0_MLO

Note: The iboot for GP boards is built into the usbboot binary.

Now "omapboot/out/ /iboot.ift" and "omapboot/out/ /omap5evm_HS_ES1.0_MLO" are what you use in place of stock binaries from daily build.

How to flash the omap5 board
OMAP5 SEVM: Check your dip switch settings S6-SYSBOOT(located on the back of the sEVM) Set the boot order to be USB first and eMMC second 3 2  1  0 ON ON ON ON

OMAP5 UEVM/PANDA5: Check your dip switch settings S1-SYSBOOT Set the boot order to be USB first and eMMC second 3  2   1   0 OFF OFF OFF OFF

NOTE: Refer to TI internal wiki for OMAPBOOT for more information on PANDA5 Revisions.

Start usbboot in fastboot mode: sudo ./usbboot -f

Connect your micro usb cable (USB3 cable can also be used) from the target to your flashing station Make sure the board is powered OFF

Power up your board

On PANDA5, connect the power cable and only after that connect the USB cable.

Run your fastboot.sh script sudo ./fastboot.sh

This will flash the binaries to the eMMC. Now reset the board.

How to flash using Virtual Box
NOTE: You can use virtualized Linux on Windows to make it work. Below is example for VirtualBox: Settings -> USB -> Add Empty Filter Name: OMAP5 sEVM Vendor Id: 0451 Product Id: d011

Then sudo ./usbboot -f and do as usual with your board: * first time should fail as drivers will be installed * next time will work OK.

Note: We don't support this, so if you have any issues please direct it to the omap5 mailing list.

Example
This is what you will see when you run usbboot:

sudo ./out/omap5evm/usbboot -f usbboot -f: starting in fastboot mode waiting for device... reading ASIC ID CHIP: 5430 IDEN: 0000000000000000000000000000000000000000 MPKH: 0000000000000000000000000000000000000000000000000000000000000000 CRC0: 06e92275 CRC1: 00000000 sending 2ndstage to target... f0030002 waiting for 2ndstage response...

This is what you will see on your console: [ iboot second-stage loader ] MSV=00000000 stay in SRAM and enter FASTBOOT mode

Usage
sudo ./usbboot -f

Downloads a built in second stage loader i.e. iboot into SRAM. Once in iboot, we perform some basic initialization and then enter into FASTBOOT mode. While in Fastboot mode, the user can run a fastboot script or send fastboot commands individually.

Format the device
sudo ./fastboot oem format

ERASE a partition
sudo ./fastboot erase 

FLASH a partition
sudo ./fastboot flash  

Update zImage only
sudo ./fastboot flash zimage zImage

Update ramdisk only
sudo ./fastboot flash ramdisk ramdisk.img

Read variables
sudo ./fastboot getvar  sudo ./fastboot getvar all ==> Read important board info

Boot a kernel directly from RAM
sudo ./fastboot boot boot.img

Format SD card
sudo ./fastboot getvar flash_slot        ==> reads the current device sudo ./fastboot oem set_flash_slot:SD    ==> changes the device to SD sudo ./fastboot.sh       OR sudo ./fastboot oem format sudo ./fastboot flash  

Flash SATA
sudo ./fastboot getvar flash_slot        ==> reads the current device sudo ./fastboot oem set_flash_slot:SATA  ==> changes the device to SATA sudo ./fastboot.sh      OR sudo ./fastboot oem format sudo ./fastboot flash  

Erase partitions on SATA
sudo ./fastboot getvar flash_slot        ==> reads the current device sudo ./fastboot oem set_flash_slot:SATA  ==> changes the device to SATA sudo ./fastboot erase 

Boot from SATA
On OMAP5 ES1.0, we cannot boot the bootloader from SATA but we can boot rest of the images from SATA. To do so, add this hack patch to the bootloader. The kernel too requires some changes, refer to TI internal wiki on SATA for more information.

EBOOT
This is the bootloader generated during the usbboot/omapboot build. At the end of the build, an MLO will be generated under /omapboot/out/. Flash this MLO to the XLOADER partition on your board by running, sudo ./fastboot flash xloader MLO. Now reboot the board.

This is what you will see on the console when you boot:

[ eboot second-stage loader ] boot device: MMC2 do_booti: boot device is mmc board_mmc_init efi partition table: load_ptbl efi partition table found 256    256K xloader 768    256K bootloader 1280    128K misc 2304     16M efs 35072     16K crypto 35104      8M recovery 51488      8M boot 67872    512M system 1116448    256M cache 1640736  29630M userdata printing bootimg header ...  Image magic:   ANDROID! kernel_size:  0x40e048 kernel_addr:  0x80008000 rdisk_size:  0x27fdc rdisk_addr:  0x81000000 second_size:  0x0 second_addr:  0x80f00000 tags_addr:  0x80000100 page_size:  0x800 name: cmdline:  0 id[0]:  0x57f894ea id[1]:  0x4129f002 id[2]:  0xda4a9147 id[3]:  0xe941a3ed id[4]:  0x9b02c1bb id[5]:  0x0 id[6]:  0x0 id[7]:  0x0 Reading kernel from start sector 51492 and reading 8305 number of sectors 8304 Done reading kernel from mmc Reading ramdisk from start sector 59800 and reading 320 number of sectors 319 Done reading ramdisk from mmc kernel  @ 80008000 (4251720) ramdisk @ 81000000 (163804) booting kernel... Uncompressing Linux... done, booting the kernel.

Keypad support to enter into FASTBOOT
NOTE: This will only work when you have a valid MLO on the eMMC.

Hold down the volume up and volume down keys on the OMAP5SEVM and you will enter into fastboot mode. The user will see this message on the console: "Keypress detected: going to fastboot mode"
 * OMAP5 SEVM:

Hold down button BTN1 (located near the USB OTG) on the OMAP5UEVM and you will enter into fastboot mode. The user will see this message on the console: "Button press detected: go to fastboot mode"
 * OMAP5 UEVM/PANDA5: