Firmware hacking


[edit] NOLO Hacking

For all NOLO related hacks see: here and here.

[edit] X-Loader Hacking

The information pertain requires JTAG and knowledge when dealing with serial debugging, etc. Most of the information has been scoured from various sources, credit goes to jacekowski for providing insights.

You will need: - OMAP3430 CSST Binary Release - Version 2.5 - Nokia's keys (which was never given to public).

The booting stage is separated into two parts prior to the booting of the kernel from /dev/mtd3. The first stage is the NOLO-X Loader (which is signed) and NOLO-secondary (which is not signed and is only a binary blob, if you want to edit secondary.bin, see the section NOLO hacking).

X-Loader portion is not only signed but was said to be encrypted in AES 256bit. The information below contains specific information from another handset bearing similar hardware features as Nokia N900. (The original site is no longer accessible).

Initial Software image

Since the NAND flash cannot be used to XIP (eXecute In Place), and since there must be public-key certificates inside the ISW block, there's a header on the ISW (Initial SoftWare) block. This header is not publicly documented (i.e., not in the TRM) for HS devices like the Milestone and the Droid. User droid001 has compared the Droid dump, the Milestone dump and the example CSST HS image, proposing an ISW structure like this one:


ISW Block

ISW Block Headers


0200: 00 24 00 00  8c be 00 00  00 00 00 00  00 00 00 00
0210: 00 00 00 87  58 2d 4c 4f  41 44 45 52  00 00 00 00
Offset (mbmloader img)	Value	Meaning	Comment
0x0200	0x00002400	ISW offset1) to X-LOADER 	
0x0204	0x0000BE8C	X-LOADER block length 	This is the number of bytes to load into RAM, since the whole X-LOADER block is copied.
This value differs on the Droid (it's 0x0000862C).
0x0208	0x00000000 0x00000000		
0x0210	0x87000000	RAM load address. This is the RAM location where the X-LOADER block is copied into RAM. 	The RAM execution starts at (this value+ 0x350), which is the ISW Entry Point, because CertISW's length is fixed (0x350).
0x0214	'X-LOADER'	Id 	

KEYS header

0220: 00 02 00 00  60 09 00 00  00 00 00 00  00 00 00 00
0230: 00 00 00 00  4b 45 59 53  00 00 00 00  00 00 00 00
Offset (mbmloader img)	Value	Meaning	Comment
0x0220	0x00000200	ISW offset to CertPK 	
0x0224	0x00000960	Lenght of CertPK 	
0x0228	0x00000000 0x00000000		
0x0230	0x00000000		
0x0234	'KEYS'	Id 	Public Keys (plural?)

PRIMAPP header

0240: 00 0c 00 00  50 16 00 00  00 00 00 00  00 00 00 00
0250: 00 00 00 00  50 52 49 4d  41 50 50 00  00 00 00 00
Offset (mbmloader img)	Value	Meaning	Comment
0x0240	0x00000C00	ISW offset to CertPPA 	
0x0244	0x00001650	Length of CertPPA	This value differs on the Droid (0x00001604).
0x0248	0x00000000 0x00000000		
0x0250	0x00000000		
0x0254	'PRIMAPP'	Id 	Primary Application

ISW Block Headers closing mark

0260: ff ff ff ff  ff ff ff ff  ff ff ff ff  ff ff ff ff
0270: ff ff ff ff  ff ff ff ff  ff ff ff ff  ff ff ff ff

Empty space

0280: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
03f0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00

KEYS block
Offset (mbmloader img)	Value	Meaning	Comment
0x0400	'CertPK_' 	Public Key Certificate2) 	Ends at 0x0200+0x0200+(0x0960-0x0001) = 0x0d5f

Empty space

0d60: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
0df0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00

Offset (mbmloader img)	Value	Meaning	Comment
0x0e00	'CertPPA' 	Primary Protected Application Certificate3) 	Ends at 0x0200+0x0c00+(0x1650-0x0001) = 0x244f

Empty space

2450: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00
25f0: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00

X-LOADER block

This storage area contains the signed ISW. We have named it “X-LOADER” for naming consistency reasons, and to avoid having too many data blocks called “ISW”. This is not to be confused with the X-Loader or X-Load program, which is the name of a program that is not used in Motorola Milestone/Droid but in TI OMAP development boards. In fact, Motorola itself (or picked this up by some patch from TI) labeled the whole 0x00000-0x7ffff NAND area as “X-Loader-NAND” in this code added by Motorola to the Linux kernel. And TI's eFuse patent mentions that the “X-LOADER” string is required for the system to boot in HS mode.

CertISW Offset (mbmloader img) Value Meaning Comment

0x2600	'CertISW' 	Initial Software Certificate4) 	Fixed length 0x350 Bytes

