amazfitbip / documentation

Collection of data sheet of internals component found in Amazfit bip
91 stars 8 forks source link

All I know about Amazfit Bip #4

Open endes0 opened 6 years ago

endes0 commented 6 years ago

I've been investigating this device for several days and trying to reverse engineer the firmware, here I publish everything I know about it.

The first thing is the hardware, thanks to this post in XDA and several references that I found in the firmware I discovered that this smartwatch has the following components:

Clearly the GPS is missing, which seems quite difficult to figure out what it is. On the other hand highlights that the main SoC is the Stm32f476, which has an ARM cortex M4 and an integrated LCD controller. In addition, with what I have managed to decompile (not much) I have found several variables that make references to registers and pinouts of the microcontroller:

Returning to the firmware, as for the file format at the beginning we found some headers that in some versions remain the same and between devices (there are more devices that use this firmware) only varies the beginning (These headers remind me of an ELF). Then we found what could be the firmware of the BLE ic(DA14580-01), I have not found much information regarding the flashing of this ic, but I believe that the microcontroller does not flash directly the firmware to this one, also it is necessary to emphasize that many times this firmware does not vary between versions and between devices only vary a few parts. After the division marked by FF, we found the stm32 firmware and near the end, in old versions there was a division of FF that marked the end of the code and the beginning of the data.

On the other hand, the main firm is made on freeRTOS, I have tried to decompile it with RetDec, but I have not got anything useful (more than 1 million lines, infinite recursions, 6200 functions and no names), even so I found something interesting and is that in the data part of the firmware there is a list of all the names of the functions: `flash_init BSP_QSPI_Init sensor_store_init REBOOTUSR_DATA store_manager_clean store_manager_clean_data store_manager_init set_data_store_manager_info get_data_store_manager_info set_generic_data get_generic_data set_frequent_data_manager get_frequent_data_manager check_free_region store_sport_space_check store_clean_region store_sport_start store_sport_end store_sport_data get_sport_size sync_sport_data sport_get_num sport_get_not_synced_num sport_get_summary sport_get_detail sport_delete_item notify_alg_task_internal algorithm_task_init notify_compass_task_internal compass_task_init notify_sensor_task_internal sensor_task_init sensor_timer_reconf set_sensor_interval alg_init hrm_switch_ecg_mode hrm_set_interval hrm_continous_monitor_enable hrm_allday_monitor_enable exit_peridic_mode exit_manual_measure_mode exit_continuous_measure_mode hrm_sport_mode hrm_init wear_enable […] gesture_enable hr_enable hr_disable hr_process alg_heartrate_init […] heart_initialize sedentary_enable buffer_alloc buffer_put buffer_acc_alloc buffer_acc_put as7024_set_mode as702x_hrm_ulp_adjust_led_current uart_read_dma gps_usart_init get_sony_gps_version gps_enter_mode gps_enable sony_gps_init nema_parser sony_upgrade_ecmd sony_burn_cep sony_burn_almanac pm_init pm_lock_sleep gtl_recv_put gtl_recv_get gtl_uart_send_data usart1_error_cb da14580_boot_from_uart alipay_task_init

Amazfit Bip

[…] code128_append_pattern code128_append_code code128_switch_code vbat_adc_init i2c1_drv_init_internal i2c3_read i2c3_blk_read i2c3_write_reg i2c3_blk_write i2c3_drv_init i2c2_drv_init enable_wdg iwdg_reboot motor_init HAL_GPIO_EXTI_Callback periph_init rng_init set_current_time rtc_init set_rtc_alarm spi1_rw spi_drv_init spi1_read spi1_write set_backlight_percent bl_pwm_init tim2_enable tim2_disable clock_calibration vApplicationStackOverflowHook vApplicationMallocFailedHook vApplicationTimerCommandFailedHook main SystemClock_Config HAL_UART_MspInit HAL_RTC_MspInit HAL_RNG_MspInit HAL_ADC_MspInit HardFault_Handler MemManage_Handler BusFault_Handler UsageFault_Handler lptim1_enable lptim1_disable vPortSuppressTicksAndSleep prvGtlTask send_msg_to_gtl ble_gtl_task_init set_app_state app_state_init MX_USART1_UART_Init prvDisplayTask display_task_init Charge Flash Gsensor Compass Barometer MOTOR Font gps_test_task_init touch_test_task_init selftest_task_init […] sport_detail_page_create sport_agps_page_create sport_gps_page_pass_create sport_gps_page_ok_create sport_gps_page_create sport_countdown_page_create sport_ready_page_create alarm_clock_init &#($) start_transfer_cmd_handle prvStm32l476appTask stm32l476_app_task_init pets HMZK NEZK HMRES NERES HMDIAL HMEMJ ancc_push_uid_to_end ancc_release_uid parse_date app_ancc_user_init xQueueGenericReset xQueueGenericCreate xQueueGiveMutexRecursive xQueueTakeMutexRecursive xQueueCreateCountingSemaphore xQueueGenericSend xQueueGenericSendFromISR xQueueGiveFromISR xQueueGenericReceive xQueueReceiveFromISR xQueuePeekFromISR uxQueueMessagesWaiting uxQueueSpacesAvailable uxQueueMessagesWaitingFromISR vQueueDelete xQueueIsQueueEmptyFromISR xQueueIsQueueFullFromISR xTimerCreateTimerTask prvInitialiseNewTimer xTimerGenericCommand xTimerGetTimerDaemonTaskHandle xTimerGetPeriod xTimerGetExpiryTime pcTimerGetName prvProcessExpiredTimer prvProcessReceivedCommands prvSwitchTimerLists xTimerIsTimerActive pvTimerGetTimerID vTimerSetTimerID prvInitialiseNewTask vTaskDelete vTaskDelay eTaskGetState vTaskPrioritySet vTaskSuspend prvTaskIsTaskSuspended vTaskResume xTaskResumeFromISR vTaskStartScheduler xTaskResumeAll pcTaskGetName vTaskStepTick xTaskIncrementTick vTaskSwitchContext vTaskPlaceOnEventList vTaskPlaceOnUnorderedEventList vTaskPlaceOnEventListRestricted xTaskRemoveFromEventList xTaskRemoveFromUnorderedEventList vTaskSetTimeOutState xTaskCheckForTimeOut prvIdleTask xTaskPriorityDisinherit xTaskGenericNotify xTaskGenericNotifyFromISR vTaskNotifyGiveFromISR prvTaskExitError xPortStartScheduler vPortEndScheduler vPortEnterCritical vPortExitCritical vPortValidateInterruptPriority pvPortMalloc vPortFree`

I'm pretty noob in reverse engineering, so I don't know what else to do and I'm out of time. I hope to have been of help to someone.

JohnRThomas commented 5 years ago

@endes123321 I'm the originator of that post on XDA. I've taken a few looks through the FW using Hopper. IDA/HexRays is just too pricey for me haha, but I found a few things mainly some stray printf format strings. Here are my notes on the Bip: https://docs.google.com/document/d/1oob8PY7eX7btq0YpjrgDdRVN0fvHo8CKBxAjR5WI6s4/edit?usp=sharing

I also was trying to find the UART pins on the pcb of the Bip (No luck on that front sadly): https://forum.xda-developers.com/smartwatch/amazfit/bip-quest-bip-uart-pins-t3856505

I also was working a bit on RebbleOS trying to possibly port it over to the Bip, but without a good to way to safely flash FW I had no way to test anything custom. If my FW bricks the Bip, then I don't think I can recover it with just bluetooth.

If you want to work together on anything, send me an email (you can find it on my profile) or we can just collaborate on this repository.

endes0 commented 5 years ago

@JohnRThomas I was looking at your notes and rebbleOS(just what I was looking for) and they are very interesting, I started to investigate this device just to port some FOSS firmware and improve its documentation in general. I'm glad to know that I'm not the only one. :+1:

Firstly, I would like to say that there are many details about the hardware, such as the screen, that are still missing, since I find it strange that use the internal LCD controller. Then find out which peripheral(this MCU have a lot) communicates with each component and in some cases even find out the protocol of some (the sony GPS, I think I saw it is by UART). Then let's not even talk about the whole updating system, that still have a lot of unknow parts like the update files structure. I plan to continue with reverse engineering, especially after watching this live(not all XD) that has given me several ideas for where to continue: https://www.youtube.com/watch?v=OHYq3zNR1yo

