Как написать прошивку для камеры

Это продолжение рассказа о лучших (по мнению участников) докладах HighLoad++ 2017. В предыдущей статье я писал о двух лидерах рейтинга. Идем дальше. В этом материале — доклад Вадима Антонюка о фродах и Макса Лапшина  — о прошивке для IP-камеры на Rust.

Fraud in mobile applications: how to define and detect, Vadim Antonyuk (4,73 балла)

Почетное третье место. Вадим не первый раз рассказывает про антифрод на Highload++. Годом ранее он говорил об антифроде в RTB-системах в целом, в этот раз «досталось» мобильным приложениям. Забегая вперед, скажу, что до сих пор идут споры о том, что считать фродом именно в мобильных приложениях, в отличие от веба, где все более-менее понятно. Тем не менее, растет и сам сегмент, и вместе с ним проблема. А значит, самое время начать ее решать — «пока не началось».

Между тем, если вы не знаете или все еще сомневаетесь, что RTB — это хайлод, — как вам цифра в 400 миллиардов запросов в сутки? При этом по статистике на долю мобильных приложений приходится около 40% — больше, чем на десктопный веб. IPONWEB (один из крупных игроков рынка RTB-рекламы) достаточно давно и успешно детектирует фрод в веб-сегменте, но до приложений добрались только вот-вот.

Итак. Классические методы (боты, AdStackng, Domains Spoofing, Ghost sites), которые давно применяются в классическом вебе, в мобильных приложениях в явном виде не работают. Как следствие, не подходят и методы борьбы с ними, и нужно изобретать что-то новое.
Кстати, индустрия еще не договорилась о том, что считать фродом в мобильных приложениях. Казалось бы, истории с рекламой в мобилках уже прилично, но факт остаётся фактом, и об этом говорит Вадим.

