Khadas VimDIY box с открытым исходным кодом, разработан компанией Shenzhen Wesion Technology CO., LTD., которая сосредоточена на производстве OTT боксов и перепроектировке аппаратного обеспечения в соответствии с требованием заказчика.

Hardware Features

Khadas Vim это миниатюрный одноплатный ПК работающий на SoC Amlogic S905X включающий четырех-ядерный процессор ARM® Cortex™-A53 и 3D ускоритель ARM® Mali™-450. Наличие технической документации от компании Wesion Technology и открытых исходных кодов позволяет рассматривать Khadas VIM не только как законченное устройство, но и как инженерный образец для разработки собственных решений.

Khadas VIM
  • Amlogic S905X: 2.0 GHz 64Bit Quad-Core ARM® Cortex™-A53 CPU, 750MHz+ Penta Core ARM® Mali™-450 GPU
  • Broadcom AP6212/AP6255 Wifi + Bluetooth Module
  • 2GB DDR3+8GB/16GB EMMC-V5.0
  • HDMI 2.0a with 4K H.265/VP9 10bit & HDR10 Video Processing
  • USB-C, Type-C with USB 2.0 OTG Supported
  • 40-Pin 2.54mm Header (I2C, I2S, UART, PWM, ADC, USB, SPDIF, etc)
  • Tiny form factor: thin with dimensions of credit card (82.0x57.5 mm)

Платы Khadas VIM поддерживают операционные системы на базе ядра Linux (поставки Ubuntu, Buildroot), Android, а также OpenELEC.

Новости компании Wesion Technology, касающиеся платы Khadas VIM, а также техническую поддержку, можно получить на форуме forum.khadas.com.

Toolchains

Для Khadas VIM мы приготовили четыре toolchain-а.

Первый предназначен для создания ПО на архитектуру AArch64, причем сам toolchain работает на x86_64 Linux машинах. Получить его можно на нашем FTP-сервере в каталоге toolchains/x86_64. Выбирать здесь нужно последнюю версию архива с именем 'aarch64-S9XX-linux-glibc-*.tar.gz'.

Второй toolchain предназначен для создания систем, способных работать на 64-битных ARM процессорах, но использующих лишь 32-битные наборы команд. Данный toolchain находится в архиве с именем 'arm8l-A9XX-linux-glibc-*.tar.gz'.

Третий toolchain предназначен для сборки firmware в составе U-Boot и готовит программы под архитектуру ARM® Cortex™-A3, причем без использования GNU Libc. Этот toolchain расположен в каталоге toolchains/x86_64 под именем 'arm-A9XX-eabi-newlib-*.tar.gz'.

И, наконец, четвертый toolchain построен для создания целевых программ низкого уровня, не использующих библиотеку GNU Libc. Данный toolchain можно использовать, например, при создании собственного загрузчика или для сборки U-Boot. Этот toolchain расположен в каталоге toolchains/x86_64 под именем 'aarch64-S9XX-elf-newlib-*.tar.gz'.

Для самостоятельной сборки toolchain-а, необходимо получить ветку toolchains-1.1.x репозитория toolchains, например, следующим образом

$ svn co
  svn://radix-linux.su/toolchains/branches/toolchains-1.1.x
  toolchains

И выполнить команду make в соответствующем каталоге:

$ cd toolchains/products/S9XX-glibc/1.1.2
$ make -j8

Напомним здесь, что перед сборкой необходимо подготовить каталог для инсталляции toolchain-а так, как это описано в разделе, посвященном загрузке toolchain-ов с нашего FTP-сервера.

Source Code

Компания Amlogic Co, Inc., которая является разработчиком SoC S905X, распространяет исходные коды на собственном FTP-сервере. Здесь представлены не только коды ядра и загрузчика, а так же все необходимые драйверы устройств, которые обычно представлены на платах базирующихся на SoCs серии S8xx, S9xx.

Однако разработчики платы Khadas VIM ведут собственные репозитории исходных кодов на ресурсе GitHub.

