vak: (Улыбка)
[personal profile] vak
Я уже писал про появившуюся на днях в продаже платку с Wi-Fi по цене $13. Она поставляется с уже предустановленным Линуксом OpenWRT и языками программирования Lua и Python. Это здорово, но объем памяти и наличие карточки microSD позволяют запустить кое-что более серьезное, а именно полный Debian Linux. Чем мы и займемся.

Шаг 1: обновляем ядро. Зачем это нужно - я объясню ниже. Скачиваем файл LinkIt7688-sysupgrade-3.18.23.zip и распаковываем его в корень Flash-диска, имеющего разъем micro-USB. Должен получиться файл с именем lks7688.img. Годится любой диск с файловой системой FAT32, главное, чтобы он втыкался в микро-USB (как на Android-телефоне). Вставляем этот диск в разъем "HOST" платы, и подаем питание на разъем "PWR". Затем держим кнопку "WiFi" и нажимаем-отпускаем кнопку "MPU". Через пять секунд отпускаем кнопку "WiFi". Обновление занимает примерно три минуты, пока красная лампочка не перестанет мигать. После этого USB-диск отключаем, он больше не понадобится. Подробно процесс обновления firmware описан в главе 4.6.1 руководства LinkIt Smart 7688 Developer's Guide (PDF).

Шаг 2: готовим microSD-карточку. Тут понадобится линуксный компьютер. Скачиваем файл debian-jessie-mini.tgz - минимальный вариант корневой файловой системы для Debian 8 (jessie). Вставляем карточку microSD в компьютер, непосредственно (есть есть слот SD) или через USB-адаптер. Карточка будет видна в системе как /dev/mmcblk0 или как /dev/sdc (или sdb или с другой буквой - проверьте). Нужно карточку отмонтировать, переделать таблицу разделов, создать новую файловую систему, заново смонтировать и распаковать туда файлы. Выглядит это примерно так:

    $ sudo umount /dev/mmcblk0p1
    $ sudo fdisk /dev/mmcblk0
    [подробности здесь]
    $ sudo mke2fs /dev/mmcblk0p1
    [...]
    $ sudo mount /dev/mmcblk0p1 /mnt
    $ sudo tar xzf debian-jessie-mini.tgz -C /mnt
    $ sudo umount /mnt


Шаг 3: подсоединяем консольный порт. Используем любой адаптер USB-to-serial, например FT232, CP2102 или CH340. Сигнал GND адаптера соединяем с ножкой GND платы, сигнал TXD - с ножкой P9, RXD - P8. Включаем USB-адаптер в компьютер и подключаемся к консольному порту на скорости 57600. Нажимаем кнопку "MPU" - видим протокол загрузки типа этого.

Шаг 4: настраиваем подключение Wi-Fi. Устанавливаем нужные пакеты, создаем раздел swap. Заметьте: мы никоим образом не портим исходную предустановленную систему OpenWRT. Все имеющиеся функции и методы разработки, описанные в руководстве для платы Linkit Smart, продолжают работать.

    uci set wireless.sta.ssid=Ваша-сеть
    uci set wireless.sta.encryption=psk2
    uci set wireless.sta.key=ваш-пароль
    uci set wireless.sta.disabled=0
    uci commit
    wifi
    [ждем около минуты, когда появится связь]
    opkg update
    opkg install swap-utils block-mount nano
    mkswap /dev/mmcblk0p2
    swapon /dev/mmcblk0p2


Шаг 5: стартуем среду Debian. Для этого мы используем утилиту chroot. Корневая файловая система Debian находится на карточке microSD. Ее всегда можно вынуть и переставить в другой компьютер: переписать нужные файлы, сдублировать, забэкапить и т.п. В принципе, когда заработал Wi-Fi, консольный порт больше не нужен - можно подключаться через ssh (предварительно установив пароль на root).

    root@mylinkit:/# mount --bind /dev /tmp/run/mountd/mmcblk0p1/dev
    root@mylinkit:/# mount --bind /proc /tmp/run/mountd/mmcblk0p1/proc
    root@mylinkit:/# mount --bind /sys /tmp/run/mountd/mmcblk0p1/sys
    root@mylinkit:/# chroot /tmp/run/mountd/mmcblk0p1 /bin/bash
    root@mylinkit:/# _


Последнее приглашение - это уже bash из окружения Debian. Здесь при первом запуске имеет смысл сгенерировать нужные локали и установить полезные пакеты:

    echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen
    locale-gen
    apt-get update
    apt-get install locales bison byacc flex libelf-dev libfuse-dev \
        build-essential make autoconf automake libtool gdb fuse man-db \
        groff less ed bmake git byacc flex exuberant-ctags libfuse-dev \
        bmake git byacc flex exuberant-ctags libfuse-dev dialog \
        openssh-client subversion le vim gettext iputils-ping locate procps


Теперь у нас имеется полноценный Debian Linux, со всеми наворотами, и Wi-Fi подключением к интернету. Можно скачивать, компилировать и запускать любой софт. И все это на платке размером 2x5.5 сантиметров. В следующем посте я напишу про измерение скорости процессора посредством стандартного теста Dhrystone.

Чтобы освободить карточку перед тем как вынуть, надо будет выполнить:

    umount /tmp/run/mountd/mmcblk0p1/dev
    umount /tmp/run/mountd/mmcblk0p1/proc
    umount /tmp/run/mountd/mmcblk0p1/sys
    umount /tmp/run/mountd/mmcblk0p1
    swapoff /dev/mmcblk0p2


Зачем надо было обновлять ядро на шаге 1? Дело в том, что версия ядра, предустановленная на плате, не позволяет выполнять программы непосредственно с SD-карточки. Не то чтобы запрещает, но такие программы не работают. Это связано с особенностями работы кэша на этом чипе. Когда драйвер SD-карточки читает сектор кода программы, часть данных оседает в D-кэше и не успевает попасть в память. Когда процессор начинает выполнять эту страницу, он получает старое содержимое памяти. То есть код из D-кэша не попадает в I-кэш. Это не ошибка, а особенность функционирования данного типа кэша. Просто ядро должно об этом знать и в нужный момент сбросить содержимое кэша, соответствующего конкретной странице. В системе команд MIPS даже есть специальная инструкция для этого (SYNCI). Чтобы исправить ситуацию, надо в одном их файлов ядра Linux, а именно arch/mips/include/asm/cacheflush.h, пустую функцию flush_icache_page() заменить на:

static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
    if (cpu_has_dc_aliases || ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)) {
        __flush_dcache_page(vma, page);
    }
}


После этого все отлично работает. Эта правка есть в очереди на внесение в ядро версии 4.x, но в 3.18 она не попала.

Date: 2016-01-10 03:04 (UTC)
From: [identity profile] spamsink.livejournal.com
Э75 strikes again!

Date: 2016-01-10 04:26 (UTC)
From: [identity profile] spamsink.livejournal.com
В том-то и дело, что режим свертки при исполнении команды ЗП можно было переключать (собственно, мониторка работала преимущественно в режиме записи с командной сверткой), а вот проблему раздельных кэшей без системного вызова никак не решить.

Date: 2016-03-06 02:55 (UTC)
ext_646638: (Default)
From: [identity profile] rdia.livejournal.com
Ещё нужно как-то /dev/pts перебросить, иначе debian ругается на отсутствие логов.

И, кстати, вопрос - вы нового пользователя, который не root, не заводили?

И можно ли поставить debian напрямую?

Date: 2018-06-28 16:04 (UTC)
From: [personal profile] zmulian
Добрый день. Поделитесь патчами на ядро 3.18.23.
От себя могу добавить следующее: Ваша сборка работает. Самому собрать не получается. __flush_dcache_page(vma, page) несколькими строками выше определена как __flush_dcache_page(page). Ядро V4 с картой памяти работает криво. Через раз вываливается ошибка сегментации. apt-get update выполняется с 10 раза. Одним словом - прошу вашей помощи.. или пнуть в нужном направлении..

решено (как я и предполагал).. через 2 часа

static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
{
if (cpu_has_dc_aliases || ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)) {
__flush_dcache_page(page);
}
}




Edited Date: 2018-06-28 17:39 (UTC)

Date: 2018-07-02 12:50 (UTC)
From: [personal profile] zmulian
Добрый день. В данный момент пытаюсь запустить Debian напрямую с карты. С флешки получается нормально. С карты на первый раз получилось коряво. Не хватило драйверов для карты и чипа мт7688 в обрезанном мною ядре. В данный момент компилится новое ядро. Одним словом логика как в DEBWRT. Грузим из сквоша часть ядра с поддержкой накопителя с которого будет происходить старт системы, далее все остальные модули ядра грузятся с карты... С флешки работает отлично... Если знаете, то подскажите какие модули нужно включать для карты в ядре для чипа мт7688 (у меня linkit7688).