В докладе рассматриваются два (а на самом деле почти три) подхода детектирования фрода:

  • Backgroundness — показ рекламы в фоновом режиме. Суть такого типа фрода  — в его названии. То есть реклама есть, но пользователь ее не видит. Как ее искать? Все не очень сложно, но есть нюансы.  Суть изначального метода состоит в поиске в потоке входящих запросов всех запросов от пары «приложение+пользователь», которые шлют запросы непрерывно. Вычисляются такие интервалы и делается анализ на реалистичность.

    Например, на слайде ниже поток сигналов T1 с интервалом между сигналами t1 можеть быть достаточно длинным, часов 10, что почти наверняка говорит о том, что это фрод. Ведь пользователь не может смотреть на экран 10 часов без перерыва. Если собрать статистику по этому приложению, можно с высокой степенью вероятности вычислить негодяев. Но, как обычно, есть нюанс — метод зависит как минимум от двух параметров, и оба из них вычисляются эмпирически.

    Можно сделать проще? Оказывается, что можно опираться только на значение T (период непрерывного испускания сигнала) и анализировать интервалы между соседними отрезками времени (в нашем примере — искомый интервал  между T1 и T2. Если в течение суток нет реалистичного перерыва (допустим, 6 часов), то, скорее всего, что-то пошло не так. В итоге при большом числе измерений от одного приложения точность метода растет.

  • Второй метод — Entropy Score.  Поиск негодяев через аномальную энтропию. Чтобы стало понятнее, рекомендую предварительно почитать вики. Метод строится на последовательном численном анализе поведения пользователей и приложений. Вычисляется Entropy Score, за счет большого числа измерений определяется допустимый интервал значения этого параметра — когда с высокой степенью вероятности поведение приложения и пользователя являются реальными —  а все остальные приложения подвергаются анализу.  

    Чуть более сложный метод используется и в IPONWEB в качестве дополнения к первому. Он позволяет поймать приложения, у которых небольшое число пользователей, даже несмотря на то, что непрерывного потока запросов нет.  В качестве примера приводятся приложения для искусственного просмотра рекламы.

  • Третий метод не выделен явно. В нем анализируется большое число запросов с одного устройства. По сути это аналог бота в вебе. Так что если вернуться к началу разговора, то Вадим немного лукавил, когда говорил, что методы анализа фрода в вебе не подходят.

    В итоге за счет применения комбинации методов идентификации фрода ребята из IPONWEB отфильтровывают более 15% трафика. Очень солидный показатель с учетом общего числа запросов. Все методы — вероятностные, и всегда есть вероятность ошибки.

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

Если эта тема заинтересовала, то можно полистать ссылки под спойлером или просто погуглить термины, которые упоминает Вадим. Единственное, что немного раздражает — львиная доля инфы на эту тему представляет собой полурекламные статьи в обмен на почту от команд, которые занимаются как рекламой, так и борьбой с фродом.

Делаем свою прошивку для IP-камеры на Rust, Макс Лапшин (Max Lapshin) (4,70 балла)

Макс — постоянный участник айтишных мероприятий, член программного комитета Highload++, автор очень быстрых и производительных решений для стриминга видео, которыми пользуются по всей планете, знаток erlang’a и просто отличный спикер. Его рассказ не вошел в тройку лучших, но послушать его обязательно надо — хотя бы потому, что его компания — одна из немногих в России успешно продвигает свой программный продукт на мировом рынке.

Непосредственно про стриминг и его нюансы Макс рассказывал на прошлых конференциях. В этот раз речь шла о том, как поменять софт на IP-камерах, как появился в этой истории Rust, и что из этого вышло. В докладе две части: первая — непосредственно про специфику работы с IP-камерами, вторая же посвящена Rust’у и его особенностям.

Несмотря на то, что IP-камеры широко распространены, дешевы, а аппаратная платформа с каждым годом становится все надежнее, софт для IP-камер оставляет желать лучшего. То есть вместе с камерой вы получаете софт 10-12 летней выдержки со всеми дефектами, отсутствием фич, а главное — невозможностью вносить изменения. В итоге разумнее всего написать свой софт, чтобы получить набор нужных фич и снизить сложность работы с устройством. Кстати, вариант сделать свою камеру тоже был — но от него отказались ввиду дороговизны и длительности, а также необходимости работать с уже существующими камерами, которых миллионы.

По сути IP-камера является компьютером с процессором, памятью и прочими узлами, а значит и работать с ней можно, например, по аналогии с мобилками. Так же, как и в мобилках, здесь есть куча вариантов исполнения внутреннего программного обеспечения: где-то что-то можно писать, где-то только читать, есть разный U-boot (мощный загрузчик с кучей нужных для заливки функций) с разным софтом для перезаписи, есть большой набор различных шлейфов, щипцов и паяльников. Ну и, как следствие, — вылезают все прелести перепрошивки вашего любимого андроида: скакнуло питание — камера превратилась в кирпич, ошиблись в прошивке — снова кирпич. Благо, стоимость такого «кирпича» на текущий момент в пределах десяти долларов за штуку.

Чтобы облегчить себе жизнь, можно, как только удается добыть документацию на камеру и взломать ее, положить на нее софт, позволяющий производить дальнейшее обновление более привычным способом.

После сборки можно смело приступать к прошивке. Оказывается, что то, что вы раньше считали «зоопарком» технологий, — детский лепет по сравнению с тем, когда речь идет о камерах. Различные версии ядра, библиотек, SDK — абсолютная норма для них. Нормой же следует считать полное отсутствие возможности погонять тесты без заливки на камеру, жесткую нехватку места (8 мегабайт, ага), а также постоянную работу с железом и точное управлением памятью.  Подытожим  — камера очень интересный и одновременно дешевый прибор (можно смело экспериментировать и превращать камеры в кирпичи), с которым можно очень неплохо взаимодействовать, достигая свои цели.

Вторая часть рассказа всецело отдана Rust’у и его особенностям. Внимательный слушатель обязательно отметит для себя причины, по которым был выбран именно Rust, а не старый добрый С.

Следующие два слайда демонстрируют результаты, которые были достигнуты при использовании этого пока не очень распространенного языка для работы с железом.

Детально останавливаться не буду, отмечу только, что Макс очень доходчиво объясняет любителям хайпа, что за все надо платить, и Rust — не исключение.  В заключении отмечается, что, несмотря на внешнюю сложность, использовать для полу-embedded систем Rust можно, и это свежо и прикольно, хоть и придется немного переформатировать свой мозг.

От себя замечу, что многие вещи, о которых говорит Макс, характерны для разработки большинства встраиваемых систем. Если вы нацелились на это направление — обязательно послушайте.


В скором времени вас ждет обзор еще четырех докладов. Если же вы сами готовы поделиться опытом или интересными кейсами в области хайлода, управления и тимлидерства, программирования или мобильной разработки, приглашаем стать спикером соответствующей секции РИТ++ 2018. В программном комитете уже открыт прием заявок, которые можно оставить тут. Возможно, именно ваш доклад станет лучшим в этом году.

Привет, меня зовут Олег Герасимов, я директор центра компетенций IT-кластера Ростелекома. Наша команда среди многих задач разрабатывает прошивки камер видеонаблюдения для B2B и B2C-сервисов. В предыдущей статье я рассказывал, как мы научились самостоятельно разрабатывать софт и прошивки для IP-камер, в том числе и недорогих, и подключать их к облаку.

За прошедшее время камеры с нашей прошивкой уже появились на рынке, и, судя по данным Яндекс.Маркета, — на полках магазинов цены на них начинаются от 1500 рублей. И это уже не дешевый «ноунэйм», а качественные камеры ведущих мировых брендов: Hikvision, Dahua и Uniview. На мой взгляд, это отличный результат!

Когда мы начинали работать с прошивками, количество поддерживаемых моделей камер было небольшим. В процессе разработки общих компонентов мы самостоятельно реализовывали поддержку новых моделей камер.

Тогда у нас была возможность самим выбирать, какие модели интегрировать в первую очередь, а какие нет, исходя из технических соображений.
Например, если в камере используется сенсор, под который в SDK процессора нет драйвера, то драйвер сенсора придется разработать самим. Это очень трудоемкий процесс, требующий сложной разработки и отладки. Сенсор — технически сложный компонент, и на одно изучение технического описания (Datasheet) сенсора могут уйти недели. Это, на секундочку, сотни страниц с описанием тысяч регистров, влияющих на работу сенсора, и логики взаимодействия с ними.

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

Следующий этап разработки прошивок для камер совпал с объявлением тендера на закупку камер. Это уже серьезное событие. Ростелеком закупал сотни тысяч камер на открытом тендере, в который могли войти любые вендоры камер, соответствующих по своим ТТХ продуктовым и техническим требованиям.

Одно из ключевых требований к поставщикам — предоставление технической информации о схемотехнике камер, например, о GPIO-выводах, к которым подключены светодиоды, кнопки, ИК фильтры и т.д. Кроме этой информации, мы просили вендоров предоставить специфичные для оборудования патчи ядра/загрузчика и исходные тексты драйверов устройств, в первую очередь, сенсоров и WI-FI чипов.

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

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

Самостоятельно найти ошибку в спецификациях или драйверах получалось не всегда, да и искать ошибки в стороннем коде — небыстрое занятие. Поэтому чаще для решения проблемы приходилось обращаться к вендорам. Как правило разработчики, которые могут ответить на вопросы о схемотехнике, найти
и поправить ошибки в драйверах, находятся в Китае. А это сразу замедляет коммуникацию — одна итерация «вопрос-ответ» может занимать несколько дней, а исправление ошибок и того дольше.
Пока поток новых камер был небольшим такой режим устраивал, но со временем запросы от маркетологов выросли. Возникла потребность в интеграции большего количества линеек: уличные камеры с Wi-Fi, домашние с PTZ, с сиреной и т.д. Но с другой стороны, по мере развития облачного видеонаблюдения увеличивалось количество вендоров, желающих работать с нами.

В этот момент мы поняли, что силами команды с возросшим в разы количеством новых камер уже не справиться. Всё время разработки
будет занимать исключительно интеграция новых камер, а на разработку новых фич и улучшения времени не останется. Нужно было найти новый подход.

Мы начали анализировать узкие места процесса. Они оказались на поверхности: больше всего времени уходило на итерации получения патчей и драйверов, багрепорты в сторону вендоров и ожидание исправлений.

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

Техническое решение, с одной стороны, очевидное: сделать SDK для сборки нашей прошивки. Но есть ряд требований:
SDK должен уметь собирать прошивки под все типы поддерживаемых SoC. На сегодня это больше 10 чипсетов от Hisilicon, Ambarella, MStar и Fullhan.

  • Нельзя передавать компоненты прошивок от одного вендора другим, потому что это интеллектуальная собственность. Мы подписываем NDA, в котором обязуемся не раскрывать передаваемую информацию.
  • Результаты интеграции, полученные от вендора, нужно уметь замерджить в общее дерево исходников прошивки в нашем Git.
  • У вендора должна быть возможность вносить патчи и дополнения во все компоненты: ядро, загрузчик, SoC SDK и прочие.
  • Нужно иметь гибкую структуру настроек, в которой будут учитываться максимальное количество возможных конфигураций оборудования.
  • Для каждой пары «вендор-SoC» должна собираться универсальная прошивка, поддерживающая все камеры вендора на базе этого процессора.
  • Сборка должна работать автономно и не требовать доступа в Интернет. Да, большинство разработчиков ПО для камер в Китае не имеют доступа в Интернет на рабочих местах.

Структура системы сборки, в тот момент, была не готова к такому подходу. Например, в некоторых файлах конфигурации были совмещены настройки камер от нескольких вендоров, а для сборки прошивки и загрузки пакетов требовался доступ к нашим внутренним репозиториям. Да и некоторые места системы сборки (чего греха таить) не предполагали такого масштабирования: их разработали в то время, когда поддерживался один тип процессора и две модели камеры…

Другая проблема: под каждый процессор поставляется отдельный SDK от его производителя, с уникальным набором системных компонентов: своя версия и набор патчей ядра, toolchain, uboot, системная библиотека (где-то uclibc, а может быть glibc). Под эти факторы приходится подстраивать систему сборки, а местами и код приложений. Для наглядности масштабов фрагментации вот табличка со списком версий компонентов:

Как видно, разброс огромный: от легаси десятилетней давности до относительно свежих ревизий.

С такими вводными нам предстоял рефакторинг системы сборки прошивок: выделить общие патчи и драйвера, которые будут доступны для всех вендоров, повторить это для 10+ поддерживаемых моделей SoC, полностью переосмыслить систему конфигурации наших компонентов. Заодно выпилить специфичные для камер костыли из init-скриптов, сделав общие и универсальные решения.

В результате мы пришли к структуре, в которой все специфичные для конкретных моделей настройки/конфигурации/makefile/патчи собраны в папках, структурированную по иерархии «Вендор → SoC → Модель камеры». Такая иерархия позволила автоматизировать сборку SDK с разделением сборок по вендорам. Вот пример, драйверы и конфигурации для камер от выдуманного вендора Megatech на чипсете Hisilicon.

Структура каталогов

Драйверы

drivers 
+ megatech/             -> драйвера и конфиги для вендора 'megatech'
| + hi3518ev200/        -> чипсет hisilicon hi3518ev200
| | + 1421              -> конфигурации модели камеры с кодом оборудования 1421
| | | | + ipcdb.1421.yml -> общая конфигурация
| | | | + mpi/entry.1421.yml -> конфигурация видеозахвата
| | | | + ptz/entry.1421.yml -> конфигурация PTZ
| | + motor             -> драйверы моторов управления PTZ
| | | + bu24036_motor   -> драйвер шагового мотора на чипе bu24036
| | | | gpio_motor      -> драйвер шагового мотора управляемый GPIO выводами
| | + wlan              -> драйверы wi-fi чипов 
| | | + Makefile        -> скрипт сборки 
| | + sensor            -> драйверы сенсоров
| | | + Makefile        -> скрипт сборки 

Патчи ядра

kernel
+ megatech/
| + hi3518ev200/
| | + mmc_hotplug.patch
| | + kernel-config.patch

Патчи uboot

uboot
+ megatech/
| + hi3518ev200/
| | + uboot-mmc.patch
| | + uboot-spi.patch

Все файлы конфигурации камер перевели в формат YAML, как самый удобный для ручного редактирования, и разделили по компонентам:

  • Настройки оборудования модели камеры (GPIO, наличие и тип Wi-Fi, сенсора, флаги наличия микрофонов, динамиков, дополнительные скрипты инициализации).

Пример yaml

1421:
  vendor: megatech
  model: Model A
  soc: 3518ev2
  ethernet: 0
  wlan: rtl8188eu
  sensor: ov9732
  leds:            
    ir:            
      gpio: 23
      inverse: true
    red:           
      gpio: 10
    power:
      gpio: 10     
    green:
      gpio: 2
    net:
      gpio: 2
  keys:
    wps:
      gpio: 16
    reset:
      gpio: 16
  peri-out:
    pwdn:
      gpio: 1
      inverse: true
    ircut.p:
      gpio: 57
    ircut.n:
      gpio: 60
    wifi_pwr:
      gpio: 7
  flash: spi
  misc:
    microphone: true
    speaker: true
    mic_hpf_level: 3
    mic_anr_level: 4
  scripts:
    insert-sns:
      - himm 0x200f0040 0x2; # I2C0_SCL
      - himm 0x2003002c 0xc4001; # sensor unreset, clk 24MHz, VI 99MHz
    init-wlan:
      - insmod 8188eu.ko

  • Настройки видеоприложения для конкретной модели (тип сенсора, поддерживаемые разрешения, режимы синхронизации и видеозахвата, подстройки алгоритмов).

Пример yaml

1421:
  sensor:
    type: ov9732
    lib: libsns_ov9732.so
  resolutions:
    - targets: 
        - { width: 1280, height: 720, maxrate: 30 }
        - { width: 640, height: 480, maxrate: 30 }
        - { width: 640, height: 360, maxrate: 30 }
        - { width: 320, height: 240, maxrate: 30 }
      channels:
        - main
      source: { width: 1280, height: 720, rates: [30, 25] }

  combo_dev_attr:
    input_mode: CMOS_33V
  vi_dev_attr:
    interface_mode: DIGITAL_CAMERA
    component_mask: [67043328, 0]
    syn_cfg:
      vsync: field
      vsync_neg: high
      hsync: valid_signal
      hsync_neg: high
      vsync_valid: valid_signal
      vsync_valid_neg: high
      timing_blank: [ 370, 1280, 0, 6, 720, 6, 0, 0, 0 ]
  isp_image_attr:
    bayer_format: BGGR

  • Настройки PTZ (тип чипа, тайминги работы шаговых драйверов).

Пример yaml

1421:
  type: pan_controller_and_tilt_gpio_generic
  interrupt_gpio: 50
  absolute: true
  pan:
    park_ccw: false
    continuous: [-20, 20]
    relative: [-7.9, 7.9]
    absolute: [0, 355]
    channel: 0
    min_wait: 100
    max_step: 140
    max_speed: 375
    unity: 430
  tilt:
    park_ccw: true
    continuous: [-20, 20]
    relative: [-3.5, 3.5]
    absolute: [0, 90]
    max_step: 2000
    unity: 157

Выбор способа сборки дистрибуции SDK был очевидным. Docker оказался вне конкуренции, с его помощью можно легко передать подготовленную среду.
Мы использовали Docker практически с самого начала разработки, как в CI, так и для локальной отладки на компьютерах разработчиков.

Процесс сборки полностью автоматизирован. Docker-образы с нашим SDK собираются в общем CI под матрицу сочетаний «SoC-вендор».

Исходно у нас было два основных репозитория:

  • build-tools — в нем хранятся Dockerfile, скрипты установки SoC SDK и скрипты сборки общих библиотек для поддерживаемых аппаратных платформ. В CI этого репозитория собираются Docker-образы со всем необходимым для сборки прошивки и софта под целевую платформу.
  • vc-firmware — здесь хранится система сборки прошивки и компонент. К этому же репозиторию как git-submodule подключены репозитории с исходниками наших компонентов: видеоприложение, облачный агент, модуль обновления). Результатом работы CI в этом репозитории являются сами прошивки камер.

