Я не психопат — я просто мыслю творчески
(c) Гарри Поттер и методы рационального мышления
Участие в соревнованиях типа «евробота», где кодить приходить в самых разнообразных позах, согнувшись хрен знает как, под/на/за столом, да и пара других веселых поездочек натолкнули меня на не совсем адекватную мысль, что надо бы сделать из своего телефона что-то более полезное, чем звонилку. Не все же ему ворочать своими мегагерцами жабу.
Итак, в наличии имеем:
- Тупой китайский кирпич HD7 Pro с android 2.3.5, умеющим точку доступа, и не развалившийся за полтора года службы. Внутри — MT6573
- Прямые руки (2 шт., костлявые)
- Немного свободного времени
Хотим получить
- Набор штатных инструментов — lighttpd, ssh, git, прочее
- WiFi точку доступа с локальным dns, выходом в интернеты (если есть)
- Блэкджек и прочие полезности (с)
Итак, приступаем. Все нижеизложенное требует прямых рук, красных глаз, и скорее всего лишает гарантии. При должной сноровке применимо ко всем аппаратам на андройде, какие только есть на рынке.
Ясное дело, что рут и бизибокс у меня был с хрен знает каких времен. Они нам и пригодятся.
Итак, первое что я сделал, это подсунул конфиг dnsmasq’у, чтобы тот поднял нам локальный dns.
Фактически когда мы поднимаем локальную сеть по WiFi, теперь это мы делаем с блекджеком и шлюхами с dns. Теперь, вместо того, чтобы вбивать IP адрес телефона, мы сможем вбивать просто http://anomalia, и точно так же со всеми компьютерами в сети. Годно, двигаемся дальше.
Общий план такой — закинуть на телефон корень дебиана, и запускать нужные мне службы из чрута, так как каждый раз огребать проблем с сбором той или иной софтины через ndk — застрелиться не жить.
А когда заработает — можно и набросать в эклипсе гуёвину, для запуска/остановки карманного сервера одним кликом прикосновением.
Если честно, то я так ни разу и не удосужился пощупать кишки своего аппарата за почти полтора года владения им. А это уже упущение — стареем-с. Итак, подцепляем по adb консольку и осматриваемся.
/ # uname -a Linux localhost 2.6.35.7 #1 PREEMPT Wed Feb 8 19:45:24 CST 2012 armv6l GNU/Linux
/proc/filesystems выдает весьма нелицеприятный диагноз:
/ # cat /proc/filesystems nodev sysfs nodev rootfs nodev bdev nodev proc nodev tmpfs nodev sockfs nodev pipefs nodev anon_inodefs nodev devpts nodev ramfs vfat msdos yaffs yaffs2 nodev mqueue nodev mtd_inodefs
И это печально. Печально тем, что у нас нет ни одной файловой системы, кроме yaffs2, которая поддерживает все так нужные фичи и годиться для корневой фс дебиана. только убожества типа vfat и msdos. Так как телефон у меня на MTК6573, а про то, как медиатек открывает исходники любят говорить плохо, я изначально приготовился к тому, что ядро пересобрать не выйдет. Но мне повезло — в ядре были включены подгружаемые модули, а значит при должной сноровке можно дособрать необходимые куски в рабочем виде, даже не имея родных исходников ядра.
Но эту магию я, пожалуй, распишу как-нибудь в другой раз — мне повезло вдвойне — в /system/lib/modules/ оказалось…
/ # ls /system/lib/modules/ xlog.ko wlan.ko sec.ko sbup.ko pvrsrvkm.ko p2p.ko mtklfb.ko mtk_stp_wmt.ko mtk_stp_uart.ko mtk_stp_sdio.ko mtk_stp_gps.ko mtk_stp_core.ko mtk_stp_bt.ko mtk_hif_sdio.ko mtk_fm_priv.ko mtk_drvb_73.ko mt6573_mfv_kernel_driver.ko mt6573_m4u.ko lca_core.ko ext2.ko ccmni.ko ccci.ko aed.ko
ext2.ko. Который надо полагать и не подгружался автоматом. Сойдет. Как говориться — на безрыбье и рак рыба.
загружаем@проверяем…
/ # cat /proc/filesystems nodev sysfs nodev rootfs nodev bdev nodev proc nodev tmpfs nodev sockfs nodev pipefs nodev anon_inodefs nodev devpts nodev ramfs vfat msdos yaffs yaffs2 nodev mqueue nodev mtd_inodefs ext2 / #
И оно даже работает. Вин.
Далее я поставил бэкапится всю свою 32GiB карту, так как предстояла ее переразбивка на два раздела. Первый так и останется в vfat’е для андроеда, второй гига эдак на 3-4 станет корнем для debian’а.
Оный, пока шел бэкап, я забутсрепил раскурив оффициальный(tm) мануал на Debian Wiki.
после шаманства с cfdisk’ом и распаковки минимальный дебиан был водружен на раздел. И вот тут-то и потребовалось шаманство.
Так как графические приложения из дебиана мне на телефоне не сильно нужны, мне надо только запустить/остановить пяток служб. Не долго думая, я выдавил из себя вот такое вот шаманство на баше:
DAEMONS="lighttpd ssh minidlna mysql" export SDCARD=/sdcard export ROOT=/data/debian export DEV=/dev/block/mmcblk0p2 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH CMD=$1 log() { am broadcast -a org.ncrmnt.serverctl.log -e log "$*" } prepare() { log "Mounting debian chroot..." insmod /system/lib/modules/ext2.ko mount -o rw,noatime -t ext2 $DEV $ROOT mount -o bind /sys $ROOT/sys mount -o bind /dev $ROOT/dev mount -o bind /proc $ROOT/proc mount -o bind /dev/pts $ROOT/dev/pts mount -o bind,users $SDCARD $ROOT/mnt mount -t tmpfs none $ROOT/tmp mount -o rw -t tmpfs none $ROOT/var/log mkdir $ROOT/var/log/lighttpd hostname `cat $ROOT/etc/hostname` log "Hostname set to `cat $ROOT/etc/hostname`" } run_service() { log `chroot $ROOT /etc/init.d/$1 $CMD` } t_done() { log "chroot environment fully unmounted. " exit } if [ "$CMD" == "terminate" ]; then echo "Cleaning up..." $0 stop #Kill any working ssh sessions. killall -9 sshd killall ssh umount $ROOT/var/log umount $ROOT/tmp umount $ROOT/dev/pts umount $ROOT/dev umount $ROOT/proc umount $ROOT/sys umount $ROOT/mnt umount $ROOT rmmod /system/lib/modules/ext2.ko [ -f "$ROOT/etc/hostname" ] || t_done log "ERROR: chroot is still mounted" log "ERROR: ditch any running ssh sessions and try again" log "ERROR: termination failed" exit fi log "clean" log "Necromant's pocket server" [ -d $ROOT/dev ] || prepare for s in $DAEMONS; do run_service $s done log "All done, have fun" |
По коду только заострю внимание на паре вещей:
- Для ext2/3/4 опция noatime. Эта опция нам здорово продлит срок службы карты, так как не будет фиксировать каждое прикосновение к файлу.
- /tmp и /var/log — я поместил в tmpfs с той же самой целью — меньше нагрузки на карту.
- Для того, чтобы лайти взлетел ему пришлось создать каталог для логов.
- Так как инит дебиана у нас не стартует, то имя хоста мы выставляем хаком при подкотовке чрута.
- /dev в подмонтированной FS служит нам маркером, что мы все сделали.
- Terminate специально натаскан пришибать все висящие ssh сеансы чтобы отрубить чрут окружение.
Далее мы тупо запускаем/останавливаем выводок наших демонов из переменной «DAEMONS». Осталось только сохранить этот скрипт как serverctl куда-нибудь в /system/bin или на карту памяти и можно делать
serverctl start/stop/restart
Тут есть один нюанс. Когда корень дебиана монтируется куда-то на карту памяти, у меня по этой фс начинал шастать media scanner, из-за которого нельзя было размонтировать chroot. Потому, я создал каталог debian в /data, и монтирую корень уже в него.
Дальше я штатными средствами установил и настроил стандартную связку: lighttpd, php, minidlna, gitweb, ssh, mysql и сел рисовать вебгуй.
Особо не запариваясь стянул темплейт с freecsstemplates и начал его уродовать. Так как тянуть cms’ку с темплейтингом было очень лень, я решил обойтись одним хтмль файлом, который заполнять/обновлять ажаксом. Ну и несколько штук php файликов в две-три строчки, которые выдают данные. Больше-то и не надо.
В ходе копаний в /sys обнаружились интересные «вкусняшки», которые я и решил вывести в веб-гуй. Сделал я это через очень простые костыли на php, от которых матерых веб девелоперов должно в теории передернуть.
$f=$_GET['file']; $f=str_replace("..","",$f); $f=str_replace("\/\/","",$f); $a=file_get_contents("/sys/$f"); echo $a; |
Таким образом в веб-интерфейс попали данные о напряжении/температуре батарейки, потребляемый ток, напряжение на заряднике (если он подцеплен), и куча других не менее бесполезных данных, которые я периодически получаю из веб-гуя ажаксом.
Дополнил я это еще несколькими не менее уродливыми скриптами на php:
Для получения свободного места:
$fs = $_GET['fs']; $data=shell_exec("df -h $fs"); $data = explode("\n",$data); $data = preg_split ("/\s+/",$data[1]); //print_r($data); foreach ($data as $d) { echo "'$d',"; } |
Всего у меня получилось около 5-7 таких страшеньких файликов, которые я закинул в /var/www.
На очереди было поднятие gitweb и вообще организация git репозиториев на этом карманном сервере. Начал я с того, что добавил пользователя git.
Далее создал в каталоге этого пользователя .ssh, где создаем файлик authorized_keys. Так как push и pull мы будем делать по ssh, то и авторизацию лучше поставить по ключу, а ключи добавлять через веб интерфейс. Сначала я экспериментировал с правами и strictmode опцией в sshd, но потом забил, и заставил lighttpd работать от имени пользователя git. Это упростило задачу, и я быстренько нарисовал скрипты для решения из веба основных задач: создание пустого репозитория, клонирование репозитория к себе по урлу и отображение ссылок для клона и добавления remote. Все тот же php, который запускает шелл. Можно было сделать и красивее, но мне было очень лень.
Получился эдакий github в кармане.
Из более тяжелых php скриптов (собственно, ради которых я вообще тащил туда php) на карманном сервере быстренько разместились sticky-notes и phpmyadmin (за компанию). В планах еще подыскать какой-нибудь удобоваримый и простой багтрекер уровня TODO листа на php.
Наконец, венец моего на сегодня сумасшествия — гуй для запуска/останова всего этого хозяйства. Для этого я выдавил из себя немного кода на джаве.
Для обратной связи с гуем, я добавил в баш скрипт рассыл броадкаста по запуску каждой из служб. Все это добро присутствует выше.
Все? Нет, и это еще не все, ибо знатно что-то меня сегодня припекло. (Весна?) До кучи я решил выводить в веб-интерфейс данные с камер. А то один хрен на главной странице пустое место. Подумаешь, захватить картинку через v4l?
Оказалось, что нет. Суровые тайваньцы/китайцы/хрен_этих_азиатов_разберет из медиатека положили крепежные изделия на поддержку v4l/v4l2 и камера у них заведена через «нестандартное техническое решение»(tm). По-русски — проприетарный огороженный костыль. (Как и блютуз, кстати — никакими bluez’ами и dbus’ами на медиатеках даже и не пахло!).
Получить картинку из debian’а просто так не вышло. В итоге, потыкавшись минуты три, пришлось в мою запускалку на java за компанию добавить службу, которая слушает порт 8888 и на по GET запросам выдает картинки с передней камеры и задней, которые уже вставляются в веб страницу.
Для добавления пафоса, я реализовал это через lightbox2, который обеспечивает плавно вылетающее всплывающее окно с фотографией по нажатию на front cam или back cam. Выглядит примерно так:
Теперь самое вкусное, а именно исходники этого маразма, которые можно бесплатно и без смс скачать на github’е. (Achtung! Код писался за пару вечеров и ОЧЕНЬ страшен!)
Впечатления:
Телефон у меня, мягко говоря, не топовый, и интерфейс андроеда на нем иногда подлагивает, и плавностью анимаций как на топовых телефонах или эталоне гламурности и пафосности — iPhone тут даже не пахнет.
Внутри arm1176 на частоте 650Mhz и 512 мегабайт памяти из которых половину, если не больше отожрал сам андройд, 64 метра откусил еще при старте 3д ускоритель. И тем не менее, несмотря на все это, я не заметил заметных тормозов ни при пользовании gitweb’ом, ни при поьзовании sticky-notes. Даже phpmyadmin, поставленный смеха ради, и который должен быть эталоном тормознутости ворочается вполне себе быстро… И только java… «не тормозит» (с) ™.
Интересное решение. остается выкинуть все внутренности андроида кроме браузера, звонилки и медиасервера и будет суровая firefoxOS 🙂
и еще один риторический вопрос: а почему не арч?
@domov0y: WebUi заскриншотен с десктопа, на телефоне я его обычно не открываю, телефон при этом работает как телефон, без каких либо проблем.
> и еще один риторический вопрос: а почему не арч?
У дебиана реже апдейты, и реже что-то ломают. Арч я юзаю только на десктопе, где для работы нужен апстрим как можно свежее. На сервере/телефоне возня с арчем не окупает временных затрат.
«В планах еще подыскать какой-нибудь удобоваримый и простой багтрекер уровня TODO листа на php. »
http://mantisbt.org/ не подойдет? Он вроде сьедобный и явного отторжения не вызывает.
смысл сервера — флешка с сорцами в условиях когда до интернета сто верст и все лесом?
@domov0y:
mantis щупал, таки сильно навороченный для задачи.
Смысл — это не флешка в кармане, а уже карманный роутер+сервер, которым можно быстро сорганизовать работу в полевых условиях небольшой команды, и иметь под рукой все инструменты. git да, на флешке можно держать, и делать push/pull друг другу, но менее удобно.
Вопрос: из chroot окружения звук мплеером вывести можно? или все глухо чуть менее чем полностью?
@domov0y: Зависит от трубки. дройдовский звуковой сервер может залочить устройство на себя, и куку. А может и нет, и тогда все через альзу нормально полезет.
Т.е от того на каком SOC сделано оно не зависит?! если так, то обидно.
Я надеялся, что доблестные китайцы работающие с медиатек, чаще реализуют alsa на уровне ядра.