На нашем сервере мы поддерживаем зеркала ключевых репозиториев. Так исходные коды ядра Linux можно найти в репозитории linux.git, а загрузчик, – в репозитории u-boot.git.

Для того, чтобы разобраться, какие именно срезы репозиториев используются при сборке платформы Radix.Linux, следует обратиться к Make-файлам репозитория sources.git. Например, в файле Linux/Khadas/S905X/Makefile, можно видеть, что мы используем ветку ubuntu репозитория https://github.com/khadas/linux.git, поскольку данная ветка наиболее близка для обычных дистрибутивов Linux.

На странице, документации от компании Wesion Technology, можно найти необходимую информацию, позволяющую самостоятельно собрать ядро Linux и загрузчик U-Boot.

Flash Layout

Составить наиболее полное представление о размещении всех компонентов системы, как на загрузочной SD карте, так и во внутренней памяти устройства (eMMC), легче всего на примере инсталляции системы Radix.Linux.

SD Card

Загрузчик, предназначенный для SD карты, записывается в два этапа. Сначала записываются первые 442 байта информации по нулевому смещению от начала карты, затем оставшиеся байты загрузчика, начиная с 512-го, записываются со смещением 512 байтов от начала SD карты. Делается это для того, чтобы не повредить таблицу разделов диска. Всю процедуру записи загрузчика на SD карту можно представить следующими командами:

# dd if=u-boot.sd.bin of=/dev/mmcblk0  bs=1   count=442
# dd if=u-boot.sd.bin of=/dev/mmcblk0  bs=512 skip=1 seek=1

Пользователям системы Radix.Linux нет необходимости самостоятельно заботиться о порядке размещения данных на SD карте. Как мы говорили в разделе Products Release вводной статьи, для записи загрузочного образа достаточно загрузить свежие файлы с FTP сервера, например, из каталога 1.1.620/s9xx-glibc/khadas-vim и выполнить две следующие операции:

# cat khadas-vim.boot-records khadas-vim.ext4fs > SDHC.img 
# dd if=SDHC.img of=/dev/mmcblk0

Оставшееся место на карте можно распределить с помощью утилиты fdisk, например, создав дополнительный раздел для размещения домашних каталогов пользователей.

Следует отметить, что использование утилиты fdisk совершенно безопасно для загрузчика, который размещен на карте до начала разделов и не затрагивает таблицу разделов в MBR.


Прежде чем приступать к инсталляции системы Radix.Linux во встроенную eMMC память, необходимо очистить eMMC flash. Дело в том, что платы Khadas VIM поставляются с предустановленной системой Android и, при неудачной попытке загрузить ядро, расположенное на SD карте, с помощью стандартного загрузчика, произойдет запуск Android, который разрушит все данные на карте.

Если же eMMC память пуста, то процессор начнет загрузку с SD карты, разумеется, если обнаружит на ней необходимые для этого данные.

Итак, подключившись к плате через серийный порт и остановив загрузку с помощью клавиш <Space>, <Enter> или комбинации <Ctrl>+<C>, мы попадаем в консоль загрузчика.

Для очистки eMMC памяти достаточно выполнить команду store init 3, которая выдаст примерно следующий результат:

kvim# store init 3
emmc/sd response timeout, cmd8, status=0x1ff2800
emmc/sd response timeout, cmd55, status=0x1ff2800
[mmc_startup] mmc refix success
[mmc_init] mmc init success
switch to partitions #0, OK
mmc1(part 0) is current device
Device: SDIO Port C
Manufacturer ID: 15
OEM: 100
Name: 8WPD3
Tran Speed: 52000000
Rd Block Len: 512
MMC version 5.0
High Capacity: Yes
Capacity: 7.3 GiB
mmc clock: 40000000
Bus Width: 8-bit DDR
[store]amlmmc erase 1emmckey_is_protected : protect
 start = 0,end = 8191


Caution! Your devices Erase group is 0x400
The erase range would be change to 0x22000~0xe8ffff