Для нового SDK добавили еще один репозиторий, vc-sdk, к которому подключили vc-firmware и build-tools как git-submodule. В CI этого репозитория сборка разделена на этапы:

  • подготовка базового Docker-образа по аналогии с репозиторием build-tools;
  • сборка пакетов с компонентами (видеоприложение, облачный агент, модуль обновления);
  • загрузка пакетов с общими компонентами (публичные библиотеки, драйверы Wi-Fi и т.д.)
  • копирование каталогов с драйверами и патчами, специфичными для вендора

В результате работы CI получается автономный Docker-образ, рассчитанный на сборку прошивок для камер на выбранном чипе вендором. Он загружался
в общий registry образов, из которого вендор может скачать свой образ.

Следующий объемный фронт работ — разработка документации. Документацию мы писали поэтапно, собирая обратную связь от вендоров и учитывая замечания. Кстати, для документации использовался наш инструмент Foliant. Про него наши ребята уже рассказывали на митапе «Write the Docs Moscow» (https://habr.com/ru/post/431210/).

Заключение

За этот год уже 8 вендоров освоило использование нашего SDK, с его помощью добавили поддержку работы с видеонаблюдением Ростелекома в нескольких десятков новых моделей камер. Некоторые из этих камер уже продаются.

Важно, что выбранный подход — разработка собственной прошивки на базе SDK — работает на потребителей: интеграция камер таким способом позволила организовать честную конкуренцию при тендере на закупку камер. Победители выявляются по объективным показателям: качеству оборудования и наименьшей стоимости.

Наконец, если раньше количество поддерживаемых моделей камер было ограничено силами и ресурсами команды, то сегодня эта проблема ушла в прошлое. Теперь вендоры камер могут сами добавлять поддержку новых моделей через облако РТК.

  Давненько что-то я здесь ничего не писал, вот, взял себя в руки и решил, что надо бы. Ведь до сих пор я так и не написал мануал по разборке/сборке и модификации прошивок камер D-Link DCS-2210 (и множества других на основе SoC DaVinci DM365, и даже не только D-Link, но IP-камер от некоторых других производителей, например от ENEO). Итак, обо всём по порядку…

Часть 0. Общие сведения о прошивке DCS-2210.

  Прежде всего, нужно рассказать, что собой представляет прошивка IP-камеры D-Link DCS-2210. Сама прошивка состоит из четырех частей (блоков? разделов? тут уж кому как удобнее…). Вот они:

  1. u-boot.env — представляет собой бинарно-текстовый файл, в котором находятся переменные окружения для начального загрузчика Das U-Boot. Почему я назвал его бинарно-текстовым? На то есть причины, и я обязательно еще вернусь к этому файлу в следующей статье, он довольно интересен. На распаянной на плате камеры микросхеме флеш-памяти при прошивке камеры содержимое этого файла записывается в раздел mtdblock0, но не с самого начала раздела, а с адреса 0x1c00.
  2. kernel.img — как, я полагаю, становится понятно из названия файла, это образ ядра Linux. Тут ничего экстраординарного, просто образ ядра MontaVista Linux v5.0. На флешке для ядра выделен диапазон адресов 0x00200000-0x00400000, это раздел mtdblock3.
  3. www.jffs2 — образ раздела в формате jffs2, в котором находится содержимое папки www, предназначенное для функционирования внутреннего web-сервера камеры. Раздел может занимать адреса в диапазоне 0x00c00000-0x01000000, это раздел mtdblock6.
  4. ipnc.jffs2 — это низкоуровневый софт от производителя устройства, в этом разделе в формате Jffs2 находятся бинарники, не входящие в состав ядра, но тем не менее, необходимые для нормального функционирования камеры. Диапазон адресов 0x01000000-0x01a00000, раздел — mtdblock7.

 И все!

  «И всё??? WTF??? Где корневая файловая система?» — спросите вы. Да, всё верно, в состав прошивок от D-Link НЕ входит образ rootfs. Почему ядро есть, а rootfs нету, я не знаю. Ну да ладно, будем отталкиваться от того, что имеем. Теперь предлагаю взглянуть на полную карту организации флеш-памяти в IP-камере DCS-2210:


Диапазон адресов       Название раздела на флешке Имя файла   Примечания
=============================================================================================================
0x00000000-0x02000000  nand_image    (mtdblock0)              (Всё содержимое флешки)
0x00004000-0x00100000  bootloader    (mtdblock1)              (Начальный загрузчик Das U-Boot)
0x00100000-0x00200000  backup kernel (mtdblock2)              (Запасное ядро, как его юзать - ума не приложу)
0x00200000-0x00400000  kernel        (mtdblock3)  kernel.img  (Ядро Linux)
0x00400000-0x00b00000  rootfs        (mtdblock4)              (Корневая ФС Linux)
0x00b00000-0x00c00000  config data   (mtdblock5)              (Параметры работы устройства)
0x00c00000-0x01000000  web page      (mtdblock6)  www.jffs2   (Html, cgi и прочие файлы для вебсервера)
0x01000000-0x01a00000  firmware      (mtdblock7)  ipnc.jffs2  (Вендор-специфичные бинарники)
0x01a00000-0x02000000  sensor data   (mtdblock7)              (Пустой раздел)

А u-boot.env записывается в mtdblock0 с адреса 0x1c00 и имеет размер 16384 байта.

  Как я уже говорил, в состав файла прошивки входят лишь 4 файла: u-boot.env, kernel.img, www.jffs2 и ipnc.jffs2, хотя при сборке прошивки в результирующий файл теоретически можно добавить и другие разделы, но об этом поговорим чуть позже. Файлы эти в файле прошивки собраны воедино, и, похоже для того, чтобы усложнить жизнь любопытным, зашифрованы шифром Вернама с одноразовым блокнотом, содержащимся где-то в глубине прошивки (точно не знаю где, я в этом не очень-то разбираюсь).

Часть 1. Разбираем прошивку.

  Для разборки нам, разумеется, нужна сама прошивка камеры. Топаем на support.dlink.com или на ftp2.dlink.com скачиваем её оттуда. Для удобства переименовываем файл в dcs2210.bin. Теперь нам нужно распаковать этот файл. Сам бы я с этой задачей никогда не справился и эта заметка никогда не появилась бы, если бы не товарищ под ником leecher. Он смог разобраться во внутреннем устройстве файла прошивки и написал утилитку для распаковки прошивки. Взять исходный код этой утилиты для Linux можно с его сайта http://dose.0wnz.at/ipcams/ или скопипастить из спойлера ниже:

[Spoiler (click to open)]

/******************************************
 * D-Link Firmware unpacker V1.0          *
 * DCS-2130, DCS-2230, DCS-6815, DCS-3710 *
 * DCS-3716, DCS-6511, DCS-6818, DVS-210  *
 * DCS-6616, DVS-310                      *
 *                                        *
 * Version 1.00                09/2012    *
 * http://www.hardwarefetish.com          *
 ******************************************/

#include 

#define HEADER_MAGIC 0xAA7EC55B

#define SECT_SIGN	0xA55A
#define SECTT_AUTO	0
#define SECTT_JFFS2	1
#define SECTT_YAFFS	2
#define SECTT_NONE	3

#pragma pack(1)
typedef struct
{
	unsigned short hdr;	// A55A
	char mtd;
	char section_type;
	unsigned long size;
	unsigned long offset;	// # of 0x4000 chunks?
	char padding[52];
} sec_head;

static char *sectypes[] = {
	"AUTO ",
	"JFFS2",
	"YAFFS",
	"NONE "
};

typedef struct {
	int Signature;
	int size;
	unsigned short checksum;
	unsigned short scramble;
	unsigned short hdrBlocks;	// ?? Don't really know that this is
	unsigned short machine_code;
} fm_header;
#pragma pack()

fm_header FmHead;
unsigned short scramble = 0x2021;
unsigned short machine_code = 0x2021;

unsigned short random1[] =
{
0x07CC, 0x33A8, 0xAEA8, 0x5A00, 0xDD42, 0x518E, 0x45B2, 0x0DED, 
0x6D05, 0xD447, 0x9C3F, 0x4678, 0xB113, 0x7BF8, 0x4510, 0xB3F8,
0x9C21, 0xFD90, 0x8055, 0xB43A, 0xCE09, 0x5294, 0x6100, 0xD7DC, 
0x989A, 0x4EC7, 0xC3D3, 0xFF7E, 0xEF08, 0xA4DA, 0xD9D3, 0xF6D4,
0xD883, 0x887B, 0x50D4, 0xB5C5, 0xDA09, 0x9687, 0xC3B3, 0x470F,
0x6ACE, 0x5FF2, 0x8D87, 0x1BE1, 0xDBEA, 0xD297, 0xCFDA, 0x780B,
0xD027, 0x502F, 0x2C45, 0x9E31, 0xA2C3, 0x8D45, 0x760D, 0x3B5D, 
0xDC0D, 0x39E1, 0x3ADB, 0xCB15, 0xDEBB, 0x14AE, 0xC1E9, 0xB73E,
0x9D2A, 0x12BD, 0x6D04, 0x7733, 0xA944, 0x30B7, 0xBE42, 0x1413, 
0x90A9, 0x4BC9, 0x2FF4, 0x6C93, 0x1E60, 0xFFCE, 0xE49E, 0xEE88,
0x4FFE, 0x10E4, 0x8CB9, 0xF2C1, 0x9E29, 0x02C6, 0x2E1F, 0x7A36, 
0x3CA7, 0x68FA, 0x454B, 0x1B63, 0x7DA9, 0x0734, 0xD2A1, 0x1AD3,
0x19F2, 0x3FA5, 0x9206, 0xC336, 0x705C, 0x5049, 0xD749, 0x0105,
0x9C12, 0x073E, 0x6D98, 0xBA73, 0x070C, 0x5237, 0xA8FB, 0x570A,
0x631B, 0x35B4, 0x49CC, 0x0144, 0x387A, 0x77EB, 0x7B7B, 0x7522, 
0xE0E5, 0xC0C6, 0x9085, 0x5E8E, 0xC7FB, 0x6326, 0x7961, 0xE1ED,
0xA2CC, 0x0B68, 0xA523, 0x1328, 0x5BB1, 0x7C6D, 0x142E, 0xF7C3, 
0x83AB, 0x81C6, 0xB236, 0x8AB7, 0xD3FD, 0x5B31, 0xE1C2, 0x3718,
0x90E5, 0x2B8E, 0x385D, 0xC960, 0xA379, 0xB3D8, 0x3E82, 0x845E,
0x749E, 0xCF07, 0xE2ED, 0x3C99, 0x322D, 0x5C4E, 0x1E86, 0xD4F9,
0x67B6, 0xC3AA, 0xE822, 0xC367, 0x4017, 0xFC50, 0xBB2B, 0xC3C2,
0x7E16, 0x6D61, 0x4E79, 0x5214, 0xC893, 0x303B, 0x892C, 0x5978,
0x5BC9, 0xC189, 0x22D8, 0xFF42, 0x7561, 0x615A, 0x83A1, 0xEA00,
0x3061, 0x668E, 0x2699, 0x628F, 0xC2DC, 0x4520, 0x3788, 0x2A93,
0x08CA, 0x1FAA, 0xEDFA, 0x48E1, 0x1BFA, 0xA925, 0x0CA3
};

unsigned short random2[] =
{
0x9A11, 0x1687, 0x5B1C, 0xEC25, 0xDF1A, 0x8B58, 0x7551, 0x3892,
0xE721, 0x36DB, 0x5B6B, 0xE664, 0xAC3C, 0xBCC5, 0x6A05, 0x963C,
0xED27, 0xD093, 0xBCD6, 0x4FB6, 0x936F, 0x01F6, 0x873E, 0xBE02,
0x0AC0, 0xA6E9, 0xABFD, 0x53A1, 0xC2E3, 0x5522, 0x6044, 0x5CF4, 
0x6BA9, 0xBB60, 0x4919, 0x4AC3, 0x46B8, 0xBE6B, 0x8356, 0x2DDA,
0xF546, 0xDEC1, 0x143E, 0xA182, 0x9B86, 0x7E43, 0x37BF, 0x88AD, 
0x4ED6, 0xF495, 0xD863, 0xE245, 0xF68B, 0x5FA2, 0xA048, 0x014B,
0x068B, 0x4C45, 0x54EC, 0xC96E, 0xA167, 0xB530, 0x2663, 0x0D11,
0x7090, 0x6F7C, 0x57D4, 0xB749, 0x2DE7, 0xDB2A, 0xE523, 0x232D,
0xB9EB, 0xF961, 0xC4B0, 0x5572, 0x77A4, 0xFC6F, 0xDE1F, 0xC67A,
0xF104, 0xB683, 0xA8BF, 0xE78F, 0x1625, 0x4907, 0xE8DA, 0x1CB0,
0x954C, 0x3DC6, 0xE61E, 0x36B4, 0xF2F6, 0x0C81, 0x43C5, 0x6386, 
0x7BFE, 0x9B99, 0x1ACF, 0xA9E5, 0x76C4, 0xFFF2, 0xCD13, 0x30AF,
0xF953, 0x91C3, 0x8621, 0x70F7, 0x8E32, 0x6441, 0x3771, 0x7F36, 
0x1AC4, 0xE031, 0x66C5, 0x30E9, 0x2938, 0x4F9F, 0x4D99, 0xBE85,
0x8D65, 0x33B7, 0xF539, 0x805B, 0x4039, 0x38FE, 0xE3E1, 0xBC37, 
0xD497, 0xFEB1, 0x661C, 0x4B5B, 0xFEA3, 0x332F, 0x7C0B, 0xF7F7,
0xC4F2, 0x022C, 0x68EE, 0x5324, 0x666D, 0xA060, 0xD25A, 0x8131, 
0x8091, 0x391F, 0xB21A, 0xA9C9, 0x88BE, 0xFFB3, 0x684E, 0x1623,
0x336B, 0x5D87, 0x967E, 0x73A4, 0x9685, 0x7A60, 0x2FDB, 0x6B1D, 
0x7911, 0x95F7, 0xB678, 0x77B4, 0xC927, 0x3283, 0x6FAB, 0x8E19,
0x34B0, 0xD89A, 0xE13E, 0x9B1D, 0x78FA, 0xB398, 0x1C4F, 0xF98B, 
0xECB8, 0xCE69, 0xA354, 0x7576, 0xCE1D, 0x0BA3, 0x8B9A, 0x0188,
0x692A, 0x2218, 0x752C, 0xFFB0, 0x9C78, 0xA507, 0x6ACD, 0x1589, 
0x3AFE, 0x2145, 0x8D3E, 0x0425, 0x53C9, 0xFCE9, 0x923F, 0x8879,
0xD583, 0x737D, 0x2396, 0x4E7D, 0x2715, 0x3FE5, 0x4808, 0x13CD, 
0x0E4F, 0xEB5D, 0x8944
};

unsigned short random3[] =
{
0xDC6C, 0xF700, 0x14DE, 0xDDF4, 0x602A, 0x36F6, 0x5320, 0x5FDA, 
0xD36F, 0xF827, 0xCAA7, 0xE8F8, 0x3325, 0xEBED, 0x7636, 0x374B,
0x3FB6, 0x7320, 0xC98A, 0xC82F, 0x48A3, 0x3D07, 0xEBC5, 0x9721,
0x641C, 0x2BAB, 0xDF29, 0x77EA, 0x39FA, 0xCA86, 0x012E, 0x1666,
0xC186, 0x160C, 0xF45A, 0x21B1, 0x4D02, 0x477A, 0x818B, 0x2071,
0x3FA1, 0x4C33, 0x096A, 0x72C6, 0x3820, 0x7FA0, 0xAA11, 0x77D6,
0xF2C0, 0x739B, 0x4005, 0x3B64, 0xB0A2, 0x2BCA, 0xD285, 0x14BF,
0x5775, 0xB1AE, 0x8CA9, 0x916F, 0x7C35, 0x8DD7, 0xA7D5, 0x3DBB,
0xA3E3, 0x9C2F, 0x5F6C, 0xF0E5, 0xE3A9, 0xE0F8, 0x1157, 0x234A,
0x2D2B, 0x1AC1, 0x9611, 0x654B, 0x9A61, 0x4022, 0xDD21, 0x8D22,
0xB3BE, 0x1D26, 0xC886, 0x6460, 0x48F0, 0x9B0B, 0x791F, 0xA066,
0x4CB9, 0x05C8, 0x31D5, 0xC8EE, 0x939F, 0xD9AB, 0x06AA, 0x3782,
0x75DA, 0x6616, 0x2868, 0x5984, 0x470E, 0x39BF, 0x7CCE, 0x7439,
0x5480, 0x12DF, 0xD984, 0xEEE1, 0x5302, 0xB6A5, 0x7C03, 0x06C0,
0xD3CB, 0x4489, 0x6B20, 0x1CBC, 0xDF94, 0xE440, 0xBD22, 0x2C4E,
0xEA08, 0xEEF7, 0xF53C, 0x7DA8, 0xC8A2, 0xFBE6, 0xB52A, 0x3E7D,
0x61FD, 0xDD92, 0x9801, 0xA90B, 0x1751, 0x14CF, 0x1D45, 0x6BD1,
0x27AF, 0xF6C9, 0x5AB3, 0x7AB1, 0xAD6F, 0xD6B6, 0x8171, 0x813A,
0x1B40, 0xEC91, 0x9DF6, 0xFAD4, 0xD0D1, 0x5B18, 0x2722, 0xBADA,
0x4A10, 0x1C5F, 0x3882, 0x12B2, 0x1845, 0xEDAC, 0x512F, 0x7A42,
0xCB3F, 0xE930, 0x234E, 0xE290, 0xFE00, 0x4093, 0x4E62, 0x25AF,
0x375C, 0xA915, 0xA060, 0xE4CB, 0x7FCB, 0x21D1, 0x6606, 0x9B0B,
0x0E62, 0x03FC, 0x95E0, 0xDF34, 0x5F15, 0xBD02, 0x9A0E, 0xA925,
0xD961, 0xD290, 0xBBD7, 0xF1A7, 0xC03C, 0x0D07, 0x6BE9, 0x8B7B,
0xF637, 0x8F37, 0x6E0C, 0xF437, 0xCFCA, 0xBC6E, 0x19E6, 0x0727,
0x6583, 0xBA46, 0xEBF2, 0xE54E, 0xDC17, 0x51F8, 0x805A, 0xEA7A,
0x55F5, 0x163A, 0xC9AE, 0xB50A, 0xD33C, 0x63BC, 0x5E2F, 0xAC9E,
0x364C, 0x1A06, 0x9E45, 0xF688, 0x270D, 0x0A2E, 0x8204
};

static unsigned short get_rand1()
{
	static short cnt = 0;
	unsigned short result = random1[cnt];

	cnt = (cnt+1)%(sizeof(random1)/sizeof(random1[0]));
	return result;
}

static unsigned short get_rand2()
{
	static short cnt = 0;
	unsigned short result = random2[cnt];

	cnt = (cnt+1)%(sizeof(random2)/sizeof(random2[0]));
	return result;
}

static unsigned short get_rand3()
{
	static short cnt = 0;
	unsigned short result = random3[cnt];

	cnt = (cnt+1)%(sizeof(random3)/sizeof(random3[0]));
	return result;
}

static unsigned short get_random()
{
	return get_rand3() ^ (get_rand1() ^get_rand2());
}

static void decode_data(short *dest, short *src, int nBytes)
{
	while (nBytes)
	{
		*dest = get_random() ^ scramble ^ *src ^ machine_code;
		src++;
		dest++;
		nBytes -= sizeof(short);
	}
}

static void decode_header(short *dest, short *src, int nBytes)
{
	while (nBytes)
	{
		*dest = *src ^ machine_code;
		src++;
		dest++;
		nBytes -= sizeof(short);
	}
}

static int get_num_sections(FILE *fp)
{
	sec_head SectHead;
	int sects = 0;

	fseek(fp, 0x10, SEEK_SET);
	while (fread(&SectHead, sizeof(SectHead), 1, fp) && SectHead.hdr == SECT_SIGN)
		sects++;
	return sects;
}

static void dump_sections(FILE *fp)
{
	sec_head SectHead;
	int i, offset, sects;
	FILE *fpOut;
	char szFile[16];

	if (!(sects = get_num_sections(fp)))
	{
		fprintf (stderr, "Cannot determine number of sections.n");
		return;
	}
	offset=0x10+sects*sizeof(SectHead);
	for (i=0; i0; size-=read)
			{
				read = fread(buf, 1, size>sizeof(buf)?sizeof(buf):size, fp);
				if (!read) break;
				fwrite (buf, 1, read, fpOut);
			}
			printf ("Dumped to %s.n", szFile);
			fclose(fpOut);
		}
		offset += SectHead.size;
	}
}

