Интернет пестрит информацией о том, как запускают DOOM на различных устройствах. Захотелось и мне запустить Doom на своём стареньком роутере TP-Link WR-841N. Как видно из заголовка статьи, у меня этого не получилось, но результатом стало понимание основ написания прошивок роутеров и запущенный на роутере тетрис.

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

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

Для TP-Link WR-841N существует 14 версий аппаратной реализации этого роутера, а я собирал прошивку с тетрисом именно для версии V8.

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

Системная консоль

Алгоритм получения доступа к системной консоли следующий:

  1. Разбираем роутер. Мне пришлось открутить два шурупа и аккуратно разделить две половинки корпуса, не сломав защёлки. На плате, как правило, можно увидеть 4 отверстия для подключения по UART-интерфейсу. Но я уже успел туда припаять гребёнку.

Плата роутера TPlink WR-841N v8
Плата роутера TPlink WR-841N v8
  1. Вооружившись паяльником, припаиваем гребёнку. Разбираемся с распиновкой контактов. Для моего роутера она следующая:

Распиновка контактов UART-интерфейса TPlink WR-841N v8
Распиновка контактов UART-интерфейса TPlink WR-841N v8

Нужно использовать только три пина: TX, RX, GND. VCC нам не нужен.

  1. Подсоединяем USB-UART адаптер к компьютеру и роутеру. Убедитесь в том, что UART-адаптер для TTL-уровней использует верный вольтаж, для моего это 3,3 В.

  2. Набираем команду в Linux:

    sudo picocom -b 115200 /dev/ttyUSB0
    

115200 — скорость передачи данных по UART-интерфейсу,

/dev/ttyUSB0 — символьное устройство, появившееся в Linux для нашего адаптера.

  1. Включаем роутер и наблюдаем загрузку в системной консоли:

    U-Boot 1.1.4 (Jun 20 2013 - 17:34:51)
    
    U-boot AP123
    
    
    DRAM:  32 MB
    id read 0x100000ff
    Flash:  4 MB
    Using default environment
    
    In:    serial
    Out:   serial
    Err:   serial
    Net:   ag934x_enet_initialize...
    wasp reset mask:c03300
    WASP ----> S27 PHY
    file: ag934x.c,line: 179==: set LAN&WAN SWAP. --debug by HouXB
    GMAC: cfg1 0x5 cfg2 0x7114
    eth0: ba:be:fa:ce:08:41
    s27 reg init 
    athrs27_phy_setup ATHR_PHY_CONTROL 4: 0x1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 4: 0x10
    eth0 up
    WASP ----> S27 PHY
    file: ag934x.c,line: 179==: set LAN&WAN SWAP. --debug by HouXB
    GMAC: cfg1 0xf cfg2 0x7214
    eth1: ba:be:fa:ce:08:41
    s27 reg init lan 
    ATHRS27: resetting s27
    ATHRS27: s27 reset done
    athrs27_phy_setup ATHR_PHY_CONTROL 0: 0x1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 0: 0x10
    athrs27_phy_setup ATHR_PHY_CONTROL 1: 0x1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 1: 0x10
    athrs27_phy_setup ATHR_PHY_CONTROL 2: 0x1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 2: 0x10
    athrs27_phy_setup ATHR_PHY_CONTROL 3: 0x1000
    athrs27_phy_setup ATHR_PHY_SPEC_STAUS 3: 0x10
    eth1 up
    eth0, eth1
    Autobooting in 1 seconds
    ## Booting image at 9f020000 ...
       Uncompressing Kernel Image ... OK
    ........
    
  2. При загрузке можем увидеть ценную информацию, например, распределение памяти на флеш-чипе:

    5 cmdlinepart partitions found on MTD device ath-nor0
    Creating 5 MTD partitions on "ath-nor0":
    0x000000000000-0x000000020000 : "u-boot"
    0x000000020000-0x000000120000 : "kernel"
    0x000000120000-0x0000003e0000 : "rootfs"
    0x0000003e0000-0x0000003f0000 : "config"
    0x0000003f0000-0x000000400000 : "art"
    
  3. Нажимаем Enter и наблюдаем приглашения входа в систему:

    TL-WR841N mips #11 Thu Jul 24 17:24:48 CST 2014 (none)
    TL-WR841N login: 
    
  4. Вводим пользователя: root, пароль: sohoadmin. С современными роутерами узнать пароль, наверное, так просто не получится.

