Обновление Linux в устройстве на базе чипа Altera SoC FPGA и получение доступа с этого устройства к расшаренным сетевым ресурсам Windows-сервера

от автора

Недавно компания Terasic начала продажи весьма интересной платы DE0-Nano-SoC Kit. Интересна она тем, что за весьма скромную цену предлагается очень мощный и функционально-насыщенный комплект разработчика на основе чипа Altera Cyclone V SoC FPGA со встроенным двухъядерным процессором ARM Cortex-A9. Кроме того, производитель в комплекте с платой даёт ОС Linux, развёрнутую на карту памяти MicroSD.

Но получив эту плату в своё распоряжение, я довольно быстро наткнулся на несколько проблем, обусловленых тем, что Linux был скомпилирован из исходников Yocto Project. В основном все проблемы были связаны с отсутствием общедоступных репозиториев, из которых можно было бы добавить в систему недостающие компоненты. Например, для того, чтобы получить доступ с этого устройства через сеть к расшаренным ресурсам Windows-сервера, в ядре не хватало модуля поддержки файловой системы Cifs.

Поэтому прежде всего было решено обновить ядро, заменить Yocto на более привычный Debian Wheezy и доустановить всё, что необходимо для доступа к расшаренным ресурсам Windows-сервера.

Процесс сборки изучался мной и выполнялся следуя рекомендациям из этой статьи, за что её автору Des333 огромное спасибо!

Полная переделка в мои планы не входила, поэтому загрузчики на карточке было решено оставить родные — от образа Linux 3.13, идущего в комплекте с платой. Так что раздел с типом A2 было решено не трогать совсем.

Задачи

  • Обновить ядро Linux
  • Заменить RootFS на Debian 7
  • Доточить образ так, чтобы его можно было апдейтить из Интернета
  • Примонтировать директорию, расшаренную на сервере Windows

Сборка ядра

Так как основной моей рабочей средой по жизни является Windows, то все действия по сборке Linux выполнялись из-под ОС Linux Mint 17.2 Cinnamon, установленной на виртуальную машину.

1. Запускаем терминалку и входим в root-режим — чтобы не набирать каждый раз команду sudo:

sudo -i 

При этом /root будет нашей домашней директорией — всё будем делать в ней.

2. Компилировать ядро будем с помощью кросс-компилятора, входящего в пакет Altera SoC Embedded Design Suite (EDS). Поэтому скачиваем и устанавливаем самый свежий пакет Altera SoC EDS. На данный момент времени Altera SoC EDS имеет версию 15.0. Скачать этот пакет можно прямо с сайта Альтеры.

Altera SoC EDS установится в директорию /root/altera/15.0.

3. Устанавливаем build-essential:

apt-get install build-essential 

4. Установливаем libncurses:

apt-get install libncurses5-dev 

5. Скачиваем исходники linux-socfpga из репозиториев Альтеры и распаковываем их в домашнюю директорию:

  • Заходим в релизы linux-socfpga в репозиториях Альтеры
  • Находим нужный релиз. Я выбрал версию 4.1 — так как это была самая свежая стабильная версия на данный момент времени
  • Скачиваем архив с исходниками
  • Распаковываем исходники в домашнюю директорию

В результате появляется директория /root/linux-socfpga-4.1 с исходниками ядра Linux версии 4.1.

6. Запускаем альтеровский скрипт, который запустит новый BASH и подправит в нём некоторые переменные окружения (например, PATH). Все действия по компиляции будем проводить не выходя из этого BASH:

cd /root/altera/15.0/embedded ./embedded_command_shell.sh 

7. Создаём несколько переменных окружения:

export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- export LOADADDR=0x8000 

8. Создаём дефолтную конфигурацию для socfpga:

cd /root/linux-socfpga-4.1 make socfpga_defconfig 

При этом будет создан конфигурационный файл .config, заточенный для компиляции под ARM.

9. Добавляем недостающие компоненты в конфигурацию ядра (или удаляем лишние):

make menuconfig 

При этом откроется псевдографическое окно с менюшками.

Нам нужно добавить драйвер файловой системы CIFS — чтобы иметь возможность заходить на сетевые расшаренные ресурсы. Для этого идём по пути File Systems -> Network File Systems, становимся на CIFS Support и нажимаем клавишу пробел — напротив строки CIFS Suport должна появиться буква M — значит это драйвер, не встраиваемый в ядро. Нужно будет позднее скомпилировать его отдельно и положить в директорию внешних модулей.

