CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Новогоднее исследование ADSL-роутера на базе Linux - 0x7 - заключение


0x0 — введение
0x1 — разбираем :)
0x2 — знакомимся с программной частью
0x3 — формат прошивки
0x4 — модифицируем файловую систему
0x5 — пишем первую программу
0x6 — последовательный порт
0x7 — заключение

Вот и крайний день новогодних каникул… Как же быстро они пролетели! А сколько ещё нужно было сделать, исследовать, написать…
Но нельзя объять необъятное и нет сил, чтобы продлить время.
Честно признаюсь — я надолго «залип» при выборе названия этого шага. Заключение? Конец? А может всё-таки нет? Разумеется нет :) Надеюсь, что это только начало. Скромный шажок в сторону настоящих встраиваемых систем и такого милого линукса :) Надеюсь, впереди нас ждёт ещё масса удивительных открытий, прозрачного кода и светлого неба. Вот только когда?..

В этом заключении — я бегло опишу — что же я ещё пробовал сделать со своим подопытным ADSL-модемом ZTE ZXDSL831AII.

Завершив шаг про консольный кабель, — я ненадолго задумался — что же делать дальше. А дальше было следующее…
Я проверил возможность автозапуска своей программы:
достаточно прописать в файл
/etc/init.d/rcS
строчку вызова своего приложения :)

Затем, я всё-таки скачал три iso-образа Redhat Linux 9.0 (в этой ОС используется версия линуксового ядра 2.4)
ftp://archive.download.redhat.com/pub/redhat/linux/9/en/iso/i386/

установил на другую виртуальную машину (установка посложнее, чем у Ubuntu, но именно с дистрибутива Redhat Linux я начинал знакомство с ОС Linux (тогда это была 6-я версия Redhat))

затем скачал и установил набор для ADSL модема D-link 2500U:
ftp://ftp.dlink.ru/pub/ADSL/GPL_source_code/RU_DSL-2500U/RU_DSL-2500U_3-06-04-3C_GPL.tar.gz (100Mb)

установка toolchain-а прошла без ошибок:


затем так же без ошибок собрался дефолтный образ прошивки.
Для его сборки нужно в каталоге, в котором распаковались файлы RU_DSL-2500U_3-06-04-3C_consumer.tar.gz выполнить команду:
# make PROFILE=RU_DSL-2500U


в Redhat Linux 9.0 всё собирается на ура:


попытка выполнить данную команду в Ubuntu тоже запускает сборку, которая, однако, вываливается с ошибкой.
Похоже дело в версии используемого GCC и сопутствующих утилит.
В Redhat Linux 9.0 используется gcc 3.2.2-5
Но я всё же попробовал наладить сборку образа под Ubuntu:
скачал rpm-пакет gcc-3.2.2-5, преобразовал его в deb-пакет и он даже установился, но попытка сборки образа прошивки — так же сваливается с ошибками.

Далее, я начал копать в сторону управления светодиодами модема.
Сначала, начал смотреть в сторону модуля ядра и даже собрал Hello World-овский модуль :)

За основу я взял статью:
Введение в написание модулей ядра Linux.
и версию модуля, которая создаёт в /proc файл hello_world и возвращает соответствующую строчку при попытке чтения данного файла.

Файл в /proc — это один из простейших и наиболее популярных способов сделать связь между ядром и пользовательскими программами.
/proc — это псевдофайловая система, где операция чтения из файлов возвращает данные, синтезированные ядром, а данные, записываемые в файлы, читаются и оперируются ядром.
Т.о. /proc предоставляет простой, предопределенный путь передачи данных между ядром и пользовательским пространством с полезными инструментами и достаточной свободой действий модулей ядра.


код модуля khello.c:
//
//
// hello world via /proc
//
//

#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h> // включает поддержку работы с /proc.

static int
hello_read_proc(char *buffer, char **start, off_t offset, 
		int size, int *eof,
                void *data)
{
		char *hello_str = "Hello, world!\n";
        int len = strlen(hello_str);

        if (size < len)
            return EINVAL;

        if (offset != 0)
                return 0;

        strcpy(buffer, hello_str);
        /*
		* Signal EOF.
		*/
        *eof = 1;

        return len;

}

