воскресенье, 22 марта 2009 г.

CeBootLin - автозагрузка Linux/Android из WinCE на Loox 5XX (560/550)

Написал "bootloader" для загрузки Linux/Android из WinCE автоматически при включении КПК. Это не настоящий bootloader, так как он не имеет ничего общего с загрузочными секторами, это просто WinCE приложение, которое начинает свою работу как можно раньше, чтобы загрузить Linux. Я сделал это именно так, а не иначе, из-за того, что не хотел убить свою КПК изменением бут секторов или иметь сложный механизм перепрошивок, обновлений и т.д. Автозагрузка из WinCE мне показалась досточно неплохим решением, имеющим разве что 3-4 секундный проиграш, если сравнивать с нормальным bootloader'ом, который еще помучиться реализовать надо. Также, такая рализация позволяет достаточно легко пропустить загрузку Linux и продолжить загрузку WM5 или WM6.. Код основан на утилите Haret (спасибо им), но я удалил ненужные мне части. Так как загрузчик использует аппаратные регистры для работы с клавиатурой и подсветкой (GPIO/CPLD) Fujitsu Siemens Loox N560/C550, то без изменений кода данный загрузчик не заработает на другой модели КПК...
Когда КПК включается и начинается загрузка WinCE, то ядро WinCE читает список приложений из HKEY_LOCAL_MACHINE\init и запускает их. Таким способом загружается CeBootLin. CeBootLin начинает мигать подсветкой клавиатуры и ждет одну секунду. В то время, пока клавиатура подмигивает, пользователь может нажать и отпустить какую-нибудь кнопку КПК - это сигнал для CeBootLin не продолжать загрузку Linux. Если никакие кнопки нажаты не были, то CeBootLin попытается открыть \CeBootLin\default.txt и будет использовать его в качестве скрипта Haret для загрузки Linux'а.

Итого, чтобы поставить и настроить CeBootLin, надо проделать такие шаги:
1. Скачать CeBootLin.
2. Распаковать содержимое архива в корень основной памяти КПК. CeBootLin.exe должен быть доступен по пути \CeBootLin\CeBootLin.exe.
3. Поместить default.txt в каталог \CeBootLin. Файл default txt может например выглядеть так (для загрузки Andorid'а, например):

set MTYPE 1454
set KERNEL "\CeBootLin\zImage"
set CMDLINE "root=179:3 mem=62M rootdelay=3 boot_delay=0 init=/init console=tty0 fbcon=rotate:0 androidboot.console=tty0 android.checkjni=1"
set RAMADDR 0xA0200000
bootlinux

4. Поместить zImage в каталог \CeBootLin\.

5. Добавить в HKEY_LOCAL_MACHINE\init значение для Launch82 ="CeBootLin.exe" и Depend82 = 14 00.


6. Добавить в HKEY_LOCAL_MACHINE\Loader\SystemPath путь \CeBootLin\

7. Подождать 5 минут или типа того (WinCE нужно время, прежде чем она сохранит обновление в registry).
8. Перезагрузить КПК

Если возникнут какие-то проблемы, то первым делом стоит проверить, а грузит ли CeBootLin.exe вообще ядро... для этого достаточно просто его запустить.

В дальнейшем при желании можно сделать нормальный cab с setup'ом внутри, который, например, будет ставить андройд..

Здесь находятся исходные коды CeBootLinux. CeBootLinux лицензирован под GNU GPL.

воскресенье, 15 марта 2009 г.

Фотографии Android и Linux на Fujitsu-Siemens Loox N560


Сегодня судьба WM5 - загрузить Linux


Haret.. все что нужно - нажать Run


Android на Loox N560


Установка Debian'а на Loox N560


Установка Debian'а на Loox N560

Тестирование памяти на Loox N560/C550

Недавно набросал "утилиту" для тестирования памяти на Fujitsu-Siemens Loox N560/C550. Нужна она тем, кто перепаевает память (с 64М на 128М) и хочет проверить ее работоспособность "на месте" без переустановки WM5. Итак, для того, чтобы протестировать память КПК:
1. Качаем LooxMem128-v0.zip (чтобы тестировать 128Мб памяти) или LooxMem64-v0.zip (чтобы тестировать 64Мб памяти).
2. Заливаем распакованный архив на SD карточку.
3. Карточку вставляем в Loox и перегружаем КПК.
4. Не давая КПК заснуть, запускаем haret.exe из архива, что распаковывали на SD карточку.
5. После запуска haret.exe нужно нажать на Run.
6. Загрузится linux и появится предупреждение.
7. Читаем предупреждение и либо нажимаем на RESET (на попе у КПК) либо нажимаем enter..
ВНИМАНИЕ: Накачественная память при тестировании может сгореть (собственно "утилита" для этого и нужна, чтобы выявлять такую память). Ни я, ни авторы memtester ни кто иной кроме вас никакой ответственности за это нести не будет. Вы тестируете память на свой страх и риск!!

Замечание: При тестировании необходимо раз в 3-5 минут нажимать какую-нибудь кнопку КПК, чтобы КПК не заснула...
(Для портирования "утилиты" на другую платформу достаточно заменить ядро zImage и поправить default.txt.)

суббота, 14 марта 2009 г.

Ядро linux для Loox N560/C550 с рабочим CPLD и светодиодами

Добавил поддержку CPLD и светодиодов. Для CPLD был заюзан драйвер htc-gpio с перечислением адресов регистров CPLD на Fujitsu-Siemens Loox 5XX (N560/C550). Теперь CPLD доступен для других драйверов.

Примечательно, как в 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.
На основе работающиго CPLD драйвера для Loox N560/C550 реализовал драйвер управления светодиодами КПК. Драйвер экспортирует методы и константы которые другие драйвера (wifi, gps, bluetooth, pm, ...) должны использовать для управления светодиодами. Также драйвер позволяет контролировать светодиоды из userspace пространства путем манипуляций с файлами sysfs.

Ниже перечисленны файлы и значения которые могут находиться:
/sys/devices/platform/loox5xx-leds.1/keyboard: on, off, any
- подсветка клавиатуры

/sys/devices/platform/loox5xx-leds.1/left_green: on, off, any
- зеленый светодиод с левой стороны. WM5 использует для индикации активности WiFi

/sys/devices/platform/loox5xx-leds.1/left_blue: on, off, any
- голубой светодиод с левой стороны. WM5 использует для индикации активности Bluetooth

/sys/devices/platform/loox5xx-leds.1/left_orange: on, off, any
- оранжевый светодиод с левой стороны. WM5 использует для индикации активности GPS на Loox N560

/sys/devices/platform/loox5xx-leds.1/right_green: on, off, any
- зеленый светодиод на правой стороне КПК. WM5 использует как светодиод доступный приложениям (нотификации и т.д.)

/sys/devices/platform/loox5xx-leds.1/right_orange: on, off, blink, any
- оранжевый светодиод с правой стороны КПК. WM5 использует для индикации процесса зарядки

Где:
on - светодиод включен независимо от желаний ядра,
off - светодиод выключен независимо от желаний ядра,
blink - светодиод мигает независимо от желаний ядра,
any - светодиод контролируется ядром.

Например, если установить right_orange в состояние on, то светодиод зарядки будет гореть независимо от того, заряжается КПК или нет. Это будет продолжаться до тех пор, пока в файл right_orange не будет записано значение any. После чего, первое же событие (установка КПК в крэдл и т.д.) переключит светодиод в соответствующее состояние. Sysfs интерфейс для светодиодов позволяет использовать светодиоды из программ для нотификации о событиях (пришла почта, кончается заряд и т.д.) с помощью всех доступных на устройстве светодиодов - насколько хватит фантазии. Например следующий shell код мигает подсветкой клавиатуры:

while true;
do echo on > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
echo off > /sys/devices/platform/loox5xx-leds.1/keyboard;
sleep 0.1;
# Condition for break...
done
echo any > /sys/devices/platform/loox5xx-leds.1/keyboard;


Актуальный патч на cupcake ядро андройда качать здесь.

вторник, 10 марта 2009 г.

Полезные команды для межплатформенной работы

Несмотря на то, что debian/emdebian уже содержат громадное количество пакетов под armel, иногда нужно собрать или пересобрать что-то из исходников.

Сборка пакетов в emdebian происходит например так:
emsource --arch armel -b memtester

Установка собранного пакета НЕ на целевом устройстве, а на хостовом, выполняется например вот так:

dpkg-cross -a armel -i zlib1g-dev_1.2.3.3.dfsg-13em1_armel.deb
При этом команда dpkg -l | grep zlib1g выдаст:

ii zlib1g-dev-armel-cross 1:1.2.3.3.dfsg-13em1

(dpkg-cross автоматически переназвала установленный пакет и разместила его содержимое в /usr/arm-linux-gnueabi)

Чтобы пользоваться командой emsource без привелегий root'а, надо настроить ~/.apt-cross/emsource например вот так:

workingdir: /home/akshaal/.apt-cross-working-dir

Сборка пакета под armel из исходников, которые уже развернуты и имеют каталог debian производится командой:

dpkg-buildpackage -aarmel

понедельник, 9 марта 2009 г.

Установка emdebian на PDA (C550/N560)

Последовательность действий, выполнив которую я без проблем установил debian на свой Fujitsu-Siemens Loox N560. Я предполагаю, что emdebian-tools уже установлен, а также стоят всякие кросскомпиляторы под arm платформу.

Первым делом необходимо собрать архив базовой системой:
cd /tmp;
mkdir grip/
sudo debootstrap --arch=arm --foreign lenny grip/ http://www.emdebian.org/grip/
cd grip/
sudo tar -czf /tmp/emdebian-grip-arm-debootstrap.tgz .
Теперь необходимо переразбить SD карточку выделив на ней раздел под linux:

cfdisk /dev/sdX
mkfs.ext3 /dev/sdXy

где sdX - это устройство с SD картой, а sdXy это раздел который предполагается использовать под linux. Теперь монтируем раздел и разворачиваем туда emdebian-grip-arm-debootstrap.tgz:

mount /dev/sdXy /mnt
cd /mnt
tar zxpvf /tmp/emdebian-grip-arm-debootstrap.tgz
ln -s bin/sh init
cd /tmp
umount /mnt

Теперь, когда раздел подготовлен, загружаем с него linux и выполняем следующие команды:
cd /debootstrap
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
run ./debootstrap --second-stage
dpkg --configure -a
rm /init
cd /
ln -s sbin/init init
Теперь перегружаем linux еще раз. В этот раз должно появится приглашение залогинится. Используем root без пароля. И конфигурируем основные настройки:

echo 'nameserver 1.1.1.1' > /etc/resolv.conf
echo '127.0.0.1 localhost' > /etc/hosts
echo '172.16.0.2 myhost 172.16.0.2' >> /etc/hosts
echo 'myhost' > /etc/hostname

Вместо 1.1.1.1 нужно использовать IP DNS сервера. И снова перегружаем КПК. Теперь конфигурирем сеть:

ifconfig usb0 172.16.0.1 netmask 255.255.255.0
route add default gw 172.16.0.1
Убеждаемся, что сеть работает. Апгрейдим пакеты:

echo 'deb http://www.emdebian.org/grip/ sid main' > /etc/apt/sources.list
echo 'deb http://ftp.debian.org/debian/ sid main contrib non-free' >> /etc/apt/sources.list
apt-get update
apt-get dist-upgrade
apt-get install ...что угодно...

И теперь настраеваем сеть так как это положено (собственно это можно было зделать и раньше, но тут можно уже залогинится через ssh и нормально все сделать с помощью copy&paste с ББ...):
cat > /etc/network/interfaces
auto lo
iface lo inet loopback
allow-hotplug usb0
iface usb0 inet static
address 172.16.0.2
netmask 255.255.255.0
network 127.16.0.0
broadcast 172.16.0.255
gateway 172.16.0.1
dns-nameservers 1.1.1.1
dns-search your.domain

суббота, 7 марта 2009 г.

Ядро linux для Loox N560/C550 с рабочим usbnet'ом

После 3х дней мучений все-таки собрал ядро linux для Fujitsu-Siemens Loox N560/C550. Ядро брал с http://www.asm32.ru. Потратив еще несколько часов разобрался как запустить usbnet (сеть через обычный usb шнурок). Для этого пришлось дополнительно пропатчить pxa27x_udc.c. Сделал diff между текущей версией ядра андройда и теми исходниками (за 02-03-09), что выложены на asm32. В дальнейшем при обновлении ядра в cupcake'овской ветке можно будет просто накладывать этот патч сверху имея в результате и изменения под c550/n560 и исправления/дополнения внесенные в cupcake ветку. Вот итоговый патч в который также включены изменения для работы usbnet. В патче уже имеется .config, но там не включена поддержка usbnet. Вот другой config, он отличается от того, что в патче (а там тот, что выложен на asm32) поддержкой usbnet, выключенной power management (зачем не знаю, потом надо будет включить обратно), и настройкой для более крупного шрифта в консоли.. может еще чем-то.

Собирать ядро можно с помощью любого toolchain'а. Я пробовал собирать с помощью: crosstool-ng, emdebian, а также того, что идет вместе с ядром андройда. Остановился на emdebian'е. Для сборки ядра emdebian'ом необходимо выполнить:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Предварительно emdebian конечно же нужно установить, например так:

apt-get install emdebian-tool
emsetup --arch arm
Добавить:

deb http://www.emdebian.org/debian/ unstable main

в /etc/apt/sources.list и выполнить:
apt-get install linux-kernel-headers-arm-cross gcc-4.2-arm-linux-gnu


Готовое ядро запускается haret'ом с конфигом:

set MTYPE 1454
set KERNEL zImage
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"
set RAMADDR 0xA0200000
bootlinux

И самое главное! После того, как ядро закинуто на sd карточку, эту sd карточку нужно вставить в КПК и ребутнуть КПК. А уже только после этого грузить haret'ом ядро! Ибо ядро не грузится (либо грузится с вероятностью 10%), если:
1. КПК заснула, а потом ее разбудили.
2. Вы только что вставили в КПК карточку.
Наверное это бага драйвера wince...

P.S. Cupcake на который накладывается выложенный патч качается отсюда http://source.android.com/download

P.P.S. При сборке с поддержкой usbnet опцию CONFIG_USB_ETH_RNDIS
включать не следует! Ибо в этом случае ПК не может нормально соеденится с КПК.. ни cdc_ether ни cdc_subset не видят usb устройство.

пятница, 6 марта 2009 г.

Related Posts / Похожие темы

Написал расширение (widget) для тем blogger'а. Расширение отображает список постов похожих по меткам. Данное расширение отличается от всех прочих Related Posts Widget'ов тем, что очень легковесно и не замедляет загрузку страницы браузером, так как выполняет дополнительные запросы к серверу параллельно (асинхронно) с загрузкой страницы. Более того, записи сортируются не только с учетом даты написания постов, но и с учетом релевантности (по меткам). Так как у меня несколько блогов и мне не хочется заниматься рутиной, то я постарался написать виджет как можно более простым для установки.

Итак, чтобы установить это расширение в своем блоге, необходимо произвести две довольно простые модификации HTML шаблона (HTML Template'а). Для этого нужно открыть Настройки (Settings) -> Макет (Layout) -> Изменить HTML. Перед тем как менять что-то далее, сделайте резервную копию шаблона (Загрузить весь шаблон)! После чего нужно пометить галочкой Расширить шаблоны виджета (Expend Widget Templates). После чего можно приступать к редактированию:
1. В поле с текстом шаблона нужно найти строку <data:post.body/>. И вот сразу за этой строкой нужно аккуратно вставить следующий код:
<div caption='Похожие темы:' id='akRelatedPosts' max='8'/>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
<script language='javascript' type='text/javascript'>
(function(_1,_2){var _3={};var _4=_2.length;var _5=function(_6){var _7=&quot;([0-9]{4})(-([0-9]{2})(-([0-9]{2})(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?&quot;;var d=_6.match(new RegExp(_7));var _9=0;var _a=new Date(d[1],0,1);if(d[3]){_a.setMonth(d[3]-1)}if(d[5]){_a.setDate(d[5])}if(d[7]){_a.setHours(d[7])}if(d[8]){_a.setMinutes(d[8])}if(d[10]){_a.setSeconds(d[10])}if(d[12]){_a.setMilliseconds(Number(&quot;0.&quot;+d[12])*1000)}if(d[14]){_9=(Number(d[16])*60)+Number(d[17]);_9*=((d[15]==&quot;-&quot;)?1:-1)}_9-=_a.getTimezoneOffset();time=(Number(_a)+(_9*60*1000));return Number(time)};var _b=function(){var _c=[];for(var i in _3){_c.push(_3[i])}if(_c.length&lt;1){return}var _e=document.getElementById(&quot;akRelatedPosts&quot;);if(!_e){return}var _f=_e.getAttribute(&quot;max&quot;)||5;_c=_c.sort(function(a,b){var _12=b.weight-a.weight;if(_12!=0){return _12}return b.date-a.date});var s=&quot;&lt;ul&gt;&quot;;for(var i in _c){if(_f--&lt;1){break}var _14=_c[i];s+=&quot;&lt;li&gt;&lt;a href=&#39;&quot;+_14.href+&quot;&#39;&gt;&quot;+_14.title+&quot;&lt;/a&gt;&lt;/li&gt;&quot;}s+=&quot;&lt;/ul&gt;&quot;;var _15=_e.getAttribute(&quot;caption&quot;);s=&quot;&lt;span class=&#39;caption&#39;&gt;&quot;+_15+&quot;&lt;/span&gt;&quot;+s;_e.innerHTML=s};var _16=function(_17){for(var i in _17.feed.entry){var _19=_17.feed.entry[i];var _1a=_19.id[&quot;$t&quot;];var _1b=_3[_1a];if(_1b){_1b.weight++}else{var _1c;for(var _1d in _19.link){if(_19.link[_1d].rel==&quot;alternate&quot;){_1c=_19.link[_1d].href;break}}if(_1c==_1){continue}_1b={weight:1,title:_19.title[&quot;$t&quot;],date:_5(_19.published[&quot;$t&quot;]),href:_1c};_3[_1a]=_1b}}if(--_4==0){_b()}};var _1e=function(_1f){var _20;try{_20=new XMLHttpRequest()}catch(excp1){try{_20=new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;)}catch(excp2){try{_20=new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;)}catch(excp3){_20=false}}}var _21=function(){if(_20.readyState==4){if(_20.status==200){_16(eval(&quot;(&quot;+_20.responseText+&quot;)&quot;))}}};_20.open(&quot;GET&quot;,_1f,true);_20.onreadystatechange=_21;_20.send(null)};for(var _22 in _2){_1e(_2[_22])}} <!-- = = = = = endoffunc = = = = = = -->
)(&quot;<data:blog.url/>&quot;,[
<b:loop values='data:post.labels' var='label'>
&quot;/feeds/posts/default/-/<data:label.name/>?alt=json&amp;max-results=5&quot;<b:if cond='data:label.isLast != &quot;true&quot;'>,</b:if>
</b:loop>
]);
</script>
</b:if>
Должно получиться что-то типа вот этого (на картинку можно нажать и нормально рассмотреть):
Обратите внимание на caption='...' и max='8' Значения в кавычках можно изменить. Значение для caption определяет текст, который будет высвечиватся над списком похожих постов. Значение max определяет максимальное количество элементов в списке.
2. Это изменение вобщем-то и не обязательно, все должно заработать и без него. Но выглядеть оно будет не очень. Поэтому, этим шагом производится настройка внешнего вида. Для этого необходимо найти строку ]]></b:skin>. И перед(!) этой строкой вставить вот такой кусок настроек:
#akRelatedPosts {
padding-top: 20px;
}

#akRelatedPosts .caption {
font-weight: bold;
}

#akRelatedPosts ul {
margin: 0;
}
Если есть желание и знание css, то можно тут подкрутить стили как душе угодно. Должно получиться как-то вот так:
Это все. Можно сохранять шаблон и пробовать.

четверг, 5 марта 2009 г.

Локальное тестирование AJAX запросов

Иногда бывает очень удобно отлаживать javascript сценарии без заливки на сервер, а просто путем запуска из локально html файла. Но таким образом не получается протестировать скрипты делающие асинхронные запросы. Связано это с тем, что firefox не дает выполнять запрос, если домен в запросе не соответствует домену с которого этот запрос выполняется - делается это из соображений безопасности.
uncaught exception: Access to restricted URI denied (NS_ERROR_DOM_BAD_URI)
Но если вы отдаете себе отчет в том что делаете, то никто не мешает отключить эту проверку. Для этого нужно открыть about:config и установить signed.applets.codebase_principal_support в true. Также перед выполнением запроса в javascript'е, необходимо выполнить следующий код:
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

Самое главное, по окончанию тестирования не забыть удалить эту строку из скрипта и установить signed.applets.codebase_principal_support в false!!