Jekyll2018-11-01T20:03:20+00:00/Łukasz’s embedded developmentWrite an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.Update2018-11-01T20:00:00+00:002018-11-01T20:00:00+00:00/news/2018/11/01/update<p>Small update on the page layout. Starting from now I will put
articles as separate static pages and not blog posts. That way
it will be easier to categorize and update them. For “compatibility”
I will not remove old posts but all updates will go only to article
pages (under “Articles” menu).</p>Small update on the page layout. Starting from now I will put articles as separate static pages and not blog posts. That way it will be easier to categorize and update them. For “compatibility” I will not remove old posts but all updates will go only to article pages (under “Articles” menu).tuple-driven file read/write with variadic templates2016-07-31T10:35:21+00:002016-07-31T10:35:21+00:00/c++/c++11/tuple/2016/07/31/tuple-driven-file-io<p>Today will be something completely different. We’ll focus on C++11 feature called variadic templates. Goal of
this post is providing functions which will read binary files described by tuples, for example you can describe
content of the file as std::tuple and by only one call you will dump or read this tuple to file. Tuple is
somehow similar to std::array with the difference that it’s capable of holding different types of data in one container.</p>
<h2 id="variadic-templates">Variadic templates</h2>
<p>First of all we need to understand what variadic template is. You can of course start with some overview on
<a href="https://en.wikipedia.org/wiki/Variadic_template">wiki</a>. I think the simplest usable example of variadic
templates would be something like this snippet:</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="cp">#include <iostream>
</span>
<span class="kt">void</span> <span class="nf">print_many</span><span class="p">()</span> <span class="p">{}</span>
<span class="k">template</span><span class="o"><</span><span class="k">typename</span> <span class="n">T</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Args</span><span class="o">></span>
<span class="kt">void</span> <span class="n">print_many</span><span class="p">(</span><span class="n">T</span> <span class="n">value</span><span class="p">,</span> <span class="n">Args</span><span class="p">...</span> <span class="n">args</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">value</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="n">print_many</span><span class="p">(</span><span class="n">args</span><span class="p">...);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">print_many</span><span class="p">(</span><span class="s">"foo"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>What is it? We have created print_many variadic function. It accepts any number of arguments of any type. We
call it with 3 arguments of types ‘const char<em>’, ‘int’ and ‘int’. Compiler matches print_many(T value, Args… args)
and put ‘const char</em>’ as T and {‘int’, ‘int’} as Args… The function is now created by the compiler. We cannot
easily access elements in parameter pack (args) but we do have access to the first argument ‘T value’. We can
access it as any other regular function argument. In this case we will pass it to std::cout for printing on
stdout. After that we’re recursively calling print_many but this time with 2 arguments, int’s. Now T becomes
int and Args becomes {‘int’}. Recursing again, T is once again int but Args is empty, printing last item and
recursing again with empty parameter pack. This is why we have explicitly defined print_many() without any
arguments, just to satisfy termination condition. The equivalent of the above code without variadic templates
would be (this is what will be generated by compiler):</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="cp">#include <iostream>
</span>
<span class="kt">void</span> <span class="nf">print_many</span><span class="p">()</span> <span class="p">{}</span>
<span class="kt">void</span> <span class="nf">print_many</span><span class="p">(</span><span class="kt">int</span> <span class="n">c</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">c</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">print_many</span><span class="p">(</span><span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">c</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">b</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="n">print_many</span><span class="p">(</span><span class="n">c</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">print_many</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">c</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">a</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="n">print_many</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">print_many</span><span class="p">(</span><span class="s">"foo"</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>And this is how for example make_shared was implemented without variadic templates. Libraries (boost) provides
make_shared overload for any number of arguments. To support N arguments you need to create N+1 functions.</p>
<h2 id="iterating-through-stdtuple">Iterating through std::tuple</h2>
<p>Next step will be to write some routines for iterating through std::tuple and printing it content. It will be quite similar to our previous example with print_many().</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="cp">#include <iostream>
#include <tuple>
#include <type_traits>
</span>
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o"><</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="n">t</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="n">I</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="n">print_tuple</span><span class="o"><</span><span class="n">I</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Tp</span><span class="p">...</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">t</span><span class="p">{</span><span class="sc">'A'</span><span class="p">,</span> <span class="mf">1.5</span><span class="n">f</span><span class="p">,</span> <span class="mi">6</span><span class="p">};</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>It’s a little bit more complicated than the first example. But let’s start from the beginning, what happen
when you call print_tuple function? Compiler will match both functions so the call should be ambiguous. It is
not thanks to enable_if which uses C++ feature called SFINAE. The I argument defaults to 0 which is less than
sizeof…(Tp) (3 at this point) so enable_if will produce error for first overload leaving us with the second
one and this is what we want. Now each call to print_tuple will cause calling second variant until we meet the
I == sizeof…(Tp) condition. You can check this by changing print_tuple call in main function to
print_tuple<3>(t);, it will cause the condition in first overload to be true and the second to be false.
Nothing will be printed, you have just used the first function. But let’s dive into implementation of the
second print_tuple, it’s two-liner. First line is just for getting an I-th element from tuple and printing it.
The second line is recursive call with I+1 causing next element to be recursively printed. It will recurse
until first print_tuple’s enable_if condition evaluates to true, namely until I == 3 in our case, this will
terminate recursion.</p>
<h2 id="putting-it-all-together">Putting it all together</h2>
<p>Only thing which is left is to provide functions for reading and writing data. They will be very similar to
print_tuple but instead of writing to stdout they will read/write from a file stream.</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="cp">#include <iostream>
#include <tuple>
#include <type_traits>
#include <fstream>
</span>
<span class="c1">// printing tuple
</span><span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o"><</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="n">t</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="n">I</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="o"><<</span> <span class="s">", "</span><span class="p">;</span>
<span class="n">print_tuple</span><span class="o"><</span><span class="n">I</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Tp</span><span class="p">...</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// writing tuple to a file
</span><span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">write_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="o">&</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o"><</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">write_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="o">&</span><span class="n">ofs</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="n">t</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ofs</span><span class="p">.</span><span class="n">write</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="o">&</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="n">I</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">),</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple_element</span><span class="o"><</span><span class="n">I</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">>>::</span><span class="n">type</span><span class="p">));</span>
<span class="n">write_tuple</span><span class="o"><</span><span class="n">I</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Tp</span><span class="p">...</span><span class="o">></span><span class="p">(</span><span class="n">ofs</span><span class="p">,</span> <span class="n">t</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// reading tuple from a file
</span><span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o">==</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">read_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="o">&</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">template</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">I</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="k">typename</span><span class="p">...</span> <span class="n">Tp</span><span class="o">></span>
<span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">enable_if</span><span class="o"><</span><span class="n">I</span> <span class="o"><</span> <span class="k">sizeof</span><span class="p">...(</span><span class="n">Tp</span><span class="p">),</span> <span class="kt">void</span><span class="o">>::</span><span class="n">type</span>
<span class="n">read_tuple</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="o">&</span><span class="n">ifs</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">></span> <span class="o">&</span><span class="n">t</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ifs</span><span class="p">.</span><span class="n">read</span><span class="p">((</span><span class="kt">char</span> <span class="o">*</span><span class="p">)</span><span class="o">&</span><span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o"><</span><span class="n">I</span><span class="o">></span><span class="p">(</span><span class="n">t</span><span class="p">),</span> <span class="k">sizeof</span><span class="p">(</span><span class="k">typename</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple_element</span><span class="o"><</span><span class="n">I</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="n">Tp</span><span class="p">...</span><span class="o">>>::</span><span class="n">type</span><span class="p">));</span>
<span class="n">read_tuple</span><span class="o"><</span><span class="n">I</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Tp</span><span class="p">...</span><span class="o">></span><span class="p">(</span><span class="n">ifs</span><span class="p">,</span> <span class="n">t</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">tout</span><span class="p">{</span><span class="sc">'A'</span><span class="p">,</span> <span class="mf">1.5</span><span class="n">f</span><span class="p">,</span> <span class="mi">6</span><span class="p">};</span>
<span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">float</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">tin</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="n">out</span><span class="p">(</span><span class="s">"test.bin"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Writing tuple to test.bin: "</span><span class="p">;</span>
<span class="n">print_tuple</span><span class="p">(</span><span class="n">tout</span><span class="p">);</span> <span class="c1">// print out the tuple
</span> <span class="n">write_tuple</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">tout</span><span class="p">);</span> <span class="c1">// write tuple to file
</span> <span class="n">out</span><span class="p">.</span><span class="n">flush</span><span class="p">();</span> <span class="c1">// flush the file so we can read it immediately
</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="n">in</span><span class="p">(</span><span class="s">"test.bin"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"reading tuple from test.bin: "</span><span class="p">;</span>
<span class="n">read_tuple</span><span class="p">(</span><span class="n">in</span><span class="p">,</span> <span class="n">tin</span><span class="p">);</span> <span class="c1">// read the tuple from file
</span> <span class="n">print_tuple</span><span class="p">(</span><span class="n">tin</span><span class="p">);</span> <span class="c1">// print it out
</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
<p>Simple, isn’t it?;-) Looks pretty obfuscated but this is C++ meta programming. As a homework you can create a
function for iterating through the tuple and applying some functor over each element. That way you can have
only one iterate_over function and three functors for reading from file, writing to file and printing to stdout.
No code duplication!</p>Today will be something completely different. We’ll focus on C++11 feature called variadic templates. Goal of this post is providing functions which will read binary files described by tuples, for example you can describe content of the file as std::tuple and by only one call you will dump or read this tuple to file. Tuple is somehow similar to std::array with the difference that it’s capable of holding different types of data in one container.Simple state machine in C++2016-07-29T10:35:21+00:002016-07-29T10:35:21+00:00/c++/c++11/tuple/fsm/2016/07/29/simple-state-machine<p>Some time ago we faced a small problem – we need a state machine in our embedded project. There are several
libraries and tools available out there, starting with things like <a href="http://smc.sourceforge.net/">SMC</a> ending
on boost <a href="http://www.boost.org/doc/libs/1_64_0/libs/msm/doc/HTML/index.html">MSM</a> library. Our application is
running on STM32F103 family microprocessor with 20kB of SRAM so size matters. :-) Using boost would be overkill because of few reasons:</p>
<ul>
<li>we want small and maintainable code also we want small output binary size. MSM is quite small but probably
<a href="http://www.boost.org/doc/libs/1_64_0/libs/msm/doc/HTML/ch04s04.html">not small enough</a>.</li>
<li>we want zero dynamic allocations, reason for that is that our project needs to run on microprocessor for days
or months in very memory limited environment. I don’t want to care about tracing every memory allocation (it’s
hard to say anything about MSM at first glance but after quick “grep” we can find some std::deque’s and vectors in the implementation).</li>
<li>the main requirement of such library is ability to “keep” current state and allow to trigger state transitions with some event</li>
<li>not generated code is a plus, unfortunately SMC is “generator”</li>
</ul>
<p>Keeping this in mind I’ve created very small state machine library consisting of only one header file and have
only dependency to great <a href="https://github.com/ericniebler/meta">meta programming library by Eric Niebler</a>.
The outcome of this idea is my <a href="https://github.com/lukaszgemborowski/fsmpp">fsmpp library</a>.
State machine description is inspired by boost msm but slightly different, for example:</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="k">using</span> <span class="n">my_transition_table</span> <span class="o">=</span> <span class="n">fsm</span><span class="o">::</span><span class="n">transitions</span><span class="o"><</span>
<span class="n">fsm</span><span class="o">::</span><span class="n">transition</span><span class="o"><</span><span class="n">StateA</span><span class="p">,</span> <span class="n">TriggerA</span><span class="p">,</span> <span class="n">StateB</span><span class="o">></span><span class="p">,</span>
<span class="n">fsm</span><span class="o">::</span><span class="n">transition</span><span class="o"><</span><span class="n">StateB</span><span class="p">,</span> <span class="n">TriggerB</span><span class="p">,</span> <span class="n">StateC</span><span class="o">></span>
<span class="o">></span><span class="p">;</span></code></pre></figure>
<p>Where StateA, StateB, StateC, TriggerA, TriggerB are user defined classed. Given such transition table you can create state machine such as:</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="n">fsm</span><span class="o">::</span><span class="n">fsm</span><span class="o"><</span><span class="n">my_transition_table</span><span class="o">></span> <span class="n">sm</span><span class="p">;</span></code></pre></figure>
<p>This code will instantiate all state classes for you in std::tuple – you do not need to do anything special.
Using std::tuple is not requiring any dynamic allocation so state machine size is known at compile time. Each
state class has to have some special methods:</p>
<ul>
<li>enter() – called when entering the state</li>
<li>exit() – called when exiting the state</li>
<li>event() – called when handling event in current state</li>
</ul>
<p>you need to define them, keep in mind that if your state is handling TriggerA or TriggerB you need to implement
appropriate event(const EventType &) method. Not doing this results in compile time error. To trigger state
transition just call fsm::on method on fsm instance, eg.:</p>
<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="n">sm</span><span class="p">.</span><span class="n">on</span><span class="p">(</span><span class="n">TriggerA</span><span class="p">{});</span></code></pre></figure>
<p>being in StateA fsm will call StateA::event(TriggerA &) method. If the call return true state transition (in
this case to StateB) occurs. Meaning it will call StateA::exit() and then StateB::enter() methods. Full
example can be found in projects <a href="https://github.com/lukaszgemborowski/fsmpp/blob/master/tests/">tests directory</a>.</p>
<p>For now this is just proof of concept but is somehow usable.</p>Some time ago we faced a small problem – we need a state machine in our embedded project. There are several libraries and tools available out there, starting with things like SMC ending on boost MSM library. Our application is running on STM32F103 family microprocessor with 20kB of SRAM so size matters. :-) Using boost would be overkill because of few reasons:Building your own qemu2016-07-24T10:35:21+00:002016-07-24T10:35:21+00:00/linux/qemu/2016/07/24/building-your-own-qemu<p>This post is about where to find, how to clone official qemu repository and how to build fresh copy of it.</p>
<h2 id="why">Why?</h2>
<p>As always there is a question why? There are some reasons why would you like to build your own qemu:</p>
<ul>
<li>you don’t have qemu package in your distro (is there such a distro anyway?)</li>
<li>your distro is providing quite old qemu or you want to try some new dev snapshot</li>
<li>and most important: you want to become a qemu developer :-)</li>
</ul>
<p>In the future I will probably write some posts about qemu development so this short post should be good entry
point for the future.</p>
<h2 id="start">Start</h2>
<p>qemu needs some extra packages (libs and tools) installed on your machine before building:</p>
<ul>
<li>git</li>
<li>glib2.0-dev</li>
<li>libfdt-dev</li>
<li>libpixman-1-dev</li>
<li>zlib1g-dev</li>
<li>… and of course some basic dev stuff like C compiler, make, etc</li>
</ul>
<p>Now you can get sources, as always create some workspace directory for that, go into it and clone qemu
repository:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git clone git://git.qemu-project.org/qemu.git
$ cd qemu
</code></pre></div></div>
<p>Now you should decide, to build fresh qemu you can stick to master branch (ie. branch that you are actually
in), if you want to check some release or release candidate first list available tags:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git tag
</code></pre></div></div>
<p>You can choose whatever you want or need. Let’s try stable 2.6.0 version:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git checkout v2.6.0
</code></pre></div></div>
<h2 id="configuring">Configuring</h2>
<p>This is the most important part of building qemu. You may want to run ./configure –help top see all the
options available. If you want to reduce compile time and output size you may choose only one platform
target, in our example ARM. In this point you can also define “target directory” where make install will put
all the files. You will use prefix switch for that. I often tend to put all custom-built packages in my $HOME/opt directory. Let’s do it this way:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./configure --target-list=arm-softmmu --prefix=$HOME/opt
</code></pre></div></div>
<p>Now you can proceed with build:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make
$ make install
</code></pre></div></div>
<p>Verify the installation</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ $HOME/opt/bin/qemu-system-arm --version
QEMU emulator version 2.6.0, Copyright (c) 2003-2008 Fabrice Bellard
</code></pre></div></div>
<p>That’s it, you have your own qemu correctly built and installed. In the near feature I will try to write
something about qemu development itself.</p>This post is about where to find, how to clone official qemu repository and how to build fresh copy of it.Buildroot basic usage2016-07-19T10:35:21+00:002016-07-19T10:35:21+00:00/linux/qemu/2016/07/19/buildroot-basic-usage<p>In two previous posts you have learned how to build a corss-compiler and how to build and run simple Linux
system on Qemu ARM. In this post we will simplify the whole process (in terms of steps you need to perform)
and create more advanced Linux system than before.</p>
<h2 id="buildroot">Buildroot</h2>
<p>For this purpose we will use tool called <a href="https://buildroot.org/">buildroot</a>. In short, buildroot is a set of
makefiles which automates process of building the embedded Linux system. It will build several things for us:</p>
<ul>
<li>cross-compiler</li>
<li>Linux kernel</li>
<li>busybox</li>
<li>libc</li>
<li>final system image</li>
</ul>
<p>It will do many other things, for example it provide default configuration or build several other tools and
packages. We can just select packages (like ssh server) from the list in configuration menu similar to kernel
or busybox menuconfig. But let’s start with simple things. Let’s build minimalistic system which does not have
much more functionality than the system built before.</p>
<h2 id="building">Building</h2>
<p>First of all you need to download buildroot package. In the time of writing this post newest version is
2016.02. You can download it from official webpage or from github. You can take archive or clone repository.
Let’s get tar.gz release from github and unpack it.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wget https://github.com/buildroot/buildroot/archive/2016.02.tar.gz
$ tar xf 2016.02.tar.gz
</code></pre></div></div>
<p>you should see buildroot-2016.02 directory, now create separate build directory (in fact it is not needed but
will separate sources from actual build stuff making it more clear) and initialize project with default
configuration:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mkdir build
$ make -C $(pwd)/buildroot-2016.02 O=$(pwd)/build qemu_arm_versatile_defconfig
</code></pre></div></div>
<p>we’re almost done but to retain the same output format as in previous post we need to change one configuration
option. Let’s do this now:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd build
$ make menuconfig
</code></pre></div></div>
<p>you should see the menu, go to Filesystem images, uncheck ext2/3/4 root filesystem, instead check cpio the
root filesystem and set compression to gzip.</p>
<p><img src="/assets/menu-1.png" alt="menuconfig" /></p>
<p>You can exit the menu saving configuration file (remember to press “Yes” when you’re asked about save). After
this step you can just run make and watch how your system is being build. Do not pass -j option to make here,
buildroot will automatically pass proper -j option to each package makefile when building (you can change this
in menu also: Build options -> Number of jobs to run simultaneously (0 for auto)).</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make
</code></pre></div></div>
<p>now you have quite long coffee-break.</p>
<h2 id="running-the-system">Running the system</h2>
<p>We will run our fresh system exactly like the one built by ourselves before. The output of the build is now
placed in images subdirectory of our build directory. Let’s go:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ qemu-system-arm -M versatilepb -kernel images/zImage -dtb images/versatile-pb.dtb -initrd images/rootfs.cpio.gz -serial stdio -append "root=/dev/mem serial=ttyAMA0"
</code></pre></div></div>
<p>After a while you should see login prompt:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Welcome to Buildroot
buildroot login:
</code></pre></div></div>
<p>type “root”, press enter and you’re in the shell. So what do we get by using buildroot? Simplified build
process for sure. Buildroot also comes with many predefined configs for popular boards like:</p>
<ul>
<li>raspberrypi2_defconfig</li>
<li>cubieboard2_defconfig</li>
<li>beaglebone_defconfig</li>
</ul>
<p>just list buildroot-2016.02/configs directory to see them all. Do we get something more? Kill qemu (ctrl+c)
and re-run menuconfig by make menuconfig. Go to Target packages -> Games and check sl. Exit and save
configuration, run make, wait a while and run qemu the same way as before. Login as root and type “sl” in
terminal.</p>
<p><img src="/assets/sl.png" alt="sl command" /></p>
<p>Easy, isn’t it? You can select any predefined package from this menu or even add your own custom package.</p>In two previous posts you have learned how to build a corss-compiler and how to build and run simple Linux system on Qemu ARM. In this post we will simplify the whole process (in terms of steps you need to perform) and create more advanced Linux system than before.ARM cross compiler with crosstols-ng2016-07-16T10:35:21+00:002016-07-16T10:35:21+00:00/linux/qemu/2016/07/16/arm-cross-compiler-with-crosstools-ng<p>In previous post I have showed you how to build small Linux system running on Qemu ARM. Most probably some of
you faced a problem that ARM cross compiler is not delivered with your linux distribution. We can easily solve
this issue with project named <a href="http://crosstool-ng.org/">crosstools-ng</a>. From the project web page:</p>
<blockquote>
<p>crosstool-NG aims at building toolchains. Toolchains are an essential component in a software development
project. It will compile, assemble and link the code that is being developed. Some pieces of the toolchain
will eventually end up in the resulting binary/ies: static libraries are but an example.</p>
</blockquote>
<p>Other reason to have your own toolchain is repeatability. If you have bigger project with multiple people
involved then most probably you want to have exactly the same environment for everyone. Compilers can differ a
little bit from version to version so having the same toolchain across the team is very important especially
in embedded development.</p>
<h2 id="getting-the-toolchain">Getting the toolchain</h2>
<p>Navigate to http://crosstool-ng.org/ to find latest release. You will find announces on the top of the page in
“news” section. If not, you can directly go to download page: http://crosstool-ng.org/download/crosstool-ng/.
Naming scheme is crosstool-ng-VERSION.tar.bz2, where version is X.Y.Z, so you need to get highest X, highest Y
and Z. They usually put a file named 00-LATEST-is-VERSION so you can easily find newest version. Now it’s
1.22.0. Grab and extract it:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.22.0.tar.bz2
$ tar xf crosstool-ng-1.22.0.tar.bz2
$ cd crosstool-ng/
</code></pre></div></div>
<p>This is standard autotools package so the building is straightforward. One thing you need to consider is
location where you want to install your toolchain. I don’t want to install it system-wide so my destination
directory will be $HOME/opt. If you want to install it system-wide you can omit prefix option in configure
invocation:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./configure --prefix=$HOME/opt
$ make
$ make install
</code></pre></div></div>
<p>At this point you will have tool called ct-ng installed. If you installed it in non standard place you need to
add it to your PATH variable. In my case:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ export PATH=$HOME/opt/bin:$PATH
</code></pre></div></div>
<p>This is build and management script for toolchains. You can see all preconfigured toolchains:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ct-ng list-samples
</code></pre></div></div>
<p>select desired toolchain</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ct-ng arm-unknown-linux-gnueabi
</code></pre></div></div>
<p>After the build toolchain will be installed by default in ${HOME}/x-tools. If you want to change this edit
.config file, search for CT_PREFIX_DIR variable and modify it if you want.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ct-ng build
</code></pre></div></div>
<p>You should see something like:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
[EXTRA] Building a toolchain for:
[EXTRA] build = x86_64-pc-linux-gnu
[EXTRA] host = x86_64-pc-linux-gnu
[EXTRA] target = arm-unknown-linux-gnueabi
...
</code></pre></div></div>
<p>It means that you are building x86 toolchain for ARM target. So cross compiling from you PC architecture to
ARM. Now it’s coffee break time as downloading and building gcc will take a while, really. Done!</p>
<h2 id="usage">Usage</h2>
<p>In the previous post I have described how to build Linux kernel for ARM architecture. To provide
cross-compiler for build system we have set variable CROSS_COMPILE=arm-linux-gnueabi-. Now if you want to use
your brand new toolchain when building the linux kernel you can simply use:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make ARCH=arm CROSS_COMPILE=${HOME}/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-
</code></pre></div></div>In previous post I have showed you how to build small Linux system running on Qemu ARM. Most probably some of you faced a problem that ARM cross compiler is not delivered with your linux distribution. We can easily solve this issue with project named crosstools-ng. From the project web page:Minimalistic Linux system on qemu ARM2016-07-16T10:35:21+00:002016-07-16T10:35:21+00:00/linux/qemu/2016/07/16/minimalistic-linux-system-on-qemu-arm<p>Goal of this post is to show you how to build and run a simple ARM-based linux kernel and system on qemu.
Content of this little distribution will be made of two main parts: Linux kernel and Busybox for simple shell
and user space utils.</p>
<h2 id="why">Why?</h2>
<p>There are some reasons why you want to have ARM Linux running on QEMU:</p>
<ul>
<li>You’re Linux developer and you want to test some changes in kernel, with qemu it’s quick and simple. Qemu is able to run it’s own gdb server so you can attach with gdb to running kernel and debug it!</li>
<li>You’re qemu developer and you want to have simple OS for testing</li>
<li>You just want to learn how Linux works and how to build simple system.</li>
</ul>
<h2 id="go">Go!</h2>
<p>I assume that you’re running some Linux distro, preferably Debian or Ubuntu based (because it comes with
pre-built ARM cross-compiler). So first of all you need a… cross-compiler, for Ubuntu you can just “apt
install gcc-arm-linux-gnueabi” it. For other distro it may be different. Unfortunately I need to send you to
your distro documentation. You can also build your own cross-compiler following steps described in my next
post. In my case installed gcc binary is named arm-linux-gnueabi-gcc and it’s available in my PATH environment
variable. The second tool you need is qemu. On Ubuntu you need to install qemu-system-arm package. Create some
empty workspace for our project and navigate there. We will put all the stuff there. To verify if our
cross-compiler is working correctly we can try to compile simple program, create a file main.c with following
content:</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="p">}</span></code></pre></figure>
<p>And then run:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ arm-linux-gnueabi-gcc main.cpp main.c -o test
</code></pre></div></div>
<p>It should compile without any errors. To verify if it’s really arm executable run:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ file test
test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=2bf38f2c75d90391b4ec5aa4eac3cb2f041a15ee, not stripped
</code></pre></div></div>
<p>Yeah, it’s ARM executable. We just prove that we have working ARM cross-compiler. This is really good start.
:-) Now we need to get sources for our Linux “distribution”. The main part of our system will be kernel itself,
navigate to <a href="https://www.kernel.org/">kernel.org</a> ang grab latest stable release. In the time when I’m writing
this document it’s 4.6.3. So:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.6.3.tar.xz
</code></pre></div></div>
<p>Next we need some userland so we can log-in and perform some interactive actions. Kernel alone is not quite
useful for a regular user. For that we will use BusyBox. Once again, navigate to
<a href="https://www.busybox.net/">busybox.net</a> and grab some fresh stable release. In my case it will be 1.24.2:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ wget http://busybox.net/downloads/busybox-1.24.2.tar.bz2
</code></pre></div></div>
<p>Extract downloaded archives:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ tar xf linux-4.6.3.tar.xz
$ tar xf busybox-1.24.2.tar.bz2
</code></pre></div></div>
<h2 id="building-arm-linux-kernel">Building ARM Linux kernel</h2>
<p>To do this as quick as possible we will use default configuration for qemu. To cross-compile Linux you need to
know two things:</p>
<ol>
<li>Target architecture (in our case it’s arm)</li>
<li>Cross compiler name prefix, for example arm-linux-gnueabi-</li>
</ol>
<p>You can start by navigating to kernel source tree and making default configuration:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd linux-4.6.3
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- versatile_defconfig
</code></pre></div></div>
<p>As you can see we need provide those two things discussed before. Target architecture and prefix of gcc cross
compiler. Note that you only provide the prefix, not the full name of binary (so not including the “gcc” part
of the name). After that you can start compilation:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
</code></pre></div></div>
<p>The compilation process will start and take some time. After it finishes you can test your brand new kernel:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ qemu-system-arm -M versatilepb -kernel arch/arm/boot/zImage -dtb arch/arm/boot/dts/versatile-pb.dtb -serial stdio -append "serial=ttyAMA0"
</code></pre></div></div>
<p>Let’s talk about the arguments passed to qemu:</p>
<ul>
<li>-M – the board name, qemu is able to simulate several different boards but our kernel is especially customized for this one. We have provided this defconfig when configuring the kernel.</li>
<li>-kernel – the kernel binary itself</li>
<li>-dtb – device tree for the board, I can discus this file on another occasion, but assume that it’s mandatory to boot the system</li>
<li>-serial – where the console should be printed, we want it on stdio.</li>
<li>-append – append additional kernel command line arguments. We need to inform kernel where to print stuff by default. We want it to be ttyAMA0 device (first serial port)</li>
</ul>
<p>You should see the kernel booting and finally… kernel panic.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
CPU: 0 PID: 1 Comm: swapper Not tainted 4.6.3 #1
Hardware name: ARM-Versatile (Device Tree Support)
</code></pre></div></div>
<p>Don’t worry, it’s expected. You do not have a device with a valid root file system. We will provide it in a
while and this is the reason why we want to have BusyBox. It will provide basic functionality for our small
system.</p>
<h2 id="busybox">Busybox</h2>
<p>Go back one directory up to the place where you have extracted your BusyBox sources. Go into this directory
and configure BusyBox, you will need almost the same command line arguments as for Linux kernel:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd busybox-1.24.2
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
</code></pre></div></div>
<p>Now we we have default configuration file created. We need to tune it a little by making busybox executable
statically linked as we don’t want to provide additional shared libraries. We can do this by invoking:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
</code></pre></div></div>
<p>Navigating to Busybox Settings -> Build Options and checking “Build BusyBox as a static binary (no shared
libs)” option. Now we can proceed with compilation:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
</code></pre></div></div>
<p>This should be quite quick. Now we are ready to create our root filesystem image. We will put there init
script, busybox and also provide proper directory layout.</p>
<h2 id="root-filesystem">Root filesystem</h2>
<p>So what this thing should contain? What do we want for our minimalistic Linux system? Only a few things:</p>
<ul>
<li>init script – Kernel needs to run something as first process in the system.</li>
<li>Busybox – it will contain basic shell and utilities (like cd, cp, ls, echo etc)</li>
</ul>
<p>Navigate back to our workspace and create directory named rootfs. In this directory create file named init,
eg. vim rootfs/init</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="c">#!/bin/sh</span>
mount <span class="nt">-t</span> proc none /proc
mount <span class="nt">-t</span> sysfs none /sys
mknod <span class="nt">-m</span> 660 /dev/mem c 1 1
<span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">Hello!</span><span class="se">\n</span><span class="s2">"</span>
<span class="nb">exec</span> /bin/sh</code></pre></figure>
<p>Make it executable by:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ chmod +x rootfs/init
</code></pre></div></div>
<p>Now copy busybox stuff there:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cp -av busybox-1.24.2/_install/* rootfs/
</code></pre></div></div>
<p>Now you should have almost everything, there is only one thing missing, ie. standard directory layout. Let’s
create it:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ mkdir -pv rootfs/{bin,sbin,etc,proc,sys,usr/{bin,sbin}}
</code></pre></div></div>
<p>That’s all. We will use contents of this directory as the init ram disk so we need to create cpio archive and
compress it with gzip:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cd rootfs
$ find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
</code></pre></div></div>
<p>Note that we changed the current directory to rootfs first. This is because we don’t want “rootfs” to be
prepended to file paths.</p>
<h2 id="running">Running</h2>
<p>This part is pretty straight forward, we will run our kernel almost exactly as before:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ qemu-system-arm -M versatilepb -kernel linux-4.6.3/arch/arm/boot/zImage -dtb linux-4.6.3/arch/arm/boot/dts/versatile-pb.dtb -initrd rootfs.cpio.gz -serial stdio -append "root=/dev/mem serial=ttyAMA0"
</code></pre></div></div>
<p>There are two minor changes:</p>
<ul>
<li>-initrd argument is added, it points to the initial ram disk</li>
<li>root=/dev/mem is added to -append string. It tells kernel from where we want to boot.</li>
</ul>
<p>Now you should see shell prompt. You’re in your own Linux “distribution”. :-)</p>Goal of this post is to show you how to build and run a simple ARM-based linux kernel and system on qemu. Content of this little distribution will be made of two main parts: Linux kernel and Busybox for simple shell and user space utils.