Теперь стоит вопрос, как запустить на роутере какую-нибудь свою программу, например, тетрис. Так просто, как на обычном компьютере, не получится.

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

Режимы работы загрузчика

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

Режим восстановления переводит роутер в режим считывания прошивки с последующей её записью на флеш-чип.

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

Разберёмся, как запустить загрузчик в интерактивном режиме.

Работа с загрузчиком U-Boot в интерактивном режиме

Для большинства роутеров TP-Link, стоит модифицированный загрузчик U-Boot. Чтобы попасть в его интерактивный режим, нужно во время отображения сообщения Autobooting in 1 seconds быстро набрать на клавиатуре tpl.

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

Параметры роутера

При покупке роутера, на коробке будет указана скорость, различные поддерживаемые технологии, но не будут указаны главные параметры роутера, которые нужно знать при разработке прошивки:

  • используемый SoC,

  • система команд процессора (ISA),

  • используемые чипы для Ethernet и WiFi, если они не интегрированы в SoC,

  • размер оперативной памяти,

  • размер и тип используемой флеш-памяти,

  • схема разделов,

  • какой используется стоковый загрузчик.

Для многих роутеров характеристики можно подсмотреть на сайте OpenWRT.

Для роутера TP-Link WR-841N v8 имеем следующие характеристики:

Параметр

Значение

SoC

Atheros AR9341

Ethernet

Интегрирован в SoC

WiFi

Интегрирован в SoC

ISA

MIPS32

CPU

MIPS 24Kc 560 MHz

RAM

32 MB

Flash

4 MB SPI NOR

Знание этих параметров даёт очень многое для понимания процесса разработки или модификации прошивки.

Например, знание ISA и CPU даёт понимание, какой использовать toolchain, как процессор обрабатывает данные (Big Endian или Little Endian), а знание размера RAM и flash позволит понять насколько жёсткие требования к оптимизации.

Карты памяти

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

Распределение памяти флеш-чипа

Название раздела

Смещение (Offset)

Размер

Содержимое и назначение

u-boot

0x000000

128 КБ

Загрузчик. Инициализирует «железо», содержит консоль восстановления

firmware

0x020000

3904 КБ

Прошивка. Объединённая область для ядра и файловой системы

config

0x3e0000

64 КБ

Конфигурация. Хранит текущие настройки пользователя

art

0x3f0000

64 КБ

Калибровки Wi-Fi и MAC-адрес. Всегда в конце чипа

Карта оперативной памяти

Область памяти

Начальный адрес

Куда распаковывается ядро

0x80000000

Куда можно загрузить файл по TFTP

0x81000000

Куда мапится память флеш-чипа

0x9f000000

Карту памяти я привёл в упрощённом виде, так как для детализации нужно будет ещё рассказывать об архитектуре Atheros AR9341 и MIPS 24Kc. Скажу только, что запись во флеш, это запись по адресам оперативной памяти, но так как флеш у нас SPI NOR, то записывать нужно блоками, предварительно очистив эти блоки.

Обратите внимание на разделы boot и art — если вы затрёте информацию в этих разделах, восстановление полноценной работы роутера у вас займёт много времени и сил.

Для восстановления boot-раздела вам придётся выпаивать флеш из платы роутера и записывать загрузчик при помощи программатора. Возможен вариант без выпаивания с использованием «прищепки», но этот вариант не всегда надёжен, и я его не проверял.