static void usage(char *pszApp)
{
	fprintf (stderr, "%s  n", pszApp);
}

int main(int argc, char **argv)
{
	FILE *fp, *fpDst;
	int iRet = -1;

	printf ("D-Link firmware decrypter V1.00nhttp://www.hardwarefetish.comnn");
	if (argc<3)
	{
		usage(argv[0]);
		return -1;
	}

	if (!(fp = fopen(argv[1], "rb")))
	{
		perror("Cannot open input file");
		return -1;
	}

	if (!(fpDst = fopen(argv[2], "w+b")))
	{
		fclose (fp);
		perror("Cannot open output file");
		return -1;
	}

	if (fread(&FmHead, sizeof(FmHead), 1, fp))
	{
		int size, read=0;
		unsigned char buf[1024];

		if (FmHead.machine_code) machine_code = FmHead.machine_code;
		decode_header((short*)&FmHead, (short*)&FmHead, sizeof(FmHead));
		scramble = FmHead.scramble;
		fwrite(&FmHead, sizeof(FmHead), 1, fpDst);
		printf ("magic = %08X, machine_code = %04X, scramble = %04X, checksum = %04Xn", 
			FmHead.Signature, machine_code, scramble, FmHead.checksum);

		while (read = fread(buf, 1, sizeof(buf), fp))
		{
			decode_data((short*)buf, (short*)buf, read);
			fwrite (buf, 1, read, fpDst);
		}
		printf ("%s written.n", argv[2]);
		dump_sections(fpDst);
		iRet = 0;
	}
	else perror("Reading header failed.");
	fclose (fp);
	fclose (fpDst);
	return iRet;
}

  Сохраняем в файл decode_fw.c и компилируем его при помощи GCC, но, прошу заметить, что компилировать нужно только в 32-х битном дистрибутиве Linux (Мне пришлось ставить 32-битную версию Ubuntu 13.04 в виртуальную машину), иначе, хотя компиляция и пройдёт нормально, но утилита нормально работать не будет и нормального содержимого прошивки вы не увидите. В итоге мы получаем файл decode_fw, затем делаем его исполняемым при помощи команда sudo сhmod a+x decode_fw.