static int __init
hello_init(void)
{

        if (create_proc_read_entry("hello_world", 0, 
				NULL, hello_read_proc,
                                    NULL) == 0) {
                printk(KERN_ERR
				"Unable to register \"Hello, world!\" proc file\n");
                return -ENOMEM;
        }

        return 0;
}

module_init(hello_init);

static void __exit
hello_exit(void)
{
        remove_proc_entry("hello_world", NULL);
}

module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Valerie Henson ");
MODULE_DESCRIPTION("\"Hello, world!\" minimal module");
MODULE_VERSION("proc");


Makefile:
obj-m := khello.o

all:
	$(MAKE) -C /lib/modules/`uname -r`/build/ M=`pwd` modules
insmod: all rmmod
	sudo insmod khello.ko
rmmod: 
	sudo rmmod khello|true
clean:
	$(MAKE) -C /lib/modules/`uname -r`/build/ M=`pwd` clean


Обратите внимание, на используемую команду uname -r — она возвращает текущую версию используемого ядра ОС.
В моём случае — Ubuntu 10.10 пишет:
2.6.35-22-generic


Соответсвенно, по пути /lib/modules/версия_ядра должны находиться исходные коды вашего ядра, чтобы компилятор мог подключить требуемые заголовочные файлы.

И ещё момент — данный модуль успешно компилируется и работает под ядрами версии 2.6, но под версиями ядра 2.4 оформление модуля должно быть другим (т.е. под той же Redhat Linux 9.0 — этот модуль не скомпилируется).


Выполнив команду make мы получим в папке с кодом массу файлов, самый важный из которых — это khello.ko
Попробуйте загрузить модуль:
# insmod khello.ko


и выполните чтение /proc/hello_world
работает? :)

чтобы выгрузить модуль воспользуйтесь командой
# rmmod khello


Итак, модуль работает. Остаётся скомпилировать его для нашего модема.
Для этого достаточно всего-лишь изменить Makefile:
obj-m := khello.o

all:
	$(MAKE) -C /home/noonv/adsl/ M=`pwd` modules  


, где путь /home/noonv/adsl/, у меня ведёт к директории, в которой распакованы файлы для сборки образа прошивки.

Остаётся выполнить команду make

Однако, во время попытки компиляции (под Ubuntu) вывалилось три ошибки — не удавалось найти 3 файла
по пути
/usr/crossdev/mips/bin/

сначала, выполним команду создания нужных директорий с параметром -p, чтобы создать все требуемые родительские каталоги:
# mkdir -p /usr/crossdev/mips/bin/


а далее нужно создать символьные ссылки на требуемые исполнительные файлы нашего кросс-компилятора командой ln -s:
ln -s /opt/toolchains/uclibc-crosstools_gcc-3.4.2_uclibc-20050502/bin/mips-linux-uclibc-gcc /usr/crossdev/mips/bin/mips-linux-gcc 


у меня потребовались:
mips-linux-gcc
mips-linux-ld
mips-linux-sstrip


# ls -asl /usr/crossdev/mips/bin/
total 20
4 drwxr-xr-x 2 root root 4096 2011-01-08 21:38 .
4 drwxr-xr-x 3 root root 4096 2011-01-08 21:33 ..
4 lrwxrwxrwx 1 root root   85 2011-01-08 21:36 mips-linux-gcc -> /opt/toolchains/uclibc-crosstools_gcc-3.4.2_uclibc-20050502/bin/mips-linux-uclibc-gcc
4 lrwxrwxrwx 1 root root   84 2011-01-08 21:36 mips-linux-ld -> /opt/toolchains/uclibc-crosstools_gcc-3.4.2_uclibc-20050502/bin/mips-linux-uclibc-ld
4 lrwxrwxrwx 1 root root   88 2011-01-08 21:38 mips-linux-sstrip -> /opt/toolchains/uclibc-crosstools_gcc-3.4.2_uclibc-20050502/bin/mips-linux-uclibc-sstrip


пробуем выполнить make

в итоге — в Ubuntu, make всё равно заканчивается с ошибкой, но модуль всё же создайтся.
(в RedHat — компиляция модуля происходит безо всяких проблем)

исходный код и файл модуля — khello.tar.gz

ну что же проверяем :)
сбросим файл модуля в наш традиционный user/bin и соберём корневую файловую систему —
sq6.zip

прошивка с модулем khello:
result-sq6-khello.zip

подключаемся