Раздел art содержит калибровочные данные для работы драйвера беспроводной сети. Содержимое раздела уникальное для каждого конкретного роутера, а использование art-раздела от другого экземпляра роутера может ухудшить работу WiFi.

Как загружается роутер

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

Загрузчик распаковывает ядро Linux и флеш-памяти в оперативную память по адресу, указанному в заголовке, и передаёт управление по адресу, также указанному в заголовке.

При интерактивном режиме работы загрузчика вы можете управлять процессом загрузки.

Чтобы выполнить загрузку, нужно ввести в командной строке:

bootm 0x9f020000

Загрузчик поддерживает загрузку по сети с использованием протокола TFTP, но так как команда bootm требует адрес в памяти, нужно сначала образ с Linux скачать в оперативную память при помощи команды tftpboot, а потом выполнить команду bootm.

tftpboot 0x81000000 firmware.bin
bootm 0x81000000

Чтобы можно было загрузить по TFTP, нужно настроить TFTP-сервер. Какой адрес сервера ожидает загрузчик, я подсмотрел в выводе команды printenv. Им оказался 192.168.1.100.

wasp> printenv
bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs init=/sbin/init mtdparts=ath-nor0:128k(u-boot),1024k(kernel),2816k(rootfs),64k(config),64k(art)
bootcmd=bootm 0x9f020000
bootdelay=1
baudrate=115200
ethaddr=0xba:0xbe:0xfa:0xce:0x08:0x41
ipaddr=192.168.1.111
serverip=192.168.1.100
dir=
bc=ap123
lu=tftp 0x81000000 ${dir}u-boot.bin&&erase 0x9f000000 +$filesize;cp.b $fileaddr 0x9f000000 $filesize
lf=tftp 0x81000000 ${dir}${bc}-squashfs&&erase 0x9f120000 +$filesize;cp.b $fileaddr 0x9f120000 $filesize
stdin=serial
stdout=serial
stderr=serial
ethact=eth0

Настройка TFTP сервера

Под Windows удобно использовать Tftpd64, но я всё выполнял на Linux и использовал TFTP-сервер в Docker-контейнере.

Создать такой контейнер просто.

  1. Создаём директорию:

    mkdir -p tftp/boot
    cd tftp
    

    В директорию boot мы будем помещать прошивки.

  2. Создаём в директории simple-tftp Dockerfile:

    FROM busybox:latest
    
    RUN echo "69 dgram udp wait root tftpd tftpd -c /tftpboot" > /etc/inetd.conf
    
    EXPOSE 69/udp
    
    CMD ["inetd", "-f", "-e", "/etc/inetd.conf"]
    
  3. Собираем:

    sudo docker build -t simple-tftp .
    
  4. Настраиваем сетевой интерфейс, на котором у нас будет работать TFTP-сервер. Я обычно использую внешнюю сетевую карту своего ноутбука.

    Настройки сетевого интерфейса
    Настройки сетевого интерфейса
  5. Запускаем:

    sudo docker run --rm -p 192.168.1.100:69:69/udp -v $(pwd)/boot:/tftpboot --name simple-tftp -it simple-tftp
    

Что содержит прошивка роутера

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

Прошивки там бывают трёх типов:

  • initramfs,

  • factory,

  • sysupgrade.

Откуда взять прошивки для экспериментов

Для своего роутера вы можете поискать прошивки на сайте OpenWRT.

Нам интересны первые две. Но безопаснее всего использовать первую — initramfs. Initfamfs-прошивок нет в готовом виде, но позже я покажу, как её собрать. Если factory прошивка использует такую же разбивку, как и на вашем флеш-чипе, эту прошивку можно тоже использовать для эксперимента по загрузке прошивки.

Сборка своей прошивки для роутера

Мне очень хотелось собрать прошивку с нуля на основе свежего mainlinе-ядра, но, к сожалению, пока эта задача не увенчалась успехом. Поэтому воспользуемся системой сборки, предоставляемой OpenWRT. Мой роутер, из-за того, что у него малый объём оперативной памяти и флеш-чипа, уже не подцеживается OpenWRT. Сборка и запуск современных прошивок приводили к тому, что загрузка падала из-за нехватки памяти.