As for the UART port, the truth is that I can not help you, although I have a small logic analyzer, my bip device is new, still has a warranty, I can not be opening it. Also, as you commented in your notes, the most possible thing is that they've disabled it. Anyway the device saves a debug log downloadable with Gadgetbridge, by the way its github wiki has relevant information.

I would like to work together, but at the moment I have 0 free time. Surely when I have vacations I will continue publishing in this repository or I will send you an email or if you have telegram you can send me a message: @endes

endes0 commented 5 years ago

Founded!! This is the GPS protocol: https://github.com/sonydevworld/spresense/tree/c2c84a9db6eb2e03afc28554ce0345f2d7ff2ffd/examples/gnss_atcmd

dslul commented 5 years ago

According to what Viktor_7 from xda found out, the gps chip is Sony CXD5603GF (https://yadi.sk/d/fhZ_85AQFkPTEA) @endes123321 the microcontroller is not Stm32f476 but Stm32l476, as noted in @JohnRThomas 's document. I think the actual firmware starts from the second block (F8 7B 01 20 59 12 01 08), which are the initial stack pointer address (0x20017BF8) and the reset routine address (0x8011259) respectively. I may be wrong though. I'm not sure what the first part of the firmware is. I also think that the main firmware is loaded in the internal 1MB flash and the rest (fonts, resources and gps data) in the 8MB winbond. Maybe someone can try to dump its content directly to get a confirmation.

To flash the microcontroller directly the SWJ debug port can be used (see manual https://www.st.com/content/ccc/resource/technical/document/reference_manual/02/35/09/0c/4f/f7/40/03/DM00083560.pdf/files/DM00083560.pdf/jcr:content/translations/en.DM00083560.pdf) schermata da 2019-03-05 10-13-43

SWDIO and SWCLK, in serial wire mode, can be used for debugging (more information here https://www.st.com/content/ccc/resource/training/technical/product_training/16/31/0e/0d/94/11/4f/5e/STM32L4_System_Debug.pdf/files/STM32L4_System_Debug.pdf/jcr:content/translations/en.STM32L4_System_Debug.pdf)

schermata da 2019-03-05 10-17-43

schermata da 2019-03-05 10-18-38 It's possible though that serial wire is already active and they used the jtag pins as GPIO. This also explains why on the test pins there are only SWDIO and SWCLK.

Here is a link that explains how to use this interface. On windows, I think it's better to use ST visual programmer instead of openocd

I also add the pinouts and connections for completeness (to see the full images use the link at the beginning of this message)

schermata da 2019-03-05 11-18-48 schermata da 2019-03-05 11-19-22

JohnRThomas commented 5 years ago

@dslul That is an awesome break out! I have a bip torn that still works and I was trying to figure out how to access the flash to see if I could dump or write to it not over bluetooth. I'll have to get an ST link and see if I can flash some FW to it. This is was the main blocker for me actually trying some custom FW.

I was messing around in Hopper binary explorer and I found some printf messages that lead me to find an intize functions. I think talking offsets is useless unless we decide on a single FW image and agree to work solely off of that at least to start.

Once Ghirda is released (this month I think), I'll probably explore the image with that instead of Hopper.

dslul commented 5 years ago

I used this one, took from the latest release of mi fit from apkmirror: Mili_chaohu.fw.zip

I think the disassembler should be instructed in order to interpret the assembly correctly (https://blog.3or.de/starting-embedded-reverse-engineering-freertos-libopencm3-on-stm32f103c8t6.html). I'll delve into it and see what I can come up with. I don't understand though why all the functions are in plain text, maybe they log the name as soon as each function starts... EDIT: the firmware has log messages all over the place (warnings, info, errors and other things), if you manage to connect from the serial you should be able to see al this

dpeddi commented 5 years ago

let me know if you want write access to this git

On Tue, Mar 5, 2019 at 6:48 PM Daniele Laudani notifications@github.com wrote:

I used this one, took from the latest release of mi fit from apkmirror: Mili_chaohu.fw.zip https://github.com/amazfitbip/documentation/files/2932055/Mili_chaohu.fw.zip

I think the disassembler should be instructed in order to interpret the assembly correctly ( https://blog.3or.de/starting-embedded-reverse-engineering-freertos-libopencm3-on-stm32f103c8t6.html). I'll delve into it and see what I can come up with. I don't understand though why all the functions are in plain text, maybe they log the name as soon as each function starts...

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/amazfitbip/documentation/issues/4#issuecomment-469781641, or mute the thread https://github.com/notifications/unsubscribe-auth/ABCVX4ewZnmVdudz7ZxaKKlGV8f0nMBTks5vTq3YgaJpZM4YS_IX .

endes0 commented 5 years ago

I used this one, took from the latest release of mi fit from apkmirror: Mili_chaohu.fw.zip

I think the disassembler should be instructed in order to interpret the assembly correctly (https://blog.3or.de/starting-embedded-reverse-engineering-freertos-libopencm3-on-stm32f103c8t6.html). I'll delve into it and see what I can come up with. I don't understand though why all the functions are in plain text, maybe they log the name as soon as each function starts... EDIT: the firmware has log messages all over the place (warnings, info, errors and other things), if you manage to connect from the serial you should be able to see al this

Actually, you can access the logs with Gadgetbridge, but it seems the logs does not print the functions name. I guess it only print the functions names in a debug mode or on a crash.

Here are a little log of my bip, I have more large logs but contains sensible information. https://pastebin.com/Uxcb5pK9

endes0 commented 5 years ago

@JohnRThomas Ghidra has just been released https://ghidra-sre.org/

dslul commented 5 years ago

@dpeddi do you still have the broken amazfit bip that you tore down on gizchina?

dpeddi commented 5 years ago

I should have it somewhere but something get irrimediabile broken trying to unsoldered the flash. What do you need about it?

Il sab 9 mar 2019, 17:37 Daniele Laudani notifications@github.com ha scritto:

@dpeddi https://github.com/dpeddi do you still have the broken amazfit bip that you tore down on gizchina?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/amazfitbip/documentation/issues/4#issuecomment-471198606, or mute the thread https://github.com/notifications/unsubscribe-auth/ABCVX8FvpgDmoL-bA_MmQ8AFtF89AU8Mks5vU-M7gaJpZM4YS_IX .

dslul commented 5 years ago

I was looking for a broken one with at least the mcu working (per caso sei di Torino o dintorni?) Alternatively, if you're interested, you can try by yourself if anything we talked about is doable. A st-link (or similar) is needed though

dslul commented 5 years ago

The display is a JDI 8-color memory LCD LPM013M126A (datasheet) with backlight LPM013M126C (datasheet) which seems to be of pretty common use in other chinese watches (like SMA Q2) and breakout boards. From left to right: SCLK - SI - SCS - EXTCOMIN - DISP - VDDA - VDD - EXTMODE - VSS - VSSA Schermata da 2019-03-10 10-53-18 EXTMODE is set to HIGH, so polarity inversion is done through EXTCOMIN.

BACKLIGHT (from left to right):

Cathode2 - cathode1 - anode - anode

Schermata da 2019-03-11 16-58-56

Schermata da 2019-03-11 16-53-48

Here is a more detailed guide on how to use this kind of low power LCDs (on a different model but with the same pinout). There is also a library for arduino (for the A version without backlight).

JohnRThomas commented 5 years ago

I seem to have blown out my Bip mule, when I tried to power it off my power supply instead of the watch dock(Was just a bad solder joint on the ground wire). I ordered a new one and an ST link. Should be here tuesday and then I can play around with this a bit more.

JohnRThomas commented 5 years ago

I printed a small jig to pin out the board. Just need my ST link now... https://i.imgur.com/iDXrnve.jpg

dslul commented 5 years ago

I ordered an ST link. Should be here tuesday and then I can play around with this a bit more.

Great! I am sure you already know, but for those who might read this, remember not to connect 3.3V (or 5V) from the st link if you power the watch from an external source

dslul commented 5 years ago

@JohnRThomas would you mind testing the continuity between these two (light blue) points and the lcd leds cathode1 and cathode2 (see my previous post for the position)? Amazfit_BIP_bot_00

Viktor_7 did not specify the connections, but I'm pretty confident one is connected to cathode1 and the other to cathode2

JohnRThomas commented 5 years ago

@dslul I would love to, however I haven't desoldered the cage on my pcb and I don't want to do so since I might desolder something else while I do that and break the whole thing :( Those parts are under the lip of the cage and I can't get a probe under there.

dslul commented 5 years ago

Those parts are under the lip of the cage and I can't get a probe under there.

Oh, I completely forgot there was a shield. Sorry.

@dpeddi can you initialize the repo with an empty readme so I can send a pull request with all the components and datasheets?

dslul commented 5 years ago

I set up a repo with a basic freertos firmware that should run on the bip https://github.com/dslul/Amazfitbip-FreeRTOS.

It does essentially nothing, except running a task and turning on and off pin A11. I used libopencm3 instead of the official cubemx hal that doesn't seem to be that good.

@JohnRThomas I saw your repo, you tried to add support to rebbleos, but there is a fundamental problem: they used the old peripheral library (which was dropped by ST and not mantained anymore) that doesn't support the newer L4 family (our case), so if we want to port it to the bip we should migrate the codebase to use cubemx hal or libopencm3.

JohnRThomas commented 5 years ago

@dslul yeah, I didn't know what I was getting into with that. I talked to the rebbleOS developers and they were not opposed to converting to libopencm3 but did not seem to like the way cubemx HAL did things (mainly I2C iirc). I'll look at using what you did as a base for learning opencm3. I'm pretty new to FW development so there is a bit of a learning curve for me, but I should get there.

I had a bit of a set back with using the ST link, but I should be able to look more into it later this week.

dslul commented 5 years ago

@JohnRThomas I find Beginning STM32 by Warren Gay pretty good for getting started. It focuses on the "blue pill" with the f1 (our l4 is a bit different) but in general the same rules still apply.

If you have problems with the st link feel free to ask for help.

JohnRThomas commented 5 years ago

Finally got my debugging shield finished, and of course now the St link I bought is DOA. https://i.imgur.com/jw4nLog.png

dslul commented 5 years ago

Well, that's unfortunate... BTW, I think there is a way to flash a firmware even when the system is bricked. People with a dead Bip report that the bluetooth is still functioning, so I guess the bootloader accepts bluetooth connections for reflashing (like the pebble). I don't know the format it accepts though.

endes0 commented 5 years ago

I have discovered the factory test mode, when the tests end, the bip just reset. To enter you have to put the bip on charge turn it upside down on a grounded floor and wait 10 seconds.

photo_2019-05-05_15-39-20 photo_2019-05-05_15-40-05 photo_2019-05-05_15-40-23 photo_2019-05-05_15-40-28

this is the log of this mode

[88617948] enter_selftest_steps = 0

[88618059] enter_selftest_steps = 0

[88618703] enter_selftest_steps = 0

[88618815] enter_selftest_steps = 0

[88619768] enter_selftest_steps = 0

[88619942] enter_selftest_steps = 0

[88619970] enter_selftest_steps = 0

[88619989] enter_selftest_steps = 0

[88620029] enter_selftest_steps = 1

[88620074] enter_selftest_steps = 1

[88620208] enter_selftest_steps = 1

[88620215] enter_selftest_steps = 1

[88620236] enter_selftest_steps = 1

[88620263] enter_selftest_steps = 1

[88620296] enter_selftest_steps = 1

[88620403] enter_selftest_steps = 1

[88620436] enter_selftest_steps = 1

[88620482] enter_selftest_steps = 1

[88620503] enter_selftest_steps = 1

[88620542] enter_selftest_steps = 1

[88620603] enter_selftest_steps = 1

[88620648] enter_selftest_steps = 1

[88620720] enter_selftest_steps = 1

[88620765] enter_selftest_steps = 1

[88620808] enter_selftest_steps = 1

[88620901] enter_selftest_steps = 1

[88620913] enter_selftest_steps = 1

[88620965] enter_selftest_steps = 1

[88621040] enter_selftest_steps = 1

[88621084] enter_selftest_steps = 1

[88621125] enter_selftest_steps = 1

[88621190] enter_selftest_steps = 1

[88621263] enter_selftest_steps = 1

[88621288] enter_selftest_steps = 1

[88621347] enter_selftest_steps = 1

[88621381] enter_selftest_steps = 1

[88621468] enter_selftest_steps = 1

[88621487] enter_selftest_steps = 1

[88621608] enter_selftest_steps = 1

[88621620] enter_selftest_steps = 1

[88621647] enter_selftest_steps = 1

[88621692] enter_selftest_steps = 1

[88621705] enter_selftest_steps = 1

[88621751] enter_selftest_steps = 1

[88621818] enter_selftest_steps = 1

[88621832] enter_selftest_steps = 1

[88621852] enter_selftest_steps = 1

[88621937] enter_selftest_steps = 1

[88622010] enter_selftest_steps = 1

[88622037] enter_selftest_steps = 1

[88622057] enter_selftest_steps = 1

[88622170] enter_selftest_steps = 1

[88622251] enter_selftest_steps = 1

[88622378] enter_selftest_steps = 1

[88622398] enter_selftest_steps = 1

[88622439] enter_selftest_steps = 1

[88622466] enter_selftest_steps = 1

[88622531] enter_selftest_steps = 1

[88622606] enter_selftest_steps = 1

[88622734] enter_selftest_steps = 2

[88622746] enter_selftest_steps = 2

[88622920] enter_selftest_steps = 3

[88623000] enter_selftest_steps = 3

[88623013] enter_selftest_steps = 3

[88623100] enter_selftest_steps = 3

[88623166] enter_selftest_steps = 3

[88623272] enter_selftest_steps = 3

[88623287] enter_selftest_steps = 4

[88623300] enter_selftest_steps = 5

[88623326] enter_selftest_steps = 6

[88623346] enter_selftest_steps = 6

[88623453] enter_selftest_steps = 6

[88623479] enter_selftest_steps = 6

[88623566] enter_selftest_steps = 6

[88623592] enter_selftest_steps = 6

[88623633] enter_selftest_steps = 6

[88623699] enter_selftest_steps = 7

[88623746] enter_selftest_steps = 7

[88623765] enter_selftest_steps = 8

[88623838] enter_selftest_steps = 8

[88623849] enter_selftest_steps = 9

[88623944] enter_selftest_steps = 9

[88623964] enter_selftest_steps = 9

[88624011] enter_selftest_steps = 9

[88624037] enter_selftest_steps = 9

[88624084] enter_selftest_steps = 10

[88624110] enter_selftest_steps = 11

[88624190] enter_selftest_steps = 12

[88624251] enter_selftest_steps = 12

[88624264] enter_selftest_steps = 13

[88624391] enter_selftest_steps = 13

[88624398] enter_selftest_steps = 14

PD: if you make a long press and this is for walking mode, the bip crash.

dpeddi commented 5 years ago

Tried more and more to get into this more but never entered... Can't understand what I'm wrong, please try to explain again with different words. Thankbyou

protobits commented 4 years ago

Hi, by any chance did someone figure out the connection between the bluetooth chip and main MCU? I'm interesting to know what are the options for flashing via bluetooth via some known protocol. It would be really cool if they had wired some pins of the bluetooth chip into the STM32L4 SWD pins to allow for bluetooth flashing/debugging.

endes0 commented 4 years ago

Well, some time ago I decompiled some parts of the main firmware. I found some interesting things, but I lost the project and notes. For what I remember the MCU and BLE communicates via serial. The BLE firmware is never flashed on to the BLE chip, instead is loaded every time it boots. I don't remember how the flashing of the main MCU is.

protobits commented 4 years ago

Do you think it is feasible to remove the glass to access the SWD pins safely? (without killing the screen or anything else in the process?)

JohnRThomas commented 4 years ago

It is feasible, and I've done it. The current FW examples that I've built can be found here: https://github.com/JohnRThomas/Amazfitbip-FreeRTOS

The BLE chip actually loads it's boot ROM over SPI from the STM32 chip. I've haven't quite gotten it working, but the datasheets describe what needs to happen.

There is an active FW dev effort that you can find by following links to here: https://www.reddit.com/r/AmazfitBip/comments/gzmtxj/the_bipdev_discord_channel_exists_and_is_an/