понедельник, 13 июля 2015 г.

Сборка и установка ядра 4.4, u-boot, rootfs на BBB

У меня есть плата BBB rev. C element 14 (еMMC размером 4GB) с предустановленной ОС (debian 8). Купить ее можно на алиэкспресс за 3700 рублей или, например, здесь за 6000 рублей (цены актуальны на 10.08.2017). На рабочей машине у меня установлена ОС Ubuntu 16.04 amd64.

Питание платы BBB производится через USB. Подключение к BBB осуществляется либо по RS-232 через собранную на коленке плату-конвертор (подробнее), либо по USB (подробнее).
С рабочей машины под управлением Ubuntu 16.04 amd64 мы можем увидеть терминал следующим образом:

1) для RS232:

sudo screen /dev/ttyS0 115200,cs8

2) для USB:

sudo screen /dev/ttyUSB0 115200,cs8

Плата BBB подключена к локальной сети с действующим DHCP-сервером через коммутатор, к которому подключена рабочая машина. Дополнительно к плате я подключаю carpc-монитор с тачскрином либо через hdmi (примерно такой), либо через RGB-пины и дополнительную плату конвертирующую сигналы цифровые коды RGB в аналоговый VGA-сигнал (примерно такой).

Собирать ядро, u-boot и rootfs будем по следующей инструкции https://eewiki.net/display/linuxonarm/BeagleBone+Black (версия страницы 133).

1. Скачиваем кросскомпилятор отсюда, распаковываем и перемещаем в директорию /usr/local/tools/linaro-gnueabihf-5.3, настраиваем переменную окружения для сборки:

export CC=/usr/local/tools/linaro-5.3/bin/arm-linux-gnueabihf-

Проверить установленную переменную можно, выполнив echo $CC. Вывод должен соответствовать ( /usr/local/tools/linaro-5.3/bin/arm-linux-gnueabihf- ).

Для скачивания и сборки ядра, u-boot и rootfs нужна временная директория. Можно воспользоваться, как предложено в инструкции, домашней директорией(~), я же создам отдельную папку на общем диске (/media/Data/Kernel). 

2. Собираем U-boot. Переходим в папку, клонируем главную ветку репозитария, берем срез файлов коммита 2017.03-rc1скачиваем и применяем патчи, настраиваем сборку с помощью установленной переменной окружения $СС и собираем U-boot (после окончания сборки бинарник будет лежать в корне папки):

cd /media/Data/Kernel
git clone https://github.com/u-boot/u-boot
cd u-boot/
git checkout v2017.03-rc1 -b tmp

wget -c https://rcn-ee.com/repos/git/u-boot-patches/v2017.03-rc1/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
wget -c https://rcn-ee.com/repos/git/u-boot-patches/v2017.03-rc1/0002-U-Boot-BeagleBone-Cape-Manager.patch

patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
patch -p1 < 0002-U-Boot-BeagleBone-Cape-Manager.patch


make ARCH=arm CROSS_COMPILE=${CC} distclean
make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig
make ARCH=arm CROSS_COMPILE=${CC}


3. Собираем ядро. Переходим в нашу папку, клонируем ветку репозитария разработчика, берем срез файлов для ядра 4.4 с долгосрочной поддержкой (longterm) am33x-v4.4 и запускаем скрипт сборки build_kernel.sh:

cd /media/Data/Kernel
git clone https://github.com/RobertCNelson/bb-kernel

cd bb-kernel/
git checkout origin/am33x-v4.4 -b tmp
./build_kernel.sh

При сборке на этапе компилирования оверлеев девайстри у меня возникает ошибка "fatal error: dt-bindings/gpio/gpio.h: No such file or directory". Для того, чтобы пофиксить её надо создать символическую ссылку на папку с хедерами:

cd /media/Data/Kernel/bb-kernel/KERNEL/arch/arm/boot/dts/include/
ln -s ../../../../../include/dt-bindings .

4. Скачиваем rootfs с набором утилит для Debian 8:

