<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>devtools | Blue Duck Valley Rd</title><link>https://juju.nz/michaelh/tags/devtools/</link><atom:link href="https://juju.nz/michaelh/tags/devtools/index.xml" rel="self" type="application/rss+xml"/><description>devtools</description><generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>en-us</language><copyright>© 2017-2025 Michael Hope</copyright><lastBuildDate>Sun, 24 Aug 2014 00:00:00 +0000</lastBuildDate><image><url>img/map[gravatar:%!s(bool=false) shape:circle]</url><title>devtools</title><link>https://juju.nz/michaelh/tags/devtools/</link></image><item><title>Mini Xplus as a Server</title><link>https://juju.nz/michaelh/note/xplusserver/</link><pubDate>Sun, 24 Aug 2014 00:00:00 +0000</pubDate><guid>https://juju.nz/michaelh/note/xplusserver/</guid><description>&lt;p>Random, incomplete notes on using a
&lt;a href="https://www.miniand.com/" target="_blank" rel="noopener">Miniand
Tech&lt;/a>
&lt;a href="https://www.miniand.com/products/Mini%C2%A0Xplus%20TV%20Box%20H24" target="_blank" rel="noopener">Mini Xplus
H24&lt;/a>
as a server machine.&lt;/p>
&lt;h2 id="v2">v2&lt;/h2>
&lt;p>I&amp;rsquo;ve soldered up a serial port so doing things from scratch is much
easier.&lt;/p>
&lt;pre>&lt;code>$ sudo cp -a hwpack/rootfs/* /media/removable/rootfs/
sun4i# set extraargs init=/bin/sh
sun4i# run bootcmd
# rm -rf /var/run
# ./debootstrap/debootstrap --second-stage
# passwd
&lt;/code>&lt;/pre>
&lt;h2 id="v1">v1&lt;/h2>
&lt;p>Start with the Lubuntu image:
&lt;a href="https://www.miniand.com/forums/forums/2/topics/1" target="_blank" rel="noopener">https://www.miniand.com/forums/forums/2/topics/1&lt;/a>&lt;/p>
&lt;p>I used
&lt;a href="http://dl.miniand.com/allwinnera10/ubuntu/lubuntu-desktop-12.04-4-720p-512MB-miniand.com.img.7z" target="_blank" rel="noopener">http://dl.miniand.com/allwinnera10/ubuntu/lubuntu-desktop-12.04-4-720p-512MB-miniand.com.img.7z&lt;/a>&lt;/p>
&lt;p>Turns out my board has 1 GB and the board probed for it just fine.&lt;/p>
&lt;p>Writing the image to an SD card gives a boot and rootfs partition
similar to the OMAP series. The bootfs has a binary file and kernel
image.&lt;/p>
&lt;p>I don&amp;rsquo;t have a keyboard. Fix the wifi interface by editing
&lt;code>/etc/network/interfaces&lt;/code>:&lt;/p>
&lt;pre>&lt;code>auto wlan0
iface wlan0 inet dhcp
wpa-ssid &amp;quot;your network name&amp;quot;
wpa-psk your-network-key
&lt;/code>&lt;/pre>
&lt;p>The board doesn&amp;rsquo;t seem to register the hostname with the DHCP server.
mDNS works though.&lt;/p>
&lt;p>The Lubuntu image is armel based. The hard float armhf Precise image
should be much faster for floating point workloads as the A8 takes some
time to shift values back and forth between the core and VFP unit.&lt;/p>
&lt;p>Grab the modules from &lt;code>/lib/modules&lt;/code>. kpartx is your friend.&lt;/p>
&lt;p>Grab the most recent Precise release. I used
&lt;a href="http://cdimage.ubuntu.com/releases/precise/release/ubuntu-12.04-preinstalled-server-armhf&amp;#43;omap4.img.gz" target="_blank" rel="noopener">http://cdimage.ubuntu.com/releases/precise/release/ubuntu-12.04-preinstalled-server-armhf+omap4.img.gz&lt;/a>&lt;/p>
&lt;p>gunzip, &lt;code>mkfs.ext4 -L rootfs -m 0.5 /dev/sdc2&lt;/code>, and tar across to the SD
card.&lt;/p>
&lt;p>Set a password for root by editing &lt;code>/etc/shadow&lt;/code>.&lt;/p>
&lt;p>Use QEMU to boot and &lt;code>apt-get install wireless-tools wpasupplicant openssh-server&lt;/code>. &lt;code>adduser your-name&lt;/code>. &lt;code>adduser your-name sudo&lt;/code>.&lt;/p>
&lt;p>You can now boot and login.&lt;/p>
&lt;p>Set the default locale in &lt;code>/etc/default/locale&lt;/code>&lt;/p>
&lt;pre>&lt;code>LANG=C
LANGUAGE=C
&lt;/code>&lt;/pre>
&lt;p>Add universe to &lt;code>/etc/apt/sources.list&lt;/code>. Toast
/var/lib/preinstalled-pool/.&lt;/p></description></item><item><title>Builder</title><link>https://juju.nz/michaelh/note/builder/</link><pubDate>Thu, 01 Aug 2013 00:00:00 +0000</pubDate><guid>https://juju.nz/michaelh/note/builder/</guid><description>&lt;p>I&amp;rsquo;d like to set up clean auto builds of my personal projects and some
upstream projects like crosstool-ng, gcc, and binutils.&lt;/p>
&lt;h2 id="clean-install">Clean install&lt;/h2>
&lt;p>I&amp;rsquo;d like the build to run in a clean setup so the base system can be
used for general development without affecting the build results.&lt;/p>
&lt;p>Some technologies are:&lt;/p>
&lt;ul>
&lt;li>docker (LXC containers)&lt;/li>
&lt;li>schroot (Debian specific chroot helper)&lt;/li>
&lt;/ul>
&lt;p>debootstrap or Ubuntu Core can be used for the base system. Use polipo
as a cache for the packages.&lt;/p>
&lt;p>Aside: what does the debootstrap buildd variant include?&lt;/p>
&lt;ul>
&lt;li>/usr/share/debootstrap/scripts/&lt;distro> include the selectors&lt;/li>
&lt;li>Adds build-essential (quite reasonable)&lt;/li>
&lt;li>Or all tagged as Build-Essential&lt;/li>
&lt;/ul>
&lt;h2 id="schroot">schroot&lt;/h2>
&lt;p>schroot is nice:&lt;/p>
&lt;ul>
&lt;li>normal users can enter the chroot&lt;/li>
&lt;li>you can spawn a session chroot off a seed&lt;/li>
&lt;li>the startup scripts copy various files from the host across&lt;/li>
&lt;/ul></description></item><item><title>C++11 abuse</title><link>https://juju.nz/michaelh/note/cxxabuse/</link><pubDate>Sat, 23 Jun 2012 00:00:00 +0000</pubDate><guid>https://juju.nz/michaelh/note/cxxabuse/</guid><description>&lt;p>I&amp;rsquo;d like to use the new features in C++11 and the GCC extensions in
anger. What are they?&lt;/p>
&lt;p>rvalue references:&lt;/p>
&lt;ul>
&lt;li>Use?&lt;/li>
&lt;/ul>
&lt;p>Generalised constant expressions:&lt;/p>
&lt;ul>
&lt;li>&lt;code>constexpr&lt;/code> to mark a function/constructor as compile time constant&lt;/li>
&lt;li>non-void return&lt;/li>
&lt;li>can&amp;rsquo;t declare variables, declare types&lt;/li>
&lt;li>single return&lt;/li>
&lt;li>non-integrals are now OK: &lt;code>constexpr double foo = ...&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>POD:&lt;/p>
&lt;ul>
&lt;li>Wider than before&lt;/li>
&lt;li>trivial: can be statically initialised, can copy via memcpy()&lt;/li>
&lt;li>standard layout: C compatible&lt;/li>
&lt;li>No virtual functions, base classes&lt;/li>
&lt;li>Same access control&lt;/li>
&lt;/ul>
&lt;p>Initialiser lists:&lt;/p>
&lt;ul>
&lt;li>Class can have a std::initializer_list&lt;type> constructor&lt;/li>
&lt;li>Foo foo = {1, 2, 3};&lt;/li>
&lt;li>bar({4, 5, 6})&lt;/li>
&lt;li>std::vector
&lt;a href="std::string">std::string&lt;/a> v = { &amp;ldquo;x&amp;rdquo;, &amp;ldquo;y&amp;rdquo; }&lt;/li>
&lt;/ul>
&lt;p>Uniform initialisation:&lt;/p>
&lt;ul>
&lt;li>Not sure?&lt;/li>
&lt;li>&lt;code>struct Foo { int a; int b; } ... Foo get_bar() { return ( 5, 6 ); }&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Type inference:&lt;/p>
&lt;ul>
&lt;li>Awesome!&lt;/li>
&lt;li>&lt;code>auto foo = wacky_template_type::yeah&amp;lt;int, bar&amp;gt;...&lt;/code>&lt;/li>
&lt;li>&lt;code>auto foo = 5;&lt;/code>&lt;/li>
&lt;li>&lt;code>decltype(some_variable) some_other;&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Range based for:&lt;/p>
&lt;ul>
&lt;li>&lt;code>for (int &amp;amp;x : some_int_array) {}&lt;/code>&lt;/li>
&lt;li>Also works with iterators, begin()/end()&lt;/li>
&lt;/ul>
&lt;p>Anonymous functions:&lt;/p>
&lt;ul>
&lt;li>&lt;code>[](int arg1, int arg2) { return arg1 + arg2; }&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Trailing return type:&lt;/p>
&lt;ul>
&lt;li>Just like Go&lt;/li>
&lt;li>&lt;code>auto foo(int x, int y) -&amp;gt; int;&lt;/code>&lt;/li>
&lt;li>&lt;code>auto foo(int x, int y) -&amp;gt; decltype(x+y);&lt;/code>&lt;/li>
&lt;li>Used as x, y are now defined&lt;/li>
&lt;/ul>
&lt;p>Constructors:&lt;/p>
&lt;ul>
&lt;li>Delegation: &lt;code>Foo(int x) ...; Foo() : Foo(42) {}&lt;/code>&lt;/li>
&lt;li>Better than default values as the default gets spread across all
callers&lt;/li>
&lt;li>Base class constructor inheritance: &lt;code>Derived : Base { using Base::Base; }&lt;/code>&lt;/li>
&lt;li>Member initialisation: &lt;code>int value = 5;&lt;/code> will be called by all
constructors&lt;/li>
&lt;li>&lt;code>explicit Constructor...&lt;/code> to skip&lt;/li>
&lt;/ul>
&lt;p>Explicit override:&lt;/p>
&lt;ul>
&lt;li>Mark that you intended to override a base function&lt;/li>
&lt;li>&lt;code>virtual void do_it() override;&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Final classes and functions:&lt;/p>
&lt;ul>
&lt;li>&lt;code>struct Base final {}&lt;/code>: can&amp;rsquo;t derrive from&lt;/li>
&lt;li>&lt;code>virtual void the_last() final;&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Null pointer constant:&lt;/p>
&lt;ul>
&lt;li>No more zero, no more NULL: just &lt;code>nullptr&lt;/code>&lt;/li>
&lt;li>No ambiguity with int args&lt;/li>
&lt;/ul>
&lt;p>Fancy enums:&lt;/p>
&lt;ul>
&lt;li>&lt;code>enum class Foo : char { X, Y };&lt;/code>&lt;/li>
&lt;li>Gives Foo::X&lt;/li>
&lt;li>Explicit storage type&lt;/li>
&lt;/ul>
&lt;p>Extended templates:&lt;/p>
&lt;ul>
&lt;li>Typedef for a partial template specialisation&lt;/li>
&lt;li>&lt;code>using TypedefName = SomeType&amp;lt;OtherType, Second, 5&amp;gt;;&lt;/code>&lt;/li>
&lt;li>&lt;code>using OtherType = void (*)(double);&lt;/code> is the same as typedef
(*OtherType)(double)&lt;/li>
&lt;/ul>
&lt;p>Unrestricted unions:&lt;/p>
&lt;ul>
&lt;li>union can hold a type with a non trivial constructor&lt;/li>
&lt;/ul>
&lt;p>String literals:&lt;/p>
&lt;ul>
&lt;li>u8&amp;quot;I&amp;rsquo;m in UTF-8 and a const char and a random \u2012 character&amp;quot;&lt;/li>
&lt;li>u&amp;quot;I&amp;rsquo;m in UTF-16 and a const char16_t&amp;quot;&lt;/li>
&lt;li>U&amp;quot;I&amp;rsquo;m in UTF-32 and a const char32_t&amp;quot;&lt;/li>
&lt;li>R&amp;quot;(I&amp;rsquo;m a raw string)&amp;quot;&lt;/li>
&lt;li>R&amp;quot;xy(So am I)xy&amp;quot;&lt;/li>
&lt;/ul>
&lt;p>Explicitly deleted/defaulted members:&lt;/p>
&lt;ul>
&lt;li>Explicit default constructor &lt;code>class Foo { Foo() = default; }&lt;/code>&lt;/li>
&lt;li>No default copy constructor &lt;code>class Foo { Foo(const Foo&amp;amp;) = delete; }&lt;/code>&lt;/li>
&lt;li>No implicit cast &lt;code>class Foo { void f(double); void f(int) = delete; }&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Misc:&lt;/p>
&lt;ul>
&lt;li>&lt;code>&amp;gt;&amp;gt;&lt;/code> closes templates. Don&amp;rsquo;t need &lt;code>&amp;gt; &amp;gt;&lt;/code>&lt;/li>
&lt;li>&lt;code>explicit&lt;/code> on conversion operators and constructors to prevent
implicit conversion to other types&lt;/li>
&lt;li>Variadic templates?&lt;/li>
&lt;li>User defined literals: &lt;code>Type variable = 1234_suffix;&lt;/code>&lt;/li>
&lt;li>But when are they evaluated? compile, start, or runtime?&lt;/li>
&lt;li>static_assert&lt;/li>
&lt;li>sizeof on members: &lt;code>struct Foo { int bar; }; sizeof(Foo::bar);&lt;/code>&lt;/li>
&lt;li>alignof(), alignas()&lt;/li>
&lt;/ul>
&lt;p>Standard library:&lt;/p>
&lt;ul>
&lt;li>std::thread&lt;/li>
&lt;li>std::lock_guard, std::unique_lock&lt;/li>
&lt;li>Futures, promises, and async&lt;/li>
&lt;li>std::tuples&lt;/li>
&lt;/ul></description></item><item><title>Running Ubuntu armel cloud instances manually</title><link>https://juju.nz/michaelh/note/armel-cloud/</link><pubDate>Sun, 22 Jan 2012 00:00:00 +0000</pubDate><guid>https://juju.nz/michaelh/note/armel-cloud/</guid><description>&lt;p>Documentation:
&lt;a href="https://help.ubuntu.com/community/UEC/Images" target="_blank" rel="noopener">https://help.ubuntu.com/community/UEC/Images&lt;/a>&lt;/p>
&lt;p>The image itself:
&lt;a href="http://uec-images.ubuntu.com/oneiric/current/oneiric-server-cloudimg-armel-disk1.img" target="_blank" rel="noopener">http://uec-images.ubuntu.com/oneiric/current/oneiric-server-cloudimg-armel-disk1.img&lt;/a>&lt;/p>
&lt;p>This is the plain QCOW2 image. The normal one includes OMAP3/4(?) kernel
but I&amp;rsquo;ll use the vexpress-a9 Linaro hwpack
instead.&lt;/p>
&lt;pre>&lt;code>michaelh@crucis:~/linaro/tests/qemu/img$ qemu-img info oneiric-server-cloudimg-armel-disk1.img
image: oneiric-server-cloudimg-armel-disk1.img
file format: qcow2
virtual size: 808M (847203840 bytes)
disk size: 198M
cluster_size: 65536
&lt;/code>&lt;/pre>
&lt;p>Running with:&lt;/p>
&lt;pre>&lt;code>qemu-system-arm -M vexpress-a9 -m 1024 \
-drive file=../../img/ubuntu.img,if=sd,cache=writeback \
-serial stdio \
-append 'root=/dev/mmcblk0p1 rw mem=1024M console=ttyAMA0,38400n8 rootwait' \
-kernel ../../img/tip/uImage -initrd ../../img/tip/uInitrd
&lt;/code>&lt;/pre>
&lt;p>Sits there saying:&lt;/p>
&lt;p>&lt;tt>2012-01-09 03:12:12,509 - DataSourceEc2.py[WARNING]:
&amp;lsquo;http://169.254.169.254&amp;rsquo; failed: url error [[Errno 111] Connection
refused]&lt;/tt>&lt;/p>
&lt;p>Try different boot args:&lt;/p>
&lt;pre>&lt;code>root=/dev/mmcblk0p1 rw mem=1024M console=ttyAMA0,38400n8 rootwait \
init=/usr/lib/cloud-init/uncloud-init ubuntu-pass=ubuntu ds=unloud-init
&lt;/code>&lt;/pre>
&lt;p>Running:&lt;/p>
&lt;pre>&lt;code>qemu-system-arm -M vexpress-a9 -m 1024 \
-drive file=../../img/ubuntu.img,if=sd,cache=writeback \
-serial stdio \
-append 'root=/dev/mmcblk0p1 rw mem=1024M console=ttyAMA0,38400n8 rootwait init=/usr/lib/cloud-init/uncloud-init ubuntu-pass=ubuntu ds=nocloud' \
-kernel ../../img/tip/uImage -initrd ../../img/tip/uInitrd
&lt;/code>&lt;/pre>
&lt;p>Fails
with:&lt;/p>
&lt;pre>&lt;code>Failed to execute /usr/lib/cloud-init/nocloud-init. Attempting defaults...
&lt;/code>&lt;/pre>
&lt;p>Should be &lt;code>uncloud-init&lt;/code>.&lt;/p>
&lt;p>&lt;code>uncloud-init&lt;/code> assumes the console is on &lt;code>ttyS0&lt;/code>. Patch to ttyAMA0.&lt;/p>
&lt;p>Final fault is the &lt;code>ds=&lt;/code>. Should be nocloud which causes cloud-init to
use &lt;code>DataSourceNoCloud.py&lt;/code>.&lt;/p>
&lt;p>Forward SSH:&lt;/p>
&lt;pre>&lt;code>-redir tcp:5022::22
&lt;/code>&lt;/pre>
&lt;p>Giving:&lt;/p>
&lt;pre>&lt;code>qemu-system-arm -M vexpress-a9 -m 1024 \
-drive file=../../img/ubuntu.img,if=sd,cache=writeback -serial stdio \
-append 'root=/dev/mmcblk0p1 rw mem=1024M console=ttyAMA0,38400n8 rootwait init=/usr/lib/cloud-init/uncloud-init ubuntu-pass=ubuntu ds=nocloud' \
-kernel ../../img/tip/uImage -initrd ../../img/tip/uInitrd \
-redir tcp:5022::22
&lt;/code>&lt;/pre></description></item></channel></rss>