ISW Code & Data

Offset (mbmloader img)	Value	Meaning	Comment
0x2950	0f 10 a0 e1 	See disassembly below. 	ISW Entry point
0x2954	lots of code and data here 	This contains the Motorola mbmloader code (anything else?).	Ends at 0x0200+0x2400+(0xbe8c-0x0001)

Here is a disasembly of the Entry Point:

   Starting to disassemble from this point brings a meaningful flow. It is the 
   initial portion of the whole ca. 48kB or 34kB by droid image loaded into RAM
   (SDRAM Q2-ChipSelect-0 512MB starts at 0x8000 0000 [see TRM]) 
   It is the check for the PC if it was 0x87000350, which fits with the
   recorded "Load Address"+"Initial SW Entry Point" in CSST that is 0x87000000 + 0x0350.
   When the ISW entry point is changed in CSST, its value will be added to a value with base
   value 0x350 at 0x27B4 of the .img file.
   So in a nutshell, the first 0x0350 bytes in RAM are likely a copy of the CertISW.
ROM:00000000 0F 10 A0 E1                 MOV     R1, PC          ; Subtract 8 for the address of THIS
ROM:00000004 08 10 41 E2                 SUB     R1, R1, #8      ; due to pipelining.
ROM:00000008 C0 20 9F E5                 LDR     R2, =0x87000350
ROM:0000000C 02 00 51 E1                 CMP     R1, R2          ; Checks whether it is running at the correct RAM location.
ROM:00000010 1B 00 00 1A                 BNE     loc_84          ; If it's not, branches into a dead loop.
ROM:00000084             loc_84                                  ; CODE XREF: ROM:00000010
ROM:00000084                                                     ; ROM:loc_84
ROM:00000084 FE FF FF EA                 B       loc_84          ; This is a Dead Loop.

A nice disassembly of mbmloader has been provided by Yakk IDA DB of mbmloader. He used IDA version 5.5.

Here is an older, barely readable decompilation of mbmloader by maui.

ISW Block End 1) ISW offsets are relative to the start of the ISW block (0x200). 2) , 4) CSST_UserManual 2.5 p.77 4.2.5 3) CSST_UserManual 2.5 p.4 0.3 --- END --- The following set of information is pulled from another website (which is also now no longer available):

[edit] OMAP Bootloader Overview

There are several stages of bootloaders that perform different levels of initialization on an OMAP platform, in order to eventually load and run the filesystem. This figure shows the booting sequence of the ROM code, x-loader, u-boot, and kernel, with each stage performing enough configuration in order to load and execute the next.

The Bootloader Project covers specifically the x-loader and the u-boot: a code overview, and how to obtain and build the code.

Why are there two bootloaders? The first bootloader, x-loader, is a stripped-down version of the u-boot, designed to run in OMAP's small on-chip SRAM. It initializes the main off-chip memory of the system and other necessary device drivers, and then loads the larger bootloader for Linux, u-boot.

When a system is first booted, the CPU invokes the reset vector to start the code at a known location in ROM:

-> ROM Code: 1) Performs minimal clocks, memories and peripheral configuration. 2) Searches the booting devices for a valid booting image. 3) Loads the x-loader into SRAM and executes it.

-> X-Loader: 1) Sets up the pin muxing. 2) Initializes clocks and memory. 3) Loads the U-Boot into SDRAM and executes it.

-> U-Boot: 1) Performs some additional platform initialization. 2) Sets the boot arguments. 3) Passes control to the kernel image.

-> Kernel: 1) Decompresses the kernel into SDRAM. 2) Sets up peripherals such as LCD, HDMI, I2C bus, USB, SD card, audio etc. 3) Mounts the Linux filesystem that contains at userspace libraries/applications.

[edit] OMAP Boot Sequence

Detailed documentation on the OMAP boot sequence is available in the OMAP TRM, Initialization chapter. The TRMs for multiple OMAP platforms (OMAP4430, OMAP4460, OMAP34xx, etc) are available here:

[edit] SYSBOOT Pins

The internal ROM Code can attempt to boot from several different peripheral and memory devices, including, but not limited to: Serial (UART3), SD Card, eMMC, NAND, and USB. The order in which these devices are searched for a valid first-stage booting image (x-loader) is determine by a set of GPIO configuration pins referred to as SYSBOOT. The TRM includes a table that shows the booting device list that each combination of the SYSBOOT pins refers to.

The SYSBOOT value can be read from physical address 0x480022f0, either using JTAG, or if you have linux running, use devmem2:

# devmem2 0x480022f0 b                           
/dev/mem opened.
Memory mapped at address 0x40020000.
Value at address 0x480022F0 (0x400202f0): 0x2F