# cd /usr/bin
# ls -asl
   1 lrwxrwxrwx    1 0        0              17 tftp -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 test -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 tty -> ../../bin/busybox
   0 -rwxrwxrwx    1 0        0              37 mytest
   1 lrwxrwxrwx    1 0        0              17 expr -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 logger -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 [ -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 ftpget -> ../../bin/busybox
   4 -rw-r--r--    1 0        0            3716 khello.ko


модуль есть — попробуем его загрузить
# insmod khello.ko
# cat /proc/modules
khello 992 0 - Live 0xc00c8000
ipt_multiport 672 0 - Live 0xc00c6000
ipt_REDIRECT 768 0 - Live 0xc00c4000
ip_nat_rtsp 4816 0 - Live 0xc009a000
ipt_state 544 1 - Live 0xc00c0000
ipt_MARK 704 0 - Live 0xc00be000
ipt_TCPMSS 2304 0 - Live 0xc00bc000
ip_conntrack_irc 68896 0 - Live 0xc00aa000
ipt_limit 896 0 - Live 0xc00a8000
ipt_connlimit 1696 0 - Live 0xc00a6000
ip_nat_ftp 2976 0 - Live 0xc00a4000
ipt_MASQUERADE 3280 0 - Live 0xc005d000
ip_conntrack_ftp 20608 1 ip_nat_ftp, Live 0xc009d000
ipt_mark 416 0 - Live 0xc0081000
ipt_FTOS 992 0 - Live 0xc007f000
ipt_RDNS 1152 1 - Live 0xc007d000
ipt_dns 640 1 - Live 0xc005f000
ip_nat_ipsec 46720 0 - Live 0xc008d000
ip_conntrack_ipsec 30640 0 - Live 0xc0074000
ip_nat_h323 5056 0 - Live 0xc0044000
ip_conntrack_h323 35280 1 ip_nat_h323, Live 0xc0083000
ip_conntrack_rtsp 73024 1 ip_nat_rtsp, Live 0xc0061000
ip_nat_pptp 2048 0 - Live 0xc005b000
ip_conntrack_pptp 3312 0 - Live 0xc0059000
ip_nat_gre 1280 0 - Live 0xc0057000
ip_conntrack_gre 2064 2 ip_nat_pptp,ip_conntrack_pptp, Live 0xc0055000
iptable_mangle 960 1 - Live 0xc0042000
iptable_nat 15632 9 ipt_REDIRECT,ip_nat_rtsp,ip_nat_ftp,ipt_MASQUERADE,ip_nat_ip
sec,ip_nat_h323,ip_nat_pptp,ip_nat_gre, Live 0xc0050000
ip_conntrack 29984 17 ipt_REDIRECT,ip_nat_rtsp,ipt_state,ip_conntrack_irc,ipt_co
nnlimit,ip_nat_ftp,ipt_MASQUERADE,ip_conntrack_ftp,ip_nat_ipsec,ip_conntrack_ips
ec,ip_nat_h323,ip_conntrack_h323,ip_conntrack_rtsp,ip_nat_pptp,ip_conntrack_pptp
,ip_conntrack_gre,iptable_nat, Live 0xc0047000
iptable_filter 928 1 - Live 0xc0037000
ip_tables 14144 15 ipt_multiport,ipt_REDIRECT,ipt_state,ipt_MARK,ipt_TCPMSS,ipt_
limit,ipt_connlimit,ipt_MASQUERADE,ipt_mark,ipt_FTOS,ipt_RDNS,ipt_dns,iptable_ma
ngle,iptable_nat,iptable_filter, Live 0xc0026000
bcm_usb 15984 0 - Live 0xc0008000
bcm_enet 25312 0 - Live 0xc002c000
br2684 66016 0 - Live 0xc000e000

# ls /proc
802          8            uptime       cpuinfo      net          iomem
676          7            meminfo      partitions   sysvipc      mtd
675          6            version      stat         sys          nvram
674          5            devices      interrupts   fs           var
481          4            filesystems  slabinfo     driver       hello_world
202          3            cmdline      buddyinfo    tty
44           2            locks        vmstat       bus
18           1            execdomains  diskstats    irq
10           self         mounts       modules      misc
9            loadavg      kmsg         kcore        ioports

модуль загрузился!
проверим его работу:
# cat /proc/hello_world
Hello, world!

нууууууууу! сууууууууууууупер! Вы как хотите, но это решительно здорово! :)