start = 139264,end = 15269886
kvim#

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

В случае успешной загрузки системы Radix.Linux, пользователь получит приглашение:

 . . .

Radix Linux 3.14.29 for Khadas Vim S905X release 1.1 [ tty1 ]

khadas-vim login:

Изначально пароль суперпользователя не задан и войти в систему можно просто указав имя root,

Radix Linux 3.14.29 for Khadas Vim S905X release 1.1 [ tty1 ]

khadas-vim login: root
Last login: Thu Jan  1 00:01:49 UTC 2015 on ttyS0
Linux 3.14.29.

root@khadas-vim:~#

однако, после первого входа в систему, следует установить пароль пользователя root.

eMMC Flash

Убедившись в том, что сделанные нами записи на SD карте исправны и система загружается нормально, можно приступать к инсталляции Radix.Linux.

Перезагрузив систему с помощью команды reboot, необходимо войти в консоль загрузчика (клавиши <Space>, <Enter> или комбинация <Ctrl>+<C>) и последовательно выполнить следующие операции.

Инициализировав mmc интерфейс с помошью команды mmcinfo:

kvim# mmcinfo
Device: SDIO Port B
Manufacturer ID: 41
OEM: 3432
Name: SD16G
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.5 GiB
mmc clock: 40000000
Bus Width: 4-bit

и загрузив параметры ядра из каталога /boot файловой системы, находящейся на SD карте:

kvim# ext4load mmc 0:1 0x01080000 /boot/kvim.dtb
36927 bytes read in 49 ms (735.4 KiB/s)

записываем новую таблицу разделов:

kvim# store dtb write 0x01080000
[store]To run cmd[emmc dtb_write 0x01080000 0x40000]
write emmc dtb
mmc read lba=0x14000, blocks=0x400
start dts,buffer=0000000073eeb850,dt_addr=0000000073eeb850
parts: 2
00:      logo   0000000002000000 1
01:    rootfs   ffffffffffffffff 4
get_dtb_struct: Get emmc dtb OK!
Partition table get from SPL is :
       name                        offset              size              flag
===================================================================================
  0: bootloader                         0            200000                 0
  1: reserved                      400000           4000000                 0
  2: env                          4400000            400000                 0
  3: logo                         4800000           2000000                 1
  4: rootfs                       6800000         1cb800000                 4
mmc read lba=0x2000, blocks=0x2
mmc read lba=0x2002, blocks=0x2
mmc_read_partition_tbl: mmc read partition ERROR!
mmc write lba=0x2000, blocks=0x2
mmc write lba=0x2002, blocks=0x2
mmc_write_partition_tbl: mmc write partition OK!
  partition table success

Таблица записывается в начало раздела reserved и используется в дальнейшем не только загрузчиком, но и ядром Linux для обеспечения доступа к файловым системам на пользовательском уровне.


Здесь следует дать некоторые пояснения.

Дело в том, что разделы bootloader, reserved и env жестко определены в исходном коде загрузчика, а именно, в файле include/emmc_partitions.h:

#ifndef CONFIG_AML_MMC_INHERENT_PART
#define     PARTITION_RESERVED              (0)         /* size reserver after each partition */
#define     MMC_BOOT_PARTITION_RESERVED     (0x2*SZ_1M) /* size reserved after 'bootloader' partition */

#define     MMC_BOOT_NAME                   "bootloader"
#define     MMC_BOOT_DEVICE_SIZE            (0x2*SZ_1M) /* currently U-Boot size is approximately 920K */

#define     MMC_RESERVED_NAME               "reserved"
#define     MMC_RESERVED_SIZE               (64*SZ_1M)
#define     MMC_BOTTOM_RSV_SIZE             (0)
#endif      /* CONFIG_AML_MMC_INHERENT_PART */

// #define     MMC_CACHE_NAME                  "cache"
// #define     MMC_CACHE_SIZE                  (512*SZ_1M) // this is not used and should be get from spl