cd /media/Data/Kernel
wget -c https://rcn-ee.com/rootfs/eewiki/minfs/debian-8.7-minimal-armhf-2017-01-14.tar.xz
tar xf debian-8.7-minimal-armhf-2017-01-14.tar.xz


5. Записываем все это на microsd-карту (можно взять microsd-карту размером от 2GB). Воспользуемся microsd-картридером или sd-картридером, предварительно вставим microsd-карту в sd-переходник. 

5.1. Вставим microsd-карту через переходник и удалим через gparted имеющиеся разделы. Выясним, выполнив команду lsblk, номер устройства, соответствующего вставленной microsd-карте (у меня это устройство /dev/sdb):

adil@adil:/media/Data/Kernel$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 931,5G  0 disk 
├─sda1   8:1    0   100M  0 part 
├─sda2   8:2    0 125,8G  0 part 
├─sda3   8:3    0  98,6G  0 part /
├─sda5   8:5    0   3,9G  0 part [SWAP]
├─sda6   8:6    0 683,6G  0 part /media/Data
└─sda7   8:7    0  19,5G  0 part 
sdb      8:16   1   3,7G  0 disk 
sr0     11:0    1  1024M  0 rom  

Определим вспомогательную переменную окружения для карты:

export DISK=/dev/sdb

5.2. Очистим карту и прошьем на неё бинарники u-boot:

sudo dd if=/dev/zero of=${DISK} bs=1M count=10
sudo dd if=./u-boot/MLO of=${DISK} count=1 seek=1 bs=128k
sudo dd if=./u-boot/u-boot.img of=${DISK} count=2 seek=1 bs=384k


5.3. Создадим раздел на карте при помощи утилиты sfdisk. Определим версию

adil@adil:/media/Data/Kernel$ sudo sfdisk --version
sfdisk из util-linux 2.27.1


У меня версия util-linux 2.27.1 - старше 2.26 (для версии младше 2.26 эта команда выглядит иначе):

sudo sfdisk ${DISK} <<-__EOF__
4M,,L,*
__EOF__


5.4. Создадим файловую систему с помощью утилиты mkfs.ext4. Определим версию:

adil@adil:/media/Data/Kernel$ sudo mkfs.ext4 -V
mke2fs 1.42.13 (17-May-2015)
Using EXT2FS Library version 1.42.13

У меня версия mkfs.ext4 1.42.13 (=1.42) и устройство /dev/sdX (для устройства  /dev/mmcblkX и старшей версии mkfs.ext4 следующие команды будут выглядеть иначе):

sudo mkfs.ext4 -L rootfs ${DISK}1

5.5. Создадим папку для монтирования и смонтируем microsd-карту (для устройства  /dev/mmcblkX следующие команды будут выглядеть иначе):

sudo mkdir -p /media/rootfs/
sudo mount ${DISK}1 /media/rootfs/

5.6. Сделаем backup файлов u-boot'а:

sudo mkdir -p /media/rootfs/opt/backup/uboot/
sudo cp -v ./u-boot/MLO /media/rootfs/opt/backup/uboot/
sudo cp -v ./u-boot/u-boot.img /media/rootfs/opt/backup/uboot/


5.7. Скопируем rootfs на примонтированный раздел карты:

sudo tar xfvp ./*-*-*-armhf-*/armhf-rootfs-*.tar -C /media/rootfs/

5.8. Установим вспомогательную переменную окружения для копирования ядра (версию ядра можно взять из вывода скрипта сборки ядра, у меня версия 4.4.47-bone16):

export kernel_version=4.4.47-bone16

5.9. Установим вывод uname и скопируем бинарник ядра, device tree base и модули ядра:

Для отображения версии в uname:
sudo sh -c "echo 'uname_r=${kernel_version}' >> /media/rootfs/boot/uEnv.txt"

Для HDMI дисплея 640x480:
sudo sh -c "echo 'optargs="consoleblank=0" video=HDMI-A-1:640x480@75' >> /media/rootfs/boot/uEnv.txt"