For OMAP34xx, there is also a tool to show the boot order: omap34xx-boot-order

[edit] First Stage Boot

For example, the SYSBOOT pins could be set such that booting device list consists of 1) serial (UART3), 2) SD card (MMC1), and 3) NAND flash. In this case, the ROM code would first look for a valid x-loader over the serial port, then in the SD card, then in the NAND flash. Whenever it finds a valid x-loader, it proceeds with execution of that binary.

[edit] Serial Boot

For serial boot, a simple ID is written out of the serial port. If the host responds correctly within a short window of time, the ROM will read from the serial port and transfer the data to the internal SRAM. Control is passed to the start of SDRAM if no errors are detected. UART3 is the only uart for which the ROM will attempt to load from.

[edit] SD Card Boot

If MMC is included in the booting device list, the ROM looks for an SD Card on the first MMC controller. If a card is found, the ROM then looks for the first FAT32 partition within the partition table. Once the partition is found, the root directory is scanned for a special signed file called "MLO" (which is the x-loader binary with a header containing the memory location to load the file to and the size of the file). Assuming all is well with the file, it is transfered into the internal SRAM and control is passed to it. Both MMC1 and MMC2 can be used for booting.

[edit] NAND / eMMC Boot

If NAND is included in the booting device list, the ROM attempts to load the first sector of NAND. If the sector is bad, corrupt, or blank, the ROM will try the next sector (up to 4) before exiting. Once a good sector is found, the ROM transfers the contents to SRAM and transfers control to it. (The same steps are performed for eMMC if eMMC is included in the booting device list instead of NAND.)

[edit] Second Stage Boot

It is the job of the x-loader to transfer the 2nd stage loader into main memory, which we call the u-boot. Typically both the x-loader and u-boot come from the same storage medium. For example, typically if the x-loader is transferred via USB, the u-boot will also be transferred via USB, and if the x-loader is transferred via SD card, the u-boot will also be transferred via SD card. However, this is not required. For example, you could flash the serial x-loader into the NAND. The ROM code will load the x-loader from NAND and transfer control to the x-loader, which will wait for the u-boot to be downloaded from the serial port.

[edit] Serial Boot

In the case of loading both the u-boot over the serial port, the x-loader waits for the host to initiate a kermit connection to reliably transfer large files into main memory. Once the file transfer is completed successfully, control is transfered.

[edit] SD Card Boot

In the case of loading the u-boot via the SD card, the SD card x-loader looks for a FAT32 partition on the first MMC controller and scans the top level directory for a file named "u-boot.bin". It then transfers the file into main memory and transfers control to it.

[edit] NAND / eMMC Boot

In the case of a u-boot stored in NAND, the x-loader expects the u-boot to be located at the 5th sector (offset 0x00800000). It transfers the image from NAND into main memory and transfers control to it. In the case of a u-boot stored in eMMC, the x-loader expects the u-boot to be located at the offset 0x200.

[edit] x-loader overview

The x-loader is a small first stage bootloader derived from the u-boot base code. It is loaded into the internal static RAM by the OMAP ROM code. Due to the small size of the internal static RAM, the x-loader is stripped down to the essentials. The x-loader configures the pin muxing, clocks, DDR, and serial console, so that it can access and load the second stage bootloader (u-boot) into the DDR.

[edit] u-boot overview

The u-boot is a second stage bootloader that is loaded by the x-loader into DDR. It comes from Das U-Boot. The u-boot can perform CPU dependent and board dependent initialization and configuration not done in the x-loader. The u-boot also includes fastboot functionality for partitioning and flashing the eMMC. The u-boot runs on the Master CPU (CPU ID 0), which is responsible for the initialization and booting; at the same time, the Slave CPU (CPU ID 1) is held in the “wait for event” state.

[edit] Building the Bootloaders

The following steps will build the x-loader and u-boot.

Note: In order to build the x-loader or u-boot, it is recommended that you use the omappedia Release Notes page corresponding to the platform you are using (Blaze, Blaze Tablet, Panda, or Zoom) and follow the instructions for that release: In general, the instructions will be very similar with the following exceptions:

   The commit ID used to pull the code from the u-boot and x-loader git trees varies based on the release. It is recommended that you use the correct commit ID corresponding to your release, as this is how the validation is performed.
   The config file used to setup the configuration when building the u-boot and x-loader varies based on the platform you are using. See the tables below. 

Also, ensure that you have installed the pre-requisite packages for building the bootloaders, namely Git and the CodeSourcery ARM Compiler. These instructions are included in the omappedia Release Notes corresponding to your release. You can also find the information here:

   Git is available for download at For more details on installing and using git please see this wiki page.

[edit] Further reading