#define     MMC_ENV_NAME                    "env"
#define     MMC_ENV_SIZE                    (0x4*SZ_1M)

Кроме того, в исходном коде ядра (файл include/linux/mmc/emmc_partitions.h):

/* MMC Partition Table */
#define     MMC_PARTITIONS_MAGIC            "MPT"
#define     MMC_RESERVED_NAME               "reserved"

#define     SZ_1M                           0x00100000

/* the size of bootloader partition */
#define     MMC_BOOT_PARTITION_SIZE         (2*SZ_1M)

/* the size of reserve space behind bootloader partition */
#define     MMC_BOOT_PARTITION_RESERVED     (2*SZ_1M)

заданы переменные MMC_BOOT_PARTITION_SIZE и MMC_BOOT_PARTITION_RESERVED, с помощью которых процедура инициализации ядра определяет адрес раздела reserved, где находится таблица разделов eMMC памяти.

Адреса остальных разделов, а именно разделов logo и rootfs, определяются в файле kvim.dts и читаются подсистемой команд загрузчика store во время записи параметров ядра (kvim.dtb) и формировании таблицы разделов.


Итак, с помощью команды:

kvim# store dtb write 0x01080000

мы сформировали таблицу разделов eMMC.

Следующим шагом будет запись в раздел bootloader загрузчика, предназначенного специально для eMMC. Данный загрузчик находится в файле u-boot.bin и должен быть записан с нулевым смещением от начала eMMC памяти:

kvim# ext4load mmc 0:1 0x01080000 /boot/u-boot.bin
901120 bytes read in 104 ms (8.3 MiB/s)

kvim# store rom_write 0x01080000 0 100000
mmc switch to boot0 success
mmc switch to boot1 success
mmc switch to user success

kvim#

Далее необходимо записать переменные окружения U-Boot в раздел env:

kvim# defenv
## defenv_reserve

kvim# saveenv
Saving Environment to aml-storage...
mmc env offset: 0x4400000
Writing to MMC(1)... done

kvim#

На этом этапе, все действия, которые должны были быть произведены средствами загрузчика, выполнены. Однако для того, чтобы мы могли загружать устройство, нам необходимо установить непосредственно систему Radix.Linux, а также дать дополнительную информацию загрузчику и ядру Linux о том, на каком именно разделе eMMC следует искать корневую файловую систему.


Как ни странно, но для того, чтобы загрузчик мог читать файлы из корневой файловой системы, расположенной в разделе rootfs, необходимо создать классическую таблицу разделов в области MBR.

Для создания такой записи нам необходимо еще раз загрузить систему с SD карты и воспользоваться утилитой fdisk.

Проще всего, создание записи в таблице разделов, можно выполнить с помощью следующего скрипта, который подает необходимые команды на вход утилиты fdisk:

#!/bin/sh

fdisk /dev/mmcblk1 <<EOF
n
p
1
212992

a
p
w
EOF

Здесь число 212992 определяет начальный сектор, занимаемый корневой файловой системой и, поскольку размер сектора равен 512 байтов, данное число может быть получено путем деления смещения раздела rootfs от начала eMMC, заданного в байтах, на размер сектора диска:

212992 =
0x6800000 /
512;

Для того, чтобы упростить действия пользователей по созданию записи о разделе для корневой файловой системы в области MBR, в пакете u-boot поставляется файл /boot/rootfs-partition, который содержит необходимые команды для утилиты fdisk.


Итак, загрузив систему с SD карты,

Radix Linux 3.14.29 for Khadas Vim S905X release 1.1 [ tty1 ]

khadas-vim login: root
Last login: Thu Jan  1 00:01:49 UTC 2015 on ttyS0
Linux 3.14.29.

root@khadas-vim:~#

необходимо записать информацию в таблицу разделов MBR с помощью команды:

root@khadas-vim:~# sh /boot/rootfs-partition

создать непосредственно Ext4 файловую систему:

root@khadas-vim:~# mke2fs -t ext4 -L rootfs /dev/mmcblk1p1