sudo cp -v ./bb-kernel/deploy/${kernel_version}.zImage /media/rootfs/boot/vmlinuz-${kernel_version}

sudo mkdir -p /media/rootfs/boot/dtbs/${kernel_version}/
sudo tar xfv ./bb-kernel/deploy/${kernel_version}-dtbs.tar.gz -C /media/rootfs/boot/dtbs/${kernel_version}/

sudo tar xfv ./bb-kernel/deploy/${kernel_version}-modules.tar.gz -C /media/rootfs/

5.10. Сформируем файл монтируемых при загрузке разделов (/etc/fstab), добавив туда раздел встроенного eMMC:

sudo sh -c "echo '/dev/mmcblk0p1 / auto errors=remount-ro 0 1' >> /media/rootfs/etc/fstab"

5.11. Настроим сеть. Отредактируем файл /etc/network/interfaces:

sudo nano /media/rootfs/etc/network/interfaces

Добавим:

auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp

Для того, чтобы у нас был один сетевой интерфейс eth0, отредактируем файл  /etc/udev/rules.d/70-persistent-net.rules:

sudo nano /media/rootfs/etc/udev/rules.d/70-persistent-net.rules


Добавим:

# BeagleBone: net device ()
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"


5.12 (может вам это не нужно). Дадим возможность root-го доступа через ssh. Для этого отредактируем файл /etc/ssh/sshd_config:

sudo nano /media/rootfs/etc/ssh/sshd_config

Поменяем значение PermitRootLogin со значения without-password на yes.

5.13 (может вам это не нужно). Настроим доступ по RS-232. Создадим файл /etc/init/serial.conf:

sudo nano /media/rootfs/etc/init/serial.conf

Добавим:

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty 115200 ttyO0

6. Отмонтируем карту:

sync
sudo umount /media/rootfs


7. Загрузка BBB c нашей microsd-карты. Вставляем карту в BBB и, удерживая кнопку загрузки, подключаем к USB-разъему рабочей машины. Начинается загрузка с microsd-карты. После загрузки входим под пользователем debian пароль temppwd.

Если вы выполнили пункт 5.12, сейчас можно задать другой пароль для рута, выполнив:

sudo passwd root
7.1. Свой скрипт при загрузке. Если мы хотим, чтобы при загрузке BBB выполнялся наш скрипт (например, файл mystart.sh), нужно создать файл в папке /etc/init.d:

sudo nano /etc/init.d/mystart.sh

Например, со следующим содержимым:

#!/bin/sh
echo "My script started!"

Записываем файл и выполняем скрипт update-rc.d, который размещает ссылки на вызов нашего скрипта в системных папках запуска ядра в стиле SystemV:

sudo update-rc.d mystart.sh defaults

Даем скрипту права на исполнение:

sudo chmod +x mystart.sh

7.2. Скачаем из инета скрипт для записи содержимого microsd-карты на встроенную память eMMC и запустим:

wget https://raw.githubusercontent.com/RobertCNelson/boot-scripts/master/tools/eMMC/bbb-eMMC-flasher-eewiki-ext4.sh
chmod +x bbb-eMMC-flasher-eewiki-ext4.sh
sudo /bin/bash ./bbb-eMMC-flasher-eewiki-ext4.sh

После окончания прошивки вынимаем microsd-карту и загружаемся с eMMC, не нажимая кнопку загрузки.

7.3. Чтобы пересобрать ядро с изменениями в конфигурации или исходном коде, лучше запускать не скрипт build_kernel.sh, который коннектится к стабильной ветке репозитария kernel.org и скачивает fix'ы и обновления, а запустить ./tools/rebuild.sh :

cd /media/Data/Kernel/bb-kernel
./tools/rebuild.sh

После сборки надо заново залить измененные части ядра на установочную флешку (пункт 5.9), затем загрузиться с флешки (пункт 7) и перекинуть её содержимое на внутреннюю память eMMC (пункт 7.2).

Использованный материал:
1) https://eewiki.net/display/linuxonarm/BeagleBone+Black

Комментариев нет:

Отправить комментарий