Зачем нам нужен модуль ядра?
А затем, что Linux не позволяет обратиться напрямую к регистрам. Либо через ядро, либо через драйвер. Поэтому, для общения с железом модема нам и нужен собственный драйвер, который предоставляет пользовательским приложениям стандартный интерфейс взаимодействия (каждый девайс — есть файл).

Итак, кажется что остаётся теперь наполнить модуль для работы с GPIO светодиодов.

GPIO (General Purpose Input/Output) — вывод (пин) чипа, чьим состоянием можно программно управлять.
Выводы GPIO не имеют специального назначения и по-умолчанию не используются.

GPIO, по сути, является портом ввода\вывода, который нужен для реализации различных функций.
В частности, для:
* включения/выключения индикаторов (например, светодиодов)
* управления некоторыми сигналами выбора внешнего чипа (сигналы chip_select, сокращенно CS)
* обслуживания прерываний с внешних устройств

документация gpio в ядре Linux: gpio.txt
Для работы с GPIO в модуль нужно подключить одноименный заголовочный файл:
#include <linux/gpio.h>



И тут я обнаружил, что в исходниках ядра, который идёт в RU_DSL-2500U_3-06-04-3C_GPL.tar.gz
его просто нет :(
Ну и ладно, решил я, — придётся пока отложить разбирательство с GPIO, к тому же я нашёл другой — более «простой» способ поработать со светодиодами :)

Я спросил себя — а как же прошивка работает со светодиодами — если не через gpio.h?
Полез смотреть исходники. Не знаю, всё ли правильно я понял в структуре исходников, но я нашёл вот такие интересные файлы:
bcmdrivers\opensource\include\bcm963xx\bcm_map_part.h
#ifndef __BCM_MAP_PART_H
#define __BCM_MAP_PART_H

#if defined(CONFIG_BCM96338)
#include <6338_map_part.h>
#endif
#if defined(CONFIG_BCM96348)
#include <6348_map_part.h>
#endif
#if defined(CONFIG_BCM96358)
#include <6358_map_part.h>
#endif

#endif

— т.е. в зависимости от заданного типа процессора — он подключает соответствующий заголовочный файл, в нашем случае 6338_map_part.h, который нашёлся здесь:
shared\opensource\include\bcm963xx\6338_map_part.h

и в котором есть вот такие интересные строчки:
#define PERF_BASE           0xfffe0000
#define TIMR_BASE           0xfffe0200 
#define UART_BASE           0xfffe0300
#define GPIO_BASE           0xfffe0400
#define SPI_BASE            0xfffe0c00 

...

typedef struct GpioControl {
  uint32        unused0;
  uint32        GPIODir;      /* bits 7:0 */
  uint32        unused1;
  uint32        GPIOio;       /* bits 7:0 */
  uint32        LEDCtrl;
#define         LED3_STROBE             0x08000000
#define         LED2_STROBE             0x04000000
#define         LED1_STROBE             0x02000000
#define         LED0_STROBE             0x01000000
#define         LED_TEST                0x00010000
#define         LED3_DISABLE_LINK_ACT   0x00008000
#define         LED2_DISABLE_LINK_ACT   0x00004000
#define         LED1_DISABLE_LINK_ACT   0x00002000
#define         LED0_DISABLE_LINK_ACT   0x00001000
#define         LED_INTERVAL_SET_MASK   0x00000f00
#define         LED_INTERVAL_SET_320MS  0x00000500
#define         LED_INTERVAL_SET_160MS  0x00000400
#define         LED_INTERVAL_SET_80MS   0x00000300
#define         LED_INTERVAL_SET_40MS   0x00000200
#define         LED_INTERVAL_SET_20MS   0x00000100
#define         LED3_ON                 0x00000080
#define         LED2_ON                 0x00000040
#define         LED1_ON                 0x00000020
#define         LED0_ON                 0x00000010
#define         LED3_ENABLE             0x00000008
#define         LED2_ENABLE             0x00000004
#define         LED1_ENABLE             0x00000002
#define         LED0_ENABLE             0x00000001
  uint32        SpiSlaveCfg;
#define         SPI_SLAVE_RESET         0x00010000
#define         SPI_RESTRICT            0x00000400
#define         SPI_DELAY_DISABLE       0x00000200
#define         SPI_PROBE_MUX_SEL_MASK  0x000001e0
#define         SPI_SER_ADDR_CFG_MASK   0x0000000c
#define         SPI_MODE                0x00000001
  uint32        vRegConfig;
} GpioControl;

#define GPIO ((volatile GpioControl * const) GPIO_BASE)

/* Number to mask conversion macro used for GPIODir and GPIOio */
#define GPIO_NUM_MAX_BITS_MASK          0x0f
#define GPIO_NUM_TO_MASK(X)             (1 << ((X) & GPIO_NUM_MAX_BITS_MASK)) 


а пример работы со светодиодами реализован в:
bcmdrivers\opensource\char\board\bcm963xx\impl1\bcm63xx_led.c
вот код одной из функций:

// turn led on and set the ledState
void ledOn(PLED_INFO pLed)
{
    if( pLed->ledMask )
    {
        if (pLed->ledSerial) {
#if defined(CONFIG_BCM96358)
            while (GPIO->SerialLedCtrl & SER_LED_BUSY);
            if( pLed->ledActiveLow )
                GPIO->SerialLed  &= ~pLed->ledMask;    // turn on the led
            else
                GPIO->SerialLed  |= pLed->ledMask;     // turn on the led
#endif
        }
        else {
            GPIO->GPIODir |= pLed->ledMask;         // turn on the direction bit in case was turned off by some one
            if( pLed->ledActiveLow )
                GPIO->GPIOio  &= ~pLed->ledMask;    // turn on the led
            else
                GPIO->GPIOio  |= pLed->ledMask;     // turn on the led
        }
        pLed->ledState = pLed->savedLedState = kLedStateOn;
    }
}


Выходит, что GPIO_BASE задаёт адрес памяти по которому доступны регистры GPIO.

Далее, я прочитал, что доступ просто получить через memory mapping (/dev/mem), причём — для этого не нужен специальный драйвер ядра!

Таким образом, через /dev/mem можно читать-писать любые адреса памяти или устройств (т.к. все устройства отображены на память).
Для работы используется функция mmap()

mmap — системный вызов Unix, позволяющий выполнить отображение файла или устройства на память. Является методом ввода/вывода через отображение файла на память

документация mmap

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);



Для дальнейших исследований воспользуемся утилиткой memwrite — если программе передать один параметр, то она покажет данные по данному адресу, а если задать и второй параметр, то она запишет эти данные по адресу в первом параметре.

соберём утилиту и сбросим в наш usr/bin/
сразу утилита не запустилась — ругнулась, что функция atoll() не поддерживается (программа собирается, но на модеме запускаться отказывается)
заменим atoll() на atol() :)

исходник и программа — memwrite-blank.tar.gz