Также нужно включить поддержку HighMem — иначе система не сможет использовать верхние 256 мегабайт ОЗУ. Для этого идём по пути Kernel Features -> High Memory Support и также нажимаем клавишу пробел.

Выходим из меню — нажимаем EXIT пока не выйдем. На вопрос — надо ли сохранять конфигурацию — отвечаем Yes.

10. Компилируем ядро:

make uImage 

В моём случае виртуальной машине было отдано только одно ядро. Процесс компиляции занял около 20 минут. Если же компилирование будет выполняться в машине с несколькими ядрами, то для скорости можно распараллелить процесс компиляции на несколько ядер. Для этого надо явно задать количество ядер через опцию -j:

make -j 3 uImage 

11. Компилируем dtb-файл, соответствующий нашему устройству. Если воспользоваться старым dtb-файлом, то или устройство повиснет при загрузке или будут страшные глюки при работе:

  • Ищем все файлы, имеющие в названии cyclone5 и заканчивающиеся на dts:
    find ~/linux-socfpga-4.1 -name "*cyclone5*dts" 

  • Выбираем наиболее подходящий из найденых файлов. Я просто просматривал их содержимое и в одном из них увидел слово terasic. Мне подумалось, что это самый подходящий файл для данного устройства — вот его и использовал. Файл назывался socfpga_cyclone5_sockit.dts.
  • Запускаем компиляцию socfpga_cyclone5_sockit.dtb:
    make socfpga_cyclone5_sockit.dtb 

В результате компиляции создалось два файла:

/root/linux-socfpga-4.1/arch/arm/boot/zImage /root/linux-socfpga-4.1/arch/arm/boot/dts/socfpga_cyclone5_sockit.dtb 

12. Компилируем модуль CIFS:

make M=fs/cifs 

13. Компилируем все модули криптографии — они понадобятся при монтировании расшаренных ресурсов Windows:

make M=crypto 

14. Копируем файлы ядра и dtb на карточку. Исходно карточка была нарезана так, что ядро и DTB-файл лежали на отдельном партишене FAT32. Вот на него эти файлы и записываем. Единственное замечание: DTB-файл нужно переименовать — чтобы он назывался также, как тот, который уже лежит на разделе FAT32 карточки:

  • Подключаем карточку к виртуальной машине. Мне пришлось воспользоваться внешним кардридером, подключенным прямо к порту USB2 компьютера. Сделать то-же самое через встроенный в компьютер кардридер почему-то не удалось. Также не удалось подсоединить внешний кардридер к виртуальной машине, если подключать его через порт USB3.
  • Произойдёт автомонтирование разделов карточки — нельзя размонтировать разделы через GUI, потому что в этом случае происходит полное отключение кардридера от виртуальной машины.
  • Смотрим названия примонтированных разделов:
    mount 

    Увидим нечто в этом роде:

    /dev/sdb1 on /media/user/F725-1429 type vfat (rw,nosuid,nodev,uid=1000,gid=1000,shortname=mixed,dmask=0077,utf8=1,showexec,flush,uhelper=udisks2) /dev/sdb2 on /media/user/41cad05c-898e-49a3-9d00-02b92fa817ba type ext3 (rw,nosuid,nodev,uhelper=udisks2) 

    Раздел типа vfat (первая строка) — то, что нас интересует в данный момент.

  • Смотрим, что лежит на разделе vfat:
    ll /media/user/F725-1429 

    Видим нечто в этом роде:

    -rw-r--r--  1 user user 1164128 Apr 20 20:23 de0_nano_soc.rbf -rw-r--r--  1 user user   15274 Jul 26 17:08 socfpga.dtb -rw-r--r--  1 user user     176 Apr 20 19:59 u-boot.scr -rw-r--r--  1 user user 3371472 Jul 29 16:50 zImage 

    Значит dtb-файл называется socfpga.dtb.

  • Копируем наши файлы на карточку:
    cp /root/linux-socfpga-4.1/arch/arm/boot/zImage /media/user/F725-1429/ cp /root/linux-socfpga-4.1/arch/arm/boot/dts/socfpga_cyclone5_sockit.dtb /media/user/F725-1429/socfpga.dtb 

Сборка файловой системы

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

Собирать будем Debian 7 Wheezy:

1. Устанавливаем пакеты, которые понадобятся для сборки файловой системы:

apt-get install debootstrap qemu-user-static binfmt-support 

2. Создаем директорию и загружаем в неё все необходимые файлы:

cd /root mkdir debian7 debootstrap --arch armel --foreign wheezy debian7 http://ftp.debian.org/debian 

3. Чтобы запускать приложения, собранные под ARM-архитектуру, будем использовать qemu static. Для этого скопируем файл в нашу директорию debian7:

cp /usr/bin/qemu-arm-static debian7/usr/bin/ 

4. Переходим в нашу новую файловую систему:

chroot debian7 /bin/bash 

5. Если приглашение интерпретатора изменилось на «I have no name!@hostname:/#», значит всё прошло успешно.
Заканчиваем процесс сборки:

/debootstrap/debootstrap --second-stage 

6. В /etc/inittab оставляем следующие строки:

/etc/inittab id:5:initdefault: si::sysinit:/etc/init.d/rcS ~~:S:wait:/sbin/sulogin l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 z6:6:respawn:/sbin/sulogin S:2345:respawn:/sbin/getty 115200 console 

7. Устанавливаем пароль для root-аккаунта:

passwd 

8. Запаковываем новую файловую систему в архив:

tar -cpzf debian7.tar.gz --exclude=debian7.tar.gz  / 

9. Выходим из chroot:

exit 

10. Размонтируем и затем форматируем раздел ext3 на карточке (названия разделов смотрим в пункте 14 из сборки ядра):

umount /dev/sdb2 mkfs.ext3 /dev/sdb2 

11. Монтируем раздел ext3:

mount /dev/sdb2 /mnt/ 

12. Распаковываем архив с файловой системой на карточку в раздел ext3:

tar -xzf /root/debian7/debian7.tar.gz -C /mnt/ 

13. Так как мы хотим подключаться к расшаренным ресурсам на сервере Windows, то необходимо записать на карточку внешние модули, скомпилированные на этапах 12 и 13 процесса сборки ядра:

cd /mnt/lib mkdir modules mkdir modules/4.1.0 mkdir modules/4.1.0/extra mkdir modules/4.1.0/kernel mkdir modules/4.1.0/kernel/crypto cp /root/linux-socfpga-4.1/fs/cifs/cifs.ko ./modules/4.1.0/extra/ cp /root/linux-socfpga-4.1/crypto/*.ko ./modules/4.1.0/kernel/crypto/ 

14. Размонтируем разделы:

umount /dev/sdb1 umount /dev/sdb2 

На этом всё — карточка готова, можно устанавливать её в устройство и загружаться.

Окончательная доводка

После загрузки устройства дотачиваем образ на месте:

1. Логинимся в Debian на устройстве, подключившись к нему через встроенный serial-порт.

2. Генерим файлы с информацией о внешних модулях ядра:

depmod -a 

3. Добавляем в список репозиториев репозиторий Debian 7 (я добавил немецкий сервер):

echo "deb http://ftp.de.debian.org/debian wheezy main" > /etc/apt/sources.list 

4. Подключаем устройство к Ethernet-сети. Получаем адрес по DHCP:

dhclient -4 eth0 

5. Поднимаем NTP, так как с неправильным временем не удастся примонтировать расшаренные ресурсы:

apt-get update apt-get install ntp 

6. Устанавливаем наш часовой пояс:

dpkg-reconfigure tzdata 

7. Для проверки, что всё собралось нормально, монтируем серверную шару. Например, в моём случае я делал это так:

mount //192.168.48.4/distrib /mnt -o username=jok40 

8. Устанавливаем SSH-сервер. Пользоваться serial-пором неудобно, так как при работе через него происходит заворот набираемых команд на начало строки после достижения колонки 80:

apt-get install openssh 

9. Назначаем статический адрес интерфейсу eth0 — чтобы в дальнейшем проще было подключаться к устройству по SSH. Для этого редактируем файл interfaces:

nano /etc/network/interfaces 

В моём случае он стал выглядеть вот так:

# interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback  # The primary network interface allow-hotplug eth0 iface eth0 inet static address   192.168.48.27 netmask   255.255.255.0 gateway   192.168.48.1 network   192.168.48.0 broadcast 192.168.48.255  auto eth0 

10. Редактируем файл resolv.conf — чтобы нормально работал DNS-клиент:

nano /etc/resolv.conf 

Добавляем в него строки:

nameserver 192.168.48.1 nameserver 8.8.8.8 

11. Перезагружаем устройство.

12. Для проверки, что всё сделано правильно

подключаемся к устройству по SSH через Ethernet:

Всем спасибо за внимание!

ссылка на оригинал статьи http://habrahabr.ru/post/264515/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *