tag:blogger.com,1999:blog-68273632805925329572024-02-08T08:24:51.703+02:00cat **/* | grep яAkshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-6827363280592532957.post-6141997722341529132009-03-14T19:49:00.003+02:002009-03-14T20:36:07.533+02:00Ядро linux для Loox N560/C550 с рабочим CPLD и светодиодамиДобавил поддержку CPLD и светодиодов. Для CPLD был заюзан драйвер htc-gpio с перечислением адресов регистров CPLD на Fujitsu-Siemens Loox 5XX (N560/C550). Теперь CPLD доступен для других драйверов.<br /><br />Примечательно, как в Linux'е реализована работа с CPLD. По сути, CPLD это чип, содержащий очень простую логику (за счет чего он очень быстр по сравнению с CPU), имеющий входные и выходные "ножки" (pins). Входные и выходные ножки - регистры - проецируются на определенную область памяти CPU. С логической точки зрения работа с CPLD заключается в переключении битов в регистрах CPLD в 0 или 1 (можно еще и читать оттуда, но я об этом тут не буду рассказывать..). Таким же образом выглядит работа с GPIO - общим вводом/выводом CPU: биты регистров CPU таким же образом принимают значение 0 или 1. В ядре Linux уже имеется драйвер GPIO, предоставляющий функции для работы с GPIO разработчикам платформенных драйверов. Также драйвер GPIO имеет механизм расширения, позволяющий другим драйверам/модулям проецировать заданные интервалы портов GPIO таким образом, что при обращении к такому порту произойдет вызов указанных при проецировании функций. Этот механизм используется CPLD драйвером htc-egpio для проецирования CPLD регистров на GPIO порты. Таким образом работа с CPLD идет через обыкновенные методы типа gpio_set_value.<ad2></ad2><br />На основе работающиго CPLD драйвера для Loox N560/C550 реализовал драйвер управления светодиодами КПК. Драйвер экспортирует методы и константы которые другие драйвера (wifi, gps, bluetooth, pm, ...) должны использовать для управления светодиодами. Также драйвер позволяет контролировать светодиоды из userspace пространства путем манипуляций с файлами sysfs. <br /><br />Ниже перечисленны файлы и значения которые могут находиться:<br /><b>/sys/devices/platform/loox5xx-leds.1/keyboard</b>: on, off, any<br />- подсветка клавиатуры<br /><br /><b>/sys/devices/platform/loox5xx-leds.1/left_green</b>: on, off, any<br />- зеленый светодиод с левой стороны. WM5 использует для индикации активности WiFi<br /><br /><b>/sys/devices/platform/loox5xx-leds.1/left_blue</b>: on, off, any<br />- голубой светодиод с левой стороны. WM5 использует для индикации активности Bluetooth<br /><br /><b>/sys/devices/platform/loox5xx-leds.1/left_orange</b>: on, off, any<br />- оранжевый светодиод с левой стороны. WM5 использует для индикации активности GPS на Loox N560<br /><br /><b>/sys/devices/platform/loox5xx-leds.1/right_green</b>: on, off, any<br />- зеленый светодиод на правой стороне КПК. WM5 использует как светодиод доступный приложениям (нотификации и т.д.)<br /><br /><b>/sys/devices/platform/loox5xx-leds.1/right_orange</b>: on, off, blink, any<br />- оранжевый светодиод с правой стороны КПК. WM5 использует для индикации процесса зарядки<br /><br />Где:<br /><b>on</b> - светодиод включен независимо от желаний ядра,<br /><b>off</b> - светодиод выключен независимо от желаний ядра,<br /><b>blink</b> - светодиод мигает независимо от желаний ядра,<br /><b>any</b> - светодиод контролируется ядром.<br /><br />Например, если установить right_orange в состояние on, то светодиод зарядки будет гореть независимо от того, заряжается КПК или нет. Это будет продолжаться до тех пор, пока в файл right_orange не будет записано значение any. После чего, первое же событие (установка КПК в крэдл и т.д.) переключит светодиод в соответствующее состояние. Sysfs интерфейс для светодиодов позволяет использовать светодиоды из программ для нотификации о событиях (пришла почта, кончается заряд и т.д.) с помощью всех доступных на устройстве светодиодов - насколько хватит фантазии. Например следующий shell код мигает подсветкой клавиатуры:<pre><br />while true;<br /> do echo on > /sys/devices/platform/loox5xx-leds.1/keyboard;<br /> sleep 0.1;<br /> echo off > /sys/devices/platform/loox5xx-leds.1/keyboard;<br /> sleep 0.1;<br /> # Condition for break...<br />done<br />echo any > /sys/devices/platform/loox5xx-leds.1/keyboard;</pre><br /><br />Актуальный патч на cupcake ядро андройда качать <a href="http://downloads.akshaal.info/linux-n560-c550/c550-android-kernel-2009-03-14.patch.gz?attredirects=0">здесь</a>.<br /><ad></ad>Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com6tag:blogger.com,1999:blog-6827363280592532957.post-72887756924752396952009-03-07T22:51:00.005+02:002009-03-08T12:49:32.445+02:00Ядро linux для Loox N560/C550 с рабочим usbnet'омПосле 3х дней мучений все-таки собрал ядро linux для Fujitsu-Siemens Loox N560/C550. Ядро брал с <a href="http://www.asm32.ru">http://www.asm32.ru</a>. Потратив еще несколько часов разобрался как запустить usbnet (сеть через обычный usb шнурок). Для этого пришлось дополнительно пропатчить pxa27x_udc.c. Сделал diff между текущей версией ядра андройда и теми исходниками (за 02-03-09), что выложены на asm32. В дальнейшем при обновлении ядра в cupcake'овской ветке можно будет просто накладывать этот патч сверху имея в результате и изменения под c550/n560 и исправления/дополнения внесенные в cupcake ветку. <a href="http://downloads.akshaal.info/linux-n560-c550/c550-android-kernel-2009-03-07.patch.gz?attredirects=0">Вот итоговый патч</a> в который также включены изменения для работы usbnet. В патче уже имеется .config, но там не включена поддержка usbnet. <a href="http://downloads.akshaal.info/linux-n560-c550/linux-config-2009-03-07?attredirects=0">Вот другой config</a>, он отличается от того, что в патче (а там тот, что выложен на asm32) поддержкой usbnet, выключенной power management (зачем не знаю, потом надо будет включить обратно), и настройкой для более крупного шрифта в консоли.. может еще чем-то.<br /><br />Собирать ядро можно с помощью любого toolchain'а. Я пробовал собирать с помощью: crosstool-ng, emdebian, а также того, что идет вместе с ядром андройда. Остановился на emdebian'е. Для сборки ядра emdebian'ом необходимо выполнить:<pre>make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-</pre>Предварительно emdebian конечно же нужно установить, например так:<pre><br />apt-get install emdebian-tool<br />emsetup --arch arm</pre>Добавить:<pre><br />deb http://www.emdebian.org/debian/ unstable main</pre><br />в /etc/apt/sources.list и выполнить:<br /><pre>apt-get install linux-kernel-headers-arm-cross gcc-4.2-arm-linux-gnu</pre><br /><br />Готовое ядро запускается haret'ом с конфигом:<pre><br />set MTYPE 1454<br />set KERNEL zImage<br />set CMDLINE "root=179:2 mem=60M rootdelay=3 boot_delay=0 init=/init console=tty0 fbcon=rotate:0 androidboot.console=tty0 android.checkjni=1"<br />set RAMADDR 0xA0200000<br />bootlinux</pre><ad></ad><br />И самое главное! После того, как ядро закинуто на sd карточку, эту sd карточку нужно вставить в КПК и ребутнуть КПК. А уже только после этого грузить haret'ом ядро! Ибо ядро не грузится (либо грузится с вероятностью 10%), если:<br />1. КПК заснула, а потом ее разбудили.<br />2. Вы только что вставили в КПК карточку.<br />Наверное это бага драйвера wince...<br /><br />P.S. Cupcake на который накладывается выложенный патч качается отсюда <a href="http://source.android.com/download"> http://source.android.com/download</a><br /><br />P.P.S. При сборке с поддержкой usbnet опцию CONFIG_USB_ETH_RNDIS<br /> включать не следует! Ибо в этом случае ПК не может нормально соеденится с КПК.. ни cdc_ether ни cdc_subset не видят usb устройство.Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6827363280592532957.post-15027549460103158712008-01-21T22:56:00.001+02:002009-02-22T15:56:40.193+02:00WayBackИногда возникает необходимость запустить приложение не в настоящем времени, а в прошлом или будущем. Обычно это нужно для тестирования приложения или для обхода устаревания evaluation license. Достигается это переводом системных часов, либо запуском приложения в vmware - оба этих метода имеют свои очевидные недостатки. К счастью в linux есть такая замечательная вещь как LD_PRELOAD, позволяющяя "переопределить" импортируемые функции приложения. Так, например, если подменить time, gettimeofday и clock_gettime - то программа с большой долей вероятности будет жить в том времени который нам нужен, в то время как вся остальная система будет жить в обычном временном русле. Для этих целей я написал <a href="http://toril.ru/soft/libwayback-1.tar.gz">небольшую C'ную библиотеку</a>. Устанавливается библиотека как обычно make install. <ad></ad><br /><br />Для примера, небольшое тестовое приложение на C:<pre><br />void main () {<br /> printf ("%lu\n", time(0));<br />}<br /></pre><br />Запускаем:<pre><br /><b>akshaal@...:/tmp% ./test</b><br />1200947571<br /><br /><b>akshaal@...:/tmp% WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test</b><br />63225<br /><br /><b>akshaal@...:/tmp% WAYBACK_LOG_LEVEL=3 WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test</b><br />Delta time: 3094082896<br />time modified<br />63257<br /></pre><br /><br />Библиотека libwayback не возвращает константу. После запуска, она определяет разницу между текущим временем и желаемым и запоминает ее как delta. В дальнейшем все вызовы к функция возвращающим время перехватываются и delta прибваляется к результату. Таким образом время не стоит на месте и в то же время она очень близко к желаемому.<br /><br />Например приложение на Java и стандартная утилита date:<pre><br />import java.util.Date;<br /><br />public class test {<br /> public static void main (String[] args) {<br /> System.out.println (new Date());<br /> }<br />}<br /><br /><b>akshaal@...:/tmp% java test</b><br />Mon Jan 21 22:39:26 EET 2008<br /><br /><b>akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 java test</b><br />Sat Nov 27 20:40:39 EET 2010<br /><br /><b>akshaal@...:/tmp% date</b><br />Mon Jan 21 22:41:20 EET 2008<br /><br /><b>akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 date</b><br />Sat Nov 27 20:41:50 EET 2010<br /></pre><br /><br />К сожалению данный способ может быть использован для обхода устаревания лицензии :) у программ к которым есть evaluation license ограниченная на определенный срок (например JProfiler 5, YourKit Profiler 7, InteliJ Idea и еще много). Я не проверял работает ли (но уверен, что да :) ) ибо предпочитаю опенсоурс софт и вообще это плохо и я против использования библиотеки для этих целей :).<br /><br />В библиотеке существует опция WAYBACK_RESET, которая определяет сколько секунд будет происходить подмена времени. К сожалению и эта опция может быть использована в целях обмана программ проверяющих срок действия лицензии. К примеру, если программа проверяет лицензию при запуске, то WAYBACK_RESET несознательный человек установит в 5 секунд, и после 5с получит пройденную проверку и программу с актуальным временем.<br /><br />Библиотека написана за час и не является Абсолютным Решением. Кому надо - юзают на свой страх и риск, а с меня никакого спросу.<ad2></ad2><br /><br />P.S. Больше всего напарился с одной вещью. Запускаю свинговое приложение, а оно виснет. Думаю че за нахрен. Копался-копался... оказывается java юзает pthread_condwait и ей в качестве параметра передается не относительное время (время когда ожидание прекращается), а абсолютное! Пришлось и эту функцию переопределить и вычитать дельту. Но как я искал.. strace говорит, что нить висит на futex каком-то.. и только чудом догадался, что futex может быть более нижним лаером под pthread'ом, а там уже полез смотреть как работа с X'ами идет в libawt.Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com1tag:blogger.com,1999:blog-6827363280592532957.post-91105037872125483802006-06-10T00:49:00.003+03:002009-02-22T17:03:28.169+02:00Joyemu v3. Пишим сложный патч для телефона на C. Информация должна быть свободной.Еще одной записью в TODO сегодня стало меньше, после новой версии патча, выпустить которую у меня наконец-то дошли руки. Что изменилось:<br />1. Теперь при включении режима эмуляции джойстика светодиоды в верхней части телефона горят и горят до выхода из эмуляции. Благодаря этому всегда понятно в каком мы сейчас режиме.<br />2. Нажатие на софт кнопки ничего не эмулирует. Иногда их надо нажимать, не выходя из эмуляции.<br />3. Блокировка клавиатуры эмуляцию выключает.<br /><br />Новая версия <a href="http://toril.ru/siemens/joyemu-3.vkp">патча в формате vkp</a>.<br /><br />Вопреки сложившейся традиции с форума сайта http://allsiemens.com я выложу и исходники патча, и все функции прошивки Siemens CX65 sw50, которые мне удалось найти (более 400), расскажу как писать патчи на C. Я не придерживаюсь мнения, что каждый новичок должен найти все эти функции сам - этот подход мне кажется бесполезной тратой времени, которое человек мог бы направить на что-то полезное, а не изобретать велосипед. Я также не сторонник подхода, когда создается элитарный клуб, между людьми которого передается информация - мне это несколько противно. Информация должна быть свободной.<br /><br />Тем не менее, эта информация не освобождает от необходимости знать Assembler ARM.<br /><br /><b>Пишем патч на C на примере Joyemu.</b><br />При написании сложнофункциональных патчей некоторая логика может быть написана на C.<br />Так, например, при эмуляции джойстика (я рассказывал <a href="http://rus.akshaal.info/2006/02/blog-post.html">в первом посте</a> на эту тему) телефона мы имеем множество ветвлений в алгоритме, реализовать которые можно и на ассемблере, но проще и чище это сделать на C.<br /><ad></ad><br />Первое, что делает joyemu - перехватывает нажатие на клавишу. Для этого мы ищем в прошивке тот участок кода, который обрабатывает это событие. Нашли, допустим, по адресу ORIGINAL_KEY_HANDLER. Теперь надо найти свободное место в прошивке под наш код, который будет обрабатывать это нажатие (ищем в прошивке длинную последовательность FF). Пускай наш обработчик должен быть по адресу OUR_KEY_HANDLER. Передать управление на наш обработчик при нажатии на клавишу можно двумя способами. Найти все места из которых происходит переход в ORIGINAL_KEY_HANDLER. И заменить на переходы на OUR_KEY_HANDLER. Так обычно никто никогда не делает, ибо мест таких может быть много. Мы же вставляем по адресу ORIGINAL_KEY_HANDLER инструкцию для загрузки в регистр PC адрес OUR_KEY_HANDLER. То, что мы затерли этими инструкциями запоминаем, оно нам пригодится, когда мы захотим вызвать оригинальный обработчик. А код, который находится за нашей инструкцией перехода на OUR_KEY_HANDLER, будет иметь адрес ORIGINAL_KEY_HANDLER_CHUNK.<br />Получается вот что:<pre><br />ROM:A121D4BC ORIGINAL_KEY_HANDLER:<br />ROM:A121D4BC 04 F0 1F E5 LDR PC, =OUR_KEY_HANDLER<br />ROM:A121D4C0 10 F3 65 A1 DCD OUR_KEY_HANDLER<br />ROM:A121D4C4 ORIGINAL_KEY_HANDLER_CHUNK:<br /></pre><br /><br />А так как в алгоритме эмуляции нам понадобится вызов оригинального обработчика нажатия, то для этого надо где-то разместить тот самый затертый код, после которого вставить переход к ORIGINAL_KEY_HANDLER_CHUNK. Разместим этот код сразу перед<br />OUR_KEY_HANDLER по адресу MOVED_ORIGINAL_KEY_HANDLER. Выглядит это вот так (сначала идут 8 оригинальных байт, потом 4 байта инструкции перехода, после 8 байт данных для инструкций):<br /><pre><br />ROM:A165F2FC MOVED_ORIGINAL_KEY_HANDLER:<br />ROM:A165F2FC 70 40 2D E9 STMFD SP!, {R4-R6,LR}<br />ROM:A165F300 04 10 9F E5 LDR R1, =off_A8663120<br />ROM:A165F304 04 F0 1F E5 LDR PC, =ORIGINAL_KEY_HANDLER_CHUNK<br />ROM:A165F308 C4 D4 21 A1 DCD ORIGINAL_KEY_HANDLER_CHUNK<br />ROM:A165F30C 20 31 66 A8 DCD off_A8663120<br />ROM:A165F310 OUR_KEY_HANDLER:<br /></pre><br /><br />Сохраняем изменения как vkp patch. Для этого в интернете валяется IDC скрипт для IDA, а также инструкции.<br /><br />Из всех адресов, дальше нам понадобятся два:<br />MOVED_ORIGINAL_KEY_HANDLER - это та точка входа, куда мы должны сделать переход, если хотим вызывать родной обработчик нажатия.<br />OUR_KEY_HANDLER - здесь будет наш обработчик.<br /><br />Теперь осталось только наш обработчик написать. Работа с ассемблером на этом заканчивается, на сцену выходит C. Для компиляции я использовал пакет gcc-4.1-arm для Debian. Начну с описания опций необходимых для компиляции под телефон:<br /><b>-c</b> -- делает объектный файл.<br /><b>-mcpu=arm926ej-s</b> -- компилировать под указанный процессор. Именно эти процы стоят в Siemens x65.<br /><b>-mthumb-interwork</b> -- компилировать инструкции дальнего перехода с учетом бита отвечающего за ARM/THUMB режим работы процессора. Короче вместо B и BL будет BX и BLX.<br /><b>-fomit-frame-pointer</b> -- а нафик он нужен?<br /><b>-fno-unit-at-a-time</b> -- это чтобы откомпилированные функции в объектном файле были в том же порядке, в котором они были в исходниках.<br /><b>-mlong-calls</b> -- ну длинные переходы типа.<br />Прочие опции типа -Wall -Os или -O3 - это на усмотрение.<br /><br />Допустим мы написали C файл. Скомпилировали его с вышеперечисленными опциями в объектный файл. Теперь его надо слинковать в исполняемый файл elf. Это маленькое извращение нужно для того, чтобы линкер привел все relocation'ы в норму и разместил все по тем адресам, которые мы ему скажем. Нет, конечно можно при компиляции указать -fPIC и получить оверхеадный код, но мы пойдем другим путем. Опции линкера:<br /><b>-s</b> -- удаляет всю символьную информацию. А нафик она?<br /><b>-nostdlib</b> -- Не прилинковывать никаких левых библиотек.<br /><b>-Bstatic</b> -- Эта опция говорит о том, что все релокейшены будут жестко забиты. Никаких динамически подгружаемых библиотек. Статическая компиляция.<br /><b>-X</b> -- Забыл уже зачем добавил. Но наверное надо. Пусть будет.<br /><b>-entry 0</b> -- стартовый адрес. 0 - адрес первой функции первого объектного файла. <br /><b>-R local.symbols</b> -- Файл, откуда будут подгружаться определения локальных символов.<br /><b>-R ../CX65sw50dev/firmware.symbols</b> -- определение символов прошивки.<br /><b>--section-start .text=A165F310</b> -- адрес, по которому размещать код. Как раз тот самый адрес OUR_KEY_HANDLER.<br /><b>--section-start .data=A80C8FFC</b> -- адрес, по которому размещать данные (переменные).<br /><br />Среди опций мелькнули два файла. Первый файл local.symbols:<br />my_original_press_key = 0xA165F2FC;<br />-- тут сказано, что C'ная функция с именем 'my_original_press_key' расположена по адресу '0xA165F2FC', а это тот самый адрес MOVED_ORIGINAL_KEY_HANDLER. Тоесть, чтобы вызвать из C оригинальный обработчик, я должен воспользоваться функцией void my_original_press_key (int keycode);<br /><br />Файл ../CX65sw50dev/firmware.symbols, аналогичен, сюда я внес немного функций и переменных, которые всегда есть в прошивке sw50 у cx65, например кусок:<br /><pre><br />[...]<br />switch_phone_off = 0xA1240EF0;<br />dynamic_light_mode = 0xA863E6E0;<br /><br />set_dynamic_light_mode = 0xA0B1ECDD;<br />locked = 0xA8656060;<br />[...]<br /></pre><br />Замечу, что если функция прошивки написана THUMB инструкциями, то к адресу нужно прибавить единичку, то есть адрес должен быть нечетным (младший бит включен).<br />Также напомню, что если мы хотим использовать внешние функции, то их прототипы где-то надо описать. Локальную в рамках патча функцию my_original_press_key я описал прям в .c файле, а функции и переменные прошивки в файле cx65sw50.h:<br /><pre><br />[...]<br />void switch_phone_off ();<br />void set_dynamic_light_mode (unsigned mode);<br /><br />extern unsigned dynamic_light_mode;<br />extern unsigned locked;<br />[...]<br /></pre><br /><br />Теперь все вспомогательные вещи описаны. Можно приступать к написанию самого патча.<br />Нужно помнить, что первая функция в объектном файле будет той функцией, что ляжет по адресу OUR_KEY_HANDLER. Еще нужно указывать глобальным переменным секцию .data, чтобы они вдруг не оказались в секции кода .text (как любит делать последний gcc), нужно это из-за того, что в телефоне есть флэш память (под код), а есть RAM (под переменные). Если попытаться изменить с помощью STR что-то, что лежит во флэше, то телефон пискнет и выключится.<br /><br />К нашим баранам. Первой функцией будет pressKeyChunk, которая и будет эмулировать нажатия на джойстик путем хранения состояния, вызова к оригинальному коду и т.д. Все, что нужно этой функции объявлено перед ней прототипами. Чтобы отслеживать изменение состояния светодиодов и реагировать на блокировку клавиатуры, при первом нажатии на клавишу, будет запущен таймер с частотой вызова обработчика ~0.4с. Как это все сделано можно увидеть скачав <a href="http://toril.ru/siemens/CX65-sw50-joy-patch-3.tar.gz">исходный код (5kb)</a>.<br />Для компиляции патча необходим мой <a href="http://toril.ru/siemens/CX65sw50dev-1.tar.gz">Набор-Разработчика-Патчей-Для-CX65-SW50 (6.5kb)</a>. Этот архив включает в себя:<br /><i>Makefile.inc</i> в котором прописаны правила сборки,<br /><i>cx65sw50.h</i> прототипы некоторых функций прошивки,<br /><i>firmware.symbols</i> адреса некоторых функций прошивки,<br /><i>fw50.map</i> адреса всех функций, что мне удалось найти в прошивке, пока не надоело,<br /><i>mk_patch.pl</i> скрипт для создания vkp патча на основе elf файла, использует в свой работе программу elfsh.<br /><br />Конечный vkp файл создается на основе elf файла скриптом mk_patch.pl и добавлением заголовка - файла, который мы сделали из IDA с помощью IDC скрипта.<br /><br />Вот и все. Может быть все это выглядит запутанно и сложно, но на самом деле большая часть этих функций выполняется Makefile'ом и, чтобы создать патч, надо только написать make. Общие механизмы сборки вынесены в файл Makefile.inc, а в Makefile патча остались только настройки типа адреса данных, адреса кода, опций оптимизации и т.д.<br /><br /><b>Немного слов о функциях прошивки которые я нашел (из них более 250 nucleus os).</b><br />Как я уже говорил, адреса этих функций находятся в файле fw50.map <a href="http://toril.ru/siemens/CX65sw50dev-1.tar.gz">архива (6.5kb)</a>. Если первой цифрой адреса не является 'A', то значит это смещение функции внутри секции и надо перед использованием к адресу прибавить A0000000. Какое-то количество этих функций удалось насобирать по форуму. Немного - из других патчей. Из туториалов. Что-то нашел сам. Небольшое число функций nucleus os удалось получить по сигнатурам, остальные - мой кропотливый труд.<br /><br />Перед использованием какой-то функции ее желательно проверить. Не гарантирую, что идентифицировал правильно и правильно интерпретировал.<br /><br />Для использования функций операционной системы Nucleus PLUS достаточно посмотреть на nucleus.h который есть в демоверсии этого продукта, а также можно поискать документацию по этим функциям. Самое полное, что удалось найти - это pdf под названием 'Nucleus Plus Internals'.<br /><ad></ad><br />P.S. Спасибо авторам программ IDA, ArmDebugger и V_klay, а также другим, кто писал софт для работы с Siemens x65. Без этих программ телефон скорее всего пришлось бы править паяльником или покупать новый.<br />P.S. Все это является художественным вымыслом. Совпадение с реальностью случайны. Слышал, что обезьяны в состоянии случайно Войну и Мир написать, чем я хуже?Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6827363280592532957.post-33647118714468776132006-02-22T12:09:00.002+02:002009-02-22T16:58:27.576+02:00Как я правил прошивку своего сотового телефонаВ общем решил я тут починить джойстик у своего Siemens CX65 (ношу телефон в кармане джинс вот выпирающая часть джойстика и отломилась еще месяц назад). Взял телефон, снял панель съемную, достал клей моментальный, взял хреновину одну, чтобы приклеить её к остаткам джойстика, намазал джойстик, приставил хреновину, подождал - хреновина прилипла к рукам, а не куда надо. Проделал еще пару попыток, поматерился своей лени на тему зачистить, обезжирить и тд, одел съемную панель обратно, включил телефон и заметил, что джойстик теперь совсем перестал работать, наверное капелька клея скатилась по остаткам джойстика к контактам и изолировала их. Если раньше остатки джойстика можно было как-то ногтем или вспомогательным предметом двигать, чтобы добиться нажатия в нужном направлении, то теперь это стало бесполезно.<br /><br />Для исправления новоявленной проблемы можно было бы до конца разобрать телефон и сам джойстик, а потом химическим путем убрать клей. Только есть шанс, что после этого может стать только хуже :), да и не факт, что там все дело в моем предположении. И выбрал я другой путь - надо подправить прошивку телефона, чтобы сочетания работающих клавишь имитировали джойстик.<br /><br />Первым делом требовалось вытащить эту самую прошивку из телефона, а для этого необходим шнур и програмное обеспечение. За четыре дня до прошлого нового года я купил шнур "телефон<->usb" за 1000 рублей, после чего, буквально в тот же день улетел на родину в Омск (из Москвы) на неделю, а потом в Киев еще недели на две. Когда же я вернулся в Москву и попробовал тот шнур, что купил вскрылись две детали: для телефонов сименс существует множество шнуров различающихся как по моделям телефонов, так и по функциональности. Мой шнур тогда не завелся ни в винде (с родными и не родным дровами), ни в линухе. А гарантия на обмен (15 дней) истекла, пока я мотался Москва->Омск->Москва->Киев->Москва. Но теперь, начитавшись форумов, я твердо решил взять этот шнур и переделать его из нерабочего в рабочий. Подключив его для верности в linux 2.6.15, дабы убедится, что он таки не работает, но по dmesg я увидел обратное:<pre>drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303<br />pl2303 3-1:1.0: pl2303 converter detected<br />usb 3-1: pl2303 converter now attached to ttyUSB0</pre><ad></ad><br />Поискав драйвера под винду конкретно для pl-2303 я завел его и в винде без всяких передлок. Теперь нужно программное обеспечение... к счастью, с ним никаких проблем, его полно в интернете.<br /><br />Когда телефон подружился с компьютером, настало время сделать backup этого телефона: рассчитать все коды (HASH, SKEY, IMEI, BKEY, ESN) и записав их в файлик, сделать дампы фулфлэша, буткора (на всякий), лэнгпака (на всякий), еелайта и еефула. Теперь душа спокойна, шансы окончатильно убить тело уменьшились. Для того, чтобы не патчить старую прошивку, я заодно поставил sw50 взамен стоявшей 12 версии (обновил фуллфлэш, обновил файловую систему и мэппинг). На всякий случай снова сделал бэкапы всего подрят.<br /><br />Бэкапы сделаны, прошивка лежит на винте, самое время поставить IDA, изучить ассемблер ARM710, найти в прошивке нужный код и наконец сделать патч. Для верности и на всякий случай (вдруг пригодится), собрал и поставил на свой debian binutils-arm-linux и компилятор gcc-arm-linux. Изучать набор инструкций ARM было достаточно необычно, интересно и приятно, все-таки набор отличается от x86 в лучшую сторону.<br /><br />А дальше началось изучение прошивки. Процесс надо сказать неоднозначный.. то ты начинаешь впадать в уныние не знаешь с какой стороны подойти и понять какой вызов был для чего сделан, а то вдруг неожиданно находишь интересные куски кода. Процесс изучения прошивки напоминает следующую ситуацию: вас помещают в произвольное место гиганского лабиринта из которого вам надо найти выход, у вас есть возможность телепортироваться в случайное место лабиринта по желанию, в лабиринте темно, а на полу начерчена замкнутая схема, которую можно использовать на ощупь. Сравнение может быть не очень корректное, но процесс перемещения по функциям немного напоминает.. Радостными моментами в таком деле стали: распознавание стандартных функций типа memset, strcpy, strchr, strlen, printf и т.д., обнаружении функции вызываемой в случае ошибки (не понятно правда куда она ошибку девает, толи в лог, толи еще куда, но это и не важно, а важно, что она вызывается с текстовым описанием ошибки), функции isKeyGood и наконец функции KeyPress!!! А я ведь все время был рядом с этой заветной функцией... всего-то надо было внимательнее смотреть на BFC, хотя наверное эта внимательность пришла как раз в процессе разгребания прочих участков.<br /><br />Теперь появилось чувство определенности. Самое главное - это найти где править, а это я уже сделал. Дело за малым - найти свободные участки прошвки, озу и написать патч. К сожалению скачать keil arm не получается - траффик на интернет аккаунте кончился, а keil весит под 50м, поэтому решаю покомпилировать с помощью arm-linux-as.<br /><br />Правлю участок прошивки отвечающий за обработку нажатия клавиши таким образом, чтобы он передавал управление на мой основной код (который еще не написан), а также добавляю в прошивку псевдофункцию для выполнения оригинального кода. Теоретически это все не сложно, а на практике приходится набирать команды чуть-ли не побитно, подбирая смещения - это ужасно, хотя кажется где-то я уже этим когда-то занимался. Вспомогательный код готов, можно приниматься за основной, формулирую для себя, что он должен делать.<br /><br />При нажатии на клавишу green (start) происходит переход в режим имитации джойстика. а при ее отжатии мы возвращаемся в нормальный режим, причем если в режиме имитации прочих нажатий не было, то трактуем нажатие на кнопку green как в обычном режиме. В результате при одиночном нажатии (нажали и отпустили) клавиша выполняет свою обычную функцию, а в сочетании с цифровыми клавишами - является модификатором. В свою очередь, при нажатии на цифровую клавишу смотрим, в каком режиме мы находимся: если режим расширенный, то трактуем нажатие как действие джойстика, в противном случае клавиша выполняет свои обычные действия; похожим образом обрабатываем отпускание цифровой клавиши, но тут нужно смотреть, что если мы сейчас в режиме имитации, или эта клавиша была ранее нажата в этом режиме, то имитируем отжатие джойстика, в противном случае ничего не имитируем, а трактуем отжатие как есть. При таком подходе получается следующая клавиатура телефона:<br /><table border=1><br /><tr><td>1, left-up</td> <td>2, up</td> <td>3, right-up</td></tr><br /><tr><td>4, left</td> <td>5, click</td> <td>6, right</td></tr><br /><tr><td>7, left-down</td> <td>8, down</td> <td>9, right-down</td></tr><br /></table><br />Как нетрудно заметить из функционального описания, программа должна использовать состояние. Выделяем под него 32 бита и находим свободную память для переменной с помощью ArmDebugger'а.<br /><br />Алгоритм при любом подходе получается немного сложноватый, чтобы тратить время на его реализацию на ассемблере, поэтому я набросал его на C и скомпилировал с помощью arm-linux-gcc в объектный файл. Но не все так просто, как хотелось бы. Замечательный GCC сгенерировал код использующий не хилую таблицу абсолютных адресов (для switch'а), а так как этот код будет располагаться в совершенно другом участке памяти, то надо либо править адреса руками, либо думать как объяснить gcc/as, что я хочу код для определенного участка памяти. Как объяснить GCC/AS я не нашел :(. Но зато разобрался с ld, которым слинковал объектный файл, указав, что хочу секцию .text расположить строго по такому-то адресу. Получилось! Для того, чтобы получить vkp патч на основе elf файла, пишу скрипт на perl'е, на выходе которого получаю заветный патч.<br /><br />Почти все сделано, напряжение и нетерпение растет! Загружаю патч в IDA, правлю в патче адрес переменной и адрес оригинального обработчика на реальные. Добавляю в патч изменения связанные с изменениями самой прошивки и вот патч готов!<br /><br />Немного волнуясь, загружаю v_klay, заливаю патч в телефон.<br /><ad></ad><br />Нажимаю кнопку включения - черный экран и ничего не происходит, что-то внутри опустилось. Нажимаю кнопку включения еще раз! О! Телефон включается - уже хорошо. Робко набираю первую цифру pin кода.. телефон издает характерный звук нажатия и цифра появляется на экране - значит нормальный режим отрабатывает верно. Захожу в меню и пробую режим имитации - работает, я могу бегать по меню.. работает все в том числе диагональные перемещения!<br /><br />Даже не ожидал, что патч получится с первой попытки! Какой я молодец! :)))<br /><br />А вот и сам <a href="http://toril.ru/siemens/joyemu-1.vkp">патч</a>.Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0tag:blogger.com,1999:blog-6827363280592532957.post-17861536073975589662005-12-15T18:01:00.001+02:002009-02-22T16:59:25.840+02:00Продолжаю добывать прошивку своего сименсаНапомню, что мне нужна прошивка, чтобы найти способ включения подсветки клавиатуры и включения динамического света в немигающий режим - все это чтобы сделать фонарик более ярким (у каждого своя шиза).<br /><ad2></ad2><br />Слегка продвинуться на пути получения прошивки удалось <i>найдя</i> утилиту для выковыривания xbz файла из файлов вида CX65250300.xbz_update.exe. Заметьте, <i>найдя</i> - а не написав, я очень <b>законопослушный гражданин</b> (это могут подтвердить все, кто меня хорошо знает) и если в лицензионном соглашении исполняемого файла с зашифрованной прошивкой написано, что программу <b>нельзя</b> дизассемблировать и модифицировать - то я этого конечно же не буду делать! *невин *миг :)<br /><br />Итак с помощью <a href="http://toril.ru/siemens/akxbzextr v0.tar.bz2">этой утилиты</a>, исходный код которой я разместил, на сайте, чтобы другим не пришлось искать как мне (полтора дня убил на поиск в самых закромах), мне удалось вытащить и разшифровать xbz файл.<br /><br />С другой стороны, ми опять не добрался до прошвки. Дело в том, что xbz это сжатая версия xbi.. и как его развернуть ми еще не думал. Будем искать на досуге.<br /><br />Дизассемблировать код сименовской программы нельзя, поэтому ограничусь изучением кода найденной утилиты :). Судя по-всему *xbz_update.exe файлы состоят из четырех частей:<br />1. Собтсвенно сама программа обновления телефона прошивкой приложенной к файлу.<br />2. Информация для расшифровки файла и контроля целостности. Это версия формата, таймстамп используемый как одна из составляющих IV и 128 байт сигнатуры с которой скорее всего для контроля целостности необходимо сверить хэш разшифрованного файла.<br />3. Зашифрованный с помощью Rijndael-128 (AES) файл с прошивкой в формате xbz.<br />4. Блок данных в конце exe файла в котором указано с какого смещения в exe файле начинается зашифрованная часть. Это блок данных тоже хитрым способом организован, что должно прятать смещение от посторонних глаз.<br />128 битный ключ, судя по коментарию в исходнике утилиты (кусок асеблерного кода) :), был выдран прям из exe файла, как и 128 битный IV (но первые его 4 байта это timestamp). Полагаю, что вполне вероятна ситуация в которой ключ не подойдет и надо будет его искать заново... (а приведенный кусок асм кода должен в этом помочь) кто их этих сименцев знает.. может у них на каждый апдейт свой ключ...<br />Более подробно можно узнать посмотрев исходник утилиты, или дизассемблировать программу обновления прошивки (только это запрещено лицензионным соглашением).<br /><br />К слову о... Вообще, из собственного опыта изучения программ, чье лицензионное соглашение не запрещает этого делать могу сказать, что начинать надо с сообщений (например об ошибках)!<br />Загружаем файл в какой-нибудь интерактивный дизассемблер (под unix и win32 есть бесплатный и замечательный <a href="http://hte.sourceforge.net">hte</a>), находим интересное сообщение, такое, которое вполне вероятно используется в том коде, который мы хотим найти (например password check failure) и просим интерактивный дизассеблер дать нам все места с которых есть ссылки на это сообщения... Ну, а дальше дело техники, знания ассеблера и того языка на котором написана подобытная программа.<br /><br />На самом деле, получить прошивку можно еще и:<br />1. Скачав ее из интернета. Самый простой вариант. Но если ты на GPRS (как я сейчас временно) - то он не подходит, прошивка не маленькая.<br />2. Вытащить из телефона. Для этого нужен шнурок. Я за 3000км от своего шнурка, а брать новый (400р) жаба душит.<br />3. Попробовать вытащить прошивку через irda с телефона. Помучив телефон по протоколу BFC через IRDA и увидев как на все мои корректные запросы телефон реагирует только эхом.. а на некорректные не реагирует вообще я понял, что занятие бесполезное или у меня лапы кривые. Хотя выключение телефона BFC командой работает... забавно ).<br />4. Загрузить программу обновления в vmware, сделать виртуальный порт который будет обслуживать программа имитатор моблиьного телефона. Программу я эту написал, но далеко дело не пошло, я не знаю как должен реагировать телефон на те или иные команды и поэтому дописать эмулятор телефона не смог.<ad></ad><br />5. Загрузить программу обновления прошивки в vmware и сделать suspend. Открыть файл памяти виртуально машины и выдрать оттуда прошивку. Самый просто вариант, но нужно знать какой последовательностью начинается прошивка (теперь я знаю, что она начинается Siemens Mobile Phones:SIGNATURE...) и какую длинну она имеет.Akshaalhttp://www.blogger.com/profile/05677582369584740657noreply@blogger.com0