Добрый день! Целью данной работы было расширение возможностей имеющейся платы от NAS WesternDigital MyBook Live.
По своим характеристикам данная плата очень не плоха:
Процессор: APM82181
Частота: 800 МГц
Платформа: PowerPC 44x
ОЗУ: 256 MB
ПЗУ: 512 КВ
Из интерфейсов в наличии SATA, сеть 100 Мбит/с, последовательный порт (UART, не распаян), место под отладочный разъем JTAG. На плате была этикетка с номером 4061-705086-003 REV. AH. На другой стороне вытравлен номер 4060-705086.
Содержание статьи:
1. Подключение консоли
2. Загрузка без диска
3. Компиляция в LEDE
4. Управление портами (через LuCI и консоль)
5. Подключение к шине I2C
6. Подключение расширителя портов PCF8574
Остальное в следующей части…
Дополнения и замечания приветствуются. Поехали!
1. Подключение консоли
Для работы с платой требуется локальное подключение консоли (хотя большинство операций после загрузки можно выполнять и через SSH). Делается это просто, в интернете достаточно информации, например вот WD MyBook Live UART Port.
Подключение делается к порту RS232 компьютера через переходник RS232-UART, т.к. на плате логические уровни в пределах 3.3В. Скорость по умолчанию 115200 бод.
U-Boot 2009.08-svn65645 (Oct 08 2012 - 14:36:50), Build: 0.2.5
CPU: AMCC PowerPC UNKNOWN (PVR=12c41c83) at 800 MHz (PLB=200, OPB=100, EBC=100 MHz)
Bootstrap Option E - Boot ROM Location NOR/SRAM (8 bits)
32 kB I-Cache 32 kB D-Cache
Board: Apollo-3G - APM82181 Board, 2*SATA, 1*USB
I2C: ready
DRAM: Auto calibration 256 MB
FLASH: 512 kB
DTT: 1 FAILED INIT
Net: PHY EC1 Register: 0x2c8c
ppc_4xx_eth0
Type run flash_nfs to mount root filesystem over NFS
Hit any key to stop autoboot: 0
Сообщение «Apollo-3G — APM82181 Board, 2*SATA, 1*USB» немного неверное, так как USB тут нет, а SATA всего один. Это связано видимо что загрузчик общий для MyBook Live и модели DUO с двумя дисками.
Если ничего не нажимать в консоли, то будет произведена попытка загрузки с жесткого диска. В нашем случае его нет, поэтому нажатием любой кнопки загрузка остановлена.
2. Загрузка без диска
В загрузчике u-boot много возможностей для работы с оборудованием.
ledtestoff
Тест трех цветов светодиода поочередно:
ledtest
Список команд можно увидеть набрав help. Подробнее о загрузчике можно узнать здесь. В консоли при загрузке видно, что u-boot предлагает вариант монтирования файловой системы nfs «Type run flash_nfs to mount root filesystem over NFS». В данном же случае мы будем пользоваться другим вариантом — загрузкой RAM-образа c TFTP-сервера.
На компьютере поднимается сервер, например TFTPD32 (Official site), затем настраиваем плату. Устанавливаем локальный IP адрес и адрес TFTP сервера (вашего компьютера). Они должны быть из одной подсети:
setenv ipaddr '192.168.1.1'
setenv serverip '192.168.1.10'
Посмотреть имена файлов, которые будут запрашиваться с TFTP-сервера:
=> printenv fdt_file bootfile
fdt_file=apollo3g.dtb
bootfile=uImage
Заметим, что в переменной fdt_file записано имя файла дерева устройств, а в bootfile — имя файла образа RAM-диска с операционной системой.
Имена можно поменять на более удобные аналогично адресам командой setenv. После настройки желательно сохранить новые значения переменных в ПЗУ:
=> saveenv
Saving Environment to Flash...
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash...
. done
Erased 1 sectors
Writing to Flash... done
Protected 1 sectors
Protected 1 sectors
Таким образом после перезагрузки или отключения питания настройки сохранятся. После этого размещаем два необходимых файла (если у вас их нет, то об их создании смотрите в следующем разделе) на TFTP-сервере и набираем команду run net_nfs.
Waiting for PHY auto negotiation to complete.. done
ENET Speed is 100 Mbps - FULL duplex connection (EMAC0)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.10; our IP address is 192.168.1.1
Filename 'uImage'.
Load address: 0x1000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#
done
Bytes transferred = 6680079 (65ee0f hex)
Using ppc_4xx_eth0 device
TFTP from server 192.168.1.10; our IP address is 192.168.1.1
Filename 'apollo3g.dtb'.
Load address: 0x1800000
Loading: ##
done
Bytes transferred = 16384 (4000 hex)
## Booting kernel from Legacy Image at 01000000 ...
Image Name: POWERPC LEDE Linux-4.4.21
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 6680015 Bytes = 6.4 MB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 01800000
Booting using the fdt blob at 0x1800000
Uncompressing Kernel Image ... OK
Loading Device Tree to 00ff9000, end 00ffffff ... OK
Как видно, в результате загружаются два файла. Они размещаются в заданных местах оперативной памяти, ядро распаковывается и загружается. В результате имеем рабочую систему, в данном случае LEDE:
root@lede: uname -a
Linux lede 4.4.21 #0 Fri Nov 18 03:27:44 UTC 2016 ppc GNU/Linux
3. Компиляция в LEDE
В качестве источника операционной системы для нашей платы будем использовать LEDE. Это форк OpenWRT и он поддерживает плату MyBook Live. Скачать можно здесь: apm82181-lede. Докачиваем пакеты, как написано в инструкции:
./scripts/feeds update -a
./scripts/feeds install -a
Запускаем конфигуратор:
make menuconfig
Выбираем в качестве системы («Target System») «AppliedMicro APM821xx», в качестве подсистемы («Subtarget») — «Devices which boot from SATA (NAS)», профиль («Target Profile») — «Western Digital My Book Live». Конечным образом («Target Images») должен обязательно быть отмечен ramdisk.
Пакеты выбираем по своему усмотрению. Сохранив настройки в конфигураторе и выйдя из него, можно запустить компиляцию командой make.
После окончания процесса, если он прошел без ошибок, необходимые файлы можно забрать и положить на TFTP-сервер:
- файл bin/targets/apm821xx/sata/lede-apm821xx-sata-MyBookLiveSingle-initramfs-kernel.bin переименовываем в uImage
- файл build_dir/target-powerpc_464fp_musl-1.1.15/linux-apm821xx_sata/tmp/lede-apm821xx-sata-MyBookLiveSingle-initramfs-kernel.bin.dtb переименовываем в apollo3g.dtb
Таким образом мы прошли этапы загрузки системы без диска.
4. Управление портами (через LuCI и консоль)
Найти в интернете схему данной платы и вообще схему любого устройства на базе процессора APM82181 мне не удалось. Поэтому будем выполнять частично реверс-инжиниринг (обратную разработку), то есть догадываться о соединениях на плате и проверять это. Разработчики LEDE видимо частично это сделали, потому что подключенные порты можно увидеть в дереве устройств или посмотреть информацию из ядра:
root@lede: cat /sys/kernel/debug/gpio
GPIOs 496-503, platform/4e0100000.gpio1, 4e0100000.gpio1:
gpio-498 ( |Reset button ) in hi
GPIOs 504-511, platform/4e0000000.gpio0, 4e0000000.gpio0:
gpio-504 ( |enable EMAC PHY ) out hi
gpio-505 ( |Enable Reset Button,) out lo
gpio-506 ( |Power USB Core ) out hi
gpio-507 ( |Power Drive Port 1 ) out hi
gpio-508 ( |? ) out lo
gpio-509 ( |? ) out hi
gpio-510 ( |? ) out lo
gpio-511 ( |Power Drive Port 0 ) out hi
Как видно, один порт используется для ввода нажатия кнопки, остальные на вывод для управления. Понятно, что редактируя файл дерева устройств (файл с расширением .dts) можно освободить от функций любой порт в операционной системе, но это может сказаться на работоспособности функциональных блоков платы. Разве что кроме светодиода. Порты, подключенные к этому индикатору, можно использовать в своих целях. Порты обозначенные знаком вопроса, как раз к нему и подключены. А управление светодиодом доступно, например, из консоли.
По умолчанию после загрузки LEDE индикатор горит зеленым цветом. Вот так его можно выключить:
echo 0 > /sys/class/leds/mbl:green:power/brightness
И включить синий:
echo 1 > /sys/class/leds/mbl:blue:power/brightness
Если LEDE собиралась с веб-оболочкой LuCI, то светодиодами можно управлять из браузера.
В меню System заходим в LED Configuration, и настраиваем на какие события срабатывает каждый конкретный цвет светодиода. Например вот так зеленый светодиод будет мигать на приходящие и уходящие сетевые пакеты:
Понятно, что если использовать порты светодиода для своих нужд, то сервис, управляющий светодиодом (/etc/init.d/led) будет не нужен и драйвер тоже. А управление можно сделать из скрипта например так:
echo 1 > /sys/class/gpio/gpio508/value
5. Подключение к шине I2C
Итак, имеется возможность использовать как минимум три порта. Хотелось бы конечно иметь больше ресурсов. Можно поставить на эти порты расширитель портов, подключить его к программному порту I2C. Тогда можно набрать практически неограниченное количество портов, правда с невысоким быстродействием.
На плате имелось некоторое количество пустых посадочных мест, появилось желание проверить может на них что-то разведено, что может нам пригодиться.
Например вблизи процессора посадочное место, маркированное U12 для чипа с 8-ю ногами:
Убедившись что на всех контактах не более 3.3В, был подключен цифровой анализатор.
В процессе загрузки ОС никаких сигналов обнаружено не было. Тогда в дерево устройств было добавлено описание шины I2C, так как изначально она отсутствовала:
IIC0: i2c@ef600700 {
compatible = "ibm,iic";
reg = <0xef600700 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
fast-mode;
#address-cells = <1>;
#size-cells = <0>;
};
Понятно, что в конфигурации LEDE тоже необходимо включить поддержку I2C в ядре (kmod-i2c-core).
После компиляции, обновления файла на сервере TFTP и перезагрузки появилось устройство /dev/i2c-0.
root@lede: dmesg | grep i2c
[ 4.816060] i2c /dev entries driver
[ 4.819878] ibm-iic 4ef600700.i2c: using standard (100 kHz) mode
Отправляя символы командой echo:
root@lede: echo 11 > /dev/i2c-0
ash: write error: Remote I/O error
Таким образом обнаружена аппаратная шина I2C, что сильно расширило возможности ввода-вывода данной платы.
Судя по расположению сигналов на U12 (5 — GND, 7 — SDA, 8 — SCL), это возможно предполагался ADM1032ARMZ — датчик температуры.
6. Подключение расширителя портов PCF8574
Пришло время подключить что-либо на шину I2C. В запасах нашелся жидкокристаллический индикатор размерностью 2х16 знакомест, каждое 8х5 пикселов. Сделан в Китае на основе клона контроллера HD44780 и расширителя портов PCF8574.
По описанию допускает питание и уровни сигналов как 5 так и 3.3В, но при проверке была обнаружена очень низкая контрастность изображения при питании 3.3В. Так как питание 5В привело бы и к уровням сигналов от 0 до 5 В, а плата рассчитана на 3.3, то пришлось сделать примитивный преобразователь уровней сигналов. Шина I2C двунаправленная, от устройства должен приходить сигнал подтверждения, поэтому как минимум на линии SDA должен быть двунаправленный преобразователь. Очень хорошо варианты схем описаны здесь: Согласование логических уровней 5В и 3.3В устройств. В нашем случае была использована
Правда транзистор другой, подобран из аналогичных — BSS123.
Таким образом, на ЖКИ индикатор подано питание 5В (взято на плате с разъема питания SATA), на преобразователь уровня приходят оба питания — 3.3 и 5В.
Теперь добавим в LEDE расширитель портов. Включаем поддержку в ядре (Kernel modules — Other modules — kmod-gpio-pcf857x… PCX857x, PCA967x and MAX732X I2C GPIO expanders), перекомпилируем, заливаем на сервер, перезагружаемся.
Смотрим наличие драйвера:
root@lede: lsmod |grep pcf
gpio_pcf857x 6128 0
Подключаем (0x27 — адрес нашего расширителя на шине I2C):
root@lede: echo pcf8574 0x27 > /sys/bus/i2c/devices/i2c-0/new_device
[ 218.957888] pcf857x 0-0027: probed
[ 218.961321] i2c i2c-0: new_device: Instantiated device pcf8574 at 0x27
Проверяем появление портов:
root@lede: ls -l /sys/class/gpio/
--w------- 1 root root 4096 Jan 1 1970 export
lrwxrwxrwx 1 root root 0 Nov 25 04:04 gpiochip488 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpiochip488
lrwxrwxrwx 1 root root 0 Jan 1 1970 gpiochip496 -> ../../devices_platform/plb/plb:opb/4e0100000.gpio1/gpio/gpiochip496
lrwxrwxrwx 1 root root 0 Jan 1 1970 gpiochip504 -> ../../devices/platform/plb/plb:opb/4e0000000.gpio0/gpio/gpiochip504
--w------- 1 root root 4096 Jan 1 1970 unexport
Как видно, появилась группа портов gpiochip488 на шине I2C с адресом 0x27. Сейчас можно добавить порты, которые будут также представлены системой, как и расположенные на процессоре, несмотря на то, что они работают через расширитель портов:
root@lede: echo 488 > /sys/class/gpio/export
root@lede: echo 489 > /sys/class/gpio/export
root@lede: echo 490 > /sys/class/gpio/export
root@lede: echo 491 > /sys/class/gpio/export
… и так до 495, так как у нас 8-и портовый расширитель в наличии. Проверим их наличие:
root@lede: ls -l /sys/class/gpio/gpio???
lrwxrwxrwx 1 root root 0 Nov 25 04:17 /sys/class/gpio/gpio488 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio488
lrwxrwxrwx 1 root root 0 Nov 25 04:17 /sys/class/gpio/gpio489 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio489
lrwxrwxrwx 1 root root 0 Nov 25 04:17 /sys/class/gpio/gpio490 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio490
lrwxrwxrwx 1 root root 0 Nov 25 04:17 /sys/class/gpio/gpio491 -> ../../devices/platform/plb/plb:opb/4ef600700.i2c/i2c-0/0-0027/gpio/gpio491
Зададим направление работы на вывод:
root@lede: echo out > /sys/class/gpio/gpio488/direction
root@lede: echo out > /sys/class/gpio/gpio489/direction
root@lede: echo out > /sys/class/gpio/gpio490/direction
root@lede: echo out > /sys/class/gpio/gpio491/direction
Если надо на ввод, то надо дать команду «in». Ну и проверить как работает вывод, например измеряя состояние выхода тестером или цифровым анализатором. В случае подключенного к расширителю ЖКИ HD447880 можно воспользоваться тем что третий бит расширителя управляет подсветкой индикатора:
root@lede: echo 1 > /sys/class/gpio/gpio491/value
root@lede: echo 0 > /sys/class/gpio/gpio491/value
Первая команда включает подсветку, вторая ее выключает. Чтобы устройства добавлялись в процессе загрузки можно включить их в дерево устройств:
IIC0: i2c@ef600700 {
compatible = "ibm,iic";
reg = <0xef600700 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
fast-mode;
#address-cells = <1>;
#size-cells = <0>;
/* Boot ROM is at 0x52-0x53, do not touch */
/* Unknown chip at 0x6e, not sure what it is */
i2cled: led@27{
#gpio-cells = <2>;
compatible = "nxp,pcf8574";
reg = <0x27>;
gpio-controller;
};
};
Строки после метки i2cled заменяют команду «echo pcf8574 0x27 > /sys/bus/i2c/devices/i2c-0/new_device».
Итак, появилась и реализована на практике возможность прозрачно использовать порты ввода-вывода, подключенные через расширитель к шине I2C.
Для первой части, наверное, достаточно. Во второй части, если конечно не будет явного антагонизма в комментариях, дойдем до использования индикатора для отображения состояния системы:
Для этого был использован и доработан драйвер HD44780. Подключен пакет LCD4Linux, в котором также был написан новый драйвер дисплея, управляющий дисплеем командами терминала VT100, потому что существующие драйверы не подошли.
Автор: sergey2ru