Удобнее всего собирать в докере.

  1. Создаём Docker-образ Ubuntu со всеми необходимыми пакетами:

    cat <<EOF > Dockerfile
    FROM ubuntu:18.04
    
    RUN apt-get update && apt-get install -y --no-install-recommends \\
        build-essential \\
        subversion \\
        git-core \\
        libncurses5-dev \\
        zlib1g-dev \\
        gawk \\
        flex \\
        quilt \\
        libssl-dev \\
        xsltproc \\
        libxml-parser-perl \\
        mercurial \\
        unzip \\
        wget \\
        file \\
        && rm -rf /var/lib/apt/lists/*
    
    ENV FORCE_UNSAFE_CONFIGURE=1
    EOF
    
    sudo docker build -t firmware-builder .
    
  2. Запускаем Docker-контейнер:

    sudo docker run -it -v $(pwd):/out firmware-builder
    
  3. Скачиваем OpenWRT:

    cd root
    
    wget wget https://github.com/openwrt/openwrt/archive/refs/tags/v19.07.8.tar.gz
    
    tar xvf v19.07.8.tar.gz 
    
    cd openwrt-19.07.8/
    
  4. Конфигурируем нашу прошивку:

    ./scripts/feeds update -a
    
    ./scripts/feeds install -a
    
    make menuconfig
    

    Выбираем Target System -> Atheros AR7xxx/AR9xxx
    Выбираем Subtarget -> Devices with small flash
    Выбираем Target Profile -> TP-LINK TL-WR841N/ND v8
    ОтключаемTarget Images -> squashfs
    Включаем Target Images -> ramdisk

  5. Запускаем сборку:

    make -j$(nproc) V=s
    
  6. Собранная прошивка находится здесь: bin/targets/ar71xx/tiny/openwrt-ar71xx-tiny-tl-wr841-v8-initramfs-kernel.bin

  7. Копируем файл в примонтированную директорию, чтобы файл можно было использовать на хосте:

    cp bin/targets/ar71xx/tiny/openwrt-ar71xx-tiny-tl-wr841-v8-initramfs-kernel.bin /out/tftp/boot/bare.bin
    

Полученный файл прошивки можно попробовать загрузить на роутере.

Но мы хотели запустить какую-то свою программу на роутере, как это сделать?

Создание своего пакета для прошивки OpenWRT

Роутер работает под операционной системой Linux с запущенными пользовательскими приложениями. Нам нужно создать своё приложение и интегрировать его в прошивку роутера. В OpenWRT это решается просто.

  1. Создаём папку с исходным кодом пакета:

    mkdir -p ~/packages/helloworld/src
    
  2. Создаём Makefile в директории ~/packages/helloworld. Не забываем про табуляции в Makefile:

    include $(TOPDIR)/rules.mk
    
    PKG_NAME:=helloworld
    PKG_VERSION:=1.0
    PKG_RELEASE:=1
    
    PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
    
    include $(INCLUDE_DIR)/package.mk
    
    define Package/helloworld
     SECTION:=examples
     CATEGORY:=Examples
     TITLE:=Simple Hello World program
     URL:=https://example.com
    endef
    
    define Package/helloworld/description
     A very basic "Hello, World!" example packaged for OpenWrt.
    endef
    
    define Build/Prepare
     mkdir -p $(PKG_BUILD_DIR)
     $(CP) ./src/* $(PKG_BUILD_DIR)/
    endef
    
    define Build/Compile
     $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) \
     -o $(PKG_BUILD_DIR)/helloworld \
     $(PKG_BUILD_DIR)/helloworld.c
    endef
    
    define Package/helloworld/install
     $(INSTALL_DIR) $(1)/usr/bin
     $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin/
    endef
    
    $(eval $(call BuildPackage,helloworld))
    
  3. Пишем исходный код приложения:

    #include <stdio.h>
    
    int main() {
     printf("Hello world! \n");
     return 0;
    }
    
    
  4. Прописываем папку с пакетами в конфигурации:

    echo "src-link myfeed /root/packages" >> feeds.conf.default
    
  5. Обновляем фиды:

    ./scripts/feeds update -a
    
  6. Устанавливаем пакет в сборку, чтобы он стал доступен в меню конфигурации:

    ./scripts/feeds install -p myfeed helloworld
    
  7. Конфигурируем сборку:

    make menuconfig
    
  8. Отмечаем наше приложение как встроенное (*):
    Examples->helloworld

  9. Сохраняем конфигурацию.

  10. Выходим из меню конфигурации и запускаем сборку:

    make -j$(nproc) V=s
    

Теперь прошивка будет содержать наш пакет.

Создание прошивки с тетрисом

Можно, конечно, написать свою версию тетриса, но я воспользовался следующим.

Добавление этого тетриса в прошивку похоже на то, как мы добавляли helloworld. Но некоторые шаги выполнять не нужно.

  1. Создаём папку с исходным кодом пакета:

    mkdir -p ~/packages/tetris
    
  2. Создаём Makefile в директории ~/packages/tetris. Не забываем про табуляции в Makefile:

    include $(TOPDIR)/rules.mk
    
    PKG_NAME:=tetris
    PKG_VERSION:=1.5.0
    PKG_RELEASE:=1
    
    PKG_SOURCE_PROTO:=git
    PKG_SOURCE_URL:=https://github.com/troglobit/tetris.git
    PKG_SOURCE_VERSION:=1.5.0
    PKG_MIRROR_HASH:=skip
    
    PKG_MAINTAINER:=Your Name <you@example.com>
    PKG_LICENSE:=GPL
    
    include $(INCLUDE_DIR)/package.mk
    
    define Package/tetris
      SECTION:=examples
      CATEGORY:=Examples
      TITLE:=Micro Tetris - very small terminal Tetris
      URL:=https://github.com/troglobit/tetris
      DEPENDS:=+libc
    endef
    
    define Package/tetris/description
      One of the smallest Tetris implementations using only ANSI escapes.
      Perfect for embedded devices with terminal access.
    endef
    
    define Build/Compile
     $(MAKE) -C $(PKG_BUILD_DIR) \
     CC="$(TARGET_CC)" \
     CFLAGS="$(TARGET_CFLAGS)" \
     LDFLAGS="$(TARGET_LDFLAGS)"
    endef
    
    define Package/tetris/install
     $(INSTALL_DIR) $(1)/usr/bin
     $(INSTALL_BIN) $(PKG_BUILD_DIR)/tetris $(1)/usr/bin/
    endef
    
    $(eval $(call BuildPackage,tetris))   
    
    
  3. Исходный код тетриса писать не нужно, так как его возьмёт из Git-репозитория OpenWRT при сборке.

  4. Обновляем фиды:

    ./scripts/feeds update -a
    
  5. Устанавливаем пакет в сборку, чтобы он стал доступен в меню конфигурации:

    ./scripts/feeds install -p myfeed tetris
    
  6. Конфигурируем сборку:

    make menuconfig
    
  7. Отмечаем наше приложение как встроенное (*): Examples->tetris

  8. Сохраняем конфигурацию.

  9. Выходим из меню конфигурации и запускаем сборку:

    make -j$(nproc) V=s
    
  10. Копируем файл в примонтированную директорию, чтобы файл можно было использовать на хосте:

    cp bin/targets/ar71xx/tiny/openwrt-ar71xx-tiny-tl-wr841-v8-initramfs-kernel.bin /out/tftp/boot/tetris-wrong.bin
    

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

Создание патча к исходному коду пакета

  1. Скачиваем исходный код тетриса:

    git clone https://github.com/troglobit/tetris.git
    cd tetris
    git checkout 1.5.0 -b temp
    
  2. Выполняем изменения в исходном файле tetris.c. Я привожу sed-команды, чтобы удобно это было сделать из командной строки:

    sed -i 's/if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)) {/if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, \&ws) \&\& ws.ws_col >= MIN_COLS \&\& ws.ws_row >= MIN_ROWS) {/' tetris.c
    
    sed -i '/getenv("LINES");/a \
    \tttcols = cols ? atoi(cols) : 80;\
    \tttrows = lins ? atoi(lins) : 24;' tetris.c
    
    
  3. Проверяем внесённые изменения:

    git diff
    

    Команда должна вывести следующий diff:

    diff --git a/tetris.c b/tetris.c
    index da29f70..21e30ea 100644
    --- a/tetris.c
    +++ b/tetris.c
    @@ -355,12 +355,14 @@ static int tty_size(void)
    
            cols = getenv("COLUMNS");
            lins = getenv("LINES");
    +       ttcols = cols ? atoi(cols) : 80;
    +       ttrows = lins ? atoi(lins) : 24;
            if (cols && lins) {
                    ttcols = atoi(cols);
                    ttrows = atoi(lins);
            }
    
    -       if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)) {
    +       if (!ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) && ws.ws_col >= MIN_COLS && ws.ws_row >= MIN_ROWS) {
                    ttcols = ws.ws_col;
                    ttrows = ws.ws_row;
            } else {
    
    
  4. Создаём коммит. Так как мы делаем его первый раз, и git не настроен, нужно проконфигурировать git:

    git config --global user.email "mynamet@mail.com"
    git config --global user.name "myname"
    git add .
    git commit -m "Changed default columns and rows behaviour"
    
  5. Создаём и копируем патч в директорию tetris/patches:

    git format-patch -1
    
    mkdir -p /out/packages/tetris/patches
     
    cp 0001-Changed-default-columns-and-rows-behaviour.patch /out/packages/tetris/patches
    
  6. Собираем прошивку:

    cd ../openwrt-19.07.8
    
    make -j$(nproc) V=s
    
  7. Копируем файл в примонтированную директорию, чтобы файл можно было использовать на хосте:

    cp bin/targets/ar71xx/tiny/openwrt-ar71xx-tiny-tl-wr841-v8-initramfs-kernel.bin /out/tftp/boot/tetris.bin
    

Запуск прошивки

  1. Подключаем роутер с тетрисом к компьютеру через UART-интерфейс.

  2. Запускаем TFTP-сервер.

  3. Включаем роутер и входим в интерактивный режим загрузчика (набираем tpl).

  4. Загружаем файл прошивки по TFTP.

    tftpboot 0x81000000 firmware.bin
    bootm 0x81000000
    
  5. Нажимаем клавишу Enter.

  6. Вводим команду tetris.

    tetris
    
  7. Играем в тетрис.

Игра тетрис, запущеннная на роутере TPLink WR-841N
Игра тетрис, запущеннная на роутере TPLink WR-841N

Выводы

Модификация прошивки не такая сложная, как может показаться, если использовать OpenWRT. Главное — знать характеристики роутера, как распределена память.

Роутер TpLink WR-841N имеет очень маленький по современным меркам объём памяти, что усложняет создание полноценных прошивок.

Было бы интересно создать прошивку на основе Mainline ядра, пусть даже без поддержки всего железа. Но задача увлекательная с технической точки зрения.

Мы можем записать нашу прошивку во флеш, но я это намеренно не рассказываю, чтобы не дать вам больше шансов окирпичить роутер.

Старые роутеры кажутся бесполезными устройствами. Но на самом деле это полноценные Linux-компьютеры.

Немного паяльника, UART-адаптер — и вы погружаетесь embedded-разработку. В моём случае всё закончилось тетрисом на роутере.

Но, возможно, кто-то из читателей всё-таки сможет запустить на нём Doom.

© 2026 ООО «МТ ФИНАНС»