Переходим к самому процессу распаковки. Запускаем утилиту и в командной строке передаём ей параметры, в которых указываем имя файла прошивки, а также имя файла, в который будет сохранён файл прошивки со снятой защитой. В-общем делаем так:

sudo decode_fw dcs2210.bin a.out

  И видим:

magic = AA7DC558, machine_code = 2021, scramble = 3FA6, checksum = CFFF
a.out written.
Section 0 : mtd: 0 Type: AUTO Size: 16384 Offset: 1C000 @00000110
Dumped to 00000000.dmp.
Section 1 : mtd: 3 Type: AUTO Size: 1918976 Offset: 0 @00004110
Dumped to 00000001.dmp.
Section 2 : mtd: 6 Type: JFFS2 Size: 3701760 Offset: 0 @001D8910
Dumped to 00000002.dmp.
Section 3 : mtd: 7 Type: JFFS2 Size: 7300096 Offset: 0 @00560510
Dumped to 00000003.dmp.

  Результатом работы утилиты будут 4 файла с именами 00000000.dmp — 00000003.dmp, а также файл a.out. Теперь для удобства нужно их переименовать:

mv 00000000.dmp u-boot.env
mv 00000001.dmp kernel.img
mv 00000002.dmp www.jffs2
mv 00000003.dmp ipnc.jffs2

  Файл a.out не трогаем, он нам не особо нужен. Вот они, наши искомые файлы, теперь с ними можно делать всё, что угодно. Например, попробуем смонтировать раздел www.jffs2 в файловую систму нашего компьютера и внести в него какие-либо изменения, а затем заново сохранить. Для монтирования можно использовать найденный leecher’ом где-то на просторах Интернета скрипт. Взять его можно также с его сайта http://dose.0wnz.at/ipcams/ или скопипастить из-под спойлера ниже:

[Spoiler (click to open)]

#!/bin/sh
JFFSIMG=$1 # jffs image
MP="fs" # mount point
MTDBLOCK="/tmp/mtdblock0" # MTD device file
UMNT=""
 
echo "$0" | grep unmount_ >/dev/null 2>&1
[ $? -eq 0 ] && UMNT=1
if [ $# -gt 1 -a x"$2"x = x"unmount"x ]; then
  UMNT=1
fi
 
if [ x"${UMNT}"x = x""x ]; then
  if [ ! -b ${MTDBLOCK} ] ; then
    mknod ${MTDBLOCK} b 31 0 || exit 1
  fi
  modprobe mtdblock
  modprobe mtdram total_size=65536 erase_size=16
  modprobe jffs2
  dd if=${JFFSIMG} of=${MTDBLOCK}
  [ ! -d ${MP} ] && mkdir -p ${MP}
  mount -t jffs2 ${MTDBLOCK} ${MP}
else
  umount ${MP}
  if [ $? -ne 0 ]; then
    echo "Cannot unmount JFFS2 at $MP"
  fi
  modprobe -r jffs2
  modprobe -r mtdram
  modprobe -r mtdblock
  modprobe -r mtdram
  modprobe -r mtdchar
  modprobe -r mtd
fi

  Сохраняем его под именем mount_jffs2.sh и делаем исполняемым. С помощью этого скрипта монтируем www.jffs2:

./mount_jffs2.sh www.jffs2

  При этом в текущей папке будет создана подпапка fs, и содержимое раздела jffs2 будет смонтировано в неё. Вносим в файловую систему изменения. Сохраняем внесённые изменения в новый файл www.jffs2.new так:

mkfs.jffs2 -l -e 0x4000 -n -U -d fs -o www.jffs2.new

  И отмонтируем старый раздел jffs2:

./mount_jffs2.sh www.jffs2 unmount

  Всё, файл www.jffs2.new, содержащий наши изменения, сохранён. Настала пора добавить его к остальным файлам прошивки и собрать её.

Часть 2. Собираем прошивку.

  Прежде всего, нам потребуется исходный код прошивки. Скачиваем его с http://tsd.dlink.com.tw/gpl.asp но, как показывает практика, скачать оттуда что-либо практически невозможно, поскольку скорость загрузки крайне низка, загрузка постоянно обрывается, а докачка — отсутствует. Я совершенно случайно наткнулся на исходники прошивки DCS-2210 блуждая по российскому ftp D-Link, скорость скачивания с которого намного выше и скачивание идёт намного стабильнее. Посему скачиваем исходники оттуда по ссылке ftp://ftp.dlink.ru/pub/Multimedia/Sources/GPL_DCS-2210.tar.gz Вообще-то весь исходный код нам не нужен, если только глянуть на что да как собирается (все равно прошивка, скомпилированная из него, не умеет ровным счётом ничего, только показывает страничку, предлагающую загрузить прошивку с сайта D-Link, поскольку в собранной из этих исходников прошивки нет большого количества проприетарных файлов), а нужны нам лишь 2 файла для сборки нашей изменённой прошивки — текстовый файл firmware.conf и исполняемый бинарник host_mkfm, собирающий и шифрующий прошивку. Находим их в папке firmware исходных файлов прошивки и копируем в свою рабочую папку. Открываем firmware.conf в текстовом редакторе и правим так:

# file_name		mtd		section_type	offset(hex)	FLAG(GZ_COMPRESS)

u-boot.env		0		AUTO		1C000		0
kernel.img		3		AUTO		0		0
www.jffs2		6		JFFS2		0		0
ipnc.jffs2.old		7		JFFS2		0		0

#kernel.img		3		NONE		0		0
#rootfs.img		4		NONE		0		0
#yaffs.img		7               YAFFS           0               0
#yaffs.img.z		7		YAFFS		0		1

  Помните, что я говорил, что в прошивку в теории можно добавить и другие разделы? Вот, пожалуйста, заполняем таблицу как надо (вписываем имя файла, номер блока, тип ФС, и, при необходимости, смещение от начала блока), сохраняем файл. Теперь собираем прошивку:

sudo host_mkfm dcs2210_new.bin

  И на выходе получаем файл dcs2210_new.bin, готовый к прошивке в камеру стандартными средствами.

  Вот и всё, удачи!

Update: Таки можно добавить свои разделы! Мне нужно было добавить кое-что в rootfs, я смонтировал mtdblock4 при помощи скрипта, внёс нужные изменения, сохранил, внёс соответствующие изменения в firmware.conf, собрал прошивку, прошил камеру стандартными средствами и… удача! Камера прошилась и содержала в себе все сделанные мной в rootfs изменения! Вот только сам процесс прошивки выглядел как-то корявенько, примерно на середине отсчёта таймера страничка обновилась и вместо веб-интерфейса мне открылась просто пустая страничка. Я уж думал всё, придётся подпаивать консольный кабель, ан нет, пока я над этим размышлял камера успела перезагрузиться и отобразить мне нормальный веб-интерфейс. Почему так получилось? А фиг его знает! Я не разбирался, работает и ладно… После этого я вносил еще кое-какие изменения, и процесс прошивки проходил точно так же.
Update 2 Понял причину пустой странички при прошивке — в section_type надо поставить AUTO и всё будет шиться без проблем. Кстати, только что сделал прошивку с одним разделом (только rootfs) — без проблем, все прошилось нормально!

OpenIPC Wiki

Оглавление

Switcam HS-303

Компания-производитель выпускала IP камеры Switcam HS-303 в трёх версиях,
значительно отличающихся аппаратно между собой. На данный момент проект
OpenIPC поддерживает прошивку без разборки всех трёх версий камер, однако
есть некоторые ограничения по настройке HS303 v3. Сейчас мы работаем над
созданием единой универсальной прошивки для всех трёх версий видеокамеры
Switcam HS-303.

Обсуждение проекта и возможностей прошивок (на русском языке) возможно в
открытой Telegram группе нашего проекта.

Визуальное отличие устройств по цвету:

  • HS303 v1 — имеет чёрно-белый цвет
  • HS303 v2 — имеет черный цвет
  • HS303 v3 — имеет белый цвет и более вытянутую вертикально форму

Выбирайте правильный тип прошивки для своей камеры !

Подготовка перед прошивкой и эксплуатацией

Для комфортной работы в камерами OpenIPC в Windows необходимо установить программы:

  • Putty для доступа по протоколу ssh (лучшая замена telnet)
  • WinSCP для доступа к файловой системе по протоколу scp
  • Notepad++ в качестве редактора файлов на Linux камере

Для входа по SSH необходимо использовать имя пользователя root, без пароля

HS303 v1/v2/v3

Краткая инструкция установки OpenIPC v2.2 (на 2022.10.02)

  • подключите SD/MMC карту к ПК и разбейте её на два раздела
  • карта может быть любого размера, но первый раздел должен быть не более 2GB
  • отформатируйте SD/MMC карту как FAT (ограничение 2GB)
  • распакуйте содержимое архива и папки OpenIPC_PayWall в корень SD/MMC карты
  • внесите правки в фаил autoconfig/etc/network/interfaces (см.ниже)
  • вставьте карту памяти в слот и подайте питание на камеру
  • через 1 минуту (обновится загрузчик), сделайте сброс питания на пару секунд
  • примерно через 2-3 минуты камера будет прошита и станет щелкать ИК фильтром
  • сделайте сброс питания на пару секунд
  • дождитесь двойного щелчка ИК фильтра и извлеките SD карту
  • камера готова к эксплуатации

По-умолчанию камера пытается соединиться с точкой доступа с именем OpenIPC_NFS
и паролем сети project2021. Для изменения имени сети и пароля перед прошивкой
устройства, откройте файл autoconfig/etc/network/interfaces на SD/MMC карте в
редакторе Notepad++ (для Windows), выбрав при этом кодировку UTF-8 и впишите
свои значения.

После прошивки устройства, каталог autoconfig можно удалить или перенести в
место для хранения резервных копий на ПК.

Для восстановления настроек, достаточно записать сохраненные каталог и фаил в
корень SD карты, вставить её в выключенную камеру и подать питание.

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

Особенности релиза

  • Что-бы устройство работало максимально стабильно, по-умолчанию отключены
    дополнительные сервисы и службы: HLS, OSD, Motion и RTSP суб-поток;
  • Для тех кто будет перепрошивать камеры с OpenWrt понадобится дополнительное
    действие в виде разового выполнения команды в старой прошивке — зайдите на
    камеру по SSH и выполните команду flash_eraseall -j /dev/mtd4; reboot -f

Наиболее актуальные вопросы и ответы

Где можно взять прошивку для устройств Ростелеком Switcam HS303 v1/v2 ?

Готовые файлы для прошивки и базовая техподдержка доступны в телеграм группе
через PayWall сервис здесь.

Пошаговая инструкция по прошивке устройств и несколько ответов на часто задаваемые
вопросы находятся здесь.

Исходные коды проекта, для тех кому претит PayWall или кто хочет собрать прошивку
полностью самостоятельно.

Ваше право выбора в действиях полностью соблюдено. Успехов в техническом творчестве !

Как узнать какой IP адрес у прошитой камеры и как зайти на неё ?

Если внесены корректные данные по настройке WiFi интерфейса в конфигурационный
файл (SSID и ключ), то вы можете найти IP адрес камеры на своём роутере в списке
подключенных устройств с пометкой «OpenIPC».
Интерфейс управления камерой доступен в браузере на порту 85, а доступ по SSH
возможен на стандартном порту 22 с использованием логина root, без пароля при
первом подключении.

Как можно обновить прошивку до последней актуальной версии через SSH ?

Зайдите на камеру по протоколу SSH через программу Putty (логин root, без пароля,
при первом подключении или с паролем, который установили в WEB, 22 порт) и
выполните команду:

При наличии интернета, камера автоматически подключится к GitHub, скачает
и установит самые последние обновления.

Как можно обновить прошивку до последней актуальной версии через WEB ?

Зайдите на камеру через браузер указав IP адрес камеры и порт подключения 85,
например вот так:

Введите дефолтные логин и пароль (логин admin, пароль 12345).
После захода на камеру, установите новый пароль (не забудьте его записать!).
В разделе Firmware/Прошивка выполните действия, которые указаны в подсказках.

Как зарегистрировать данный тип камеры на сервисе ipeye.ru ?

В личном кабинете IPeye (зайти обязательно через браузер) добавить камеру по ID,
в качестве которого использовать MAC написанный в нижнем регистре (маленькими
буквами). MAC написан на титульной странице WEB-интерфейса на 85 порту.

Перед этим необходимо включить поддержку протокола IPeye во вкладке Majestic в
WEB-интерфейсе или присвоить параметру ipeye.enabled статус true в конфигурационном
файле /etc/majestic.yaml, а так-же перезагрузить камеру.

По материалам соответсвующей ветки форума iXBT.

Для чего это нужно

Изначально предполагалось просто научить камеру сохранять RAW файлы.

Смотрим в прошивку

Для анализа прошивки вам понадобится дизассемблер. Я использовал IDA Pro. Прошивку (файл PRIMARY.BIN) следует загрузить как бинарный файл для процессора ARM с начального адреса 0xFFC00000.

Для автоматического распознавания функций можно использовать FLIRT-сигнатуры от прошивки A610. А также IDC-скрипт, который поможет на начальном этапе запустить дизассемблирование. Оба эти файла можно взять здесь или здесь.
  • Общие выкладки по архитектуре прошивок на примере s2is
  • Полезная информация о работе прошивки

Где взять альтернативную «прошивку»

Исходники

На данный момент самые свежие исходники можно взять из SVN репозитория, логин anonymous, без пароля. Прошивка постоянно (но не очень регулярно) обновляется, за что огромное спасибо vitalyb.
Для работы с SVN-репозиторием вам понадобится SVN-клиент (хотя можно и через web, но это не очень удобно, так как файлов очень много и не будет возможности накладывать изменения), который можно скачать здесь. Также доступно описание на русском.

Собранные прошивки

Пока нет одного места, где бы выкладывались бы последние собранные версии прошивок. Можете попробовать посмотреть либо здесь, либо ищите ссылки по форуму.
Ещё они могут быть здесь.

Если нет прошивки для вашей модели/версии

Если ваша камера построена на базе DIGICII, то скорее всего для неё существует возможность собрать альтернативную прошивку. Что для этого нужно смотри здесь.

Собираем прошивку сами

На данный момент сборка прошивки может осуществляться либо под Windows, либо под Linux 64bit.

Сборка под Windows

Вам понадобится gcc для ARM под Windows. А тагже Unux-подобная среда типа Cygwin или Mingw/MSys.

Если не хочется возиться с настройкой, можно взять готовый environment здесь. Вот инструкция по установке:

  1. Запускаем Far (или ваш любимый файловый менеджер).
  2. Создаём на каком-нибудь диске рабочую папку, скажем ‘D:hdk-devel’.
  3. Переходим в неё.
  4. Скачиваем архив с environment’ом gcc_env_for_hdk.rar.
  5. Распаковываем его.
  6. Добавляем каталог ‘D:hdk-develbin’ в PATH. Для этого идём в настройки Windows (у меня WinXP Eng): ‘Start’ -> ‘Control Panel’ -> ‘System’, закладка ‘Advanced’, кнопка ‘Environment Variables’. Я добавлял в переменные пользователя. Если у вас такой переменной, как PATH, ещё не было, то жмём ‘New’ и вписываем имя переменной ‘PATH’ и значение ‘D:hdk-develbin’. Если такая переменная была, то жмём ‘Edit’, и добавляем к значению в конец ‘;D:hdk-develbin’ (не забываем разделитель ‘;’ (точка с запятой)). Отбиваемся от всей этой кучи окон кнопками ‘Ok’.
  7. На всякий случай, перезапускаем Far (или ваш любимый файл менеджер), чтобы он зацепил изменения в переменных окружения. Не для всех файл менеджеров этот шаг необходим, но лучше перестраховаться.
  8. Всё. Подготовка завершена.
  9. Для сборки прошивки находясь в каталоге верхнего уровня с исходниками набираем ‘gmake fir’. Для запаковки прошивки в zip-архив — ‘gmake firzip’.
  10. По-умолчанию собирается прошивка для A610 версии 1.00e. Для сборки под другую модель и/или версию прошивки можно указать параметры для gmake: PLATFORM=<модель> PLATFORMSUB=<версия прошивки>.
    Например, 'gmake PLATFORM=a620 PLATFORMSUB=100f fir'
  11. Для очистки дерева исходников от всех объектников и собранных бинарников — ‘gmake clean’.
    Также можно использовать ‘gmake batch-zip’ и ‘gmake batch-clean’ для сборки прошивок под все версии оригинальных прошивок и очистки всего дерева исходников соответственно.

Сборка под Linux

Здесь всё гораздо проще, так как почти всё уже есть в системе…
Скачиваете gcc для ARM, распаковываете, настраиваете на него путь в файле makefile.inc, и вперёд.

Загрузка «прошивки» в камеру

Для загрузки прошивки вам возможно понадобится картридер, тат как необходимо записать файл прошивки PS.FIR в корень флэшки. Включаете фотоаппарат в режиме просмотра, заходите в меню и выбираете пункт меню Update Firmware….

Здесь нужно сделать важное замечание — данная операция на самом деле ничего перепрошивать не будет, так как алтернативная прошивка не является прошивкой, а по сути есть резидентная программа, которая остаётся в памяти и работает только до выключения питания. Так что, даже если что-нибудь пойдёт не так и прошивка зависнет, то ничего плохого не произойдёт, так как после выключения и повторного включения аппарата никаких следов прошивки не останется.

Как пользоваться

Для входа в альтернативный режим аспользуется кнопка прямой печати.
В альтернативном режиме клавиша меню вызывает альтернативное меню, при помощи которого можно производить настройки параметров и включать/отключать функциональные возможности, заложенные в альтернативную прошивку.
Кнопка съёмка в алтернативном режиме используется для запуска/останова выполнения скрипта.

Скрипты

Маленькая инструкция (на английском).

Горячие клавиши

Можно быстро включать и отключатьсъемку в RAW
[erase] — Вкл/выкл RAW
Можно быстро включать и отключать OSD элементы кнопками при полунажатом спуске:
[half shoot]+[left] — Вкл/выкл Зебры
[half shoot]+[up] — Вкл/выкл Гистограммы
[half shoot]+[right] — Вкл/выкл OSD

Полезные ссылки

  • Форум iXBT
  • digicanon.narod.ru
  • http://alexbernstein.com/wiki/canon-camera-hacking/

Понравилась статья? Поделить с друзьями:
  • Как написать психологический рассказ
  • Как написать прошивку для attiny13
  • Как написать психологический портрет персонажа
  • Как написать прошение святой матроне московской
  • Как написать психологический портрет личности пример подростка