Frederic CambusPersonal site and technical blog of Frederic CambusZola2023-10-01T17:14:00+00:00https://www.cambus.net/atom.xmlMy FreeBSD years: 2000-20052023-10-01T17:14:00+00:002023-10-01T17:14:00+00:00Unknownhttps://www.cambus.net/my-freebsd-years-2000-2005/<p>In the introduction of my "<a rel="noopener" target="_blank" href="https://www.cambus.net/why-openbsd/">Why OpenBSD?</a>" post, I mentioned that I came
to the BSD world through FreeBSD.</p>
<p>Rather than paraphrasing what I wrote back then, here is the relevant part:</p>
<blockquote>
<p>I’ve been using FreeBSD from 2000 to 2005 as my sole operating system at
the time (both on servers and workstations), from 4.1 to the end of the 4.x
series. I have fond memories of that period, and that’s probably the main
reason why I’ve been diving again into the BSDs during the last few years.</p>
</blockquote>
<p>I started using FreeBSD in September 2000 coming from Slackware Linux,
not knowing it would be the beginning of a more than 20-year journey.</p>
<p>At the time, I still didn't have broadband internet access so downloading
ISOs over a dial-up connection was not an option. I'm not exactly sure how
I got the <a rel="noopener" target="_blank" href="https://www.freebsd.org/releases/4.1R/announce/">FreeBSD 4.1</a> installation CD from, but I think I might have
ordered it from <a rel="noopener" target="_blank" href="https://web.archive.org/web/20001109120500/http://ikarios.com/form/#bsd">Ikarios</a>, a French distributor of Linux and BSD
distribution CDs.</p>
<p>Having spent a large part of the nineties immersed in text mode on MS-DOS,
mostly because of my involvement in the BBS and ANSI art scenes, it's
only natural that I kept the habit of using text consoles on Linux.
On the hardware I was using at the time, I was often hitting a random issue
causing the machine to become unusable when switching between text consoles
and the X server.</p>
<p>Switching back and forth between X and text consoles was such an important
use case for me at the time, that I was willing to try everything in order
to fix the problem. Luckily, FreeBSD didn't exhibit the issue, and as an
added benefit, the FreeBSD console could display ANSI art with <em>cat(1)</em>
in full glory out of the box. One could connect to telnet BBSes using the
system telnet client, and enjoy an MS-DOS like experience.</p>
<p>FreeBSD provided many other benefits, but most importantly a clean and
well integrated system. The quality of the documentation made things a lot
easier than in the Linux world. Configuring IPFW was a breeze compared to
what was available on Linux at the time. Being able to tweak and compile
kernels using a single text configuration file was also a powerful thing,
and I remember spending an unhealthy amount of time compiling the smallest
possible working kernels in order to save RAM and compile time.</p>
<p>FreeBSD also offered a great platform for C development, with quality manual
pages documenting the C library.</p>
<p>It thus won't come as a surprise that I learned a lot about UNIX systems
during that period. I also started contributing to the ports collection
(<a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/baf57e3382b63a31656f1de6844afaba5be1c014">babytrans</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/302c3bd32990a4006a52370149d091a1dfa26308">dtc</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/2c1676782f3825a08496b1a302f861ddfd2c28cf">gsfv</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/486a5d36cb11f558f319fe3d5f07a54a2f214922">huc</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/479a0785ef1500e7ffe454b4e6a7d39761c58ebf">multimail</a>,
<a rel="noopener" target="_blank" href="https://freshbsd.org/freebsd/ports/commit/aa51c6b92894d532fcf5472299efe5db0394eed9">tetradraw</a>), and even doing some evangelization on LinuxFR, a community
driven social news site for the releases of FreeBSD <a rel="noopener" target="_blank" href="https://linuxfr.org/news/sortie-de-freebsd-411">4.11</a> and <a rel="noopener" target="_blank" href="https://linuxfr.org/news/sortie-de-freebsd-60--2">6.0</a>.</p>
<p>Ultimately by 2005 software was getting larger, especially browsers so
compiling ports was not practical anymore and binary packages were still a
bit of a hit and miss on FreeBSD at this time. The FreeBSD 5.x series was
unfortunately plagued by unreliability issues, which prompted me to go explore
other shores.
My BSD story was to be continued a few years later anyway, little did I know
at the time...</p>
Toolchains adventures - Q3 20232023-09-29T15:35:00+00:002023-09-29T15:35:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q3-2023/<p>This is the eighth post in my toolchains adventures series. Please check
the previous posts in the <a rel="noopener" target="_blank" href="https://www.cambus.net/categories/toolchains/">toolchains</a> category for more context about
this journey. There was no Q2 2023 report as there wasn't really anything
worthwhile to write about.</p>
<p>In Pkgsrc land, I updated binutils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/2VUJaul8Sjn0GXyE">2.41</a> version, and mold to
the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/hEThY685zwgmjryE">2.0.0</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/LAKGtWH9koo2kUAE">2.1.0</a>, and <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/ez912PBJ3l4WZxGE">2.2.0</a> versions.
It's worth noting that Mold transitioned its license from <strong>AGPL</strong> to <strong>MIT</strong>
starting with the 2.0.0 release.</p>
<p>I also updated the NetBSD system call table in GDB to add the <em>memfd_create(2)</em>
and <em>epoll(2)</em> syscalls which were added in July.</p>
<p>Regarding OpenBSD, I updated binutils to version <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/ports/commit/eluRBtCgq3JHeGDm">2.41</a>, allowing us to
remove patches for <strong>ARM</strong> support as they had been pushed upstream.</p>
<p>During this release cycle, OpenBSD enabled <a rel="noopener" target="_blank" href="https://undeadly.org/cgi?action=article;sid=20230714121907">mandatory enforcement of indirect
branch targets</a> using Intel's <strong>IBT</strong> on OpenBSD/amd64 and ARM's <strong>BTI</strong>
on OpenBSD/arm64. I added support upstream for the <strong>PT_OPENBSD_NOBTCFI</strong>
segment type to <em>readelf</em> in GNU Binutils, as well as in LLVM versions of
<em>objdump</em> and <em>readobj</em>.</p>
<p>As usual, I’ve also been busy reading different material, and adding new
resources to <a rel="noopener" target="_blank" href="https://www.toolchains.net/">toolchains.net</a>.</p>
<p>binutils and GDB commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2023-09-28</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=73b22419edd563cf26bc8688c3f04fb3cf414cb0">73b2241</a></td><td>Add support to readelf for the PT_OPENBSD_NOBTCFI segment type</td></tr>
<tr><td>2023-09-21</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=9c1e3e42042643194bd53fd003b24098b7f65639">9c1e3e4</a></td><td>Update the NetBSD system call table to add memfd_create(2) and epoll(2)</td></tr>
</tbody></table>
<p>LLVM commits</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2023-09-25</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/e5038f0f34c93399ee99e31c739f9945cadf9b70">e5038f0</a></td><td>[llvm-readobj] Add support for the PT_OPENBSD_NOBTCFI segment type</td></tr>
<tr><td>2023-09-22</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/a921f2a3d721aac0814b6e319b81db1bc46cd3f8">a921f2a</a></td><td>[llvm-objdump] Add support for the PT_OPENBSD_NOBTCFI segment type</td></tr>
<tr><td>2023-09-21</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/ca3ed7b2a0fdea7349242c2b63fcb049fc4a2b14">ca3ed7b</a></td><td>[clang] Update Clang version from 17 to 18 in scan-build.1</td></tr>
</tbody></table>
Playing with Caml Light on DOS2023-09-27T13:54:00+00:002023-09-27T13:54:00+00:00Unknownhttps://www.cambus.net/playing-with-caml-light-on-dos/<p><strong>OCaml</strong> has been on my radar for some years now, and I think it was
<a rel="noopener" target="_blank" href="https://mirage.io">MirageOS</a> which sparked my interest in the language. Lately, I started
reading more about OCaml and its ecosystem, and indulged myself in an
historical detour.</p>
<p>For more background information on Caml and the <strong>Caml Light</strong> implementation
in particular, please refer to "<a rel="noopener" target="_blank" href="https://caml.inria.fr/about/history.en.html">A History of Caml</a>". Distribution
archives for Caml Light are available <a rel="noopener" target="_blank" href="https://caml.inria.fr/pub/distrib/Oldies/">here</a>.</p>
<p>The oldest DOS version available on Inria site is Caml Light 0.6, and I
was able to find Caml Light 0.5 on the <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Simtel">Simtel</a> archives. The recovered
files are available <a href="/files/caml/">here</a>, along with documentation for the 0.6 version.</p>
<p>Here is an ANSI logo tribute which was drawn especially for this post:</p>
<p><img src="/content/2023/09/caml-light.gif" alt="Caml Light" title="Caml Light" /></p>
<p>Caml Light is implemented as a <strong>bytecode compiler</strong> which made it highly
portable. It is possible to create executables using the <strong>CAMLC.EXE</strong> command,
but please be aware that the resulting binaries are not standalone when using
the default linking mode, and the runtime system (<strong>CAMLRUN.EXE</strong>) is required
to run them.</p>
<p>The latest available release of Caml Light for DOS is version 0.7 released
in 1995.</p>
<p>Compared with the UNIX version, one of the drawbacks is that it is not
possible to interface with C functions.
Another one is that we cannot use Ctrl+D to send the <em>EOT</em> character to quit
the REPL, one should type <em>quit();;</em> instead to invoke the quit system
function to get back to the DOS command interpreter.</p>
<p>On the plus side, the DOS version supports graphics primitives using the
<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Borland_Graphics_Interface">Borland Graphics Interface</a> <strong>CGA.BGI</strong> driver for CGA graphic cards, or
<strong>EGAVGA.BGI</strong> for EGA and VGA cards.</p>
<p>The development environment can be bootstrapped as follows:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>mkdir -p ~/dos/caml386
</span><span>cd ~/dos/caml386
</span><span>wget https://caml.inria.fr/pub/distrib/Oldies/cl7pcbin.zip
</span><span>unzip cl7pcbin.zip
</span></code></pre>
<p>When using <strong>FreeDOS</strong>, we need to add the following in <em>FDAUTO.BAT</em>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>set PATH=c:\caml386\bin;%PATH%
</span><span>set CAMLLIB=c:\caml386\lib
</span><span>set GO32TMP=c:\tmp
</span></code></pre>
<p>Alternatively, when using <strong>DOSBox</strong> instead, we need the following in
<em>dosbox.conf</em>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>[autoexec]
</span><span>mount c ~/dos
</span><span>path=c:\caml386\bin
</span><span>set CAMLLIB=c:\caml386\lib
</span><span>set GO32TMP=c:\tmp
</span><span>set GO32=driver c:\caml386\dev\vesa_s3.grd gw 800 gh 600
</span><span>c:
</span></code></pre>
<p>The last configuration line is optional and only required for using the
graphics primitives. DOSBox emulates an <strong>S3 Trio64</strong> by default, so we need
to use the <em>VESA_S3.GRD</em> driver.</p>
<p>Once we are done installing, this gives us Caml Light 0.7:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>camlc -v
</span><span>The Caml Light system for the 80386 PC, version 0.7
</span><span> (standard library from c:\caml386\lib)
</span><span>The Caml Light runtime system, version 0.7
</span><span>The Caml Light compiler, version 0.7
</span><span>The Caml Light linker, version 0.7
</span></code></pre>
<p>We can then start playing with the example programs bundled with the Caml
Light distribution.</p>
<p>This is a screenshot from the "Color Wheel" program:</p>
<p><img src="/content/2023/09/colwheel.png" alt="Caml Light - Color Wheel" title="Caml Light - Color Wheel" /></p>
<p>Another program showing graphics animation of sorting algorithms:</p>
<p><img src="/content/2023/09/showsort.png" alt="Caml Light - Showsort" title="Caml Light - Showsort" /></p>
<p>And finally the interactive "Spirals" program:</p>
<p><img src="/content/2023/09/spirals.png" alt="Caml Light - Spirals" title="Caml Light - Spirals" /></p>
<p>For the more adventurous reader, there also was a user contributed <a rel="noopener" target="_blank" href="https://caml.inria.fr/pub/distrib/Usercontribs/ocaml-1.00-msdos.exe">DOS port
of OCaml 1.00</a>. Have fun!</p>
OpenBSD/arm64 on Hetzner Cloud2023-09-20T08:58:00+00:002023-09-20T08:58:00+00:00Unknownhttps://www.cambus.net/openbsd-arm64-on-hetzner-cloud/<p>Hetzner introduced its <strong>Ampere Altra</strong> powered <a rel="noopener" target="_blank" href="https://www.hetzner.com/press-release/arm64-cloud">arm64-based cloud servers</a>
earlier this year, making it possible to easily run OpenBSD/arm64 on their
platform.</p>
<p>The only caveat for now is that the <a rel="noopener" target="_blank" href="https://www.undeadly.org/cgi?action=article;sid=20230421124221">viogpu(4) driver</a> is required, which
was committed by jcs@ in April 2023 and thus only available in snapshots.
It will first appear in OpenBSD 7.4.</p>
<p>Here is the relevant excerpt from the manual page:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>DESCRIPTION
</span><span> The viogpu driver provides support for the virtio(4) GPU interface
</span><span> provided by QEMU and other virtual machines to create a wscons(4)
</span><span> console.
</span></code></pre>
<p>To install the system, we need to provision a Linux instance to fetch
the installation media and write it to the root disk.</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>wget https://cdn.openbsd.org/pub/OpenBSD/snapshots/arm64/miniroot74.img
</span><span>dd if=miniroot74.img of=/dev/sda bs=4M
</span></code></pre>
<p>The installer will start after reboot, allowing us to perform an interactive
installation using the console.</p>
<p>I'm using the CAX11 instance providing 2 vCPUs and 4 GB of RAM.</p>
<p>Here is the result of a quick <strong>md5 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>MD5 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 52e5f9c9e6f656f3e1800dfa5579d089
</span><span>Time = 0.220000 seconds
</span><span>Speed = 454545454.545455 bytes/second
</span></code></pre>
<p>Here is the result of the <strong>sha1 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>SHA1 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 74a57b897cc581defa5b3a359fa762a1b83a60e8
</span><span>Time = 0.230000 seconds
</span><span>Speed = 434782608.695652 bytes/second
</span></code></pre>
<p>For the record, LibreSSL speed benchmark results are available <a href="/files/openbsd/openssl-speed-hetzner-cloud.txt">here</a>.</p>
<p>System message buffer (dmesg output):</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>OpenBSD 7.4-beta (GENERIC.MP) #2251: Tue Sep 19 12:41:16 MDT 2023
</span><span> deraadt@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
</span><span>real mem = 4185800704 (3991MB)
</span><span>avail mem = 3976454144 (3792MB)
</span><span>random: good seed from bootblocks
</span><span>mainbus0 at root: ACPI
</span><span>psci0 at mainbus0: PSCI 1.0, SMCCC 1.1
</span><span>efi0 at mainbus0: UEFI 2.7
</span><span>efi0: EDK II rev 0x10000
</span><span>smbios0 at efi0: SMBIOS 3.0.0
</span><span>smbios0: vendor Hetzner version "20171111" date 11/11/2017
</span><span>smbios0: Hetzner vServer
</span><span>cpu0 at mainbus0 mpidr 0: ARM Neoverse N1 r3p1
</span><span>cpu0: 64KB 64b/line 4-way L1 PIPT I-cache, 64KB 64b/line 4-way L1 D-cache
</span><span>cpu0: 1024KB 64b/line 8-way L2 cache
</span><span>cpu0: DP,RDM,Atomic,CRC32,SHA2,SHA1,AES+PMULL,LRCPC,DPB,ASID16,PAN+ATS1E1,LO,HPDS,VH,HAFDBS,CSV3,CSV2,SBSS+MSR
</span><span>cpu1 at mainbus0 mpidr 1: ARM Neoverse N1 r3p1
</span><span>cpu1: 64KB 64b/line 4-way L1 PIPT I-cache, 64KB 64b/line 4-way L1 D-cache
</span><span>cpu1: 1024KB 64b/line 8-way L2 cache
</span><span>cpu1: DP,RDM,Atomic,CRC32,SHA2,SHA1,AES+PMULL,LRCPC,DPB,ASID16,PAN+ATS1E1,LO,HPDS,VH,HAFDBS,CSV3,CSV2,SBSS+MSR
</span><span>apm0 at mainbus0
</span><span>agintc0 at mainbus0 shift 4:4 nirq 288 nredist 2 ipi: 0, 1, 2: "interrupt-controller"
</span><span>agintcmsi0 at agintc0
</span><span>agtimer0 at mainbus0: 25000 kHz
</span><span>acpi0 at mainbus0: ACPI 5.1
</span><span>acpi0: sleep states
</span><span>acpi0: tables DSDT FACP APIC PPTT GTDT MCFG SPCR DBG2 IORT BGRT
</span><span>acpi0: wakeup devices
</span><span>acpimcfg0 at acpi0
</span><span>acpimcfg0: addr 0x4010000000, bus 0-255
</span><span>acpiiort0 at acpi0
</span><span>"ACPI0007" at acpi0 not configured
</span><span>"ACPI0007" at acpi0 not configured
</span><span>pluart0 at acpi0 COM0 addr 0x9000000/0x1000 irq 33
</span><span>pluart0: console
</span><span>"QEMU0002" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>"LNRO0005" at acpi0 not configured
</span><span>acpipci0 at acpi0 PCI0
</span><span>pci0 at acpipci0
</span><span>0:4:0: io address conflict 0x8200/0x8
</span><span>"Red Hat Host" rev 0x00 at pci0 dev 0 function 0 not configured
</span><span>virtio0 at pci0 dev 1 function 0 "Qumranet Virtio 1.x GPU" rev 0x01
</span><span>viogpu0 at virtio0: 1024x768, 32bpp
</span><span>wsdisplay0 at viogpu0 mux 1: console (std, vt100 emulation)
</span><span>wsdisplay0: screen 1-5 added (std, vt100 emulation)
</span><span>virtio0: msix per-VQ
</span><span>ppb0 at pci0 dev 2 function 0 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci1 at ppb0 bus 1
</span><span>1:0:0: rom address conflict 0xfff80000/0x80000
</span><span>virtio1 at pci1 dev 0 function 0 "Qumranet Virtio 1.x Network" rev 0x01
</span><span>vio0 at virtio1: address 96:00:02:8c:5b:eb
</span><span>virtio1: msix per-VQ
</span><span>ppb1 at pci0 dev 2 function 1 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci2 at ppb1 bus 2
</span><span>xhci0 at pci2 dev 0 function 0 vendor "Red Hat", unknown product 0x000d rev 0x01: msix, xHCI 0.0
</span><span>usb0 at xhci0: USB revision 3.0
</span><span>uhub0 at usb0 configuration 1 interface 0 "Red Hat xHCI root hub" rev 3.00/1.00 addr 1
</span><span>ppb2 at pci0 dev 2 function 2 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci3 at ppb2 bus 3
</span><span>virtio2 at pci3 dev 0 function 0 "Qumranet Virtio 1.x Console" rev 0x01
</span><span>virtio2: no matching child driver; not configured
</span><span>ppb3 at pci0 dev 2 function 3 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci4 at ppb3 bus 4
</span><span>virtio3 at pci4 dev 0 function 0 vendor "Qumranet", unknown product 0x1045 rev 0x01
</span><span>viomb0 at virtio3
</span><span>virtio3: irq 37
</span><span>ppb4 at pci0 dev 2 function 4 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci5 at ppb4 bus 5
</span><span>virtio4 at pci5 dev 0 function 0 "Qumranet Virtio 1.x RNG" rev 0x01
</span><span>viornd0 at virtio4
</span><span>virtio4: irq 37
</span><span>ppb5 at pci0 dev 2 function 5 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci6 at ppb5 bus 6
</span><span>virtio5 at pci6 dev 0 function 0 "Qumranet Virtio 1.x SCSI" rev 0x01
</span><span>vioscsi0 at virtio5: qsize 256
</span><span>scsibus0 at vioscsi0: 255 targets
</span><span>cd0 at scsibus0 targ 0 lun 0: <QEMU, QEMU CD-ROM, 2.5+> removable
</span><span>sd0 at scsibus0 targ 0 lun 1: <QEMU, QEMU HARDDISK, 2.5+>
</span><span>sd0: 39064MB, 512 bytes/sector, 80003072 sectors, thin
</span><span>virtio5: msix per-VQ
</span><span>ppb6 at pci0 dev 2 function 6 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci7 at ppb6 bus 7
</span><span>ppb7 at pci0 dev 2 function 7 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 37
</span><span>pci8 at ppb7 bus 8
</span><span>ppb8 at pci0 dev 3 function 0 vendor "Red Hat", unknown product 0x000c rev 0x00: irq 38
</span><span>pci9 at ppb8 bus 9
</span><span>"Red Hat Qemu Serial" rev 0x01 at pci0 dev 4 function 0 not configured
</span><span>acpige0 at acpi0 irq 41
</span><span>acpibtn0 at acpi0: PWRB
</span><span>uhidev0 at uhub0 port 5 configuration 1 interface 0 "QEMU QEMU USB Tablet" rev 2.00/0.00 addr 2
</span><span>uhidev0: iclass 3/0
</span><span>ums0 at uhidev0: 3 buttons, Z dir
</span><span>wsmouse0 at ums0 mux 0
</span><span>uhidev1 at uhub0 port 6 configuration 1 interface 0 "QEMU QEMU USB Keyboard" rev 2.00/0.00 addr 3
</span><span>uhidev1: iclass 3/1
</span><span>ukbd0 at uhidev1: 8 variable keys, 6 key codes
</span><span>wskbd0 at ukbd0 mux 1
</span><span>wskbd0: connecting to wsdisplay0
</span><span>vscsi0 at root
</span><span>scsibus1 at vscsi0: 256 targets
</span><span>softraid0 at root
</span><span>scsibus2 at softraid0: 256 targets
</span><span>root on sd0a (8d3ced025e1dcf8f.a) swap on sd0b dump on sd0b
</span></code></pre>
On the importance of distfiles2023-09-17T23:22:00+00:002023-09-17T23:22:00+00:00Unknownhttps://www.cambus.net/on-the-importance-of-distfiles/<p>I've been involved with the OpenBSD ports collection since 2015, and have
accumulated some notes on the topic over the years. This is an attempt at
doing a redacted version, mostly for my personal use.
While some of these notes are specific to the OpenBSD Ports Collection,
most of them will also apply to the others BSDs and Linux distributions.</p>
<p>It will come at no surprise that distfiles are at the core of the problem
domain. The ports system fetches distribution files, most often tarballs,
verifies their checksum and starts building programs. In order to be
able to reliably build packages from the source tarballs, we need both
<strong>availability</strong> and <strong>integrity</strong>.</p>
<p>Because <strong>MASTER_SITES</strong> can be down, either temporarily or permanently,
each of the BSD maintains their own distfiles mirrors, or caches.</p>
<p>As a rule of thumb though, MASTER_SITES (or nowadays simply SITES) should
not be set to point to <em>ftp.openbsd.org</em>, mostly because there is sometimes
no guarantee that the files will be cached there forever, and also to avoid
putting unnecessary load on the server. To remedy this, some porters maintain
their own distfiles hosting sites.</p>
<p>For checking distfiles integrity, each BSD uses a different combination of
cryptographic hashes:</p>
<p>OpenBSD and FreeBSD both use <strong>SHA256</strong>, while NetBSD uses <strong>BLAKE2s</strong> and
<strong>SHA512</strong>. The hashes are stored in a file called <em>distinfo</em>.</p>
<p>Here is an example from OpenBSD's distinfo for binutils:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>SHA256 (binutils-2.41.tar.bz2) = pMS+wFL3uDcAJOYDieGUN38/SLVmGEGOpRBn9nqqsws=
</span><span>SIZE (binutils-2.41.tar.bz2) = 37132937
</span></code></pre>
<p>And another excerpt from NetBSD's Pkgsrc distinfo for binutils:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>BLAKE2s (binutils-2.41.tar.bz2) = bd20a803c6f86632b62e27fce2cb07eb0ee4aa06fb374d80c8ba235568466dd2
</span><span>SHA512 (binutils-2.41.tar.bz2) = 8c4303145262e84598d828e1a6465ddbf5a8ff757efe3fd981948854f32b311afe5b154be3966e50d85cf5d25217564c1f519d197165aac8e82efcadc9e1e47c
</span><span>Size (binutils-2.41.tar.bz2) = 37132937 bytes
</span></code></pre>
<p>Checksums can fail because there was a network failure while downloading
the source file, or because the file itself changed.</p>
<p>If the distfile changed, there can be several causes:</p>
<ul>
<li>The source archive has been replaced by a malicious one</li>
<li>Upstream re-rolled the tarball</li>
<li>Automatically generated tarballs are not immutable</li>
</ul>
<p>Re-rolling tarballs can happen for software which is not versioned, or
when upstream try to fix minor issues not long after a release, without
issuing a new one in order not to have to bump version numbers.</p>
<p>For the last possible cause, this has been a problem with GitHub auto
generated tarballs in the past. More information can be found in sthen@'s
"<a rel="noopener" target="_blank" href="https://marc.info/?l=openbsd-ports&m=151973450514279&w=2">Porters, please read re GitHub auto-generated tarballs vs releases</a>"
post on the ports mailing list back in 2018.</p>
<p>In January 2023, GitHub updated the Git version they are using on their
platform. Because Git switched to use their internal <em>gzip</em> implementation
for generating tarballs, this resulted in the generated tarballs having
different checksums. The <a rel="noopener" target="_blank" href="https://github.blog/changelog/2023-01-30-git-archive-checksums-may-change/">change</a> has quickly been reverted.</p>
<p>Each durable checksum failure will require maintainers to spend time
analyzing changes to ensure there has not been any malicious changes
happening.</p>
<p>Ideally, distfiles should be as small as possible to prevent wasting
bandwidth when fetching and CPU cycles when unpacking content. Unfortunately,
that's not always the case because some projects do vendor dependencies, and
everyone has to pay the cost.</p>
Spleen 2.0.0 released with full CP437 support2023-05-31T09:43:00+00:002023-05-31T09:43:00+00:00Unknownhttps://www.cambus.net/spleen-2.0.0-released-with-full-cp437-support/<p><a rel="noopener" target="_blank" href="https://github.com/fcambus/spleen">Spleen</a> 2.0.0 has been released, with full support for <a rel="noopener" target="_blank" href="https://www.ascii-codes.com">CP437 (IBM PC)</a>
encoding in the 8x16, 16x32, and 32x64 versions.</p>
<p>It required a large effort and represents 135 commits since Spleen 1.9.3
which resulted in almost 90 new characters in the previously mentioned sizes.</p>
<p>A lot has happened since the 1.0.0 release back in September 2018:</p>
<ul>
<li>It became the <a rel="noopener" target="_blank" href="https://undeadly.org/cgi?action=article;sid=20190110064857">default font for OpenBSD consoles</a> in January 2019</li>
<li>It was imported in the NetBSD src tree in March 2019</li>
<li>It was included in the FreeBSD base system in May 2023</li>
</ul>
<p>Spleen's README now has a <a rel="noopener" target="_blank" href="https://github.com/fcambus/spleen#trivia">trivia</a> section listing all the operating
systems and programs where the fonts have been embedded or bundled in.</p>
<p>But let's go back to the newly announced release and focus on the recently
introduced changes.</p>
<p>Here is a screenshot of the CP437 version of 16x32:</p>
<p><img src="/content/2023/05/spleen-16x32-ibm-cp437.png" alt="Spleen 16x32 - IBM CP437" /></p>
<p>This is an important milestone as it allows nice things like having a DOS
version of Spleen. It is implemented as a <a rel="noopener" target="_blank" href="https://github.com/fcambus/spleen/blob/master/dos/spleen.com">COM file</a> changing the font
to Spleen 8x16, and has been tested both in DOSBox and on FreeDOS.</p>
<p>Here is "L'Étranger" from Baudelaire using Spleen on an ASUS Eee PC running FreeDOS:</p>
<p><img src="/content/2023/05/spleen-eee-pc-freedos.jpg" alt="Spleen 8x16 - FreeDOS" /></p>
<p>On top on that, Spleen is now also available in <a rel="noopener" target="_blank" href="https://github.com/ansilove/libansilove">libansilove</a> since version
1.4.0 and in <a rel="noopener" target="_blank" href="https://www.ansilove.org/">Ansilove</a> since version 4.2.0, making it possible to render
ANSI art using a modern font.</p>
<p>And with this out of the way, I can now start working on the next Spleen
milestone, which I hope to be able to announce in a not so distant future...
Stay tuned!</p>
Fun with Kermit and ZMODEM over SSH2023-04-25T18:30:00+00:002023-04-25T18:30:00+00:00Unknownhttps://www.cambus.net/fun-with-kermit-and-zmodem-over-ssh/<p>In my "<a rel="noopener" target="_blank" href="https://www.cambus.net/capturing-text-screens-on-modern-operating-systems/">Capturing text screens on modern operating systems</a>" article
published back in 2013, I mentioned finding a very promising program called
<a rel="noopener" target="_blank" href="https://qodem.sourceforge.net">Qodem</a>. It has since reached maturity and version 1.0 was released in
2017. I have been enjoying it on a regular basis to reminisce about the
glorious days of using <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Terminate_(software)">Terminate</a> and <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Minicom">Minicom</a> in the nineties,
and even packaged it in both <strong>OpenBSD</strong> and <strong>NetBSD</strong>.</p>
<p>Qodem has built in support for SSH, and also lets you spawn a local shell
and SSH from there, which allows authentication using SSH keys.</p>
<p>For the purpose of this article, I used two Fedora machines and installed
the <em>ckermit</em> and <em>lrzsz</em> packages to handle the <strong>Kermit</strong> and <strong>ZMODEM</strong>
protocols respectively. There is a <em>qodem</em> package as well, but it only
bundles the X11 binary. I prefer to use the curses version, so I built it
from source.</p>
<p>And from there, let the fun begin:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C-Kermit 9.0.302 OPEN SOURCE:, 20 Aug 2011, for Linux (64-bit)
</span><span> Copyright (C) 1985, 2011,
</span><span> Trustees of Columbia University in the City of New York.
</span><span>Type ? or HELP for help.
</span><span>(/home/fcambus/) C-Kermit>send NetBSD-9.3-amd64.iso
</span><span>Return to your local Kermit and give a RECEIVE command.
</span><span>
</span><span>KERMIT READY TO SEND...
</span><span>9 S~/ @- SENT: [/home/fcambus/NetBSD-9.3-amd64.iso] To: [netbsd-9_3-amd64.iso] (OK)
</span><span>(/home/fcambus/) C-Kermit>
</span></code></pre>
<p>Here is our Kermit transfer in action:</p>
<p><img src="/content/2023/04/qodem-ssh-kermit.gif" alt="Qodem - File transfer using Kermit" title="Qodem - File transfer using Kermit" /></p>
<p>For transferring files using ZMODEM, we use <strong>sz</strong> from the <em>lrzsz</em> package:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>sz NetBSD-9.3-amd64.iso
</span></code></pre>
<p>And here is our ZMODEM transfer in action:</p>
<p><img src="/content/2023/04/qodem-ssh-zmodem.gif" alt="Qodem - File transfer using ZMODEM" title="Qodem - File transfer using ZMODEM" /></p>
<p>There is something quite special about seeing ZMODEM transfers reach speeds
close to 600 MBit/s. It's hard to explain.</p>
<p>For the record, I used the following script to take screenshots in burst mode
and then create an animated GIF:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span style="color:#f92672;">while </span><span>true</span><span style="color:#f92672;">; do
</span><span> gnome-screenshot</span><span style="font-style:italic;color:#fd971f;"> -w</span><span style="color:#f92672;">;
</span><span style="color:#f92672;">done
</span></code></pre>
<p>Lastly, if you enjoy watching those glorious progress bars, you might
also enjoy my "<a rel="noopener" target="_blank" href="https://www.cambus.net/file-transfers-via-the-parallel-port-on-dos-using-laplink/">File transfers via the parallel port on DOS using LapLink</a>"
post from last year, which served as the inspiration for this one.</p>
Toolchains adventures - Q1 20232023-03-31T18:17:00+00:002023-03-31T18:17:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q1-2023/<p>This is the seventh post in my toolchains adventures series. Please check
the previous posts in the <a rel="noopener" target="_blank" href="https://www.cambus.net/categories/toolchains/">toolchains</a> category for more context about
this journey. There was no Q4 2022 report as there wasn't really anything
worthwhile to write about, only some usual Pkgsrc and OpenBSD toolchains
related ports updates.</p>
<p>In Pkgsrc land, I updated binutils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/dN9V4mUrHJtW2y9E">2.40</a> version, mold to the
<a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/ivaZRYk0LoHV509E">1.9.0</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/IoMgZLpXsiHSkjaE">1.10.0</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/PPR6qELWZLG2qIaE">1.10.1</a>, and <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/cMGTIsiVQ2gTQuhE">1.11.0</a> versions, patchelf
to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/jsJ98FRLoGZhw69E">0.17.2</a> version, and finally pax-utils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/rQ2YR1F6eLsDNA8E">1.3.6</a> and
the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/TaiNkvpMLQ2BkmbE">1.3.7</a> ones. I also updated the NetBSD system call table in GDB
to add the eventfd(2) and timerfd(2) syscalls which were added back in 2021.</p>
<p>Regarding OpenBSD, I updated binutils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/ports/commit/ahb3gh2E3c0M6VbM">2.40</a> version and enabled
the build of <em>gas</em>, for which I also pushed support for ARM upstream. While
there, I added support upstream for the <strong>PT_OPENBSD_MUTABLE</strong> segment type
to <em>readelf</em>. Lastly, I packaged and <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/ports/commit/KYYIJZhH4gtbct2t">imported pax-utils</a> into the ports
collection.</p>
<p>In early February, I attended <strong>FOSDEM 2023</strong> in Brussels and had the
opportunity to attend some talks in the <a rel="noopener" target="_blank" href="https://fosdem.org/2023/schedule/track/llvm/">LLVM devroom</a> as well as some
toolchains related ones in the <a rel="noopener" target="_blank" href="https://fosdem.org/2023/schedule/track/risc_v/">RISC-V</a> and <a rel="noopener" target="_blank" href="https://fosdem.org/2023/schedule/track/binary_tools/">Binary Tools</a> devrooms.</p>
<p>Lately, I've been exploring using alternative linkers in Pkgsrc. By default,
the host system default linker will be used, which happens to be <strong>GNU ld</strong>
on NetBSD and most Linux distributions.</p>
<p>Thanks to work done by pho@ and the <a rel="noopener" target="_blank" href="https://mail-index.netbsd.org/tech-pkg/2022/01/19/msg025960.html">instructions</a> he posted on the
<strong>tech-pkg</strong> mailing list, it was already possible to use <strong>mold</strong> within
Pkgsrc, by adding these directives in the <em>etc/mk.conf</em> configuration file:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>LD</span><span style="color:#f92672;">= </span><span>/usr/pkg/bin/mold
</span><span>LDFLAGS</span><span style="color:#f92672;">+= </span><span>-Wl,-L/usr/lib
</span><span>CWRAPPERS_PREPEND.cc</span><span style="color:#f92672;">+= </span><span>-B/usr/pkg/libexec/mold
</span><span>CWRAPPERS_PREPEND.cxx</span><span style="color:#f92672;">+= </span><span>-B/usr/pkg/libexec/mold
</span></code></pre>
<p>I wanted to also try using <strong>LLD</strong> (the LLVM linker), and modified the
<a rel="noopener" target="_blank" href="https://pkgsrc.se/devel/lld">devel/lld</a> package to add a symlink in <em>${PREFIX}/libexec</em> so that it
can be used in Pkgsrc.</p>
<p>While mold can be used as a linker when using both GCC and Clang, for LLD
one must use Clang as a compiler, using the <em>PKGSRC_COMPILER</em> directive.
The reason for this is that LLD does not support the <em>-dc</em> and <em>-dp</em> options.</p>
<p>The following directives must be added in the <em>etc/mk.conf</em> configuration
file:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>PKGSRC_COMPILER</span><span style="color:#f92672;">= </span><span>clang
</span><span>
</span><span>LD</span><span style="color:#f92672;">= </span><span>/usr/pkg/bin/lld
</span><span>LDFLAGS</span><span style="color:#f92672;">+= </span><span>-Wl,-L/usr/lib
</span><span>CWRAPPERS_PREPEND.cc</span><span style="color:#f92672;">+= </span><span>-B/usr/pkg/libexec/lld
</span><span>CWRAPPERS_PREPEND.cxx</span><span style="color:#f92672;">+= </span><span>-B/usr/pkg/libexec/lld
</span></code></pre>
<p>Verifying that a binary was produced by mold or LLD can be done using
<em>readelf</em>.</p>
<p>On the mold binary linked with mold itself:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>readelf</span><span style="font-style:italic;color:#fd971f;"> -p</span><span> .comment mold
</span><span>
</span><span>String dump of section </span><span style="color:#e6db74;">'.comment'</span><span>:
</span><span> </span><span style="color:#66d9ef;">[</span><span> 0] mold 1.10.1 (compatible with GNU ld)
</span><span> </span><span style="color:#66d9ef;">[</span><span> 25] GCC: (NetBSD nb1 20220722) 10.4.0
</span><span> </span><span style="color:#66d9ef;">[</span><span> 47] GCC: (nb1 20220722) 10.4.0
</span></code></pre>
<p>And on the lld binary linked with LLD itself:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>readelf</span><span style="font-style:italic;color:#fd971f;"> -p</span><span> .comment lld
</span><span>
</span><span>String dump of section </span><span style="color:#e6db74;">'.comment'</span><span>:
</span><span> </span><span style="color:#66d9ef;">[</span><span> 0] clang version 15.0.7
</span><span> </span><span style="color:#66d9ef;">[</span><span> 16] Linker: LLD 15.0.7
</span><span> </span><span style="color:#66d9ef;">[</span><span> 29] GCC: (NetBSD nb1 20220722) 10.4.0
</span></code></pre>
<p>As usual, I’ve also been busy reading different material, and adding new
resources to <a rel="noopener" target="_blank" href="https://www.toolchains.net/">toolchains.net</a>.</p>
<p>That’s all for now, happy Spring 2023 everyone!</p>
<p>binutils and GDB commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2023-03-23</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=80251d4185048c6391b74abe96c754e8a536b35f">80251d4</a></td><td>Add support to readelf for the PT_OPENBSD_MUTABLE segment type</td></tr>
<tr><td>2023-03-17</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=152d9c48a29685752ce06a0248a3f0f490c5660a">152d9c4</a></td><td>Update the NetBSD system call table to add eventfd(2) and timerfd(2)</td></tr>
<tr><td>2023-01-20</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=2e175383bfe010c05c55fb19e29b5c0665229a9c">2e17538</a></td><td>Add OpenBSD ARM GAS support</td></tr>
</tbody></table>
<p>LLVM commits</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2023-03-19</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/8510cf9fc1a431b70737b2b046007d318c62b7a8">8510cf9</a></td><td>[compiler-rt] Add missing #else clause to fix the build on NetBSD</td></tr>
<tr><td>2023-03-16</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/245f26a430aa92050e2d1bf3ca7add76dcbe23c2">245f26a</a></td><td>[docs] Document "PGO" (Profile-Guided Optimization) in the lexicon</td></tr>
<tr><td>2023-03-15</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/d8df8710e127f8f8ff0714afdecba450ce591d9d">d8df871</a></td><td>[compiler-rt] Point UndefinedBehaviorSanitizer link to its own page</td></tr>
<tr><td>2023-02-10</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/5cec69bb43bc375dabe0d26e9a7aee1c71d00d3f">5cec69b</a></td><td>[clang] Update Clang version from 16 to 17 in scan-build.1</td></tr>
</tbody></table>
NetBSD ASCII flag for the bootloader2023-01-12T13:37:00+00:002023-01-12T13:37:00+00:00Unknownhttps://www.cambus.net/netbsd-ascii-flag-for-the-bootloader/<p>As mentioned in my "<a rel="noopener" target="_blank" href="https://www.cambus.net/customizing-netbsd-boot-banners/">Customizing NetBSD boot banners</a>" article, it's
really easy to customize NetBSD boot banners using the <a rel="noopener" target="_blank" href="https://man.netbsd.org/boot.cfg.5">boot.cfg</a>
configuration file.</p>
<p>In a previous life, I used to draw ASCII art (mostly in the pre-2000 era)
and more precisely a type of ASCII art referred as newschool ASCII in the
<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Computer_art_scene">artscene</a>. By taking advantage of the extended character set (the 128
to 255 range) of the IBM PC's <a rel="noopener" target="_blank" href="https://www.ascii-codes.com">code page 437</a>, it was possible to achieve
great detail and really smooth curves. Some examples can be found at the
bottom of my <a rel="noopener" target="_blank" href="https://cleaner.ansilove.org/gallery.html">online gallery</a>.</p>
<p>Attempting to draw the NetBSD flag in ASCII and use it when booting in
both <strong>NetBSD/i386</strong> and <strong>NetBSD/amd64</strong> in BIOS mode was thus too
tempting, so here we go.</p>
<p>The NetBSD flag in full glory, loaded in TheDraw:</p>
<p><img src="/content/2023/01/netbsd-ascii-flag.png" alt="NetBSD ASCII Flag" /></p>
<p>And here is a screenshot of the NetBSD x86 bootloader:</p>
<p><img src="/content/2023/01/netbsd-ascii-flag-bootloader.png" alt="NetBSD ASCII Flag in the bootloader" /></p>
<p>And this is how it could look like with colors and a customized VGA palette:</p>
<p><img src="/content/2023/01/netbsd-ascii-flag-bootloader-color.png" alt="NetBSD ASCII Flag in the bootloader" /></p>
<p>Unfortunately, the extended ASCII characters do not display correctly
when booting in EFI mode, at least on the machine I tested on, but I
suspect it will likely be the case on other implementations as well.</p>
<p>As specified in the <strong>Human Interface Infrastructure</strong> part (<a rel="noopener" target="_blank" href="https://uefi.org/specs/UEFI/2.10/33_Human_Interface_Infrastructure.html#limiting-glyphs">33.2.7.2</a>
subsection) of the <strong>UEFI</strong> specification, UEFI requires platform support
of a font containing the basic Latin character set. So extended ASCII
support is not mandatory, and there is no guarantee that the characters
would be the same between fonts used by different EFI firmwares anyway.</p>
<p>The <em>boot.cfg</em> configuration file can be downloaded <a rel="noopener" target="_blank" href="https://www.cambus.net/files/netbsd/boot.cfg">here</a>. Enjoy!</p>
Toolchains adventures - Q3 20222022-09-23T14:54:00+00:002022-09-23T14:54:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q3-2022/<p>This is the sixth post in my toolchains adventures series. Please check
the previous posts in the <a rel="noopener" target="_blank" href="https://www.cambus.net/categories/toolchains/">toolchains</a> category for more context about
this journey.</p>
<p>In Pkgsrc land, I updated binutils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/ngfw8TyP5LOAMNOD">2.39</a> version, mold to the
<a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/OnnOeG6M1ye8KmKD">1.3.1</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/37koLEgf4whfANOD">1.4.0</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/4devoGdZI3vC5tQD">1.4.1</a>, and <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/TsK7yjFsSDourySD">1.4.2</a> versions, patchelf to
the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/lkzJBxMLKw9nVMMD">0.15.0</a> one, and finally pax-utils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/lHoZp7wKwx3Jp4OD">1.3.5</a> one.</p>
<p>Regarding OpenBSD, we imported <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/src/commit/fjoGF4PMbyhAZgxr">llvm-profdata</a> into the base system in
early July, so I took the opportunity to <a rel="noopener" target="_blank" href="https://marc.info/?l=openbsd-tech&m=165913304219043&w=2">propose importing llvm-cov</a>
as well. This was accepted and is now <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/src/commit/zYBS8ROcqahl9Pfa">committed</a>, which will allow
producing reports from coverage data without having to install the
devel/llvm port.</p>
<p>I also submitted a <a rel="noopener" target="_blank" href="https://marc.info/?l=openbsd-ports&m=165928478832521&w=2">binutils port</a>, with the stated goal to have up to
date versions of the GNU binary utilities. As such it excludes <em>as</em> (for
which we have the devel/gas port) and <em>ld</em>. This is intended to replace the
aging versions we have in the base system (from binutils 2.17, released in
2006). All installed utilities have the 'g' prefix prepended to the binary
name.
After <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/ports/commit/pwvdVZ5a6j7kZHWy">importing</a> it, I noticed packages didn't build on OpenBSD/arm64
and OpenBSD/armv7, so I got the chance to send patches upstream to add
OpenBSD ARM and AArch64 Little Endian BFD support. While there, I also
added the required entry for AArch64 GAS support in upstream binutils.</p>
<p>In September, I got the opportunity to attend the <a rel="noopener" target="_blank" href="https://gcc.gnu.org/wiki/cauldron2022">GNU Tools Cauldron 2022</a>
conference which was held on September 16-18th 2022 in Prague, Czech
Republic. Three days of talks and discussions about the GNU toolchain,
in a friendly and relaxed atmosphere. There were a lot of interesting
talks and people, and being able to discuss such topics in person was a
nice change.</p>
<p>That's all for now... Stay tuned!</p>
<p>binutils commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2022-09-02</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=d0a122d31107cfe645466e9b20b3fe3ba2439011">d0a122d</a></td><td>Add OpenBSD ARM Little Endian BFD support</td></tr>
<tr><td>2022-08-31</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=6472b2302de5cd8753be629f58c8ce880d0c2e32">6472b23</a></td><td>Add OpenBSD AArch64 GAS support</td></tr>
<tr><td>2022-08-22</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=ba86e7501391c1eef4efa8201f39abf127e1084b">ba86e75</a></td><td>Add OpenBSD AArch64 Little Endian BFD support</td></tr>
</tbody></table>
<p>LLVM commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2022-08-01</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/892e6e2200d90e1b3140dc7feda6f46318688441">892e6e2</a></td><td>[clang] Update Clang version from 15 to 16 in scan-build.1</td></tr>
</tbody></table>
Toolchains adventures - Q2 20222022-06-30T10:54:00+00:002022-06-30T10:54:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q2-2022/<p>This is the fifth post in my toolchains adventures series. Please check
the previous posts in the <a rel="noopener" target="_blank" href="https://www.cambus.net/categories/toolchains/">toolchains</a> category for more context about
this journey.</p>
<p>In Pkgsrc land, I updated mold to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/FSZoy5Z3mdMmDjAD">1.2</a>, <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/1cAXEc80W80QW3CD">1.2.1</a>, and <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/Iegiqqk02trIRwID">1.3</a>
versions, and pax-utils to the <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/wcgzZiFbBhdkcABD">1.3.4</a> one.
I also added a z3 option to our <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/xP1pGKheDOhqSCHD">llvm</a> and <a rel="noopener" target="_blank" href="https://freshbsd.org/netbsd/pkgsrc/commit/Ur5ax14JahyeTCHD">clang</a> packages to allow
building them against the <a rel="noopener" target="_blank" href="https://github.com/Z3Prover/z3">Z3 theorem prover</a>. When both <a rel="noopener" target="_blank" href="https://pkgsrc.se/lang/llvm">lang/llvm</a>
and <a rel="noopener" target="_blank" href="https://pkgsrc.se/lang/clang">lang/clang</a> are built with the z3 option enabled, the Z3 constraint
solver is activated for the Clang static analyzer. This option is not
enabled by default. I wrote a blog post showing <a rel="noopener" target="_blank" href="https://www.cambus.net/clang-static-analyzer-and-the-z3-constraint-solver/">how to use Z3</a> as an
external solver and to do refutation to filter out false positives.</p>
<p>While I mention static analysis, I've been extremely impressed with the
progress of the <a rel="noopener" target="_blank" href="https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc/Static-Analyzer-Options.html">GCC's static analysis</a> framework. It was introduced in
GCC 10, and a major rewrite occurred in GCC 11. It now generates significantly
less false positives, and found some valid memory leaks on error paths in
<a rel="noopener" target="_blank" href="https://github.com/ansilove/libansilove/releases/tag/1.3.0">libansilove 1.30</a>, which the Clang static analyzer didn't catch.</p>
<p>Regarding the NetBSD base system, I started evaluating what it would take
to upstream our local binutils patches. The version we have in NetBSD's src
repository is <a rel="noopener" target="_blank" href="https://lists.gnu.org/archive/html/info-gnu/2020-02/msg00000.html">binutils 2.34</a> (released in February 2020), and diffing
our tree with the release tarball results in a 4310 lines diff, touching
163 files with 1404 insertions and 186 deletions.</p>
<p>For each of these changes, we need to dig into version control history to
find why they were needed in the first place, verify if they are still
needed, and if so potentially rework them to meet upstream coding standards.
This requires an understanding of the problem domain to be able to explain
the rationale behind the changes while submitting patches and writing
relevant commit messages.</p>
<p>While some of those patches are NetBSD specific, we still need to ensure
we are not breaking other operating systems. Ultimately, vanilla binutils
should be able to produce working binaries on NetBSD without requiring any
local patches. Once this goal is reached, we need to ensure it keeps
building, investigate test suite failures, and setup buildbots for
continuous builds on key architectures.</p>
<p>On the LLVM side, I managed to do a couple of commits as well to add
<code>libclang_rt.profile{{.*}}.a</code> tests for both OpenBSD and NetBSD in the
Clang driver test suite.</p>
<p>Lastly, I also wrote a couple of blog posts about various topics:</p>
<ul>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/assembly-instructions-distribution/">Assembly instructions distribution</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/differences-between-base-and-ports-llvm-in-openbsd/">Differences between base and ports LLVM in OpenBSD</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/clang-static-analyzer-and-the-z3-constraint-solver/">Clang Static Analyzer and the Z3 constraint solver</a></li>
</ul>
<p>That's all for now, happy Summer 2022 everyone!</p>
<p>LLVM commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2022-06-27</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/aa89bb3435e0abe6e80eac9d1ac43aaf5e04d1c8">aa89bb3</a></td><td>[Driver][test] Add libclang_rt.profile{{.*}}.a tests for NetBSD</td></tr>
<tr><td>2022-06-26</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/2ff4fb6573c111265a9d4d445f5cf43b659e71eb">2ff4fb6</a></td><td>[Driver][test] Add libclang_rt.profile{{.*}}.a tests for OpenBSD</td></tr>
<tr><td>2022-06-24</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/a129a371610dc342402dcdd122330369b25ff247">a129a37</a></td><td>[clang] Update Clang version from 14 to 15 in scan-build.1</td></tr>
</tbody></table>
Clang Static Analyzer and the Z3 constraint solver2022-06-21T23:12:00+00:002022-06-21T23:12:00+00:00Unknownhttps://www.cambus.net/clang-static-analyzer-and-the-z3-constraint-solver/<p>As far as static analyzers are concerned, one of the most important point
to consider is filtering out false positives as much as possible, in order
for the reports to be actionable.</p>
<p>This is an area on which <strong>Coverity</strong> did an excellent job, and likely a
major reason why they got so popular within the open source community,
despite being a closed-source product.</p>
<p>LLVM has the <strong>LLVM_ENABLE_Z3_SOLVER</strong> build option, which allows building
LLVM against the <a rel="noopener" target="_blank" href="https://github.com/Z3Prover/z3">Z3 constraint solver</a>.</p>
<p>It is documented as follow:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>LLVM_ENABLE_Z3_SOLVER:BOOL
</span><span> If enabled, the Z3 constraint solver is activated for the Clang static analyzer.
</span><span> A recent version of the z3 library needs to be available on the system.
</span></code></pre>
<p>The option is enabled in the Debian 11 package (clang-tools-11), but not
in Fedora 36 or Ubuntu 22.04 ones. I added a build option (not enabled by
default) to the <a rel="noopener" target="_blank" href="https://pkgsrc.se/lang/llvm">llvm</a> and <a rel="noopener" target="_blank" href="https://pkgsrc.se/lang/clang">clang</a> packages in Pkgsrc, and successfully
built Z3 enabled packages on NetBSD.</p>
<p>For Pkgsrc users, add the following in <em>mk.conf</em>, and build <strong>lang/clang</strong>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>PKG_OPTIONS.llvm= z3
</span><span>PKG_OPTIONS.clang= z3
</span></code></pre>
<p>There are two ways of using Z3 with the Clang Static Analyzer, and to
demonstrate them, let's reuse the small demo snippet from the <a rel="noopener" target="_blank" href="https://arxiv.org/abs/1810.12041">SMT-Based
Refutation of Spurious Bug Reports in the Clang Static Analyzer</a> paper.</p>
<pre data-lang="c" style="background-color:#272822;color:#f8f8f2;" class="language-c "><code class="language-c" data-lang="c"><span style="font-style:italic;color:#66d9ef;">unsigned int </span><span style="color:#a6e22e;">func</span><span>(</span><span style="font-style:italic;color:#66d9ef;">unsigned int </span><span style="font-style:italic;color:#fd971f;">a</span><span>) {
</span><span> </span><span style="font-style:italic;color:#66d9ef;">unsigned int </span><span style="color:#f92672;">*</span><span>z </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">0</span><span>;
</span><span>
</span><span> </span><span style="color:#f92672;">if </span><span>((a </span><span style="color:#f92672;">& </span><span style="color:#ae81ff;">1</span><span>) </span><span style="color:#f92672;">&& </span><span>((a </span><span style="color:#f92672;">& </span><span style="color:#ae81ff;">1</span><span>) </span><span style="color:#f92672;">^</span><span style="color:#ae81ff;">1</span><span>))
</span><span> </span><span style="color:#f92672;">return *</span><span>z; </span><span style="color:#75715e;">// unreachable
</span><span>
</span><span> </span><span style="color:#f92672;">return </span><span style="color:#ae81ff;">0</span><span>;
</span><span>}
</span></code></pre>
<p>For each method, we can use Clang directly on a given translation
unit or use <strong>scan-build</strong>.</p>
<p>The first way is using Z3 as an external constraint solver:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ clang --analyze -Xanalyzer -analyzer-constraints=z3 main.c
</span><span>
</span><span>$ scan-build -constraints z3 clang -c main.c
</span><span>scan-build: Using '/usr/lib/llvm-11/bin/clang' for static analysis
</span><span>scan-build: Analysis run complete.
</span><span>scan-build: Removing directory '/tmp/scan-build-2022-06-21-171854-18215-1' because it contains no reports.
</span><span>scan-build: No bugs found.
</span></code></pre>
<p>This is a lot slower than the default, and the <a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/714b50eb2df5c3b8391a82418352764c32c1d258">commit</a> which documented
the feature mentions a ~15x slowdown over the built-in constraint solver.</p>
<p>The second way is using the default range based solver but having Z3 do
refutation to filter out false positives, which is a lot faster:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ clang --analyze -Xanalyzer -analyzer-config -Xanalyzer crosscheck-with-z3=true main.c
</span><span>
</span><span>$ scan-build -analyzer-config crosscheck-with-z3=true clang -c main.c
</span><span>scan-build: Using '/usr/lib/llvm-11/bin/clang' for static analysis
</span><span>scan-build: Analysis run complete.
</span><span>scan-build: Removing directory '/tmp/scan-build-2022-06-21-171924-18226-1' because it contains no reports.
</span><span>scan-build: No bugs found.
</span></code></pre>
<p>Again, no bugs found. How boring.</p>
<p>We can verify what happens if we run the analyzer without involving Z3 at all:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ clang --analyze main.c
</span><span>main.c:5:9: warning: Dereference of null pointer (loaded from variable 'z') [core.NullDereference]
</span><span> return *z; // unreachable
</span><span> ^~
</span><span>1 warning generated.
</span></code></pre>
<p>We get a false positive, because the default constraint solver cannot
reason about bitwise operations (among other things), and report an
unreachable NULL pointer dereference.</p>
Differences between base and ports LLVM in OpenBSD2022-06-20T14:50:00+00:002022-06-20T14:50:00+00:00Unknownhttps://www.cambus.net/differences-between-base-and-ports-llvm-in-openbsd/<p>LLVM was <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/ports/commit/8341693aaf9f5ca9351dd990e7aad1f1bc3783db4cf989c705f3213c3aeb27de">imported</a> in the OpenBSD ports tree back in 2008, and happily
lived there for a long while before being imported in the source tree
at the g2k16 hackathon in 2016. I previously wrote about this in
"<a rel="noopener" target="_blank" href="https://www.cambus.net/the-state-of-toolchains-in-openbsd/">The state of toolchains in OpenBSD</a>" last year.</p>
<p>As mentioned in my previous article, we do not use upstream build system
to build <strong>LLVM</strong> in the base system, but hand-written BSD Makefiles.
Importing CMake into the base system was not an option, because of
the size of the project and the large dependency chain it requires
for building. As a drawback, the build is slower than it could be, were
we able to take advantage of a more modern build system.</p>
<p>Nowadays, <strong>Clang</strong> is the default compiler on the amd64, arm64, armv7,
i386, macppc, octeon, powerpc64, and riscv64 platforms. It is also available
in the sparc64 base system.</p>
<p>But then, why do we still need LLVM in the ports tree? As an aside, for those
wondering why we need a compiler in the base system in the first place, Julio
Merino wrote about this in his "<a rel="noopener" target="_blank" href="https://jmmv.dev/2015/10/compilers-in-the-bsd-base-system.html">Compilers in the (BSD) base system</a>" post.</p>
<p>In the OpenBSD base system, we only build LLVM backends for a given
architecture, so on amd64 and i386 we build LLVM's <strong>X86 backend</strong>.
The mapping we do between OpenBSD's <strong>MACHINE_ARCH</strong> and <strong>LLVM_ARCH</strong> values
can be found in <a rel="noopener" target="_blank" href="https://github.com/openbsd/src/blob/master/gnu/usr.bin/clang/Makefile.arch">gnu/usr.bin/clang/Makefile.arch</a>.</p>
<p>Note that we also build the AMDGPU backend on platforms requiring it.</p>
<p>On an amd64 machine, the registered targets for the base compiler are:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ clang --print-targets
</span><span> Registered Targets:
</span><span> amdgcn - AMD GCN GPUs
</span><span> r600 - AMD GPUs HD2XXX-HD6XXX
</span><span> x86 - 32-bit X86: Pentium-Pro and above
</span><span> x86-64 - 64-bit X86: EM64T and AMD64
</span></code></pre>
<p>And the ones for Clang installed from ports are:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ clang-13 --print-targets
</span><span> Registered Targets:
</span><span> aarch64 - AArch64 (little endian)
</span><span> aarch64_32 - AArch64 (little endian ILP32)
</span><span> aarch64_be - AArch64 (big endian)
</span><span> amdgcn - AMD GCN GPUs
</span><span> arm - ARM
</span><span> arm64 - ARM64 (little endian)
</span><span> arm64_32 - ARM64 (little endian ILP32)
</span><span> armeb - ARM (big endian)
</span><span> avr - Atmel AVR Microcontroller
</span><span> bpf - BPF (host endian)
</span><span> bpfeb - BPF (big endian)
</span><span> bpfel - BPF (little endian)
</span><span> hexagon - Hexagon
</span><span> lanai - Lanai
</span><span> mips - MIPS (32-bit big endian)
</span><span> mips64 - MIPS (64-bit big endian)
</span><span> mips64el - MIPS (64-bit little endian)
</span><span> mipsel - MIPS (32-bit little endian)
</span><span> msp430 - MSP430 [experimental]
</span><span> nvptx - NVIDIA PTX 32-bit
</span><span> nvptx64 - NVIDIA PTX 64-bit
</span><span> ppc32 - PowerPC 32
</span><span> ppc32le - PowerPC 32 LE
</span><span> ppc64 - PowerPC 64
</span><span> ppc64le - PowerPC 64 LE
</span><span> r600 - AMD GPUs HD2XXX-HD6XXX
</span><span> riscv32 - 32-bit RISC-V
</span><span> riscv64 - 64-bit RISC-V
</span><span> sparc - Sparc
</span><span> sparcel - Sparc LE
</span><span> sparcv9 - Sparc V9
</span><span> systemz - SystemZ
</span><span> thumb - Thumb
</span><span> thumbeb - Thumb (big endian)
</span><span> wasm32 - WebAssembly 32-bit
</span><span> wasm64 - WebAssembly 64-bit
</span><span> x86 - 32-bit X86: Pentium-Pro and above
</span><span> x86-64 - 64-bit X86: EM64T and AMD64
</span><span> xcore - XCore
</span></code></pre>
<p>The <strong>devel/llvm</strong> port is built using CMake and Ninja, resulting in more
efficient builds. On top of building all available LLVM backends, we
also build:</p>
<ul>
<li>The <strong>Clang Static Analyzer</strong> and its companion tool scan-build</li>
<li><strong>Clang utilities</strong> (clang-format and clang-* tools)</li>
<li><strong>LLVM utilities</strong> (LLVM binary utilities: llvm-ar, llvm-as, llvm-objcopy,
llvm-objdump, etc.)</li>
<li>Tools to process code coverage data (llvm-profdata and llvm-cov)</li>
<li>Various other tools such as llc, lli, llvm-mc, llvm-mca, etc.</li>
</ul>
<p>So in essence, we try to keep the base system LLVM somewhat minimal,
and build additional features and tooling in the port version. This
solution has worked well for us so far.</p>
<p>One last thing to note, we only build one version of LLVM in ports, which
is kept in sync with the base version, so we do not ship packages for older
(or newer) versions of LLVM.</p>
Assembly instructions distribution2022-06-13T17:44:00+00:002022-06-13T17:44:00+00:00Unknownhttps://www.cambus.net/assembly-instructions-distribution/<p>In my article about running <a rel="noopener" target="_blank" href="https://www.cambus.net/freebsd-on-the-vortex86dx-cpu/">FreeBSD on the Vortex86DX CPU</a>, I mentioned
using <strong>objdump</strong> to disassemble kernels in order to check whether they were
using CMOV instructions or not.</p>
<p>One thing leading to another, I thought it would be fun to calculate the
<strong>distribution of assembly instructions</strong> in <strong>ELF binaries</strong>. It turns out
it can be done rather easily with a bit of Shell foo.</p>
<p>For the purpose of this article, I used <strong>SQLite</strong> 3.38.5 (2022-05-06) built
with <strong>GCC 12.1.1</strong> on Fedora 36 using the default optimization level (-O2)
as a target binary to test instructions distribution against. It is a
self-contained, full-featured SQL database engine as a single binary, making
it an excellent choice for our experiment.</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>$ gcc</span><span style="font-style:italic;color:#fd971f;"> --version
</span><span>gcc (GCC) 12.1.1 20220507 (Red Hat 12.1.1-1)
</span><span>Copyright (C) 2022 Free Software Foundation, Inc.
</span><span>This is free software</span><span style="color:#f92672;">; </span><span>see the source for copying conditions. There is NO
</span><span>warranty</span><span style="color:#f92672;">; </span><span>not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</span></code></pre>
<p>For the record, the example below is using <em>objdump</em> 2.37 from <strong>GNU binutils</strong>
on a Linux system.</p>
<p>The naive solution:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>objdump</span><span style="font-style:italic;color:#fd971f;"> -dj</span><span> .text</span><span style="font-style:italic;color:#fd971f;"> --no-show-raw-insn --no-addresses</span><span> sqlite3 </span><span style="color:#f92672;">| </span><span>\
</span><span> grep </span><span style="color:#e6db74;">$'^</span><span style="color:#ae81ff;">\t</span><span style="color:#e6db74;">' </span><span style="color:#f92672;">| </span><span>awk</span><span style="font-style:italic;color:#fd971f;"> -F </span><span style="color:#e6db74;">'\t'</span><span style="font-style:italic;color:#fd971f;"> -F </span><span style="color:#e6db74;">' ' '{ print $1 }' </span><span style="color:#f92672;">| </span><span>\
</span><span> sort </span><span style="color:#f92672;">| </span><span>uniq</span><span style="font-style:italic;color:#fd971f;"> -c </span><span style="color:#f92672;">| </span><span>sort</span><span style="font-style:italic;color:#fd971f;"> -nr
</span></code></pre>
<p>There is a problem with this approach however, it doesn't differentiate
between instructions and prefixes, so for prefixed instructions, we only
account for the prefixes and discard the actual instructions. Given the
choice between adding more Shell hackery and reaching out for a proper
instruction decoder, I opted for the later.</p>
<p>I already knew about <a rel="noopener" target="_blank" href="https://www.capstone-engine.org">Capstone</a> so this is the one I decided to use.
It is widely packaged, supports multiple architectures, and also has
<a rel="noopener" target="_blank" href="https://www.capstone-engine.org/lang_python.html">Python bindings</a> which makes it an extremely convenient option. As a
word of caution, the reader should be aware that if we compare the results
provided by different tools, we will notice divergences.
Distinct disassemblers decode instructions differently, and this is
exacerbated on <strong>x86-64</strong> due to the complexity of the instruction decoder.
Hardware decoders should be considered the only source of truth.</p>
<p>Here is a small Python snippet using Capstone 4.0.2 to print one instruction
per line:</p>
<pre data-lang="python" style="background-color:#272822;color:#f8f8f2;" class="language-python "><code class="language-python" data-lang="python"><span style="color:#75715e;">#!/usr/bin/env python3
</span><span style="color:#f92672;">import </span><span>sys
</span><span style="color:#f92672;">from </span><span>capstone </span><span style="color:#f92672;">import </span><span style="color:#ae81ff;">*
</span><span>
</span><span style="color:#f92672;">with </span><span style="color:#66d9ef;">open</span><span>(sys.argv[</span><span style="color:#ae81ff;">1</span><span>],</span><span style="color:#e6db74;">'rb'</span><span>) </span><span style="color:#f92672;">as </span><span>file:
</span><span> text </span><span style="color:#f92672;">= </span><span>file.read()
</span><span>
</span><span> md </span><span style="color:#f92672;">= </span><span>Cs(CS_ARCH_X86, CS_MODE_64)
</span><span> </span><span style="color:#f92672;">for </span><span>insn </span><span style="color:#f92672;">in </span><span>md.disasm(text, </span><span style="color:#ae81ff;">0x0</span><span>):
</span><span> </span><span style="color:#66d9ef;">print</span><span>(</span><span style="color:#e6db74;">"</span><span style="color:#ae81ff;">%s</span><span style="color:#e6db74;">" </span><span style="color:#f92672;">%</span><span>(insn.mnemonic.split().pop()))
</span></code></pre>
<p>As previously when we used <em>objdump</em>, we are only interested by the <strong>.text
section</strong>, so we need to extract it from the binary using <em>objcopy</em>:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>objcopy</span><span style="font-style:italic;color:#fd971f;"> --dump-section</span><span> .text=sqlite3.text sqlite3
</span></code></pre>
<p>We can then use the Python program we created to compute our distribution:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>./insn.py sqlite3.text </span><span style="color:#f92672;">| </span><span>sort </span><span style="color:#f92672;">| </span><span>uniq</span><span style="font-style:italic;color:#fd971f;"> -c </span><span style="color:#f92672;">| </span><span>sort</span><span style="font-style:italic;color:#fd971f;"> -nr
</span></code></pre>
<p>Here are the first 10 lines of results, showing the most used instructions:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span> 106158 mov
</span><span> 19462 test
</span><span> 17918 call
</span><span> 15866 je
</span><span> 15566 cmp
</span><span> 13276 jmp
</span><span> 12720 nop
</span><span> 12072 jne
</span><span> 11629 pop
</span><span> 10873 xor
</span></code></pre>
<p>The full set of results is available for download <a href="/files/asm/data/instructions.csv">here</a> in CSV format.</p>
<p>Here is a visualization of the 50 most used instructions using logarithmic
scale:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="instructions"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('instructions').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['mov', 'test', 'call', 'je', 'cmp', 'jmp', 'nop', 'jne', 'pop', 'xor', 'add', 'lea', 'push', 'movzx', 'sub', 'movsxd', 'ret', 'and', 'jle', 'shl', 'or', 'jg', 'movups', 'movaps', 'movsx', 'pxor', 'ja', 'shr', 'js', 'jbe', 'jae', 'cdqe', 'jb', 'imul', 'jge', 'movq', 'sete', 'movsd', 'jl', 'cmove', 'sar', 'movabs', 'setne', 'movdqu', 'bswap', 'jns', 'movd', 'cmovne', 'not', 'movdqa'],
datasets: [{
label: 'Assembly instructions',
data: [106158, 19462, 17918, 15866, 15566, 13276, 12720, 12072, 11629, 10873, 10015, 9861, 7578, 6176, 4719, 3662, 3322, 2490, 2036, 1721, 1538, 1068, 935, 831, 769, 643, 603, 586, 583, 510, 484, 452, 424, 371, 364, 354, 339, 331, 330, 316, 311, 301, 283, 265, 235, 233, 228, 198, 188, 188],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>While being able to visualize the number of occurrences for every
instruction is valuable, the produced charts are a bit noisy if we want
to include the whole set. We can remedy this by grouping instructions by
categories.</p>
<p>Here is another chart, showing instructions grouped by category:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="categories"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('categories').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['Data Transfer Instructions', 'Control Transfer Instructions', 'Binary Arithmetic Instructions', 'Miscellaneous Instructions', 'Bit and Byte Instructions', 'Logical Instructions', 'Shift and Rotate Instructions', 'SSE Data Transfer Instructions', 'MMX Logical Instructions', 'MMX Data Transfer Instructions', 'SSE2 128-Bit SIMD Integer Instructions', 'SSE2 Data Movement Instructions', 'SSE2 Conversion Instructions', 'SSE2 Packed Arithmetic Instructions', 'String Instructions', 'x87 FPU Data Transfer Instructions', 'SSE2 Compare Instructions', 'MMX Conversion Instructions', 'SSE2 Logical Instructions', 'x87 FPU Basic Arithmetic Instructions', 'MMX Packed Arithmetic Instructions', 'SSE Packed Arithmetic Instructions', 'x87 FPU Comparison Instructions', 'SSE Comparison Instructions', 'SSE2 Shuffle and Unpack Instructions', 'SSE Shuffle and Unpack Instructions', 'x87 FPU Load Constants Instructions', 'x87 FPU Control Instructions', 'SSE 64-Bit SIMD Integer Instructions', 'Control Transfer Terminating Instructions', 'MMX Comparison Instructions', 'SSE Conversion Instructions', 'SSE Logical Instructions', 'System Instructions'],
datasets: [{
label: 'Assembly instructions grouped by category',
data: [138114, 69122, 31092, 22615, 20318, 15089, 2821, 1932, 647, 582, 542, 391, 255, 174, 154, 149, 123, 73, 26, 26, 22, 22, 22, 19, 19, 11, 7, 6, 5, 4, 1, 1, 1, 1],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>The dataset with instructions grouped by categories is available for download <a href="/files/asm/data/categories.csv">here</a> in CSV format.</p>
<p>So what can we take away from these numbers? MOV is by far the most used
instruction, and grouping by category also shows that the top contenders
are data transfer instructions. Not surprising, and this is why data
locality is so important for performance.</p>
<p>We can also notice that by default, GCC doesn't take advantage of modern
CPUs features like SSE3, SSE4, and AVX instructions.</p>
<p>GCC 11 and Clang 12 introduced support for <strong>x86-64 micro-architecture
levels</strong> as documented <a rel="noopener" target="_blank" href="https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html">here</a> and <a rel="noopener" target="_blank" href="https://clang.llvm.org/docs/UsersManual.html#x86">here</a> respectively for each compiler.
This was first <a rel="noopener" target="_blank" href="https://sourceware.org/pipermail/libc-alpha/2020-July/116135.html">discussed in 2020</a> and is now part of the <a rel="noopener" target="_blank" href="https://gitlab.com/x86-psABIs/x86-64-ABI/-/commit/77566eb03bc6a326811cb7e9">x86-64 psABI</a>.
Each micro-architecture level can be enabled by setting the march flag
to one of the following values:</p>
<ul>
<li><strong>x86-64</strong>: CMOV, CMPXCHG8B, FPU, FXSR, MMX, FXSR, SCE, SSE, SSE2</li>
<li><strong>x86-64-v2</strong>: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3</li>
<li><strong>x86-64-v3</strong>: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE</li>
<li><strong>x86-64-v4</strong>: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL</li>
</ul>
<p>When building with <strong>x86-64-v2</strong>, here are the 50 most used instructions:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="instructions-x86-64-v2"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('instructions-x86-64-v2').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['mov', 'test', 'call', 'je', 'cmp', 'jmp', 'nop', 'jne', 'pop', 'xor', 'add', 'lea', 'push', 'movzx', 'sub', 'movsxd', 'ret', 'and', 'jle', 'shl', 'or', 'jg', 'movups', 'movaps', 'movsx', 'pxor', 'ja', 'shr', 'js', 'jbe', 'jae', 'cdqe', 'jb', 'imul', 'jge', 'sete', 'movq', 'jl', 'movsd', 'cmove', 'sar', 'movabs', 'setne', 'movdqu', 'jns', 'movd', 'bswap', 'movdqa', 'cmovne', 'not'],
datasets: [{
label: 'Assembly instructions',
data: [106134, 19454, 17918, 15866, 15551, 13278, 12732, 12071, 11621, 10862, 10016, 9855, 7573, 6164, 4718, 3656, 3322, 2490, 2037, 1722, 1536, 1068, 938, 837, 769, 651, 602, 586, 583, 506, 484, 448, 424, 370, 363, 339, 333, 330, 322, 316, 311, 301, 283, 265, 233, 227, 217, 213, 198, 188],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>And here are instructions grouped by category:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="categories-x86-64-v2"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('categories-x86-64-v2').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['Data Transfer Instructions', 'Control Transfer Instructions', 'Binary Arithmetic Instructions', 'Miscellaneous Instructions', 'Bit and Byte Instructions', 'Logical Instructions', 'Shift and Rotate Instructions', 'SSE Data Transfer Instructions', 'MMX Logical Instructions', 'MMX Data Transfer Instructions', 'SSE2 128-Bit SIMD Integer Instructions', 'SSE2 Data Movement Instructions', 'SSE2 Conversion Instructions', 'Insertion and Extractions from XMM Registers', 'SSE2 Packed Arithmetic Instructions', 'String Instructions', 'x87 FPU Data Transfer Instructions', 'SSE2 Compare Instructions', 'MMX Packed Arithmetic Instructions', 'x87 FPU Basic Arithmetic Instructions', 'Packed Integer MIN/MAX Instructions', 'SSE Packed Arithmetic Instructions', 'x87 FPU Comparison Instructions', 'SSE Comparison Instructions', 'SSE3 SIMD Floating-Point LOAD/MOVE/DUPLICATE Instructions', 'Packed Shuffle Bytes', 'SSE2 Shuffle and Unpack Instructions', 'SSE Shuffle and Unpack Instructions', 'Packed Blending Instructions', 'x87 FPU Load Constants Instructions', 'SSE2 Logical Instructions', 'Packed Integer Format Conversions', 'SSE 64-Bit SIMD Integer Instructions', 'Control Transfer Terminating Instructions', 'Packed Align Right', 'Dword Packing With Unsigned Saturation', 'Floating-Point Round Instructions with Selectable Rounding Mode', 'SSE3 x87-FP Integer Conversion Instruction', 'Dword Multiply Instructions', 'MMX Comparison Instructions', 'MMX Conversion Instructions', 'MMX Shift and Rotate Instructions', 'Packed Absolute Values', 'SSE Conversion Instructions', 'SSE Logical Instructions', 'SSE3 SIMD Floating-Point Packed ADD/SUB Instructions', 'System Instructions'],
datasets: [{
label: 'Assembly instructions grouped by category',
data: [138014, 69118, 31075, 22621, 20310, 15076, 2822, 1837, 661, 560, 521, 386, 251, 201, 171, 154, 147, 120, 30, 26, 23, 22, 22, 19, 15, 14, 14, 11, 8, 7, 6, 5, 5, 4, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>We can notice that the <strong>x86-64-v2</strong> level takes advantage of <strong>SSE3</strong>
instructions.</p>
<p>The following extra instructions are used:</p>
<p>ADDSUBPD, BLENDVPD, CMPLESD, FISTTP, MOVDDUP, PABSD, PACKUSDW, PADDQ,
PALIGNR, PBLENDW, PEXTRD, PEXTRQ, PINSRD, PINSRQ, PMAXSD, PMAXUD, PMINSD,
PMINUD, PMOVSXDQ, PMULLD, POR, PSHUFB, PSLLD, PSRLDQ, and ROUNDSD.</p>
<p>When building with <strong>x86-64-v3</strong>, here are the 50 most used instructions:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="instructions-x86-64-v3"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('instructions-x86-64-v3').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['mov', 'test', 'call', 'je', 'cmp', 'jmp', 'nop', 'jne', 'pop', 'xor', 'add', 'lea', 'push', 'movzx', 'sub', 'movsxd', 'ret', 'and', 'jle', 'shl', 'or', 'vmovdqu', 'jg', 'movsx', 'vmovdqa', 'ja', 'js', 'shr', 'jbe', 'jae', 'cdqe', 'jb', 'vpxor', 'imul', 'vmovsd', 'jge', 'vmovq', 'sete', 'vmovaps', 'jl', 'cmove', 'sar', 'movabs', 'setne', 'movbe', 'vmovd', 'jns', 'cmovne', 'andn', 'vpinsrq'],
datasets: [{
label: 'Assembly instructions',
data: [105641, 19442, 17920, 15862, 15535, 13269, 12740, 12073, 11641, 10863, 9996, 9846, 7588, 6091, 4717, 3658, 3321, 2360, 2034, 1583, 1536, 1193, 1076, 771, 666, 603, 583, 563, 506, 484, 448, 425, 395, 367, 365, 363, 339, 339, 334, 328, 316, 302, 295, 283, 275, 236, 233, 199, 134, 130],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>And here are instructions grouped by category:</p>
<div style="width: 100%;height: 768px;margin: 0 auto">
<canvas id="categories-x86-64-v3"></canvas>
</div>
<script src="/scripts/chart.min.js"></script>
<script type="text/javascript">
var ctx = document.getElementById('categories-x86-64-v3').getContext('2d');
var options =
{
type: 'bar',
data: {
labels: ['Data Transfer Instructions', 'Control Transfer Instructions', 'Binary Arithmetic Instructions', 'Miscellaneous Instructions', 'Bit and Byte Instructions', 'Logical Instructions', 'AVX Instructions', 'Shift and Rotate Instructions', 'BMI2 Instructions', 'String Instructions', 'BMI1 Instructions', 'x87 FPU Data Transfer Instructions', 'x87 FPU Basic Arithmetic Instructions', 'AVX2 Instructions', 'x87 FPU Comparison Instructions', 'FMA Instructions', 'x87 FPU Load Constants Instructions', 'Control Transfer Terminating Instructions', 'SSE3 x87-FP Integer Conversion Instruction', 'SSE2 Data Movement Instructions', 'System Instructions'],
datasets: [{
label: 'Assembly instructions grouped by category',
data: [137288, 69114, 31035, 22895, 20295, 14832, 4757, 2450, 270, 154, 151, 147, 26, 24, 22, 19, 7, 4, 2, 1, 1],
backgroundColor: ['#4e79a7', '#a0cbe8', '#f28e2b', '#ffbe7d', '#59a14f', '#8cd17d', '#b6992d', '#f1ce63', '#499894', '#86bcb6', '#e15759', '#ff9d9a', '#79706e', '#bab0ac', '#d37295', '#fabfd2', '#b07aa1', '#d4a6c8', '#9d7660', '#d7b5a6'],
}]
},
options: {
maintainAspectRatio: false,
scales: {
x: {
ticks: {
autoSkip: false
}
},
y: {
display: true,
type: 'logarithmic'
}
}
}
};
new Chart(ctx, options);
</script>
<p>The <strong>x86-64-v3</strong> level takes advantage of <strong>AVX</strong> and <strong>AVX2</strong> instructions,
as well as <strong>BMI1</strong>, <strong>BMI2</strong>, and <strong>FMA</strong> instructions.</p>
<p>The following extra instructions are used:</p>
<p>ANDN, BLSR, LEAVE, LZCNT, MOVBE, RORX, SARX, SHLX, SHRX, VADDPD, VADDSD,
VADDSS, VADDSUBPD, VBLENDVPD, VCMPLESD, VCMPLTSD, VCMPNLTSD, VCOMISD,
VCOMISS, VCVTDQ2PD, VCVTPD2PS, VCVTPS2PD, VCVTSD2SS, VCVTSI2SD, VCVTSI2SS,
VCVTSS2SD, VCVTTSD2SI, VDIVSD, VDIVSS, VEXTRACTI128, VFMADD132PD, VFMADD132SD,
VFMADD213SD, VFMADD231SD, VFMSUB132SD, VFNMADD231SD, VINSERTF128, VINSERTI128,
VMAXSS, VMINSD, VMINSS, VMOVAPD, VMOVAPS, VMOVD, VMOVDDUP, VMOVDQA, VMOVDQU,
VMOVLHPS, VMOVLPS, VMOVQ, VMOVSD, VMOVSS, VMOVUPD, VMOVUPS, VMULPD, VMULSD,
VMULSS, VPABSD, VPACKUSDW, VPACKUSWB, VPADDB, VPADDD, VPADDQ, VPADDW,
VPALIGNR, VPAND, VPBLENDW, VPBROADCASTB, VPBROADCASTD, VPBROADCASTQ,
VPBROADCASTW, VPCMPEQD, VPERMQ, VPEXTRD, VPEXTRQ, VPEXTRW, VPINSRD, VPINSRQ,
VPMAXSD, VPMAXUD, VPMINSD, VPMINUD, VPMOVSXDQ, VPMULLD, VPOR, VPSHUFB,
VPSHUFD, VPSHUFLW, VPSLLD, VPSUBD, VPUNPCKLQDQ, VPXOR, VROUNDSD, VSHUFPD,
VSUBSD, VSUBSS, VUCOMISD, VUCOMISS, VUNPCKLPD, VUNPCKLPS, VXORPD, VXORPS,
and VZEROUPPER.</p>
<p>The full counts of used instructions are available for download in CSV format
for the <a href="/files/asm/data/instructions-v2.csv">x86-64-v2</a> and <a href="/files/asm/data/instructions-v3.csv">x86-64-v3</a> levels.</p>
<p>I'm leaving out the <strong>x86-64-v4</strong> level for now, as I was getting weird
instructions counts compared to the others binaries, so it seems something
got wrong at some point. I might revisit this in the future.</p>
<p><strong>EDIT:</strong> Harold kindly <a rel="noopener" target="_blank" href="https://twitter.com/HaroldAptroot/status/1542165356701257730">pointed out</a> on Twitter that while it seems
MMX instructions are used a lot, it's probably mainly/only the SSE2 versions
that are used instead.</p>
OpenBSD folklore and share/misc/airport2022-06-08T23:45:00+00:002022-06-08T23:45:00+00:00Unknownhttps://www.cambus.net/openbsd-folklore-and-share-misc-airport/<p>Back in 2016, I sent a <a rel="noopener" target="_blank" href="https://marc.info/?l=openbsd-tech&m=147535923705402&w=2">diff</a> to OpenBSD's tech@ mailing list which
added missing airports and area codes for Poland. Theo kindly pointed
out privately that there was a rule governing the update of this file,
which was known among OpenBSD developers but never made it into a commit.
So I ended up making <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/src/commit/8qKRlaACyhZSrcEa">one</a> adding my home airport (<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Rzesz%C3%B3w%E2%80%93Jasionka_Airport">RZE</a>) to the
list and specifying update rules: only add ones you have been to.
Later on, I also added the code for the Warsaw Modlin airport (<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Warsaw_Modlin_Airport">WMI</a>),
from which I did a couple of round trips that same year.</p>
<p>At the OpenBSD <strong>d2k17</strong> hackathon, the rules were documented in a newly
introduced <a rel="noopener" target="_blank" href="https://man.openbsd.org/airport.7">airport(7)</a> manual page: "New airports can only be added
by OpenBSD developers who have visited an airport and thereby have verified
its existence". Once again, the more astute reader will not have missed
the fact that the rules do not stipulate any flying requirements. Neither
did henning@, who not long after <em>airport.7</em> was committed, <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/src/commit/ztW1pPgN6oa712AF">added
an entry for XFW</a>, (the Airbus factory) which he had visited but not
flown from.</p>
<p>Today, I finally took some time off and did a day trip to Lublin.
No trip to a city is complete without a visit to its airport, right?</p>
<p><img src="/content/2022/06/lublin-airport.jpg" alt="Lublin Airport" /></p>
<p>One can say anything about Lublin airport, but they sure do consider
<strong>IATA</strong> codes are serious business. The tone was set right from the
parking lot entrance.</p>
<p><img src="/content/2022/06/lublin-airport-luz.jpg" alt="Lublin Airport LUZ sign" /></p>
<p>And with this, I'm happy to announce that there is a <a rel="noopener" target="_blank" href="https://freshbsd.org/openbsd/src/commit/xZeFvUEDeAp8INp3">new entry</a> for
<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Lublin_Airport">LUZ</a> in the <em>airport</em> file! You are welcome.</p>
Customizing NetBSD boot banners2022-05-12T22:55:00+00:002022-05-12T22:55:00+00:00Unknownhttps://www.cambus.net/customizing-netbsd-boot-banners/<p>I recently discovered that it's surprisingly easy to customize the NetBSD
boot loader banner, simply by adding some directives in the <strong>boot.cfg</strong>
configuration file.</p>
<p>Here is the relevant part of the <a rel="noopener" target="_blank" href="https://man.netbsd.org/boot.cfg.5">boot.cfg(5)</a> manual page:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span> banner The text from banner lines is displayed instead of the standard
</span><span> welcome text by the boot loader. Up to 12 lines can be defined.
</span><span> No special character sequences are recognised, so to specify a
</span><span> blank line, a banner line with no value should be given.
</span></code></pre>
<p>Back in 2014, I published some <a rel="noopener" target="_blank" href="https://www.cambus.net/netbsd-ascii-logos/">NetBSD ASCII logos</a> to be used as <em>motd</em>
or as <em>/etc/issue</em>, but they are higher than 12 lines so using them would
either require raising the allowed lines limit (likely not a good idea),
or resizing them. I then remembered I had requested some Amiga style
<a rel="noopener" target="_blank" href="https://16colo.rs/pack/break_02/h7-os-logos.txt">logos for Linux and *BSD</a>, which were released by h7 in Break's second
artpack in 2013.</p>
<p>So we can simply append this in <em>/boot.cfg</em>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>banner= _______ ______ ___ _________ ____ __________
</span><span>banner=__ _____/ // _/___ __/ \_____\__ /_/ _//______\___ /\_______
</span><span>banner=--/ _ \ // _/ \\ _/ |/_ /\______ / |/ / \- -- -
</span><span>banner=_/ \ \ \ // \ |_/ / |/ \ / \ /
</span><span>banner=\______/ /\_____\_____\______/\____ // : ____/____ /\/
</span><span>banner= \ \_____/ \ \ \ \ \ \_____/ \______/\ \ \_____/ \
</span><span>banner=h7\_____\ \ /\___________\_____\/\__\ \ \ \ \______\ \dS!
</span><span>banner=------ - \____\/ - --( n e t b s d )-- - \____\/ \_____\/ - --- \____\/ -------
</span></code></pre>
<p>And enjoy some stylish Amiga ASCII art after the next reboot:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span> _______ ______ ___ _________ ____ __________
</span><span>__ _____/ // _/___ __/ \_____\__ /_/ _//______\___ /\_______
</span><span>--/ _ \ // _/ \\ _/ |/_ /\______ / |/ / \- -- -
</span><span>_/ \ \ \ // \ |_/ / |/ \ / \ /
</span><span>\______/ /\_____\_____\______/\____ // : ____/____ /\/
</span><span> \ \_____/ \ \ \ \ \ \_____/ \______/\ \ \_____/ \
</span><span>h7\_____\ \ /\___________\_____\/\__\ \ \ \ \______\ \dS!
</span><span>------ - \____\/ - --( n e t b s d )-- - \____\/ \_____\/ - --- \____\/ -------
</span><span>
</span><span> 1. Boot normally
</span><span> 2. Boot single user
</span><span> 3. Drop to boot prompt
</span><span>
</span><span>Choose an option; RETURN for default; SPACE to stop countdown.
</span><span>Option 1 will be chosen in 2 seconds.
</span></code></pre>
<p>Lastly, here is the PNG version converted with <a rel="noopener" target="_blank" href="https://www.ansilove.org">Ansilove</a>, in full Topaz
glory:</p>
<p><img src="/content/2022/05/h7-netbsd.png" alt="NetBSD ASCII Logo" /></p>
File transfers via the parallel port on DOS using LapLink2022-04-13T13:10:00+00:002022-04-13T13:10:00+00:00Unknownhttps://www.cambus.net/file-transfers-via-the-parallel-port-on-dos-using-laplink/<p>I've already mentioned the <a rel="noopener" target="_blank" href="https://www.parkytowers.me.uk/thin/hp/t5570/">HP t5570e</a> and <a rel="noopener" target="_blank" href="https://www.parkytowers.me.uk/thin/hp/t510/">HP t510</a> thin clients a few
times on this site, so they probably don't require any more introduction.
I will however just stress that one of the nice thing they have going for
them is that they still have serial and parallel ports.</p>
<p>I've already put their parallel port to good use, as it allowed me to re-plug
my <a rel="noopener" target="_blank" href="https://www.cambus.net/gba-nostalgia-and-the-flash-advance-linker/">Flash Advance Linker</a> and also use the wonderful <a rel="noopener" target="_blank" href="https://www.serdaco.com/products/other-audio/opl3lpt/">OPL3LPT</a> device
(an '<strong>AdLib</strong>' parallel port FM synthesizer soundcard).</p>
<p>There is one thing I had always wanted to try, though: the <strong>parallel port</strong>
transfer mode of LapLink. I had used LapLink in the early nineties, but only
with null modem (serial) cables.</p>
<p>I originally planned to solder a cable, but it ended up not being necessary,
as I was able to buy a brand new compatible cable from a seller in Germany.</p>
<p><img src="/content/2022/04/null-printer-cable.jpg" alt="Null printer cable" title="Null printer cable" /></p>
<p>Surprisingly, there is very little history available online about the DOS
versions of LapLink, and I'm not sure when its parallel cable was actually
introduced. The "<a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/LapLink_cable">LapLink cable</a>" Wikipedia page mentions 1983, but that
seems strange, as LapLink 2.15 from 1987 does not have any way to configure
the software for using a parallel port cable. LapLink 3.00 from 1989 does.</p>
<p>For the purpose of this article, I decided to use the latest DOS version
available, which appears to be <strong>LapLink 5.00</strong>, released in 1993. It comes
with an improved UI using redefined characters including cute files and folder
icons, along with some subtle animations. I've been using the standard color
theme.</p>
<p><img src="/content/2022/04/laplink-about.png" alt="LapLink 5 - About LapLink" title="LapLink 5 - About LapLink" /></p>
<p>I normally use <strong>THEGRAB.EXE</strong> which was bundled with <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/TheDraw">TheDraw</a> ANSI editor
to capture text screens and save them as ANSI files which I can then archive
and convert using <a rel="noopener" target="_blank" href="https://www.ansilove.org">Ansilove</a>. However, I ran into some issues and I wanted
to enable the redefined characters anyway. I opted to use the excellent
Screen Thief program from Villa Software, which I had used in the past to
capture some of the screenshots from my <a rel="noopener" target="_blank" href="https://cleaner.ansilove.org/coding.html">demoscene productions</a>.</p>
<p>Below is the main file navigation view:</p>
<p><img src="/content/2022/04/laplink-copy.gif" alt="LapLink 5 - File navigation" title="LapLink 5 - File navigation" /></p>
<p>Notice the small animated arrows along the copy button: the direction changes
to show the destination target. In our case, files will be copied from the
local machine (on the left) to the remote machine (on the right).</p>
<p>LapLink will even warn you if the clocks are out of sync:</p>
<p><img src="/content/2022/04/laplink-time.png" alt="LapLink 5 - Time synchronization" title="LapLink 5 - Time synchronization" /></p>
<p>Here is a transfer in action:</p>
<p><img src="/content/2022/04/laplink-transfer.gif" alt="LapLink 5 - File transfer" title="LapLink 5 - File transfer" /></p>
<p>The file used is a floppy disk image, and the larger jumps at the end
of the transfer is compression taking place.</p>
<p>Below is a large ongoing transfer and its summary:</p>
<p><img src="/content/2022/04/laplink-transfer.png" alt="LapLink 5 - File transfer" title="LapLink 5 - File transfer" /></p>
<p><img src="/content/2022/04/laplink-success.png" alt="LapLink 5 - File transfer success" title="LapLink 5 - File transfer success" /></p>
<p>It's hard to explain, but there is something oddly satisfying in transferring
several hundred megabytes ISO images reliably over the parallel port.</p>
Toolchains adventures - Q1 20222022-04-01T14:13:00+00:002022-04-01T14:13:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q1-2022/<p>This is the fourth post in my toolchains adventures series. Please check
the previous posts in the <a rel="noopener" target="_blank" href="https://www.cambus.net/categories/toolchains/">toolchains</a> category for more context about
this journey.</p>
<p>In Pkgsrc land, I packaged and <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/ONXyoaS20LgUgeoD">imported</a> <a rel="noopener" target="_blank" href="https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities">pax-utils</a>, and updated
mold to the <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/8HAjm8hb8Z5bGWmD">1.0.1</a>, <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/gCygLxtROQYf5QqD">1.0.2</a>, <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/iMqv11CYyAdIgVqD">1.0.3</a>, <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/jO3WmDjWC7FWLttD">1.1</a>, and <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/AUn1aWVIkZxz2qvD">1.1.1</a>
versions. Since version 1.0.2, mold can now link NetBSD object files thanks
to work done by pho@.</p>
<p>I also <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/LXtgdsrYLXmMVzoD">committed</a> upstream fix for <a rel="noopener" target="_blank" href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45078">CVE-2021-45078</a> in binutils to
fix an out-of-bounds write, and imported our <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/nRgl5kGXb1YmNTpD">NetBSD/aarch64 support
patches</a> for ld from the NetBSD's src repository.
This fixes the build on NetBSD/aarch64. I then <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/PkHjNNvGrHgjS4sD">updated</a> the package to
the 2.38 version which was <a rel="noopener" target="_blank" href="https://marc.info/?l=binutils&m=164441341718811&w=2">released</a> in February.</p>
<p>I don't have much to report on the LLVM side, I only made two documentation
related commits this quarter. However, I have a few things I plan to look at,
so I should hopefully have more to report next time.</p>
<p>Besides that, I've been mostly busy reading different material, and
adding a lot of new resources to <a rel="noopener" target="_blank" href="https://www.toolchains.net">toolchains.net</a>.</p>
<p>That's all for now, happy Spring 2022 everyone!</p>
<p>LLVM commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2022-03-23</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/45c673816e1867ab7af3e63efd6af3ca44293b17">45c6738</a></td><td>[compiler-rt] Remove forgotten mention of SVN modules, LLVM now uses Git</td></tr>
<tr><td>2022-03-21</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/bc01d8fbcfd3f07e2139e898eef48349187ab64f">bc01d8f</a></td><td>[compiler-rt] Remove mentions of AuroraUX in code comments and docs</td></tr>
</tbody></table>
GBA nostalgia and the Flash Advance Linker2022-03-17T21:28:00+00:002022-03-17T21:28:00+00:00Unknownhttps://www.cambus.net/gba-nostalgia-and-the-flash-advance-linker/<p>I got involved with <strong>Game Boy Advance</strong> development in 2001 shortly after the
release of the device on the European market.</p>
<p>At the time, the PC demoscene had already moved to producing those horrible
hardware-accelerated 3D demos and it was time for me to move on.
In my eyes, the GBA scene provided a refuge for the 2D and bitmapped graphics
lovers, and so I spent some time playing with the device.</p>
<p>The scene was very active and the <a rel="noopener" target="_blank" href="https://www.gbadev.org">gbadev.org</a> site provided a lot of
resources for homebrew developers. At the same time, the release groups
were not in rest, providing a continuous supply of lovely cracktros and
trainers. Some demoscene productions were also released on this platform,
and I fondly remember <a rel="noopener" target="_blank" href="https://demozoo.org/productions/67816/">Gameboy Advance 3D-Trip</a> by Oxygene, and
<a rel="noopener" target="_blank" href="https://demozoo.org/productions/119504/">Kance</a> by Condense.</p>
<p>During this period, I acquired a pre-owned <strong>Flash Advance Linker</strong>, a device
manufactured by Visoly in 2001. Because the previous owner was also selling
his GBA, I ended up owning two of them. As my plan back then was to pursue
the idea of developing a multiplayer puzzle game, on the hardware side at
least, I had everything I ever needed.</p>
<p>Life happened though, things didn't exactly go as planned and I had to sell
the two GBAs temporarily, or so I thought. I kept the linker though, and
when I acquired the HP t5570e and HP t510 thin clients back in 2017, it
meant that I finally had some devices with a parallel port again.</p>
<p>Here is the device in full glory:</p>
<p><img src="/content/2022/03/flash-advance-linker.jpg" alt="Flash Advance Linker" title="Flash Advance Linker with flash cart inserted" /></p>
<p>And here is the PCB:</p>
<p><img src="/content/2022/03/flash-advance-linker-pcb.jpg" alt="Flash Advance Linker" title="Flash Advance Linker PCB" /></p>
<p>I'm happy to announce that after 20 years, the linker is still working!
Back in the days, I was using <a rel="noopener" target="_blank" href="https://ucon64.sourceforge.io/">uCON64</a> to transfer data to the flash cart.
Not only is it still being maintained, but it still has releases for DOS,
so I went this route to bring things back to life.</p>
<p>uCON64 uses <strong>LPT1</strong> by default when using the Flash Advance Linker, so we
can simply send and receive ROMs to/from the flash cart with the <em>-xfal</em>
option. As it outputs ANSI escape sequences for displaying its progress bar,
we need to have an ANSI driver running, either <strong>ANSI.SYS</strong> on MS-DOS or
<strong>NANSI.SYS</strong> on FreeDOS.</p>
<p>uCON64 sending a ROM to the Flash cart:</p>
<p><img src="/content/2022/03/ucon64-send.png" alt="uCON64" title="uCON64 sending a ROM to the Flash cart" /></p>
<p>uCON64 receiving a ROM from the Flash cart:</p>
<p><img src="/content/2022/03/ucon64-receive.png" alt="uCON64" title="uCON64 sending a ROM to the Flash cart" /></p>
<p>The cartridge still works flawlessly and I was able to run some demos
again on the <strong>Revo K101</strong> a friend donated a couple years ago. This sure
brings back memories...</p>
<p>Lastly, here is an old <a rel="noopener" target="_blank" href="https://www.wired.com/2001/12/flash-advance-linker-and-card/">article</a> from Wired about this wonderful little
device.</p>
FreeBSD on the Vortex86DX CPU2022-03-15T10:14:00+00:002022-03-15T10:14:00+00:00Unknownhttps://www.cambus.net/freebsd-on-the-vortex86dx-cpu/<p>After trying <a rel="noopener" target="_blank" href="https://www.cambus.net/netbsd-on-the-vortex86dx-cpu/">NetBSD</a> and <a rel="noopener" target="_blank" href="https://www.cambus.net/openbsd-on-the-vortex86dx-cpu/">OpenBSD</a> on my DMP EBOX 3300A-H with a
<strong>Vortex86DX</strong> CPU, I was curious to see how FreeBSD would fare on such
constrained systems these days.</p>
<p>For more information and background about the hardware, please refer to my
<a rel="noopener" target="_blank" href="https://www.cambus.net/netbsd-on-the-vortex86dx-cpu/">previous</a> article.</p>
<p>Attempting to install <strong>FreeBSD 13.0</strong> failed early when loading the kernel,
and both supported releases from the FreeBSD 12 series (12.2 and 12.3) also
exhibit the same issue.</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>int=00000006 err=00000000 efl=00000002 eip=013d1651
</span><span>eax=01fe26b0 ebx=0008274c ecx=00000000 edx=01fe8b77
</span><span>esi=01d8c3d8 edi=019b20c8 ebp=019b2038 esp=00000000
</span><span>cs=0008 ds=0010 es=0010 fs=0010 gs=0010 ss=0010
</span><span>cs:eip=0f 45 f0 a1 88 20 9b 01-85 c0 0f 45 f0 81 c6 ff
</span><span> ff 3f 00 81 e6 00 00 c0-ff 89 35 d4 ad d8 01 8d
</span><span>ss:esp=f3 ee 00 f0 f3 ee 00 f0-c3 e2 00 f0 f3 ee 00 f0
</span><span> f3 ee 00 f0 54 ff 00 f0-4f 07 00 f0 f7 06 00 f0
</span><span>BTX halted
</span></code></pre>
<p>FreeBSD 13.0 <a rel="noopener" target="_blank" href="https://www.freebsd.org/releases/13.0R/relnotes/">release notes</a> mention that the default CPUTYPE for the i386
architecture is now 686 (instead of 486), and have details on the rationale
behind this change.</p>
<p>After digging a bit, it turns out some Vortex86 CPUs lack support for the
<strong>Conditional Move</strong> (<strong>CMOV</strong>) instruction, and code targeting i686 will
fail on those models.</p>
<p>Using <strong>objdump</strong> to disassemble the kernels for the 12.2, 12.3, and 13.0
releases revealed that they were indeed using CMOV. Performing
the same checks on the kernels from FreeBSD 12.0 and 12.1 releases did not
show any CMOV instructions use.</p>
<p>The FreeBSD 12.1 installation process completed successfully and I could
reboot into the installed system without issues. This version is not
supported anymore but it doesn't matter in this case as it's more of a
one-off thing for the purpose of writing this post, the machine being
too constrained for any real world usage in this day and age.</p>
<p>For installing <strong>pkg</strong> and binary packages, I had to modify the url
directive in <em>/etc/pkg/FreeBSD.conf</em> to:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>url: "pkg+http://pkg.FreeBSD.org/${ABI}/release_2",
</span></code></pre>
<p>Indeed, <em>quarterly</em> packages and <em>release_3</em> packages are apparently
targeting i686 and their binaries contain CMOV instructions.</p>
<p>Attempting to run i686 binaries result in the following error:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>Illegal instruction (core dumped)
</span></code></pre>
<p>We can verify that the culprits are indeed CMOV instructions with the
following program:</p>
<pre data-lang="asm" style="background-color:#272822;color:#f8f8f2;" class="language-asm "><code class="language-asm" data-lang="asm"><span style="color:#a6e22e;">.</span><span style="color:#66d9ef;">section </span><span style="color:#a6e22e;">.text
</span><span>
</span><span style="color:#a6e22e;">.globl _start
</span><span>
</span><span style="color:#a6e22e;">_start:
</span><span style="color:#a6e22e;"> </span><span style="color:#f92672;">cmovl </span><span style="color:#a6e22e;">%</span><span style="font-style:italic;color:#fd971f;">eax</span><span>, </span><span style="color:#a6e22e;">%</span><span style="font-style:italic;color:#fd971f;">ebx
</span></code></pre>
<p>Let's assemble, link, and run it:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>as cmov.s -o cmov.o
</span><span>ld cmov.o -o cmov
</span><span>./cmov
</span><span>Illegal instruction (core dumped)
</span></code></pre>
<p>With this out of the way, we now have a fully functioning FreeBSD 12.1
installation on this machine.</p>
<p>On a freshly booted system, 16 processes are running and most of the RAM is
unused.</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>last pid: 787</span><span style="color:#f92672;">; </span><span>load averages: 0.30, 0.30, 0.13 up 0+00:02:12 09:55:29
</span><span>16 processes: 1 running, 15 sleeping
</span><span>CPU: 6.2% user, 0.0% nice, 10.1% system, 2.1% interrupt, 81.6% idle
</span><span>Mem: 6556K Active, 1028K Inact, 28M Wired, 16M Buf, 181M Free
</span><span>Swap: 2752M Total, 2752M Free
</span><span>
</span><span> PID USERNAME THR PRI NICE SIZE RES STATE TIME WCPU COMMAND
</span><span> 751 root 1 22 0 5268K 2616K wait 0:00 0.00% login
</span><span> 759 root 1 20 0 6192K 3108K pause 0:00 0.00% csh
</span><span> 581 root 1 20 0 4588K 2112K select 0:00 0.00% syslogd
</span><span> 692 root 1 20 0 8772K 5360K select 0:00 0.00% sendmail
</span><span> 699 root 1 24 0 4588K 2104K nanslp 0:00 0.00% cron
</span><span> 787 root 1 23 0 5868K 2592K RUN 0:00 0.00% top
</span><span> 752 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 756 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 758 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 753 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 757 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 754 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 755 root 1 52 0 4276K 1908K ttyin 0:00 0.00% getty
</span><span> 695 smmsp 1 52 0 8548K 4848K pause 0:00 0.00% sendmail
</span><span> 94 root 1 52 0 4152K 1688K pause 0:00 0.00% adjkerntz
</span><span> 421 root 1 20 0 3864K 1108K select 0:00 0.00% devd
</span></code></pre>
<p>Here is the result of the <strong>md5 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>MD5 time trial. Digesting 100000 10000-byte blocks ... done
</span><span>Digest = 766a2bb5d24bddae466c572bcabca3ee
</span><span>Time = 20.719989 seconds
</span><span>Speed = 46.026777 MiB/second
</span></code></pre>
<p>And this is the result of the <strong>sha1 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>SHA1 time trial. Digesting 100000 10000-byte blocks ... done
</span><span>Digest = 02522491d7a8253fcab708560acfa84b2fb7ef1c
</span><span>Time = 54.165445 seconds
</span><span>Speed = 17.606692 MiB/second
</span></code></pre>
<p>For the record, OpenSSL speed benchmark results are available
<a href="/files/freebsd/openssl-speed-vortex86.txt">here</a>.</p>
<p>Finally, here is a dmesg for reference purposes:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>Copyright (c) 1992-2019 The FreeBSD Project.
</span><span>Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
</span><span> The Regents of the University of California. All rights reserved.
</span><span>FreeBSD is a registered trademark of The FreeBSD Foundation.
</span><span>FreeBSD 12.1-RELEASE r354233 GENERIC i386
</span><span>FreeBSD clang version 8.0.1 (tags/RELEASE_801/final 366581) (based on LLVM 8.0.1)
</span><span>VT(vga): resolution 640x480
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>CPU: PentiumUnknown (1000.02-MHz 586-class CPU)
</span><span> Origin="Vortex86 SoC" Id=0x522
</span><span>real memory = 268435456 (256 MB)
</span><span>avail memory = 225300480 (214 MB)
</span><span>random: unblocking device.
</span><span>stray irq7
</span><span>Timecounter "TSC" frequency 1000023008 Hz quality 800
</span><span>random: entropy device external interface
</span><span>kbd1 at kbdmux0
</span><span>[ath_hal] loaded
</span><span>module_register_init: MOD_LOAD (vesa, 0x14d9fb0, 0) error 19
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>ACPI: Table initialisation failed: AE_NOT_FOUND
</span><span>ACPI: Try disabling either ACPI or apic support.
</span><span>vtvga0: <VT VGA driver> on motherboard
</span><span>cryptosoft0: <software crypto> on motherboard
</span><span>pcib0 pcibus 0 on motherboard
</span><span>pir0: <PCI Interrupt Routing Table: 12 Entries> on motherboard
</span><span>pci0: <PCI bus> on pcib0
</span><span>vgapci0: <VGA-compatible display> port 0xdf80-0xdfff mem 0xf8000000-0xfbffffff,0xfefc0000-0xfeffffff at device 3.0 on pci0
</span><span>vgapci0: Boot video device
</span><span>isab0: <PCI-ISA bridge> at device 7.0 on pci0
</span><span>isa0: <ISA bus> on isab0
</span><span>vte0: <RDC R6040 FastEthernet> port 0xde00-0xdeff mem 0xfefbb400-0xfefbb4ff irq 10 at device 8.0 on pci0
</span><span>miibus0: <MII bus> on vte0
</span><span>rdcphy0: <R6040 10/100 media interface> PHY 1 on miibus0
</span><span>rdcphy0: none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
</span><span>vte0: Ethernet address: 00:1b:eb:22:16:5c
</span><span>ohci0: <OHCI (generic) USB controller> mem 0xfefb9000-0xfefb9fff irq 11 at device 10.0 on pci0
</span><span>usbus0 on ohci0
</span><span>ehci0: <EHCI (generic) USB 2.0 controller> mem 0xfefbb800-0xfefbb8ff irq 11 at device 10.1 on pci0
</span><span>usbus1: EHCI version 1.0
</span><span>usbus1 on ehci0
</span><span>ohci1: <OHCI (generic) USB controller> mem 0xfefba000-0xfefbafff irq 11 at device 11.0 on pci0
</span><span>usbus2 on ohci1
</span><span>ehci1: <EHCI (generic) USB 2.0 controller> mem 0xfefbbc00-0xfefbbcff irq 11 at device 11.1 on pci0
</span><span>usbus3: EHCI version 1.0
</span><span>usbus3 on ehci1
</span><span>atapci0: <Generic ATA controller> port 0x1f0-0x1f7,0x3f6,0x170-0x177,0x376,0xef00-0xef0f irq 14 at device 12.0 on pci0
</span><span>ata0: <ATA channel> at channel 0 on atapci0
</span><span>ata1: <ATA channel> at channel 1 on atapci0
</span><span>cpu0 on motherboard
</span><span>unknown: <PNP0c01> can't assign resources (memory)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>attimer0: <AT timer> at port 0x40-0x43 irq 0 pnpid PNP0100 on isa0
</span><span>Timecounter "i8254" frequency 1193182 Hz quality 0
</span><span>Event timer "i8254" frequency 1193182 Hz quality 100
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>atrtc0: <AT realtime clock> at port 0x70-0x71 irq 8 pnpid PNP0b00 on isa0
</span><span>atrtc0: registered as a time-of-day clock, resolution 1.000000s
</span><span>Event timer "RTC" frequency 32768 Hz quality 0
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 irq 1 pnpid PNP0303 on isa0
</span><span>atkbd0: <AT Keyboard> irq 1 on atkbdc0
</span><span>kbd0 at atkbd0
</span><span>atkbd0: [GIANT-LOCKED]
</span><span>orm0: <ISA Option ROM> at iomem 0xc0000-0xc7fff pnpid ORM0000 on isa0
</span><span>fdc0: No FDOUT register!
</span><span>ppc0: parallel port not found.
</span><span>unknown: <PNP0c01> can't assign resources (memory)
</span><span>Firmware Error (ACPI): A valid RSDP was not found (20181213/tbxfroot-369)
</span><span>Timecounters tick every 1.000 msec
</span><span>usbus0: 12Mbps Full Speed USB v1.0
</span><span>usbus1: 480Mbps High Speed USB v2.0
</span><span>ugen0.1: <(0x17f3) OHCI root HUB> at usbus0
</span><span>uhub0: <(0x17f3) OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus0
</span><span>ugen1.1: <(0x17f3) EHCI root HUB> at usbus1
</span><span>uhub1: <(0x17f3) EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1
</span><span>usbus2: 12Mbps Full Speed USB v1.0
</span><span>usbus3: 480Mbps High Speed USB v2.0
</span><span>ugen2.1: <(0x17f3) OHCI root HUB> at usbus2
</span><span>uhub2: <(0x17f3) OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus2
</span><span>ugen3.1: <(0x17f3) EHCI root HUB> at usbus3
</span><span>uhub3: <(0x17f3) EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus3
</span><span>uhub0: 2 ports with 2 removable, self powered
</span><span>uhub2: 2 ports with 2 removable, self powered
</span><span>Trying to mount root from ufs:/dev/da0s1a [rw]...
</span><span>Root mount waiting for: usbus3 usbus1
</span><span>uhub1: 2 ports with 2 removable, self powered
</span><span>uhub3: 2 ports with 2 removable, self powered
</span><span>Root mount waiting for: usbus3 usbus1
</span><span>ugen0.2: <vendor 0x0d8c C-Media USB Audio Device> at usbus0
</span><span>ugen2.2: <Lenovo ThinkPad Compact USB Keyboard with TrackPoint> at usbus2
</span><span>ukbd0 on uhub2
</span><span>ukbd0: <Lenovo ThinkPad Compact USB Keyboard with TrackPoint, class 0/0, rev 2.00/3.30, addr 2> on usbus2
</span><span>kbd2 at ukbd0
</span><span>Root mount waiting for: usbus3
</span><span>Root mount waiting for: usbus3
</span><span>ugen3.2: <Generic USB Storage> at usbus3
</span><span>umass0 on uhub3
</span><span>umass0: <Generic USB Storage, class 0/0, rev 2.00/2.20, addr 2> on usbus3
</span><span>umass0: SCSI over Bulk-Only; quirks = 0xc100
</span><span>umass0:2:0: Attached to scbus2
</span><span>mountroot: waiting for device /dev/da0s1a...
</span><span>da0 at umass-sim0 bus 0 scbus2 target 0 lun 0
</span><span>da0: <Generic STORAGE DEVICE 0220> Removable Direct Access SCSI device
</span><span>da0: 40.000MB/s transfers
</span><span>da0: 61120MB (125173760 512 byte sectors)
</span><span>da0: quirks=0x3<NO_SYNC_CACHE,NO_6_BYTE>
</span><span>lo0: link state changed to UP
</span><span>vte0: link state changed to DOWN
</span><span>uaudio0 on uhub0
</span><span>uaudio0: <vendor 0x0d8c C-Media USB Audio Device, class 0/0, rev 1.10/1.00, addr 2> on usbus0
</span><span>uaudio0: Play: 48000 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer.
</span><span>uaudio0: Play: 44100 Hz, 2 ch, 16-bit S-LE PCM format, 2x8ms buffer.
</span><span>uaudio0: Record: 48000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
</span><span>uaudio0: Record: 44100 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
</span><span>uaudio0: No MIDI sequencer.
</span><span>pcm0: <USB audio> on uaudio0
</span><span>uaudio0: HID volume keys found.
</span><span>ums0 on uhub2
</span><span>ums0: <Lenovo ThinkPad Compact USB Keyboard with TrackPoint, class 0/0, rev 2.00/3.30, addr 2> on usbus2
</span><span>ums0: 6 buttons and [XYZT] coordinates ID=1
</span></code></pre>
FreeBSD on the CubieBoard22022-03-14T09:08:00+00:002022-03-14T09:08:00+00:00Unknownhttps://www.cambus.net/freebsd-on-the-cubieboard2/<p>I have previously been running <a rel="noopener" target="_blank" href="https://wiki.netbsd.org/ports/evbarm/">NetBSD/evbarm</a> and <a rel="noopener" target="_blank" href="https://www.openbsd.org/armv7.html">OpenBSD/armv7</a>
on my CubieBoard2, and wrote about it <a rel="noopener" target="_blank" href="https://www.cambus.net/netbsd-on-the-cubieboard2/">here</a> and <a rel="noopener" target="_blank" href="https://www.cambus.net/openbsd-armv7-on-the-cubieboard2/">here</a>.</p>
<p>The <a rel="noopener" target="_blank" href="https://linux-sunxi.org/Cubietech_Cubieboard2">Cubieboard2</a> is an <strong>ARMv7</strong> device which was released in 2013 so
it is quite ancient by now. However, a renewed interest in FreeBSD on my
side prompted me to try running the system on this device.</p>
<p>ARMv7 is a <strong>Tier 2</strong> architecture on FreeBSD, so the system cannot be upgraded
by <strong>freebsd-update</strong> and must be kept up to date by source. On the plus side,
binary packages are available on this platform. For those interested, the
FreeBSD wiki has more information about <a rel="noopener" target="_blank" href="https://wiki.freebsd.org/action/show/arm/Allwinner?action=show&redirect=FreeBSD%2Farm%2FAllwinner">running FreeBSD on Allwinner systems</a>.</p>
<p><img src="/content/2021/03/cubieboard2.jpg" alt="Cubieboard2" title="Cubieboard2" /></p>
<p>Required steps for creating a bootable micro SD card are as follow:
on a FreeBSD machine, we need to install the <a rel="noopener" target="_blank" href="https://www.freshports.org/sysutils/u-boot-cubieboard2/">u-boot-cubieboard2</a> package
and write the image file and the bootloader to the card.</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>pkg install u-boot-cubieboard2
</span><span>dd if=FreeBSD-13.0-RELEASE-arm-armv7-GENERICSD.img of=/dev/da0 bs=1M conv=sync
</span><span>dd if=/usr/local/share/u-boot/u-boot-cubieboard2/u-boot-sunxi-with-spl.bin of=/dev/da0 bs=1k seek=8 conv=sync
</span></code></pre>
<p>The partition will be automatically resized during first boot to span the
whole capacity of the card.</p>
<p>Here is the output of running <em>file</em> on executables:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>ELF 32-bit LSB executable, ARM, EABI5 version 1 (FreeBSD), dynamically linked, interpreter /libexec/ld-elf.so.1, FreeBSD-style, for FreeBSD 13.0 (1300139), stripped
</span></code></pre>
<p>Here is the result of the <strong>md5 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>MD5 time trial. Digesting 100000 10000-byte blocks ... done
</span><span>Digest = 766a2bb5d24bddae466c572bcabca3ee
</span><span>Time = 13.895305 seconds
</span><span>Speed = 68.632843 MiB/second
</span></code></pre>
<p>And this is the result of the <strong>sha1 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>SHA1 time trial. Digesting 100000 10000-byte blocks ... done
</span><span>Digest = 02522491d7a8253fcab708560acfa84b2fb7ef1c
</span><span>Time = 23.223881 seconds
</span><span>Speed = 41.064381 MiB/second
</span></code></pre>
<p>For the record, OpenSSL speed benchmark results are available
<a href="/files/freebsd/openssl-speed-cubieboard2.txt">here</a>.</p>
<p>Finally, here is a dmesg for reference purposes:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>Copyright (c) 1992-2021 The FreeBSD Project.
</span><span>Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
</span><span> The Regents of the University of California. All rights reserved.
</span><span>FreeBSD is a registered trademark of The FreeBSD Foundation.
</span><span>FreeBSD 13.0-RELEASE #0 releng/13.0-n244733-ea31abc261f: Fri Apr 9 06:33:09 UTC 2021
</span><span> root@releng1.nyi.freebsd.org:/usr/obj/usr/src/arm.armv7/sys/GENERIC arm
</span><span>FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
</span><span>VT: init without driver.
</span><span>No PSCI/SMCCC call function found
</span><span>CPU: ARM Cortex-A7 r0p4 (ECO: 0x00000000)
</span><span>CPU Features:
</span><span> Multiprocessing, Thumb2, Security, Virtualization, Generic Timer, VMSAv7,
</span><span> PXN, LPAE, Coherent Walk
</span><span>Optional instructions:
</span><span> SDIV/UDIV, UMULL, SMULL, SIMD(ext)
</span><span>LoUU:2 LoC:3 LoUIS:2
</span><span>Cache level 1:
</span><span> 32KB/64B 4-way data cache WB Read-Alloc Write-Alloc
</span><span> 32KB/32B 2-way instruction cache Read-Alloc
</span><span>Cache level 2:
</span><span> 256KB/64B 8-way unified cache WB Read-Alloc Write-Alloc
</span><span>real memory = 1039581184 (991 MB)
</span><span>avail memory = 1002311680 (955 MB)
</span><span>FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
</span><span>random: unblocking device.
</span><span>random: entropy device external interface
</span><span>WARNING: Device "kbd" is Giant locked and may be deleted before FreeBSD 14.0.
</span><span>kbd0 at kbdmux0
</span><span>WARNING: Device "openfirm" is Giant locked and may be deleted before FreeBSD 14.0.
</span><span>ofwbus0: <Open Firmware Device Tree>
</span><span>aw_ccu0: <Allwinner Clock Control Unit> on ofwbus0
</span><span>clk_fixed0: <Fixed clock> on aw_ccu0
</span><span>clk_fixed1: <Fixed clock> on aw_ccu0
</span><span>clk_fixed2: <Fixed clock> on aw_ccu0
</span><span>clk_fixed3: <Fixed clock> on aw_ccu0
</span><span>simplebus0: <Flattened device tree simple bus> on ofwbus0
</span><span>regfix0: <Fixed Regulator> on ofwbus0
</span><span>regfix1: <Fixed Regulator> on ofwbus0
</span><span>regfix2: <Fixed Regulator> on ofwbus0
</span><span>regfix3: <Fixed Regulator> on ofwbus0
</span><span>regfix4: <Fixed Regulator> on ofwbus0
</span><span>regfix5: <Fixed Regulator> on ofwbus0
</span><span>rtc0: <Allwinner RTC> mem 0x1c20d00-0x1c20d1f irq 39 on simplebus0
</span><span>rtc0: registered as a time-of-day clock, resolution 1.000000s
</span><span>aw_gmacclk0: <Allwinner GMAC Clock> mem 0x1c20164-0x1c20167 on aw_ccu0
</span><span>ccu_a10ng0: <Allwinner A10/A20 Clock Control Unit NG> mem 0x1c20000-0x1c203ff on simplebus0
</span><span>gic0: <ARM Generic Interrupt Controller> mem 0x1c81000-0x1c81fff,0x1c82000-0x1c83fff,0x1c84000-0x1c85fff,0x1c86000-0x1c87fff irq 77 on simplebus0
</span><span>gic0: pn 0x1, arch 0x2, rev 0x1, implementer 0x43b irqs 160
</span><span>aw_nmi0: <Allwinner NMI Controller> mem 0x1c00030-0x1c0003b irq 6 on simplebus0
</span><span>gpio0: <Allwinner GPIO/Pinmux controller> mem 0x1c20800-0x1c20bff irq 31 on simplebus0
</span><span>gpiobus0: <OFW GPIO bus> on gpio0
</span><span>iichb0: <Allwinner Integrated I2C Bus Controller> mem 0x1c2ac00-0x1c2afff irq 59 on simplebus0
</span><span>iicbus0: <OFW I2C bus> on iichb0
</span><span>axp2xx_pmu0: <X-Powers AXP209 Power Management Unit> at addr 0x68 irq 82 on iicbus0
</span><span>gpiobus1: <OFW GPIO bus> on axp2xx_pmu0
</span><span>iichb1: <Allwinner Integrated I2C Bus Controller> mem 0x1c2b000-0x1c2b3ff irq 60 on simplebus0
</span><span>iicbus1: <OFW I2C bus> on iichb1
</span><span>generic_timer0: <ARMv7 Generic Timer> irq 0,1,2,3 on ofwbus0
</span><span>Timecounter "ARM MPCore Timecounter" frequency 24000000 Hz quality 1000
</span><span>Event timer "ARM MPCore Eventtimer" frequency 24000000 Hz quality 1000
</span><span>aw_sid0: <Allwinner Secure ID Controller> mem 0x1c23800-0x1c239ff on simplebus0
</span><span>awusbphy0: <Allwinner USB PHY> mem 0x1c13400-0x1c1340f,0x1c14800-0x1c14803,0x1c1c800-0x1c1c803 on simplebus0
</span><span>cpulist0: <Open Firmware CPU Group> on ofwbus0
</span><span>cpu0: <Open Firmware CPU> on cpulist0
</span><span>cpufreq_dt0: <Generic cpufreq driver> on cpu0
</span><span>cpu1: <Open Firmware CPU> on cpulist0
</span><span>pmu0: <Performance Monitoring Unit> irq 4,5 on ofwbus0
</span><span>a10dmac0: <Allwinner DMA controller> mem 0x1c02000-0x1c02fff irq 7 on simplebus0
</span><span>aw_mmc0: <Allwinner Integrated MMC/SD controller> mem 0x1c0f000-0x1c0ffff irq 16 on simplebus0
</span><span>musbotg0: <Allwinner USB DRD> mem 0x1c13000-0x1c133ff irq 20 on simplebus0
</span><span>musbotg0: setting phy mode 3
</span><span>usbus0: Dynamic FIFO sizing detected, assuming 16Kbytes of FIFO RAM
</span><span>usbus0 on musbotg0
</span><span>ehci0: <Generic EHCI Controller> mem 0x1c14000-0x1c140ff irq 21 on simplebus0
</span><span>usbus1: EHCI version 1.0
</span><span>usbus1 on ehci0
</span><span>ohci0: <Generic OHCI Controller> mem 0x1c14400-0x1c144ff irq 22 on simplebus0
</span><span>usbus2 on ohci0
</span><span>ahci0: <Allwinner Integrated AHCI controller> mem 0x1c18000-0x1c18fff irq 26 on simplebus0
</span><span>ahci0: AHCI v1.10 with 1 3Gbps ports, Port Multiplier not supported
</span><span>ahci0: quirks=0x2<NOPMP>
</span><span>ehci1: <Generic EHCI Controller> mem 0x1c1c000-0x1c1c0ff irq 27 on simplebus0
</span><span>usbus3: EHCI version 1.0
</span><span>usbus3 on ehci1
</span><span>ohci1: <Generic OHCI Controller> mem 0x1c1c400-0x1c1c4ff irq 28 on simplebus0
</span><span>usbus4 on ohci1
</span><span>gpioc0: <GPIO controller> on gpio0
</span><span>aw_wdog0: <Allwinner A10 Watchdog> mem 0x1c20c90-0x1c20c9f irq 38 on simplebus0
</span><span>aw_ir0: <Allwinner CIR controller> mem 0x1c21800-0x1c2183f irq 41 on simplebus0
</span><span>pcm0: <Allwinner Audio Codec> mem 0x1c22c00-0x1c22c3f irq 46 on simplebus0
</span><span>pcm0: cannot find codec clock
</span><span>device_attach: pcm0 attach returned 6
</span><span>aw_ts0: <Allwinner Touch Screen controller> mem 0x1c25000-0x1c250ff irq 48 on simplebus0
</span><span>uart0: <16750 or compatible> mem 0x1c28000-0x1c283ff irq 49 on simplebus0
</span><span>uart0: console (115384,n,8,1)
</span><span>gpioc1: <GPIO controller> on axp2xx_pmu0
</span><span>iic0: <I2C generic I/O> on iicbus0
</span><span>iic1: <I2C generic I/O> on iicbus1
</span><span>dwc0: <A20 Gigabit Ethernet Controller> mem 0x1c50000-0x1c5ffff irq 72 on simplebus0
</span><span>miibus0: <MII bus> on dwc0
</span><span>rlphy0: <RTL8201L 10/100 media interface> PHY 1 on miibus0
</span><span>rlphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
</span><span>dwc0: Ethernet address: 02:0a:09:03:27:08
</span><span>gpioled0: <GPIO LEDs> on ofwbus0
</span><span>cryptosoft0: <software crypto>
</span><span>Timecounters tick every 1.000 msec
</span><span>usbus0: 480Mbps High Speed USB v2.0
</span><span>usbus1: 480Mbps High Speed USB v2.0
</span><span>usbus2: 12Mbps Full Speed USB v1.0
</span><span>usbus3: 480Mbps High Speed USB v2.0
</span><span>usbus4: 12Mbps Full Speed USB v1.0
</span><span>Release APs
</span><span>ugen0.1: <Mentor Graphics OTG Root HUB> at usbus0
</span><span>Trying to mount root from ufs:/dev/ufs/rootfs [rw]...
</span><span>uhub0Root mount waiting for: on usbus0
</span><span> usbus0uhub0: <Mentor Graphics OTG Root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus0
</span><span> usbus1ugen1.1: <Generic EHCI root HUB> at usbus1
</span><span> usbus2uhub1 usbus3 on usbus1
</span><span> usbus4uhub1: <Generic EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus1
</span><span> CAMugen2.1: <Generic OHCI root HUB> at usbus2
</span><span>
</span><span>uhub2 on usbus2
</span><span>uhub2: <Generic OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus2
</span><span>ugen4.1: <Generic OHCI root HUB> at usbus4
</span><span>ugen3.1: <Generic EHCI root HUB> at usbus3
</span><span>uhub3 on usbus4
</span><span>uhub4 on usbus3
</span><span>uhub3: <Generic OHCI root HUB, class 9/0, rev 1.00/1.00, addr 1> on usbus4
</span><span>uhub4: <Generic EHCI root HUB, class 9/0, rev 2.00/1.00, addr 1> on usbus3
</span><span>mmc0: <MMC/SD bus> on aw_mmc0
</span><span>mmcsd0: 249GB <SDHC SD256 6.1 SN 35B0016A MFG 09/2020 by 159 TI> at mmc0 50.0MHz/4bit/32768-block
</span><span>mmc0: Failed to set VCCQ for card at relative address 20552
</span><span>uhub2: 1 port with 1 removable, self powered
</span><span>uhub3: 1 port with 1 removable, self powered
</span><span>uhub0: 1 port with 1 removable, self powered
</span><span>uhub1: 1 port with 1 removable, self powered
</span><span>uhub4: 1 port with 1 removable, self powered
</span><span>mountroot: waiting for device /dev/ufs/rootfs...
</span><span>lo0: link state changed to UP
</span><span>dwc0: link state changed to UP
</span></code></pre>
Toolchains adventures - Q4 20212022-01-03T18:17:00+00:002022-01-03T18:17:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q4-2021/<p>This is the third post in my toolchains adventures series. Please read the
<a rel="noopener" target="_blank" href="https://www.cambus.net/diving-into-toolchains/">introduction</a> and the <a rel="noopener" target="_blank" href="https://www.cambus.net/toolchains-adventures-q3-2021/">Q3 2021 report</a> if you want to get more context
about this journey.</p>
<p>The fourth quarter of 2021 started out in the best possible way, as I've
been granted commit access to the <strong>LLVM project</strong> on October 1st.</p>
<p>During the first part of October, I did commit a couple of micro-optimizations
to several compiler drivers along with small improvements in various places,
as highlighted in the commit list at the end of this post.</p>
<p>At the end of the month, I attended the OpenBSD h2k21 hackathon in Gouveia,
Portugal.</p>
<p>During the hackathon, I spent some time doing builds of LLVM from our base
system to do measurements and evaluate if it could make sense to build our
toolchain with <a rel="noopener" target="_blank" href="https://clang.llvm.org/docs/ThinLTO.html">ThinLTO</a> optimizations enabled. While full LTO builds
would be out of the question as our developers regularly build snapshots
of the base system (and often on laptops), <strong>ThinLTO</strong> typically achieves
a good compromise between optimizations and resources usage.</p>
<p>Unfortunately, my experiment didn't prove conclusive, and I quickly grew tired
of waiting hours between each run to check the results. I used LLVM 11.1.0 at
the time, and retesting more recently with LLVM 13.0.0 on a 4 CPUs virtual
machine with 16GB of RAM gave similar results. Running <code>time make -j4</code> in
<code>/usr/src/gnu/usr.bin/clang</code> after applying modifications to enable building
with ThinLTO resulted in a 7.3% increase in build time. Then, using the newly
built ThinLTO optimized toolchain, I rebuilt an optimized LLVM again and
the build was only 1.1% faster than the previous run.</p>
<p>Those preliminary benchmarks only measuring build time make me think there
is little point in enabling ThinLTO alone at this time, and that it should
be coupled with PGO (<strong>Profile-guided optimization</strong>) to be worth considering.</p>
<p>For the record, I used the following <a href="/files/openbsd/thinlto.diff">diff</a> to rebuild LLVM in base:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>Index: gnu/usr.bin/clang/Makefile.inc
</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">==================================================================
</span><span>RCS file: /cvs/src/gnu/usr.bin/clang/Makefile.inc,v
</span><span>retrieving revision 1.25
</span><span>diff</span><span style="font-style:italic;color:#fd971f;"> -u -p -r1</span><span>.25 Makefile.inc
</span><span>--- gnu/usr.bin/clang/Makefile.inc 21 Aug 2021 03:00:02</span><span style="font-style:italic;color:#fd971f;"> -0000</span><span> 1.25
</span><span>+++ gnu/usr.bin/clang/Makefile.inc 24 Oct 2021 16:18:15</span><span style="font-style:italic;color:#fd971f;"> -0000
</span><span>@@</span><span style="font-style:italic;color:#fd971f;"> -46</span><span>,6 +46,11 @@ CXXFLAGS+=</span><span style="font-style:italic;color:#fd971f;"> -fomit-frame-pointer
</span><span> NOPIE_FLAGS</span><span style="color:#f92672;">= </span><span>-fPIE
</span><span> .endif
</span><span>
</span><span>+# ThinLTO
</span><span>+.if ${MACHINE_ARCH} == </span><span style="color:#e6db74;">"amd64"
</span><span>+CXXFLAGS</span><span style="color:#f92672;">+= </span><span>-flto</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">thin
</span><span>+.endif
</span><span>+
</span><span> CPPFLAGS</span><span style="color:#f92672;">+= </span><span>-D__STDC_LIMIT_MACROS</span><span style="font-style:italic;color:#fd971f;"> -D__STDC_CONSTANT_MACROS </span><span>\
</span><span style="font-style:italic;color:#fd971f;"> -D__STDC_FORMAT_MACROS
</span></code></pre>
<p>The next thing I did was checking usage of <strong>.gnu.warning.</strong>* sections in our
C library. For an introduction to these sections, please refer to this
<a rel="noopener" target="_blank" href="https://ninjalj.blogspot.com/2011/11/your-own-linker-warnings-using-gnu.html">article</a>.</p>
<p>At the time of writing, <strong>libc functions</strong> for which we have .gnu.warning.*
sections are:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>.gnu.warning.strcpy:
</span><span> strcpy() is almost always misused, please use strlcpy()
</span><span>.gnu.warning.stpcpy:
</span><span> stpcpy() is dangerous; do not use it
</span><span>.gnu.warning.wcscat:
</span><span> wcscat() is almost always misused, please use wcslcat()
</span><span>.gnu.warning.sprintf:
</span><span> sprintf() is often misused, please use snprintf()
</span><span>.gnu.warning.tempnam:
</span><span> tempnam() possibly used unsafely; consider using mkstemp()
</span><span>.gnu.warning.vsprintf:
</span><span> vsprintf() is often misused, please use vsnprintf()
</span><span>.gnu.warning.mktemp:
</span><span> mktemp() possibly used unsafely; consider using mkstemp()
</span><span>.gnu.warning.strcat:
</span><span> strcat() is almost always misused, please use strlcat()
</span><span>.gnu.warning.wcscpy:
</span><span> wcscpy() is almost always misused, please use wcslcpy()
</span><span>.gnu.warning.rand_r:
</span><span> rand_r() is not random, it is deterministic.
</span><span>.gnu.warning.rand:
</span><span> rand() may return deterministic values, is that what you want?
</span><span>.gnu.warning.getwd:
</span><span> getwd() possibly used unsafely; consider using getcwd()
</span><span>.gnu.warning.random:
</span><span> random() may return deterministic values, is that what you want?
</span><span>.gnu.warning.tmpnam:
</span><span> tmpnam() possibly used unsafely; consider using mkstemp()
</span></code></pre>
<p>Support for emitting linker warnings when using a symbol for which a
.gnu.warning.symbol section exists is implemented in GNU linkers (ld and
gold), but currently not in LLVM's LLD linker. Since we switched to LLD
as the default linker on most of OpenBSD architectures, those warnings are
not emitted anymore for a majority of users.</p>
<p>I thus sent a <a rel="noopener" target="_blank" href="https://marc.info/?l=openbsd-tech&m=163507853319867&w=2">diff</a> to remove mentions of <strong>ld</strong> warning messages for the
mktemp(3), tmpnam(3), and tempnam(3) manual pages, but it was suggested that
we should instead try to get <strong>LLD</strong> to support this feature instead.
After discussing the matter with other developers during h2k21, this
is indeed the consensus.</p>
<p>On the last day of the hackathon, I packaged <a rel="noopener" target="_blank" href="https://openports.pl/path/devel/elfcat">elfcat</a>, which is a neat
ELF visualizer generating interactive HTML files from ELF binaries.</p>
<p>In November, I built <a rel="noopener" target="_blank" href="https://github.com/fcambus/gwcheck">gwcheck</a>, a small tool to display .gnu.warning.*
sections names in <strong>ELF objects</strong> along with their content, in order to check
which other projects used them. So far, aside from OpenBSD, it turned out that
FreeBSD, NetBSD, and DragonFly all use these sections in their libc, and that
glibc, Newlib, diet libc, uClibc do as well. I then added a comment about my
findings in the LLVM bug tracker <a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/issues/41353#issuecomment-981013806">issue</a> about adding support in LLD to
generate linker warnings when encountering them.</p>
<p>Regarding LLVM itself, I added support in <strong>llvm-readobj</strong> for reading <strong>ELF
core notes</strong> for both OpenBSD and NetBSD. Notes generated in those core files
provide additional information about the kernel state and CPU registers.
These notes are described in the core(5) manual pages for each of those
operating systems. Here is a link to the <a rel="noopener" target="_blank" href="https://man.openbsd.org/core.5">OpenBSD</a> version, and here is
one for the <a rel="noopener" target="_blank" href="https://man.netbsd.org/core.5">NetBSD</a> counterpart.</p>
<p>I have not much to report in Pkgsrc land for this quarter, the only
toolchains related <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/pkgsrc/commit/UfXqJMaMEgq2SQkD">commit</a> I got the chance to make was for updating
the <a rel="noopener" target="_blank" href="https://github.com/rui314/mold">mold</a> linker to the 1.0.0 version.</p>
<p>That's all for now. I absolutely would like to continue exploring the topic,
but I feel there is only so much I can do on my free time. Maybe I should
start considering working in the field full-time?</p>
<p>LLVM commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-12-20</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/f6ba5c4d5f228366a016534e7d1cf099d274fced">f6ba5c4</a></td><td>[llvm-readobj] Check ELFType value first when checking for OpenBSD notes</td></tr>
<tr><td>2021-11-29</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/878ff1f9f85f6c539efb9b8c00978011d381f278">878ff1f</a></td><td>[llvm-readobj] Add support for machine-independent NetBSD ELF core notes</td></tr>
<tr><td>2021-11-24</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/69deb1371fd4cd2fbf37a82cbc21df79c6d51c70">69deb13</a></td><td>[clang][scan-build] Use cc/c++ instead of gcc/g++ on FreeBSD</td></tr>
<tr><td>2021-11-02</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/650311737eee207171f2407da8ecea780863fa1f">6503117</a></td><td>[llvm-readobj] Add support for reading OpenBSD ELF core notes</td></tr>
<tr><td>2021-10-30</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/6ecd4a4d01a3f71dc6590194dd00f96550c2ab04">6ecd4a4</a></td><td>[clang][scan-build] Use uname -s to detect the operating system</td></tr>
<tr><td>2021-10-21</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/b471e25a59241b6b60e75494ca7b8d775a4131a2">b471e25</a></td><td>[clang] Support __float128 on DragonFlyBSD</td></tr>
<tr><td>2021-10-21</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/9635b2951da18ade951341f7ec6b9a7b8eb7cba3">9635b29</a></td><td>[docs] Fix broken link rendering in the LLVM Coding Standards</td></tr>
<tr><td>2021-10-16</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/4d7c7d87e46e3589594aa789c543e2a8b667d3f2">4d7c7d8</a></td><td>[docs] Mention DragonFlyBSD as a supported platform for LLVM</td></tr>
<tr><td>2021-10-15</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/ecef0359538ca54a5374dbf3547a395adc326bbe">ecef035</a></td><td>[Driver][NetBSD] Use Triple reference instead of ToolChain.getTriple()</td></tr>
<tr><td>2021-10-14</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/8ecbcd058fbd552375fda614f36a1e01755c2620">8ecbcd0</a></td><td>[Driver][Darwin] Use T reference instead of getToolChain().getTriple()</td></tr>
<tr><td>2021-10-14</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/f7a3214306cb83c350a89e2247f67983dbd792ea">f7a3214</a></td><td>[Driver][WebAssembly] Use ToolChain reference instead of getToolChain()</td></tr>
<tr><td>2021-10-09</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/6417260a57dd4292ce91f2357479831e3fcf177e">6417260</a></td><td>[Driver][OpenBSD] Use ToolChain reference instead of getToolChain()</td></tr>
<tr><td>2021-10-08</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/1f90b365bd626e5d7d963106692143699c69f616">1f90b36</a></td><td>[Driver][NetBSD] Use ToolChain reference instead of getToolChain()</td></tr>
<tr><td>2021-10-06</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/f0ffff43b765ee0484e5303edc82f9e528a3547e">f0ffff4</a></td><td>[CMake] Fix typo in error message for LLD in bootstrap builds</td></tr>
</tbody></table>
OpenBSD on the VIA Eden X2 powered HP t510 Thin Client2021-11-25T11:55:00+00:002021-11-25T11:55:00+00:00Unknownhttps://www.cambus.net/openbsd-on-the-via-eden-x2-powered-hp-t510-thin-client/<p>Back in 2017, I bought two used HP thin clients on a local auction site, the
<a rel="noopener" target="_blank" href="https://www.parkytowers.me.uk/thin/hp/t5570/">t5570e</a> and the <a rel="noopener" target="_blank" href="https://www.parkytowers.me.uk/thin/hp/t510/">t510</a>, both of them powered by VIA x86-64 CPUs. In
this article, I will focus on the t510, which is the more powerful of the two.</p>
<p>The CPU in this machine is a <strong>VIA Eden X2 U4200</strong>, which is a dual-core
<strong>x86-64</strong> CPU running at 1GHz released in 2011. For those interested about
the status of those CPUs, I wrote an article about <a rel="noopener" target="_blank" href="https://www.cambus.net/the-future-of-via-x86-processors/">the future of VIA x86
processors</a> back in 2018.</p>
<p>The machine came equipped with 4GB of RAM and a 16GB SATA module from Apacer
which I replaced with a SSD. On the plus side, those machines are fanless and
all x86-64 VIA CPUs have the <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/VIA_PadLock">PadLock</a> features, making them an interesting
alternative to older Celerons which were lacking <strong>AES-NI</strong> support. On the
minus side, the CPU is quite slow and the power consumption of the device is
not that light.</p>
<p>Xenocara works on this machine using the <a rel="noopener" target="_blank" href="https://cgit.freedesktop.org/openchrome/xf86-video-openchrome">openchrome</a> driver, which I
updated to version <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/xenocara/commit/63bx9z1nqXyscwsa">0.6.176</a> back in 2018 in order to fix display issues
on my system, thanks to matthieu@ who was kind enough to give me some
pointers about the process. I then updated it to the <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/xenocara/commit/BHwf7TMIp1fZSvYE">0.6.182</a> version
in 2019, and finally to the <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/xenocara/commit/jJnb7elWE6Y81VPL">0.6.409</a> version a couple days ago.</p>
<p>Here is the result of a quick <strong>md5 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>MD5 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 52e5f9c9e6f656f3e1800dfa5579d089
</span><span>Time = 1.000000 seconds
</span><span>Speed = 100000000.000000 bytes/second
</span></code></pre>
<p>Here is the result of the <strong>sha1 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>SHA1 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 74a57b897cc581defa5b3a359fa762a1b83a60e8
</span><span>Time = 1.800000 seconds
</span><span>Speed = 55555555.555556 bytes/second
</span></code></pre>
<p>For the record, LibreSSL speed benchmark results are available <a href="/files/openbsd/openssl-speed-via-eden-x2.txt">here</a>.</p>
<p>System message buffer (dmesg output):</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>OpenBSD 7.0-current (GENERIC.MP) #117: Wed Nov 24 01:03:57 MST 2021
</span><span> deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
</span><span>real mem = 4143775744 (3951MB)
</span><span>avail mem = 4002222080 (3816MB)
</span><span>random: good seed from bootblocks
</span><span>mpath0 at root
</span><span>scsibus0 at mpath0: 256 targets
</span><span>mainbus0 at root
</span><span>bios0 at mainbus0: SMBIOS rev. 2.6 @ 0xfd6d0 (36 entries)
</span><span>bios0: vendor American Megatrends Inc. version "786R11 v1.05" date 06/03/2013
</span><span>bios0: Hewlett-Packard HP t510 Thin Client
</span><span>acpi0 at bios0: ACPI 4.0
</span><span>acpi0: sleep states S0 S5
</span><span>acpi0: tables DSDT FACP APIC MCFG OEMB HPET SSDT
</span><span>acpi0: wakeup devices NP2S(S0) NP3S(S0) USB0(S0) USB1(S0) USB2(S0) USB3(S0) EHCI(S0) SBRG(S5) P0P4(S5) AZAL(S0)
</span><span>acpitimer0 at acpi0: 3579545 Hz, 24 bits
</span><span>acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
</span><span>cpu0 at mainbus0: apid 0 (boot processor)
</span><span>cpu0: VIA Eden X2 U4200 @ 1.0+ GHz, 1000.19 MHz, 06-0f-0d
</span><span>cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,MWAIT,VMX,EST,TM2,SSSE3,CX16,xTPR,SSE4.1,POPCNT,NXE,LONG,LAHF,PERF
</span><span>cpu0: 64KB 64b/line 16-way I-cache, 64KB 64b/line 16-way D-cache, 1MB 64b/line 16-way L2 cache
</span><span>cpu0: ITLB 128 4KB entries 8-way
</span><span>cpu0: DTLB 128 4KB entries 8-way
</span><span>mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
</span><span>cpu0: apic clock running at 200MHz
</span><span>cpu0: RNG AES AES-CTR SHA1 SHA256 RSA
</span><span>cpu0: mwait min=64, max=64, C-substates=0.2.2.2.2, IBE
</span><span>cpu1 at mainbus0: apid 2 (application processor)
</span><span>cpu1: VIA Eden X2 U4200 @ 1.0+ GHz, 1000.05 MHz, 06-0f-0d
</span><span>cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,MWAIT,VMX,EST,TM2,SSSE3,CX16,xTPR,SSE4.1,POPCNT,NXE,LONG,LAHF,PERF
</span><span>cpu1: 64KB 64b/line 16-way I-cache, 64KB 64b/line 16-way D-cache, 1MB 64b/line 16-way L2 cache
</span><span>cpu1: ITLB 128 4KB entries 8-way
</span><span>cpu1: DTLB 128 4KB entries 8-way
</span><span>cpu1: disabling user TSC (skew=-220)
</span><span>ioapic0 at mainbus0: apid 3 pa 0xfec00000, version 3, 24 pins
</span><span>ioapic1 at mainbus0: apid 4 pa 0xfecc0000, version 3, 24 pins
</span><span>acpimcfg0 at acpi0
</span><span>acpimcfg0: addr 0xe0000000, bus 0-255
</span><span>acpihpet0 at acpi0: 14318179 Hz
</span><span>acpiprt0 at acpi0: bus 0 (PCI0)
</span><span>acpiprt1 at acpi0: bus 1 (NBP0)
</span><span>acpiprt2 at acpi0: bus 2 (NBP1)
</span><span>acpiprt3 at acpi0: bus 3 (NBP2)
</span><span>acpiprt4 at acpi0: bus 5 (NBP3)
</span><span>acpiprt5 at acpi0: bus 6 (P0P4)
</span><span>acpipci0 at acpi0 PCI0
</span><span>acpicmos0 at acpi0
</span><span>acpibtn0 at acpi0: SLPB
</span><span>acpibtn1 at acpi0: PWRB
</span><span>acpicpu0 at acpi0: C1(1000@1 halt), PSS
</span><span>acpicpu1 at acpi0: C1(1000@1 halt), PSS
</span><span>acpipwrres0 at acpi0: URP1
</span><span>acpipwrres1 at acpi0: URP2
</span><span>acpipwrres2 at acpi0: FDDP
</span><span>acpipwrres3 at acpi0: LPTP
</span><span>cpu0: Enhanced SpeedStep 1000 MHz: speeds: 1000, 900, 800 MHz
</span><span>pci0 at mainbus0 bus 0
</span><span>pchb0 at pci0 dev 0 function 0 "VIA VX900 Host" rev 0x80
</span><span>pchb1 at pci0 dev 0 function 1 "VIA VX900 Error Reporting" rev 0x00
</span><span>pchb2 at pci0 dev 0 function 2 "VIA VX900 Host" rev 0x00
</span><span>pchb3 at pci0 dev 0 function 3 "VIA VX900 DRAM" rev 0x00
</span><span>pchb4 at pci0 dev 0 function 4 "VIA VX900 Host" rev 0x00
</span><span>pchb5 at pci0 dev 0 function 5 "VIA VX900 APIC" rev 0x00
</span><span>pchb6 at pci0 dev 0 function 6 "VIA VX900 Scratch" rev 0x00
</span><span>pchb7 at pci0 dev 0 function 7 "VIA VX900 Host" rev 0x00
</span><span>vga1 at pci0 dev 1 function 0 "VIA Chrome9 HD" rev 0x00
</span><span>wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
</span><span>wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
</span><span>ppb0 at pci0 dev 3 function 0 "VIA VX900 PCIE" rev 0x00: msi
</span><span>pci1 at ppb0 bus 1
</span><span>ppb1 at pci0 dev 3 function 1 "VIA VX900 PCIE" rev 0x00: msi
</span><span>pci2 at ppb1 bus 2
</span><span>ppb2 at pci0 dev 3 function 2 "VIA VX900 PCIE" rev 0x00: msi
</span><span>pci3 at ppb2 bus 3
</span><span>ppb3 at pci0 dev 3 function 3 "VIA VX900 PCIE" rev 0x00: msi
</span><span>pci4 at ppb3 bus 5
</span><span>bge0 at pci4 dev 0 function 0 "Broadcom BCM57780" rev 0x01, BCM57780 A1 (0x57780001): msi, address c8:cb:b8:1f:42:6a
</span><span>brgphy0 at bge0 phy 1: BCM57780 10/100/1000baseT PHY, rev. 1
</span><span>pchb8 at pci0 dev 3 function 4 "VIA VX900 PCIE" rev 0x00
</span><span>pciide0 at pci0 dev 15 function 0 "VIA VX900 IDE" rev 0x00: ATA133, channel 0 configured to compatibility, channel 1 configured to compatibility
</span><span>wd0 at pciide0 channel 0 drive 1: <M4-CT128M4SSD1>
</span><span>wd0: 16-sector PIO, LBA48, 122104MB, 250069680 sectors
</span><span>wd0(pciide0:0:1): using PIO mode 4, Ultra-DMA mode 5
</span><span>pciide0: channel 1 disabled (no drives)
</span><span>uhci0 at pci0 dev 16 function 0 "VIA VT83C572 USB" rev 0xa0: apic 3 int 20
</span><span>uhci1 at pci0 dev 16 function 1 "VIA VT83C572 USB" rev 0xa0: apic 3 int 22
</span><span>uhci2 at pci0 dev 16 function 2 "VIA VT83C572 USB" rev 0xa0: apic 3 int 21
</span><span>uhci3 at pci0 dev 16 function 3 "VIA VT83C572 USB" rev 0xa0: apic 3 int 23
</span><span>ehci0 at pci0 dev 16 function 4 "VIA VT6202 USB" rev 0x90: apic 3 int 23
</span><span>usb0 at ehci0: USB revision 2.0
</span><span>uhub0 at usb0 configuration 1 interface 0 "VIA EHCI root hub" rev 2.00/1.00 addr 1
</span><span>viapm0 at pci0 dev 17 function 0 "VIA VX900 ISA" rev 0x00: SMI
</span><span>iic0 at viapm0
</span><span>pchb9 at pci0 dev 17 function 7 "VIA VX800 Host" rev 0x00
</span><span>ppb4 at pci0 dev 19 function 0 "VIA VX800" rev 0x00
</span><span>pci5 at ppb4 bus 6
</span><span>azalia0 at pci0 dev 20 function 0 "VIA HD Audio" rev 0x20: msi
</span><span>azalia0: codecs: VIA/0x0397
</span><span>audio0 at azalia0
</span><span>usb1 at uhci0: USB revision 1.0
</span><span>uhub1 at usb1 configuration 1 interface 0 "VIA UHCI root hub" rev 1.00/1.00 addr 1
</span><span>usb2 at uhci1: USB revision 1.0
</span><span>uhub2 at usb2 configuration 1 interface 0 "VIA UHCI root hub" rev 1.00/1.00 addr 1
</span><span>usb3 at uhci2: USB revision 1.0
</span><span>uhub3 at usb3 configuration 1 interface 0 "VIA UHCI root hub" rev 1.00/1.00 addr 1
</span><span>usb4 at uhci3: USB revision 1.0
</span><span>uhub4 at usb4 configuration 1 interface 0 "VIA UHCI root hub" rev 1.00/1.00 addr 1
</span><span>isa0 at mainbus0
</span><span>isadma0 at isa0
</span><span>com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
</span><span>pckbc0 at isa0 port 0x60/5 irq 1 irq 12
</span><span>pckbd0 at pckbc0 (kbd slot)
</span><span>wskbd0 at pckbd0: console keyboard, using wsdisplay0
</span><span>pcppi0 at isa0 port 0x61
</span><span>spkr0 at pcppi0
</span><span>lpt0 at isa0 port 0x378/4 irq 7
</span><span>vmm0 at mainbus0: VMX (using slow L1TF mitigation)
</span><span>dt: 445 probes
</span><span>vscsi0 at root
</span><span>scsibus1 at vscsi0: 256 targets
</span><span>softraid0 at root
</span><span>scsibus2 at softraid0: 256 targets
</span><span>root on wd0a (4561d3363de7f2a6.a) swap on wd0b dump on wd0b
</span></code></pre>
<p>Sensors output:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>$ sysctl hw.sensors
</span><span>hw.sensors.cpu0.temp0=49.00 degC
</span></code></pre>
<p>PCI device data:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span># pcidump
</span><span>Domain /dev/pci0:
</span><span> 0:0:0: VIA VX900 Host
</span><span> 0:0:1: VIA VX900 Error Reporting
</span><span> 0:0:2: VIA VX900 Host
</span><span> 0:0:3: VIA VX900 DRAM
</span><span> 0:0:4: VIA VX900 Host
</span><span> 0:0:5: VIA VX900 APIC
</span><span> 0:0:6: VIA VX900 Scratch
</span><span> 0:0:7: VIA VX900 Host
</span><span> 0:1:0: VIA Chrome9 HD
</span><span> 0:3:0: VIA VX900 PCIE
</span><span> 0:3:1: VIA VX900 PCIE
</span><span> 0:3:2: VIA VX900 PCIE
</span><span> 0:3:3: VIA VX900 PCIE
</span><span> 0:3:4: VIA VX900 PCIE
</span><span> 0:15:0: VIA VX900 IDE
</span><span> 0:16:0: VIA VT83C572 USB
</span><span> 0:16:1: VIA VT83C572 USB
</span><span> 0:16:2: VIA VT83C572 USB
</span><span> 0:16:3: VIA VT83C572 USB
</span><span> 0:16:4: VIA VT6202 USB
</span><span> 0:17:0: VIA VX900 ISA
</span><span> 0:17:7: VIA VX800 Host
</span><span> 0:19:0: VIA VX800
</span><span> 0:20:0: VIA HD Audio
</span><span> 5:0:0: Broadcom BCM57780
</span></code></pre>
NetBSD, CTWM, and Spleen2021-10-09T19:52:00+00:002021-10-09T19:52:00+00:00Unknownhttps://www.cambus.net/netbsd-ctwm-and-spleen/<p>Back in the fall of 2020, I was approached about adding <a rel="noopener" target="_blank" href="https://github.com/fcambus/spleen">Spleen</a> to
the NetBSD's <strong>xsrc</strong> repository. Needless to say, I wasn't difficult to
convince, and imported Spleen 1.8.2 as <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/xsrc/commit/ltINGQFMDlVR4drC">font-spleen-misc</a>. With this
being done, nia@ added all the required glue to hook the fonts to the
build, and then changed the default CTWM configuration to do <a rel="noopener" target="_blank" href="https://www.freshbsd.org/netbsd/src/commit/KkU41ZuoYV9FvBrC">automatic
font scaling based on screen size</a>, and make Spleen the default font.</p>
<p>CTWM had previously been promoted as the <a rel="noopener" target="_blank" href="https://blog.netbsd.org/tnf/entry/default_window_manager_switched_to">default window manager</a> on
NetBSD, and saw several tweaks and improvements to make it look more
modern, notably with a nice orange themed menu.</p>
<p>Below is a screenshot of CTWM with <strong>Spleen 8x16</strong>, running on my <strong>HP
t510</strong> Thin Client plugged to a 1600x900 monitor, showing <strong>JED</strong>,
<strong>Lynx</strong>, <strong>xcalc</strong> and <strong>xv</strong>.</p>
<p><img src="/content/2021/10/netbsd-ctwm-spleen.png" alt="CTWM on NetBSD 9.99.90" /></p>
<p>One last thing to note, there are now live images available in <strong>-current</strong>
for amd64, and NetBSD 10 will be the first release to officially provide
them. While <a rel="noopener" target="_blank" href="https://wiki.netbsd.org/ports/evbarm/">NetBSD/evbarm</a> has had live images for a long time now,
their availability on amd64 is a much welcome addition, as this allows to
easily test NetBSD's default CTWM configuration :-)</p>
<p>The most recent version is currently <strong>NetBSD-9.99.90-amd64-live.img.gz</strong>
and can be downloaded <a rel="noopener" target="_blank" href="https://nycdn.netbsd.org/pub/NetBSD-daily/HEAD/latest/images/">here</a>.</p>
<p>Once again, thanks to Nia for doing all of this!</p>
Toolchains adventures - Q3 20212021-10-01T23:16:00+00:002021-10-01T23:16:00+00:00Unknownhttps://www.cambus.net/toolchains-adventures-q3-2021/<p>I've been keeping myself busy since I posted the "<a rel="noopener" target="_blank" href="https://www.cambus.net/diving-into-toolchains/">Diving into toolchains</a>"
article at the beginning of June, so here is an update detailing what I've
been up to during the past couple of months.</p>
<p>At the end of June, I went through the FSF copyright assignment process for
both <strong>Binutils</strong> and <strong>GDB</strong>, which now allows me to contribute larger
changes to these codebases. I thus updated the <a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=77db4723ddda2a5eb20876e8a818f77ffa7dafc8">NetBSD system call table</a>
in GDB, and added support to readelf for <a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=98ca73afe51e1e921915c37f242c88d4d445841c">reading OpenBSD ELF core notes</a>.</p>
<p>In Pkgsrc land, I packaged and imported <a rel="noopener" target="_blank" href="https://github.com/rui314/mold">mold</a>, a new linker that is
optimized for modern multi-core machines, and updated our binutils package
to the latest version.</p>
<p>At the end of August, I attended the <strong>OpenBSD k2k21 hackathon</strong>, and one of
the goals I had was to get <a rel="noopener" target="_blank" href="https://clang.llvm.org/docs/SourceBasedCodeCoverage.html">source-based code coverage</a> working in LLVM.
The first part of this was to find how to allow the compiler driver to
link against the <strong>libclang_rt.profile</strong> library when passing the
<strong>-fprofile-instr-generate</strong> and <strong>-fcoverage-mapping</strong> options to Clang.
Once I figured the <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/src/commit/uWsA4smmd2wX3UBC">magic incantation</a>, I committed my change to src
and <a rel="noopener" target="_blank" href="https://reviews.llvm.org/D109244">sent it upstream</a> where it got committed and backported to the
LLVM 13 branch. With this part sorted, the next step was to build and ship
the library in the base system. I added <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/src/commit/mQ6P5wL9QLzzIzbt">build infrastructure</a> for the
library in base, and <a rel="noopener" target="_blank" href="https://www.freshbsd.org/openbsd/src/commit/nVaOYoXmnskB2gez">linked it to the build</a>. It is now enabled on
architectures where Clang is built.</p>
<p>To illustrate what we can do with the source-based code coverage, let's
take the following C program:</p>
<pre data-lang="c" style="background-color:#272822;color:#f8f8f2;" class="language-c "><code class="language-c" data-lang="c"><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><stdio.h>
</span><span>
</span><span style="font-style:italic;color:#66d9ef;">int
</span><span style="color:#a6e22e;">main</span><span>()
</span><span>{
</span><span> </span><span style="color:#66d9ef;">printf</span><span>(</span><span style="color:#e6db74;">" >o_/ >o_/ >o_/ </span><span style="color:#ae81ff;">\n</span><span style="color:#e6db74;">"</span><span>);
</span><span> </span><span style="color:#f92672;">return </span><span style="color:#ae81ff;">0</span><span>;
</span><span>
</span><span> </span><span style="color:#66d9ef;">printf</span><span>(</span><span style="color:#e6db74;">"*PAN!* *PAN!* *PAN!*</span><span style="color:#ae81ff;">\n</span><span style="color:#e6db74;">"</span><span>);
</span><span>}
</span></code></pre>
<p>Let's build and instrument it to emit profile data:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>clang -fprofile-instr-generate -fcoverage-mapping ducks.c -o ducks
</span></code></pre>
<p>And we can now run it to collect and process profile data:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>LLVM_PROFILE_FILE="ducks.profraw" ./ducks
</span><span>llvm-profdata merge -sparse ducks.profraw -o ducks.profdata
</span><span>llvm-cov show ./ducks -instr-profile=ducks.profdata
</span></code></pre>
<p>We can see that no ducks were harmed during this experiment:</p>
<p><img src="/content/2021/10/ducks.png" alt="Ducks profile" title="Ducks profiling" /></p>
<p>Coverage reports can also be created by llvm-cov:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>llvm-cov report ./ducks -instr-profile=ducks.profdata
</span><span>
</span><span>Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover
</span><span>-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
</span><span>/home/f/ducks/ducks.c 2 1 50.00% 1 0 100.00% 6 1 83.33%
</span><span>-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
</span><span>TOTAL 2 1 50.00% 1 0 100.00% 6 1 83.33%
</span></code></pre>
<p>Using the <strong>LLVM_PROFILE_FILE</strong> environment variable, it is possible to
do several runs with different options and/or input files and get a new
<strong>.profraw</strong> file each time. All those files can then be merged using
<strong>llvm-profdata</strong>, which is pretty useful for doing coverage reports from
unit tests.</p>
<p>On top of the OpenBSD related changes I've been contributing upstream to
LLVM, I've been continuing my experiments with the build system. I've also
been reading documentation about various parts of the toolchain, sending
diffs when encountering mistakes or things which could be improved.</p>
<p>binutils and GDB commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-09-11</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=98ca73afe51e1e921915c37f242c88d4d445841c">98ca73a</a></td><td>Add support to readelf for reading OpenBSD ELF core notes</td></tr>
<tr><td>2021-07-14</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=77db4723ddda2a5eb20876e8a818f77ffa7dafc8">77db472</a></td><td>Update the NetBSD system call table to match NetBSD-current</td></tr>
</tbody></table>
<p>Pkgsrc toolchains related commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-09-27</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/65675ea811f6d03c306ce7f7c0025b3a54c4d616">65675ea</a></td><td>Update to mold 0.9.6</td></tr>
<tr><td>2021-09-11</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/871f328dd67d65399dd1c14fb9399facbee7e1ce">871f328</a></td><td>Update to binutils 2.37</td></tr>
<tr><td>2021-09-11</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/053d0f2eb4be764d374dff859c8fe3f1d0e1b661">53d0f2e</a></td><td>Update to mold 0.9.5</td></tr>
<tr><td>2021-07-29</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/1b5d5857ac970d79e15d7c766626956da3a65e68">1b5d585</a></td><td>Import mold 0.9.3</td></tr>
</tbody></table>
<p>LLVM commits:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-09-30</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/97a0ba475d105838bd9bb7ed8506f599210995c7">97a0ba4</a></td><td>[clang] Update Clang version from 13 to 14 in scan-build.1</td></tr>
<tr><td>2021-09-30</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/01641f665f5a3f94fc9e2bba598b5a65a6a7bd01">01641f6</a></td><td>[clang] Fix sentence in the usage section of ThinLTO docs</td></tr>
<tr><td>2021-09-29</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/7a7caf97012f53172743d650fd3c97bce99f86ef">7a7caf9</a></td><td>[clang] Fix library name (libsupc++) in the admonition note</td></tr>
<tr><td>2021-09-28</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/5b125a49ba9f52cb6b24767f3c98ce623a2d5207">5b125a4</a></td><td>[CMake] Add detection for the mold linker in AddLLVM.cmake</td></tr>
<tr><td>2021-09-24</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/626e2a6c6236d2fd7582928a0363d381c55eb43d">626e2a6</a></td><td>[compiler-rt] Use portable "#!/usr/bin/env bash" shebang for tests</td></tr>
<tr><td>2021-09-24</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/4ed05312a1557b2f2552298a3aac12c2e224d77e">4ed0531</a></td><td>[docs] Document the --print-passes flag in opt</td></tr>
<tr><td>2021-09-23</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/7f5ca8cc2158debe66663f09eb19b4613e75e124">7f5ca8c</a></td><td>[clang] Use portable "#!/usr/bin/env bash" shebang for tools and utils</td></tr>
<tr><td>2021-09-17</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/b588f5d665aa01fe88921fe2ffb7256fdedfbfb0">b588f5d</a></td><td>[clang][scan-build] Use cc/c++ instead of gcc/g++ on OpenBSD</td></tr>
<tr><td>2021-09-07</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/4787ef3d0f0abfdc041d418aba28a7e6473f0766">4787ef3</a></td><td>[compiler-rt] Document that builtins is known to work on OpenBSD</td></tr>
<tr><td>2021-09-03</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/466451c6616272d8c779618b92b0ae80f394a795">466451c</a></td><td>[clang] Allow the OpenBSD driver to link the libclang_rt.profile library</td></tr>
<tr><td>2021-07-27</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/1862ffe25a2e927ecae012f5f0c4cdf7c3fc1b67">1862ffe</a></td><td>[clang] Fix a typo in the manual page: s/contraint/constraint</td></tr>
<tr><td>2021-07-23</td><td><a rel="noopener" target="_blank" href="https://github.com/llvm/llvm-project/commit/bc96aa9f2c9b25ae65a7e05dbbff8c28079db9c9">bc96aa9</a></td><td>[clang] Fix typos in Options.td and regen ClangCommandLineReference.rst</td></tr>
</tbody></table>
OpenBSD on the Vortex86DX CPU2021-09-24T13:12:00+00:002021-09-24T13:12:00+00:00Unknownhttps://www.cambus.net/openbsd-on-the-vortex86dx-cpu/<p>This is the OpenBSD counterpart of my article about running <a rel="noopener" target="_blank" href="https://www.cambus.net/netbsd-on-the-vortex86dx-cpu/">NetBSD on
the Vortex86DX CPU</a>, and its purpose is mostly to archive a <strong>dmesg</strong>
entry and various benchmarks for this machine. I should note that with
only 256MB of RAM, the machine is too constrained to do kernel and
libraries relinking in a timely manner, due to swapping.</p>
<p>For more information and background about the hardware, please refer to
my other article.</p>
<p>Here is the result of a quick <strong>md5 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>MD5 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 52e5f9c9e6f656f3e1800dfa5579d089
</span><span>Time = 2.398437 seconds
</span><span>Speed = 41693819.766790 bytes/second
</span></code></pre>
<p>Here is the result of the <strong>sha1 -t</strong> benchmark:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>SHA1 time trial. Processing 10000 10000-byte blocks...
</span><span>Digest = 74a57b897cc581defa5b3a359fa762a1b83a60e8
</span><span>Time = 5.648437 seconds
</span><span>Speed = 17704012.632167 bytes/second
</span></code></pre>
<p>For the record, LibreSSL speed benchmark results are available <a href="/files/openbsd/openssl-speed-vortex.txt">here</a>.</p>
<p>System message buffer (dmesg output):</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>OpenBSD 7.0 (GENERIC) #203: Wed Sep 22 19:24:38 MDT 2021
</span><span> deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC
</span><span>real mem = 267927552 (255MB)
</span><span>avail mem = 246661120 (235MB)
</span><span>random: good seed from bootblocks
</span><span>mpath0 at root
</span><span>scsibus0 at mpath0: 256 targets
</span><span>mainbus0 at root
</span><span>bios0 at mainbus0: date 10/29/10, BIOS32 rev. 0 @ 0xf0010
</span><span>pcibios0 at bios0: rev 3.0 @ 0xf0000/0x10000
</span><span>pcibios0: PCI IRQ Routing Table rev 1.0 @ 0xf3a80/224 (12 entries)
</span><span>pcibios0: no compatible PCI ICU found: ICU vendor 0x17f3 product 0x6031
</span><span>pcibios0: Warning, unable to fix up PCI interrupt routing
</span><span>pcibios0: PCI bus #0 is the last bus
</span><span>bios0: ROM list: 0xc0000/0x8000 0xe9400/0x200!
</span><span>cpu0 at mainbus0: (uniprocessor)
</span><span>cpu0: Vortex86 SoC (586-class) 1.01 GHz, 05-02-02
</span><span>cpu0: FPU,TSC,CX8
</span><span>pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
</span><span>pchb0 at pci0 dev 0 function 0 "RDC R6021 Host" rev 0x02
</span><span>vga1 at pci0 dev 3 function 0 "XGI Technology Volari Z7" rev 0x00
</span><span>wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
</span><span>wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
</span><span>pcib0 at pci0 dev 7 function 0 "RDC R6031 ISA" rev 0x02
</span><span>vte0 at pci0 dev 8 function 0 "RDC R6040 Ethernet" rev 0x00: irq 10, address 00:1b:eb:22:16:5c
</span><span>rdcphy0 at vte0 phy 1: R6040 10/100 PHY, rev. 1
</span><span>ohci0 at pci0 dev 10 function 0 "RDC R6060 USB" rev 0x12: irq 11, version 1.0, legacy support
</span><span>ehci0 at pci0 dev 10 function 1 "RDC R6061 USB2" rev 0x03: irq 11
</span><span>usb0 at ehci0: USB revision 2.0
</span><span>uhub0 at usb0 configuration 1 interface 0 "RDC EHCI root hub" rev 2.00/1.00 addr 1
</span><span>ohci1 at pci0 dev 11 function 0 "RDC R6060 USB" rev 0x12: irq 11, version 1.0, legacy support
</span><span>ehci1 at pci0 dev 11 function 1 "RDC R6061 USB2" rev 0x03: irq 11
</span><span>usb1 at ehci1: USB revision 2.0
</span><span>uhub1 at usb1 configuration 1 interface 0 "RDC EHCI root hub" rev 2.00/1.00 addr 1
</span><span>pciide0 at pci0 dev 12 function 0 "RDC R1011 IDE" rev 0x01: DMA (unsupported), channel 0 configured to compatibility, channel 1 configured to compatibility
</span><span>pciide0: channel 0 ignored (not responding; disabled or no drives?)
</span><span>pciide0: channel 1 ignored (not responding; disabled or no drives?)
</span><span>isa0 at pcib0
</span><span>isadma0 at isa0
</span><span>pckbc0 at isa0 port 0x60/5 irq 1 irq 12
</span><span>pckbd0 at pckbc0 (kbd slot)
</span><span>wskbd0 at pckbd0: console keyboard, using wsdisplay0
</span><span>pcppi0 at isa0 port 0x61
</span><span>spkr0 at pcppi0
</span><span>npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
</span><span>usb2 at ohci0: USB revision 1.0
</span><span>uhub2 at usb2 configuration 1 interface 0 "RDC OHCI root hub" rev 1.00/1.00 addr 1
</span><span>usb3 at ohci1: USB revision 1.0
</span><span>uhub3 at usb3 configuration 1 interface 0 "RDC OHCI root hub" rev 1.00/1.00 addr 1
</span><span>dt: 445 probes
</span><span>umass0 at uhub1 port 2 configuration 1 interface 0 "SanDisk Cruzer Switch" rev 2.00/1.27 addr 2
</span><span>umass0: using SCSI over Bulk-Only
</span><span>scsibus1 at umass0: 2 targets, initiator 0
</span><span>sd0 at scsibus1 targ 1 lun 0: <SanDisk, Cruzer Switch, 1.27> removable serial.07815572120302108502
</span><span>sd0: 7633MB, 512 bytes/sector, 15633408 sectors
</span><span>uhidev0 at uhub2 port 1 configuration 1 interface 0 "Lenovo ThinkPad Compact USB Keyboard with TrackPoint" rev 2.00/3.30 addr 2
</span><span>uhidev0: iclass 3/1
</span><span>ukbd0 at uhidev0: 8 variable keys, 6 key codes
</span><span>wskbd1 at ukbd0 mux 1
</span><span>wskbd1: connecting to wsdisplay0
</span><span>uhidev1 at uhub2 port 1 configuration 1 interface 1 "Lenovo ThinkPad Compact USB Keyboard with TrackPoint" rev 2.00/3.30 addr 2
</span><span>uhidev1: iclass 3/1, 22 report ids
</span><span>ums0 at uhidev1 reportid 1: 5 buttons, Z and W dir
</span><span>wsmouse0 at ums0 mux 0
</span><span>ucc0 at uhidev1 reportid 16: 573 usages, 18 keys, array
</span><span>wskbd2 at ucc0 mux 1
</span><span>wskbd2: connecting to wsdisplay0
</span><span>uhid0 at uhidev1 reportid 17: input=2, output=0, feature=0
</span><span>uhid1 at uhidev1 reportid 19: input=8, output=8, feature=8
</span><span>uhid2 at uhidev1 reportid 21: input=2, output=0, feature=0
</span><span>uhid3 at uhidev1 reportid 22: input=2, output=0, feature=0
</span><span>uaudio0 at uhub2 port 2 configuration 1 interface 1 "ABC C-Media USB Audio Device" rev 1.10/1.00 addr 3
</span><span>uaudio0: class v1, full-speed, sync, channels: 2 play, 1 rec, 8 ctls
</span><span>audio0 at uaudio0
</span><span>uhidev2 at uhub2 port 2 configuration 1 interface 3 "ABC C-Media USB Audio Device" rev 1.10/1.00 addr 3
</span><span>uhidev2: iclass 3/0
</span><span>ucc1 at uhidev2: 11 usages, 3 keys, enum
</span><span>wskbd3 at ucc1 mux 1
</span><span>wskbd3: connecting to wsdisplay0
</span><span>vscsi0 at root
</span><span>scsibus2 at vscsi0: 256 targets
</span><span>softraid0 at root
</span><span>scsibus3 at softraid0: 256 targets
</span><span>root on sd0a (779fe8066eed6ce5.a) swap on sd0b dump on sd0b
</span></code></pre>
<p>There are no sensors available on this machine.</p>
<p>PCI device data:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span># pcidump
</span><span>Domain /dev/pci0:
</span><span> 0:0:0: RDC R6021 Host
</span><span> 0:3:0: XGI Technology Volari Z7
</span><span> 0:7:0: RDC R6031 ISA
</span><span> 0:8:0: RDC R6040 Ethernet
</span><span> 0:10:0: RDC R6060 USB
</span><span> 0:10:1: RDC R6061 USB2
</span><span> 0:11:0: RDC R6060 USB
</span><span> 0:11:1: RDC R6061 USB2
</span><span> 0:12:0: RDC R1011 IDE
</span></code></pre>
Diving into toolchains2021-06-08T13:37:00+00:002021-06-08T13:37:00+00:00Unknownhttps://www.cambus.net/diving-into-toolchains/<p>I've been wanting to learn more about compilers and toolchains in general
for a while now. In June 2016, I asked about <a rel="noopener" target="_blank" href="https://twitter.com/fcambus/status/744799252145070080">recommended readings on lexers
and parsers</a> on Twitter. However, I have to confess that I didn't go
forward with reading the Dragon Book.</p>
<p>Instead, I got involved as a developer in the <a rel="noopener" target="_blank" href="https://www.openbsd.org/">OpenBSD</a> and <a rel="noopener" target="_blank" href="https://www.netbsd.org/">NetBSD</a>
projects, and witnessing the evolution of toolchains within those systems
played a big role in maintaining my interest and fascination in the topic.
In retrospect, it now becomes apparent that the work I did on porting
and packaging software for those systems really helped to put in perspective
how the different parts of the toolchains interact together to produce
binaries.</p>
<p>Approximately one year ago, I asked again on Twitter whether I knew <a rel="noopener" target="_blank" href="https://twitter.com/fcambus/status/1249468322883796994">anyone
having worked on compilers and toolchains professionally</a> to get real
world advice on how to gain expertise in the field. I got several interesting
answers and started to collect and read more resources on the topic.
Some of the links I collected ended up on <a rel="noopener" target="_blank" href="https://www.toolchains.net/">toolchains.net</a>, a collection
of toolchain resources which I put online in February.</p>
<p>But the answer that resonate the most with me was <a rel="noopener" target="_blank" href="https://twitter.com/hyc_symas/status/1249474322701451265">Howard's advice to
learn by doing</a>. Because I seem to be the kind of person who need to
see some concrete results in order to keep motivated, that's exactly what
I decided to do.</p>
<p>I started by doing some cleanups in the <a rel="noopener" target="_blank" href="https://www.gnu.org/software/binutils/">binutils</a> package in NetBSD's
pkgsrc, which resulted in a <a rel="noopener" target="_blank" href="https://www.freshbsd.org/?q=binutils&committer%5B%5D=fcambus">series of commits</a>:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2020-12-20</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/ca38479f6b0fcc13f14fefc86cc1739767f9bc39">ca38479</a></td><td>Remove now unneeded OpenBSD specific checks in gold</td></tr>
<tr><td>2020-12-15</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/7263eeeda8ff66f7b3cd54b3a62743d52f98494b">7263eee</a></td><td>Add missing TEST_DEPENDS on devel/dejagnu</td></tr>
<tr><td>2020-12-14</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/b1637da54ae4c3860352f1851cb570fca8af1d6f">b1637da</a></td><td>Don't use hard-coded -ldl in the gold test suite.</td></tr>
<tr><td>2020-12-13</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/146def2d48eac2a72159ca4a40492a1f6f91e8c8">146def2</a></td><td>Remove apparently unneeded patch for libiberty</td></tr>
<tr><td>2020-12-12</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/6b347a938fed8568337c818c669418729cefde5f">6b347a9</a></td><td>Remove CFLAGS.OpenBSD+= -Wno-bounded directive</td></tr>
<tr><td>2020-12-11</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/f53b2d8ae2dd5747bdc29c0575ab8fcae26bd735">f53b2d8</a></td><td>Remove now unneeded patch dropping hidden symbols warning</td></tr>
<tr><td>2020-12-10</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/b0373808d471e15967274264affbf8deac0a3022">b037380</a></td><td>Enable building gold on Linux</td></tr>
<tr><td>2020-12-03</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/75d00bc3616276133b55e68d900e32b61fbfb23c">75d00bc</a></td><td>Remove now unneeded workaround for binutils 2.24</td></tr>
<tr><td>2020-12-03</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/adfee3096ef0366c9dbda13be5074c1267ff022a">adfee30</a></td><td>Drop all Bitrig related patches</td></tr>
</tbody></table>
<p>Meanwhile, I also got the opportunity to update our package and apply
security fixes:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-02-11</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/761e000686bc37c9791ccc34f63ede3e32b49675">761e000</a></td><td>Update to binutils 2.36.1</td></tr>
<tr><td>2021-01-27</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/ba983e5c5ee6ce131e7399200b7493b2f7efa726">ba983e5</a></td><td>Update to binutils 2.36</td></tr>
<tr><td>2021-01-07</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/7aef5c0311e2d423ae3f985dec1009fef7b112f2">7aef5c0</a></td><td>Add upstream fixes for CVE-2020-35448</td></tr>
<tr><td>2020-12-06</td><td><a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/99fdf3900a96fca988b1eb8e3ee5031f7ffad11a">99fdf39</a></td><td>Update to binutils 2.35.1</td></tr>
</tbody></table>
<p>I eventually took <a rel="noopener" target="_blank" href="https://github.com/NetBSD/pkgsrc/commit/d7146b45a9b7e78524e14f493cd5835c3334f52c">maintainership</a> of binutils in Pkgsrc.</p>
<p>Building it repeatedly with different compilers exposed different warnings,
and I've also run builds through Clang's static analyzer.</p>
<p>All of this resulted in the opportunity to contribute to <a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=search;s=Frederic+Cambus;st=author">binutils</a> itself:</p>
<table><thead><tr><th></th><th></th><th></th></tr></thead><tbody>
<tr><td>2021-04-14</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=5f47741bf633596475bb8fbb0ed304be318362cd">5f47741</a></td><td>Remove unneeded tests for definitions of NT_NETBSDCORE values</td></tr>
<tr><td>2021-04-12</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=0fa29e2deea19a33fec7f1e5a5cf49b94f93b2f8">0fa29e2</a></td><td>Remove now unneeded #ifdef check for NT_NETBSD_PAX</td></tr>
<tr><td>2021-03-12</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=be3b926d8d2dde16a55e9e303fadf95164e13ebf">be3b926</a></td><td>Add values for NetBSD .note.netbsd.ident notes (PaX)</td></tr>
<tr><td>2021-01-26</td><td><a rel="noopener" target="_blank" href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=e37709f0901fe6f2410094151002bab3d123df85">e37709f</a></td><td>Fix a double free in objcopy's memory freeing code</td></tr>
</tbody></table>
<p>Most recently, I also wrote a couple of blog posts on the topic:</p>
<ul>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/the-state-of-toolchains-in-netbsd/">The state of toolchains in NetBSD</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/speedbuilding-llvm-clang-in-5-minutes/">Speedbuilding LLVM/Clang in 5 minutes</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/speedbuilding-llvm-clang-in-2-minutes-on-arm/">Speedbuilding LLVM/Clang in 2 minutes on ARM</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/the-state-of-toolchains-in-openbsd/">The state of toolchains in OpenBSD</a></li>
<li><a rel="noopener" target="_blank" href="https://www.cambus.net/playing-with-djgpp-and-gcc-10-on-dos/">Playing with DJGPP and GCC 10 on DOS</a></li>
</ul>
<p>And the journey continues. I'm following a different path from traditional
compiler courses starting with lexers and parsers, and doing the opposite
curriculum somehow, starting from binaries instead. I will be focusing on the
final stages of the pipeline for now: compiling assembly to machine code
and producing binaries.</p>
<p>My next steps are to read the full <a rel="noopener" target="_blank" href="https://refspecs.linuxfoundation.org/elf/elf.pdf">ELF specification</a>, followed by
the <a rel="noopener" target="_blank" href="https://linker.iecc.com">Linkers and Loader</a> book, and then refresh my ASM skills. My
favorite course at university was the computer architecture one and
especially its MIPS assembly part, so I'm looking to revisit the subject
but with ARM64 assembly this time.</p>
NetBSD on the Vortex86DX CPU2021-06-03T18:40:00+00:002021-06-03T18:40:00+00:00Unknownhttps://www.cambus.net/netbsd-on-the-vortex86dx-cpu/<p>I'm not exactly sure how I first heard about the <a rel="noopener" target="_blank" href="https://www.vortex86.com">Vortex86</a> CPUs, I think
it was either when seeing the demonstration video on <a rel="noopener" target="_blank" href="https://kolibrios.org">KolibriOS</a> project
site showcasing the system running on a <strong>DMP EBOX</strong> machine, or when skimming
<strong>NetBSD</strong>'s <a rel="noopener" target="_blank" href="https://github.com/NetBSD/src/blob/trunk/sys/arch/x86/x86/identcpu.c">identcpu.c</a> code. Or did the discovery of the machine prompted
me to check if the CPU would be correctly probed by the NetBSD's kernel?</p>
<p>For those interested, Wikipedia has an article retracing the <a rel="noopener" target="_blank" href="https://en.wikipedia.org/wiki/Vortex86">history of the
Vortex86</a> from its birth at <strong>Rise</strong> to our days.</p>
<p>Several <strong>DMP EBOX</strong> machines are available for sale at various specialized
vendors, but new devices cost several hundreds of dollars which is prohibitive
for such low spec systems. However, I was recently able to acquire a boxed
older model on a local auction site for about $25: the <strong>EBOX 3300A-H</strong>, with
a 1GHz CPU and 256MB of RAM, no less.</p>
<p>As I already mentioned, those machines are quite slow but they still do have
a few things going for them:</p>
<ul>
<li>They are totally <strong>fanless</strong>, and the metal case finish is quite nice</li>
<li>They are very <strong>low-power x86</strong> embedded devices, and still being produced</li>
</ul>
<p>I used a power meter to do measurements, and an idle system consumes 5.3W.
Power consumption peaked at 6.4W when running the OpenSSL speed benchmark.</p>
<p>There is space for a 2.5" hard drive in the enclosure, but I don't have any
IDE drives anymore so I opted to use old CompactFlash cards I had laying
around. As a side note, it's actually exquisite to use those cards like
glorified floppies :-)</p>
<p>For this post, I used a <strong>1GB CompactFlash</strong> card and selected a minimal
installation in <strong>sysinst</strong>.</p>
<p>The installed system takes 212M:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>Filesystem Size Used Avail %Cap Mounted on
</span><span>/dev/wd0a 919M 212M 661M 24% /
</span><span>kernfs 1.0K 1.0K 0B 100% /kern
</span><span>ptyfs 1.0K 1.0K 0B 100% /dev/pts
</span><span>procfs 4.0K 4.0K 0B 100% /proc
</span><span>tmpfs 64M 0B 64M 0% /var/shm
</span></code></pre>
<p>On a freshly booted system, 15 processes are running and 26M of RAM are used:</p>
<pre data-lang="sh" style="background-color:#272822;color:#f8f8f2;" class="language-sh "><code class="language-sh" data-lang="sh"><span>load averages: 0.01, 0.00, 0.00</span><span style="color:#f92672;">; </span><span>up 0+00:48:26 14:48:28
</span><span>16 processes: 15 sleeping, 1 on CPU
</span><span>CPU states: 0.0% user, 0.0% nice, 0.0% system, 0.0% interrupt, 100% idle
</span><span>Memory: 26M Act, 6460K Exec, 12M File, 195M Free
</span><span>Swap:
</span><span>
</span><span> PID USERNAME PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND
</span><span> 0 root 96 0 0K 26M usbevt 0:01 0.00% 0.00% </span><span style="color:#f92672;">[</span><span>system</span><span style="color:#f92672;">]
</span><span> 795 root 43 0 6160K 1628K CPU 0:00 0.00% 0.00% top
</span><span> 555 root 85 0 12M 3472K wait 0:00 0.00% 0.00% login
</span><span> 630 postfix 85 0 13M 3220K kqueue 0:00 0.00% 0.00% qmgr
</span><span> 599 postfix 85 0 12M 3172K kqueue 0:00 0.00% 0.00% pickup
</span><span> 575 root 85 0 13M 2304K kqueue 0:00 0.00% 0.00% master
</span><span> 196 root 85 0 9780K 1960K kqueue 0:00 0.00% 0.00% syslogd
</span><span> 583 root 85 0 6788K 1824K wait 0:00 0.00% 0.00% sh
</span><span> 710 root 85 0 6276K 1448K nanoslp 0:00 0.00% 0.00% cron
</span><span> 733 root 85 0 6108K 1396K ttyraw 0:00 0.00% 0.00% getty
</span><span> 730 root 85 0 5720K 1392K ttyraw 0:00 0.00% 0.00% getty
</span><span> 633 root 85 0 6104K 1388K ttyraw 0:00 0.00% 0.00% getty
</span><span> 211 root 85 0 7316K 1360K kqueue 0:00 0.00% 0.00% dhcpcd
</span><span> 1 root 85 0 6600K 1340K wait 0:00 0.00% 0.00% init
</span><span> 689 root 85 0 5700K 1184K kqueue 0:00 0.00% 0.00% inetd
</span><span> 402 root 84 0 5920K 1140K kqueue 0:00 0.00% 0.00% powerd
</span></code></pre>
<p>Here is the result of running <strong>cat /proc/cpuinfo</strong> on this device:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>processor : 0
</span><span>vendor_id : Vortex86 SoC
</span><span>cpu family : 5
</span><span>model : 2
</span><span>model name : Vortex86DX
</span><span>stepping : 2
</span><span>cpu MHz : 1000.05
</span><span>apicid : 0
</span><span>initial apicid : 0
</span><span>fdiv_bug : no
</span><span>fpu : yes
</span><span>fpu_exception : yes
</span><span>cpuid level : 1
</span><span>wp : yes
</span><span>flags : fpu tsc cx8
</span><span>clflush size : 0
</span></code></pre>
<p>For the record, OpenSSL speed benchmark results are available <a href="/files/netbsd/openssl-speed-vortex86.txt">here</a>.</p>
<p>System message buffer (dmesg output):</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>[ 1.000000] Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
</span><span>[ 1.000000] 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
</span><span>[ 1.000000] 2018, 2019, 2020 The NetBSD Foundation, Inc. All rights reserved.
</span><span>[ 1.000000] Copyright (c) 1982, 1986, 1989, 1991, 1993
</span><span>[ 1.000000] The Regents of the University of California. All rights reserved.
</span><span>
</span><span>[ 1.000000] NetBSD 9.2 (GENERIC) #0: Wed May 12 13:15:55 UTC 2021
</span><span>[ 1.000000] mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/i386/compile/GENERIC
</span><span>[ 1.000000] total memory = 255 MB
</span><span>[ 1.000000] avail memory = 231 MB
</span><span>[ 1.000000] rnd: seeded with 66 bits
</span><span>[ 1.000000] timecounter: Timecounters tick every 10.000 msec
</span><span>[ 1.000000] Kernelized RAIDframe activated
</span><span>[ 1.000000] running cgd selftest aes-xts-256 aes-xts-512 done
</span><span>[ 1.000000] timecounter: Timecounter "i8254" frequency 1193182 Hz quality 100
</span><span>[ 1.000003] Generic PC
</span><span>[ 1.000003] mainbus0 (root)
</span><span>[ 1.000003] Firmware Error (ACPI): A valid RSDP was not found (20190405/tbxfroot-261)
</span><span>[ 1.000003] autoconfiguration error: acpi_probe: failed to initialize tables
</span><span>[ 1.000003] ACPI Error: Could not remove SCI handler (20190405/evmisc-312)
</span><span>[ 1.000003] cpu0 at mainbus0
</span><span>[ 1.000003] cpu0: Vortex86DX, id 0x522
</span><span>[ 1.000003] cpu0: package 0, core 0, smt 0
</span><span>[ 1.000003] pci0 at mainbus0 bus 0: configuration mode 1
</span><span>[ 1.000003] pci0: i/o space, memory space enabled, rd/line, rd/mult, wr/inv ok
</span><span>[ 1.000003] pchb0 at pci0 dev 0 function 0: vendor 17f3 product 6021 (rev. 0x02)
</span><span>[ 1.000003] vga0 at pci0 dev 3 function 0: vendor 18ca product 0020 (rev. 0x00)
</span><span>[ 1.000003] wsdisplay0 at vga0 kbdmux 1: console (80x25, vt100 emulation)
</span><span>[ 1.000003] wsmux1: connecting to wsdisplay0
</span><span>[ 1.000003] drm at vga0 not configured
</span><span>[ 1.000003] rdcpcib0 at pci0 dev 7 function 0: vendor 17f3 product 6031 (rev. 0x02)
</span><span>[ 1.000003] rdcpcib0: watchdog timer configured.
</span><span>[ 1.000003] vte0 at pci0 dev 8 function 0: vendor 17f3 product 6040 (rev. 0x00)
</span><span>[ 1.000003] vte0: Ethernet address 00:1b:eb:22:16:5c
</span><span>[ 1.000003] vte0: interrupting at irq 10
</span><span>[ 1.000003] rdcphy0 at vte0 phy 1: R6040 10/100 media interface, rev. 1
</span><span>[ 1.000003] rdcphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
</span><span>[ 1.000003] ohci0 at pci0 dev 10 function 0: vendor 17f3 product 6060 (rev. 0x12)
</span><span>[ 1.000003] ohci0: interrupting at irq 11
</span><span>[ 1.000003] ohci0: OHCI version 1.0, legacy support
</span><span>[ 1.000003] usb0 at ohci0: USB revision 1.0
</span><span>[ 1.000003] ehci0 at pci0 dev 10 function 1: vendor 17f3 product 6061 (rev. 0x03)
</span><span>[ 1.000003] ehci0: interrupting at irq 11
</span><span>[ 1.000003] ehci0: BIOS has given up ownership
</span><span>[ 1.000003] ehci0: EHCI version 1.0
</span><span>[ 1.000003] ehci0: 1 companion controller, 2 ports: ohci0
</span><span>[ 1.000003] usb1 at ehci0: USB revision 2.0
</span><span>[ 1.000003] ohci1 at pci0 dev 11 function 0: vendor 17f3 product 6060 (rev. 0x12)
</span><span>[ 1.000003] ohci1: interrupting at irq 11
</span><span>[ 1.000003] ohci1: OHCI version 1.0, legacy support
</span><span>[ 1.000003] usb2 at ohci1: USB revision 1.0
</span><span>[ 1.000003] ehci1 at pci0 dev 11 function 1: vendor 17f3 product 6061 (rev. 0x03)
</span><span>[ 1.000003] ehci1: interrupting at irq 11
</span><span>[ 1.000003] ehci1: BIOS has given up ownership
</span><span>[ 1.000003] ehci1: EHCI version 1.0
</span><span>[ 1.000003] ehci1: 1 companion controller, 2 ports: ohci1
</span><span>[ 1.000003] usb3 at ehci1: USB revision 2.0
</span><span>[ 1.000003] rdcide0 at pci0 dev 12 function 0: RDC R1011 IDE controller (rev. 0x01)
</span><span>[ 1.000003] rdcide0: bus-master DMA support present
</span><span>[ 1.000003] rdcide0: primary channel configured to compatibility mode
</span><span>[ 1.000003] rdcide0: primary channel interrupting at irq 14
</span><span>[ 1.000003] atabus0 at rdcide0 channel 0
</span><span>[ 1.000003] rdcide0: secondary channel configured to compatibility mode
</span><span>[ 1.000003] rdcide0: secondary channel interrupting at irq 15
</span><span>[ 1.000003] atabus1 at rdcide0 channel 1
</span><span>[ 1.000003] isa0 at rdcpcib0
</span><span>[ 1.000003] pckbc0 at isa0 port 0x60-0x64
</span><span>[ 1.000003] attimer0 at isa0 port 0x40-0x43
</span><span>[ 1.000003] pcppi0 at isa0 port 0x61
</span><span>[ 1.000003] midi0 at pcppi0: PC speaker
</span><span>[ 1.000003] sysbeep0 at pcppi0
</span><span>[ 1.000003] isapnp0 at isa0 port 0x279
</span><span>[ 1.000003] attimer0: attached to pcppi0
</span><span>[ 1.000003] isapnp0: no ISA Plug 'n Play devices found
</span><span>[ 1.000003] timecounter: Timecounter "clockinterrupt" frequency 100 Hz quality 0
</span><span>[ 1.064509] uhub0 at usb1: NetBSD (0000) EHCI root hub (0000), class 9/0, rev 2.00/1.00, addr 1
</span><span>[ 1.064509] uhub0: 2 ports with 2 removable, self powered
</span><span>[ 1.064509] uhub1 at usb2: NetBSD (0000) OHCI root hub (0000), class 9/0, rev 1.00/1.00, addr 1
</span><span>[ 1.064509] uhub1: 2 ports with 2 removable, self powered
</span><span>[ 1.064509] uhub2 at usb3: NetBSD (0000) EHCI root hub (0000), class 9/0, rev 2.00/1.00, addr 1
</span><span>[ 1.064509] uhub2: 2 ports with 2 removable, self powered
</span><span>[ 1.064509] uhub3 at usb0: NetBSD (0000) OHCI root hub (0000), class 9/0, rev 1.00/1.00, addr 1
</span><span>[ 1.064509] uhub3: 2 ports with 2 removable, self powered
</span><span>[ 1.064509] IPsec: Initialized Security Association Processing.
</span><span>[ 3.914550] uaudio0 at uhub3 port 2 configuration 1 interface 0
</span><span>[ 3.914550] uaudio0: vendor 0d8c (0xd8c) C-Media USB Audio Device (0x08), rev 1.10/1.00, addr 2
</span><span>[ 3.934546] uaudio0: audio rev 1.00
</span><span>[ 3.934546] audio0 at uaudio0: playback, capture, full duplex, independent
</span><span>[ 3.934546] audio0: slinear_le:16 2ch 48000Hz, blk 11520 bytes (60ms) for playback
</span><span>[ 3.934546] audio0: slinear_le:16 1ch 48000Hz, blk 6000 bytes (62.5ms) for recording
</span><span>[ 3.934546] uhidev0 at uhub3 port 2 configuration 1 interface 3
</span><span>[ 3.934546] uhidev0: vendor 0d8c (0xd8c) C-Media USB Audio Device (0x08), rev 1.10/1.00, addr 2, iclass 3/0
</span><span>[ 3.944550] uhid0 at uhidev0: input=4, output=4, feature=0
</span><span>[ 4.054550] wd0 at atabus1 drive 0
</span><span>[ 4.054550] wd0: <Hitachi XX.V.3.5.0.0>
</span><span>[ 4.054550] wd0: drive supports 1-sector PIO transfers, LBA addressing
</span><span>[ 4.054550] wd0: 977 MB, 1987 cyl, 16 head, 63 sec, 512 bytes/sect x 2002896 sectors
</span><span>[ 4.064551] wd0: 32-bit data port
</span><span>[ 4.064551] wd0: drive supports PIO mode 4
</span><span>[ 4.064551] wd0(rdcide0:1:0): using PIO mode 4
</span><span>[ 4.084559] WARNING: 1 error while detecting hardware; check system log.
</span><span>[ 4.084559] boot device: wd0
</span><span>[ 4.084559] root on wd0a dumps on wd0b
</span><span>[ 4.094550] root file system type: ffs
</span><span>[ 4.094550] kern.module.path=/stand/i386/9.2/modules
</span><span>[ 20.764808] wsdisplay0: screen 1 added (80x25, vt100 emulation)
</span><span>[ 20.784809] wsdisplay0: screen 2 added (80x25, vt100 emulation)
</span><span>[ 20.794810] wsdisplay0: screen 3 added (80x25, vt100 emulation)
</span><span>[ 20.804812] wsdisplay0: screen 4 added (80x25, vt100 emulation)
</span></code></pre>
Character and color cycling effect in C on DOS2021-05-27T23:21:00+00:002021-05-27T23:21:00+00:00Unknownhttps://www.cambus.net/character-and-color-cycling-effect-in-c-on-dos/<p>As mentioned in my previous post about <a rel="noopener" target="_blank" href="https://www.cambus.net/playing-with-djgpp-and-gcc-10-on-dos/">playing with DJGPP and GCC 10 on DOS</a>,
I have been redoing my small character and color cycling effect in text
mode. The original version in JavaScript can be seen <a rel="noopener" target="_blank" href="https://www.cambus.net/character-and-color-cycling-effect-in-javascript/">here</a>.</p>
<p><img src="/content/2021/05/cycling-effect.png" alt="Cycling effect" /></p>
<p>To understand why we can't access video memory directly and need to use the
DPMI service to create a selector to access the required real-mode segment
address, please refer to <a rel="noopener" target="_blank" href="https://www.delorie.com/djgpp/v2faq/faq18_4.html">section 18.4 of the DJGPP FAQ</a>.</p>
<p>The effect can be downloaded <a href="/content/2021/05/cycling.exe">here</a>. Sadly, the resulting binary is quite
large (104K stripped!), and it requires <a rel="noopener" target="_blank" href="https://sandmann.dotster.com/cwsdpmi/">CWSDPMI</a> to run.</p>
<p>Here is the code:</p>
<pre data-lang="c" style="background-color:#272822;color:#f8f8f2;" class="language-c "><code class="language-c" data-lang="c"><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><conio.h>
</span><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><dpmi.h>
</span><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><go32.h>
</span><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><pc.h>
</span><span>
</span><span style="font-style:italic;color:#66d9ef;">void
</span><span style="color:#a6e22e;">wait_vbl</span><span>()
</span><span>{
</span><span> </span><span style="color:#f92672;">while</span><span>(inp(</span><span style="color:#ae81ff;">0x3da</span><span>) </span><span style="color:#f92672;">& </span><span style="color:#ae81ff;">0x08</span><span>);
</span><span> </span><span style="color:#f92672;">while</span><span>(</span><span style="color:#f92672;">!</span><span>(inp(</span><span style="color:#ae81ff;">0x3da</span><span>) </span><span style="color:#f92672;">& </span><span style="color:#ae81ff;">0x08</span><span>));
</span><span>}
</span><span>
</span><span style="font-style:italic;color:#66d9ef;">int
</span><span style="color:#a6e22e;">main</span><span>()
</span><span>{
</span><span> </span><span style="font-style:italic;color:#66d9ef;">short</span><span> video </span><span style="color:#f92672;">= </span><span>__dpmi_segment_to_descriptor(</span><span style="color:#ae81ff;">0xb800</span><span>);
</span><span> </span><span style="font-style:italic;color:#66d9ef;">unsigned char</span><span> buffer[</span><span style="color:#ae81ff;">4000</span><span>];
</span><span>
</span><span> </span><span style="font-style:italic;color:#66d9ef;">int</span><span> character </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">0</span><span>, color </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">0</span><span>;
</span><span>
</span><span> </span><span style="color:#75715e;">/* Define character and color arrays */
</span><span> </span><span style="font-style:italic;color:#66d9ef;">char</span><span> characters[] </span><span style="color:#f92672;">= </span><span>{ </span><span style="color:#ae81ff;">0x5c</span><span>, </span><span style="color:#ae81ff;">0x7c</span><span>, </span><span style="color:#ae81ff;">0x2f</span><span>, </span><span style="color:#ae81ff;">0x2d </span><span>};
</span><span> </span><span style="font-style:italic;color:#66d9ef;">char</span><span> colors[] </span><span style="color:#f92672;">= </span><span>{ </span><span style="color:#ae81ff;">0xf</span><span>, </span><span style="color:#ae81ff;">0xb</span><span>, </span><span style="color:#ae81ff;">0x9</span><span>, </span><span style="color:#ae81ff;">0x1</span><span>, </span><span style="color:#ae81ff;">0x9</span><span>, </span><span style="color:#ae81ff;">0xb</span><span>, </span><span style="color:#ae81ff;">0xf </span><span>};
</span><span>
</span><span> </span><span style="color:#f92672;">while </span><span>(</span><span style="color:#f92672;">!</span><span>kbhit()) {
</span><span> </span><span style="color:#f92672;">for </span><span>(</span><span style="font-style:italic;color:#66d9ef;">size_t</span><span> offset </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">0</span><span>; offset </span><span style="color:#f92672;">< </span><span style="color:#ae81ff;">4000</span><span>; offset </span><span style="color:#f92672;">+= </span><span style="color:#ae81ff;">2</span><span>) {
</span><span> </span><span style="color:#75715e;">/* Write character and color data */
</span><span> buffer[offset] </span><span style="color:#f92672;">=</span><span> characters[character];
</span><span> buffer[offset </span><span style="color:#f92672;">+ </span><span style="color:#ae81ff;">1</span><span>] </span><span style="color:#f92672;">=</span><span> colors[color];
</span><span>
</span><span> </span><span style="color:#75715e;">/* Increment the color index */
</span><span> color </span><span style="color:#f92672;">=</span><span> color </span><span style="color:#f92672;">+ </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">< sizeof</span><span>(colors) </span><span style="color:#f92672;">?</span><span> color </span><span style="color:#f92672;">+ </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">: </span><span style="color:#ae81ff;">0</span><span>;
</span><span> }
</span><span>
</span><span> </span><span style="color:#75715e;">/* Increment the character index */
</span><span> character </span><span style="color:#f92672;">=</span><span> character </span><span style="color:#f92672;">+ </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">< sizeof</span><span>(characters) </span><span style="color:#f92672;">?
</span><span> character </span><span style="color:#f92672;">+ </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">: </span><span style="color:#ae81ff;">0</span><span>;
</span><span>
</span><span> </span><span style="color:#75715e;">/* Copy the buffer into text mode video memory */
</span><span> movedata(_my_ds(), (</span><span style="font-style:italic;color:#66d9ef;">unsigned</span><span>)buffer, video, </span><span style="color:#ae81ff;">0</span><span>, </span><span style="color:#ae81ff;">4000</span><span>);
</span><span>
</span><span> </span><span style="color:#75715e;">/* Wait for VBL */
</span><span> wait_vbl();
</span><span> wait_vbl();
</span><span> wait_vbl();
</span><span> wait_vbl();
</span><span> wait_vbl();
</span><span> }
</span><span>}
</span></code></pre>
Playing with DJGPP and GCC 10 on DOS2021-05-23T00:36:00+00:002021-05-23T00:36:00+00:00Unknownhttps://www.cambus.net/playing-with-djgpp-and-gcc-10-on-dos/<p>I was recently amazed to discover that <a rel="noopener" target="_blank" href="https://www.delorie.com/djgpp/">DJGPP</a> was still being maintained,
and had very recent versions of GCC and binutils available. I have not been
doing any C programming on DOS in a very long time now, so I think the timing
is right.</p>
<p>There is an installation program with an interface very similar to the good
old <strong>Turbo Vision</strong>, which could be helpful in case one wants to install the
full environment.</p>
<p><img src="https://www.cambus.net/content/2021/05/djgpp-01.png" alt="DJGPP Installer" /></p>
<p><img src="https://www.cambus.net/content/2021/05/djgpp-02.png" alt="DJGPP Installer" /></p>
<p>I'm only interested in using the <strong>C</strong> and <strong>C++</strong> frontends for now, so
I will do a manual installation.</p>
<p>We need the following components:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>djdev205.zip B 2,509,574 2015-10-18 DJGPP development kit 2.05
</span><span>bnu2351b.zip B 6,230,009 2021-01-16 GNU Binutils 2.35.1 binaries for DJGPP
</span><span>gcc1030b.zip B 42,027,946 2021-04-18 GNU GCC C compiler 10.3.0 for DJGPP V2
</span><span>gpp1030b.zip B 16,207,187 2021-04-18 GNU C++ compiler 10.3.0 for DJGPP V2
</span><span>csdpmi7b.zip B 71,339 2010-01-29 CS's DPMI Provider r7 Binaries
</span></code></pre>
<p>The development environment can be bootstrapped as follows:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>mkdir -p ~/dos/djgpp
</span><span>cd ~/dos/djgpp
</span><span>wget https://www.delorie.com/pub/djgpp/current/v2/djdev205.zip
</span><span>wget https://www.delorie.com/pub/djgpp/current/v2gnu/bnu2351b.zip
</span><span>wget https://www.delorie.com/pub/djgpp/current/v2gnu/gcc1030b.zip
</span><span>wget https://www.delorie.com/pub/djgpp/current/v2gnu/gpp1030b.zip
</span><span>wget https://www.delorie.com/pub/djgpp/current/v2misc/csdpmi7b.zip
</span><span>unzip djdev205.zip
</span><span>unzip bnu2351b.zip
</span><span>unzip gcc1030b.zip
</span><span>unzip gpp1030b.zip
</span><span>unzip csdpmi7b.zip
</span></code></pre>
<p>When using <strong>FreeDOS</strong>, we need to add the following in <em>FDAUTO.BAT</em>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>set DJGPP=c:\djgpp\djgpp.env
</span><span>set PATH=c:\djgpp\bin;%PATH%
</span></code></pre>
<p>Alternatively, when using <strong>DOSBox</strong> instead, we need the following in
<em>dosbox.conf</em>:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>[autoexec]
</span><span>mount c ~/dos
</span><span>path=c:\djgpp\bin
</span><span>set DJGPP=c:\djgpp\djgpp.env
</span><span>c:
</span></code></pre>
<p>Once we are done installing, this gives us GCC 10.3.0 and ld 2.35.1:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>gcc --version
</span><span>gcc.exe (GCC) 10.3.0
</span><span>Copyright (C) 2020 Free Software Foundation, Inc.
</span><span>This is free software; see the source for copying conditions. There is NO
</span><span>warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</span><span>
</span><span>C:\>ld --version
</span><span>GNU ld (GNU Binutils) 2.35.1
</span><span>Copyright (C) 2020 Free Software Foundation, Inc.
</span><span>This program is free software; you may redistribute it under the terms of
</span><span>the GNU General Public License version 3 or (at your option) a later version.
</span><span>This program has absolutely no warranty.
</span></code></pre>
<p>To verify things are working properly, let's create a simple test program:</p>
<pre data-lang="c" style="background-color:#272822;color:#f8f8f2;" class="language-c "><code class="language-c" data-lang="c"><span style="color:#f92672;">#include </span><span style="color:#e6db74;"><stdio.h>
</span><span>
</span><span style="font-style:italic;color:#66d9ef;">int
</span><span style="color:#a6e22e;">main</span><span>()
</span><span>{
</span><span> </span><span style="color:#66d9ef;">puts</span><span>(</span><span style="color:#e6db74;">"Hello World!"</span><span>);
</span><span>
</span><span> </span><span style="color:#f92672;">return </span><span style="color:#ae81ff;">0</span><span>;
</span><span>}
</span></code></pre>
<p>We then build and run it:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>gcc hello.c -o hello
</span><span>
</span><span>C:\>hello
</span><span>Hello World!
</span></code></pre>
<p>Here is the output of running <strong>file</strong> on the executable:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>HELLO.EXE: MS-DOS executable, COFF for MS-DOS, DJGPP go32 DOS extender
</span></code></pre>
<p>Let's build only an object file:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>gcc -c hello.c
</span></code></pre>
<p>We can run <strong>nm</strong> on it to list symbols:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>nm hello.o
</span><span>00000000 b .bss
</span><span>00000000 N .comment
</span><span>00000000 d .data
</span><span>00000000 t .text
</span><span>0000000d T _main
</span><span> U _puts
</span></code></pre>
<p>And run <strong>objdump</strong> to display its content:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>objdump -s hello.o
</span><span>
</span><span>HELLO.o: file format coff-go32
</span><span>
</span><span>Contents of section .text:
</span><span> 0000 48656c6c 6f20576f 726c6421 008d4c24 Hello World!..L$
</span><span> 0010 0483e4f0 ff71fc55 89e55183 ec0483ec .....q.U..Q.....
</span><span> 0020 0c680000 0000e8d5 ffffff83 c410b800 .h..............
</span><span> 0030 0000008b 4dfc89ec 5d8d61fc c3909090 ....M...].a.....
</span><span>Contents of section .comment:
</span><span> 0000 4743433a 2028474e 55292031 302e332e GCC: (GNU) 10.3.
</span><span> 0010 30000000 0...
</span></code></pre>
<p>We can also use <strong>objdump</strong> to disassemble the object file:</p>
<pre style="background-color:#272822;color:#f8f8f2;"><code><span>C:\>objdump -d hello.o
</span><span>
</span><span>HELLO.o: file format coff-go32
</span><span>
</span><span>Disassembly of section .text:
</span><span>
</span><span>00000000 <.text>:
</span><span> 0: 48 dec %eax
</span><span> 1: 65 6c gs insb (%dx),%es:(%edi)
</span><span> 3: 6c insb (%dx),%es:(%edi)
</span><span> 4: 6f outsl %ds:(%esi),(%dx)
</span><span> 5: 20 57 6f and %dl,0x6f(%edi)
</span><span> 8: 72 6c jb 76 <_main+0x69>
</span><span> a: 64 21 00 and %eax,%fs:(%eax)
</span><span>
</span><span>0000000d <_main>:
</span><span> d: 8d 4c 24 04 lea 0x4(%esp),%ecx
</span><span> 11: 83 e4 f0 and $0xfffffff0,%esp
</span><span> 14: ff 71 fc pushl -0x4(%ecx)
</span><span> 17: 55 push %ebp
</span><span> 18: 89 e5 mov %esp,%ebp
</span><span> 1a: 51 push %ecx
</span><span> 1b: 83 ec 04 sub $0x4,%esp
</span><span> 1e: 83 ec 0c sub $0xc,%esp
</span><span> 21: 68 00 00 00 00 push $0x0
</span><span> 26: e8 d5 ff ff ff call 0 <.text>
</span><span> 2b: 83 c4 10 add $0x10,%esp
</span><span> 2e: b8 00 00 00 00 mov $0x0,%eax
</span><span> 33: 8b 4d fc mov -0x4(%ebp),%ecx
</span><span> 36: 89 ec mov %ebp,%esp
</span><span> 38: 5d pop %ebp
</span><span> 39: 8d 61 fc lea -0x4(%ecx),%esp
</span><span> 3c: c3 ret
</span><span> 3d: 90 nop
</span><span> 3e: 90 nop
</span><span> 3f: 90 nop
</span></code></pre>
<p>Besides the C and C++ frontends, the <strong>Ada</strong>, <strong>Fortran</strong>, <strong>Objective C</strong>,
and <strong>Pascal</strong> frontends are also available. While I used DOSBox to test the
development environment and prepare this article, I've since moved to FreeDOS
which I'm running natively on my ASUS Eee PC. I'm currently having a lot of
fun redoing some small character and color cycling effects in text mode.</p>