# cd usr/bin
# ls
tftp      memwrite  mytest    logger    ftpget
test      tty       expr      [
# ls -asl
   1 lrwxrwxrwx    1 0        0              17 tftp -> ../../bin/busybox
   0 lrwxrwxrwx    1 0        0              17 test -> ../../bin/busybox
   7 -rwxr-xr-x    1 0        0            7602 memwrite
   1 lrwxrwxrwx    1 0        0              17 tty -> ../../bin/busybox
   0 -rwxrwxrwx    1 0        0              37 mytest
   0 lrwxrwxrwx    1 0        0              17 expr -> ../../bin/busybox
   1 lrwxrwxrwx    1 0        0              17 logger -> ../../bin/busybox
   0 lrwxrwxrwx    1 0        0              17 [ -> ../../bin/busybox
   0 lrwxrwxrwx    1 0        0              17 ftpget -> ../../bin/busybox
# memwrite
pagesize = 4096
do_page_fault() #2: sending SIGSEGV to memwrite for invalid read access from
00000000 (epc == 2ab07a70, ra == 0040082c)
SIGSEGV

# memwrite 4096
pagesize = 4096
basepage=00001000, baseoff = 00000000, destaddr = 00001000
Old value:
addr[00001000]=0xFFFFFFF7 0xFFFFFFFA 0xFFFFFFED 0xFFFFFFFE


но до нужного адреса я что-то никак не мог добраться, пока не модифицировал memwrite так, что отсчёт нуля теперь начинался от
#define PERF_BASE           0xfffe0000

т.е. просто добавляю это значение к первому параметру:
base = PERF_BASE + atol(argv[1]);


модифицированный memwrite — исходник и программа специально для bcm6338 — memwrite-bcm6338.tar.gz

корневая файловая система — sq7.zip

файл прошивки — result-sq7-memwrite.zip

чтож, теперь посмотрим, что покажет модифицированная версия memwrite для bcm6338

# memwrite 1024
pagesize = 4096
basepage=FFFE0000, baseoff = 00000400, destaddr = FFFE0400
Old value:
addr[FFFE0400]=0x00 0x00 0x00 0x00

# memwrite 1032
pagesize = 4096
basepage=FFFE0000, baseoff = 00000408, destaddr = FFFE0408
Old value:
addr[FFFE0408]=0x00 0x00 0x00 0x00

# memwrite 1036
pagesize = 4096
basepage=FFFE0000, baseoff = 0000040C, destaddr = FFFE040C
Old value:
addr[FFFE040C]=0x00 0x00 0x00 0x7A

# memwrite 1040
pagesize = 4096
basepage=FFFE0000, baseoff = 00000410, destaddr = FFFE0410
Old value:
addr[FFFE0410]=0x00 0x00 0x03 0x00

# memwrite 1044
pagesize = 4096
basepage=FFFE0000, baseoff = 00000414, destaddr = FFFE0414
Old value:
addr[FFFE0414]=0x00 0x00 0x08 0x09

в общем, стал я разбираться и сумел поуправлять двумя светодиодами — Ethernet и USB:

USB led off, Ethernet led off (биты: 0000 0000) — светодиоды выключены
# memwrite 1024 0
pagesize = 4096
basepage=FFFE0000, baseoff = 00000400, destaddr = FFFE0400
Old value:
addr[FFFE0400]=0x00 0x00 0x00 0x00
New value:
addr[FFFE0420]=0x00 0x00 0x00 0x00


USB led on (биты: 0001 0000) — светодиод USB — горит
# memwrite 1024 16
pagesize = 4096
basepage=FFFE0000, baseoff = 00000400, destaddr = FFFE0400
Old value:
addr[FFFE0400]=0x00 0x00 0x00 0x00
New value:
addr[FFFE0420]=0x00 0x00 0x00 0x00


Ethernet led on (USB led off) (биты: 0010 0000) — светодид Ethernet горит, USB — выключен
# memwrite 1024 32
pagesize = 4096
basepage=FFFE0000, baseoff = 00000400, destaddr = FFFE0400
Old value:
addr[FFFE0400]=0x00 0x00 0x00 0x00
New value:
addr[FFFE0420]=0x00 0x00 0x00 0x00


Ethernet led on, USB led on (биты: 0011 0000) светодиоды Ethernet и USB — горят
# memwrite 1024 48
pagesize = 4096
basepage=FFFE0000, baseoff = 00000400, destaddr = FFFE0400
Old value:
addr[FFFE0400]=0x00 0x00 0x00 0x00
New value:
addr[FFFE0420]=0x00 0x00 0x00 0x00


Воооот. Другие светодиоды я пока не победил, но думаю принцип уже понятен :)
(кстати, если кто справится с остальными светодиодами — дайте знать :)

UPD по подсказке neitrino:
утилита управления светодиодами ledctrl отыскалась в исходниках:
RU_DSL-2500U_3-06-04-3C_consumer\userapps\opensource\busybox\miscutils\ledctrl.c
работает, общаясь с /dev/brcmboard через ioctl.

Кажется — пока всё :)
Вот стоит себе тихонько эта маленькая коробочка модема, но сколько нового, увлекательно-интересного она позволила узнать! Получилось настоящее погружение в мир встроенных систем и более близкое знакомство с линуксом.
Разумеется, отладочные платы в этом плане намного удобнее, но если модем/роутер уже есть или приобрести его проще (и дешевле), то и он вполне поддаётся настойчивости исследователя :)

Далее: Превращаем ADSL-модем в Ethernet-шилд
Исследование Wi-Fi-роутера TP-LINK TL-MR3020

Ссылки:
Введение в написание модулей ядра Linux.
Writing device drivers in Linux: A brief tutorial
The Kernel Newbie Corner: Your First Loadable Kernel Module
mini2440 Работа с GPIO из Linux

Программы:
khello.tar.gz
memwrite-blank.tar.gz
memwrite-bcm6338.tar.gz