и переписать на нее содержимое образа khadas-vim.ext4fs.

Здесь важно подчеркнуть, что копирование файлов следует осуществлять от имени суперпользователя с сохранением всех аттрибутов файлов.

На этом процесс инсталляции системы Radix.Linux полностью завершен и, при включении питания, загрузчик должен вести себя следующим образом.

  • Если подключена SD карта и в корневой файловой системе /dev/mmcblk0p1 присутствует скрипт /boot/boot.sd.scr, то загрузчик следует инструкциям, записанным в данном скрипте. Если же файл /boot/boot.sd.scr не будет найден, то загрузчик попытается выполнить стандартную процедуру, предусмотренную для плат Khadas VIM.
  • Если SD карта не подключена, то загрузчик попытается выполнить скрипт /boot/boot.scr, который предполагается найти в корневой файловой системе, расположенной в разделе /dev/mmcblk1p1, то есть в разделе rootfs eMMC.

В заключение важно подчеркнуть, что во время инициализации системы, ядро Linux перечитает таблицу разделов, расположенную в области reserved и раздел, известный ранее как /dev/mmcblk1p1, будет переименован в /dev/rootfs. Кроме того, все известные разделы eMMC, в файловой системе /dev, будут представлены по именам:

/dev/bootloader
/dev/reserved
/dev/env
/dev/logo
/dev/rootfs

Наверное это удобно для доступа к разделам во время работы системы.


Мы рассмотрели процесс ручной инсталляции системы Radix.Linux для того, чтобы наиболее полным образом составить представление об организации памяти. В дальнейшем значения размеров и смещений отдельных разделов дискового пространства могут быть изменены, однако, основной смысл представленного материала останется прежним.


Wireless

Платы Khadas VIM поставляются в разных модификациях. На одних могут быть установлены WiFi модули AP6212, на других – AP6255. Если на плате установлен модуль AP6255, то для того, чтобы драйвер мог загрузить firmware, необходимо поменять символическую ссылку в каталоге /lib/firmware/broadcom/ap6xxx с помощью следующих команд:

# cd /lib/firmware/broadcom/ap6xxx
# ln -sf nvram_ap6255.txt nvram.txt

Файл /etc/wpa_supplicant.conf, после установки системы Radix.Linux, содержит следующие данные.

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=root

update_config=1
eapol_version=1
ap_scan=1
fast_reauth=1
pmf=1

disable_scan_offload=1
wowlan_triggers=any
p2p_no_go_freq=5170-5740
p2p_search_delay=0
no_ctrl_interface=

ctrl_interface=wlan0
p2p_go_intent=13

Прежде чем использовать wpa_supplicant для соединения необходимо добавить существующие сети, например:

network={
   scan_ssid=0
   proto=WPA
   key_mgmt=WPA-PSK
   pairwise=CCMP TKIP
   group=CCMP TKIP WEP104 WEP40
}

network={
   ssid="your_id"
   psk=YOUR_HEX_KEY
}

Здесь your_id является именем сети, а YOUR_HEX_KEY – представляет собой шестнадцатеричный пароль для сети, использующей WPA-PSK/WPA2-PSK шифрование.

Создать шеснадцатеричный ключ для сети можно с помощью утилиты wpa_passphrase:

# wpa_passphrase your_id passphrase

network={
   ssid="your_id"
   #psk="passphrase"
   psk=59e0d07fa4c7741797a4e394f38a5c321e3bed51d54ad5fcbd3f84bc7415d73d
}

Где passphrase представляет собой текстовый пароль для сети your_id.

После создания необходимых записей в файле /etc/wpa_supplicant.conf подключение к беспроводной сети можно осуществить с помошью дух простых комманд:

# /usr/sbin/wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
# dhcpcd wlan0

В заключение необходимо сказать, что компания Shenzhen Wesion Technology CO., LTD. уделяет большое внимание поддержке пользователей и организовало специальный домен khadas.com с субдоменами, на которых можно найти документацию и форум открыторго сообщества.