Первую часть можно почитать здесь.
Устанавливаем на разные носители, собираем ядро и т.п.
Установка на NAND.
Казалось бы — всё описано в доке, запускаешь sudo cubian-nandinstall (возможно, предварительно его установив через sudo apt-get install cubian-nandinstall), перезагружаешься и ещё раз запускаешь. Неспешно пьёшь кофе и, вынув флешку с cubian,
запускаешь Кубик...А! Оп-паньки! Только RS232 консоль, да и в той ругань, что не найден /boot/script.bin и иже с ним.
Горестно запускаемся снова с флешки и изучаем что у нас с NAND-ом. А он разбит на 3 раздела, один из которых — пустое место. Гугление приводит нас к выводу, что на загрузочном разделе NAND-а вовсе не то, что там должно располагаться.
- Восстанавливаем "убитый" NAND, как было описано в предыдущей части (я использовал образ lubuntu-server-nand-vga.img версии 1.02). Запускаем и убеждаемся, что всё заработало.
- Выполняем "магические команды", прямо из запущенного lubuntu-server:
Первая команда переразбивает логические разделы NAND. Как ни странно, данные при этом не теряются. Вторая команда проверяет файловую систему на ошибки — её попросит выполнить третья. Третья же отдаёт второму разделу всё свободное место. Секретные цифры первой команды не что иное, как указание начала разделов и их размеры. Смещение и размер раздела 'boot' надо оставить как есть, а раздел 'rootfs' вычисляется из общего числа секторов на /dev/nand минус смещение и 'boot'. Говорят, его можно указать и сильно больше — урежется автоматически. Не пробовал.$ sudo nand-part -f a20 /dev/nand 32768 'boot 131072' 'rootfs 14778368' $ sudo reboot ... $ sudo e2fsck -f /dev/nandb $ sudo resize2fs /dev/nandb
- Лезем в /etc/fstab и убеждаемся, что корневой раздел монтируется на /dev/nandb с флагами relatime,discard,errors=remount-ro. Если нет — правим.
- Перезагружаемся и проверяем, что всё работает, а под раздел / выделено всё доступное место — порядка 7Гб:
$ sudo fdisk -hBM Filesystem 1M-blocks Used Available Use% Mounted on ... /dev/nandb 7152M 1470M 5356M 22% /mnt/nandb /dev/nanda 128M 16M 113M 13% /mnt/nanda
- Сохраняем куда-нибудь наш загрузочный раздел, чтобы можно было потом восстановить только его:
$sudo dd if=/dev/nanda conv=sync,noerror bs=1024 count=65536 |gzip -c -9 >nanda.img.gz $sudo dd if=/dev/nand conv=sync,noerror bs=1024 count=16384 |gzip -c -9 > nand-boot.img.gz
- Распаковываем образ cubian-base-xxx на флешку с cubian (потребуется порядка 1Гб места)
- Загружаемся с флешки, очищаем корневой раздел nandb, монтируем образ и копируем его на NAND:
$ sudo mkfs.ext4 /dev/nandb $ mkdir tmp $ sudo mount -o loop,offset=1048576 -t ext4 cubian-base-r5-a20-ct.img tmp $ mkdir r $ sudo mount /dev/nandb r $ sudo rsync -HEAhav --numeric-ids tmp/* r $ sudo umount r $ sudo mount /dev/nanda r & cd r $ sudo for F in {script.bin,uEnv.txt,uImage}; do cp $F $F.old; done $ cd .. $ sudo cp tmp/{script.bin,uEnv.txt,uImage} r $ nano r/uEnv.txt -> edit/add: rootfstype=ext4 rootfsflags=discard -> (?) edit/del: строки с EDID -> edit: nand_root=/dev/nandb -> edit/add: mac_addr=c0:b0:01:02:03:04
- Последняя строчка это один из способов задать фиксированный MAC адрес сетевой карты
- Выключаем Cubietruck, вынимаем флешку и проверяем, что всё заработало
Разворачивание на HDD
Для тестов и сбережения времени и ресура флеша (на время тестов) установим систему на внешний SATA диск.
Действия аналогичны вышеописанному копированию на NAND, за исключением того, что в uEnv.txt надо написать nand_root=/dev/sda1
Замечена закономерность: если в выключенный cubietruck воткнуть uSD карточку, то при включении может пойти с SATA. Для запуска же с карточки надо перезагрузиться не выключая питания (или даже кнопкой reset)
До-настройка сетевой карты
Поскольку в Кубике используется дешёвая сетевая карта, не умеющая хранить свой MAC, это приводит к неудобству с DHCP серверами и прочим железом. Аналогично себя ведут большинство китайских андроидо-фонов, меняющих MAC после перезагрузки.Способов лечения несколько:
- Правка config.fex с добавлением раздела (не заработало с гигабитной картой):
[dynamic] MAC="010203040506"
- Вроде бы "кошерный" — передачей параметров ядру. В uEnv.txt добавить параметр вида mac_addr=01:02:03:04:05:06
- В cubian встроен сервис, устанавливающий MAC при загрузке. MAC хранится в /root/.cubian-emac, и создаётся со случайным адресом вида c0:b0:xx:xx:xx:xx, если его там не было. У меня как-то через раз срабатывает, судя по логам загрузки
- Вручную добавить настройки в /etc/network/interfaces примерно так:
auto eth0 iface eth0 inet dhcp hwaddress ether c0:b0:01:02:03:04
## /etc/sysctl.conf
# -- TUNE Gigabit Ethernet --
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 0
net.core.wmem_max = 8388608
net.core.wmem_default = 131072
net.core.rmem_default = 131072
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_mem = 98304 131072 196608
# -- DISABLE IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
Дополнительно в /etc/rc.local добавляется строчка "ifconfig eth0 txqueuelen 5000"
UPD: По результатам простого теста эти "оптимизации" ухудшают картику: если тормозная samba с ними даёт 17.4Мб/с при копировании 1.5Гб файла, то без них получается 21.4 Мб/с. Отключаем опции в sysctl.conf и продолжаем тестирование...
UPD2: Если вы готовы мириться с зависаниями клиентов при отключении NFS-шары, то лучше обойтись без samba-ы: разница в скорости — вдвое: 21.4Мб/с у samba против 41.6Мб/с у NFS4.
Копируем HDD на NAND.
Наигравшись и настроив всё, как хотелось, переносим готовую систему на NAND.- Загружаемся с SD карты. предполагается, что cubian-nandinstall установлен (он нужен только для файла исключений, содержимое которого приведено ниже и может быть просто создано где-нибудь)
- Выполняем:
$ sudo mount /dev/nandb /mnt/nandb $ sudo mount /dev/sda1 mnt/sda $ cd /usr/lib/cubian-nandinstall $ sudo rsync -HEAXahv --numeric-ids --exclude-from=exclude.txt --delete --delete-excluded /mnt/sda/* /mnt/nandb $ sudo mount /dev/nanda /mnt/nanda $ sudo nano /mnt/nanda/uEnv.txt -> edit nand_root=/dev/nandb
- Содержимое exclude.txt:
/home/cubie/* /boot/* /dev/* /proc/* /sys/* /media/* /mnt/* /run/* /tmp/*
Собираем своё ядро с блэкдж... дополнительными модулями
Поскольку одной из целей покупки сего девайса было использование его с самой разной периферией, первое что я попытался сделать — подключить радио модуль NRF24L01 дабы читать показания всяких температур и прочих влажностей с уже готового прототипа передатчика.Тут меня ждал немалый облом — оказывается, ни в одном из готовых ядер нет поддержки шины SPI для Cubietruck.
Для начала было решено собрать своё ядро, включив этот модуль. Позже выяснилось, что просто так это работать не будет и надо внести некоторые изменения в конфиги чтобы получить желаемое (см. http://docs.cubieboard.org/tutorials/dvk521/documentations/a20/driver_porting_and_configuration).
Итоговая последовательность действий примерно такая:
- Готовим среду кросс-компиляции на PC:
$ sudo apt-get install arm-gcc-gnueabihf u-boot-tools $ sudo apt-get install libgtk2.0-dev libglib2.0-dev libglade2-dev
- Качаем ядро (я брал 3.4.79 от patwood) и дополнительый файл с поддержкой SPI:
$ git clone git@github.com:patrickhwood/linux-sunxi.git $ cd linux-sunxi/drivers/spi $ wget -nc http://dl.cubieboard.org/parteners/waveshare/Source_Code/a20-cubieboard-dvk/driver%20source/spi-sun7i.c
- Правим drivers/spi/Makefile (добавить строку):
+ obj-$(CONFIG_SPI_SUN7I) += spi-sun7i.o
- Правим drivers/spi/Kconfig. Добавляем где-то после проеверки "IF SPI":
config SPI_SUN7I tristate "SUN7I SPI Controller" depends on ARCH_SUN7I help Allwinner Soc SPI controller,present on SUN7I chips. config SUN7I_SPI_NDMA bool "SUN7I SPI Normal DMA mode select" depends on SPI_SUN7I help This selects SPI DMA mode with DMA transfer Y select NDMA mode and N select DDMA mode
- Загружаемся в Cubietruck и сохраняем на PC файл /proc/config.gz.
- Распаковываем его в ядро и начинаем конфигурировать систему:
$ gunzip -c config.gz > linux-sunxi/.config $ make ARCH=arm SUBARCH=mach-sun7i gconfig
- Включаем поддержку SPI как модуль. Должка получиться примерно такая картинка (SUN7I включены как модули):
Device Drivers ---> [*] SPI support ---> <*> SUN7I SPI Controller [*] SUN7I SPI Normal DMA mode select <*> DesignWare SPI controller core support <*> User mode SPI device driver support
- Исправляем ещё, что захочется. Например, добавляем поддержку 1-wire или отключаем ненужные модули. Не стоит отключать поддержку CSI если будет подключён VGA дисплей. Желательно отключить отладочные символы в ядре (Compile the kernel with debug info (DEBUG_INFO)) это сэкономит порядка 300Мб места и, наверняка, несколько ускорит работу.
- Говорят, следующая опция ощутимо ускоряет сеть. У меня не помогло. В gconfig:
- Device Drivers
- Network Device Support
- Ethernet Driver Support
- Select DMA for TX/RX [...] modes
- Ring Mode переключить на Chained Mode
- Сохраняемся и выходим из конфигуратора
- Собираем ядро, модули и заголовочные файлы:
$ make ARCH=arm SUBARCH=mach-sun7i CROSS_COMPILE=arm-linux-gnueabihf -j4 uImage modules $ make ARCH=arm SUBARCH=mach-sun7i CROSS_COMPILE=arm-linux-gnueabihf INSTALL_MOD_PATH=output modules_install $ make ARCH=arm SUBARCH=mach-sun7i CROSS_COMPILE=arm-linux-gnueabihf INSTALL_HDR_PATH=output/usr headers_install $ cp arch/arm/boot/uImage output
- Переносим содержимое output на Кубик. Папки модулей заменяем целиком, стирая предыдущее содержимое, заголовки перезаписываем измененное, uImage копируем на загрузочный раздел (/dev/nanda). Всё это можно проделывать прямо на загруженном cubietruck, главное — сделать изменения и в /lib и заменить uImage до перезагрузки чтобы версии ядра и модулей совпадали.
- Не помешает установить правильного владельца на файлы модулей:
$ sudo chown -R root:root /lib/{modules,firmware}
- Перезагружаем Cubietruck. Если не накосячили с выбором модулей, всё будет работать. Если нет — смотреть информацию в терминале и анализировать.
- Замечание по пересборке. После выполнения make clean или make mrproper для очистки перед пересборкой ядра будут удалены файлы firmware/ap6210, которые нужны для сборки wifi/bluetooth. Временное решение — скопировать их заранее куда-нибудь и восстанавливать перед сборкой или выполнить команды:
которая восстановит "всё как было". В противном случае сборка будет неудачна с руганью на broadcomm$ cd firmware/ap6210 $ git checkout -- *
- Замечания по Hardware monitor. Если возникает ошибка/предупреждение про hwmon_axp — проверить чтобы оба параметра AXP_HWMON и HWMON были включены в ядро ("Y")
SPI
- Правим /dev/nanda/script.fex для включения SPI:
$ cd /mnt/nanda $ sudo bin2fex script.bin script.fex $ sudo nano script.fex
[spi2_para] spi_used = 1 # ... [spi_devices] spi_dev_num = 1 [spi_board_0] modalias = "spidev" max_speed_hz = 8000000 bus_num = 2 chip_select = 0 mode = 0 full_duplex = 1 manual_cs = 0
$ fex2bin script.fex script.bin
- Создаём правило для юзера в /udev/rules.d и перезагружаемся:
KERNEL=="spidev*", MODE="0660", GROUP="gpio"
- Перезагружаемся
- Качаем spidev_test.c, правим (по желанию) устройство по-умолчанию на /dev/spidev2.0, компилим (gcc spidev_test.c).
- Замыкаем MISO и MOSI пины (6, 8 в данном случае)
- запускаем ./a.out:
root@Truck:~# ./a.out spi mode: 0 bits per word: 8 max speed: 500000 Hz (500 KHz) FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF DE AD BE EF BA AD F0 0D
- Если тестовая программа test_spi.c не собирается или вылетает с внутренней ошибкой — смотреть содержимое /usr/include/linux/spi/spidev.h: в оригинальном ядре пропущен один из элементов структуры. Если устанавливали заголовочные файлы, то это уже должно быть поправлено, но проверить:
struct spi_ioc_transfer { __u64 tx_buf; __u64 rx_buf; __u32 len; __u32 speed_hz; __u16 delay_usecs; __u16 interbyte_usecs; // !!! вот это пропущено в оригинале __u8 bits_per_word; __u8 cs_change; __u32 pad; }
1-Wire
В железе
Поскольку входы у Cubietruck трёхвольтовые, для тех сенсоров, что не могут работать от 3.3В придётся городить преобразователь уровней. Для традиционных датчиков температуры DS18B20 и расширителей входов/выходов DS2804 3.3В вполне достаточно, поэтому можно обойтись просто питанием 3.3В на датчики (желательно через самовосстанавливающийся предохранитель на, например, 0.1А) с подтяжкой к тем же 3.3В резистором порядка 4.7кОм.В ядре
Включаем поддержку 1-wire (Device Drivers/Dallas's 1-wire support), там же выбираем все под-опции со словом sunxi, GPIO 1-w busmaster и 1-wire Slaves для тех чипов, что будем использовать (DS18x20 - 1w_thermal).В script.fex
- добавляем в раздел [gpio_para] пин, через который пойдёт 1-wire
- добавляем новый раздел [w1_para], где gpio — номер пина из предыдущего пункта:
[w1_para] gpio = 12
- перекомпилируем .fex (fex2bin)
В системе
Сначала проверяем через modprobe, если заработало — добавляем в /etc/modules:
gpio_sunxi
#...
w1_gpio
w1_therm
Результатом будет появление в /sys/bus/w1/devices наших датчиков (как код датчика и MAC адрес)
Прочитать значение можно, например, подобной командой (самый быстрый вариант по мотивам обсуждения в на Хабре и реальным тестам):
awk -F "=" '/t=/{printf("%0.1f", $2/1000);} /sys/bus/w1/devices/28-000001020304'
NFS4 Server
На сервере
$ sudo apt-get install nfs-kernel-server
$ sudo mkdir /srv/{homes,data}
$ echo "/home /srv/export/homes none bind 0 0" | sudo tee -a /etc/fstab
$ echo "/mnt/data /srv/export/data none bind 0 0" | sudo tee -a /etc/fstab
$ sudo -i
cubie password:
# echo cat >>/etc/exports <<EOL
# -- Note: no spaces between address and options !!!
/srv/export 10.0.0.0/24(rw,fsid=0,no_subtree_check,sync)
/srv/export/homes 10.0.0.0/24(rw,nohide,insecure,no_subtree_check,sync)
/srv/export/data 10.0.0.0/24(rw,nohide,insecure,no_subtree_check,sync)
EOL
# exportfs -ar || service nfs-kernel-server restart
На клиентах
$ sudo apt-get install nfs-common
$ sudo mkdir /mnt/x
$ sudo mount -t nfs4 -o proto=tcp,port=2049 cubie-ip:/homes /mnt/x
Тюнинг
$ sudo apt-get install hdparm smartmontools
$ sudo hdparm -S 255 -k 1 /dev/sda (standby after 21min 15sec)
$ smartctl -i -n standby /dev/sda && do-somethign-if-hdd-not-sleep
Логи в память с синхронизацией при выключении или по расписанию.
$ sudo dpkg -i ramlog_2.0.0.deb
Исправляем "INIT INFO" в /etc/init.d/ramlog. Добавляем записи X-Start-Before и X-Stop-After и запускаем sudo insserv -v ramlog для применения изменений:
### BEGIN INIT INFO
# Provides: ramlog
# Required-Start:
# Should-Start: $local_fs
# Required-Stop:
# X-Stop-After: rsyslog console-k
# X-Start-before: rsyslog console-k
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: moves /var/log into ramdisk
# Description: ramlog daemon moves /var/log to ramdisk on startup and copies it back to harddrive on shutdown or restart
### END INIT INFO
Если /var/log лежит на HDD, можно добавить хитрое условие в /etc/cron.hourly:
- Копируем /etc/cron.daily/ramlog в /etc/cron.hourly
- Исправляем строку запуска:
Что не даст ежечасно будить диск, если он заснул.smartctl -i -n standby /dev/sda 2>&1 >/dev/null && /etc/init.d/ramlog restart
Комментариев нет:
Отправить комментарий