Защита ПО процессора S805-B (secured boot)

    Речь пойдёт о способе защиты програмного обеспечения, который реализован в самом процессоре. Для экспериментов я выбрал мультимедиа приставку Comigo Quattro. Цель — запустить своё ядро линукс.

    Краткий обзор


    На первый взгляд ПО приставки является клоном Android. Доступ по ssh закрыт. Работает только с действующим абонементом от дистрибьютора. Стоковая прошивка полностью шифрована. Всё глухо, как в танке.

    Подготовка


    Первым делом я подробно ознакомился с техническим описанием процессора. Порадовали меня две вещи: у процессора был интерфейс UART и он поддерживал загрузку системы с разных источников (USB, SD и т.д.), которая могла настраиваться снаружи при помощи конфигурационного регистра. На борту приставки также имелось место для mSD карты, но разьём был не припаян. Для того, чтобы найти пятачки конфигурационного регистра и пины UART мне пришлось спаять процессор и прозвонить дорожки. Когда все контакты были найдены, я подключил адаптер UART и запустил приставку. На экрана высветился U-Boot. Загрузка системы прерывалась нажатием клавиш и U-Boot выходил в режим ввода, но ни на какие клавиши кроме enter, никак не реагировал. И эта лазейка тоже была закрыта.

    U-boot
    QA5:A;SVN:B72;POC:17F;STS:0;BOOT:0;INIT:0;READ:0;CHECK:0;PASS:0;
    no sdio debug board detected
    TE : 1583722
    BT : 19:30:15 Apr 13 2015
    PMU:NONE
    ##### VDDEE voltage = 0x044c
    
    CPU clock is 792MHz
    
    DDR mode: 32 bit mode
    DDR size: 1GB
    DDR check: Pass!
    DDR clock: 792MHz with 2T mode
    DDR pll bypass: Disabled
    DDR init use : 13644 us
    
    HHH
    Boot From SDIO C
    SD_boot_type: 00000002
    card_type: 00000003
    0x0000009f
    Aml log : M8-R2048 TPL pass!
    ucl decompress...pass
    0x12345678
    Boot from internal device 1st tSD/fSD on SDIO C
    
    TE : 1867612
    
    System Started
    
    
    ==================COMIGO BOOTLOADER==================
    ==========12fc92:S:Enc (Apr 13 2015 - 19:29:55)==========
    
    clr h-ram
    DRAM:  1 GiB
    relocation Offset is: 2febc000
    show partition table:
    part: 0, name :       logo, size : 800000
    part: 1, name : recovery_bak, size : 1000000
    part: 2, name :   recovery, size : 1000000
    part: 3, name :       boot, size : 1000000
    part: 4, name :     system, size : 32000000
    part: 5, name :       data, size : 8c000000
    part: 6, name :      cache, size : 20800000
    part: 7, name :    sec_gpt, size : end
    aml_card_type=0x100
    MMC:   out reg=c1108058,value=fffcf800
    out reg=c1108058,value=fffcfa00
    [mmc_register] add mmc dev_num=0, port=1, if_type=6
    [mmc_register] add mmc dev_num=1, port=2, if_type=6
    SDIO Port B: 0, SDIO Port C: 1
    power init
    out reg=c110804c,value=dfffffff
    IR init done!
    register usb cfg[0][1] = 3ff6fcf4
    register usb cfg[2][0] = 3ff72a6c
    NAND:  EMMC BOOT: not init nand
    do not init nand : cause boot_device_flag without nand
    get_boot_device_flag: init_ret -1
    get_boot_device_flag EMMC BOOT:
    init_part
    Emmckey: Access range is illegal!
    Emmckey: Access range is illegal!
    Unknown partition type on device 'SDIO Port C'
    Device 'SDIO Port C' wp size=8388608 port=2
    [mmc_init] SDIO Port C:1, if_type=6, initialized OK!
    mmc_device_init
    mmc_get_partition_table
    Start mmc_get_partition_table
    Partition table get from SPL is :
            name                        offset              size              flag
    ===================================================================================
       0: pri_gpt                            0            800000                  0
       1: env                           800000            800000                  0
       2: reserved                     1000000           4000000                  0
       3: logo                         5000000            800000                  1
       4: recovery_bak                 5800000           1000000                  1
       5: recovery                     6800000           1000000                  1
       6: boot                         7800000           1000000                  1
       7: system                       8800000          32000000                  1
       8: data                        3a800000          8c000000                  4
       9: cache                       c6800000          20800000                  2
      10: sec_gpt                     eb800000            800000                  0
    mmc read lba=0x8000, blocks=0x1
    mmc read lba=0x8001, blocks=0x1
    mmc_read_partition_tbl: mmc read partition OK!
    eMMC/TSD partition table have been checked OK!
    i=0,register --- emmc_key
    MMC BOOT, emmc_env_relocate_spec : env_relocate_spec 59
    set_storage_device_flag: store 2
    [imgread]Secure kernel sz 0x5b36a0
    Aml log : M8-R2048 IMG pass!
    vpu clk_level in dts: 3
    set vpu clk: 182150000Hz, readback: 182150000Hz(0x701)
    Net:   Meson_Ethernet
    init suspend firmware done. (ret:0)
    cvbs trimming.1.v5: 0xa0, 0x0
    upgrade_comigo_environment: expect 6 active 6
    init_comigo_environment
    type:flash,start to read mac...
    device init start
    aml_keys: version 0 can not be init 3ff72c68
    current storer:emmc_key
    flash init key ok!!
    init flash success
    all key names list are(ret=18):
    uuid
    serialno
    mac
    4:3:3:0:3:a:4:2:3:3:3:a:3:3:3:9:3:a:3:0:3:2:3:a:3:1:4:6:3:a:3:4:3:9:
    mac is: 43:30:3a:42:33:3a:33:39:3a:30:32:3a:31:46:3a:34:39:
    read ok!!
    read mac success,mac=C0:B3:39:02:1F:49
    androidboot.mac is exist in bootargs, mac=C0:B3:39:02:1F:49 androidboot.serialno=A0652602C5706198 androidboot.uuid=4a3842462f47694d364b6f544d3236596b34374e3977
    BOARD VERSION=2
    reboot_mode=charging
    hdcp get form storage medium: auto
    don't found keyname,uboot_key_read:1634
    prefetch hdcp keys from auto failed
    AKSV invalid
    hdmi tx power init
    mode = 6  vic = 4
    set HDMI vic: 4
    mode is: 6
    viu chan = 1
    config HPLL
    config HPLL done
    reconfig packet setting done
    key save in emmc
    key size=44
    the key name is :
    the key data is :4a3842462f47694d364b6f544d3236596b34374e3977
    key size=32
    the key name is :serialno
    the key data is :41303635323630324335373036313938
    A0652602C5706198
    efuse version is not selected.
    Hit ENTER key to stop autoboot:  1 tstc enter
    
    exit abortboot: 1
    COMIGO#
    


    С оригинальным U-Boot'ом на этом этапе сделать ничего было нельзя и я решил проверить загрузку с mSD карты. Для этого я припаял разьём и соединил пару контактов конфигурационного регистра с массой, чтобы процессор грузил систему с карты. Новый U-Boot был от экспериментального борта ODROID-C, который базировался на таком же процессоре.





    Собрав всё это, я вставил SD карту, включил приставку и… увидел такое:

    SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;
    

    И этот текст повторялся каждую секунду вновь и вновь. Процессор вовсе и не собирался грузить мой U-Boot и это меня огорчило.

    Поиск причины


    Мне стало ясно, что в процессоре был активирован secured boot и он проверял код на подлинность прежде чем его запускать. Параметр CHECK:FFFFBF00 указывал на то, что код, загруженый с mSD карты более чем полностью по каким-то причинам не устраивал процессор. Для сравнения, загрузка оригинала начиналась в свою очередь так:

    QA5:A;SVN:B72;POC:17F;STS:0;BOOT:0;INIT:0;READ:0;CHECK:0;PASS:0;
    

    Что же проверял процессор? Этот ответ я надеялся найти в сурсах U-Boot'а для AMLogic. После недолгих поисков, я увидел, что SPL часть от U-Boot'a заканчивается вот такой структурой

       typedef struct {
          unsigned int   nSizeH;         ///4@0
          struct st_secure{
             unsigned int   nORGFileLen;  ///4@4
             unsigned int   nSkippedLen;  ///4@8
             unsigned int   nHASHLength;  ///4@12
             unsigned int   nAESLength;   ///4@16
             unsigned char   szHashKey[32];//32@20
             unsigned char   szTmCreate[24];   //24@52
             unsigned char   szReserved[60];   //60@76
          }secure; //136@136
          unsigned char   szAES_Key_IMG[60];//60@136
          unsigned char   szTmCreate[48];   //48@196
          unsigned int   nSizeT;         ///4@244
          unsigned int   nVer;           ///4@248
          unsigned int   unAMLID;        ///4@252
       }st_aml_chk_blk; //256
    

    Небольшое отступление. Двухступенчатая загрузка системы очень часто применяется на встроенном оборудовании. Т.е. ROM процессора грузит сначала небольшую часть кода (так называемый SPL) и передаёт ему управление. Тот в свою очередь после основных настроек грузит вторую, большую часть (TPL) и передаёт ей управление. Ну а TPL после окончательных настроек грузит ядро и запускает его.

    Забегая немного вперёд, скажу, что сам SPL состоит из 32 КБ, в конце которого находится структура st_aml_chk_blk, которая в расшифрованом виде выглядит вот так:


    Стало быть, этот блок данных процессор использует для проверки SPL.

    В поисках решения


    Чтобы заставить процессор загрузить мой U-Boot, я испробовал множество вариантов. Но все они не приносили желаемого результата — процессор упорно выдавал CHECK:FFFFBF00. Я постепенно приходил к выводу, что защита сделана на 100% и дыр нет.

    После очередной неудачной попытки я оставил приставку и пошёл на кухню (за чаем, конечно), раздумывая подключать JTAG, а когда вернулся, меня ждал вот такой результат:

    SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:FFFFBF00;USB:3;SERIAL:4;STS:0;BOOT:1;INIT:0;READ:0;CHECK:0;PASS:1;
    -----------------------------------------------------------------------
    * Welcome to Hardkernel's ODROID-C... (Built at 19:33:00 Dec  8 2014) *
    -----------------------------------------------------------------------
    CPU : AMLogic S805
    MEM : 1024MB (DDR3@792MHz)
    BID : <Unknown>
    S/N :
    ***** Warning!! *****************************************************
    * This board have not been autorized or product keys are not valid. *
    * Please contact with Hardkernel or your distributor                *
    *********************************************************************
    

    О как! После некоторого времени (это было примерно секунд 40) процессор выдавал CHECK:0;PASS:1; и грузил мой U-Boot. Он конечно зависал потом, но это не имело значения, доступ к системе был получен.

    Анализ


    Первым делом я написал программу, которая сделала дамп ROM'а процессора и фьюза (это такой участок памяти в процессоре, который может быть прошит только один раз. Здесь как раз и хранятся ключи AES, public RSA и некоторые конфигурации процессора). Заполучив таким образом ключ AES я расшифровал оригинальный U-Boot и проанализировал ROM. Принцип загрузки SPL был таков: ROM первым делом считывал конфигурацию из фьюза и сохранял её как переменную. Далее он грузил 32 КБ с флэшки в память и смотрел, что показывала конфигурация на предмет проверки сигнатуры и шифрования. В нашем случае ROM затем вычитывал экспоненту e и модуль N из фьюза, собирал PublicKey(e,N) с которым он расшифровывал st_aml_chk_blk, затем вырешивал sha2 от SPL без st_aml_chk_blk и сравнивал то что получилось с ключом из st_aml_chk_blk. И в случае несовпадения дальнейших действий не предпринимал (сделать новую сигнатуру не явлается возможным, т.к. нельзя прописать во фьюз новый открытый ключ RSA, ну и закрытого ключа дистрибьютора у нас конечно тоже нет). Так что же заставило процессор выполнить мой SPL? Сигнатура ведь по-любому не совпадала…
    Для поддержки RSA в ROM была включена (с большой вероятностью) библиотека PolarSSL (разобрав ROM я нашёл параллели к сурсам этой библиотеке). Зато алгоритм AES он поддерживал на аппаратном уровне, если мне не изменяет память. ROM управлял свободной памятью используя собственный механизм (примерно как malloc и memfree). Перед вызовом функций из библиотеки PolarSSL ROM выделял ей определенный кусок памяти, но в некоторых случаях не всегда освобождал его. Например тогда, когда функция RSA отваливалась из-за невозможности расшифровать инвалидный блок, который я использовал в своём SPL в этой попытке. Что же получалось? ROM выделял память, пробовал расшифровать мою поддельную сигнатуру, забывал освободить память, выдавал ошибку CHECK:FFFFBF00 и цикл повторялся. В один прекрасный момент очередной кусок новой памяти затирал переменную из фьюза, которую ROM сохранял в самом начале. В следующем цикле в этой переменной уже было значение 0, что значило: просто грузи всё что есть и запускай.
    Дальше в принципе не было ничего интересного. Я переделал оригинальный U-Boot, убрал проверку TPL, проверку ядра команды bootm и активировал Hush Interpreter, чтобы он реагировал на команды. Расшифровав ядро и собрав минималку на BusyBox я запустил линукс из переделанного U-Boot'а, который начинал грузиться через 40 секунд.

    Оригинальный U-Boot с включеным терминалом
    ==================COMIGO BOOTLOADER==================
    ==========395456:S:Enc (Nov 03 2015 - 19:33:53)==========
    
    clr h-ram
    DRAM:  1 GiB
    relocation Offset is: 2febc000
    show partition table:
    part: 0, name :       logo, size : 800000
    part: 1, name : recovery_bak, size : 1000000
    part: 2, name :   recovery, size : 1000000
    part: 3, name :       boot, size : 1000000
    part: 4, name :     system, size : 32000000
    part: 5, name :       data, size : 8c000000
    part: 6, name :      cache, size : 20800000
    part: 7, name :    sec_gpt, size : end
    aml_card_type=0x100
    MMC:   out reg=c1108058,value=fffffdff
    out reg=c1108058,value=ffffffff
    [mmc_register] add mmc dev_num=0, port=1, if_type=6
    [mmc_register] add mmc dev_num=1, port=2, if_type=6
    SDIO Port B: 0, SDIO Port C: 1
    power init
    out reg=c110804c,value=dfffffff
    IR init done!
    register usb cfg[0][1] = 3ff6fd14
    register usb cfg[2][0] = 3ff72a8c
    NAND:  CARD BOOT: not init nand
    do not init nand : cause boot_device_flag without nand
    get_boot_device_flag: init_ret -1
    get_boot_device_flag CARD BOOT:
    BOOT FROM CARD? env_relocate_spec
    SF: Unsupported manufacturer 00
    Failed to initialize SPI flash at 0:2
    Unknown command 'nand' - try 'help'
    init_part
    Emmckey: Access range is illegal!
    Emmckey: Access range is illegal!
    Unknown partition type on device 'SDIO Port C'
    Device 'SDIO Port C' wp size=8388608 port=2
    [mmc_init] SDIO Port C:1, if_type=6, initialized OK!
    mmc_device_init
    mmc_get_partition_table
    Start mmc_get_partition_table
    Partition table get from SPL is :
            name                        offset              size              flag
    ===================================================================================
       0: pri_gpt                            0            800000                  0
       1: env                           800000            800000                  0
       2: reserved                     1000000           4000000                  0
       3: logo                         5000000            800000                  1
       4: recovery_bak                 5800000           1000000                  1
       5: recovery                     6800000           1000000                  1
       6: boot                         7800000           1000000                  1
       7: system                       8800000          32000000                  1
       8: data                        3a800000          8c000000                  4
       9: cache                       c6800000          20800000                  2
      10: sec_gpt                     eb800000            800000                  0
    mmc read lba=0x8000, blocks=0x1
    mmc read lba=0x8001, blocks=0x1
    mmc_read_partition_tbl: mmc read partition OK!
    eMMC/TSD partition table have been checked OK!
    i=0,register --- emmc_key
    Device: SDIO Port C
    Manufacturer ID: 0
    OEM: 0
    Name: ETran Speed: 25000000
    Rd Block Len: 512
    MMC version 4.0
    High Capacity: Yes
    Capacity: 3959422976
    Boot Part Size: 2097152
    Bus Width: 4-bit
    MMC BOOT, emmc_env_relocate_spec env_relocate_spec 77
    set_storage_device_flag: store 3
    Err imgread(L129):Fmt unsupported!genFmt 0x0 != 0x3
    check dts: FDT_ERR_BADMAGIC, load default vpu parameters
    vpu clk_level = 3
    set vpu clk: 182150000Hz, readback: 182150000Hz(0x701)
    Net:   Meson_Ethernet
    msg:====>upgrade_step=0<=====
    init_part
    [mmc_init] SDIO Port B:0, if_type=7, initialized OK!
    Device: SDIO Port B
    Manufacturer ID: 0
    OEM: 0
    Name: Tran Speed: 20000000
    Rd Block Len: 512
    SD version 2.0
    High Capacity: Yes
    Capacity: 15523119104
    Boot Part Size: 0
    Bus Width: 4-bit
    
    ** Unable to use mmc 0:1 for fatload **
    init suspend firmware done. (ret:0)
    cvbs trimming.1.v5: 0xa0, 0x0
    upgrade_comigo_environment: expect 9 active 9
    init_comigo_environment
    type:flash,start to read mac...
    device init start
    aml_keys: version 0 can not be init 3ff72c88
    current storer:emmc_key
    flash init key ok!!
    init flash success
    all key names list are(ret=18):
    uuid
    serialno
    mac
    4:3:3:0:3:a:4:2:3:3:3:a:3:3:3:9:3:a:3:0:3:1:3:a:3:3:3:5:3:a:3:0:3:5:
    mac is: 43:30:3a:42:33:3a:33:39:3a:30:31:3a:33:35:3a:30:35:
    read ok!!
    read mac success,mac=C0:B3:39:01:35:05
    androidboot.mac is exist in bootargs, mac=C0:B3:39:01:35:05 androidboot.serialno=A0651002B9205401 androidboot.uuid=48304142556a6c66367a5450774c6d6671692f737241
    BOARD VERSION=2
    reboot_mode=charging
    hdcp get form storage medium: auto
    don't found keyname,uboot_key_read:1634
    prefetch hdcp keys from auto failed
    hdmi tx power init
    mode = 6  vic = 4
    set HDMI vic: 4
    mode is: 6
    viu chan = 1
    config HPLL
    config HPLL done
    reconfig packet setting done
    Err imgread(L526):head magic error
    There is no valid bmp file at the given address
    key save in emmc
    don't found keyname,uboot_key_read:1634
    read error!!
    Saving Environment to eMMC...
    BOOT FROM CARD?
    SF: Unsupported manufacturer 00
    Failed to initialize SPI flash at 0:2
    Unknown command 'nand' - try 'help'
    Device: SDIO Port C
    Manufacturer ID: 0
    OEM: 0
    Name: ETran Speed: 25000000
    Rd Block Len: 512
    MMC version 4.0
    High Capacity: Yes
    Capacity: 3959422976
    Boot Part Size: 2097152
    Bus Width: 4-bit
    MMC BOOT, emmc_saveenv saveenv 119
    mmc save env ok
    key size=44
    the key name is :
    the key data is :48304142556a6c66367a5450774c6d6671692f737241
    key size=32
    the key name is :serialno
    the key data is :41303635313030324239323035343031
    A0651002B9205401
    efuse version is not selected.
    Hit ENTER key to stop autoboot:  1 tstc enter
    
    WELCOME>
    WELCOME>version
    
    395456:S:Enc (Nov 03 2015 - 19:33:53)
    arm-none-eabi-gcc (Sourcery G++ Lite 2010q1-188) 4.4.1
    GNU ld (Sourcery G++ Lite 2010q1-188) 2.19.51.20090709
    WELCOME>
    



    Загрузка ядра ODROID с новым TPL
    U-boot-00000-ge6d5633(odroidc@e6d5633f) (Feb 12 2016 - 19:16:57)
    
    I2C:   clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    set output en 0xc1108054[20]=1
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[20]=0
    set output val 0xc1108058[20]=0
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    set output en 0xc1108054[20]=1
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffffffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffdfffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    out reg=c1108058,value=ffcfffff
    set output en 0xc1108054[20]=0
    set output val 0xc1108058[20]=0
    clear pinmux reg1[24]=0
    clear pinmux reg1[1]=0
    out reg=c1108058,value=ffefffff
    set output en 0xc1108054[21]=0
    set output val 0xc1108058[21]=0
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    set output en 0xc1108054[20]=1
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    set output en 0xc1108054[20]=1
    clear pinmux reg1[25]=0
    clear pinmux reg8[12]=0
    clear pinmux reg1[3]=0
    clear pinmux reg1[2]=0
    set output en 0xc1108054[20]=1
    ready
    DRAM:  1 GiB
    relocation Offset is: 2ff18000
    MMC:   SDCARD: 0, eMMC: 1
    IR init is done!
    *** Warning - bad CRC, using default environment
    
    mmc save env ok
    vpu clk_level = 3
    set vpu clk: 182150000Hz, readback: 182150000Hz(0x701)
    mode = 6  vic = 4
    set HDMI vic: 4
    mode is: 6
    viu chan = 1
    config HPLL
    config HPLL done
    reconfig packet setting done
    MMC read: dev # 0, block # 33984, count 12288 ... 12288 blocks read: OK
    ============================================================
    Vendor: Man 035054 Snr da23a8bd Rev: 3.0 Prod: SL16G
                Type: Removable Hard Disk
                Capacity: 14804.0 MB = 14.4 GB (30318592 x 512)
    ------------------------------------------------------------
    Partition     Start Sector     Num Sectors     Type
        1                16065         1007936       2
    ============================================================
    MMC read: dev # 0, block # 17600, count 16384 ... 16384 blocks read: OK
    ## ANDROID Format IMAGE
    ## Booting kernel from Legacy Image at 12000000 ...
       Image Name:   Linux-3.10.33
       Image Type:   ARM Linux Kernel Image (lzo compressed)
       Data Size:    5012513 Bytes = 4.8 MiB
       Load Address: 00208000
       Entry Point:  00208000
       Verifying Checksum ... OK
        Ramdisk start addr = 0x124c8800, len = 0x14b29a
        Flat device tree start addr = 0x12614000, len = 0x45e1 magic=0xedfe0dd0
       Uncompressing Kernel Image ... OK
    uboot time: 56206396 us.
    Using machid 0xf81 from environment
    From device tree /memory/ node aml_reserved_end property, for relocate ramdisk and fdt, relocate_addr: 0x5154001
       Loading Ramdisk to 05008000, end 0515329a ... OK
       Loading Device Tree to 05000000, end 050075e0 ... OK
    
    Starting kernel ...
    
    [    0.000000@0] Booting Linux on physical CPU 0x200
    [    0.000000@0] Linux version 3.10.33-00262-g02f0572 (jenkins@build) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG linaro-1.13.1-4.9-2014.09 - Linaro GCC 4.9-2014.09) ) #1 SMP PREEMPT Mon Feb 22 12:44:47 KST 2016
    [    0.000000@0] CPU: ARMv7 Processor [410fc051] revision 1 (ARMv7), cr=10c5387d
    [    0.000000@0] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
    [    0.000000@0] Machine: ODROIDC, model: AMLOGIC
    [    0.000000@0] physical memory start address is 0x200000
    [    0.000000@0] reserved_end is e3fffff
    [    0.000000@0]
    [    0.000000@0] Total memory is 1022 MiB
    [    0.000000@0] Reserved low memory from 0x06000000 to 0x0e3fffff, size: 132 MiB
    [    0.000000@0]        mesonfb0(low)           : 0x06100000 - 0x07900000 ( 24 MiB)
    [    0.000000@0]        mesonfb1(low)           : 0x07900000 - 0x07a00000 (  1 MiB)
    [    0.000000@0]        deinterlace0(high)      : 0x3df00000 - 0x40000000 ( 33 MiB)
    [    0.000000@0]        mesonstream0(low)       : 0x07a00000 - 0x09a00000 ( 32 MiB)
    [    0.000000@0]        vdec0(low)      : 0x09a00000 - 0x0da00000 ( 64 MiB)
    [    0.000000@0]        ppmgr0(high)    : 0x3bf00000 - 0x3df00000 ( 32 MiB)
    [    0.000000@0]        amvideocap0(low)        : 0x0da00000 - 0x0e400000 ( 10 MiB)
    [    0.000000@0] cma: CMA: reserved 8 MiB at 2f000000
    [    0.000000@0] cma: Found region@0, memory base 0, size 42 MiB
    [    0.000000@0] cma: CMA: reserved 44 MiB at 2c400000
    [    0.000000@0] Memory policy: ECC disabled, Data cache writealloc
    [    0.000000@0] Meson chip version = RevA (1B:A - 0:B72)
    [    0.000000@0] PERCPU: Embedded 8 pages/cpu @c1318000 s8832 r8192 d15744 u32768
    [    0.000000@0] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 206096
    [    0.000000@0] Kernel command line: root=/dev/mmcblk0p2 rw console=ttyS0,115200n8 no_console_suspend
    [    0.000000@0] PID hash table entries: 4096 (order: 2, 16384 bytes)
    [    0.000000@0] Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
    [    0.000000@0] Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
    [    0.000000@0] Memory: 64MB 16MB 731MB = 811MB total
    [    0.000000@0] Memory: 755256k/755256k available, 75208k reserved, 201728K highmem
    [    0.000000@0] Virtual kernel memory layout:
    [    0.000000@0]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    [    0.000000@0]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    [    0.000000@0]     vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
    [    0.000000@0]     lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)
    [    0.000000@0]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
    [    0.000000@0]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
    [    0.000000@0]       .text : 0xc0008000 - 0xc0864328   (8561 kB)
    [    0.000000@0]       .init : 0xc0865000 - 0xc089b280   ( 217 kB)
    [    0.000000@0]       .data : 0xc089c000 - 0xc08fba60   ( 383 kB)
    [    0.000000@0]        .bss : 0xc08fba60 - 0xc0b8b0c4   (2622 kB)
    [    0.000000@0] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
    [    0.000000@0] Preemptible hierarchical RCU implementation.
    



    Я почти уверен, что эта ошибка ROM'а будет наблюдаться во всей серии S805-B, а может и в последующих версиях.

    Для тех, кто желает поэкспериментировать, вот оригинальный дамп от emmc.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 11

      0
      А не пробовали запустить образ какой-нибудь для
      www.hardkernel.com/shop/odroid-c1
      ?
        0
        Этот не пробовал. Но OpenELEC собраный с нуля включая свежее ядро запускался и работал прекрасно. DeviceTree был перенят из оригинального ядра.
          0
          Интересно, надо прикупить такой.
            0
            А можешь поподробнее рассказать?
            — Где-то есть форк репозитория для сборки OpenELEC под Comigo Quattro?
            — Какие репозитории для ядра и юбута брать?
            — Где и как вытащить Device Tree? Образа оригинальной eMMC и ядра ведь нет нигде в общем доступе?
              0
              Вот образ оригинального emmc. Монтируй согласно таблице разделов из лога выше. Например mount -o loop,offset=142606336,sizelimit=838860800 comigo_quattro_emmc.img /mnt/system
              Не исключаю, что если залить на mSD, то будет грузить как c родного emmc. Сделай себе root. Ну а дальше сам.
            +1

            У меня есть смутное ощущение, что стоковый U-Boot может начать реагировать на нажатия клавиш кроме ENTER если получит некую последовательность байтов по UART (возможно, не все из них будут printable).
            Не пробовали покопать его на эту тему?


            Также, может быть там есть какая-то проверка например на нажатость какой-нибудь физической кнопки на устройстве (кнопка нажата при включении — реагируем на всё, не нажата — не реагируем).

              0
              Да, я бегло пробежал по сурсам, но на первый взгляд ничего подобного не нашёл. Физических кнопок на девайсе нет. Много времени тратить не стал и просто активировал в U-Boot'e Hush Interpreter.
              Даже если б такой пароль был, то стоковый U-Boot грузил бы всё равно только оригинальное ядро (он тоже проверяет его сигнатуру). Можно конечно его пропатчить прям в памяти… Как вариант.
                0

                Вполне может быть, что в девайсе зашито не то, исходники чего выложены на сайте (некоторые ведь практикуют security through obscurity).
                По опыту реверсинга aboot'ов могу сказать, что там порой можно найти интересные нестандартные команды (к примеру, unlock для работы fastboot flash/fastboot boot или возможность вычитки разделов и областей RAM из девайса на комп).

                  0
                  Не думаю. Я брал зашифрованый U-Boot из стоковой прошивки (т.е. ту, чем был прошит девайс). Анализ проводился не по сурсам (их конечно никто не выкладывал), а прям в ассемблере. Но, конечно, может там и есть backdoor. Я на этом не фокусировался.
              0
              Поразительно, что только вчера целый день провели с товарищем за тем, чтобы расковырять именно эту железку. Правда у нас на руках была инструкция с 4pda, там уже была схема распайки разъёма под SD-карточку, местонахождение UART и готовый образ.

              Другое дело, что после подключения карточки загрузка всё равно шла с eMMC. Для того, чтобы это обойти, мой товарищ замкнул пин данных eMMC на землю, тем самым заставив SoC загрузиться с SD (тоже через 30-40 секунд после холодного старта). После загрузки у меня уже не было доступа к eMMC (видимо, SoC как-то инициализирует eMMC, а Linux уже не может переинициализировать, что очень странно), но работала сеть.

              Из смешного: на самом деле оригинальный юбут как минимум принимает команды, потому что внезапно работают хоткеи (^C, ^U, ^J) и автодополнение (TAB), но не даёт их исполнять.

              А как удалось стянуть образ eMMC?
                0

                Да, там были образы и с LibreElec даже по моему. Если грузил всё равно с emmc, то не была изменена бут сиквенция. А уверен, что там UBoot оригинальный? Там только мой spl стоит, остальное ребята сами собирали.
                Я пробовал снять дамп с emmc, подключив его с спец usb устройству, на загрузка на 40% заканчивалась. И да, после загрузки с mSD, emmc не виден.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое