<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Paolo Scaramuzza</title>
    <subtitle>Electronic engineering consultant: RF, EMC compliance, embedded firmware and hardware.</subtitle>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-09-01T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>Notes on Using AVRDUDE</title>
        <published>2025-09-01T00:00:00+00:00</published>
        <updated>2025-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/avrdude-notes/"/>
        <id>/articles/avrdude-notes/</id>
        
        <content type="html" xml:base="/articles/avrdude-notes/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nongnu.org&#x2F;avrdude&#x2F;&quot;&gt;avrdude&lt;&#x2F;a&gt; is the standard command-line utility
to program Atmel&#x2F;Microchip AVR microcontrollers.  It supports multiple
programmers, including:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;serialUPDI&lt;&#x2F;strong&gt; (for new ATtiny&#x2F;mega0&#x2F;1-series with UPDI interface)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;AVRISP mkII&lt;&#x2F;strong&gt; (ISP&#x2F;PDI&#x2F;TPI programmer, see Appendix A for legacy setup)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This article collects practical usage notes, examples, and troubleshooting tips
when working with &lt;tt&gt;avrdude&lt;&#x2F;tt&gt; on GNU&#x2F;Linux.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example-session-with-serialupdi-attiny816&quot;&gt;Example Session with SerialUPDI (ATtiny816)&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Using Port                    : &#x2F;dev&#x2F;ttyUSB0                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Using Programmer              : serialupdi                             &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Overriding Baud Rate          : 230400                                 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     AVR Part                      : ATtiny816                              &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     RESET disposition             : dedicated                              &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     RETRY pulse                   : SCK                                    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Serial program mode           : yes                                    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     Parallel program mode         : yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                      Block Poll               Page                       Polled                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       Memory Type Alias    Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       ----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse0       wdtcfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse1       bodcfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse2       osccfg      0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse4       tcd0cfg     0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse5       syscfg0     0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse6       syscfg1     0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse7       append      0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuse8       bootend     0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       fuses                   0     0     0    0 no          9   10      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       lock                    0     0     0    0 no          1    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       tempsense               0     0     0    0 no          2    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       signature               0     0     0    0 no          3    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       prodsig                 0     0     0    0 no         61   61      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       sernum                  0     0     0    0 no         10    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       osccal16                0     0     0    0 no          2    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       osccal20                0     0     0    0 no          2    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       osc16err                0     0     0    0 no          2    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       osc20err                0     0     0    0 no          2    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       data                    0     0     0    0 no          0    1      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       userrow     usersig     0     0     0    0 no         32   32      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       eeprom                  0     0     0    0 no        128   32      0     0     0 0x00 0x00                                                           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       flash                   0     0     0    0 no       8192   64      0     0     0 0x00 0x00 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Detected memory areas:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Fuses (fuse0 … fuse8, syscfg, osccfg, etc.)&lt;&#x2F;li&gt;
&lt;li&gt;Lock bits&lt;&#x2F;li&gt;
&lt;li&gt;Signature &#x2F; production signature &#x2F; serial number&lt;&#x2F;li&gt;
&lt;li&gt;User row (usersig)&lt;&#x2F;li&gt;
&lt;li&gt;EEPROM (128 bytes)&lt;&#x2F;li&gt;
&lt;li&gt;Flash (8 KB)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;common-avrdude-options&quot;&gt;Common avrdude Options&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-p &amp;lt;partno&amp;gt;      Specify AVR device; `-p ?` lists all supported devices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-c &amp;lt;programmer&amp;gt;  Specify programmer; `-c ?` lists all supported programmers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-P &amp;lt;port&amp;gt;        Connection (e.g. &#x2F;dev&#x2F;ttyUSB0, usb)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-b &amp;lt;baudrate&amp;gt;    Override serial baudrate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-U &amp;lt;mem&amp;gt;:op:file[:fmt]  Perform memory operation&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-e               Erase chip before programming&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-t               Start interactive terminal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-v               Verbose (repeat for more detail)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-q               Quell progress output&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-T &amp;lt;terminal cmd line&amp;gt; Run terminal line when it is its turn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;memory-operations-u&quot;&gt;Memory Operations (-U)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;flash:r|w|v:&lt;file&gt;&lt;&#x2F;tt&gt; - read&#x2F;write&#x2F;verify flash&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;eeprom:r|w|v:&lt;file&gt;&lt;&#x2F;tt&gt; - read&#x2F;write&#x2F;verify EEPROM&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;fuses:r|w:&lt;file&gt;&lt;&#x2F;tt&gt; - access fuse bytes&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;userrow:r|w:&lt;file&gt;&lt;&#x2F;tt&gt; - read&#x2F;write the USERROW&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;file-formats-fmt&quot;&gt;File formats (:fmt)&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;:a&lt;&#x2F;tt&gt; - auto-detect&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:b&lt;&#x2F;tt&gt; - 0b-binary byte list&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:d&lt;&#x2F;tt&gt; - decimal byte list&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:e&lt;&#x2F;tt&gt; - ELF&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:h&lt;&#x2F;tt&gt; - 0x-hexadecimal byte list&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:i&lt;&#x2F;tt&gt; - Intel Hex&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:I&lt;&#x2F;tt&gt; - Intel Hex with comments&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:m&lt;&#x2F;tt&gt; - in-place immediate&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:o&lt;&#x2F;tt&gt; - octal byte list&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:r&lt;&#x2F;tt&gt; - raw binary&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:R&lt;&#x2F;tt&gt; - R byte list&lt;&#x2F;li&gt;
&lt;li&gt;&lt;tt&gt;:s&lt;&#x2F;tt&gt; - Motorola S-Record&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;practical-examples&quot;&gt;Practical Examples&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;read-eeprom&quot;&gt;Read EEPROM&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -v -p t816 -c serialupdi -P &#x2F;dev&#x2F;ttyUSB0 -U eeprom:r:-:h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;read-userrow&quot;&gt;Read USERROW&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -v -p t816 -c serialupdi -P &#x2F;dev&#x2F;ttyUSB0 -U userrow:r:-:h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Say you want to read the data stored in the userrow directly, the C code is the
following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;**&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; * Start address for the USERROW segment containing configuration data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#define USERROW_CONFIG_BASE 0x1300&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;&#x2F; The USERROW is memory mapped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;typedef struct {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	uint8_t var1;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	[...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	uint8_t varN;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;} userrow_struct_t;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#define userrow (*(volatile const userrow_struct_t *)USERROW_CONFIG_BASE)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;dump-userrow-eeprom&quot;&gt;Dump USERROW&#x2F;EEPROM&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -v -pt816 -cserialupdi -P &#x2F;dev&#x2F;ttyUSB0 -T &amp;#39;dump eeprom&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the userrow: &lt;code&gt;dump userrow&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interactive-shell&quot;&gt;Interactive shell&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -v -pt816 -cserialupdi -P &#x2F;dev&#x2F;ttyUSB0 -t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dump userrow&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;write userrow 0 0xBABBE0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000  e0 bb ba 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |................|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;write userrow 0 0xBA, 0xBB, 0xE0, 0x00&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0000  ba bb e0 00 ff ff ff ff  ff ff ff ff ff ff ff ff  |................|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0010  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flush   : synchronise flash and EEPROM cache with the device&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dump eeprom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dump flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dump fuses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;erase flash; erase eeprom; flush&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The shell session can also be condensed as a single &lt;tt&gt;-T&lt;&#x2F;tt&gt; command invocation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -v -pt816 -cserialupdi -P &#x2F;dev&#x2F;ttyUSB0 -T &amp;#39;write userrow 0 0x1 0 255 16; flush&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;appendix-a-avrisp-mkii-setup-guide-legacy&quot;&gt;Appendix A – AVRISP mkII Setup Guide (Legacy)&lt;&#x2F;h2&gt;
&lt;p&gt;The following section is preserved from an older tutorial. It describes how to
build avrdude with support for the AVRISP mkII on GNU&#x2F;Linux. It remains useful
for reference if you are using older ATmega&#x2F;ATtiny devices with ISP or PDI
interfaces.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;introduction-1&quot;&gt;Introduction&lt;&#x2F;h3&gt;
&lt;p&gt;The &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.atmel.com&#x2F;tools&#x2F;AVRISPMKII.aspx&quot;&gt;AVRISP mk2&lt;&#x2F;a&gt; is an USB
programmer for Atmel 8-bit microcontrollers with ISP (ATtiny, ATmega), PDI
(ATxmega) or TPI (smaller ATtiny) interface.&lt;&#x2F;p&gt;
&lt;p&gt;It can be used either with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.atmel.com&#x2F;tools&#x2F;ATMELSTUDIO.aspx&quot;&gt;Atmel Studio&lt;&#x2F;a&gt; (Windows only)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;playground.arduino.cc&#x2F;&quot;&gt;Arduino Playground&lt;&#x2F;a&gt; (Windows, MAC, Linux)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.nongnu.org&#x2F;avrdude&#x2F;&quot;&gt;avrdude&lt;&#x2F;a&gt; (virtually any OS, directly from the command line).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Please note that the Arduino Playground uses avrdude under the hood to burn the
firmware onto microcontrollers if the arduino bootloader is not used.&lt;&#x2F;p&gt;
&lt;p&gt;This guide is about building, installing and using avrdude on GNU&#x2F;Linux.  Due to
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;savannah.nongnu.org&#x2F;bugs&#x2F;index.php?40831&quot;&gt;a bug&lt;&#x2F;a&gt; in the most recent
version of avrdude in order for the AVRISP mk2 to be recognized and used the
program must be manually built after applying a patch to the source code.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;installing-required-packages&quot;&gt;Installing Required Packages&lt;&#x2F;h3&gt;
&lt;p&gt;First of all we are going to install some helper programs and libraries. This
process varies depending on your distribution of choice.&lt;&#x2F;p&gt;
&lt;p&gt;The packages listed below are the bare minimum required to build avrdude from
source. You may also like to install &lt;code&gt;gcc-avr binutils-avr avr-libc&lt;&#x2F;code&gt; in order to
compile the firmware for Atmel microcontrollers.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;debian-ubuntu-linux-mint&quot;&gt;Debian&#x2F;Ubuntu&#x2F;Linux Mint&lt;&#x2F;h4&gt;
&lt;p&gt;As root run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# apt-get install wget bison automake autoconf flex gcc libelf-dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;libusb-dev libusb-1.0-0-dev libftdi-dev libftdi1-dev`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;red-hat-centos-fedora&quot;&gt;Red Hat&#x2F;Centos&#x2F;Fedora&lt;&#x2F;h4&gt;
&lt;p&gt;As root run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# yum install wget bison automake autoconf flex gcc patch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;elfutils-libelf-devel libusb-devel libftdi-devel`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;compiling-and-installing-avrdude&quot;&gt;Compiling and Installing avrdude&lt;&#x2F;h3&gt;
&lt;p&gt;First of all we need to prepare a working directory to store the source code,
place it where you like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ mkdir avrdude; cd avrdude&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Get the source code for the latest version (at the time of writing it is
version 6.2):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ wget -qO- http:&#x2F;&#x2F;download.savannah.gnu.org&#x2F;releases&#x2F;avrdude&#x2F;avrdude-6.2.tar.gz | tar zxv --strip-components 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Download and apply the patch to fix the bug (the patch is for version 6.2):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ wget -qO- https:&#x2F;&#x2F;savannah.nongnu.org&#x2F;support&#x2F;download.php?file_id=32171 | patch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We are now ready to build!&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;bootstrap &amp;amp;&amp;amp; .&#x2F;configure &amp;amp;&amp;amp; make -j2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If no error is received avrdude is ready to rock with the AVRISP mk2. Before
installing you can try if everything works by running the command
&lt;code&gt;$ .&#x2F;avrdude -v&lt;&#x2F;code&gt; which should display the current version and the build date.&lt;&#x2F;p&gt;
&lt;p&gt;You can now run avrdude directly from the build directory or better still
install it system-wide. To do so you need root privileges. Run the following
commands as root:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# make install &amp;amp;&amp;amp; cp .&#x2F;avrdude &#x2F;usr&#x2F;bin&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you are done. In the following section some useful avrdude commands are
listed. Try them to see if everything was configured correctly.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;testing-communication&quot;&gt;Testing Communication&lt;&#x2F;h3&gt;
&lt;p&gt;Connect the programmer to a microcontroller. Assuming you are using an ATmega16
the command you should run to test the connection is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ avrdude -p m16 -c avrispmkII -P usb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If something goes wrong ensure that &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.droids-corp.org&#x2F;blog&#x2F;html&#x2F;2013&#x2F;05&#x2F;14&#x2F;olimex_avr_isp_mk2.html&quot;&gt;udev was configured correctly&lt;&#x2F;a&gt;
and the electrical connections are OK.&lt;&#x2F;p&gt;
&lt;p&gt;To see the list of devices supported by avrdude issue: &lt;code&gt;avrdude -p ?&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A sample programming line for avrdude would be:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avrdude -p m328p -P usb -c avrispmkII -e -U flash:w:test.hex:i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If none of the above commands report any error you are ready to go. Happy
programming.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Guide to Configuring Dynamic DNS with BIND9 Using TSIG Keys</title>
        <published>2024-08-01T00:00:00+00:00</published>
        <updated>2024-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/bind9-tsig-keys/"/>
        <id>/articles/bind9-tsig-keys/</id>
        
        <content type="html" xml:base="/articles/bind9-tsig-keys/">&lt;p&gt;This guide will walk you through the process of setting up dynamic DNS updates
in BIND9 [[1]][1] using a TSIG key.&lt;&#x2F;p&gt;
&lt;p&gt;Previously, the most common authentication method for BIND was to use SIG(0)
for authentication [[2]][2], but SIG(0) support has been removed from BIND9. SIG(0) is
an older method of authenticating DNS updates, and BIND9 no longer supports it
in favor of TSIG [[3]][3].&lt;&#x2F;p&gt;
&lt;p&gt;I learned this the hard way since my dynamic DNS update script was no longer
working and I could not understand why. Enabling further debug messages
[[4]][4] revealed the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;request has a SIG(0) signature but its support was removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So I had to generate a new key and copy it to both the server and client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;step-1-generate-a-tsig-key&quot;&gt;Step 1: Generate a TSIG Key&lt;&#x2F;h2&gt;
&lt;p&gt;TSIG works by using a shared secret key and a hashing algorithm to create a
digital signature for each DNS message. Both the client and server must have
the same TSIG key. When a message is sent, the TSIG key generates a signature
that is included with the message. The receiving party then uses the same key
to verify the signature.&lt;&#x2F;p&gt;
&lt;p&gt;Use the &lt;strong&gt;tsig-keygen&lt;&#x2F;strong&gt; [[5]][5] command to generate a TSIG key and save it
into a file for later use.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# tsig-keygen -a HMAC-SHA256 ddns-key.example.com &amp;gt; ddns.key &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command will generate a key similar to the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat ddns.key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key &amp;quot;ddns-key.example.com.&amp;quot; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    algorithm hmac-sha256;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    secret &amp;quot;3b52KtNNE87pIHmZkA3bN7Gc5MZK&#x2F;zAHg0OShp1PvZI=&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Where:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ddns-key.example.com&lt;&#x2F;strong&gt;: This is the name of the key.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;HMAC-SHA256&lt;&#x2F;strong&gt;: The algorithm used for the key.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;secret&lt;&#x2F;strong&gt;: The actual secret key generated.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;step-2-configure-bind9-to-use-the-tsig-key&quot;&gt;Step 2: Configure BIND9 to Use the TSIG Key&lt;&#x2F;h2&gt;
&lt;p&gt;I like to keep the keys in my named.conf.options file separated from the zone
definitions in named.conf.local.&lt;&#x2F;p&gt;
&lt;p&gt;To allow dynamic updates using the TSIG key, open the BIND9 configuration file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo vim &#x2F;etc&#x2F;bind&#x2F;named.conf.options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add the TSIG key configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;key &amp;quot;ddns-key.example.com.&amp;quot; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	algorithm hmac-sha256;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	secret &amp;quot;3b52KtNNE87pIHmZkA3bN7Gc5MZK&#x2F;zAHg0OShp1PvZI=&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Save and exit the configuration file.&lt;&#x2F;p&gt;
&lt;p&gt;Then, configure the zone (in &#x2F;etc&#x2F;bind&#x2F;named.conf.local) to allow updates
using the TSIG key:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zone &amp;quot;example.com&amp;quot; IN {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    type master;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    file &amp;quot;&#x2F;etc&#x2F;bind&#x2F;db.example.com&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    allow-update { key &amp;quot;ddns-key.example.com.&amp;quot;; };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;step-3-restart-bind9&quot;&gt;Step 3: Restart BIND9&lt;&#x2F;h2&gt;
&lt;p&gt;Apply the changes by restarting the BIND9 service.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl restart named&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;step-4-testing-dynamic-dns-updates&quot;&gt;Step 4: Testing Dynamic DNS Updates&lt;&#x2F;h2&gt;
&lt;p&gt;According to the &lt;strong&gt;nsupdate&lt;&#x2F;strong&gt; man file [[6]][6], when using the -k option,
nsupdate reads the shared secret from a key file. This key file can be in one
of two formats:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Named.conf-style format&lt;&#x2F;strong&gt;: looks like a BIND configuration file,
containing the key definition within curly braces. This format matches the
syntax you&#x27;d find in BIND&#x27;s configuration files (like named.conf). When using
this format, the key file contains a full key definition.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Raw secret format&lt;&#x2F;strong&gt;: contains just the raw base64-encoded
secret without any additional configuration statements. This format is simpler
but requires you to specify the key name and algorithm directly in the
&lt;strong&gt;nsupdate&lt;&#x2F;strong&gt; command.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you followed &lt;strong&gt;Step 1&lt;&#x2F;strong&gt; thoroughly, the key is already saved in ddns.key file
with the named.conf-style format. Therefore, it is sufficient to use nsupdate as
usual with the option -k ddns.key.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [DNS Dynamic Update](1)
[1]: https:&#x2F;&#x2F;docstore.mik.ua&#x2F;orelly&#x2F;networking_2ndEd&#x2F;dns&#x2F;ch10_02.htm
&lt;p&gt;[2] &lt;a href=&quot;&#x2F;articles&#x2F;bind9-tsig-keys&#x2F;2&quot;&gt;Doing secure dynamic DNS updates with BIND&lt;&#x2F;a&gt;
[2]: https:&#x2F;&#x2F;blog.hqcodeshop.fi&#x2F;archives&#x2F;76-Doing-secure-dynamic-DNS-updates-with-BIND.html&lt;&#x2F;p&gt;
&lt;p&gt;[3] &lt;a href=&quot;&#x2F;articles&#x2F;bind9-tsig-keys&#x2F;3&quot;&gt;Security Configurations - TSIG&lt;&#x2F;a&gt;
[3]: https:&#x2F;&#x2F;bind9.readthedocs.io&#x2F;en&#x2F;v9.18.13&#x2F;chapter7.html#tsig&lt;&#x2F;p&gt;
&lt;p&gt;[4] &lt;a href=&quot;&#x2F;articles&#x2F;bind9-tsig-keys&#x2F;4&quot;&gt;BIND Configuration File Guide -- logging Statement&lt;&#x2F;a&gt;
[4]: https:&#x2F;&#x2F;web.mit.edu&#x2F;darwin&#x2F;src&#x2F;modules&#x2F;bind&#x2F;bind&#x2F;doc&#x2F;html&#x2F;logging.html&lt;&#x2F;p&gt;
&lt;p&gt;[5] &lt;a href=&quot;&#x2F;articles&#x2F;bind9-tsig-keys&#x2F;5&quot;&gt;tsig-keygen(8)&lt;&#x2F;a&gt;
[5]: https:&#x2F;&#x2F;manpages.debian.org&#x2F;testing&#x2F;bind9&#x2F;tsig-keygen.8.en.html&lt;&#x2F;p&gt;
&lt;p&gt;[6] &lt;a href=&quot;&#x2F;articles&#x2F;bind9-tsig-keys&#x2F;6&quot;&gt;nsupdate(1)&lt;&#x2F;a&gt;
[6]: https:&#x2F;&#x2F;www.linux.org&#x2F;docs&#x2F;man1&#x2F;nsupdate.html&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Buying No-Name SD Cards from China</title>
        <published>2022-05-01T00:00:00+00:00</published>
        <updated>2022-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/buying-sd-cards-from-china/"/>
        <id>/articles/buying-sd-cards-from-china/</id>
        
        <content type="html" xml:base="/articles/buying-sd-cards-from-china/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;So I finally decided to upgrade the self-built firewall&#x2F;gateway for my home
internet connection [[1]][1]. I replaced an old Raspberry Pi Model B revision
1 (rpi B1) with a more powerful Pine A64. The transition was seamless, but I
found myself in need of a microSD card (the rpi B1 was using a full-size SD
card). I resorted to a random class-2 [[2]][2] 4 GB card I had laying around
that worked beautifully.&lt;&#x2F;p&gt;
&lt;p&gt;With my internet connection working again I was left wondering: can I do better
with as little money as possible? What if I buy some random microSD card(s) on a
famous online retail service based in China?&lt;&#x2F;p&gt;
&lt;p&gt;Many articles (such as [[3]][3] and [[4]][4]) test the speed of microSD
cards  but none deal with no-name brands. Moreover, it turns out that buying
cheap from china may be a waste of money due to fake products [[5]][5]. But
how bad the situation really is? People usually buy high-capacity drives and end
up receiving 8-16 GB cards with a fake firmware that reports a different disk
size to the OS. I don&#x27;t need much space for a standalone router thing. What if I
buy small microSD cards directly? Will they be fake nonetheless or will they be
the real thing? I found no answer to this question on the web so I decided to
run an experiment myself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-funny-microsd-cards-under-test&quot;&gt;The Funny microSD Cards under Test&lt;&#x2F;h2&gt;
&lt;p&gt;On a whim I bought 4 microSD cards for the same price as one 8 GB card from a
reputable brand. Those cards have some of the funniest names I&#x27;ve ever seen. Upon
arrival I also noticed that they are stamped with the most weird and
nonsensical approvals and speed ratings.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;sdcard_test&#x2F;4-cards.jpg&quot;&gt;
		&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;sdcard_test&#x2F;4-cards.jpg&quot;&#x2F;&gt;
	&lt;&#x2F;a&gt;
	&lt;figcaption&gt;
		The SD cards under test: Banoi_roox, Miomg, OUIO, ShanDian.
	&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;As a bonus, I added to the test batch two more reasonable cards I acquired while
waiting for the shipment to arrive: a 4 GB card labelled &#x27;eb-flash&#x27; and an
official Raspberry Pi 16 GB microSD card.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-test-script&quot;&gt;The Test Script&lt;&#x2F;h2&gt;
&lt;p&gt;To test the cards I used the f3 - Fight Flash Fraud tools [[6]][6] with a
custom script for repeatability. The usage guide [[7]][7] does not provide a
reference script for testing cards, so I had to make my own.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;sh -e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sdcard_test.sh - test sdcards for fake&#x2F;broken flash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;######################################################&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# WARNING! This script will eat your data. Set those variables correctly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DEV=&amp;quot;&#x2F;dev&#x2F;mmcblk0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MOUNTPOINT=&amp;quot;.&#x2F;mnt&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Print some info on the device (will fail if $DEV does not exists)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fdisk -l $DEV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Perform a destructive test on the device&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f3probe --destructive --time-ops $DEV&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Get first partition name, format it, mount it and run read&#x2F;write tests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;part=$(fdisk -l $DEV | awk &amp;#39;END {print $1}&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo First partition is $part, formatting it to FAT32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umount $part || true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkfs.fat -F32 $part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo Performing R&#x2F;W test on $part&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mount $part $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f3write $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umount $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mount $part $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;f3read $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Done. Unmount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umount $MOUNTPOINT&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This script is run with &lt;tt&gt;sdcard_test.sh &amp;gt; cardname.log&lt;&#x2F;tt&gt; for each of the
microSD card tested.&lt;&#x2F;p&gt;
&lt;p&gt;As the comments already explain, it does three things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Performs a destructive test with &lt;tt&gt;f3probe&lt;&#x2F;tt&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Identifies the first partition on the card and formats it to FAT32&lt;&#x2F;li&gt;
&lt;li&gt;Since now we&#x27;re sure the card is empty, it runs &lt;tt&gt;f3write&lt;&#x2F;tt&gt; and
&lt;tt&gt;f3read&lt;&#x2F;tt&gt; to verify the whole capacity of the device&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The &lt;tt&gt;umount&lt;&#x2F;tt&gt; - &lt;tt&gt;mount&lt;&#x2F;tt&gt; incantations before &lt;tt&gt;f3read&lt;&#x2F;tt&gt; are
needed to force-flush the filesystem cache. This forces Linux to re-read from
the device directly to make sure we are verifying the actual data written.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;sdcard_test&#x2F;testing.jpg&quot;&gt;
		&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;sdcard_test&#x2F;testing.jpg&quot;&#x2F;&gt;
	&lt;&#x2F;a&gt;
	&lt;figcaption&gt;
		Using the test script.
	&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;The procedure is thorough and takes 10-15 minutes for each SD card. However, it
ensures that I&#x27;ll also catch broken or failing flash chips. The part taking
most of the time is the execution of &lt;tt&gt;f3write&lt;&#x2F;tt&gt; and &lt;tt&gt;f3read&lt;&#x2F;tt&gt;.
These tests are needed because apparently, &lt;tt&gt;f3probe&lt;&#x2F;tt&gt; alone is not
sufficient to tell for sure if a card is not fake. At first I was confused, so I
opened an issue on the f3 repository [[8]][8] that led to a great explanation
on this matter by the f3 author himself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-results&quot;&gt;Test Results&lt;&#x2F;h2&gt;
&lt;p&gt;Enough talking here is a table with the results:&lt;&#x2F;p&gt;
&lt;table&gt;
	&lt;thead&gt;
		&lt;tr&gt;
			&lt;th&gt;SD card&lt;&#x2F;th&gt;
			&lt;th&gt;Capacity&lt;&#x2F;th&gt;
			&lt;th&gt;Verdict&lt;&#x2F;th&gt;
			&lt;th&gt;Write Speed [MB&#x2F;s]&lt;&#x2F;th&gt;
			&lt;th&gt;Read Speed [MB&#x2F;s]&lt;&#x2F;th&gt;
		&lt;&#x2F;tr&gt;
	&lt;&#x2F;thead&gt;
	&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td&gt;Banoi_roox&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;7.44 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;PASS&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;8.37&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;17.14&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
		&lt;tr&gt;
			&lt;td&gt;eb-flash&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;3.69 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;PASS&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;3.9&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;18.34&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
		&lt;tr&gt;
			&lt;td&gt;miomg&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;14.88 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;PASS&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;9.01&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;18.47&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
		&lt;tr&gt;
			&lt;td&gt;ouio&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;7.5 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;FAIL&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;-&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;-&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Raspberry Pi&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;14.75 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;PASS&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;5.91&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;18.4&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
		&lt;tr&gt;
			&lt;td&gt;shandian&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Capacity&quot;&gt;7.5 GB&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Verdict&quot;&gt;PASS&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Write Speed [MB&#x2F;s]&quot;&gt;4.51&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Read Speed [MB&#x2F;s]&quot;&gt;16.21&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
	&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;To compare the SD cards against each other, I calculated two figures of merit:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;speed score&lt;&#x2F;strong&gt; is the product of the read and write speeds in MB&#x2F;s&lt;&#x2F;li&gt;
&lt;li&gt;the &lt;strong&gt;overall score&lt;&#x2F;strong&gt; which is the speed score times the capacity in GB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The results are summarized in the following table (ordered by overall score).
I have removed the OUIO SD card since it did not pass the test.&lt;&#x2F;p&gt;
&lt;table&gt;
	&lt;thead&gt;
		&lt;tr&gt;
			&lt;th&gt;SD card&lt;&#x2F;th&gt;
			&lt;th&gt;Speed Score&lt;&#x2F;th&gt;
			&lt;th&gt;Overall Score&lt;&#x2F;th&gt;
		&lt;&#x2F;tr&gt;
	&lt;&#x2F;thead&gt;&lt;tbody&gt;
		&lt;tr&gt;
			&lt;td&gt;miomg&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Speed Score&quot;&gt;166.4&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Overall Score&quot;&gt;2476.3&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
			&lt;td&gt;Raspberry Pi&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Speed Score&quot;&gt;108.7&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Overall Score&quot;&gt;1604&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
			&lt;td&gt;Banoi_roox&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Speed Score&quot;&gt;143.5&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Overall Score&quot;&gt;1067.4&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
			&lt;td&gt;shandian&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Speed Score&quot;&gt;73.1&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Overall Score&quot;&gt;548.3&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;&lt;tr&gt;
			&lt;td&gt;eb-flash&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Speed Score&quot;&gt;71.5&lt;&#x2F;td&gt;
			&lt;td data-th=&quot;Overall Score&quot;&gt;263.9&lt;&#x2F;td&gt;
		&lt;&#x2F;tr&gt;
	&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;p&gt;All in all, the best card seems to be the miomg one. It is the fastest of the
lot and holds 16 GB of data. For the second prize I&#x27;d pick the Banoi_roox SD
card which, even though is ranked third, it is faster than the stock Raspberry
Pi SD. However, I see what the Raspberry Pi Foundation did here. Application
responsiveness is tied to the read speed and their SD card heavily favors
reading compared to writing. Keep in mind though that the Banoi_roox is almost
twice as fast in writing and its read speed is roughly 7% less than the rpi
card. I did not test random IOPS while reading and writing because a
firewall&#x2F;gateway is not a desktop computer so I do not really care about
application responsiveness.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;It seems common internet knowledge that fake and&#x2F;or cheap SD cards from china
are bad. By betting on smaller-size cards you can increase your chances to
purchase a &lt;em&gt;working&lt;&#x2F;em&gt; card.  This is based on the assumption that the
higher-capacity cards are just the same as the smaller size ones reporting to
the OS a fake capacity. To test this assumption, I bought a few 8-16 GB cards
and put them through a test script that reads and writes test patterns on the
flash to make sure it&#x27;s working as expected.&lt;&#x2F;p&gt;
&lt;p&gt;From my test results, I witnessed that 3&#x2F;4 cards were actually working and
reported the correct capacity. One of those was even faster than an official
Raspberry Pi SD card of the same size. Read&#x2F;write performance of the other cards
was as expected, considering the purchase price (~2-3 $ each).&lt;&#x2F;p&gt;
&lt;p&gt;I can now provide an answer to the questions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;How bad are cheap small-size microSD cards? Not that bad actually, 25% bad
I&#x27;d say ;).&lt;&#x2F;li&gt;
&lt;li&gt;Can I trust such cards? For niche applications I&#x27;d say yes, provided that
they are thoroughly tested before use.&lt;&#x2F;li&gt;
&lt;li&gt;Will I do it again? Of course. It&#x27;s worth it and now that I&#x27;m confident
about the script, testing is not time consuming and requires minimal manual
interaction.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;P.S. I won&#x27;t trust those SD cards with my family photos anyway.&lt;&#x2F;p&gt;
&lt;p&gt;P.P.S. I received full refund for the broken OUIO card. Always ask for a refund!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [gateway_collection&#x2F;atlas - electricant][1]
[1]: https:&#x2F;&#x2F;github.com&#x2F;electricant&#x2F;gateway_collection&#x2F;tree&#x2F;master&#x2F;atlas
&lt;p&gt;[2] [Speed Class | SD Association][2]
[2]: https:&#x2F;&#x2F;www.sdcard.org&#x2F;developers&#x2F;sd-standard-overview&#x2F;speed-class&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;[3] [microSD Card Benchmarks | Raspberry Pi Dramble][3]
[3]: https:&#x2F;&#x2F;www.pidramble.com&#x2F;wiki&#x2F;benchmarks&#x2F;microsd-cards&lt;&#x2F;p&gt;
&lt;p&gt;[4] [Raspberry Pi microSD card performance comparison - 2019 | Jeff Geerling][4]
[4]: https:&#x2F;&#x2F;www.jeffgeerling.com&#x2F;blog&#x2F;2019&#x2F;raspberry-pi-microsd-card-performance-comparison-2019&lt;&#x2F;p&gt;
&lt;p&gt;[5] [Chinese micro SD card. : ExpectationVsReality][5]
[5]: https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;ExpectationVsReality&#x2F;comments&#x2F;41vl2i&#x2F;chinese_micro_sd_card&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;[6] [f3 - Fight Flash Fraud][6]
[6]: https:&#x2F;&#x2F;fight-flash-fraud.readthedocs.io&#x2F;en&#x2F;stable&#x2F;introduction.html&lt;&#x2F;p&gt;
&lt;p&gt;[7] [Usage - f3][7]
[7]: https:&#x2F;&#x2F;fight-flash-fraud.readthedocs.io&#x2F;en&#x2F;stable&#x2F;usage.html&lt;&#x2F;p&gt;
&lt;p&gt;[8] [Fake card not detected by f3probe][8]
[8]: https:&#x2F;&#x2F;github.com&#x2F;AltraMayor&#x2F;f3&#x2F;issues&#x2F;180&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Upgrading PostgreSQL Clusters</title>
        <published>2022-02-01T00:00:00+00:00</published>
        <updated>2022-02-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/postgresql-upgrade-cluster/"/>
        <id>/articles/postgresql-upgrade-cluster/</id>
        
        <content type="html" xml:base="/articles/postgresql-upgrade-cluster/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;I own a Debian PC that is used as Network Attached Storage (NAS) and runs
PostgreSQL [[1]][1] with data files stored on a Btrfs RAID1
filesystem [[2]][2]. As expected, with every new Debian release comes a
new major version of the PostgreSQL database which is not compatible with the
internal data storage format of the previous one. This requires upgrading the on
disk data files before using the new database server [[3]][3].&lt;&#x2F;p&gt;
&lt;p&gt;At the time of writing, a new stable release of Debian is available roughly
every two years with the oldstable entering end of life (EOL) one year after
the latest stable has been released [[4]][4]. It goes without saying
that, every time I upgrade Debian on such PC, I have to rediscover once again
how to also upgrade PostgreSQL. This guide will hopefully save some time to my
future self by offering a step-by-step summary of some guides available online,
which are incomplete and&#x2F;or
outdated [[5]][5] [[6]][6] [[7]][7].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;upgrade-process&quot;&gt;Upgrade Process&lt;&#x2F;h2&gt;
&lt;p&gt;The following steps assume a fresh installation of PostgreSQL from the official
Debian packages.&lt;&#x2F;p&gt;
&lt;p&gt;Right after installation, the new version is automatically started alongside
the old one. The command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemctl | grep postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;will show the two corresponding unit files as
&lt;tt&gt;postgresql@[version]-[cluster]&lt;&#x2F;tt&gt; both of which should be listed as
running.&lt;&#x2F;p&gt;
&lt;p&gt;The first step is changing the configuration file of the new server to point to
the database directory of the RAID array. To do so, the server must be stopped
and the database reinitialized after changing the &lt;tt&gt;data_directory&lt;&#x2F;tt&gt; option
of &lt;tt&gt;&#x2F;etc&#x2F;postgresql&#x2F;[version]&#x2F;[cluster]&#x2F;postgresql.conf&lt;&#x2F;tt&gt;. To make any
future migration or update process easier, it&#x27;s best to have a different folder
for each postgres version and cluster. Once the configuration file has been
changed, it&#x27;s time to initialize the new database (as the user postgres):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# su postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# &#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[new version]&#x2F;bin&#x2F;initdb \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		-D [mountpoint]&#x2F;pgsql&#x2F;[new version]&#x2F;[cluster]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl restart postgresql@[new version]-[cluster]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The new server should restart smoothly using
&lt;tt&gt;[mountpoint]&#x2F;pgsql&#x2F;[new version]&#x2F;[cluster]&lt;&#x2F;tt&gt; as the data directory. If
not, double check the config file.&lt;&#x2F;p&gt;
&lt;p&gt;If the step above succeeded, it&#x27;s time to perform the actual migration. To do
so, stop all the services using PostgreSQL and the old and new database servers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl stop postgresql@[old version]-[cluster]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl stop postgresql@[new version]-[cluster]  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Before migrating, it&#x27;s wise to perform a check to verify that the source and
destination clusters are actually compatible. Only if the check succeeds we&#x27;ll
eventually migrate the data. Please note that the option &lt;tt&gt;--link&lt;&#x2F;tt&gt; of
&lt;tt&gt;pg_upgrade&lt;&#x2F;tt&gt; has not been used on purpose: albeit it makes the migration
process faster, if something goes wrong, the cluster will remain in some
half-baked state requiring unspecified command-line voodoo to restore it. By
not using such option, the old cluster will always be available, the new data
directory can be deleted and the migration process can be restarted.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;&#x2F;strong&gt; With all the services and the database server stopped, performing a
backup of the old cluster is a clever idea. No seriously, do it now before it&#x27;s
too late.&lt;&#x2F;p&gt;
&lt;p&gt;To start the migration run the following commands as the postgres user and
double check that they are run from postgres&#x27; home directory:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# su postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# cd ~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# &#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[new version]&#x2F;bin&#x2F;pg_upgrade \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-datadir &amp;quot;[mountpoint]&#x2F;pdsql&#x2F;[old version]&#x2F;[cluster]&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-datadir &amp;quot;[mountpoint]&#x2F;pdsql&#x2F;[new version]&#x2F;[cluster]&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-bindir &amp;quot;&#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[old version]&#x2F;bin&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-bindir &amp;quot;&#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[new version]&#x2F;bin&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-options &amp;#39;-c config_file=&#x2F;etc&#x2F;postgresql&#x2F;[old version]&#x2F;[cluster]&#x2F;postgresql.conf&amp;#39; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-options &amp;#39;-c config_file=&#x2F;etc&#x2F;postgresql&#x2F;[new version]&#x2F;[cluster]&#x2F;postgresql.conf&amp;#39; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--check&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Inspect carefully the output of the command above for any error. If none, the
&lt;tt&gt;--check&lt;&#x2F;tt&gt; option can be removed to start the actual upgrade:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# &#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[new version]&#x2F;bin&#x2F;pg_upgrade \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-datadir &amp;quot;[mountpoint]&#x2F;pdsql&#x2F;[old version]&#x2F;[cluster]&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-datadir &amp;quot;[mountpoint]&#x2F;pdsql&#x2F;[new version]&#x2F;[cluster]&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-bindir &amp;quot;&#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[old version]&#x2F;bin&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-bindir &amp;quot;&#x2F;usr&#x2F;lib&#x2F;postgresql&#x2F;[new version]&#x2F;bin&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--old-options &amp;#39;-c config_file=&#x2F;etc&#x2F;postgresql&#x2F;[old version]&#x2F;[cluster]&#x2F;postgresql.conf&amp;#39; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--new-options &amp;#39;-c config_file=&#x2F;etc&#x2F;postgresql&#x2F;[new version]&#x2F;[cluster]&#x2F;postgresql.conf&amp;#39; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		--jobs [number of cpus]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Wait a few minutes hoping for the best and voilà the new data directory should
contain a migrated copy of the old cluster. If the commands above are run from
ssh, I suggest using &lt;tt&gt;screen&lt;&#x2F;tt&gt; or &lt;tt&gt;tmux&lt;&#x2F;tt&gt; to be able to reconnect to
your session in case ssh hangs for whatever reason.&lt;&#x2F;p&gt;
&lt;p&gt;As a final step, swap the old PostgreSQL server with the new one by setting the
option &lt;tt&gt;port=5232&lt;&#x2F;tt&gt; in
&lt;tt&gt;&#x2F;etc&#x2F;postgresql&#x2F;[new version]&#x2F;[cluster]&#x2F;postgresql.conf&lt;&#x2F;tt&gt;, disable the
old server and start the new one.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemctl disable postgresql@[old version]-[cluster]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemctl enable --now postgresql@[new version]-[cluster]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Since optimizer statistics are not transferred by the &lt;tt&gt;pg_upgrade&lt;&#x2F;tt&gt;
command, restore them with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# su postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# cd ~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# .&#x2F;analyze_new_cluster.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once finished, the services depending on PostgreSQL can be restarted and should
work as usual. If not, since the old data directory is still available, the new
server can be swapped for the old one to see what went wrong.&lt;&#x2F;p&gt;
&lt;p&gt;The following commands will delete the old cluster&#x27;s data files:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# su postgres&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# cd ~&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(postgres)# .&#x2F;delete_old_cluster.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I usually keep the old data around for a while (until the next migration
actually) so that I always have and old copy laying around. Better be safe than
sorry.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [Start PostgreSQL on Debian 8][1]
[1]: &#x2F;articles&#x2F;postgresql-start-debian&#x2F;
&lt;p&gt;[2] [A Note About Btrfs RAID1 for my Future Self][2]
[2]: &#x2F;articles&#x2F;note-btrfs-raid1&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;[3] [Upgrading a PostgreSQL Cluster][3]
[3]: https:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;current&#x2F;upgrading.html&lt;&#x2F;p&gt;
&lt;p&gt;[4] [Production Releases - Debian Wiki][4]
[4]: https:&#x2F;&#x2F;wiki.debian.org&#x2F;DebianReleases#Production_Releases&lt;&#x2F;p&gt;
&lt;p&gt;[5] [PostgreSQL Migration - Debian Wiki][5]
[5]: https:&#x2F;&#x2F;wiki.debian.org&#x2F;PostgreSql#Migration&lt;&#x2F;p&gt;
&lt;p&gt;[6] [Using pg upgrade on Ubuntu&#x2F;Debian - PostgreSQL Wiki][6]
[6]: https:&#x2F;&#x2F;wiki.postgresql.org&#x2F;wiki&#x2F;Using_pg_upgrade_on_Ubuntu&#x2F;Debian&lt;&#x2F;p&gt;
&lt;p&gt;[7] [DebianGis&#x2F;UpdatingPostGIS - Debian Wiki][7]
[7]: https:&#x2F;&#x2F;wiki.debian.org&#x2F;DebianGis&#x2F;UpdatingPostGIS&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Post-install Raspberry Pi Tweaks</title>
        <published>2021-09-01T00:00:00+00:00</published>
        <updated>2021-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/raspberry-pi-tweaks/"/>
        <id>/articles/raspberry-pi-tweaks/</id>
        
        <content type="html" xml:base="/articles/raspberry-pi-tweaks/">&lt;p&gt;Some notes about the first tweaks I apply on a freshly installed Arch Linux
image on a Raspberry Pi. The following notes apply to other Linux distros as
well. Maybe the commands and&#x2F;or package names are different.&lt;&#x2F;p&gt;
&lt;p&gt;If, for whatever reason, I&#x27;ll switch distro (why should I? Arch is the best one)
I may also update this guide, pointing to the Arch-specific stuff and offering
alternatives. In the meantime, if you stumble upon this page, do your own
research (DYOR) before blindly applying those tweaks. Moreover, this list is
highly opinionated and DYOR helps de-opinionate it. Feel free to discuss the
content by opening an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;electricant&#x2F;electricant.github.io&#x2F;issues&quot;&gt;issue on github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fakehwclock&quot;&gt;Fakehwclock&lt;&#x2F;h2&gt;
&lt;p&gt;The Raspberry Pi does not have an hardware real time clock (RTC). Therefore,
upon reboot the time is lost and has to be set manually or via the network time
protocol (NTP). This process takes time and requires an internet connection
available after boot. The utility fake-hwclock [[1]][1] can be used to restore
the clock to an approximately accurate value to speed up the NTP clock
synchronization procedure.&lt;&#x2F;p&gt;
&lt;p&gt;Fake-hwclock is installed the usual way via pacman:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo pacman -Syu fake-hwclock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By default, the fake-hwclock-save.timer unit is run every 15 minutes and also
15 minutes after boot. The saving interval is quite short and may damage the SD
card in the long run. Depending on the time accuracy requirements, by creating
an overlay file for the unit with the command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl edit fake-hwclock-save.timer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;the interval can be modified. By adding the following lines to the file, the
timer is run once per day:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Timer]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;OnUnitActiveSec=1day&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;AccuracySec=1day&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &#x27;AccuracySec&#x27; settings is used to save power and avoid waking up the CPU
just to save the time. Refer to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.freedesktop.org&#x2F;software&#x2F;systemd&#x2F;man&#x2F;systemd.timer.html&quot;&gt;systemd.timer&lt;&#x2F;a&gt; for more details about the various
timer config options. Keep in mind that the clock is automatically saved during
shutdown, independently of the last time it was saved. This means that, if the
Raspberry Pi is rebooted cleanly the clock will lag a few minutes. In case of a
power loss the clock will be one day behind actual time in the worst case.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-the-hardware-random-number-generator&quot;&gt;Use the Hardware Random Number Generator&lt;&#x2F;h2&gt;
&lt;p&gt;More information is available here: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Rng-tools&quot;&gt;Rng-tools - ArchWiki&lt;&#x2F;a&gt;.
This guide is shorter and tailored to the Raspberry Pi.&lt;&#x2F;p&gt;
&lt;p&gt;Make sure rng-tools is installed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo pacman -Syu rng-tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Disable haveged since it is no longer needed and it might compete with rngd&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl disable --now haveged&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Check that &#x2F;etc&#x2F;conf.d&#x2F;rngd contains the line&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RNGD_OPTS=&amp;quot;-o &#x2F;dev&#x2F;random -r &#x2F;dev&#x2F;hwrng&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;otherwise add it to the file to tell the daemon where to find the hardware
random number generator.&lt;&#x2F;p&gt;
&lt;p&gt;Rngd can now be enabled and started:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sudo systemctl enable --now rngd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can now check the amount of entropy reported by the kernel:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat &#x2F;proc&#x2F;sys&#x2F;kernel&#x2F;random&#x2F;entropy_avail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It should be around 3000 (the more the better).&lt;&#x2F;p&gt;
&lt;p&gt;On Raspberry Pis and other SBCs, rngd may exhibit sporadic CPU spikes to 100%
which can last quite a long time [[2]][2].
At the time of writing, a fix has already been merged to the repo. Anyway, the
issue disappears by editing &#x2F;etc&#x2F;conf.d&#x2F;rngd to include the following option and
restarting the daemon:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RNGD_OPTS=&amp;quot;-x jitter&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apparently, starting from Linux kernel 5.6, both haveged and rng-tools are not
needed anymore [[3]][3][[4]][4]. This section is kept for posterity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mount-var-cache-and-whatnot-in-memory-with-zram&quot;&gt;Mount &#x2F;var&#x2F;cache (and whatnot) in memory with zram&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;html&#x2F;latest&#x2F;admin-guide&#x2F;blockdev&#x2F;zram.html&quot;&gt;ZRAM&lt;&#x2F;a&gt; is a Linux kernel module to create block devices that store the data
compressed in RAM, this allows to store more data in the same amount of memory,
at the expense of CPU usage. This is ideal, for example, for &#x2F;var&#x2F;cache that
contains cached data from application programs and does not need to survive a
reboot.&lt;&#x2F;p&gt;
&lt;p&gt;Many guides already exist [[5]][5][[6]][6], I mixed and merged them to suit
my own taste. First of all one needs to load the zram module, telling it how
many devices to create. The simplest way to achieve this is to create the file
&#x2F;etc&#x2F;modules-load.d&#x2F;zram.conf containing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;zram&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This loads the zram module on boot which, by default, starts a single device.
To change this behavior, create &#x2F;etc&#x2F;modprobe.d&#x2F;zram.conf and insert:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;options zram num_devices=&amp;lt;desired number of zram devices&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Zram devices are block devices with no actual file system on them, so we need to
format the device before we can mount it somewhere. I used udev to format on
boot &#x2F;dev&#x2F;zram0 as ext4 without journalling. Removing the journal speeds up the
file system at the expense of probable data corruption if the power fails. Zram
contents are lost anyway if the power is removed so, I&#x27;d rather get my
performance bonus. Create &#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;10-zram.rules containing:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;KERNEL==&amp;quot;zram0&amp;quot;, SUBSYSTEM==&amp;quot;block&amp;quot;, ACTION==&amp;quot;add&amp;quot;, \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ATTR{disksize}=&amp;quot;256M&amp;quot; ATTR{mem_limit}=&amp;quot;256M&amp;quot;, \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	RUN+=&amp;quot;&#x2F;sbin&#x2F;mkfs.ext4 -O ^has_journal -L $name $env{DEVNAME}&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This creates a 256M zram disk formatted as ext4 on &#x2F;dev&#x2F;zram0.&lt;&#x2F;p&gt;
&lt;p&gt;The device can now be mounted via &#x2F;etc&#x2F;fstab as usual:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;zram0 &#x2F;var&#x2F;cache ext4  defaults,nosuid,nodev,noexec 0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;enable-the-watchdog&quot;&gt;Enable the Watchdog&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;NOTE:&lt;&#x2F;em&gt; I&#x27;m still checking whether I really need this or not. Or even if it
works and keeps my Pi up and running. For the time being I&#x27;ll keep this section
as a dump of unorganized thoughts and references.&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Arch_User_Repository
https:&#x2F;&#x2F;aur.archlinux.org&#x2F;packages&#x2F;watchdog&#x2F; -&amp;gt; add armv6h to the architectures
in PKGBUILD
https:&#x2F;&#x2F;raspberrypi.stackexchange.com&#x2F;questions&#x2F;92462&#x2F;installing-watchdog-daemon-on-arch&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [fake-hwclock for Arch Linux Arm on Raspberry Pi (using systemd)][1]
[1]: https:&#x2F;&#x2F;archplusplus.co.uk&#x2F;post&#x2F;40202081414&#x2F;fake-hwclock-for-arch-linux-arm-on-raspberry-pi
&lt;p&gt;[2] [Sporadic excessive CPU usage on RPi4B - Issue #136][2]
[2]: https:&#x2F;&#x2F;github.com&#x2F;nhorman&#x2F;rng-tools&#x2F;issues&#x2F;136&lt;&#x2F;p&gt;
&lt;p&gt;[3] [random: make &#x2F;dev&#x2F;random be almost like &#x2F;dev&#x2F;urandom][3]
[3]: https:&#x2F;&#x2F;github.com&#x2F;torvalds&#x2F;linux&#x2F;commit&#x2F;30c08efec8884fb106b8e57094baa51bb4c44e32&lt;&#x2F;p&gt;
&lt;p&gt;[4] [Is haveged still useful&#x2F;relevant? - Issue #57][4]
[4]: https:&#x2F;&#x2F;github.com&#x2F;jirka-h&#x2F;haveged&#x2F;issues&#x2F;57&lt;&#x2F;p&gt;
&lt;p&gt;[5] [zram - Gentoo Wiki][5]
[5]: https:&#x2F;&#x2F;wiki.gentoo.org&#x2F;wiki&#x2F;Zram&lt;&#x2F;p&gt;
&lt;p&gt;[6] [Improving performance - ArchWiki][6]
[6]: https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;title&#x2F;Improving_performance#zram_or_zswap&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Note About Btrfs RAID1 for my Future Self</title>
        <published>2021-01-01T00:00:00+00:00</published>
        <updated>2021-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/note-btrfs-raid1/"/>
        <id>/articles/note-btrfs-raid1/</id>
        
        <content type="html" xml:base="/articles/note-btrfs-raid1/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;This is just a random note I have collected about Btrfs RAID1 [[1]][1] and
how to deal with it in my NAS setup (I really have to write about it some day).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-btrfs-raid1-works&quot;&gt;How Btrfs RAID1 Works&lt;&#x2F;h2&gt;
&lt;p&gt;By default RAID1 in Btrfs creates no more than two copies of the data,
regardless of the number of disks in the array. This means that, from the data
integrity point of view, there is no point in using more than two disks. In
RAID1, mode when a third disk is added, only the total capacity is increased.
Btrfs distributes the writes in such a way that the array will survive the
failure of one disk only. There are different RAID options [[2]][2] that
enable more copies of the data and parity with more than two disks.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;btrfs-raid1-in-my-nas&quot;&gt;Btrfs RAID1 in my NAS&lt;&#x2F;h2&gt;
&lt;p&gt;The motherboard I&#x27;m currently using has 4 serial-ATA ports. One of them is used
for the OS disk while the other three are left for the data RAID.&lt;&#x2F;p&gt;
&lt;p&gt;Of the three remaining ports, two are dedicated to the main hard disks while the
third one is left unused. By doing so I can use this spare port to throw in a
new hard disk in case one is near its end of life but it is not yet failed.
I will eventually remove the failing disk after the new one is in place,
leaving its port free for future drive replacements.&lt;&#x2F;p&gt;
&lt;p&gt;To add a new device to a Btrfs RAID:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# btrfs device add &#x2F;dev&#x2F;newdrive &#x2F;mountpoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To remove the failed disk:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# btrfs device remove &#x2F;dev&#x2F;broken &#x2F;mountpoint&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This command removes the selected disk and automatically rebalances the data
within the remaining hard drives.&lt;&#x2F;p&gt;
&lt;p&gt;And while I&#x27;m at it why not throw in a run of&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# badblocks -b 4096 -e 1 -wsv &#x2F;dev&#x2F;sdX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;as a new drive burn-in ritual [[3]][3] before formatting and adding the drive
to the pool?&lt;&#x2F;p&gt;
&lt;p&gt;After going through all the steps above the array is ready. However, I have to
buy a new hard drive to have a spare when needed. It is worth having a look at
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;datahoarder&#x2F;wiki&#x2F;index&quot;&gt;r&#x2F;DataHoarder wiki&lt;&#x2F;a&gt; for some
tips.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [Using Btrfs with Multiple Devices][1]
[1]: https:&#x2F;&#x2F;btrfs.wiki.kernel.org&#x2F;index.php&#x2F;Using_Btrfs_with_Multiple_Devices
&lt;p&gt;[2] [Manpage&#x2F;mkfs.btrfs][2]
[2]: https:&#x2F;&#x2F;btrfs.wiki.kernel.org&#x2F;index.php&#x2F;Manpage&#x2F;mkfs.btrfs#PROFILES&lt;&#x2F;p&gt;
&lt;p&gt;[3] [New Drive Burn-In Rituals][3]
[3]: https:&#x2F;&#x2F;perfectmediaserver.com&#x2F;hardware&#x2F;new-drive-burnin&#x2F;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Netis WF2419I Hacking</title>
        <published>2020-08-01T00:00:00+00:00</published>
        <updated>2020-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/netis-wf2419i-hacking/"/>
        <id>/articles/netis-wf2419i-hacking/</id>
        
        <content type="html" xml:base="/articles/netis-wf2419i-hacking/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;I had an old (2014-ish) and cheap (if I recall correctly it cost me around 15-20
€) Netis WF2419I [[1]][1] router collecting dust in a cabinet at home. Its
performance has always been lackluster with the WiFi connection dropping and
restarting every few minutes. I bought it to serve as a guest AP for my dorm
while I was studying in Padova. It worked dutifully for a few years there but,
after I moved, I&#x27;ve never used it any more and switched to a whole different
setup (which I hope to describe in another post) with more powerful hardware.&lt;&#x2F;p&gt;
&lt;p&gt;This router was almost forgotten, until I read an excellent article by George
Hilliard [[2]][2] about hacking Reolink cameras. I had no plans to use this
device in any case, given that it is rather old and crappy. So reading the
article was enough to spark my interest in trying to reverse engineer and add
as much new functionality as possible to this piece of hardware (or, perhaps,
should I say &quot;junk&quot;?). It surely won&#x27;t be missed if something goes wrong in the
process.&lt;&#x2F;p&gt;
&lt;p&gt;First off I set myself some goals to keep me on track:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Open the router and identify chipset, RAM, FLASH size and serial port&lt;&#x2F;li&gt;
&lt;li&gt;Dump the flash contents and inspect them&lt;&#x2F;li&gt;
&lt;li&gt;Rebuild a bootable image from the extracted contents and flash it&lt;&#x2F;li&gt;
&lt;li&gt;Setup a working buildroot image and compile a statically-linked busybox&lt;&#x2F;li&gt;
&lt;li&gt;Compile a (hopefully working) custom kernel for the device&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;As you can see, each goal somewhat depends on the previous one. Moreover, it&#x27;s
my first time that I try something like this and some of those goals are not
easy. Murphy&#x27;s law gets you every time and I have encountered many roadblocks
during this journey. In writing, I will not spare any of the details, including
the &lt;strong&gt;MANY&lt;&#x2F;strong&gt; failed attempts. That&#x27;s why I&#x27;m calling this page a diary.&lt;&#x2F;p&gt;
&lt;p&gt;At the time of writing I&#x27;m quite far from completion and I have somewhat
abandoned the project. I may reboot it in the future so, perhaps, I might
decide to split this post into a series.&lt;&#x2F;p&gt;
&lt;p&gt;All the code and raw notes I have produced are available on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;electricant&#x2F;netis-wf2419-router-hacking&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opening-up-the-device-talking-to-the-serial-port&quot;&gt;Opening up the Device &amp;amp; Talking to the Serial Port&lt;&#x2F;h2&gt;
&lt;p&gt;Opening the device and finding the serial port has been the easy part.
Actually, before rushing to the screwdriver to open the chassis, I searched for
the FCC ID of the device on the back of the unit. Every RF device needs to be
FCC certified to be sold and imported in the US [[3]][3] and this router is
no exception. I found the FCC ID on the lower-right corner of the label:
&lt;strong&gt;T58WF2419R&lt;&#x2F;strong&gt;. By searching for this ID on the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.fcc.gov&#x2F;oet&#x2F;ea&#x2F;fccid&quot;&gt;official FCC website&lt;&#x2F;a&gt; or on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;fccid.io&#x2F;T58WF2419R&quot;&gt;fccid.io&lt;&#x2F;a&gt; I already had access to many low-level
details about the router, including internal photos, without the need to open
it. Not that opening it was a big deal. The warranty is already expired so no
worries.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;fcc_id_label.jpg&quot;&gt;
	&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;fcc_id_label.jpg&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;The FCC ID, as seen on the label.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Stop wandering around the FCC website reading test reports! Given my goals, I
need access to the flash chip so I have to open the device anyway. This was
as easy as just removing the two screws on the bottom side (one is hidden by the
mandatory &#x27;warranty void if seal is broken&#x27; sticker, about which I couldn&#x27;t care
less) and popping open the case.&lt;&#x2F;p&gt;
&lt;p&gt;With the case open, the following components appeared before me onto the sea of
green of the board and are highlighted in the picture below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Realtek RTL8196C - the main router chipset&lt;&#x2F;li&gt;
&lt;li&gt;Realtek RTL8192CE - WiFi chipset&lt;&#x2F;li&gt;
&lt;li&gt;Winbond W25Q32FV - 32Mbit (4MB) SPI FLASH memory&lt;&#x2F;li&gt;
&lt;li&gt;ESMT M12L128168A - 2M x 16 Bit x 4 Banks (16MB) SDRAM&lt;&#x2F;li&gt;
&lt;li&gt;A few test points, probably for JTAG and UART access&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;components_labelled.jpg&quot;&gt;
	&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;components_labelled.jpg&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;Router board with main components labelled.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;The usual first step is to see if a serial port is exposed somewhere on the
board in order to have access to a shell on the device. As shown in the picture
above, just by looking at the board, I already identified a few suitable
testpoints. Just to be sure and also for future use, I looked up on my
favourite search engine for the main router chipset datasheet. As expected,
somebody (thank you!) released a confidential copy of the document [[4]][4].
I neglected all the other details for the moment and scrolled right-ahead to the
pinout, looking for a serial port of some kind.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;chipset_pinout.png&quot;&gt;
		&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;chipset_pinout.png&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;
	Realtek RTL8196C chipset pinout with serial port pins highlighted.
&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;In the above picture I cut the relevant part of the datasheet, showing the
pinout of the chip. In the bottom-right part there are two pins (pin 36
and 37) labelled &lt;b&gt;UART_RX&#x2F;GPIOA7&lt;&#x2F;b&gt; and &lt;b&gt;UART_TX&#x2F;GPIOB0&lt;&#x2F;b&gt;
respectively. Those pins can be configured either as GPIOs (for controlling the
router LEDs etc.) or as a serial port. I traced those two pins with a multimeter
and they are routed to the unpopulated header labelled &lt;strong&gt;J1&lt;&#x2F;strong&gt;. Most likely,
they are the serial port I&#x27;m looking for. Time to solder a pin header and
connect a TTL to USB adapter and see who&#x27;s there. But HEY! Wait! What&#x27;s the baud
rate? A quick check with an oscilloscope revealed it&#x27;s &lt;strong&gt;38400bps&lt;&#x2F;strong&gt;. I know
using an oscilloscope for this task it&#x27;s a bit of an overkill, but I had one on
hand so why not using it? By the way, some trial and error works too.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;pin_header.jpg&quot;&gt;
	&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;pin_header.jpg&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;Pin header soldered to __J1__.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;After connecting a TTL to serial adapter and issuing&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ screen -L &#x2F;dev&#x2F;ttyUSB0 38400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When the router boots, the following messages appear on my terminal:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;=============================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;Probe SPI #0 &amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1.Manufacture ID=0xef&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2.Device ID=0x40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;3.Capacity ID=0x16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4.Winbond SPI (4 MByte)!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;5.Total sector-counts = 1024(sector=4KB)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;6.spi_flash_info[0].device_size = 22&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01_8198_SFCR(b8001200) =1f800000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01_8198_SFCR2(b8001204) =bb08000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;01_8198_SFCSR(b8001208) =d8350000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---RealTek(RTL8196C)at 2014.08.29-12:43+0800 version v1.1c [16bit](390MHz)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no sys signature at 00010000!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;no sys signature at 00020000!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Jump to image start=0x80500000...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;decompressing kernel:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Uncompressing Linux... done, booting the kernel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done decompressing kernel.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RTL8192C-RTL8188C driver version 1.5 (2012-05-04)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;serial console detected.  Disabling virtual terminals.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;init started:  BusyBox v1.00-pre8 (2015.01.23-06:46+0000) multi-call binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BusyBox v1.00-pre8 (2015.01.23-06:46+0000) Built-in shell (msh)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Enter &amp;#39;help&amp;#39; for a list of built-in commands.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cp: &#x2F;etc&#x2F;tmp&#x2F;pics*: No such file or directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING [factory_args.c:check_and_restore_factory_args:623]: current: [0x2adb521c], the length is zero!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;50&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; 4.8d.38.c2.74.9c.0.0.0.0.0.0.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;save_param load &#x2F;var&#x2F;ppp&#x2F;.pppoe.session &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;len = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wlan_check.sh: do nothing......&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;===================================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dnrd --cache=off  &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WWW:netiscc, len:9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;domain:netis.cc, len:8&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WWW2:wwwnetiscc, len:13&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;domain2:www.netis.cc, len:12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;killall: xhcatv: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;killall: multi_ppp: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;killall: igmpproxy: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;killall: udhcpc: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wlanapp_sh:2042:@@@@@@@####;wlan0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_CCK_A=302f2f2f2f2e2e2e2e2d2d2d2d2c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_CCK_A_new=302f2f2f2f2e2e2e2e2d2d2d2d2c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_HT40_1S_A=302f2f2f2f2e2e2e2e2d2d2d2d2c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_HT40_1S_An=302f2f2f2f2e2e2e2e2d2d2d2d2c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_HT20=ffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_HT20n=ffffffffffffffffffffffffffff&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_DIFF_OFDM=6161616161616161616161616161&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIB_HW_TX_POWER_DIFF_OFDMn=6161616161616161616161616161&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SIOCGIFFLAGS: No such device&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bridge br0 doesn&amp;#39;t exist; can&amp;#39;t delete it&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SIOCDELRT: No such process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SIOCDELRT: No such process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dhcp is dis----------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wlanapp_sh:2042:@@@@@@@####;wlan0 wlan0-va0 wlan0-va1 wlan0-va2 wlan0-va3 wlan0-vxd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iapp: not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wlanapp_sh:2334:wlan0:wlan0:wlan0-va3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ip:192.168.1.1 mask:255.255.255.0 gw:192.168.1.254&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SIOCDELRT: No such process&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iwcontrol RegisterPID to (wlan0)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* Setup Firewall&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;port trigger stop.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;port trigger init, wan is eth1.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;port trigger start.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;doamin=3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;* Start NTP daemon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;proc&#x2F;sys&#x2F;net&#x2F;ipv4&#x2F;conf&#x2F;all&#x2F;arp_ignore: cannot create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;proc&#x2F;sys&#x2F;net&#x2F;ipv4&#x2F;conf&#x2F;default&#x2F;arp_ignore: cannot create&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iwpriv wlan0 set_mib bcnint=25--&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;netis(WF2419I)-V2.12.36123,2015.06.30 16:47.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;time.windows.com: Unknown host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;========================END init.sh===============================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;321&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;348&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;bin&#x2F;ota_init.sh: not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;351&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;bin&#x2F;cdrom_wizard: not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;killall: boa: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;365&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;366&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;telnetd.sh: not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# killall: boa: no process killed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[run_webs_server_by_execv:46:restart_webs.c]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Starting Protocol Module: HTTP Server                      ... OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;create_server_socket-357:Bind err!caught SIGTERM, starting shutdown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;exiting Boa normally (uptime 1 seconds)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Starting Protocol Module: HTTP Server                      ... OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Good. It looks like the router offers a root command prompt on the serial port.
I poked around a bit and tried some commands to gain some info on the
hardware and software of the device:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# ls&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bin		etc		media		sbin		tmp		var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dev		lib		proc		sys			usr		web&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mount&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mtdblock1 on &#x2F; type squashfs (ro)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;none on &#x2F;proc type proc (rw)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmpfs on &#x2F;var type tmpfs (rw)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# df&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem           1k-blocks      Used Available Use% Mounted on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;dev&#x2F;mtdblock1            2048      2048         0 100% &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tmpfs                     6144       176      5968   3% &#x2F;var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat &#x2F;proc&#x2F;cmdline&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;root=&#x2F;dev&#x2F;mtdblock1 console=0 single&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat &#x2F;proc&#x2F;cpuinfo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;system type		: Philips Nino&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;processor		: 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cpu model		: R3000 V0.0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BogoMIPS		: 389.12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wait instruction	: yes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;microsecond timers	: no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tlb_entries		: 32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;extra interrupt vector	: no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;hardware watchpoint	: no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VCED exceptions		: not available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VCEI exceptions		: not available&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ll emulations		: 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sc emulations		: 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat &#x2F;proc&#x2F;version&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Linux version 2.4.18-MIPS-01.00 (root@netcore) (gcc version 3.4.6-1.3.6) #1 Tue Jun 30 16:56:20 CST 2015&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# busybox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BusyBox v1.00-pre8 (2015.01.23-06:46+0000) multi-call binary&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Usage: busybox [function] [arguments]...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   or: [function] [arguments]...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	BusyBox is a multi-call binary that combines many common Unix&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	utilities into a single executable.  Most people will create a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	link to busybox for each function they wish to use, and BusyBox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	will act like whatever it was invoked as.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Currently defined functions:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	[, adduser, arping, bunzip2, busybox, bzcat, cat, chmod, cp, cut,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	date, df, echo, egrep, expr, false, ftpget, grep, head, ifconfig,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	init, kill, killall, klogd, ln, logger, login, ls, mkdir, mknod,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	mount, msh, passwd, ping, ps, reboot, rm, route, sh, sleep, syslogd,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	tail, test, tftp, traceroute, true, umount, vconfig, wc, wget&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Quite an ancient software stack. Isn&#x27;t it?&lt;&#x2F;p&gt;
&lt;p&gt;Now that I have grabbed some basic information about the system it&#x27;s time to
move on and see what&#x27;s inside the flash chip.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;dumping-the-flash-contents&quot;&gt;Dumping The Flash Contents&lt;&#x2F;h2&gt;
&lt;p&gt;I had already identified the chip by visual inspection while opening the router:
it is a Winbond W25Q32FV chip. Time to download its datasheet [[5]][5] to get
the pinout and connect it to my beloved Bus Pirate [[6]][6]. The Bus Pirate
is a small and useful board to talk to and interact with digital stuff. Out of
the box it supports the following interfaces: 1-Wire, 2-Wire, 3-Wire, I2C, SPI,
JTAG, UART and LCD. Alternatively, the GPIO pins can be directly controlled and
many more protocols can be added using aftermarket firmware images since it is
all open source.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;flash_pinout.gif&quot;&gt;
	&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;flash_pinout.gif&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;Winbond W25Q32FV flash chip pinout.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Now that I know the pinout of the chip, I have to figure out how to connect it
for &lt;strong&gt;flashrom&lt;&#x2F;strong&gt; [[7]][7] to read it. I&#x27;ll try In-System Programming
(ISP) [[8]][8] first since it is much quicker and does not require reworking
the board every time I have to read or write the flash contents. If this won&#x27;t
work the only solution is to desolder and resolder the flash chip from the board
every time. This is time consuming and I&#x27;d like to avoid it at all cost.&lt;&#x2F;p&gt;
&lt;p&gt;By means of a quick reverse engineering of the traces around the chip, I found
out that pin 3 and pin 7 (&lt;strong&gt;&#x2F;WP&lt;&#x2F;strong&gt; and &lt;strong&gt;&#x2F;HOLD&lt;&#x2F;strong&gt; respectively) which, according
to [[7]][7] should be connected to 3.3V on the bus pirate, are already tied to
the VCC pin (pin 8). Therefore, only 6 out of the 8 required wires have to be
connected.&lt;&#x2F;p&gt;
&lt;p&gt;After twenty minutes spent with my trusty soldering iron and a piece of an old
ATA cable (the 80-wire version which uses smaller conductors) and I have
created a nice little connector ready to be plugged into the Bus Pirate socket.&lt;&#x2F;p&gt;
&lt;figure&gt;
&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;flash_buspirate.jpg&quot;&gt;
	&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;flash_buspirate.jpg&quot;&#x2F;&gt;
&lt;&#x2F;a&gt;
&lt;figcaption&gt;Bus Pirate ISP connection to the flash chip.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;To check for a successful connection I issued the following command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo flashrom -p buspirate_spi:dev=&#x2F;dev&#x2F;ttyUSB0,spispeed=2M&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[sudo] password for pol: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flashrom v1.2 on Linux 5.7.0-2-amd64 (x86_64)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flashrom is free software, get the source code at https:&#x2F;&#x2F;flashrom.org&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found Winbond flash chip &amp;quot;W25Q32.V&amp;quot; (4096 kB, SPI) on buspirate_spi.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;No operations were specified.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Hurray! The flash chip was recognized correctly. Time to dump its contents.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo flashrom -p buspirate_spi:dev=&#x2F;dev&#x2F;ttyUSB0,spispeed=2M -r firmware_orig.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To see what&#x27;s inside the image named &lt;strong&gt;firmware_orig.bin&lt;&#x2F;strong&gt; I extracted it
recursively with the following command. At the end of the process binwalk
creates a folder named &lt;strong&gt;_firmware_orig.bin.extracted&lt;&#x2F;strong&gt; containing the
files extracted from the various file systems it found.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ binwalk -e firmware_orig.bin &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DECIMAL       HEXADECIMAL     DESCRIPTION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--------------------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4976          0x1370          LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 68320 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;207888        0x32C10         LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2338816 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING: Extractor.execute failed to run external extractor &amp;#39;sasquatch -p 1 -le -d &amp;#39;squashfs-root&amp;#39; &amp;#39;%e&amp;#39;&amp;#39;: [Errno 2] No such file or directory: &amp;#39;sasquatch&amp;#39;, &amp;#39;sasquatch -p 1 -le -d &amp;#39;squashfs-root&amp;#39; &amp;#39;%e&amp;#39;&amp;#39; might not be installed correctly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;WARNING: Extractor.execute failed to run external extractor &amp;#39;sasquatch -p 1 -be -d &amp;#39;squashfs-root&amp;#39; &amp;#39;%e&amp;#39;&amp;#39;: [Errno 2] No such file or directory: &amp;#39;sasquatch&amp;#39;, &amp;#39;sasquatch -p 1 -be -d &amp;#39;squashfs-root&amp;#39; &amp;#39;%e&amp;#39;&amp;#39; might not be installed correctly&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;851968        0xD0000         Squashfs filesystem, big endian, version 2.0, size: 2076096 bytes, 389 inodes, blocksize: 65536 bytes, created: 2015-06-30 08:57:47&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or that was the expectation. What are those warnings and why is my folder
&lt;strong&gt;squashfs-root&lt;&#x2F;strong&gt; empty?  Apparently sasquatch is not installed in my
system and&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo apt search sasquatch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;does not return any result. Alright it&#x27;s not the first time I have to compile
and install something from source on my system. It&#x27;s strange however that the
Debian repos are missing this useful piece of software. Perhaps I could
volunteer as its maintainer? Not today. I have a router to hack now. Sasquatch
is downloaded from [[9]][9] and &lt;strong&gt;build.sh&lt;&#x2F;strong&gt; does all the requisite stuff for
building and installing.&lt;&#x2F;p&gt;
&lt;p&gt;As usual, the process is never as easy as running a single command. The build
failed with a ton of messages like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;usr&#x2F;bin&#x2F;ld: unsquashfs_xattr.o:&#x2F;tmp&#x2F;article&#x2F;sasquatch&#x2F;squashfs4.3&#x2F;squashfs-tools&#x2F;error.h:34: multiple definition of `verbose&amp;#39;; unsquashfs.o:&#x2F;tmp&#x2F;article&#x2F;sasquatch&#x2F;squashfs4.3&#x2F;squashfs-tools&#x2F;error.h:34: first defined here&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;collect2: error: ld returned 1 exit status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make: *** [Makefile:298: sasquatch] Error 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By looking at the issues and pull requests of sasquatch I found
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;devttys0&#x2F;sasquatch&#x2F;pull&#x2F;34&quot;&gt;pull request #34&lt;&#x2F;a&gt; which should
fix the issue. After applying it to my local copy of the code the compilation
is successful. I&#x27;m now ready to go ahead with the extraction.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ binwalk -eM firmware_orig.bin &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Scan Time:     2020-08-21 10:55:58&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Target File:   &#x2F;tmp&#x2F;article&#x2F;firmware_orig.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MD5 Checksum:  f03a657d0fd666ef7b281b178160aa6f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signatures:    391&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DECIMAL       HEXADECIMAL     DESCRIPTION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--------------------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;4976          0x1370          LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 68320 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;207888        0x32C10         LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2338816 bytes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;851968        0xD0000         Squashfs filesystem, big endian, version 2.0, size: 2076096 bytes, 389 inodes, blocksize: 65536 bytes, created: 2015-06-30 08:57:47&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Scan Time:     2020-08-21 10:55:59&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Target File:   &#x2F;tmp&#x2F;article&#x2F;_firmware_orig.bin.extracted&#x2F;1370&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MD5 Checksum:  b11f1fa953d791774f180b80c290370e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signatures:    391&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DECIMAL       HEXADECIMAL     DESCRIPTION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--------------------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Scan Time:     2020-08-21 10:55:59&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Target File:   &#x2F;tmp&#x2F;article&#x2F;_firmware_orig.bin.extracted&#x2F;32C10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MD5 Checksum:  db44ecba377a764a82135b385d6711cd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Signatures:    391&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DECIMAL       HEXADECIMAL     DESCRIPTION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--------------------------------------------------------------------------------&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;674704        0xA4B90         Certificate in DER format (x509 v3), header length: 4, sequence length: 31&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1517048       0x1725F8        Certificate in DER format (x509 v3), header length: 4, sequence length: 130&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1939552       0x1D9860        Linux kernel version 2.4.18&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;1947112       0x1DB5E8        Unix path: &#x2F;usr&#x2F;lib&#x2F;libc.so.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Great. The image contains some LZMA compressed data, probably kernel and
bootloader, and a squashfs file system [[10]][10]. This time binwalk
recursively extracted those files and what I got was in fact a kernel (version
2.4.18 of course), some certificates and the contents of the root file system. I
was now able to inspect and modify the image contents as I please. The expert
reader (or my future self if he learned something from this endeavour) may
already have noticed the first mistake here. If nothing above looks wrong fasten
your seat belt we&#x27;re going deep down a rabbit hole.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rebuilding-the-flash-image-and-first-roadblocks&quot;&gt;Rebuilding the Flash Image and First Roadblocks&lt;&#x2F;h2&gt;
&lt;p&gt;This is the root folder structure of the extracted image:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ls -l _firmware_orig.bin.extracted&#x2F;squashfs-root&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 pol pol 3580 Jun 30  2015 bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwx 2 pol pol   60 Jun 30  2015 dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwx 3 pol pol  600 Jun 30  2015 etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 pol pol  320 Jun 30  2015 lib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 pol pol   10 Sep 11 12:39 media -&amp;gt; &#x2F;var&#x2F;media&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwx 2 pol pol   40 Jun 30  2015 proc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 pol pol  180 Jun 30  2015 sbin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 pol pol    8 Sep 11 12:39 sys -&amp;gt; &#x2F;var&#x2F;sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lrwxrwxrwx 1 pol pol    8 Sep 11 12:39 tmp -&amp;gt; &#x2F;var&#x2F;tmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 4 pol pol   80 Jun 30  2015 usr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwx 2 pol pol   40 Jun 30  2015 var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 8 pol pol  300 Jun 30  2015 web&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To test if the image extraction and rebuild processes work correctly, the
easiest thing to do is modify the &lt;strong&gt;index.htm&lt;&#x2F;strong&gt; file of the router configuration
webpage and add some test code to it. I copied the directory
&lt;strong&gt;firmware_orig.bin.extracted&lt;&#x2F;strong&gt; and its contents to
&lt;strong&gt;firmware.extracted_new&lt;&#x2F;strong&gt; in order to preserve the original files. Then I
modified &lt;strong&gt;firmware.extracted_new&#x2F;squashfs-root&#x2F;web&#x2F;index.htm&lt;&#x2F;strong&gt; by
appending the following lines just before the closing html tag.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;script&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	alert(&amp;quot;I have been pwned!&amp;quot;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;script&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should display an alert window as soon as the page is loaded.&lt;&#x2F;p&gt;
&lt;p&gt;Save and close (:wq) and that&#x27;s it. Now it&#x27;s time to rebuild the image and see
if it boots. But before attempting to re-create it, I needed more details about
the file system structure.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ unsquashfs -s D0000.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading a different endian SQUASHFS filesystem on D0000.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found a valid big endian SQUASHFS 2:0 superblock on D0000.squashfs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creation or last append time Tue Jun 30 10:57:47 2015&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem size 2076096 bytes (2027.44 Kbytes &#x2F; 1.98 Mbytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Block size 65536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem is not exportable via NFS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inodes are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Data is compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fragments are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Always-use-fragments option is not specified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Check data is not present in the filesystem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Duplicates are removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of fragments 27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of inodes 389 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;umber of uids 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of gids 0	&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-lazy-way-failed&quot;&gt;The Lazy Way (Failed)&lt;&#x2F;h3&gt;
&lt;p&gt;The first root file system creation attempt I did was using the version of
squashfs-tools provided by the Debian packages (version 4.4 at the time of
writing).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ mksquashfs squashfs-root D0000.new.squashfs -b 65536 -all-root -noappend&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ unsquashfs -s D0000.new.squashfs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found a valid SQUASHFS 4:0 superblock on D0000.new.squashfs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creation or last append time [... redacted ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem size 2788625 bytes (2723.27 Kbytes &#x2F; 2.66 Mbytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Compression gzip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Block size 65536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem is exportable via NFS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inodes are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Data is compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Uids&#x2F;Gids (Id table) are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fragments are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Always-use-fragments option is not specified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Xattrs are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Duplicates are removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of fragments 26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of inodes 366&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of ids 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Apart from the different superblock version, we have that the file system size
is bigger, the endianness is gone and the number of inodes is lower than the
original image. What is going on? I decided to tackle one issue at a time.&lt;&#x2F;p&gt;
&lt;p&gt;First of all is the squashfs file system backwards-compatible? Apparently,
SquashFS v4.0 moved to a fixed little-endian format (even for big-endian
systems). Given the differences, the odds of the new image booting are already
quite low. For the sake of science I decided to test the new image anyway.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cp ..&#x2F;firmware_orig.bin firmware_pwned.bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ dd if=D0000.new.squashfs of=firmware_pwned.bin bs=1 seek=$((0xD0000)) conv=notrunc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo flashrom -p buspirate_spi:dev=&#x2F;dev&#x2F;ttyUSB0,spispeed=2M -w firmware.extracted_new&#x2F;firmware_pwned.bin &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And sure enough when I turned on the router, carefully monitoring the serial
output, the device was unable to mount the root file system and it was stuck in
a bootloop.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-hard-way&quot;&gt;The Hard Way&lt;&#x2F;h3&gt;
&lt;p&gt;Of course it could not be so easy. I needed an older version of squashfs,
supporting setting a different endianness. Is there a different&#x2F;lower version of
squashfs-tools in the Debian repos? Of course not. I had to compile it my own.
Who cares I&#x27;m already used to that. The first thing I did was to download the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sourceforge.net&#x2F;projects&#x2F;squashfs&#x2F;files&#x2F;squashfs&#x2F;squashfs2.2-r2&#x2F;&quot;&gt;squashfs sources for version 2.2-r2&lt;&#x2F;a&gt;.
And once again the stock sources cannot be compiled with gcc 10. I learned,
after trial and error, that this is due to different gcc behaviour and
due to some symbols moved to different header files. To get this squashfs-tools
version compile on my system I had to apply the following changes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ diff -u squashfs2.2-r2&#x2F;squashfs-tools squashfs-tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- squashfs2.2-r2&#x2F;squashfs-tools&#x2F;Makefile	2005-09-01 01:21:14.000000000 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+++ squashfs-tools&#x2F;Makefile	2020-08-17 14:39:16.792112129 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -1,6 +1,7 @@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; INCLUDEDIR = .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -g&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -g -O2 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+	-fcommon -std=gnu89&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; mksquashfs: mksquashfs.o read_fs.o sort.o&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	$(CC) mksquashfs.o read_fs.o sort.o -lz -o $@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- squashfs2.2-r2&#x2F;squashfs-tools&#x2F;mksquashfs.c	2005-09-09 00:34:28.000000000 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+++ squashfs-tools&#x2F;mksquashfs.c	2020-08-17 14:42:08.037022333 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -28,6 +28,7 @@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;unistd.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;sys&#x2F;types.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+#include &amp;lt;sys&#x2F;sysmacros.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;sys&#x2F;stat.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;fcntl.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;errno.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Figuring out why the code was not building and what to do to make gcc accept it
took me quite a while. However, now that I have a working copy of mksquashfs
version 2, I tried again to rebuild the file system:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ squashfs&#x2F;squashfs2.2-r2&#x2F;squashfs-tools&#x2F;mksquashfs squashfs-root D0000.new.squashfs -b 65536 -all-root -noappend -2.0 -be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ unsquashfs -s D0000.new.squashfs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading a different endian SQUASHFS filesystem on D0000.new.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Found a valid big endian SQUASHFS 2:0 superblock on D0000.new.squashfs.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Creation or last append time Wed Sep 23 14:15:42 2020&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem size 2785979 bytes (2720.68 Kbytes &#x2F; 2.66 Mbytes)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Block size 65536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem is not exportable via NFS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Inodes are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Data is compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Fragments are compressed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Always-use-fragments option is not specified&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Check data is not present in the filesystem&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Duplicates are removed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of fragments 26&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of inodes 366&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of uids 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number of gids 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The issue about endianness and superblock version were solved. There was still a
different number of inodes and a bigger file system size. But hey, who cares
right? I flashed it into the router right-away, repeating the steps in the
previous section, but the device is still stuck in a boot loop.&lt;&#x2F;p&gt;
&lt;p&gt;What are those missing inodes anyway? I thought that maybe extracting the
SquashFS file system manually will yield more information.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ unsquashfs D0000.squashfs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading a different endian SQUASHFS filesystem on D0000.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read_ids: Bad inode count in super block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;File system corruption detected&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FATAL ERROR:failed to read file system tables&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now I&#x27;m getting why binwalk was using sasquatch to extract the root file system
image. Let&#x27;s do the same&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sasquatch D0000.squashfs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SquashFS version [512.0] &#x2F; inode count [-2063532032] suggests a SquashFS image of a different endianess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading a different endian SQUASHFS filesystem on D0000.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parallel unsquashfs: Using 1 processor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress using default gzip decompressor...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress with lzma...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress with lzma-adaptive...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Detected lzma-adaptive compression&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;369 inodes (439 blocks) to write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;create_inode: could not create character device squashfs-root&#x2F;dev&#x2F;ptyp0, because you&amp;#39;re not superuser!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[... lots of lines as the one above ...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 237 files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 20 directories&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 109 symlinks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 0 devices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 0 fifos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This was one of those moments when you realize you were barking up the wrong
tree all the time. Facepalm. The missing inodes are the character devices
[[11]][11]. Of course nothing will boot! Upon extraction, binwalk did not
have the required permissions to create such files. I have to extract the file
system as root to get the whole contents of the image:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ sudo sasquatch D0000.squashfs &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[sudo] password for pol: &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SquashFS version [512.0] &#x2F; inode count [-2063532032] suggests a SquashFS image of a different endianess&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Reading a different endian SQUASHFS filesystem on D0000.squashfs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parallel unsquashfs: Using 1 processor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress using default gzip decompressor...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress with lzma...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Trying to decompress with lzma-adaptive...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Detected lzma-adaptive compression&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;369 inodes (439 blocks) to write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[===============================================================|] 439&#x2F;439 100%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 237 files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 20 directories&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 109 symlinks&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 23 devices&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;created 0 fifos&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now we are talking! Well... not really. I rebuilt the file system once again
as I did before, the only difference now is file system size. However, the
router is still stuck in a bootloop. A quick check confirmed that the size of
the final flash image fits in the flash chip, so the file system size was not
the issue. It was a symptom of the issue instead: what was still missing was
the correct compression algorithm for mksquashfs. The version 2.2 of mksquashfs
does not support lzma compression by default. A working copy of squashfs-lzma
[[12]][12] was needed. I was fed up of blindly trying stuff until something
works, so I downloaded the GPL code [[13]][13] (thanks Richard Stallman) for
my router model and started inspecting the package contents to find some clues
about how the flash image is built.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gpl-code-is-fun&quot;&gt;GPL Code is Fun&lt;&#x2F;h3&gt;
&lt;p&gt;Inside the package I found the directory
&lt;strong&gt;GPL_Code_RTL&#x2F;rtl819x-sdk-v1.2&#x2F;AP&#x2F;squashfs-tools&lt;&#x2F;strong&gt; containing some sources
for mksquashfs. After copying it somewhere else to preserve the original files,
I had to patch the code inside the new directory in a similar fashion as
SquashFS 2.2-r2.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ diff -ru squashfs-tools-orig squashfs-tools&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- squashfs-tools-orig&#x2F;Makefile	2013-11-10 14:56:41.000000000 +0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+++ squashfs-tools&#x2F;Makefile	2020-08-17 15:37:34.758142333 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -1,7 +1,8 @@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; INCLUDEDIR = .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; LZMAPATH = .&#x2F;lzma&#x2F;SRC&#x2F;7zip&#x2F;Compress&#x2F;LZMA_Lib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -O2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -O2 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+	-fcommon -std=gnu89&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- squashfs-tools-orig&#x2F;mksquashfs.c	2013-11-10 14:56:41.000000000 +0100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+++ squashfs-tools&#x2F;mksquashfs.c	2020-08-17 15:38:32.368332562 +0200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -27,6 +27,7 @@&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;unistd.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;sys&#x2F;types.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+#include &amp;lt;sys&#x2F;sysmacros.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;sys&#x2F;stat.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;fcntl.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; #include &amp;lt;errno.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that, I compiled the sources with &lt;tt&gt;make&lt;&#x2F;tt&gt; and I got a fancy new
executable to play with: &lt;strong&gt;mksquashfs-lzma&lt;&#x2F;strong&gt;. It can be used to build the new
file system as usual.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ squashfs&#x2F;squashfs-tools&#x2F;mksquashfs-lzma squashfs-root D0000.new.squashfs -b 65536 -all-root -noappend -be&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After flashing the new image, this time the router booted successfully. I
pointed my browser to the configuration page (available at
&lt;strong&gt;http:&#x2F;&#x2F;192.168.1.1&lt;&#x2F;strong&gt; by default) and logged in with the default credentials.
The following webpage appeared.&lt;&#x2F;p&gt;
&lt;figure&gt;
	&lt;a href=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;pwned_success.png&quot;&gt;
		&lt;img src=&quot;&#x2F;img&#x2F;articles&#x2F;wf2419_hacking&#x2F;pwned_success.png&quot;&#x2F;&gt;
	&lt;&#x2F;a&gt;
	&lt;figcaption&gt;Success! A pwned index.htm appears.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Hurray! This meant that I could do whatever I wanted with the root file system!
To avoid manually entering a series of commands every time I want to build a
new image, I created a small script available on GitHub [[14]][14].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;compiling-software-and-more-roadblocks&quot;&gt;Compiling Software and More Roadblocks&lt;&#x2F;h2&gt;
&lt;p&gt;This page is getting long already. Let&#x27;s recap the ultimate goal: compile a
custom kernel for the device. To do so, I need a working compiler for the
architecture. This process is streamlined by buildroot: &lt;em&gt;a set of Makefiles and
patches that simplifies and automates the process of building a complete and
bootable Linux environment for an embedded system&lt;&#x2F;em&gt; [[15]][15]. Buildroot
downloads and builds the toolchain and utilities it needs for compiling software
for the target architecture, applies custom patches to the sources, compiles the
software and assembles the final bootable image.&lt;&#x2F;p&gt;
&lt;p&gt;To test the compiler is working, I decided to build a new version of busybox
with some added functionality using buildroot. So, the first thing I did was to
clone the latest stable buildroot release (2020.08.1 at the time of writing)
with&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git clone git:&#x2F;&#x2F;git.buildroot.net&#x2F;buildroot $ cd buildroot $ git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;checkout 2020.08.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, I tried to build a statically-linked busybox executable with some nice
additions to the stock one on the router (such as telnet) using
&lt;strong&gt;MIPS (big endian)&lt;&#x2F;strong&gt; as the target architecture and the stock
&lt;strong&gt;Generic MIPS32&lt;&#x2F;strong&gt; target architecture variant for buildroot. The command I
used are the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make menuconfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;* &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Select the desided architecture and build options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Especially:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Target options -&amp;gt; Target Architecture -&amp;gt; MIPS (big endian)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	               -&amp;gt; Target Architecture Variant -&amp;gt; Generic MIPS32&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Build options -&amp;gt; libraries -&amp;gt; static only&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make busybox-menuconfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;* &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   Enable telnetd and disable all the stuff we don&amp;#39;t need to make the&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   busybox executable small&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;* have a coffe break *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After a few minutes, I found the compiled busybox executable in
&lt;strong&gt;buildroot&#x2F;output&#x2F;target&#x2F;bin&lt;&#x2F;strong&gt;. I copied it as &lt;strong&gt;busybox_p&lt;&#x2F;strong&gt; (to
avoid confusion with the original executable) to the extracted firmware image
and created a symlink to it named &lt;strong&gt;telnetd&lt;&#x2F;strong&gt;. I rebuilt the image as I did
many times, flashed it and let the router boot. Sadly this was the result when
running the new executable from the serial terminal.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# busybox_p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Illegal instruction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# telnetd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Illegal instruction&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Why can&#x27;t this stuff just work? Maybe the endianness of the executable is wrong,
all in all I just guessed it. In the extracted firmware image directory on my PC
I ran:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ file busybox&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;busybox: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter &#x2F;lib&#x2F;ld-uClibc.so.0, stripped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ file busybox_p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;busybox_p: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, stripped&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So the endianness was indeed correct. However, according to the chipset
datasheet [[4]][4] and some other web resources, the illegal
instruction the device was encountering may be due to the core which is a
RLX4181 Lexra architecture [[16]][16], a variant of the MIPS32
architecture lacking the &lt;strong&gt;lwl, lwr, swl&lt;&#x2F;strong&gt; and &lt;strong&gt;swr&lt;&#x2F;strong&gt; instructions, covered by
an US patent.&lt;&#x2F;p&gt;
&lt;p&gt;Time to dig into the search engine once again. The following links seemed to
point to some useful code:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;hackpascal&#x2F;c07dd5e3745f90b45e5ed6c1e86fde41&quot;&gt;hackpascal&#x2F;0001-binutils-2.24-add-lexra-support.patch&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;forum.openwrt.org&#x2F;t&#x2F;working-realtek-soc-rtl8196e-97d-97f-in-last-master&#x2F;70975&quot;&gt;Working Realtek SoC RTL8196E 97D 97F in last master - For Developers - OpenWrt Forum&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rlx-router&#x2F;openwrt-rtl8196c&quot;&gt;rlx-router&#x2F;openwrt-rtl8196c&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rlx-router&#x2F;linux-rlx-upstream&quot;&gt;rlx-router&#x2F;linux-rlx-upstream&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;shibajee&#x2F;buildroot-rlx4181&quot;&gt;shibajee&#x2F;buildroot-rlx4181&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The last link contains a complete buildroot repository allegedly supporting the
RLX4181 architecture. I added it to my buildroot folder, cleaned it and rebuilt
it once again:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git remote add https:&#x2F;&#x2F;notabug.org&#x2F;shibajee&#x2F;buildroot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git remote add -f rlx4181-notabug https:&#x2F;&#x2F;notabug.org&#x2F;shibajee&#x2F;buildroot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;git checkout rlx4181-master&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make clean&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make menuconfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&#x2F;* Select the correct architecture and build options *&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make -j4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After a while the executable files were ready. I ran &lt;strong&gt;objdump -D&lt;&#x2F;strong&gt; on the
output executables, grepping for the instructions which are not accepted
by the processor. Those commands did not turn any result.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;objdump -D root&#x2F;bin&#x2F;busybox_p | grep lwl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;objdump -D root&#x2F;bin&#x2F;busybox_p | grep lwr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;objdump -D root&#x2F;bin&#x2F;busybox_p | grep swl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;objdump -D root&#x2F;bin&#x2F;busybox_p | grep swr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now I was really confident that this time everything will have worked as
expected so I rebuilt the flash image and flashed onto the chip. Sadly I was
greeted again by the darn &lt;strong&gt;Illegal instruction&lt;&#x2F;strong&gt; message.&lt;&#x2F;p&gt;
&lt;p&gt;I was starting to suspect that the error was due to the wrong kernel headers
version. The actual kernel header files for the Linux version running on the
device are available in the GPL code package. So, within my buildroot folder, I
issued:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;make uclibc-menuconfig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To edit the uclibc .config file and set a different directory to fetch the
kernel headers.&lt;&#x2F;p&gt;
&lt;p&gt;Pointing uclibc to the original (and quite old) kernel headers did not work
either. This time I was unable successfully compile buildroot because I got a
bunch of undeclared identifiers in many libraries. This is probably due to the
kernel headers lacking the symbols required by the new software I was trying to
compile.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Eventually this has been too much for me. I&#x27;m calling it quits here. Porting
newer software to the older kernel headers to fix the compilation errors is a
tedious job. Another option could be to port a newer kernel to the device, but
all the kernel sources available on github seem to compile successfully but do
not boot properly.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, I could try to use an older buildroot version. I have no idea if
there is any buildroot version compatible with the Linux kernel version 2.4.
This can be easily fixed by searching within the git repository. However, I will
have to manually port the binutils patches to correctly compile software for
this unorthodox MIPS architecture. And this again is tedious.&lt;&#x2F;p&gt;
&lt;p&gt;I think the effort required to go further with this project is becoming too much
and it is not worth it any more. Some progress has already been made by the
OpenWrt folks albeit on a different processor revision (see links in the
previous section) so I may reboot this project in the future.&lt;&#x2F;p&gt;
&lt;p&gt;All in all, I learned a lot already and no electronic devices were harmed in the
process. So, even though I hit only 3 out of the 5 objectives I set at the
start, I&#x27;m quite satisfied. It was still a valid learning experience. It&#x27;s time
to try to hack another router, maybe I will be luckier this time (stay tuned).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
\[1\] [Netis WF2419I][1]
[1]: http:&#x2F;&#x2F;www.netis-systems.com&#x2F;Suppory&#x2F;de_details&#x2F;id&#x2F;1&#x2F;de&#x2F;181.html
&lt;p&gt;[2] [Hacking Reolink Cameras For Fun and Profit][2]
[2]: https:&#x2F;&#x2F;www.thirtythreeforty.net&#x2F;posts&#x2F;2020&#x2F;05&#x2F;hacking-reolink-cameras-for-fun-and-profit&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;[3] [FCC Equipment Authorization Procedures][3]
[3]: https:&#x2F;&#x2F;www.fcc.gov&#x2F;general&#x2F;equipment-authorization-procedures&lt;&#x2F;p&gt;
&lt;p&gt;[4] [RTL8196C Datasheet][4]
[4]: https:&#x2F;&#x2F;lost-contact.mit.edu&#x2F;afs&#x2F;sur5r.net&#x2F;service&#x2F;drivers+doc&#x2F;Realtek&#x2F;RTL8196C%20Datasheet.pdf&lt;&#x2F;p&gt;
&lt;p&gt;[5] [W25Q32FV Datasheet][5]
[5]: https:&#x2F;&#x2F;www.winbond.com&#x2F;resource-files&#x2F;w25q32fv%20revi%2010202015.pdf&lt;&#x2F;p&gt;
&lt;p&gt;[6] [Bus Pirate - Dangerous Prototypes][6]
[6]: http:&#x2F;&#x2F;dangerousprototypes.com&#x2F;docs&#x2F;Bus_Pirate&lt;&#x2F;p&gt;
&lt;p&gt;[7] [Bus Pirate - flashrom][7]
[7]: https:&#x2F;&#x2F;www.flashrom.org&#x2F;Bus_Pirate&lt;&#x2F;p&gt;
&lt;p&gt;[8] [ISP - flashrom][8]
[8]: https:&#x2F;&#x2F;www.flashrom.org&#x2F;ISP&lt;&#x2F;p&gt;
&lt;p&gt;[9] [GitHub - devttys0&#x2F;sasquatch][9]
[9]: https:&#x2F;&#x2F;github.com&#x2F;devttys0&#x2F;sasquatch&lt;&#x2F;p&gt;
&lt;p&gt;[10] [SquashFS - Wikipedia][10]
[10]: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;SquashFS&lt;&#x2F;p&gt;
&lt;p&gt;[11] [Device file][11]
[11]: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Device_file&lt;&#x2F;p&gt;
&lt;p&gt;[12] [Official Squashfs LZMA][12]
[12]: https:&#x2F;&#x2F;squashfs-lzma.org&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;[13] [Netis GPL Code][13]
[13]: http:&#x2F;&#x2F;www.netis-systems.com&#x2F;Suppory&#x2F;gpl.html&lt;&#x2F;p&gt;
&lt;p&gt;[14] [mkimg.sh on GitHub][14]
[14]: https:&#x2F;&#x2F;github.com&#x2F;electricant&#x2F;netis-wf2419-router-hacking&#x2F;blob&#x2F;master&#x2F;firmware.extracted_new&#x2F;mkimg.sh&lt;&#x2F;p&gt;
&lt;p&gt;[15] [Buildroot - Wikipedia][15]
[15]: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Buildroot&lt;&#x2F;p&gt;
&lt;p&gt;[16] [Lexra - LinuxMIPS][16]
[16]: https:&#x2F;&#x2F;www.linux-mips.org&#x2F;wiki&#x2F;Lexra&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Internet Radio List</title>
        <published>2020-04-01T00:00:00+00:00</published>
        <updated>2020-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/web-radio/"/>
        <id>/articles/web-radio/</id>
        
        <content type="html" xml:base="/articles/web-radio/">&lt;p&gt;Direct streaming links to web radios I like to listen to. A valid source of web radios is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.radio-browser.info&#x2F;&quot;&gt;RadioBrowser&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Last updated on: 16 July 2022.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;radio-bob&quot;&gt;Radio Bob&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.radiobob.si&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;live.radio.si&#x2F;BOB&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;groove-salad&quot;&gt;Groove Salad&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;somafm.com&#x2F;groovesalad&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;somafm.com&#x2F;m3u&#x2F;groovesalad130.m3u&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;radio-nula&quot;&gt;Radio Nula&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;radionula.com&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;strm.radionula.com&#x2F;classics&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;crucial-velocity-radio&quot;&gt;Crucial Velocity Radio&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.crucialvelocity.ca&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;ais-sa2.cdnstream1.com&#x2F;1369_128&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rock-radio-slovenija&quot;&gt;Rock Radio Slovenija&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;rockradio.si&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stream.rockradio.si:9034&#x2F;;stream&#x2F;1&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;radio-marilu&quot;&gt;Radio Marilù&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.marilu.it&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wma01.fluidstream.net&#x2F;marilu&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;radio-24&quot;&gt;Radio 24&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.radio24.ilsole24ore.com&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;shoutcast.radio24.it:8000&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rai-radio-classica&quot;&gt;RAI Radio Classica&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.raiplayradio.it&#x2F;radio3classica&#x2F;&quot;&gt;homepage&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;icestreaming.rai.it&#x2F;5.mp3&quot;&gt;streaming URL&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux VMs with qemu</title>
        <published>2017-04-01T00:00:00+00:00</published>
        <updated>2017-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/qemu-linux/"/>
        <id>/articles/qemu-linux/</id>
        
        <content type="html" xml:base="/articles/qemu-linux/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes I have to test various network configurations involving linux
machines.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes I use my own PC and some other device such as a Raspberry pi this has
the advantage that each device physically exists and can be poked at.
The main drawback is that the setup is cumbersome and time consuming and there&#x27;s
the risk of screwing something up with the configuration of my main laptop.&lt;&#x2F;p&gt;
&lt;p&gt;The ideal would be to have a bunch of virtual machines connected together
through some network interfaces, each one doing its thing independently.
The VMs have also connected to the internet in order to download the required
packages and updates.&lt;&#x2F;p&gt;
&lt;p&gt;As an added bonus the test setup should be repeatable and has to be launched
easily from the command line.&lt;&#x2F;p&gt;
&lt;p&gt;This page contains some notes on how I accomplished such thing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;guest-os-installation&quot;&gt;Guest OS installation&lt;&#x2F;h2&gt;
&lt;p&gt;I won&#x27;t go into the details of installing a linux guest OS in qemu as there&#x27;s
plenty of guides on the internet [[1]][1].&lt;&#x2F;p&gt;
&lt;h2 id=&quot;startup-script&quot;&gt;Startup Script&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s get straight into it. This is the setup I use for launching a server with
three clients. Each machine is connected to the internet and to each other
through a virtual layer 2 switch [[2]][2]. Please note that this script
requires root privileges to be effective.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Amount of RAM each VM is given&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RAM_SIZE_MB=512&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Additional qemu options&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;QEMU_OPTIONS=&amp;quot;-enable-kvm -vga std&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# interface names&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;TAP_SERVER=tapSrv0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;TAP1=tap1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;TAP2=tap2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BRIDGE=brVrt0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Preliminary network interface setup (requires root privieges)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap add $TAP_SERVER mode tap user `whoami`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP_SERVER up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap add $TAP1 mode tap user `whoami`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP1 up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap add $TAP2 mode tap user `whoami`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP2 up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link add $BRIDGE type bridge&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $BRIDGE up&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP_SERVER master $BRIDGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP1 master $BRIDGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link set $TAP2 master $BRIDGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Start the testbench&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-system-i386 $QEMU_OPTIONS -m $RAM_SIZE_MB \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev tap,id=vlan0,ifname=$TAP_SERVER \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-device e1000,netdev=vlan0,mac=52:54:00:00:00:01 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev user,id=user0 -device e1000,netdev=user0 -hda server.cow &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-system-i386 $QEMU_OPTIONS -m $RAM_SIZE_MB \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev tap,id=vlan0,ifname=$TAP1 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-device e1000,netdev=vlan0,mac=52:54:00:00:00:02 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev user,id=user0 -device e1000,netdev=user0 -hda client1.cow &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;qemu-system-i386 $QEMU_OPTIONS -m $RAM_SIZE_MB \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev tap,id=vlan0,ifname=$TAP2 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-device e1000,netdev=vlan0,mac=52:54:00:00:00:03 \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	-netdev user,id=user0 -device e1000,netdev=user0 -hda client2.cow &amp;amp;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Wait for background jobs to terminate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;wait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Interface teardown&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap del $TAP_SERVER mode tap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap del $TAP1 mode tap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip tuntap del $TAP2 mode tap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo ip link del $BRIDGE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The most difficult part was getting the interface setup right, both from the
host and guest perspective. There&#x27;s plenty of outdated and misleading guides
around the web.&lt;&#x2F;p&gt;
&lt;p&gt;The first thing to note is that qemu requires a device instance for each
declared netdev. To do so we have to add an id to each netdev
(&lt;tt&gt;-netdev id=netdev_id,netdev_type&lt;&#x2F;tt&gt;) and then attach a device to it like
so &lt;tt&gt;-device hw_type,netdev=netdev_id&lt;&#x2F;tt&gt;. As it can be seen this is done
twice, the first time for the &lt;tt&gt;tap&lt;&#x2F;tt&gt; device and the second for an
&lt;tt&gt;user&lt;&#x2F;tt&gt; device. Refer to the guide about qemu networking [[3]][3] for
details about the role of each device.&lt;&#x2F;p&gt;
&lt;p&gt;Then in order to get the network topology we like we have to create and bridge
together the tap interfaces at the host side. This has to be done before
starting the various virtual machines. The commands have been taken from
[[4]][4] and adapted a bit to the situation.&lt;&#x2F;p&gt;
&lt;p&gt;Each virtual machine is started as a background job (note the &lt;tt&gt;&amp;amp;&lt;&#x2F;tt&gt; at the
end) so before tearing down the network we issue a &lt;tt&gt;wait&lt;&#x2F;tt&gt; command which
halts the script until all the jobs terminate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;div class=&quot;references&quot;&gt;
1. [QEMU - ArchWiki -][1]
[1]: https:&#x2F;&#x2F;wiki.archlinux.org&#x2F;index.php&#x2F;QEMU &quot;QEMU - ArchWiki -&quot;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;[LAN switching - Wikipedia -][2]
[2]: https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;LAN_switching &quot;LAN switching - Wikipedia -&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;[Documentation&#x2F;Networking - qemu project -][3]
[3]: http:&#x2F;&#x2F;wiki.qemu-project.org&#x2F;Documentation&#x2F;Networking &quot;Documentation&#x2F;Networking - qemu project -&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;[Networking - KVM -][4]
[4]: https:&#x2F;&#x2F;www.linux-kvm.org&#x2F;page&#x2F;Networking &quot;Networking - KVM -&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>LaTeX Templates</title>
        <published>2017-03-01T00:00:00+00:00</published>
        <updated>2017-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/latex-templates/"/>
        <id>/articles/latex-templates/</id>
        
        <content type="html" xml:base="/articles/latex-templates/">&lt;p&gt;I was recently looking for some instructions about templates for a presentation
written using the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Beamer_%28LaTeX%29&quot;&gt;Beamer&lt;&#x2F;a&gt;
document class in LaTeX.&lt;&#x2F;p&gt;
&lt;p&gt;The aim of this page is to collect some instructions and a few bits I learned
during the process. I also plan to keep this page updated with stuff about LaTeX
in general (hopefully).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;guides&quot;&gt;Guides&lt;&#x2F;h2&gt;
&lt;p&gt;First off some useful guides:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.hartwork.org&#x2F;beamer-theme-matrix&#x2F;&quot;&gt;Beamer Theme Matrix&lt;&#x2F;a&gt; &lt;br&gt;
For choosing a base theme and its variant.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;hamaluik.com&#x2F;posts&#x2F;better-beamer-themes&#x2F;&quot;&gt;Better Beamer Themes&lt;&#x2F;a&gt; &lt;br&gt;
For some basic instructions on creating a theme.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;boilerplate-code&quot;&gt;Boilerplate code&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;presentation&quot;&gt;Presentation&lt;&#x2F;h3&gt;
&lt;p&gt;Now some boilerplate code for a presentation:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\documentclass[a4paper]{beamer}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\usetheme{%%yourtheme}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\usepackage{mathtools}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\usepackage{lmodern}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\title{The Title}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\author{Author}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\date{\today}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{document}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%% title frame&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{frame}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	\maketitle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{frame}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{frame}{Another frame, with title}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	Content&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{frame}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;%% The last frame is the same as the first one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{frame}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	\maketitle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{frame}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{document}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;article&quot;&gt;Article&lt;&#x2F;h3&gt;
&lt;p&gt;Also some code for an article:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;&#x2F;strong&gt; This code requires the IEEEtran document class which can be downloaded
from &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ctan.org&#x2F;tex-archive&#x2F;macros&#x2F;latex&#x2F;contrib&#x2F;IEEEtran&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.
On debian-based GNU&#x2F;linux systems IEEEtran and some other useful packages can be
installed with: &lt;tt&gt;sudo apt-get install texlive-publishers&lt;&#x2F;tt&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\documentclass[journal, a4paper, 12pt]{IEEEtran}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\title{The title}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\author{The author}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\markboth{Journal of Something}{Author name and paper title}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{document}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\maketitle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{abstract}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	abstract&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{abstract}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\begin{IEEEkeywords}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	keyword1, keyword2, ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{IEEEkeywords}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;% Sections and subsections as usual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;\end{document}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Refer to &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.texdoc.net&#x2F;texmf-dist&#x2F;doc&#x2F;latex&#x2F;IEEEtran&#x2F;IEEEtran_HOWTO.pdf&quot;&gt;http:&#x2F;&#x2F;www.texdoc.net&#x2F;texmf-dist&#x2F;doc&#x2F;latex&#x2F;IEEEtran&#x2F;IEEEtran_HOWTO.pdf&lt;&#x2F;a&gt;
for more details.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;custom-university-of-padova-theme&quot;&gt;Custom University of Padova Theme&lt;&#x2F;h2&gt;
&lt;p&gt;During my PhD at the University of Padova (Department of Information
Engineering) I often need some theme for a presentation.&lt;&#x2F;p&gt;
&lt;p&gt;A good one can be found
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;andrea.burattin.net&#x2F;stuff&#x2F;tema-latex-beamer-padova&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.
I used this theme as a starting point to create my own variation, adding the
department logo and modifying the style a bit. Best results can be obtained using
the presentation template above. The theme assumes that the last frame is the
same as the first one.&lt;&#x2F;p&gt;
&lt;p&gt;Download the theme from
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;electricant&#x2F;beamerThemePadovaDEI&quot;&gt;my github repo&lt;&#x2F;a&gt; and
install it or put the files in the same directory as your presentation. Then use
it with &lt;tt&gt;\usetheme{PadovaDEI}&lt;&#x2F;tt&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Directory Alias in Bash</title>
        <published>2016-10-01T00:00:00+00:00</published>
        <updated>2016-10-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/cdable-vars/"/>
        <id>/articles/cdable-vars/</id>
        
        <content type="html" xml:base="/articles/cdable-vars/">&lt;p&gt;Frequently I work with long paths from the terminal and typing them is tiresome
and time-consuming. So I started to search for a solution to this problem.
I thought that if I could create an alias for the path I could just type
&lt;tt&gt;$cd path_alias&lt;&#x2F;tt&gt; instead of the tiring and error-prone
&lt;tt&gt;$cd &#x2F;a&#x2F;very&#x2F;long&#x2F;path&#x2F;to&#x2F;write&#x2F;&lt;&#x2F;tt&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After a trip to the usual search engine &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;17958567&#x2F;how-to-make-an-alias-for-a-long-path&quot;&gt;this is what I found&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The guy that asked the question was trying to make an alias for a path by
assigning it to a variable and then &lt;em&gt;cd-ing&lt;&#x2F;em&gt; to such variable, this way:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;myFold=&amp;quot;~&#x2F;Files&#x2F;Scripts&#x2F;Main&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd myFold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This fails because by default &lt;tt&gt;cd&lt;&#x2F;tt&gt; thinks that &lt;tt&gt;myFold&lt;&#x2F;tt&gt; is a
folder, not a variable to be expanded. The correct command to run is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd $myFold&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But what if we want to get rid of the annoying &lt;tt&gt;$&lt;&#x2F;tt&gt;?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enter-shell-options&quot;&gt;Enter Shell Options&lt;&#x2F;h2&gt;
&lt;p&gt;There is a &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;wiki.bash-hackers.org&#x2F;internals&#x2F;shell_options&quot;&gt;shell option&lt;&#x2F;a&gt;
called &lt;tt&gt;cdable_vars&lt;&#x2F;tt&gt;. When it is set &lt;em&gt;&quot;an argument to the cd builtin
command that is not a directory is assumed to be the name of a variable whose
value is the directory to change to&quot;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As a result to make an alias to your favourite directory and make it permanent
you could add the following lines to your &lt;tt&gt;.bashrc&lt;&#x2F;tt&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shopt -s cdable_vars # enable cdable_vars&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;export myFold=&amp;quot;&#x2F;a&#x2F;very&#x2F;long&#x2F;path&#x2F;to&#x2F;write&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After reloading your &lt;tt&gt;.bashrc&lt;&#x2F;tt&gt; either by closing and reopening the
terminal or by entering the command &lt;tt&gt;. ~&#x2F;.bashrc&lt;&#x2F;tt&gt;  no &lt;tt&gt;$&lt;&#x2F;tt&gt; is
required any more.&lt;&#x2F;p&gt;
&lt;p&gt;You can issue &lt;tt&gt;cd myFold&lt;&#x2F;tt&gt; and you will be redirected automagically to the
directory of choice.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;caveat&quot;&gt;Caveat&lt;&#x2F;h2&gt;
&lt;p&gt;The only caveat is that subdirectories within the alias do not work. For
example the following command will result in:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd myFold&#x2F;subfolder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bash: cd: myFold&#x2F;subfolder: No such file or directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Whereas &lt;tt&gt;cd $myFold&#x2F;subfolder&lt;&#x2F;tt&gt; works as expected.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Start PostgreSQL on Debian 8</title>
        <published>2016-06-01T00:00:00+00:00</published>
        <updated>2016-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/articles/postgresql-start-debian/"/>
        <id>/articles/postgresql-start-debian/</id>
        
        <content type="html" xml:base="/articles/postgresql-start-debian/">&lt;p&gt;I run a small NAS computer at home for network file sharing and RSS feed
fetching through
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tt-rss.org&#x2F;gitlab&#x2F;fox&#x2F;tt-rss&#x2F;wikis&#x2F;home&quot;&gt;Tiny Tiny RSS&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The hardware is a regular low-power computer running Debian 8. Overall this
setup is running fine, requiring moderate amount of maintenance.&lt;&#x2F;p&gt;
&lt;p&gt;Recently, after an update, PostgreSQL stopped working and I was unable to access
to my beloved RSS feeds. Apparently something was changed in the way Debian
starts Postgres via systemd. Now to start and or enable it the version you want
to run has to be specified.&lt;&#x2F;p&gt;
&lt;p&gt;For example the command to start the service is:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;systemctl start postgresql@9.4-main&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Whereas to enable it:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;systemctl enable postgresql@9.4-main&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If there is more than one version of the software installed that has to be run,
then such version has to be specified after the &lt;tt&gt;@&lt;&#x2F;tt&gt; symbol.&lt;&#x2F;p&gt;
&lt;p&gt;For more details see &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.postgresql.org&#x2F;message-id&#x2F;CAFyxdeSZh=Fv6nikh1_WqAtyKc0nmKTdTvj8-+JzYw-GobZnzw@mail.gmail.com&quot;&gt;this mailing-list entry&lt;&#x2F;a&gt;
which states the problem but does not give a complete solution.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
