2012年5月28日月曜日

Boot Process

Boot Process

For the complete list of my articles on Android devices and software, including analysis of devices and system firmware, lists of external resources and tools, and How-To instructions, check the front page of this wiki under the Android heading.

An examination of how the  Qualcomm Mobile Station Modem (MSM) Snapdragon 7x30 system-on-chip boot-straps the processors into an operating system.

There are two processors in the MSM 7x30, an ARM9 for the radio and an ARM11 auxiliary applications processor. Each processor has its own  JTAG and can be independently controlled using it.

ARM9 Boot Process

The ARM9 is the primary processor. It boots first, executing the Primary Boot Loader (PBL) from on-board ROM at 0xFFFF0000 .

The MSM platform has the facility to force Secure Boot using the status of the FORCE_TRUSTED_BOOT Qfuse on-chip or a high-state BOOT_SCUR pin connected to GPIO95. In this mode the PBL verifies the signature of the SBL/OSBL before executing it,which verifies the REX/AMMS signature in the same way.

After some hardware initialisation the PBL reads the Device Boot Loader (DBL) from the first partition of the flash memory device (In Linux, mmcblk0p1).

DBL is part of Qualcomm's SecureBoot, which uses cryptography to guarantee that the boot-loader images haven't been tampered with. DBL configures the Cryptographic Look-aside Processor (CLP), a dedicated cryptographic co-processor, and other hardware sufficient to load and execute the Secondary Boot Loader (SBL) from a Flash memory device on EBI2 (External Bus Interface 2) from partition 3 (Linux mmcblk0p3).

The SBL, also known as the Operating System Boot Loader (OSBL), is loaded into memory at 0x8000000 (IMEM - Internal Memory, the MSM7230 package-on-package (PoP) RAM). This is the ARM9 Monitor (AMON). It provides an Extensible Firmware Interface (EFI) -like environment for controlling the boot process. After doing more hardware configuration including UARTs and USB (for potential remote console connections to the monitor) it loads the Applications processor Secondary Boot Loader (APPSBL a.k.a. hboot) on the ARM11 applications processor from partition 18 (Linux mmcblk0p18) into memory @ 0x8D000000 virtual, 0x00000000 physical.

It then loads and executes the combined REX/AMSS from partition 5 (Linux mmcblk0p5). The image contains the REX (Real-time EXecutive) which is an  L4A Pistachio embedded micro-kernel and  Iguana operating system combination, with extensive Qualcomm and HTC modifications and extensions.

REX is responsible for loading the firmware into the ancillary micro-controller (microP), digital signal processor and voice processor and initialising them. It runs in Security Domain 0 (SD0).

When the ARM11 starts REX unloads/disconnects its eMMC driver and from then on relies on remote procedure calls (RPC) via shared memory (SMEM) to the ARM11 application processor to read and write the eMMC. On the ARM11 side the Linux operating system uses the rmt_storage (remote storage) driver to handle such requests.

Finally on the ARM9 REX executes the Advanced Mobile Subscriber Software (AMSS). AMSS runs in Security Domain 1 (SD1).

ARM11 Boot Process

The ARM9 running REX loads the eMMC "hboot" partition into memory at 0x8D00000 (virtual) and starts the ARM11 auxiliary applications processor executing at this location. It runs in Security Domain 3 (SD3). The core of the boot-loader can be found in the Android source-code repository in the  platform/bootable/bootloader/legacy.git project. This source-code maps well to current hboot images when they are reverse-engineered; allowing the libc and core functions and structures to be identified.

HBoot

This secondary boot-loader is responsible for configuring, loading, and passing execution to the applications operating system which in this case is Linux. It is also responsible for updating the firmware for the entire device by writing binary images contained in compressed ZIP archives that are distributed via Firmware Over The Air (FOTA) or manual methods, or resetting the device to the same state as when it left the factory. It has several modes of operation:

  1. Fastboot restart
  2. Chain operating system
  3. Chain recovery system
  4. HBoot menu and remote command parser
  5. Fastboot menu and remote command parser
  6. Remote Update Utility (RUU) file transfer mode

Fast Boot Restart

I had previously missed mention of HTC's "fast-boot" functionality which is part of the HTC Sense customisations. From power-off it gets the device ready to make a call in about six seconds (A regular start will take upwards of a minute). From what information is out there it's an ultra-low-power sleep state - something in the PC world we'd call S3 or Suspend-to-RAM. Cyanogen has already replicated it in the 6.1 series.

Without more information it's difficult to be certain how this functions technically but my educated guess is this: When selecting power-off in the user interface the Sense/kernel sends a particular oem-XX code or calls an RPC function to tell the radio to shutdown and remove power from the ARM11 applications processor. I'd suspect the ARM9 radio continues running REX/AMSS but turns off power to almost everything. When the power button is pressed REX brings up the power to devices and restarts the ARM11. Now, the question is, did the ARM11 register state get saved by REX/AMSS so it can be restored and execution restarted where it left off, or does it restart via hboot. If it goes the hboot route then hboot will detect it's a fast-boot and restore contexts and then jump back into the kernel where it'll unfreeze itself.

Update: Having tested this on a U.K. HTC Desire Z it looks likely that hboot isn't re-executed. The green-on-white "htc" splash screen appears briefly (1/2 second maybe) then the Android lock-screen appears. The time take to be ready is less than two seconds. Holding down key-combinations that usually cause hboot to enter special modes are not recognised.

Sources:

 New HTC Fast Boot Technology Already Present On Desire Z/HD Offers 5 Second Boot Times. Smarts, Trickery, Or Both?

 Cyanogen Demos HTC Fast-Boot-A-Like On Nexus One

Chain operating system

Hboot loads the image contained in the eMMC "boot" partition into memory and then passes execution to it. This is the Linux kernel (the compressed vmlinux file found at arch/arm/boot/compressed/ in the kernel build location) and an attached initial RAM-disk - the initrd - which is responsible for configuring the operating system and starting the Android services and graphical user interface (GUI).

Chain recovery system

The boot-loader loads the image contained in the eMMC "recovery" partition into memory and passes execution to it. This is the Linux kernel and an attached initial RAM-disk containing the recovery executable. This reads commands from /recovery/command in the eMMC "cache" partition and performs tasks. It communicates with the boot-loader via the eMMC "misc" partition, which is a raw data image written from, and read into, memory and treated as a character array.

HBoot menu and Remote Command Parser

Using HBoot commands over the serial interface

To set-up a Linux host see Connecting using serial-over-USB to talk to Radio or HBoot

Use the screen utility to connect to the port and talk to the device (before using screen be sure to read the manual carefully especially in relation to the cryptic key-presses required to exit it!):

screen /dev/ttyUSB0  

The terminal will be blank to begin with so press Enter. You should see:

hboot>    

Commands

Be careful in issuing commands since some can be destructive, such as task 29, which can start a format of critical areas of the device without awaiting further confirmation. Some commands may not be available on all devices - many of them are part of the engineering HBoot which isn't usually installed on retail devices).

battcheck <param1>                                              // battery check  bdaddress <param1>:<param2>:<param3>:<param4>:<param5>:<param6> // set bluetooth address (the bluetooth MAC)  bkflash2emmc                                                    // ?  btrouter                                                        // USB blue-tooth router?  emapi  emapiBand  emapiChannel  emapiCountryID                                                  // display country signature and ID  emapiCounters  emapiCrsuprs <channel>                                          // set carrier suppression mode (channel is 1-14 or 0 to stop test)  emapiDown  emapiEtheradd  emapiFqacurcy  emapiInit  emapiMpc  emapinRate  emapiOut  emapiPkteng_start  emapiPkteng_stop  emapiRate  emapiRateset "default" | "all" | <arbitrary rateset>            // determine the WiFi rates to use  emapiReadCal                                                    // read the WiFi calibration configuration  emapiSetDefCal                                                  // set default WiFi calibration  emapiSetIrqPin  emapiTest  emapiTXpwr1  emapiUp  emapiVersion  emapiWlanMac                                                    // display the WLAN MAC address and where it is stored in non-volatile storage  emptypagecheck                                                  // check empty pages (of what - memory, cache?)  erase <partition_name>                                          // erase data in <partition_name>  erasebcid                                                       // erase back-up CID  eraseconfig <param1>                                            // erase the config fields  erasesd ?                                                       // erase micro SD-card  eraseWifiFlash                                                  // erase WiFi flash memory  fmrouter                                                        // modem AT command shell to switch audio path (for FM radio) and start bt_router  fmtx                                                            // FM transmitter ?  gotofastboot                                                    // switch to fastboot mode  gotohboot                                                       // switch to hboot mode  heap                                                            // report heap memory usage  heaptable                                                       // display the Free and Allocated heap tables  imgcrc                                                          // calculate checksums on hboot, recovery, boot and system partitions  jump                                                            // immediately continue booting the device into the operating system  keytest                                                         // enter key-test mode: displays names of keys being pressed. Exits after 5 presses.  listpartition                                                   // list partition names  partition_test <name> [auto_mark_bad_flag]                      // test a partition  powerdown                                                       // immediately powers down the device  ram_test <start address> <length> <count> <mode>                // test RAM with or without cache  rbchk [partition | block]                                       // read bad-block (artition = <all|recovery|boot|system|cache|userdata>, block id in HEX format)  rebootRUU                                                       // immediately reboot in Remote Update Utility mode (boots with white-on-black HTC logo and waits for update)  readbcid                                                        // read back-up CID  readconfig                                                      // read the config fields  readmbserialno                                                  // read main-board serial number  readserialno                                                    // read device serial number  readsku                                                         // read the SKU fields (PCBID and others)  resetautoimage                                                  // ?  resetpreferdiag                                                 // ?  reset                                                           // immediately reset the device (reboots)  resetuP                                                         // reset microP ?  rflash <param1>                                                 // read NAND flash  rMfgTp                                                          // read manufacturers test points  rtask  savefb2sd <file name> [main|ruu]                                // save frame buffer to SD-card  savemem2sd <memory offset> <length> <file name>                 // save memory region to SD-card  saveprt2sd <partition name> <-n> <file name> <-a>               // save partition to SD-card  sdtest                                                          // test the micro SD-card  task <task number>  tflash                                                          // test NAND flash  tick                                                            // report clock tick  usbspeed ?  usbtestmode <value>  wMfgTp <param1> <...>                                           // write manufacturer test points   writebcid <param1>                                              // write back-up CID  writeconfig ?  writemid <param1>                                               // write model ID  writeserialno <param1>                                          // write serial number  writesku <param1> <param2>                                      // write SKU field with value     