Автор: Vladimir (noonv), 2011

Эксклюзивно для www.robocraft.ru
копирование на другие ресурсы и публикация
без разрешения автора запрещены.
  • +1
  • 10 января 2011, 12:19
  • noonv

Комментарии (13)

RSS свернуть / развернуть
+
0
А как установить unsquashfs версии 1.5 с поддержкой LZMA. Я ее скачал распоковал а как установить и использовать непойму(Ubuntu 10.4).
avatar

himik

  • 10 января 2011, 13:19
+
+1
просто запустить.
avatar

noonv

  • 10 января 2011, 13:30
+
0
Он пишет мол не найдено программы для запуска
avatar

himik

  • 10 января 2011, 13:32
+
0
если внимательнее присмотреться к примеру вызова в статье, то можно увидеть, что перед названием программы символы
./
, которые указывают, что для запуска используется программа в текущей директории. Если Вы запускаете программу, которая находится где-то в другом месте, то нужно просто прописать абсолютный или относительный путь до неё:
абсолютный путь: /usr/bin/mytest
относительный путь: ../mytest — запустит программу из родительской директории.

(это основы ОС Linux и если Вам это внове, то рекомендую сначала почитать соответствующие статьи)
avatar

noonv

  • 10 января 2011, 13:43
+
0
Захожу в папку где лижит unsquashfs запускаю терминал и выполняю
./unsquashfs sqsh.bin

пишет нет доступа, тогда запускаю из под рута
sudo ./unsquashfs sqsh.bin
и снова ошибка
sudo: ./unsquashfs: command not found

avatar

himik

  • 10 января 2011, 14:02
+
0
Ну все вроде разобрался надо было
/media/74ACA603ACA5BFCA/unsquashfs sqsh.bin
avatar

himik

  • 10 января 2011, 14:06
+
0
И еще один вопрос, когда я запаковываю прошивку и пишу
./mksquashfs squashfs-root/ sq3.bin -be  -no-fragments -noI -all-root -noappend -lzma -b 65536
выскакивает ошибка
libstdc++.so.5: cannot open shared object file: No such file or directory
хотя у меня судя по всему установлен libstdc++ 6
avatar

himik

  • 10 января 2011, 14:56
+
0
советую очень внимательно перечитать статью. там содержатся ответы на все ваши вопросы.
avatar

noonv

  • 10 января 2011, 16:28
+
0
Если вы про это
sudo apt-get install libstdc++5
то при установки пишет ошибку
E: Не удалось найти пакет libstdc++5
avatar

himik

  • 10 января 2011, 16:43
+
0
проблема гуглится на счёт раз ;) например так:
Ubuntu 10.04 libstdc++5
и, о чудо! мы узнаём, что в репозиториях Ubuntu 10.04 (и Ubuntu 9.10) этой библиотеки нет.
А решить эту проблему можно просто сходив на packages.ubuntu.com и скачав требуемый deb-пакет вручную.
avatar

noonv

  • 10 января 2011, 19:31
+
+1
У меня модем DLink 2500U H/W Ver:A1
В папке бин есть программа ledctrl
# ledctrl

Usage: ledctrl led_name led_state

Supported led names:
Adsl
Wireless
Usb
Hpna
WanData
PPP
Voip
Alarm

Supported led states:
Off
On
Fail
BlinkOnce
SlowBlinkContinues
FastBlinkContinues
#
принимает два параметра, имя индикатора и какой режим установить.
avatar

neitrino

  • 11 января 2011, 20:25
+
0
о! спасибо! эта утилита отыскалась в исходниках:
RU_DSL-2500U_3-06-04-3C_consumer\userapps\opensource\busybox\miscutils\ledctrl.c
работает, общаясь с /dev/brcmboard через ioctl.
avatar

noonv

  • 11 января 2011, 21:06
+
0
нашел несколько модемов ZXDSL 831 II в них используется Flash с параллельным доступом и судя по даташиту на чип BOARDCOM bcm6338 вывод SPI остается свободным (незадействованным).
Так как я в линуксе еще не силен настолько;
1. как можно задействовать данный интерфейс.
2. Можно ли реализовать USB host на данном модеме, т.е. конечно это реализуется программно, но как? Подключить к нему bluetooth или USB flash накопитель?
avatar

targetorsk

  • 4 июля 2011, 15:34

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.