2016-08-14

Сборка Qualcomm модема из исходников (msm8916)

Ради фана и прокачки скилов решил собрать Qualcomm модем из исходников. В качестве целевой платформы выбрал msm8916, т.к. именно под эту платформу можно скачать исходники из интернета.

Для начала нужно скачать эти самые исходники. Для этого нужно воспользоваться торрент клиентом. Сам торрент можно найти, если загуглить строку EF3BF4FD7388657FF35C3DBF2B6367F924F8CDBC (magnet link). Скачивать можно не всё содержимое торрента, а только файл
"msm8916_2014-12-03_amss_qrd/modem_proc.zip" (500 MB).

Для сборки исходников модема msm8916 нам понадобится пакет HEXAGON Tools v6. Этот пакет входит в состав Hexagon SDK v2.0 - Linux. Но почему то консольный вариант установки этого SDK зависает на 30%. Поэтому предлагаю скачать отдельно HEXAGON Tools 6.4.06 ? используя магнет ссылку 61e8b8a520181ade801c251e5ec9352e33a7bb8c (magnet link) (490 MB).

Пока скачиваются тулзы и торрент следует распаковать NON-HLOS образ, который следует взять из прошивки целевого устройства. В моём случае этим устройством будет являться ASUS ZE550KL, т.к. разработчики из ASUS все свои модемы подписыват тестовым сертификатом Qualcomm (данный сертификат имеется в исходниках).
Распаковка образа NON-HLOS.bin осущестляется таким образом:
1.MODEM_DIR=$HOME/dev/asus_ze550kl
2.MODEM_STK=$MODEM_DIR/NON-HLOS.bin
3.MODEM_VDISK=/media/vdisk
4.sudo mkdir -p $MODEM_VDISK
5.sudo mount -t vfat $MODEM_STK -o ro $MODEM_VDISK
6.cp -f -r $MODEM_VDISK/* $MODEM_DIR
7.sudo umount $MODEM_STK

После этого в директории "dev/asus_ze550kl/image" должен появиться следующий набор файлов:
mba.mbn
modem.b00
modem.b01
modem.b02
...
modem.b25
modem.b26
modem.mdt

После скачивания торрента и утилит, при помощи которых будет осуществляться сборка модема msm8916, можно приступить к настройке операционной системы (рекомендую использовать Ubuntu 14.04 64-bit).

Для начала нужно установить некоторые зависимости:
1.sudo apt-get install p7zip-full
2.sudo apt-get install lib32z1 lib32ncurses5
3.sudo apt-get install scons
4.sudo apt-get install libxml-parser-perl

Установим HEXAGON Tools в систему из директории ~/Downloads:
1.cd $HOME
2.mkdir -p Qualcomm/HEXAGON_Tools
3.cd $HOME/Downloads
4.7za x -y -o$HOME/Qualcomm/HEXAGON_Tools hexagon_tools_6.4.06.7z

Распакуем исходники модема msm8916 в директорию ~/dev/qcom:
1.cd $HOME
2.mkdir -p dev/qcom/msm8916/modem_proc
3.cd $HOME/Downloads/msm8916_2014-12-03_amss_qrd
4.7za x -y -o$HOME/dev/qcom/msm8916/modem_proc modem_proc.zip

Т.к. zip-архив не хранит информацию о UNIX-атрибутах, следует устранить это недоразумение:
01.cd $HOME/dev/qcom/msm8916/modem_proc
02.find . -name '*.sh' -exec chmod -f 775 {} \;
03.find . -name '*.mk' -exec chmod -f 775 {} \;
04.find . -name '*.py' -exec chmod -f 775 {} \;
05.find . -name '*.pl' -exec chmod -f 775 {} \;
06.find . -name '*.lcs' -exec chmod -f 775 {} \;
07.find . -name '*.api' -exec chmod -f 775 {} \;
08.find . -name '*.xml' -exec chmod -f 775 {} \;
09.find . -name '*.scons' -exec chmod -f 775 {} \;
10.find . -name 'scons' -exec chmod -f 775 {} \;
11.find . -name 'SConscript' -exec chmod -f 775 {} \;
12.find . -name 'SConstruct' -exec chmod -f 775 {} \;
13.find . -name 'Makefile' -exec chmod -f 775 {} \;
14.find . -name 'makefile' -exec chmod -f 775 {} \;
15.find . -name 'qaic' -exec chmod -f 775 {} \;
16.find . -name 'doxygen' -exec chmod -f 775 {} \;
17.find . -name 'qdsp6-image-build' -exec chmod -f 775 {} \;
18.find . -name 'SleepSynth' -exec chmod -f 775 {} \;
19.find . -name 'crypto_cbc' -exec chmod -f 775 {} \;
20.find . -name 'crypto_ccm' -exec chmod -f 775 {} \;

Перейдём в директорию "modem_proc/build/ms" , т.к. именно тут находится shell-скрипт, запускающий процесс сборки. Так же в этой директории следует ожидать появления результатов сборки в поддиректории "bin". Перед запуском сборки нужно превести предварительную настройку. Откройте в тектовом редакторе файл build.sh и выполните следующие изменения:
1) удалите первую строчку, содержащую строку "#!/bin/sh"
2) замените строку "source setenv.sh" на ". setenv.sh"

В этой же директории нужно создать файл setenv.sh со следующим содержанием:
01.export ARMTOOLS=ARMCT5.05
02.export ARMROOT=$HOME/ARMCompiler5.05u2
03.export ARM_COMPILER_PATH=$ARMROOT/bin64
04.export ARMHOME=$ARMROOT
05.export ARMLIB=$ARMROOT/lib
06.export ARMINCLUDE=$ARMROOT/include
07.export ARMBIN=$ARMROOT/bin64
08.export ARMINC=$ARMINCLUDE
09.export ARMLMD_LICENSE_FILE=$ARMROOT/Community.lic
10. 
11.export HEXAGON_ROOT=$HOME/Qualcomm/HEXAGON_Tools
12.export HEXAGON_RTOS_RELEASE=6.4.06
13.export HEXAGON_Q6VERSION=v5
14.export HEXAGON_IMAGE_ENTRY=0xC0000000
15. 
16.export PYTHON_PATH=/usr/bin/python
17.export PYTHONPATH=/usr/bin/python
18.export MAKE_PATH=/usr/bin/make
19. 
20.export PATH=$MAKE_PATH:$ARM_COMPILER_PATH:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/qc/bin:$HEXAGON_ROOT/$HEXAGON_RTOS_RELEASE/gnu/bin:$PATH:PYTHONPATH

Хочется обратить внимание на значение параметра HEXAGON_IMAGE_ENTRY. Данное значение следует искать в стоковом модеме:
1.cd $HOME/dev/asus_ze550kl/image
2.readelf -h modem.b00

На входе получаем такую информацию о стоковом образе модема:
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           QUALCOMM DSP6 Processor
  Version:                           0x1
  Entry point address:               0xc0000000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x4
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         28
  Size of section headers:           40 (bytes)
  Number of section headers:         0
  Section header string table index: 0

Из всего этого нас интересует только значение параметра "Entry point address", равное 0xC0000000.

Теперь откройте в текстовом редакторе файл build_cfg.xml и сделайте следующие изменения:
1) значение параметра hexagon_image_entry измените на "0xC0000000"
2) значение параметра hexagon_rtos_release измените на "6.4.06"
3) значение параметра cflags измените на
"-Wno-error -Wno-tautological-constant-out-of-range-compare -Wno-medium -Wno-low -hexagon-predef-argset=modem-sw -mllvm -shrink-wrap-ext-wrapper-section=.wrap.func"

Далее нужно исправить досадную ошибку в файле "modem_proc/build/bsp/mapss_b/build/mapss_b.scons". Для этого откройте его в текстовом редакторе, найдите вот такой участок кода:
01.legacy_mode = True
02. 
03.if hex_version[0] >= '7':
04.  legacy_mode = False
05. 
06.elif hex_version[0] == '6':
07.  if hex_version[1] == '2':
08.    if len(hex_version) >= 3 and hex_version[2] >= '06':
09.      legacy_mode = False
10.  elif hex_version[1] == '4':
11.    legacy_mode = False

и добавьте 2-ве выделенных строчки кода (в оригинале они отсутствуют).

Теперь нужно добавить версию HEXAGON Tools 6.4.06 в белый список:
1.cd $HOME/dev/qcom/msm8916/modem_proc/core/kernel/qurt
2.HEXAGON_RTOS_RELEASE=6.4.06
3.WL_PREFIX="toolsver_whitelist \\= \\["
4.find . -name 'target_tools.py' -exec sed -i "s/$WL_PREFIX/$WL_PREFIX\"$HEXAGON_RTOS_RELEASE\" ,/" {} \;

Перед началом сборки следует определиться с вариантом собираемого модема. Для этого следует в распакованном образе NON-HLOS.bin найти строку "IMAGE_VARIANT_STRING=":
1.cd $HOME/dev/asus_ze550kl/image
2.grep -aohP "IMAGE_VARIANT_STRING=.{0,8}" modem.b*
Результат поиска таков: "IMAGE_VARIANT_STRING=EAAAANUZ"

Далее стоит в редактируемом ранее файле build_cfg.xml найти соответствие для строки "EAAAANUZ" найти вариант сборки:
 
    <build_variant>
      <variant_name> gen </variant_name>
      <purpose> 
        <purpose_name>prod</purpose_name>
        <build_id>  EAAAANVZ  </build_id>
      </purpose>
    </build_variant>
    <build_variant>
      <variant_name> genns </variant_name>
      <purpose> 
        <purpose_name>prod</purpose_name>
        <build_id>  EAAAANUZ  </build_id>
      </purpose>
    </build_variant>

Значит разработчики из ASUS используют вариант сборки "genns".

Запускаем сборку модема:
1.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/
2../build.sh 8916.genns BUILD_ID=EAAAANUZ -k

Через некоторое время процесс сборки остановится и выдаст следующие ошибки:
1.** Build errors...
2./home/android/dev/qcom/msm8916/modem_proc/geran/gmac/build/mapss_b/qdsp6/EAAAANUZ/gmacidleutil.o failed: Error 1
3./home/android/dev/qcom/msm8916/modem_proc/geran/gmac/build/mapss_b/qdsp6/EAAAANUZ/gmacutil.o failed: Error 1

Сначала исправим ошибку в gmacidleutil.c:
1.  
2.     else
3.     {
4.       if( /*(((starting_time_fn - reception_fn_mod_42432) % 42432) >= 0)
5.           &&*/ (((starting_time_fn - reception_fn_mod_42432) % 42432) <= 31623))
6.       {

Т.е. нужно всего навсего закоментировать первую часть условия.
В файле gmacutil.c нужно исправить полностью аналогичную ошибку.

Теперь можно снова запустить сборку исходников:
1.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/
2../build.sh 8916.genns BUILD_ID=EAAAANUZ -k

Хочу сразу отметить, что если вам понадобиться начать сборку с самого начала, то перед этим нужно выполнить "clean". Для этого нужно в консоли ввести следующее:
1.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/
2../build.sh 8916.genns BUILD_ID=EAAAANUZ --clean

Через некоторое время процесс сборки должен завершиться и при успехе вы в консоли должны увидить следующие строки:
1.#-------------------------------------------------------------------------------
2.Build 8916.genns returned code 0.
3.#-------------------------------------------------------------------------------
4.Overall Start Time: Sun Aug 14 16:26:43 2016,  Overall End Time: Sun Aug 14 16:31:21 2016
5.Overall Delta Time: 4 minutes, 37 seconds
6.#-------------------------------------------------------------------------------

Результаты сборки следует искать в директории "dev/qcom/msm8916/modem_proc/build/ms/":
./build.log
./bin/EAAAANUZ/mba.mbn
./bin/EAAAANUZ/qdsp6sw.mbn
./bin/EAAAANUZ/unsigned/mba.mbn
./bin/EAAAANUZ/unsigned/qdsp6sw.mbn

Т.к. в стоковом образе NON-HLOS.bin используются подписанные модули, то нужно использовать для дальнейших операций файлы "EAAAANUZ/mba.mbn" и "EAAAANUZ/qdsp6sw.mbn". Оба файла подписаны тестовым сертификатом Qualcomm.
Теперь нужно файл qdsp6sw.mbn разбить на множество более мелких файлов, которые представляют из себя ELF-секции исходного MBN-файла. Для этого нужно выполнить следующее:
1.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/bin
3. 
4.BUILD_ID=EAAAANUZ
5.MBN_FILE=./$BUILD_ID/qdsp6sw.mbn
6.MBN_PREFIX=modem
7.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/bin
8.python pil-splitter.py $MBN_FILE $MBN_PREFIX

После выполнения скрипта pil-splitter.py в директории "bin" появится следующий набор файлов:
modem.b00
modem.b01
modem.b02
...
modem.b24
modem.b25
modem.mdt

Так же в эту папку следует добавить файл mba.mbn , что можно сделать таким способом:
1.BUILD_ID=EAAAANUZ
2.MBN_FILE=./$BUILD_ID/mba.mbn
3.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/bin
4.cp -f $MBN_FILE ./

Далее нужно полученные файлы добавить в стоковый образ NON-HLOS.bin. Эту операцию можно осуществить следующим способом:
01.MODEM_DIR=$HOME/dev/asus_ze550kl
02.MODEM_STK=$MODEM_DIR/NON-HLOS.bin
03.MODEM_NEW=$MODEM_DIR/NON-HLOS-NEW.bin
04.MODEM_VDISK=/media/vdisk
05.cp -f $MODEM_STK $MODEM_NEW
06.sudo mkdir -p $MODEM_VDISK
07.sudo mount -t vfat $MODEM_NEW -o rw,umask=0000 $MODEM_VDISK
08.rm -f $MODEM_VDISK/image/modem.mdt
09.rm -f $MODEM_VDISK/image/modem.b*
10.rm -f $MODEM_VDISK/image/mba.*
11.cd $HOME/dev/qcom/msm8916/modem_proc/build/ms/bin
12.cp -f ./modem.mdt $MODEM_VDISK/image/
13.cp -f ./modem.b* $MODEM_VDISK/image/
14.cp -f ./mba.* $MODEM_VDISK/image/
15.sudo umount $MODEM_NEW

Теперь у нас имеется файл NON-HLOS-NEW.bin , который содержит новые бинарные модули, относящиеся непосредственно к модему. Осталось только проверить работоспособность этого образа NON-HLOS-NEW.bin. Но сделать этого я не могу, т.к. у меня нету девайса ASUS ZE550KL.

Поэтому я оставлю тут патч для TWRP, который устанавливает в девайс ASUS ZE550KL этот новый модем: modem_test_005.zip (только для модификации Z00L на чипе msm8916)

2 комментария:

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
  2. Тело одно,прошивка и радиомодуль один.Но лежат два аппарата один ловит 4ж,другой нет.Проц дракон 615,прошивка на базе msm8916

    ОтветитьУдалить