An example of the emapiReadCal command:

hboot>emapiReadCal  Wlan data header ++++++++++++++++++++  Signature : 0xEE4329  UpdateStatus : 0x1  UpdateCount : 0x1  BodyLength : 0x2B8  BodyCRC : 0xE9B44279  aDieId(0) : 0x0  aDieId(1) : 0x0  aDieId(2) : 0x0  aDieId(3) : 0x0  countryID : 0x10  Wlan data len: 696  Wlan data body --------------------------  macaddr=00:23:76:D4:E0:44  sromrev=3  vendid=0x14e4  devid=0x432f  boardtype=0x4b9  boardrev=0x32  boardflags=0x200  xtalfreq=37400  aa2g=1  aa5g=0  ag0=255  pa0b0=6003  pa0b1=64086  pa0b2=65195  pa0itssit=62  pa0maxpwr=78  opo=20  mcs2gpo0=0xCCCC  mcs2gpo1=0xCCCC  rssismf2g=0xa  rssismc2g=0xb  rssisav2g=0x3  bxa2g=0  ccode=ALL  cctl=0x0  cckdigfilttype=0  ofdmdigfilttype=1  rxpo2g=0  boardnum=1  nocrc=1  otpimagesize=182  hwhdr=0x05ffff031030031003100000  RAW1=80 32 fe 21 02 0c 00 22 2a 01 01 00 00 c5 0 e6 00 00 00 00 00 40 00 00 ff ff 80 00 00 00 00 00 00 00 00 00 00 c8 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 20 04 D0 2 29 43 21 02 0c 00 22 04 00 20 00 5A  sd_gpout=0  sd_oobonly=1    

OEM Reboot Codes

Adam (teferi) did some tests on a T-Mobile G2 with the known OEM reboot codes. Here's the results:

--reboot=oem-1F Regular reboot
--reboot=oem-42 HBoot menu
--reboot=oem-74 In some indeterminate state, for all intents and purposes powered off or just plain dead
--reboot=oem-76 Wipe data and cache (factory reset) Amber and Green LEDs flash whilst it is doing it, then the device reboots
--reboot=oem-78 ??

These codes and others are sent to REX/AMMS on the ARM9 radio processor in arch/arm/mach-msm/pm.c. This is a summary of the code that touches restart_reason:

static uint32_t restart_reason = 0x776655AA;    static void msm_pm_restart(char str, const char *cmd)  {  	msm_pm_flush_console();    	/*  always reboot device through proc comm */  	if (restart_reason == 0x6f656d99)  		msm_proc_comm(PCOM_RESET_CHIP_IMM, &restart_reason, 0);  	else  		msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);    #if defined(CONFIG_MSM_RMT_STORAGE_SERVER)  	printk(KERN_INFO "from %s\r\n", __func__);  	wait_rmt_final_call_back(10);  	printk(KERN_INFO "back %s\r\n", __func__);  	/* wait 2 seconds to let radio reset device after the final EFS sync*/  	mdelay(2000);  #else  	/* In case Radio is dead, reset device after notify Radio 5 seconds */  	mdelay(5000);  

0 件のコメント:

コメントを投稿