Description of protocol of connection wia COM port a program (V_Klay program) and device (loader in Siemens mobile phone) (protocol between program and loaders) Author : ValeraVi (valeravi@vi-soft.com.ua, http://www.vi-soft.com.ua) Release: 2003-09-13 note: --> the program is sending the data to the phone <-- the phone is sending (answering) the data to the program w<- the program is wait for acknowledge. Program will skip all data until it readed ack data from a phone. XORChecksum - a checksum of data that is calculated as XOR operation of all bytes of data. WORD, DWORD an so on is sended from phone to the program in order from lowest byte to the highest. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ FREIA LOADERS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Uploading the loadres to the phone ================================== 1. Initiate of accepting the loaders. Program sends the byte 0x55 (U) to the phone. If phone do not answer by byte 0xa0, then program sends 0x55 again and again. If phone answer 0xa0 - program starts sending the 1-st boot. 2. Sending 1-st boot. If phone has a patched boot. The program is sending a special boot first: --> BYTE = 52 - size of special boot --> 36 BYTES = 165, 90, 165, 165, 230, 88, 165, 0, 126, 182, 13, 255, 83, 73, 69, 77, 69, 78, 83, 32, 66, 79, 79, 84, 32, 80, 65, 82, 65, 77, 69, 84, 69, 82, 58, 1 --> 14 BYTES = nutzoisthebest --> 2 BYTES = 0, 0 w<- BYTE = 0xA5 - if not received 0xa5 - error. w<- BYTE = 0x06 - if not received 0x06 - error. Now sending 1-st boot: If phone is new model (x55), the 1-st boot sending in that way: --> BYTE = 0x00 --> len BYTES = 1-st boot data. --> (0x200-len) BYTES = 0xff - sending a (0x200-len) 0xff's. --> 17 BYTES = 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04 w<- BYTE = 0xA5 - if not received 0xa5 - error. If phone is old model, the 1-st boot sending as usually: --> BYTE = len - lenght in bytes of boot --> len BYTES = 1-st boot data. --> BYTE = XORchecksum - check sum of len bytes of 1-st boot data. w<- BYTE = 0xA5 - if not received 0xa5 - error. 3. Sending 2-nd boot. --> BYTE = len - lenght in bytes of boot --> len BYTES = 2-nd boot data. --> BYTE = XORchecksum - check sum of len bytes of 2-nd boot data. w<- BYTE = 0xA5 - if not received 0xa5 - error. 4. Sending 3-rd boot. --> BYTE = len - lenght in bytes of boot --> len BYTES = 3-rd boot data. --> BYTE = XORchecksum - check sum of len bytes of 3-rd boot data. w<- BYTE = 0xA6 - if not received 0xa6 - error. 5. Sending 4-th boot. --> BYTE = len - lenght in bytes of boot --> len BYTES = 4-th boot data. --> BYTE = XORchecksum - check sum of len bytes of 4-th boot data. w<- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. If WORD = UNKNOWN_FLASH_NAK = 0xCCCC - error - flash IC type is unknown for loader. Then loader sends a WORD=flashtype (LOBYTE - LOBYTE(manufacturer), HIBYTE - LOBYTE(IC ID)) and exits (reset MCU). Working with loader in the phone ================================ After upload all boots of loader to the device the program use next protocol to communicate: Communication always is initiated by the program by writting a 1 byte of command. Commands list: ============== Checking, is the loader ready to work? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x41 (A) - command <-- BYTE = ack - if ack = 0x52 (R) - loader ready, else - error (loader not ready) Set the communication port speed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x48 (H) - command --> BYTE = baudtype - speed: 0x00 - 57600, 0x01 - 115200, 0x02 - 234000, 0x03 - 460800 <-- BYTE = 0x68 (h) - ack, parameters ok. If ack=0x68 is not readed - error! after receive ack the program is changed COMM port baud rate. And loader in the phone is changed UART baud rate, then: --> BYTE = 0x41 (A) - program send a byte to confirm changing the baud rate. w<- BYTE = 0x48 (H) - ack, baud rate is changed. If this ack is not received the loader in the phone changed speed back to 115200, and program is changed back COMM port speed to 115200 and generated error. Get phone information ~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x49 (I) - command <-- 0x200 BYTES = phoneinfo <-- DWORD = phoneID1 <-- DWORD = phoneID2 (for C30 phoneID1 and phone ID2 its a one QWORD phone ID) <-- DWORD = flash 1 IC Manufacturer (LOWORD) and device ID (HIWORD) <-- DWORD = flash 2 IC Manufacturer (LOWORD) and device ID (HIWORD) <-- WORD = flashhcram <-- WORD = BC35_Type - number of flashes (but with a C35 "style") <-- 10 BYTES = B5009[FREIA_5009_AND_0001_LEN] for IMEI: <-- WORD = lockstatus <-- 4 WORDS = factory_register[4] <-- 8 BYTES = originalB5009[8] (i.e. size of ansver - 560 bytes) Quit from the loader. ~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x51 (Q) - command Also the program sends a 0x5A (Z) byte to the COM port (for quit from unisiemens loaders). After this command you can turn on the device without removing the battery. Reading the memory of the phone. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x52 (R) - command --> 3 BYTES = addr - addr of MCU memory to read (addr is from 16MB address space of MCU). Hight bytes of addr is sending first. --> 3 BYTES = size - size of block to read. Hight bytes of size is sending first. Is is recommended that size=4096 <-- size BYTES = flash data <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. <-- WORD = (LOBYTE=XORChecksum, HIBYTE=0x00) - XOR checksum of received flash data. Reading the memory of the phone. (Freia 9 loaders) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x52 (R) - command --> 3 BYTES = addr - addr of MCU memory to read (addr is from 16MB address space of MCU). Hight bytes of addr is sending first. --> 3 BYTES = size - size of block to read. Hight bytes of size is sending first. Is is recommended that size=4096 <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. <-- size BYTES = flash data <-- WORD = (LOBYTE=XORChecksum, HIBYTE=0x00) - XOR checksum of received flash data. <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. Writting the data to the memory of the phone. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x46 (F) - command --> WORD = dataseg - hight 12 bit of flash offset (from begin of flash). Hight byte of dataseg is sending first <-- WORD = flashbase - start MCU data seg (DPP) of current flash IC. If flashbase=ADDRESS_TOO_FAR_NAK=0xEEEE - error - dataseg is out of flash (next data is not sending by the phone). If flashbase=UNKNOWN_FLASH_NAK=0xCCCC - error - flash IC type is unknown for loader. Then loader sends a WORD=flashtype (LOBYTE - LOBYTE(manufacturer), HIBYTE - LOBYTE(IC ID)) and exits (reset MCU). <-- WORD = offset - Start offset in MCU data seg (DPP) of the current block of flash. <-- WORD = seg - Start MCU data seg (DPP) of the current block of flash. <-- WORD = dummy - not used, ignored. <-- WORD = flashend - not used, ignored. <-- WORD = blocksize - (blocksize*4096) = size of current block of flash to write. <-- WORD = id - always = 0xffff. --> (blocksize*4096) BYTES = flash data - data to write to flash of phone. --> BYTE = XORChecksum - XOR checksum of sended flash data. <-- WORD = flashbase - If flashbase=RAM_ERROR=0xFFFF - error - phone RAM error (after this loader send CRC_ERROR_NAK=0xBBBB and next data is not sended by the phone) If flashbase=CRC_ERROR_NAK=0xBBBB - error - XORChecksum is not correct. Loader is cancel current operation and next data is not sended. <-- WORD = seg <-- WORD = offset then loader is erasing the block of flash. After this it sends: <-- WORD = ERASE_ACK=0x0202 then loader is starting writting of flash. It sends: <-- WORD = flashbase <-- WORD = seg <-- WORD = offset when loader fihished writting the flash it sends: <-- WORD = WRITE_ACK=0x0303 then lader starts a testing written block of flash. After this it sendins a checkum: <-- WORD = CheckSum - check sum of data readed from flash block, what is just written. CheckSum is calculated as sum of all WORDS in the flash block. <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CHAOS LOADERS FOR SIEMENS X65 SERIES, THAT IS PATCHED BY CHAOS MIDLET ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Uploading the loadres to the phone ================================== 1. Initiate of accepting the loaders. Program sends the 2 bytes "AT" to the phone. If phone do not answer by byte 0xb0, then program sends 2 bytes "AT" again and again (with delay of 100 ms). If phone answer 0xb0 - program starts sending the 1-st boot. 2. Sending 1-st boot. (it is even not a boot :) - just 1 byte) --> BYTE = 0x30 3. Sending 2-nd boot. --> BYTE = lenL - low byte of lenght in bytes of boot --> BYTE = lenH - hight byte of lenght in bytes of boot --> len BYTES = 2-nd boot data. --> BYTE = XORchecksum - check sum of len bytes of 2-nd boot data. w<- BYTE = 0xB1 - if not received - error. 4. Sending 3-rd boot (key1). --- wait 100 ms. --> BYTES of key1 data 5. Sending 4-th boot (key2). --- wait 100 ms. --> BYTES of key2 data w<- BYTE = 0xA5 - if not received - error. Working with loader in the phone ================================ After upload all boots of loader to the device the program use next protocol to communicate: Communication always is initiated by the program by writting a 1 byte of command. Commands list: ============== Checking, is the loader ready to work? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x41 (A) - command <-- BYTE = ack - if ack = 0x52 (R) - loader ready, else - error (loader not ready) Set the communication port speed ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x48 (H) - command --> BYTE = baudtype - speed: 0x00 - 57600, 0x01 - 115200, 0x02 - 234000, 0x03 - 460800 0x04 - 614400, 0x05 - 921600, 0x06 - 1228800, 0x07 - 1600000 <-- BYTE = 0x68 (h) - ack, parameters ok. If ack=0x68 is not readed - error! after receive ack the program is changed COMM port baud rate. And loader in the phone is changed UART baud rate, then: --> BYTE = 0x41 (A) - program send a byte to confirm changing the baud rate. w<- BYTE = 0x48 (H) - ack, baud rate is changed. If this ack is not received the loader in the phone changed speed back to 115200, and program is changed back COMM port speed to 115200 and generated error. Get phone information ~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x49 (I) - command <-- 128 BYTES: 0x00 16 BYTES - model 0x10 16 BYTES - manufacturer 0x20 16 BYTES - IMEI (in ASCII) 0x30 16 BYTES - (reserved) 0x40 DWORD - base address of flash (ROM) 0x44 12 BYTES - (reserved) 0x50 WORD - flash manufacturer 0x52 WORD - flash ID 0x54 BYTE - N, CFI byte 27h. Size of flash = 2^N 0x55 WORD - CFI bytes 2Ah-2Bh size of write-buffer (not used by program) 0x57 BYTE - CFI byte 2Ch - number of regions. 0x58 WORD - N, CFI number of blocks in 1st region = N+1 0x5A WORD - N, CFI size of blocks in 1st region = N*256 0x5C WORD - N, CFI number of blocks in 2nd region = N+1 0x5E WORD - N, CFI size of blocks in 2nd region = N*256 0x60 32 BYTES - (reserved) !!!! WARNING !!!: 1. Program must write data to the flash by blocks. 2. Program is responsible for dividing writing data into blocks. 3. If 1 and 2 is not taken in account then DATA IN THE FLASH WILL BE CORRUPTED AND PHONE WILL DEAD! Quit from the loader. ~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x51 (Q) - command Also the program sends a 0x5A (Z) byte to the COM port (for quit from unisiemens loaders). After this command you can turn on the device without removing the battery. Reading the memory of the phone. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x52 (R) - command --> 4 BYTES = addr - addr of MCU memory to read (addr is from address space of MCU). Hight bytes of addr is sending first. --> 4 BYTES = size - size of block to read. Hight bytes of size is sending first. <-- size BYTES = flash data <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. <-- WORD = (LOBYTE=XORChecksum, HIBYTE=0x00) - XOR checksum of received flash data. Writting the data to the memory of the phone. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> BYTE = 0x46 (F) - command --> 4 BYTES = addr - addr of memory to write (addr is from address space of MCU). Hight bytes of addr is sending first. --> 4 BYTES = size - size of block to read. Hight bytes of size is sending first. --> size BYTES = flash data - data to write to flash of phone (WARNING! Size must equal to size of block at given address). --> BYTE = XORChecksum - XOR checksum of sended flash data. <-- WORD = ACK - acknowledge: ACK=OK_ACK=0x0101 - OK, ACK=CRC_ERROR_NAK=0xBBBB - checksum error ACK=BOUNDS_ERROR_NAK=0xFFFF - bounds error (address is not on the edge of block) ACK=UNKNOWN_FLASH_NAK=0xCCCC - error - flash IC type is unknown for loader. Then loader sends a WORD=flashtype (LOBYTE - LOBYTE(manufacturer), HIBYTE - LOBYTE(IC ID)). ACK=ACCESS_DENIED_NAK=0xEEEE - protected area (bootcore/EEFULL), program must skip writting to that block. If ACK not equal OK_ACK loader is cancel current operation and next data is not sended. then loader is erasing the block of flash - max 3 seconds. After this it sends: <-- WORD = ERASE_ACK=0x0202 then loader is starting writting of flash. when loader fihished writting the flash it sends: <-- WORD = WRITE_ACK=0x0303 then loader starts a testing written block of flash. After this it sendins a checkum: <-- WORD = CheckSum - check sum of data readed from flash block, what is just written. CheckSum is calculated as sum of all WORDS in the flash block. <-- WORD = 0x4b4f (OK) - if not received 0x4b4f - error. !!!! WARNING !!!: 1. Program must write data to the flash by blocks. 2. Program is responsible for dividing writing data into blocks. 3. If 1 and 2 is not taken in account then DATA IN THE FLASH WILL BE CORRUPTED AND PHONE WILL DEAD! Restore bootcore. ~~~~~~~~~~~~~~~~~ --> 'F' --> 4-byte 0x00000000 --> 4-byte 0x00000000 (data is not sended) <-- 0x0101... and so on, as for write command. Test - is flash block empty? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> 'T' --> 4-byte address (H..L) --> 4-byte len (H..L) <-- 0xFF - block is empty (all bytes is FF), 0x00 - not. Keep alive. (must be sent with interval not greather than 250 ms, else loader will be unloaded automatically) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> '.'