Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 129, СЕНТЯБРЬ 2009 г.

Ebook-потрошитель. Применяем хирургию, чтобы раскрыть секреты Sony Bookreader PRS-505

Евгений «Vshmuk» Бейсембаев (diver@edu.ioffe.ru, ICQ 308229460)

Вокруг нас полно гаджетов с Linux на борту, и никто не мешает учиться на ошибках профессионалов, вскрывая гаджеты и изучая. Мной была куплена «игрушка» - книгочиталка на электронных чернилах Sony BookReader PRS-505. Вдоволь начитавшись Хайнлайна, я полез во внутренности девайса, изучить программную и аппаратную часть. Эта статья - результат увиденного.

Наша цель - посмотреть, как используется Линукс во «взрослых», массовых устройствах, оценить находки «тамошних» профессиональных линуксоидов, поднабраться опыта в исследовании чужого софта, а может, и добавить в устройство что-то свое.

Оффлайн

Итак, сначала проведем «оффлайновый осмотр внутренней программы. Производитель электронных книг периодически выкладывает на официальный сайт свежие прошивки, исправляющие старые глюки и добавляющие новые. Чтобы не потрошить содержимое flash-карточек устройства, просто скачаем новую версию
(http://download.sony.com/prs/prs-505/1.1.00.18040/PRS-505%20Updater%201.1.00.18040.exe). Это программа, которую производитель нам предоставил для перепрошивки ридеров. Она содержит образ файловой системы для заливки в устройство. Экзешник - всего лишь самораспаковывающийся архив Win-Zip, и его совсем необязательно запускать, достаточно просто распаковать linux-утилитой unzip:

$ unzip PRS-505 Updater 1.1.00.18040.exe
$ ls
checksum eBookMSCDeviceUpdater.dll fsk.dll kconfig.xml msvcr71.dll ssleay32.dll
cramfs.Fsk.img eBookUpdater FskImage.dll libeay32.dll PRS-505 Updater 1.1.00.18040.exe USBDLL.dll
cramfs.Rootfs.img eBookUpdater.xsb Fskin.dll MSCEncComm.dll PRS-505 Updater.exe
DriveManager.dll FskCore.xsb FskPower.dll msvcr70.dll raw.BootImg.img
$ rm PRS-505 Updater 1.1.00.18040.exe

Помимо вспомогательных dll-ек и конфигурационных файлов xml (к ним мы еще вернемся), в распакованном архиве будут жить нужные образы ФС, которые и заливаются в итоге в устройство. Они имеют расширение *.img. Пропустим эти имиджи через программу file и посмотрим, что она о них думает:

$ file *.img
cramfs.Fsk.img: Linux Compressed ROM File System data, little endian size 65536 CRC 0xc3e97789, edition 2768907732, 3306537355 blocks, 1718735798 files
cramfs.Rootfs.img: Linux Compressed ROM File System data, little endian size 65536 CRC 0xdb11801f, edition 3444324402, 2364302859 blocks, 491549572 files
raw.BootImg.img: DOS executable (device driver) for DOS

Содержимое третьего файла показалось мне подозрительным, это был явно не ДОС-драйвер. Размер - 480 тысяч байт, почти полностью забит единичками (для более быстрого залива во флеш, как я полагаю) и имеет некоторое количество вкраплений чего-то малоосмысленного. Сначала я решил, что это какой-то загрузчик (истинное назначение станет ясным позднее).

Файлы cramfs.Fsk.img и cramfs.Rootfs.img, очевидно - образы файловых систем в формате CramFS. Попробуем их смонтировать:

$ mkdir Fsk.FS
$ cd Fsk.FS
# mount -t cramfs -o loop ../cramfs.Fsk.img .

Внутри - каталог sony/ebook, а в нем - подкаталоги application, bin и FONT. Заглянем в первый и увидим кучу динамических библиотек, скомпилированных под архитектуру armel, и кучку вездесущих xml-файлов. В каталоге /bin - 4 бинарника, а в FONT - шрифты.
Теперь примонтируем файл cramfs.Rootfs.img. В нем - полноценная файловая система GNU с каталогами: bin, Data, dev, etc, home, lib, mnt, opt, opt0, opt1, proc, root, sbin, tmp, usr, var. Что же интересного здесь можно накопать? Ну, во-первых, содержимое файла /etc/issue даст нам версию окружения Linux - коммерческий проект MontaVista версии 3.0 (www.mvista.com). Файлы /etc/passwd и /etc/sudoers расскажут о единственном пользователе этой системы: «libro» с зашифрованным паролем «/ET3mqgcE1NTQ». Подкаталог /etc/rc.d обозначит все сервисы и демоны, которые запускаются в устройстве. Здесь все стандартно, если бы не спрятавшийся в rcS.d скрипт S20libromount. Заглянув в него, можно узнать, что он монтирует файловые системы (в /opt, /opt0 и /opt1), подгружает драйвера экранчика, звука, usb-storage и flash-карточек, выводит наружу приветствие и устанавливает дефолтное время. В общем, все, от чего зависит книгочиталка, делается здесь.

Я чуть было не ушел из подкаталога /etc дальше по файловой системе, но в последний момент заметил скриптик rc.d/rc3.d/S98librostart, который запускает файл tinyhttp.sh, живущий в предыдущей изученной нами файловой системе. А вот здесь уже интересно. Зачем устройству, не имеющему никакого сетевого интерфейса, какой-то http? Ладно, берем на заметку и ползем по файловой системе дальше.
Некоторый интерес вызвал драйвер хваленых электронных чернил (http://ru.wikipedia.org/wiki/EInk), живущий по адресу /lib/modules/2.4.17_n12/kernel/drivers/video/etrackfb.o. Поиск последовательностей ASCII-символов в этом двоичном файле (команда «strings etrackfb.o») дал следующий результат:

kernel_version=2.4.17_n12
author=E Ink
description=8track FrameBuffer Driver
VGA e-ink 600x800

Следовательно, электронные чернила представляются Линуксу как графический Framebuffer-совместимый дисплей! Так что, если захотим похачить устройство и заставить выводить на экран что-то, отличное от книжек, – надо лишь направлять вывод нашей графической программы в /dev/fb0. Проявляется и смысл файла raw.BootImg.img - это то, что отсылается во фреймбуффер при загрузке ОС, то есть картинка с логотипом и надписью «Starting Up…». Размер файла как раз равен 800x600 (=480000), по байту на пиксель.

Одно из особенностей устройства - разработчики физически поместили на разные файловые системы собственно GNU (как универсальный софт) и устройство-зависимую оболочку Fsk - то, что и делает букридер букридером. Сделано это чтобы можно было быстро заливать обновления к программе чтения, не трогая систему целиком и повышая ее безопасность.

Разбираем…

Внутренности устройства уже давно исследованы товарищами igorsk, boroda и остальными энтузиастами с форума www.the-ebook.org/forum/viewtopic.php?t=7577. Нам осталось только повторить их подвиг, благо, инструкция по разборке там имеется.
С замиранием сердца разбираю своего хорошего друга и внутри обнаруживаю:

  • Центральный процессор FreeScale (Dragonball) MX-1 с архитектурой ARM926
  • Микросхема NAND-Flash памяти Samsung (256 Мb)
  • Микросхема NOR-Flash памяти Spansion (2 Мb)
  • Две микросхемы оперативной памяти Samsung
  • Контроллер карт SD/MMC+MemoryStick Ricoh
  • Контроллер дисплея на FPGA Actel ProASIC3
  • Цифро-аналоговый преобразователь для вывода звука
  • Контроллер USB Epson S1R72V17
  • Распайка под проприетарный отладочный разъем (100 ножек), маркирована как CN1501

Итак, никакого чуда или крутой инженерной находки внутри букридера нет. Видим микросхему NOR-памяти, в которой, скорее всего, живут загрузчик и ядро, потому как именно этот тип Flash умеет читать отдельно заданный байт (Random Access). Рядом – NAND-Flash, где, очевидно, живут файловые системы и, собственно, сами книжки. Лично меня порадовала SDRAM-память в маленьких BGA-корпусах. Тем самым инженеры нехило сэкономили место на плате.

Вообще, компоновщикам платы и дизайнерам корпуса моя похвала и зависть. Все подогнано неимоверно точно, и нигде не заметно расточительства. Впихнуть в корпус что-нибудь, кроме того, что в нем есть, мне показалось невозможным. Короче, ни добавить, ни отнять.
Разберемся с отладочным разъемом. Очевидно, на него выводятся JTAG-интерфейсы микросхем + какие-нибудь порты, типа последовательного отладочного UART'а с центрального процессора. Так и есть. Ребята с форума, названного выше, уже сделали грязную работу, в виде тыкания осциллографом, и вычислили принадлежащие DBG-порту ножки. Осталось только к ним подпаяться. Припаиваем тонкие серебряные провода к 6(Transmit) и 7(Receive) пинам, а также не забываем про «земляной» контакт, который можно взять или от 5-го пина разъема или – просто схватившись за корпус устройства. Через переходник RS-232/UART подключаем к COM-порту компьютера.

Онлайн

Включаем устройство. Если порт настроен правильно и все запаяно аккуратно, то наблюдаем лог загрузки Линукса. Как загрузка закончена, – логинимся с узнанными из /etc/passwd реквизитами (libro:librie). Система пускает нас и вываливает сообщение:

### fskLoad
### fskLoaded
latest nblconfig read from 0x0003b800
latest nblconfig written to 0x0003c000
#### xs_switcher_usbWatcher_endUSBThread
# warning: global instead of local!
# warning: global instead of local!
SYSNPM: sysnpm_pm_callback():163 Mem, CPU stopping...

После чего перестает отвечать на команды! Все хорошо, так и должно быть, это процесс-оболочка tinyhttp заметила неактивность процессора и вырубила его, чтобы сэкономить аккумулятор. «Расшевелить» процессор можно, понажимав на кнопки громкости. Работать так сложно, поэтому убиваем лишнее:

$ killall tinyhttp.sh
$ killall tinyhttp

С этого момента нам доступна настоящая, полноценная система GNU/Linux на ядре 2.4! Из лога загрузки (команда dmesg) можем узнать многое об аппаратной части девайса: например, что размер оперативной памяти 64 Mb и что flash-память разбита на очень много разделов на все случаи жизни. Взглянем на характеристики процессора:

root@(none):/proc# cat /proc/cpuinfo

Processor : ARM/CIRRUS Arm920Tsid(wb) rev 0 (v4l)
BogoMIPS : 98.09
Features : swp half 26bit
Cache type : write-back
Cache clean : cp15 c7 ops
Cache lockdown : format A
Cache unified : harvard
...
Hardware : Motorola DragonBall MX1 (eBook-2)

Выходит, контроллер работает на частоте 100 МГц и имеет архитектуру ARM9. А вот что Линукс примонтировал:

root@(none):/var# mount

/dev/root on / type cramfs (rw)
proc on /proc type proc (rw)
tmpfs on /dev/shm type tmpfs (rw)
tmpfs on /tmp type tmpfs (rw)
tmpfs on /var type tmpfs (rw)
tmpfs on /etc type tmpfs (rw)
/dev/mtdblock10 on /opt1/keys type cramfs (rw)
/dev/mtdblock11 on /opt1/info type cramfs (rw)
/dev/mtdblock15 on /opt type cramfs (rw)
/dev/mtdblock16 on /opt0 type jffs2 (rw)
devpts on /dev/pts type devpts (rw)

Кстати, то, что имеет файловую систему cramfs – доступно только для чтения. Особенность файловой системы, что бы там драйвер себе ни думал.

Оболочка

Как среди файлов прошивки устройства, так и в приложении, поставляющемся под Windows, можно заметить множество xml-файлов, как один, начинающихся со строчки «<fsk xmlns="http://www.kinoma.com/Fsk/1">». Это файлы для оболочки, созданной компанией Kinoma и приобретенной Sony (что мелькает в «титрах»). В общем, бинарник tinyhttp парсит эти файлы и делает все, что ридеру нужно: рисует интерфейс, подключает библиотеки для разбора файлов, выполняет скрипты и т.д. Назвали его, конечно, странновато, но где-то даже логично. Нужную функциональность можно добавить в систему, не прикасаясь к компилятору. Пишем по образу и подобию новые конфиги или правим существующие, потом добавляем шрифты, простенькие игры - это возможно! «Язык» xml-файлов не очень сложен, так что все в наших руках.

Энтузиасты в интернете уже создали альтернативные прошивки с пакетами локализации и даже упаковали их в CramFS-образы. Среди рекомендуемого - более читабельные шрифты, симпатичные иконки и часы в углу экрана. Можно не спешить заламывать конфиги, а сначала посмотреть, что предлагает сообщество. Но если хочется чего-то своего, то расскажу, как создать образ на примере заливки новых шрифтов.

Ttf-шрифты лежат в каталоге /opt/sony/ebook/FONT. В идеале, их надо переименовать в tt0003m_.ttf,tt0011m_.ttf,tt0419m_.ttf, а также дать внутренние имена:

Font family - Swis721 BT, Dutch801 Rm BT, Courier10 BT
Font subfamily - Roman, Roman, Roman
Full font name - Swis721 BT Roman, Dutch801 Rm BT Roman, Courier10 BT Roman

Именно такие имена прописаны в конфигах application/kconfig.xml и application/resources/scripts/main.xml. По образу и подобию написанного там можно изменить предложенные стили на свои:

<style font="Courier10 BT">
// Стиль для показа часов: жирный, размер 22
<style id="time" size="22" style="bold" color="#FFFFFF"/>
</style>
<style font="Dutch801 Rm BT">
// Текст размером 12
<style id="text" size="12"/>
</style>

В тех же конфигах, играясь со скриптами и разметкой, можно добавить возможностей в оболочку. Финальный аккорд - пакуем новую ФС в образ:

# mkfs.cramfs ./new_opt ./new_opt.img

Перепрошивка

Просто так заменить нужный файл на обновленный сжатая файловая система cramfs не позволяет. Надо будет ее распаковать на PC, внести изменения и с помощью mkfs.cramfs запаковать обратно, что и было проделано в предыдущем разделе. Товарищ igorsk написал набор скриптов (Universal Flasher, качать отсюда - www.mobileread.com/forums/showthread.php?t=26831). С их помощью можно заменить старый образ на созданный, а также (внимание!) заменять отдельные файлы, если хочется поэкспериментировать, не мучаясь с компоновками образов. Просто скидываем кучку файлов на Flash-карточку, заменяем образ new_opt.img на наш, вставляем в букридер и перезагружаемся. Если все прошло хорошо, и ошибок в конфигах нет, то мы заимеем обновленный интерфейс.

Чаще всего при заливке испорченного образа система не выходит из строя и дает нам шанс исправить проблему. Хотя иногда оболочка повреждается настолько, что без тяжелой артиллерии (подпаивания к отладочному порту) не обойтись. Но ведь остальная файловая система с GNU не убита, поэтому с полноценной консолью несложно перепрошить устройство рабочей прошивкой вручную, предварительно залив на флешку соответствующий образ (приведенная ниже последовательность действий предложена boroda):

// Создаем временный диск в памяти объемом 32 Мb
root@(none):~# mount -o remount -t tmpfs -o size=32m /dev/shm /tmp
// Монтируем Flash-карточку
root@(none):~# mkdir /tmp/sd_card
root@(none):~# mount /dev/sdmscard/r5c807a1 /tmp/sd_card
// Вынимаем оттуда образ во временный диск
root@(none):~# cp /tmp/sd_card/new_opt.img /tmp
// Проверяем контрольную сумму
root@(none):~# md5sum /tmp/new_opt.img
// Проприетарный софт Sony для низкоуровневой работы с NAND-flash карточками
root@(none):~# /usr/local/sony/bin/nblsdm delete Fsk
root@(none):~# /usr/local/sony/bin/nblsdm create -i /tmp/new_opt.img -d 1 Fsk
// Сравниваем залитое
root@(none):~# /usr/local/sony/bin/nblsdm cmp -i /tmp/new_opt.img Fsk
root@(none):~# /usr/local/sony/bin/nblconfig -ksel normal
root@(none):~# sync
root@(none):~# reboot

Простор для экспериментов

Привычка разбирать попадающиеся под руку (и собирать обратно!) гаджеты добавляет опыта и помогает при создании чего-то своего. Мы взяли устройство для чтения электронных книг, но вместо чтения стали исследовать его программную и аппаратную суть. Ладно спроектированный и созданный на базе знакомого и изученного Linux, Sony Bookreader PRS-505 предоставляет широкий простор для экспериментов и творчества.

INFO

UART - этот простой механизм позволяет последовательно передать несколько байт. В одном из предыдущих номеров журнала Сергей Долин подробно написал о нем в рубрике «Фрикинг».

Sony Bookreader PRS-505 - карманный компьютер, имеющий вместо стандартного ЖК или OLED-дисплея так называемый E-ink дисплей на электронных чернилах.

WWW

Содержание
ttfb: 6.9029331207275 ms