Введение
Рис. 1. Linksys NSLU2.
Нас заинтересовало сетевое хранилище, которое недавно побывало в нашей лаборатории, - Linksys NSLU2. Компактный корпус, бесшумная работа, низкая цена и все необходимые функции по сетевому хранению и резервированию файлов - чего ещё может желать пользователь?
К сожалению, согласно документации, устройство может работать только с клиентами под управлением Microsoft Windows, и, кроме того, использует собственную файловую систему.
Подсоединив внешний жёсткий диск, мы вышли в web-интерфейс NSLU2 с помощью браузера и настроили устройство. Вопреки документации Linksys, сетевое хранилище можно использовать и с системами под управлением MacOS X и Linux, поскольку обе они поддерживают протокол Microsoft SMB. Но это было только начало.
Дело в том, что внутри этой маленькой коробочки работает Linux - а раз так, то можно по максимуму использовать весь потенциал NSLU2. Устройство с двумя портами Hi-Speed USB и портом 10/100, определённо, способно на большее. Как насчёт NFS? Или сервера печати?
Переходник с USB на последовательный порт позволит автоматизировать некоторые домашние функции. Сетевая карта USB преобразует NSLU2 в маршрутизатор, а беспроводная карта USB 802.11b/g - в беспроводную точку доступа. Возможность полноценной работы с портами USB позволит открыть новые горизонты использования устройства, осталось только узнать, как это сделать.
Предупреждение. Исследование NSLU2 через просмотр внутренней структуры файлов любым способом, который не изменяет код, не повлечёт за собой лишение гарантии. Однако любое изменение структуры автоматически лишает гарантии.
Сайт Tom's Hardware Guide Russia и авторы не несут ответственности за повреждение оборудования. Вы используете приведённые ниже инструкции на свой страх и риск.
Перед тем, как начинать, советуем скачать последнюю прошивку. И не пытайтесь обращаться в службу поддержки Linksys, если что-то пойдёт не так.
"Потайная дверь"
Сканирование портов не показало ничего интересного. Просмотр всех стандартных меню также оказался бесплоден.
Стандартным способом входа в такие устройства являются "потайные двери" (back door). Разработчикам они нужны для контроля параметров системы при её настройке и тестировании. Иногда для этого требуется специальное оборудование, но в ряде случаев разработчики пользуются тем же сетевым интерфейсом.
Первое, с чего стоит начать, - web-интерфейс. Мы заметили, что страницы администрирования находятся в папке "Management". Мы знаем, что web-серверы иногда позволяют просматривать содержимое каталога, поэтому мы решили перейти по адресу http://192.168.3.77/Management/. Сработало! Мы увидели все файлы этого каталога.
Примечание. Возможность просмотра каталогов была устранена в прошивке V2.3R25 NSLU2.
Среди множества картинок и html-файлов мы смогли обнаружить telnet.cgi. Потенциальная точка входа найдена! После запуска скрипта мы увидели следующий экран.
Рис. 2. Экран включения Telnet.
Посмотрев на предупреждение, мы нажали на кнопку "Enable Telnet". Страница обновилась, и мы увидели сообщение о том, что Telnet активирован! Переходим к следующему этапу.
Получаем доступ к Telnet
В окне терминала мы попробовали использовать учётную запись, заданную при настройке NSLU2.
# telnet 192.168.1.70 Trying 192.168.1.70... Connected to 192.168.1.70. Escape character is '^]'.
NSLU2 login: tom Password: No directory, logging in with HOME=/ Cannot execute /dev/null: Permission denied Connection closed by foreign host. |
Близко, но не то, что требовалось. Сервер Telnet работал, имя и пароль были приняты, но каталог по умолчанию учётной записи оказался /dev/null. Тем не менее, это уже говорит о том, что учётные записи, заданные через web-интерфейс, являются учётными записями Linux, но их права ограничены. Это традиционный подход, когда пользователи могут работать со службами, но не могут выполнять вход в систему.
Мы попробовали выполнить вход под именем root (стандартная учётная запись в Linux), но не удалось - пароль был неизвестен и не был из серии простейших (admin, root и другие). Настало время взглянуть на проблему под другим углом.
В документации Linksys утверждалось, что жёсткий диск, инициализированный NSLU2, может использоваться только с паре с устройством. Мы решили это проверить. Файловая система - достаточно сложная штука, и вряд ли Linksys создала для NSLU2 новую. Многие источники указывали на то, что в NSLU2 используется файловая система Linux ext3 (это, кстати, подтвердил представитель Linksys), но никто не пытался её подключить.
Конечно, можно было подключить диск к системе Mandrake Linux, но мы скачали драйверы ext2 (подмножество ext3) для MacOs X iBook и подключили диск к порту USB.
Совет.Драйверы для Mac OS X ext2 можно скачать с сайта ext2 for Mac OS X SourceForge. Там же можно найти драйвер чтения ext2 для Windows NT/2000/XP, который использовался для того, чтобы создать скриншот, показанный на Рис. 3.
Мы увидели два раздела: большой с нашими данными и маленький с файлами конфигурации, включая passwd.
Рис. 3. Файлы конфигурации.
Как мы и ожидали, в файле passwd содержались сведения о созданных нами учётных записях с каталогом по умолчанию /dev/null. Но там же мы увидели ещё две нормальные учётные записи: root и весьма интересную - ourtelnetrescueuser, которая нам показалась именно тем, что нужно, то есть учётной записью для отладки и восстановления.
root:WeeOvKUvbQ6nI:0:0:root:/root:/bin/sh bin:x:1:1:bin:/bin: lp:x:4:7:lp:/share/spool: mail:x:8:12:mail:/var/spool/mail: ftp:x:14:50:FTP User:/: nobody:x:99:99:Nobody:/: ourtelnetrescueuser:scFf7ZMXBMl4I:100:100::/home/user:/bin/sh guest:scEPG0VnVyqmE:501:501:::/dev/null admin:sclzZZfodiRXY:502:501::/home/user/admin:/dev/null
test_user:scEPG0VnVyqmE:2000:501:::/dev/null test2:scEPG0VnVyqmE:2001:501:::/dev/null test3:sc50wKPq.zChw:2002:501:::/dev/null |
Конечно, для того, чтобы воспользоваться ими, необходимо знать пароли. Мы решили не заниматься взломом, а просто отредактировать файл passwd, заменив зашифрованный хэш одним из созданных нами! Можно было также добавить оболочку к нашим учётным записям, но мы решили просто задать новый пароль для администратора, а всё остальное оставить, как есть.
Как успехи?
При перезагрузке устройства мы опасались, что внесённые изменения будут перезаписаны, или сработает какая-либо защита. NSLU2 мог бы отказаться подключать диск или, к примеру, переформатировать его.
Но, всё прошло гладко, и мы услышали звуковой сигнал, сообщивший о том, что система готова к работе. После активации Telnet, мы попытались выполнить следующий вход:
# telnet 192.168.1.70
Trying 192.168.1.70... Connected to 192.168.1.70. Escape character is '^]'.
NSLU2 login: root Password: No directory, logging in with HOME=/
BusyBox v0.60.4 (2004.07.01-03:05+0000) Built-in shell (ash) Enter 'help' for a list of built-in commands.
# |
Готово! Мы получили командную строку, что полностью раскрыло перед нами устройство. Теперь можно расширить набор функций. Поскольку NSLU2 использует жёсткий диск, то можно создавать собственные сценарии, файлы и устанавливать необходимые драйверы.
Добавляем поддержку NFS
Поскольку устройство работает под управлением одной из версий ОС Linux, то для него можно найти множество дополнительных модулей, которые можно установить и использовать. Можно расширить возможности до полноценного web-, ftp-сервера или сервера secure shell - для замены Telnet. Но в первую очередь мы решили установить поддержку другой сетевой файловой системы.
Изначально NSLU2 поддерживает только SMB - протокол сетевой файловой системы Microsoft Windows. Поскольку наша сеть состоит, в большей степени, из UNIX-машин, таких как Apple Mac OS X и Linux, мы решили установить поддержку NFS - сетевой файловой системы UNIX.
Однако перед тем, как начать установку, необходимо преодолеть несколько трудностей. Первое - это установить инструментарий разработчика, так как мы должны скомпилировать необходимые модули. Будем считать, что вы уже включили Telnet на NSLU2.
Определение процессора
Использовать Linux для разработки программного обеспечения под другую операционную систему Linux вполне естественно, поэтому мы остановились на Mandrake. В отличие от большинства ОС Linux, NSLU2 не использует ядро x86, поэтому нам необходимо установить инструментарий для межплатформенной компиляции.
Первое, что нужно сделать в его настройке, - определить процессор, для которого будет выполняться компиляция. Согласно полученной информации, в NSLU2 используется процессор Intel IXP420.
Теперь мы можем войти в систему, а значит можем узнать текущий процессор. Для этого обратимся к файлу /proc/cpuinfo.
# cat /proc/cpuinfo Processor: XScale-IXP425/IXC1100 rev 1 (v5b) BogoMIPS: 131.48 Features: swp half thumb fastmult edsp Hardware: Intel IXDP425 Development Platform Revision: 0000 Serial: 0000000000000000 |
Ничего особого нового мы не узнали - лишь подтвердили, что в NSLU2 используется процессор IXP425. Для дальнейшей работы нужно использовать другой подход. Воспользуемся утилитой file, которая изучает файл и сообщает, к чему он относится.
На NSLU2 нет утилиты file, зато есть ftp. С помощью ftp мы можем перенести исполняемый файл на систему Mandrake. Начнём с файла telnet.cgi в каталоге /home/httpd/html/Management. После того, как он будет скопирован, можно запустить утилиту file.
# file telnet.cgi telnet.cgi: ELF 32-bit MSB executable, ARM, version 1 (ARM), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), stripped |
Уже лучше. Теперь мы знаем, что используется процессор ARM, поэтому нужно установить компилятор для него.
Собираем Toolchain
Сама мысль об установке межплатформенного Toolchain вселяет страх в сердца многих разработчиков. Представьте, нужно скомпилировать компилятор, библиотеки C и т.д. К счастью, в эпоху Интернета можно воспользоваться готовыми результатами чужого труда.
Дан Кегель (Dan Kegel) занимается созданием межплатформенных компиляторов gcc, при этом он предлагает огромный скрипт, который начинает работу со сборки всего необходимого. Он скачивает требуемый исходный код, при необходимости патчи к ним, и создаёт готовый Toolchain - и так для множества различных процессоров. Мы уже использовали скрипты для создания компилятора под Linksys WRT54G, основанного на процессоре MIPS. Как мы полагали, скрипты Дана смогут помочь и с NSLU2 - они создадут Toolchain, с помощью которого мы сможем создавать исполняемые файлы NSLU2.
Кажется, что Linksys неохотно предоставляет исходный код, требуемый по лицензии GPL. Многие устройства этой компании используют Linux, но их наборы GPL сильно отличаются. Некоторые модели включают полный набор окружения, тогда как другие, например NSLU2, этим не отличаются.
Диск, который поставляется в комплекте NSLU2, содержит достаточно большую часть исходного кода, но без Toolchain. К счастью, в арсенале Linksys есть и другое устройство, использующие Linux - WRV54G. Этот беспроводной широкополосный маршрутизатор 802.11g, по всей видимости, выполнен на той же системе Intel IXP425. Linksys выпустила Toolchain для этого продукта, поэтому им мы и воспользуемся. Для начала нужно скачать файл объёмом 125 Мбайт и распаковать его (tar).
В нашем случае мы распаковали его в папку:
| /home/jbuzbee/gpl_code_2.03 |
В ней можно найти файл toolchain.tgz. Мы распаковали его в тот же домашний каталог. После этого там можно найти все необходимые компиляторы, линкеры, модули и прочее.
Исполняемые файлы находятся в каталоге usr/local/openrg/armsaeb/bin и у всех есть префикс armv4b-hardhat-linux-. Этот каталог мы добавили в $PATH, чтобы каждый раз не указывать полный путь.
Тестирование компилятора
Теперь необходимо проверить компилятор - будет ли исполняемый код работать на тестовой платформе. Первое, что пишет любой уважающий себя программист, - "Hello World". Так и мы, создали файл hello.c.
#include main( int argc char *argv[] ) { printf("Hello world!\n"); } |
Затем откомпилировали его.
# export PATH=home/jbuzbee/gpl_code_2.03/usr/local/openrg/armsaeb/bin/:$PATH # armv4b-hardhat-linux-gcc hello.c -o hello |
И проверили тип файла.
# file hello hello: ELF 32-bit MSB executable, ARM, version 1 (ARM), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), not stripped |
Всё в порядке. Теперь можно скопировать файл на NSLU2 по ftp и запустить его там. Не забудьте включить двоичную передачу ftp (binary) и пометить файл как исполняемый. После этого можно запускать.
Работает! Теперь мы можем создавать и запускать любые программы на NSLU2. При этом не забудьте сохранять данные на жёсткий диск, поскольку домашняя папка учётной записи root располагается на RAM-диске. Создайте новый каталог стандартным способом и скопируйте туда файл.
# mkdir /share/hdd/data/jim/nslu2 # mv hello /share/hdd/data/jim/nslu2/ |
Изменение и компиляция Portmapper
Теперь можно приступать к серьёзным делам. Первое, что нам нужно сделать, - это установить и настроить дерево исходных файлов Linux для того, чтобы добраться до необходимых модулей include. Дерево можно найти в архиве snapgear tar на диске, поставляемом с NSLU2.
Затем нужно распаковать архив. Поскольку мы не собираемся перекомпилировать ядро, мы пропустим настройку для архитектуры ARM. Создайте и запустите следующий скрипт в каталоге snapgear/linux-2.4.x:
#!/bin/bash
rm -f include/asm rm -f include/asm-arm/proc rm -f include/asm-arm/arch
( cd include; ln -s asm-arm asm ) ( cd include/asm-arm; ln -s proc-armv proc ) ( cd include/asm-arm; ln -s arch-ixp425 arch ) |
NFS основана на архитектуре удалённого вызова процедур (Remote Procedure Call). Для работы RPC необходимо запустить вспомогательную службу (демон) portmapper. Исходный код службы мы нашли здесь, а сервера NFS - здесь. После распаковки деревьев исходного кода вы получите папки portmap_4, snapgear и nfs-server-2.2beta47, а также имеющуюся gpl_code_2.03.
Далее необходимо откомпилировать portmapper. Нам пришлось сделать несколько изменений для упрощения компиляции makefile. Во-первых, мы закомментировали строчку HOSTS_ACCESS= -DHOSTS_ACCESS, чтобы уменьшить зависимость от внешних библиотек. По той же причине мы закомментировали все строки со ссылками на libwrap.a. Для большей защиты можно вернуть всё обратно, но тогда потребуются дополнительные библиотеки.
После этого мы изменили строку CFLAGS, указав в ней расположение дерева исходного кода snapgear:
| CFLAGS = $(COPT) -O $(NSARCHS) $(SETPGRP) -I /home/jbuzbee/snapgear/linux-2.4.x/include/ |
В верхнюю часть makefile мы добавили следующую строчку для вызова межплатформенного компилятора:
| CC=/home/jbuzbee/gpl_code_2.03/usr/local/openrg/armsaeb/bin/armv4b-hardhat-linux-gcc |
Кроме изменений в makefile мы подправили и исходный код. В файле portmap.c, задана функция perror, переопределяющая стандартную функцию perror. Мы изменили параметр const char на __const char, чтобы он совпадал со значением, определённым в stdio.h.
Теперь осталось выполнить компиляцию. При этом появляется множество предупреждений, но процесс должен завершиться успешно. Следующая команда обрежет двоичный файл, чтобы экономно использовать память NSLU2.
| # armv4b-hardhat-linux-strip portmap |
Добавление служб NFS
Компиляция завершена, идём дальше. Теперь настала очередь самих служб (демонов) NFS. Процесс создания демонов NFS требует запуска скрипта BUILD. Никаких межплатформенных параметров в нём нет, поэтому мы запустили его и получили результат. Во время выполнения скрипта приходится отвечать на множество вопросов, и на все надо отвечать по умолчанию, единственное исключение - следующий вопрос:
| Do you want to protect mountd with HOST ACCESS? (Хотите ли вы защитить mountd) |
На этот вопрос следует ответить "no" , поскольку у нас нет необходимой библиотеки. После завершения, придётся исправить файл makefile, чтобы он мог работать с межплатформенным компилятором. В начале файла есть три переменных CC, AR и RANLIB. Там необходимо добавить префикс компилятора. Например, в нашем случае переменная CC приняла вид:
| CC = /home/jbuzbee/gpl_code_2.03/usr/local/openrg/armsaeb/bin/armv4b-hardhat-linux-gcc |
Затем, нужно добавить путь к модулям include в строке CFLAGS. У нас она стала выглядеть так:
| CFLAGS = -g -O -D_GNU_SOURCE -I /home/jbuzbee/snapgear/linux-2.4.x/include/ |
Наконец, изменим файл nfsd.h. В начале необходимо добавить дополнительный модуль, который потребуется в нашем окружении.
После всего этого команда "make" даст два необходимых файла: rpc.mountd и rpc.nfsd. Теперь можно приступить к запуску NFS.
Для этого следует скопировать все три полученных файла (portmap, rpc.mountd и rpc.nfsd) на NSLU2. Мы решили скопировать их на раздел conf, чтобы они хранились отдельно от данных. Мы создали три новых каталога в папке /share/hdd/conf - bin, etc и rc.d, как и в обычном дереве каталогов.
Двоичные файлы отправились в каталог bin, скрипты - в rc.d, файлы конфигурации - в каталог etc. В нашем случае единственным необходимым конфигурационным файлом является exports. В нём хранится информация, какие каталоги доступны в NFS и для кого. В нашем случае файл exports выглядел следующим образом:
/share/ 192.168.1.100 (rw, insecure) /share/ 192.168.1.103 (rw ) /share/ 192.168.1.102 (rw ) |
Параметр insecure предназначен для системы Mac OS X, которая использует незащищённые порты. Вам, вероятно, потребуется создать свой файл для вашей сетевой конфигурации. Подробнее об этом можно узнать в документации NFS.
Проверка
Теперь осталось всё установить. Сервер NFS ищет файл exports в каталоге /etc, поэтому необходимо сделать ссылку на новый файл, находящийся в каталоге /share/hdd/conf/etc:
| # ln -s /share/hdd/conf/etc/exports /etc/exports |
Теперь необходимо позаботиться о скриптах загрузки для всех новых служб. На NSLU2 скопируйте скрипт rc.samba из каталога /etc/rc.d в новый каталог rc.d и внесите пару изменений: создать скрипты rc.portmap и rc.nfsd. Скрипт rc.nfsd должен запускать rpc.mountd и rpc.nfsd.
Осталось создать ещё один скрипт, который будет всё это делать: создавать ссылку, запускать скрипты portmap и nfsd именно в таком порядке. Его придётся выполнять при каждом запуске системы. К сожалению, как поставить автоматическое выполнение - мы не знаем.
Пробуем запустить скрипт, выполняющий все необходимые действия. После этого ps -ax на NSLU2 должен показать, что появились три новах процесса: portmap, rpc.mountd и rpc.nfsd. Сообщения об ошибках и системных событиях сохраняются в файле /var/log/messages.
Попытайтесь смонтировать NSLU2 с клиентской машины. На нашей тестовой системе Mandrake мы выполнили следующее (с правами root):
# mkdir /mnt/nslu2 # mount 192.168.1.70:/share/ /mnt/nslu2/ |
На системе Mac OS X, мы использовали опцию "Connect to Server" в Finder, указав сервер следующим образом:
Если у вас возникли проблемы с запуском демонов или подключением, то проверьте файл /var/log/messages на NSLU2. Отметим, что запуск NFS никак не влияет на SMB, они мирно сосуществуют.
Совет.Если у вас нет желания самому заниматься компиляцией, и вы хотите использовать готовые файлы, которые можно будет загрузить на NSLU2 (редактировать файл etc/exports всё равно придётся), то можете скачать архив объёмом ~57 кбайт отсюда.
Добавляем сервер iTunes
Наверное, все сталкивались с проблемой, когда коллекция музыки занимает слишком много места на жёстком диске. Было бы прекрасно переложить обязанности по хранению музыки на другое устройство, а ещё лучше, если бы оно было общим. Сейчас мы попробуем проверить, сможет ли NSLU2 играть роль музыкального сервера. Маленькое и бесшумное устройство может хранить столько информации, сколько вместит подключённый жёсткий диск. Выглядит многообещающе!
Сервер iTunes называется mt-daapd. Использование его на NSLU2 позволит не только хранить музыку, но и слушать её с компьютеров Mac OS X и Windows при помощи iTunes.
Интересно, что mt-daapd использует Rendezvous для объявления себя в локальной сети. Это означает, что сервер NSLU2 будет автоматически обнаруживаться в сети другими системами. Необходимо лишь запустить iTunes на машине с Windows или Mac OS X, и сервер автоматически покажет свою музыкальную библиотеку. Сразу отметим, что установка mt-daapd будет сложнее, чем NFS, но мы будем с вами и поможем преодолеть все препятствия.
Поиск исходного кода
Как и прежде, будем работать с оболочкой bash. Компиляцией займёмся на машине с Mandrake. Однако теперь мы будем использовать диск NFS на NSLU2, чтобы не заниматься излишним копированием.
Первое, что нужно сделать, - подготовить место для работ. Мы создали каталог iTunes в домашнем каталоге на NSLU2. Далее нам нужно найти все необходимые пакеты с исходным кодом. Мы начали с исходного кода mt-daapd, который взяли здесь.
Из документации мы узнали, что нам потребуется библиотека чтения ID3 libid3tag и менеджер баз данных GUN gdbm. Мы также выяснили, что потребуется и библиотека сжатия zlib. libid3tag мы взяли здесь, gdbm - здесь и zlib - здесь. Все модули мы поместили в каталог iTunes. После распаковки вы получите каталоги gdbm-1.8.3, libid3tag-0.15.1b, mt-daapd-0.2.0 и zlib-1.2.1.
Перед началом межплатформенной компиляции нужно задать переменные окружения. Все модули настраиваются одинаково, при помощи GNU Autoconf. Модуль считывает расположение компилятора и других файлов их переменных окружения.
Мы создали файл setup.sh следующего содержания:
export BASE=/mnt/nslu2/data/jim/iTunes/ export LINUX=$HOME/snapgear/linux-2.4.x/include/ export TOOLSBASE=$HOME/gpl_code_2.03/usr/ local/openrg/armsaeb/bin/armv4b-hardhat-linux export CC=$TOOLSBASE-gcc export STRIP=$TOOLSBASE-strip export RANLIB=$TOOLSBASE-ranlib export LDFLAGS=-L$BASE/lib export CFLAGS="-I$BASE/include/ -I$LINUX" |
Обратите внимание, что строчка export TOOLSBASE и следующая являются единой, без переноса и пробела.
BASE указывает на папку верхнего уровня нашей рабочей области, а LINUX - на папку дерева исходного кода snapgear Linux. TOOLSBASE - инструментарий межплатформенного компилятора, CC, STRIP и RANLIB - пути исполняемых файлов. LDFLAGS и CFLAGS используются при компиляции. Перед компиляцией нужно создать такой же файл с вашими параметрами. Затем выполните "точку", то есть . setup.sh, после чего переменные будут занесены в окружение. Теперь можно перейти непосредственно к компиляции.
Начнём с простого
При компиляции модулей важно соблюдать порядок. Начинать следует с zlib, поскольку у него нет внешних зависимостей. В каталоге с zlib необходимо выполнить следующее:
| ./configure --prefix=$BASE |
Параметр prefix указывает Autoconf, куда будут помещаться откомпилированные файлы. При запуске скрипта вы увидите несколько строк выходных данных и ссылки на компилятор arm-gcc. Теперь, когда всё настроено, осталось выполнить следующее:
После завершения компиляции нескольких файлов и создания библиотеки, результаты скопируются в основной каталог. Всё просто! Одна часть сделана, осталось ещё три.
Переходим к gdbm. Здесь также нет внешних зависимостей, но нужно указать ещё пару моментов, касающихся конфигурации. В каталоге gdbm нужно выполнить следующее:
| ./configure --host=arm-linux --prefix=$BASE |
Здесь Autoconf запросит архитектуру - и параметр host отвечает как раз за это. После запуска строки появится более длинный список, чем в предыдущем случае, однако всё должно завершиться за несколько секунд. Теперь нужно выполнить следующее:
Произойдёт долгая компиляция, затем ldconfig будет "жаловаться" на общую библиотеку, которая не поддерживает двоичные файлы arm. Нас это не заинтересовало, поскольку мы не собирались использовать библиотеки на NSLU2. Можно также встретить ошибку об изменении владельца gdbm.h. Она для нашего случая абсолютно безобидна.
Приступим к libid3tag. В каталоге libid3tag выполним:
| ./configure --host=arm-linux --prefix=$BASE |
Как и прежде, длинный список, затем:
Процесс заканчивается, как и прежде, с ошибкой ldconfig. Тем не менее, наши библиотеки готовы. Просто, не так ли? Сейчас будет немного посложнее - переходим к mt-daapd.
Компилируем mt-daapd
Как мы и говорили, создание mt-daapd более запутанно. Но, не стоит волноваться, мы опишем всё достаточно подробно.
В каталоге mt-daapd нужно выполнить следующую команду:
./configure --host=arm-linux --prefix=$BASE LIBS="-lgdbm -lid3tag -lz" ac_cv_func_setpgrp_void=yes |
Обратите внимание: это одна строка, с пробелом между $BASE и LIBS.
На этом стоит остановиться подробнее. Параметры host и prefix мы встречали ранее. LIBS используется только в этом модуле. По какой-то причине, при компиляции библиотеки запрашиваются перед файлами .o, в результате чего возникает ошибка.
Подробнее рассмотрев скрипт, мы заметили, что параметр LIBS может использоваться для добавления дополнительных библиотек. Что мы и сделали. Это можно считать взломом, но именно благодаря этому нам не пришлось вносить изменения в скрипт.
Ещё один новый параметр ac_cv_func_setpgrp_void также можно считать взломом. При первом запуске скрипта конфигурации мы встретили ошибку, которая возникла при попытке запуска тестовой программы, исполняющей поведение какой-то функции. Конечно, при межплатформенной компиляции мы не можем компилировать и запускать программы локально. При установке этого параметра во время конфигурирования, мы, по сути, "говорим" скрипту, что тест прошёл и результат его получен. Однако для этого нам пришлось самостоятельно найти правильный ответ и также указать его в командной строке.
Предупреждение. Исходя из нашего опыта, можем сказать, что это обычная проблема, встречающаяся при межплатформенной компиляции с использованием Autoconf. Авторы модуля зачастую не имеют возможности скомпилировать его для системы с другой архитектурой, поэтому скрипт не совсем корректно работает с межплатформенной компиляцией. Хотя такой подход может показаться некорректным, он всё же даёт возможность завершить процесс.
После запуска указанной выше команды нам придётся сделать ещё пару исправлений. Во-первых, для упрощения установки, нужно удалить общие библиотеки, которые мы только что создали. После их удаления ссылка будет вновь указывать на статические версии. Благодаря этому мы избавимся от дополнительных библиотек, которые не используют никакие другие процессы. Если вы заметите, что другим процессам нужны эти библиотеки, то можно пропустить этот шаг и оставить библиотеки. Выполните команду в каталоге mt-daapd.
Затем необходимо внести изменения, связанные с характером работы компилятора arm. По умолчанию, компилятор arm выравнивает структуры по 16-битным границам. В обычных случаях это не вызывает проблем, однако у нас структуры считываются и записываются непосредственно из сети. С другой стороны сетевого подключения находится программа iTunes, которая не поддерживает выравнивание, что приводит к искажению. Нам нужно изменить файл src/mDNSClientAPI.h, в нём необходимо добавить директиву компилятора __attribute__ ((packed)).
Для следующих типов также нужно добавить атрибуты packed.
- mDNSOpaque16
- mDNSOpaque32
- mDNSOpaque128
- mDNSAddr
- rdataSRV
- rdataMX
После внесения изменений, скажем, mDNSOpaque16 будет иметь следующий вид:
typedef union { mDNSu8 b[2]; mDNSu16 NotAnInteger; } __attribute__ ((packed)) mDNSOpaque16; |
Примечание: это одна строчка, а между } и __ пробел отсутствует.
Между typedef и фигурной скобкой находятся специальные атрибуты компиляции. Мы рассказали об этих изменениях авторам mt-daapd, однако они специфичны для компилятора gcc arm и в следующей версии могут и не появиться.
После добавления атрибутов, выполните "make install", после чего результат появится в ../sbin/. Осталось только сократить размер файла:
Готово!
Установка сервера iTunes на NSLU2
Настало время заняться установкой. Сначала нужно изменить файл mt-daapd.conf, находящийся в каталоге contrib. Файл достаточно подробно документирован, поэтому его легко настроить под ваши параметры и указать необходимые пути. В нашем случае, мы создали каталог верхнего уровня mt-daapd: /share/hdd/data/mt-daapd.
В него мы скопировали каталог admin-root, используемый для конфигурирования через web-интерфейс. Мы создали вложенный каталог cache для базы песен и скопировали contrib/mt-daapd.playlist в каталог mt-daapd, естественно, не забыв подкорректировать файл config. Для самой базы музыки мы создали каталог верхнего уровня MP3 и внесли соответствующие изменения.
После того, как вы отредактировали файл конфигурации, его нужно скопировать в каталог /share/hdd/conf/etc и создать ссылку из etc.
| ln -s /share/hdd/conf/etc/mt-daapd.conf /etc/mt-daapd.conf |
Теперь нужно скопировать двоичный файл src/mt-daapd в /share/hdd/conf/bin/. Затем для проверки скопировать несколько песен. Мы заметили, что сервер воспринимает файлы MP3 и AAC и может сканировать дерево каталогов, а не просто отдельный каталог. Мы скопировали файлы, используя для этого NFS, но вы также можете прибегнуть к помощи SMB или ftp.
Как и в случае с сервером NFS, здесь также нужно создать скрипт rc, который будет создавать ссылку и запускать процесс. Мы использовали для этого /etc/rc.d/rc.samba. Его нужно скопировать в /share/hdd/conf/rc.d/rc.mt-daapd, изменить для mt-daapd и запустить:
| /share/hdd/conf/rc.d/rc.mt-daapd |
Просмотрев журнал /var/log/mt-daapd.log,можно увидеть несколько сообщений о состоянии, а команда ps -ax покажет работающий mt-daapd. Не пугайтесь, если увидите множество строчек в psoutput для mt-daapd.mtобозначает многопоточный (multi-threaded), а Linux показывает каждый поток отдельно.
Наслаждаемся музыкой
Настало время настоящей проверки - прослушивание музыки на компьютере. Сервер поддерживает версии iTunes для Windows и Mac OS X. В левой части, на панели "Source" в окне "iTunes", можно заметить небольшой синий значок с названием сервера, указанным в файле конфигурации mt-daapd. Просто. Никакого поиска, настройки, ничего, всё работает само по себе.
Думаем, не стоит говорить, что делать дальше. Выбрать синюю иконку, посмотреть список музыки, выбрать и включить! Нам удалось без проблем слушать музыку одновременно на трёх ноутбуках, использующих беспроводные соединения. У этой маленькой коробочки гораздо больший потенциал, чем изначально реализовала Linksys!
iTunes в действии
Совет.Если у вас нет желания самому заниматься компиляцией, и вы хотите сразу получить готовые файлы, которые можно загрузить на NSLU2, то можете скачать архив объёмом ~185 кбайт отсюда.
Пока мы ограничивали себя лишь добавлением новых модулей NSLU2. Далее приготовьтесь выбросить гарантийный талон, копнуть немного глубже и внести более существенные изменения. Мы зальём собственную прошивку - и сможем запускать новые процессы автоматически.
Вносим изменения в прошивку
Мы уже успели "выжать" из NSLU2 достаточно много, но нет предела совершенству... К сожалению, при каждой перезагрузке наши новые процессы, такие как Telnet, NFS и mt-daapd, не запускаются автоматически. Конечно же, у нас есть готовое решение, которое позволит запускать все эти процессы автоматически при загрузке, как на обычном компьютере.
На обычном компьютере достаточно включить соответствующие скрипты в автозагрузку. На Linux нужно просмотреть последовательность запуска, начиная с первого процесса init и дальше по каталогу rc. Нам нужно запускать полученный скрипт где-то после инициализации сети. Однако, у NSLU 2 это не так-то просто. Последовательность загрузки находится на RAM-диске, поэтому при перезагрузке все изменения теряются.
Мы потратили довольно много времени, пытаясь найти на диске файл, к которому можно было бы добавить ссылку на наш файл. Один из вариантов - использовать файл crontab, который на Unix-системах задаёт время запуска процессов. К сожалению, на NSLU2 файл crontab также находится на виртуальном диске в ОЗУ.
Единственное, что могло подойти для наших нужд, - файл конфигурирования Samba. Samba позволяет запускать сторонние процессы, указанные в конфигурационном файле, но, в конечном счёте, это также ни к чему не привело. Мы планировали расширить функциональность без изменения стандартной прошивки Linksys, однако простого способа нам найти не удалось.
К счастью, пока мы раздумывали над тем, как перехватить процесс загрузки, другие исследователи NSLU2 предложили свои варианты. Они пытались найти возможность изменить саму прошивку Linksys. Если удастся изменить прошивку, то можно будет дополнить список загружаемых процессов теми, которые необходимы. Конечно, с первого взгляда это может показаться чересчур сложным, но поскольку система базируется на Linux, то структура образа флэш-диска достаточно стандартна и ясна.
План действий
В случае NSLU2 флэш-память разделена на четыре части.
- Redboot
- System Configuration
- Kernel
- RAM disk
Часть Redboot, по сути, очень схожа с обычным BIOS: она инициализирует аппаратное обеспечение при включении питания. System Configuration - это место хранения постоянных параметров устройства, например IP адреса. Kernel - образ операционной системы Linux, а RAM disk - место хранения всех библиотек, конфигурационных файлов, скриптов и исполняемых модулей, таких, как web-сервер. Для автоматического запуска новых процессов нам как раз и нужно изменить RAM-диск.
Мы планируем взять образ прошивки, разбить его на компоненты, изменить содержимое RAM-диска, собрать и закачать обратно. На словах всё просто, на самом же деле - нет. Любая ошибка может превратить технологичное устройство в бесполезный кусок пластмассы.
Примечание. Способ установки последовательного порта на NSLU2 описан в документации. При помощи последовательного порта можно выполнить восстановление работоспособности устройства даже при проблемах с прошивкой. Установка порта требует пайки, а описание процесса выходит за рамки этой статьи.
Совет.Мы не описали также способ подключения к загрузчику RedBoot через Telnet. Он может помочь при восстановлении прошивки - без необходимости разбирать устройство и заниматься пайкой. Подробнее о восстановлении прошивки посредством порта или интерфейса Telnet, можно узнать здесь.
На нашей машине под управлением Mandrake Linux мы создали рабочий каталог myFlash. Конечно, с тем же успехом можно использовать и любой другой каталог. В него нужно скачать прошивку с сайта Linksys. После распаковки вы увидите документацию со списком изменений и образ прошивки: NSLU2_V23R25.bin.
Теперь нам нужен инструмент, который позволит разбить этот файл на части. Мы использовали splitnslu, созданный Брайаном Ланцом (Brian Lantz). Кстати, копию файла мы разместили на сайте. Её можно найти здесь. После распаковки tar вы получите файлы README, .c и Makefile. Можно было бы использовать Makefile, но мы будем производить все изменения вручную.
Распаковка и изменения
Начнём с компиляции splitnslu.
| gcc -o splitnslu splitnslu.c |
Утилита позволяет как распаковывать, так и сжимать образ. Для получения диска RAM нужно распаковать прошивку.
| ./splitnslu unpack NSLU2_V23R25.bin |
В процессе распаковки появится несколько сообщений. Нам интересен файл ramdisk.gz. По расширению видно, что файл заархивирован gzip. Поэтому его также предстоит распаковать:
| gzip -d ramdisk.gz |