GeistHaus
log in · sign up

https://eerielinux.wordpress.com/feed

rss
0 posts
Polling state
Status active
Last polled May 19, 2026 01:21 UTC
Next poll May 19, 2026 23:28 UTC
Poll interval 86400s
Last-Modified Sun, 03 May 2026 15:15:41 GMT

Posts

Exploring the CBSD virtual environment management framework – part 9: Bhyve (I)
bsdcomputerfreebsdsoftwarevirtualization
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2026/cbsd_pt9.gmi Belated Happy New Year everyone! After a long break (the previous article was published in July 2024!) and several failed attempts to pick up where I left off, it’s finally happening. … Continue reading Exploring the CBSD virtual environment management framework – part 9: Bhyve (I)
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2026/cbsd_pt9.gmi

Belated Happy New Year everyone! After a long break (the previous article was published in July 2024!) and several failed attempts to pick up where I left off, it’s finally happening. Here’s the latest installment in my CBSD series (thanks for bearing with me to anyone who’s still there! 😉). This time we’re going to take a look at using CBSD to manage Bhyve VMs. Here’s what has been covered so far:

Part 0 of this series is a general discussion of what virtualization actually is and what you should know to make best use of what will be covered in the later parts.
Part 1 covered an introduction of CBSD as well as the installation.
Part 2 detailed CBSD’s initial setup process.
In part 3, jail creation with a dialog-based TUI as well as starting and stopping jails was covered.
Part 4 showed how to create jails using an interactive script. It used an unusual example (a 32-bit jail of an outdated version of FreeBSD) to show some important concepts like how filesystem mounts work.
Part 5 was about removing jails and creating them both from conf files and from the command line. It also covered setting up a network-facing example application.
Part 6 discussed jail options and upgrading the base system inside jails.
Part 7 was about upgrading CBSD (and backing up metadata) as well as using the help system.
Part 8 covered customizing output and colors, using update hooks, custom profiles and more.

The operating system on the test machine is a freshly installed 15.0-RELEASE-p1 and I’m going to work with CBSD 15.0.0.

Managing Bhyve VMs with CBSD

Just like with the jails portion of this series, you don’t need to be deeply familiar with the underlying virtualization technology – CBSD makes using it extremely easy after all. Having a good idea of what happens under the hood helps, of course. But if you don’t plan to run Bhyve in production for now and just want to get started, simply letting CBSD handle the nitty-gritty and getting usable results quickly is fine.

If you’ve read the previous articles on jails, here’s the good news for you: you basically already know how to use CBSD for managing Bhyve VMs! That’s due to the (mostly) consistent naming scheme that CBSD follows across all of its virtualization domains (which was the killing feature that sold me on CBSD after having used various jail and VM managers). Remember that ‘jls’ subcommand for listing jails, ‘jstart’ for starting one and so on? Well, substitute ‘b’ for the ‘j’ prefix and guess what happens:

# cbsd bls
JNAME JID VM_RAM VM_CURMEM VM_CPUS PCPU VM_OS_TYPE IP4_ADDR STATUS VNC

Now if that isn’t nice! Of course, this being a fresh system, there are no VMs, yet. But the listing worked. And that’s the beauty of CBSD: you don’t have to learn a whole set of new commands. Yes, you probably noticed that the output says “JNAME” as well as “JID”. That’s some of the minor inconsistencies of CBSD – it started out as a jails manager and when the other virtualization domains were added, existing routines were re-used. It’s a little jarring and I wouldn’t be surprised if this were to be addressed in a future version, but for now keep in mind that sometimes CBSD will claim to be operating on jails (‘j…’) when it actually isn’t. It might have confused you if you didn’t know about it. Now that you do, though, I’m pretty confident that you can handle it and thus it becomes a cosmetic issue.

So does that mean that you can also just use subcommands like ‘bconstruct-tui’? Glad you asked. Yes, pretty much! But before anyone goes “Seriously, kraileth? You made us wait 1.5 years for that cheap reveal?! And what’s the rest of the article about, then?” – let me tell you that there are a couple of things that you should know when using VMs on FreeBSD. So for example while the ‘bconstruct-tui’ subcommand does exist, it won’t work out of the box. Unlike with jails, there’s some minimal additional setup that you have to do up-front. But let’s explore this together “like in the good old times”, shall we?

Setting up your system for Bhyve

As usual, in most situation when something doesn’t work, CBSD will not just tell you but also make some friendly suggestions. So how about just giving it a try?

# cbsd bconstruct-tui
No kldloaded module: vmm
Please add vmm_load="YES" to /boot/loader.conf and
put kld_list="vmm if_tuntap if_bridge nmdm" into your /etc/rc.conf then reboot the host. Or, for example, run:
sysrc kld_list+="vmm if_tuntap if_bridge nmdm" && service kld restart

So what does this mean? Bhyve is actually a kernel module, ‘vmm’ (“Virtual Machine Manager”). This means for FreeBSD to be able to provide hypervisor services, the respective module needs to be loaded. And since VMs that you cannot access are rather boring, two additional modules are required: one to provide a special type of network adapters (if you don’t know what they do and care for networking, you might want to take a quick look at tun(4) and tap(4) respectively) as well as the nullmodem driver.

CBSD kernel module loading recommendation text

The command line that CBSD suggests is enough to do everything required to start working with Bhyve. You could load ‘vmm’ before booting by adding it to the loader configuration, but it’s perfectly fine to have the init system dynamically load it during startup. You might see a warning that ‘if_tuntap’ could not be loaded as it’s already in the kernel. This is because it’s a fairly standard module which is compiled into the GENERIC kernel. Trying to load it even though it’s not needed doesn’t hurt anyone, though. And in case you’re running a customized kernel which might not include it, it would be required to load it. So CBSD does the right thing here.

Creating a new Bhyve VM, dialog-style

After the necessary modules have been loaded, we can try creating a new VM again. This time, the nice dialog TUI appears, providing a wealth of options as usual.

The VM construction main menu

The first essential option is ‘vm_os_type’. It’s used to select the operating system family. The various BSDs, Linux – and even Windows are there. If you’re looking for something more exotic, choose ‘other’ and see what’s available.

VM OS type selection

The next thing to choose is typically the ‘profile’. Which profiles are available depends on the OS type that you just selected. You’ll probably be surprised how many profiles CBSD ships! If for example you stuck with the FreeBSD family, you will find the various currently supported versions of FreeBSD proper (of course), but also specialized distributions like OPNsense, the BSD Router project, NAS systems like XigmaNAS, HardenedBSD and so on. There’s also desktop-oriented GhostBSD and FreeBSD-derived MidnightBSD and even more exotic projects like RavynOS.

We’re going to stick with the classic images for now and ignore the cloud-based ones.

Profile selection (FreeBSD-based profiles)

The next option you should know about is for setting the package. It’s basically a shortcut for quickly picking some common resource-related presets. Selecting one will fill out the size of the virtual disk, amount of RAM available and CPU cores for the VM. You can of course still customize each one later.

Package (preset) selection

‘Jname’ (just pretend it’s ‘bname’) is simply the internal name by which the VM will be known by CBSD. Some naming restrictions apply, so it’s best to not try to get fancy here. Totally avoid anything that could break a shell script! If you choose to ignore this advice, be prepared for some serious pain.

CBSD will propose a name based on the profile selected and the amount of other VMs of the same type already on the system.

VM name selection

The ‘host_hostname’ and ‘imgsize’ are pretty much obvious – the former is the hostname for the VM and the latter defines how big the virtual disk will be. More interesting is ‘ip4_addr’. Unlike what the name suggests, you can actually assign v6 addresses here, too.

The ‘DHCP’ and ‘REALDHCP’ options may be confusing, so a word about them. CBSD comes with an internal mechanism to hand out IP addresses from ranges it was assigned during setup. This is relatively simplistic: it basically gives out the next IP address that it deems free and records it as taken. So it’s a DHCP-alike. REALDHCP in contrast is what you might expect – it’s actually DHCP.

However since we’re going to use the classic images, setting the VM address here is mostly descriptive, it doesn’t actually set the IP in the VM. When you have selected ‘interface=auto’, CBSD will use it to determine which NIC to bind to, though. But even if you selected the interface manually, I would still recommend to enter the IP, since being able to see the address(es) of VMs when you do a ‘bls’ is very useful.

IP address selection

The ‘ram’ and ‘cpu’ options are self-explanatory as is the ‘iso_path’. You can customize the latter, but if you’re using one of the profiles that CBSD provides, you don’t have to as it’s filled out automatically.

With the ‘astart’ switch you can select whether CBSD will automatically start the VM after the virtualization host booted up or not.

Unless you understand the consequences and want more control over the virtual hardware of your VM, leave the ‘xhci’, ‘tablet’ and especially the ‘fbuf’ option alone. And while it may sound tempting to put Bhyve in a jail, resist that urge if you’re only starting out. You could be lucky, everything works and you’d get a security benefit from jailing the process – or things might break in interesting ways.

In simple setups it’s best to leave the ‘interface’ on ‘auto’. But if you have different requirements, you can select another NIC here (physical or logical).

In many cases you will want to leave ‘vnc_port’ as 0 (auto). But if you have a different means of accessing your VM, you can safely disable it by setting it to 1.

Unless you’re a developer and you want to try something special, leave ‘efi’ alone, period. Booting non-efi systems is not supported (attempts to get it working have failed years ago and it was deemed as not worth the trouble).

With ‘imgtype’ you can select the backend to use for the VM’s virtual disk. The default (ZVOL on ZFS systems) is a sensible choice, but you can choose another one if you prefer to or create a VM without a virtual disk.

Storage backend selection

The ‘zfs_snapsrc’ option can be used to create a VM from the snapshot of a ZFS dataset. It’s a very interesting feature, but most people won’t need this.

Except for the settings of Bhyve’s VNC server, I’m not going to cover the rest of the options in this article since they are mostly advanced topics.

The VNC options open a submenu. You will usually want to leave ‘cd_vnc_wait’ enabled. What this does is to only really start the VM as soon as a VNC client connects. This prevents you from having to be super quick or miss the boot loader since most systems will boot after a rather short delay.

The default resolution is a good choice in general, but with some VM guests you might have other needs, so you can change this.

It’s crucial to know that by default the VNC server binds to localhost only. If you play with Bhyve on your FreeBSD workstation that’s fine. But chances are that you may need to access the VNC console remotely. In those cases change the address to your server’s primary IP.

Unless you work with rather exotic guests, just leave ‘vnc_vgaconf’ alone. (And no, in this context I consider FreeBSD, Bhyve and CBSD pretty much mainstream. If you can come up with a use case that escaped me, feel free to let me know.)

The ‘vnc_kbdlayout’ option however is super useful. If your keyboard is non-US, you can configure it here and get rid of one reason to hate VNC. (Several very valid ones probably remain, but hey: every little bit counts, right?)

If you have to use VNC, at least make sure it’s encrypted. CBSD sets a standard password which is definitely better than nothing, but you should really use a unique one if you have the VNC server bind on a globally routable address and don’t spin the VM up because you want everybody to be able to use it.

VNC settings

When you have configured everything to your liking, scroll down to ‘GO’ and hit ‘OK’. Here are the settings that I chose for this example VM:

VM options in the main menu

A final dialogue window will be displayed, asking you if you want to create the VM right away. Usually you do. Selecting ‘no’ is useful in cases when you need several similar VMs. CBSD will write a configuration file based on your choices and you can adapt it further and use it to create your VM(s). But let’s take the straight-forward route here.

The VM was created!

The VM was created and with ‘cbsd bls’ we can confirm that it exists.

Starting, stopping and re-configuring VMs

To start the VM, we can use the ‘bstart’ subcommand of CBSD. Since it’s the first VM on this new system, the ISO is not yet present in the local filesystem. CBSD detects this and offers to download it. If you agree it will try to find the fastest mirror and then fetch the file.

Automatic downloading of the installation ISO

After the download finishes, CBSD validates the checksum, registers the new ISO file and starts up the VM. It conveniently gives you some useful information like the IP the VNC server bound to and the password that is used.

VM is running and ready

Stupid me, like every so often, I’ve forgotten to configure the VNC server properly… Since settings like these can only be changed when the VM is stopped, I have to use the ‘bstop’ subcommand to do just that.

Stopping the VM

When the VM is down, the ‘bconfig’ subcommand can be used to bring up a nice little menu to select the appropriate machine from. If you’ve got a lot of VMs, it might be more comfortable to just select the correct one via a parameter on the command line like this:

# cbsd bconfig jname=freebsd1

You will find that the dialog menu looks differently. This is because not all options can be changed after a VM has been created. VNC-related options can be, however. And after changing the VNC bind address to the primary IP of the host machine, the VM’s VNC console can be accessed remotely.

VNC connections

There are various VNC clients which you can use for that. A simple and light-weight one is TigerVNC. You can install it on a FreeBSD desktop via the package ‘tigervnc-viewer’. After running it, you simply need to tell the application the IP address and port to use – both which CBSD displays for your convenience when you start a VM.


TigerVNC: connecting to the VNC console

Next, your VNC client will ask you about the password. Again, you can conveniently copy it from your terminal since CBSD lets you know which one it is.


TigerVNC: password protection

If everything worked, a VNC session is established. You can interact with FreeBSD’s loader, and after booting up the system, the installer comes up. Basically it’s a simple way to interact with the VM using a graphical console.

FreeBSD’s installer in a VNC session

After the installation is completed, the machine reboots. CBSD will detect automatically that the virtual hard disk is not empty and instead of booting from the virtual CD into the installer, it boots the freshly installed system. At that point you can do with the VM whatever your use case requires. The only thing that I suggest strongly is configuring SSH. When you have headless access, shut down the system, and use ‘bconfig’ again to change the VM configuration. By turning off VNC (e.g. by letting it bind to 127.0.0.1 again), you tighten your VM’s security.

Changing Defaults

If you regularly create new VMs, it might be worth changing some of the defaults. Have a look at the ‘bhyve-default-default.conf’ file in the ‘etc/defaults’ subdirectory of your CBSD directory (in my case ‘/cbsd’).

You could of course make changes to this file (it’s your system after all), but that is not a good idea. When you update CBSD, your changes might get overwritten. CBSD allows you to use a custom configuration which overrides the standard defaults, however. For example, if you want to make sure you don’t forget to open VNC up for remote access during installation, and you prefer md-backed storage, just create a ‘bhyve-default-default.conf’ file directly in CBSD’s ‘etc’ directory. In here document style you can achieve it this way:

# cat >> ~cbsd/etc/bhyve-default-default.conf <<EOF
? bhyve_vnc_tcp_bind="0.0.0.0"
? imgtype="md"
? EOF

Next time you use the ‘bconstruct-tui’ subcommand, you will find that you have two less options to set.

Oh, and do remember to change the VNC port again after the installation. If you forget, CBSD is nice enough to warn you when you start the VM and recommend to protect access via firewall rules or using a non globally routable address. By the way, it’s a good idea to form a habit of reading the messages CBSD outputs to the terminal. You might think you know what it’s going to tell you – and in most cases that’s probably true. Read it anyway. Eventually you’ll notice something that you would have missed otherwise.

And that’s really all there is to basic Bhyve VM management with CBSD!

Conclusion

There are a couple of caveats to be aware when beginning to manage your Bhyve VMs with CBSD. Apart from those however, it’s not much different from using the utility to manage jails. This is one of the unique selling points of this virtualization management framework: learn it once, manage multiple means of virtualization with ease.

As usual I have to thank CBSD’s creator not only for this great tool and his continuing maintenance. He was also once again kind enough to proof-read this article before I published it. This both prevents me from making false claims and usually results in covering interesting additional details. Your work and feedback is much appreciated, Oleg!

What’s Next?

There’s a lot more that you can do with VMs when it comes to CBSD. In the next article, we’ll take a look at some of that.

kraileth
http://eerielinux.wordpress.com/?p=5538
Extensions
Playing with CP/M – part 2
historycomputercp/mgameslegacyoperating systemsoftwarevirtualization
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/playing_with_cpm_pt2.gmi CP/M was the most successful microcomputer operating system during the 8-bit era. It has been highly influential and is still very much worth exploring if you’re interested in operating system history, … Continue reading Playing with CP/M – part 2
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/playing_with_cpm_pt2.gmi

CP/M was the most successful microcomputer operating system during the 8-bit era. It has been highly influential and is still very much worth exploring if you’re interested in operating system history, retro-computing or are simply looking for a fun lesson in minimalism (which is quite a grounding experience in times where we have gigabytes of memory and IT people at large seem to have lost any motivation to optimize and not waste resources).

The previous article covered working with disk images as well as sharing files between the emulated system and the host machine. If you’re completely new to CP/M and don’t know how to use it (or how to get started with emulation), you may want to one of my previous articles: “A Gentle Introduction to CP/M”.

In this part we’re going to take a look at some CP/M software.

Free CP/M Software

Having been the dominant operating system for some years, a ton of software has been written for CP/M. There are various places on the Internet where you can find some of those programs. A lot of formerly commercial software is being distributed on the Internet and while some of the companies don’t exist anymore or have lost any interest in material this old, you have to be aware that in general this is a bit of a legally gray territory.

I’m going to recommend one site in particular, where you can find more CP/M software than you’ll likely ever be able to try out: The HUMONGOUS CP/M Software Archives.

They list the Walnut Creek CD-ROM first, and unless you look for something specific, this is an excellent starting point. If you decide to give it a try, I would suggest you check out the “beehive” archive on it. This was a BBS for users of the Australian MicroBee computers. Since those used CP/M, the board collected a lot of nice and maybe some unexpected things (if you take a close look at the beehive index, you will find proof that the statement “the Internet is for porn” was even applicable for other means of telecommunication!).

While you can of course explore everything on your own, I’m adding a little excursion here to give people an idea about what some common file formats were. If you’re not interested in a timesaver, just skip the next section.

Archive Files, Libraries and Compression

If you’re completely new to this, it’s perfectly normal to be overwhelmed and not knowing what to do with all of those files offered by the Humongous CP/M Software Archives. It takes some time and dedication to make sense of it all. I’ll be honest here: I have used DOS back in the day and have childhood memories of some of the tools / concepts required to understand. Still it took me a moment to figure things out (again). So let me give you a little introduction to some essential information:

One of the very popular early archivers on DOS was a program called ARC (for “archiver”) which was used to put multiple files into an archive file of the same extension (.ARC). This was the time when CP/M was also still going strong, so a version for that OS also existed. To make it easier to see if an archive contained programs for DOS or for CP/M, the latter simply used a different extension: .ARK. So whenever you find a .ARK file in the archive, you know it’s something for CP/M. The opposite is not true, however. Since it was just a convention, some people who didn’t know (or care?) used .ARC on CP/M as well.

A predecessor to this was a tool that would create a library files (this is not a program library!) – essentially an uncompressed archive. While this didn’t reduce the required space, it allowed for distribution of just one file instead of multiple ones. (Okay, technically it probably does save space since combining multiple files into one means less wasted space than would be occupied due to the block allocation by the filesystem. But that’s a side-effect and not the main purpose.) The extension for these files is .LBR.

There were also multiple compression tools, with the most popular algorithms being crunch and squeeze. These allowed to compress a single file. They are a bit special in not having a static extension – they change the middle character of the existing extension of a file! With ‘Z’ indicating crunch and ‘Q’ indicating squeeze, for example .TXT would turn into .TZT if crunched and .COM would become .CQM if squeezed.

You can extract the original files from .ARK archives or .LBR libraries. You can uncrunch .?Z? files and unsqueeze .?Q? files. If you have a compressed library (.LZR or .LQR), first decompress it, then extract your files.

Other formats were used, too. Have a look in the Beehive “compress” directory to find a great collection of utilities for decompression and archive extraction.

Unpacking Files

You probably want to download at least these two files to be able to extract libraries / archives:

DELBR.COM
UNARC16.LBR

How about playing a little game? The first step is of course to download it. In the Beehive archive, there’s a text adventure titled “Barsoom Adventure #1: The Lost City”. To give it a try, download the archive:

Barsoom Adventure game

Now that we have the two applications as well as the the game archive, let’s copy them into the disk image for drive c:

% cpmcp ~/.cpmsim/disks/drived.dsk delbr.com unarc16.lbr barsoom2.arc 0:

In the emulator, let’s first see if everything is there:

A>c:
C>dir
C: DELBR COM : UNARC16 LBR : BARSOOM2 ARC

Looks good. Now we need to extract the files from the library (it doesn’t allow to view the contents first and I don’t think it can extract individual files):

C>delbr unarc16
Extracting: UNARC.CPM
Extracting: UNARC.DOC
Extracting: UNARC.FOR
Extracting: UNARC.MSG
Extracting: UNARC16.CPM
Extracting: UNARC16.DIF
Extracting: UNARCA.CPM
Extracting: UNARCOVL.ASM

Okay, the commands have a .CPM ending, probably to avoid confusing DOS users who might end up with the library, since DOS also used the .COM extension for executables. However this means we have to first rename it, otherwise CP/M won’t be able to run it:

C>ren unarc.com=unarc.cpm

Let’s list the archive’s contents next:

C>unarc barsoom2

Archive File = BARSOOM2.ARC

Name	Length Disk Method Ver Stored Saved Date Time CRC 
============ ======= ==== ======== === ======= ===== ========= ====== ====
-READ .ME 768 1k Crunched 8 454 41% 20 Sep 90 6:23p 6CE1
BARSOOM .COM 39552 39k Crunched 8 28682 28% 20 Sep 90 6:23p D1C4
BARSOOM1.DAT 6656 7k Crunched 8 4032 40% 20 Sep 90 6:23p A71B
BARSOOM2.DAT 54912 54k Squashed 9 37715 32% 20 Sep 90 6:23p FCD8
==== ======= ====	======= ===	====
Total 4 101888 101k	70883 31%	E298

Okay, seems like the game is pretty big – in particular that second data file.

C>a:stat
A: R/W, Space: 11k
C: R/W, Space: 18k

Uh, no chance on the same disk. We could clean up some unnecessary stuff, but let’s simply extract to drive D:

C>unarc barsoom2 d:

I’ll leave out the output here as it’s identical to the previous command line, the only difference being that now the files are extracted.

C>d:
D>dir
D: -READ ME : BARSOOM COM : BARSOOM1 DAT : BARSOOM2 DAT
Playing Games on CP/M

We’re all set. What’s in the readme document, though?

D>type -read.me

	BARSOOM


This text adventure game runs under CP/M 2.2 on any type of terminal.

The game consists of three files: BARSOOM.COM
	BARSOOM1.DAT
	BARSOOM2.DAT

(Once you have "saved" your position during the game there will 
also be a "BARSOOM.SAV" file.)

To play: have the three files, extracted from the library and unsqueezed,
on your logged drive. Type "BARSOOM" -- it starts with a couple of
screens of instructions.

Complaints and bug reports can be addressed to Susan Schnitger on the Boskug
BBS at 617-965-7046.

(Released 5/29/89)

I don’t know if this is a very late CP/M game or if Susan wrote it much earlier and just kept maintaining it for some years. This readme is interesting for another reason, too—the key here being the info that it runs on any type of terminal. That’s relatively easy to do with text adventures but not with many other types of games.

Just run the BARSOOM program to play. If you’ve never played a text adventure, you’ll probably be frustrated quite soon. Why? Because those old games were often hard. You should not only like a challenge, but also understand that you were supposed to try things out and to fail over and over again before eventually beating the game! This makes it very satisfactory when you finally manage that, but few people are inclined to investigate hours into exploring (and drawing your own maps as the world is typically too large to keep it all in your head!) just for a simple “you win” screen. But that’s a fundamental misunderstanding: it was (and is) all about the experience of exploring the world and less about “beating the game”.

On my first try I went just in one cardinal direction until dying of thirst, only having seen drifting dunes. You’re likely in for the same fate until you figure out where you supposed to go. And no: you usually really had to figure it out by trying, there often wouldn’t be clues! ’80s game design. Or lack of design. You decide.

While this example is a hobbyist take on a text adventure and published for free, there were also various commercial games like this. One very popular example is the Zork series. These games have been very influential, and for a good reason. They are set in a fascinating world and really well designed for their time. You might think that a pure-text adventure can’t be so great. But to give you an idea of how complex the world actually is, how many areas it featured, here’s a low-res version of a map created by Aaron A. Reed for “50 Years of Text Games” (CC BY 4.0):

Zork I map low-res

Or maybe you want to try out something newer? Get the 2020 (this is not a typo!) text adventure The Queen’s Footsteps which is available for various retro platforms, including CP/M.

The advantage of this pretty nice game is that it follows more modern design standards which one might say are more “fair” (i. e. no risk of sudden, undeserved death or puzzles that make little sense).

Terminal Trouble

But why were text adventures so popular back in the day? Sure, they were relatively new. There’s another reason, too, though: there was not much of a barrier to play them. Let’s say that not only there wasn’t any standardization in handling graphics, yet – even terminal capabilities and functions were not standardized at all! Games written for one type of terminal would not work on any other, unless you patched them.

Let’s take a look at rogue for example (another game that was so important that to this very day there’s a whole genre that’s called “rogue-like”!). It’s an interesting D&D-inspired RPG. You can download it here.

When you have extracted the archive, read the last bit of the file ROGUE.DOC – or look at the following screenshot:

The last screen of the Rogue documentation

That text is absolutely not joking. If you run the game as-is despite having different terminal properties, the result looks something like this (the game uses randomized dungeons, so if you try it out yourself, it will look slightly different):

Rogue – completely garbled due to incompatible terminal settings

If you modify the game to use the proper terminal sequences, it rather looks like this:

Rogue the way it is meant to look

Now one can make out a room (dashes and pipes are walls, the @ is the player, + is a door and so on). Looks more like a playable game, doesn’t it?

As you can see, first having to use a debugger to load the program into memory, change various hex values and then save the program to disk again may not be something for everyone. Well, and of course you had to know how your terminal was different from the one assumed by the program to know what you had to patch! If you want to get an idea of how involved the process was, feel free to read the manual of the terminal that Rogue expects: Televideo 920 manual. That’s why we still have the (n)curses library on Unix today!

If you’re interested in a nice git repo with a collection of already patched CP/M games, have a look here: https://git.imzadi.de/acn/vt100-games.git

Conclusion

Back in the day, computer games didn’t play the role they do today with a whole industry behind them. But like with just about everything related to home computers, groundbreaking work was done. It’s both fun and educational at the same time to go back to the works of the pioneer days and experience what things were like. While the actual games were mentioned only briefly (Zork and Rogue alone would deserve their own articles!), in this context they were just an example to show what you could do with CP/M. We’ve used archivers and eventually even played some games this time. I hope you enjoyed the read (or the experience if you followed along with an emulated system).

On a Personal Note

As the year draws to a close, I thought that I’d do something that I haven’t done before and add this section to an article. I don’t just write technical articles, I’m also a hobbyist fiction writer. My latest project is a Retro-Futurist novel set in a noir-ish, Cyberpunk-esque world. It’s anchored in the tech level of the 1980s to ’90s, and I did about a year of world-building before writing the first line. Being obsessed with detail, one of the things covered are multiple operating systems – one of them clearly inspired by CP/M.

The plan is to eventually publish it for free (maybe with a paid ebook option for people who liked it). However I’m not an English native speaker, and writing in a foreign language is not exactly easy (even less so if you’re a bit of a perfectionist and chronic unhappy about your inadequacies). If anybody would be interested in test reading an immersion-driven story about social decline, morally gray actions and of course tech that can still be repaired or modded with ingenuity and a soldering iron, I’d love to hear from you in the comments!

What’s Next?

I’ve decided to state that I’ll maybe continue the CBSD series. Since planning to do so didn’t work out several times, it might make sense to try a different approach. 😉

kraileth
http://eerielinux.wordpress.com/?p=5477
Extensions
Playing with CP/M – part 1
historycomputercp/mlegacyoperating systemsoftwarevirtualization
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/playing_with_cpm_pt1.gmi Earlier this year I wrote an article explaining how to use the CP/M operating system which has been the dominant OS of the 8-bit era of microcomputers. The article was well-received … Continue reading Playing with CP/M – part 1
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/playing_with_cpm_pt1.gmi

Earlier this year I wrote an article explaining how to use the CP/M operating system which has been the dominant OS of the 8-bit era of microcomputers. The article was well-received and some commenters asked for more. While I originally had other plans, a lack of time for a bigger project during November made me come back to my leftover notes and turn it into this follow-up. Today we’ll go beyond the very basics and look at actually making good use of this fascinating old OS rather than just using CP/M for the sake of it! Well, more precisely we’ll do the final preparations to start playing around with CP/M software in the second part.

If you’ve come here without knowing how to use CP/M, you may want to read the previous article which covers the basics: “A Gentle Introduction to CP/M”.

And if you want to know a bit more about the line of operating systems of the CP/M family (the various versions, the multi-user version MP/M or the networking versions), you can have a look at two articles I wrote last year:

Heads up: while you can of course use any other emulator to play with this OS, I’m going to assume z80pack here. This is important to know because the CP/M distributions that come with it include some very useful additional software that was not part of the original CP/M as released by Digital Research.

Getting Started

We have (emulated) CP/M up and running as well as a basic grasp of how to work with the OS. So what’s next? Historic operating systems are interesting, but CP/M didn’t exist as an end in itself, of course. It was meant to enable the user to run programs on the computer, and to do that in a relatively convenient way (providing a filesystem and various utilities). That means the next logical step is to move beyond the core OS and use it to actually do something.

In the previous article, we explored CP/M 2.2, and we’re going to stick with it. It’s (somewhat) familiar ground now, right? The most pressing limitation that we face if we want to use CP/M is memory. Not only main memory (RAM) is precious (up to 64k), but disk space is scarce, too. With the 250 kilobyte 8″ single side, single density (SSSD) disks that were used on most platforms, each drive doesn’t exactly provide a lot of space. The z80pack versions of CP/M 1.3 and 1.4 come with only one system floppy while versions 2.2 and 3 come with two. Let’s expand on that a little.

We Need More Disk Space

The z80pack emulator comes with a utility to create new disk images, mkdiskimg. It’s really simple: just execute it and give it a drive letter as the command-line argument, and it will place a new disk image in the current directory. If you run it without arguments (or invalid ones), it will print usage info:

% mkdiskimg
usage: mkdskimg a | b | c | d | i | j | p

Since we want a third floppy for CP/M 2.2, we could simply do this:

% mkdir -p ~/.cpmsim/disks/custom
% cd ~/.cpmsim/disks/custom
% mkdskimg c

The result is a file named ‘drivec.dsk’ and it’s 250k in size. We could also have used ‘a’ as the argument, then the file would be named ‘drivea.dsk’. The fresh disk images would be identical, so it’s really only a naming thing – mostly! There’s one thing you need to know, though: a – d are meant to produce floppy disk images for CP/M, whereas the other letters generate hard disk images. If you choose ‘i’ or ‘j’, it will result in an empty 4 megabyte HDD image, giving us lots of space (by the standards of the time CP/M was popular) to work with. Finally ‘p’ is special. It also creates a HDD image, but one for a drive that is a whopping 512 MB in size!

Of course, no drive that large existed back in the day. However that’s the limit that was chosen for CP/M 3. Thus the OS can address a maximum of 512 MB on a single HDD and it’s actually possible to use such a gigantic image. Keep in mind, though, that this is version 3 only. With version 2.2 we’re stuck with the 4 MB drives (which is still a lot better than the 250k floppies).

After we’ve generated an image for the floppy in drive C, we can generate an HDD image as well and then softlink them to where the emulator script (if you’re not using the Ravenports version, adjust the path to your configuration) expects them:

% mkdskimg i
% ln -s ~/.cpmsim/disks/custom/drivec.dsk ~/.cpmsim/disks/drivec.dsk
% ln -s ~/.cpmsim/disks/custom/drivei.dsk ~/.cpmsim/disks/drivei.dsk

Let’s fire up CP/M and check if it worked:

% cpm22
A>stat c:
Bytes Remaining On C: 241k
A>stat i:
Bytes Remaining On I: 4048k

Excellent! We’ve vastly expanded on the available storage capacity (previously the remaining space of floppy a and b combined was less than 180k). If you need even more space, you can create images for d and j. Just don’t try to use 4M images for drives a – d, you will still only get 241k usable space.

Putting the Drives to Use

The simplest way of putting something on our shiny new drive I is, of course, just copying something there. The previous article covered the somewhat quirky syntax of PIP, so let’s use it:

A>pip i:=a:bye.com

Another is to create a text file with an editor. CP/M’s editor is ED, but it might not exactly meet your expectations. The reason for this is that ED is a line editor. It allows you to edit a file with line-based operations—which is rather confusing if you are used to today’s editors.

If you’re in love with Unix’ editor of the same name (which works differently, though!) or you think that it’s completely unnecessary to always see the file contents while you edit it (it’s in your head, anyways, right?), feel free to explore ED in-depth. I would recommend reading the respective manuals. Should you just be curious what it’s like, you can have a look at an older article that I wrote where I try out ED among other things.

I don’t mean to say that ED is terrible. In fact I think that it’s a surprisingly powerful application. And if you take into consideration that not all CP/M machines had a monitor but might use a so-called hardcopy terminal, a line-oriented editor makes a lot of sense. Always printing out a few dozen lines whenever you make a change, is not practical at all. Still I assume that you’re using a monitor and read the output on a screen. And that’s where visual editors come into play. They are a game-changer when it comes to convenience and ease of use.

One particularly popular program on CP/M was MicroPro’s WordMaster. It was commercial software, so you had to buy it. However the author of the z80pack emulator was kind enough to simply provide it on the first system floppy (thus massively lowering the bar to exploring CP/M). Since it’s readily available, let’s give it a try, shall we?

A>wm i:test.txt

It creates a new file ‘test.txt’ on drive I. Unlike with ED, you can just type away immediately. When you’re done, press ESC which enters command mode (indicated by the asterisk prompt). Type ‘e’ there to save and end the editing session.

I’m going to edit the file again real quick and make some changes to what I wrote earlier. Now let’s check if that worked:

A>type i:test.txt
This is just a simple text file written with WordMaster.
It even has more than one line!
A>type i:test.bak
This is just a simple text file.
But it has more than one line!

As you can see, the editor automatically created a backup (.bak) file when I saved the changes. To close without saving, use ‘q’ instead of ‘e’ on the asterisk prompt, BTW.

WM is a topic on its own and would deserve a whole separate article. It has a lot of functionality stuffed into the 11k program and it’s not hard to see why it was loved so much back in the day. If you want to use it, it makes sense to learn a couple of basic movement key combinations – for example CTRL + E moves the cursor one line up and CTRL + X moves it one line down. By default the editor is in overwrite mode, so when you start typing, you’re replacing what was on that line before.

Strictly speaking, this is all you need to be able to do the most basic editing. It’s definitely worth to read the help and pick up some more combinations as they allow for pretty convenient and efficient editing. WM is not half bad! And since it was so popular, a lot of other programs simply used the same movement commands rather than inventing the wheel over and over again (which is a really good idea!).

Sharing Files

This is all nice and fun, but when using a historical system like this, sooner or later you will want to exchange files between the guest and host operating systems. We will explore two different ways of doing this: using native z80pack functionality and with external tools.

The z80pack Way

The z80pack emulator actually has functionality built-in to do this, and it’s quite easy to use. On the second system disk, there are the two programs ‘r’ and ‘w’ (for read and write). The former can copy a file from your host system into the guest OS while the latter writes a file from CP/M to your host OS’ filesystem.

For example you could transfer the WordMaster help file from the guest to the host like this:

A>b:w wm.hlp

File WM.HLP written to host PC

Of course you have to mind the limitations that apply to filenames—just because “ümlauts totally rule!” is a perfectly acceptable filename on Unix (even though it’s gross), don’t even think of doing this to poor CP/M. The exchange with the host works in the way that the file written to (or read from) will be in the present working directory (i. e. from where you ran the emulator).

To copy the file ‘testfile.txt’ from the host system to CP/M, you can do this (provided the file exists in the directory from where you launched the emulator):

I>b:r testfile.txt

File TESTFILE.TXT read from host, written to CP/M
Using the CPMTOOLS Utilities

However there’s another way of interacting with the CP/M disk images. Just install cpmtools (they are available via Ravenports in case your OS / distribution of choice doesn’t package them)!

This set of tools is extremely useful as you continue your journey of exploring CP/M and I highly recommend getting familiar with them. Let’s start with the most basic one, cpmls. It works like this:

% cpmls ~/.cpmsim/disks/driveb.dsk
0:
bios.hex
bios.z80
boot.hex
boot.z80
bye.asm
bye.com
cls.com
cls.mac
cpm64.sys
r.asm
r.com
reset.asm
reset.com
speed.c
speed.com
survey.com
survey.mac
sysgen.sub
w.asm
w.com

As you can see, it lists all the files that are in user area 0. The command supports some switches which can for example change how the file listing is formatted. For example use ‘-d’ to get CP/M-like output:

% cpmls -d ~/.cpmsim/disks/driveb.dsk
BOOT HEX : BYE ASM : CLS MAC : SURVEY MAC
R ASM : CLS COM : BOOT Z80 : W ASM
RESET ASM : BYE COM : SYSGEN SUB : BIOS HEX
CPM64 SYS : SPEED C : BIOS Z80 : SPEED COM
SURVEY COM : R COM : RESET COM : W COM

Have a look at the manpage (all of cpmtools’ manpages are excellent!) to find out what other options are available and try them out to find the one you like best. Of course it’s also possible to to limit the results (mind the quotes – it’s a pattern for cpmls, we don’t want shell globbing for the current directory!):

% cpmls ~/.cpmsim/disks/driveb.dsk '*.asm'
0:
bye.asm
r.asm
reset.asm
w.asm

But there’s one more thing that needs to be mentioned. You need to mind the type of disk your accessing. Here’s an example without it:

% cpmls ~/.cpmsim/disks/drivei.dsk

Why is there no output? Haven’t we copied BYE.COM and created a text file on that drive? Yes, we have. But the problem is that this is not a standard 250k floppy image but a 4MB HDD one. CP/M’s disk format is pretty primitive. For example, it doesn’t record the type or layout information! Therefore there’s nothing that the cpmls tool could detect there. Which in turn means that whenever you’re using a non-standard image type, you have to specify it.

CPMTOOLS and Disk Formats

To find out which ones the program knows about, have a look at “${prefix}/share/diskdefs” as the manual suggests. If you do and you’re shocked that it contains almost 150 (!) disk definitions – well, these were the days when that technology was still new. It was much later that vendors eventually settled on standards. In the chaotic time before that, every vendor simply created their own format (or multiple formats if only one would have been too easy!).

Let’s try again, this time with specifying the right disk format:

% cpmls -f 4mb-hd ~/.cpmsim/disks/drivei.dsk
0:
bye.com
test.bak
test.txt

That looks much better, doesn’t it?

The cpmtools utilities can do more than just list files contained in images, though. You can for example remove files in an image right from your Unix host’s shell:

% cpmrm -f 4mb-hd ~/.cpmsim/disks/drivei.dsk '*.bak'

The command returns silently. So did it work?

% cpmls -f 4mb-hd ~/.cpmsim/disks/drivei.dsk
0:
bye.com
test.txt

Yes, it did! But even better, there’s also cpmcp which can be used to copy files to or from CP/M disk images. We can for example copy the BYE transient to the /tmp directory on the host machine like this:

% cpmcp -f 4mb-hd ~/.cpmsim/disks/drivei.dsk 0:bye.com /tmp

As you can see, this supports user areas. This means we can copy something onto a CP/M disk and into a specific user area without first having to get PIP there! The utility involves some checks, so as expected, trying to copy a file over that has an invalid filename by CP/M’s standards, results in this:

% cpmcp -f 4mb-hd ~/.cpmsim/disks/drivei.dsk edelib___std.log 1:
cpmcp: can not create 01edelib___std: illegal CP/M filename

What however does work is changing the name:

% cpmcp -f 4mb-hd ~/.cpmsim/disks/drivei.dsk edelib___std.log 1:edelib.log

Let’s check that to make sure it worked:

A>i:
I>user 1
I>dir
I: EDELIB LOG

Indeed! That’s pretty nice. When using cpmcp for text files, though, you usually want to use the ‘-t’ switch. It’s used to convert text files between the conventions of CP/M and Unix. Otherwise your line breaks might not work as intended.

There are some more programs among cpmtools that allow for setting CP/M 3’s file attributes, creating new disk images (more flexible than z80pack’s mkdskimg) and even a simple fsck for CP/M filesystems.

Conclusion

This article covered working with disk images as well as how to transfer files between your Unix-like host system and the emulated CP/M system. This is necessary to be able to eventually run software that doesn’t come distributed with the z80pack emulator. It also touched on using WordMaster for a more user-friendly editor.

What’s Next?

In the next part we’ll finally take a look at some more CP/M software and even play some games.

kraileth
http://eerielinux.wordpress.com/?p=5454
Extensions
EuroBSDCon 2025 report (2/2) – Main conference & trip home
bsdpersonal
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/eurobsdcon_2025_pt2.gmi In the previous part I covered my arrival and the two tutorial days. This one is about the main conference, the social event, my trip home and a conclusion. EuroBSDCon 2025 … Continue reading EuroBSDCon 2025 report (2/2) – Main conference & trip home
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/eurobsdcon_2025_pt2.gmi

In the previous part I covered my arrival and the two tutorial days. This one is about the main conference, the social event, my trip home and a conclusion.

EuroBSDCon 2025 report (1/2) – arrival & tutorial days

Conference Day 1

It’s now 7:50, and I’ve just returned from breakfast. I realize I didn’t write anything down this morning—I simply resumed working on ports where I left off last night. I think I woke up around 6:00, which means I’m slowly adjusting to a more natural schedule (well, it’s not like this evening isn’t going to blow this, right?). I wore one of my EuroBSDCon t-shirts and took my time during breakfast, hoping to run into someone. It didn’t happen, but the breakfast was good.

At 8:30, I still had plenty of time, and I decided to leave early and take a stroll. The sky was still cloudy but dry, so I figured I’d be able to take some pictures. Let’s see how that goes.

The view from my room (there’s actually a person in that cage let down from the left crane! No idea what they were doing there.)

Sometimes things turn out to be even truer than you expected! I had planned to walk only the last few tram stops, but I ended up walking the entire way. The reason was simple: I discovered that the tram line I usually take doesn’t operate on weekends! Since I don’t have mobile internet (see part 1 for an explanation of my challenge), I couldn’t look up an alternative route unless I walked all the way back to the hotel—which I didn’t want to do. Fortunately, I knew the way along the tram tracks (which, of course, branch out as you’d expect in a city). This meant I actually got to turn on my phone a few times to take pictures!

The most interesting thing along the way was what I thought was a national monument—a gas flame rising from a stone cube. When I tried to photograph it, the police told me not to. I later deleted the first picture I’d taken, respecting local rules. At the time, I assumed it was a matter of piety, perhaps related to the Croatian War of Independence. I later found out it’s actually a national ministry, and the photo ban is likely for security reasons. If you’re curious what it looks like, you can check the Wikipedia page (scroll down to the middle of the article), where they have a photo of the building and the stone cube with the flame (though I’m not sure if it was authorized!)

It’s now 22:45, and I’m back in the hotel room. I decided to take a shower immediately, so it’s about half an hour after I arrived. Time to write down how the day went!

One of the highlights for me was finally getting to talk to Michael W. Lucas, the author of BSD fame, in person. He’s from the US and doesn’t like flying at all, so he doesn’t visit Europe very often. I’d had a brief email exchange with him years ago, but actually speaking with him was an entirely different experience. When I told him that his book Absolute FreeBSD (2nd edition) had played a role in my decision to take the job that got me involved with *BSD in the first place, his reaction was, “Sorry for that!”—so very authentic Michael. We also briefly discussed how the publishing industry has changed over the last few decades and touched on his upcoming book projects. Of course, I won’t spoil anything here; if you’re interested in his books, you probably read his blog anyway, right?

I ran into Jörg Sonnenberger again, who hadn’t attended the last two years, and we had a quick chat. I also caught up with Lukas, who had been a first-timer last year and was giving a talk this year. Garlef, whom I’ve known since Vienna, and Benedict, along with a few other people, I had already met during the tutorial days.

Now, let’s recap the actual conference day. The keynote was fantastic. Terence Eden is a gifted speaker and managed to deliver the perfect blend of personal anecdotes—looking back at things we’ve all experienced—and valuable information, along with some geeky bits. This made it both entertaining and thought-provoking.

The fountain next to the hotel, this time from the ground

The first talk I attended was on fast jail provisioning on ZFS. Jan has come up with something pretty interesting, and I’ll need to take a closer look at it when time permits.

Lunch time! A catering service had prepared a nice selection of warm food. More interested in talking to people than in what I was eating, I grabbed a plate, picked something without looking too carefully, and ate it. It was alright, though. For dessert, I had some cake.

After lunch, I went to Alfonso’s talk on a two-step installer for FreeBSD. He’s already done some great work and plans to finish his alternative installer by the end of the year. It offers some functionality I absolutely want to see, and I’ll have to get in touch with him again later.

Next was my only OpenBSD talk this year. Marc presented on a simple protocol for package build servers that he created, and he definitely didn’t disappoint. The functionality to dynamically adjust build jobs is great, and I’d love to have that in Ravenports too!

The slot after that was one where I was conflicted: I wanted to go to Lukas’s talk on PkgBase, but Mario’s talk on a sovereign infrastructure stack also felt like a very important topic. In the end, the fact that Mario’s talk was about the Swiss demo scene as well made me pick that one. Fortunately, the talks were recorded, so I could watch the other one at home. Mario offered some insights into running NGO infrastructure on FreeBSD, and it was interesting. They’re even doing the right thing by documenting everything in a public wiki for others to use.

For the last talk (or the last two, depending on how you look at it), I went to Liberating the Social Web with BSD. Jeroen and Stefano held it together and got a double slot. I must confess that I had planned on sneaking out after the first half to attend Dave’s talk on 25 Years of Designing Resilient Systems. However, it’s next to impossible to leave when Stefano is talking—he sprays his passionate and always positive energy into the room! So I got stuck. It was really nice to learn more about the behind-the-scenes work of BSDCafe (and now illumos Cafe too!). While there was, of course, plenty of technical information, I’d say the cultural and philosophical aspects were even more important (to me, at least). I especially liked the many references to Italian bar (=café) culture. But that’s probably just me—ever since regularly visiting Italy for holidays as a child, I’ve had a soft spot for the Italian way of life.

After the conference day, while waiting for the social event to begin, I met Benny Siegert at the stickers table. We talked for about an hour about how he became a NetBSD developer, niche BSD systems, obscure architectures, Pkgsrc, and a lot more. The conversation was both fun and really interesting.

Social Event

This year’s social event was held just a few meters down the road. As in most years, with so many people, it was quite loud. Unlike last year in Dublin, however, it wasn’t in such a cramped space, and we had the whole place to ourselves. I chatted briefly with Patrick and a few other people but eventually ended up sticking around with Christoph. That meant catching up on more NetBSD-related topics. Through him, I also got to meet Martin, who handles release engineering for NetBSD among other things. He had read my blog post on sysinst and confirmed that it wasn’t actually me being too stupid to install to a raidframe (phew!). That part of the NetBSD installer is simply not finished in the 10.x line (though it might make it into NetBSD 11.x). There’s some other nice stuff coming in that version, so I’m looking forward to trying it.

Dražen Petrović Basketball Hall with a statue of the late player

The food was good too, and this year there was plenty of it. Overall, I liked it much better than Dublin’s busy pub, where the music was too loud and the situation rather chaotic. Still, around 22:00, I decided it was enough for me. To my left sat someone with a pretty loud voice who had to talk across the table all the time, and I was seriously starting to fear for my ears if I sat there for another hour! So I said goodbye and walked back to the hotel. While I had originally planned to use the conference Wi-Fi to look for an alternative route, the day had been so busy and packed (which is a good thing, obviously!) that I didn’t actually do it. Feeling adventurous, though, I decided not to take the known route. Fortunately, my sense of direction didn’t fail me, and after about half an hour of walking, I arrived at the hotel.

So much for now—time to get a bit of sleep!

Conference Day 2

As expected, I was too tired to write anything in the morning, but I’m trying to fit it into the conference day. I had planned to get up at 7:00 but actually woke up around 6:00. Despite not being fully functional, my brain started thinking about the day ahead, so I eventually gave in and got up. It took me quite a while to get ready for breakfast, though. Since breakfast was only open from 7:00 on Sundays, that was fine. I went down at 7:15 and was thus still relatively early. I had a good breakfast again, knowing it would be my last one here.

Back in the room, I downloaded a development snapshot of the upcoming NetBSD 11.0, dd’d it onto a USB key, and tested whether it would boot on my Intel Ultrabook Framework laptop. I had promised Christoph and Martin at the Social Event to give it a try. When I originally got the machine and tried to boot NetBSD on it (for a dmesg), the system had panicked. But this new version booted into the installer just fine.

A female statue along the way, no idea whom it depicts unfortunately

At about 8:40, I left the hotel, leaving a bit earlier since I intended to take a longer route that would pass the tram station I’d need the next morning. That worked out well, and I even immediately found my way from there to the university. Fortunately, I was in time for the keynote, which was quite good. The cURL project, which offers bug bounties, is facing increasing issues with AI-generated fake reports. Daniel made the talk entertaining, even though the problem is quite serious and a good solution is not in sight.

After that, I attended A History of the BSD Daemon—you can’t go wrong with Kirk, and this talk was no exception to the rule. Next, I went to Patrick’s talk. It was interesting to see that his company wasn’t only facing some of the same challenges as my employer but had also come to the same conclusions. However, they had already implemented what we’re still planning. I was in the right room for the group photo, which was a bit of a challenge with so many attendees!

When I went to lunch, Robert recommended not filling my plate with just any food, as further down the line there would be some pretty nice dishes. I followed his advice, and he was right. For example, I hadn’t noticed the seafood dish the day before. I joined him at his table, and we talked about assembler programming. He gave me some tips on how to get started if I really wanted to.

I’ve had a lot of great discussions so far. For example, I talked to Benedict about a secure laptop project I have in mind (yesterday, I had already discussed it with Chris). Garlef and I talked about various things—from the more obvious ones (tech) to pretty unrelated topics (Black Metal, culture, and so on!). I also got a chance to tell Christoph and Martin about my successful boot experiment in the morning and to ask John Baldwin about a problem I have with FreeBSD’s EFI loader and PXE booting. That’s all I managed to jot down quickly after lunch.

It’s now 20:15. The conference is over, and I’m back in my hotel room, ready to write down some further notes after arriving about half an hour earlier. But I should probably continue in order. The first talk I attended after lunch was Olivier’s, and it was interesting to learn more about that topic. I knew you could do something like that with FreeBSD’s MAC framework, but I had no idea how or what the limitations were.

Next came this year’s most cruel slot, where I had some interest in all three parallel talks. Well, I currently don’t use a whole lot of OpenBSD, so that was the most logical candidate to miss. Eirik’s talks are always great, but in the end, I flipped a virtual coin and went to Christos. He didn’t present solutions for everything—but that wasn’t what he had promised in the first place. He asked the right questions, though, and sparked a healthy discussion. I don’t regret going there.

I then went to another talk given by Patrick to learn more about the state of distributed networked storage on FreeBSD. I would have liked to attend Stefan’s talk as well, but I’ll have to watch the recording, I guess. The last one was easier again: while I think Capsicum is pretty interesting, the talk was obviously more aimed at developers. So I went to Benedict’s and Andreas’ talk instead—and that one was great too. I’ll be very interested to watch that space and eventually give it a try myself.

As usual, a lot of garbage as well as a few very interesting items were auctioned off. And then, finally, we were told the location of next year’s conference: Brussels!

It’s now 22:00. My hair has almost dried, and I’ve finished writing down my report for the second part of the day as well as reconstructing what happened up to lunch from my quick notes. I’ve also finished packing most of the stuff I won’t need in the morning. Time to get a few hours of sleep.

Trip Back Home

I tried to stay in bed a little longer after waking up at around 4:00, but I couldn’t fall back asleep. About half an hour later, I got up and wrote some emails. At 5:10, I packed up the rest of my belongings and left the room to check out—there really wasn’t much point in waiting in the room over some other location. On the way to the tram station, I ate half of my fruit, and despite walking slowly, I arrived in time. At about 5:45, the tram came, and a while later, I arrived at the bus terminal. It was good that I was early, as it took some time to orient myself. In the end, I found the right platform for the airline bus.

A large art installation at Zagreb Airport

While waiting for the bus to depart, an elderly lady asked me something in Croatian. When I asked whether she spoke English too, she told me she had lived in London for many years and was flying there again to sort some things out. We talked for a while, and it was nice to kill some time. This time, the radio was obviously tuned to a different station, as the music was much more chaotic (aka. _modern_), but still mostly in Croatian. The sun had risen, and while it was another gray day, I decided to stop taking notes and take in some final impressions of the country on the way to the airport.

I’m at the airport now and have already gotten my boarding pass. Since there were several counters open, I didn’t even have to wait at all. What a contrast to the lengthy queue in Frankfurt! It’s 7:15, and boarding starts at 8:35, so I’ve got more than enough time for this travel diary and other things. I’m going to eat the rest of my food and drink the remaining water, then proceed through the security check.

It’s 8:00 now, and I’m sitting next to the gate. Everything went absolutely flawlessly with the security check. In the international zone, there’s a large piece of art, I’d call it—a circular wall made out of metal tubes, many of which have a plate that you can spin. On one side of the plate, there’s a photo, and on the other, the name of the person and a short text about why they were significant. This was a pretty interesting opportunity to learn a bit more about some famous Croats, from inventors to politicians to celebrities from sports or culture. I bought a little souvenir for my children in one of the duty-free shops and headed for the gate, where I met Patrick and John again. Both seemed to be occupied, working on their laptops.

Now it’s 9:55, and I can write something down again. Boarding worked pretty well, but then there was a considerable delay due to technical issues. Instead of taking off at 9:05, we departed around 9:45, so at this point, we’re a bit late again. Like with the previous flight, I don’t need to worry about connecting flights, but of course, this could be quite annoying for other people. But I did pick up some more Krekeri (which I haven’t tried yet; I’m bringing them home to give to my family).

A large art installation at Zagreb Airport

It’s 11:45 now, and I’m sitting at the baggage claim in Frankfurt. The display asked for patience, as it’s being delayed, so this might take some time.

I’m in a very crowded regional train at Frankfurt Central Station. It’s 12:45, and maybe the same trick will work again? When I wrote about the delay in the last entry, my bag arrived in less than five minutes. This train was meant to leave at 12:25, but there have been some unspecified issues that delayed it a couple of times now. The last announcement didn’t sound too promising, explaining that the train would be delayed “indefinitely” due to a disruption of service at some hub along the route.

It didn’t work immediately. But at 12:55, the train finally left—without another notice. But I really don’t care at this point. Half of the car is full of students going home after school. Their behavior is disturbing. It’s not just that they are very loud and pretty reckless, taking absolutely no notice of other passengers. What I find even more alarming is what they say, not just how. The kind of casual sexism that we as a society finally overcame to some degree in the 2000s is definitely back with a vengeance. Their language is extremely primitive and vulgar. But what’s actually disturbing is the girls participating in this as a duck takes to water. I couldn’t find even a trace of self-esteem or regret in them.

There we have it: we’re back to accepting that “things are as they are.” Fantastic! I’m back home again, but it feels less and less like home. Yet I think of the “Run BSD — Fight Fascism” stickers that I have in my bag. I know a lot of people who will want one. And that’s something, isn’t it?

Conclusion

But to end things on a lighter note: I’ve definitely had a great time at the conference. Even though the friendly and inclusive BSD community in a way highlights the contrast with a declining civilization around us, it’s also proof enough that living differently is of course still possible.

In previous years, I’ve thought that tech—and in particular our love of BSD—is what unites us. But now I’m leaning more toward the idea that it’s actually something else that makes all the difference. It’s about trying to be decent people, despite considerably large parts of society either struggling or having given up.

If you’re even remotely interested in BSD, definitely come to the conferences. It’s a different world entirely, and completely for the better. Of course, there are always interesting new things happening in our favorite line of operating systems, and it’s good to keep up on that. Maybe see you next year in Brussels? Oh, and if you are interested in any of the talks, have a look at the recordings.

What’s next?

Next will be me finally picking up my series on CBSD that I’ve been keeping on halt for far too long.

kraileth
http://eerielinux.wordpress.com/?p=5437
Extensions
EuroBSDCon 2025 report (1/2) – arrival & tutorial days
bsdpersonal
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/eurobsdcon_2025_pt1.gmi This year’s EuroBSDCon took place in Zagreb, as usual in late September. I wasn’t sure I’d be able to attend until about three weeks before the event, due to circumstances beyond … Continue reading EuroBSDCon 2025 report (1/2) – arrival & tutorial days
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/eurobsdcon_2025_pt1.gmi

This year’s EuroBSDCon took place in Zagreb, as usual in late September. I wasn’t sure I’d be able to attend until about three weeks before the event, due to circumstances beyond my control. Despite the effort to fit it into my schedule, it was absolutely the right decision to go! As in previous years, I continued my quirky little analogue game: bringing the schedule, maps, and notices on paper, and deliberately avoiding using a smartphone. Admittedly, doing this isn’t getting any easier—even within my own country. But navigating a foreign city this way is definitely always an interesting challenge. It worked out surprisingly well this year, though.

If you’re interested in my previous reports, find them here:

EuroBSDCon 2024, part 2
EuroBSDCon 2024, part 1
EuroBSDCon 2023, part 2
EuroBSDCon 2023, part 1
EuroBSDCon 2022

I briefly considered attending only the main conference. But skipping the tutorials would mean missing out on two days of BSD goodness, so I decided to participate in them as well. EuroBSDCon only happens once a year, after all! I’ll be following my established format for this report, covering the entire experience: the trip itself (which I consider an integral part of the conference feeling), the tutorial days, and the main conference. I took approximately 12.5 pages of notes throughout the trip and conference, whenever I had a moment to jot something down that felt worthwhile.

These days, I usually travel around my country by car and generally avoid events and parties. So, going on a trip like I used to do more frequently in the past is a grounding experience for me. As a hobbyist writer who, after decades of writing Fantasy and Sci-Fi, has switched to Cyberpunk, I’ve become somewhat accustomed to offering harsh(ish) social commentary (it’s difficult to do the same with elves, orcs, and unicorns, as you can probably imagine!). Well, and I’m certainly not spilling any secrets when I document my observations on how things are going in Germany today. Let’s begin.

(Oh, and since a lot of people are complaining about the rise of the em-dash these days, out of pure spite I’ve started actually using them. Yes, LLM usage by a society to a significant part composed of people who never achieved mental adulthood is a terrible idea. But certainly not for encountering some proper English on the net more often than before!)

The trip to Croatia

After a few years, I was confident I had enough experience and even a bit of a routine for this. But as usual, life chooses to punish arrogance. Things looked simple and even pleasant on paper. However, the adventure began right at Darmstadt main train station, the starting point of my journey. I arrived at about 6:40, giving me plenty of time to buy a ticket – or so I thought. The first ticket machine was—of course—out of order. I tried the second, selected my destination, and when I tried to pay, nothing happened. I inserted my card multiple times, but the machine stubbornly ignored it. Alright, a third one then. I selected everything again and tried to pay. This one had the decency to at least inform me that my card wasn’t accepted.

What the heck? I’ve never had any problems like this before. Very well, cash then. However, I soon noticed the small banner at the bottom stating “no cash accepted”… *Sigh*. So, I tried the former ticket machine again, which finally accepted my cash and issued a ticket! Then I hurried to my platform. I would have made it, but when I arrived, I found out about a 16-minute delay and a message informing me that several cars would be missing. So, I can offer my usual “thank you, Deutsche Bahn!” early on. It’s now 7:05, and I’ll be waiting for some more minutes.

A couple of minutes before the train arrived, they announced that it would be arriving at a different platform. Well, whatever. It’s 7:15 now, and I’m on the train heading to Frankfurt main station. Let’s see what happens there! By the way, it looks like I’m the only person in this whole car who isn’t either closing his or her eyes for a moment (a few people) or staring at a phone all the time (most people). Nobody is reading a book, looking around, observing the world, or having a conversation. It’s not a generational thing, either – people my age or older aren’t really any different in that regard. Society is largely broken. It’s really no wonder that terrible things are happening right before our eyes—and nobody cares enough to stop it while there’s still time. How did we lose it? And more importantly, how on earth are we supposed to fix it again?

I arrived at the airport at about 7:55. This year, I didn’t have to head to terminal 2, so I got to explore T 1 instead. I couldn’t find my flight number on the display because I was still somewhat early. It’s 8:10 now, and I’m waiting for it to appear, so I have some time to take notes. The S-Bahn station at Frankfurt main station was another noteworthy thing. As I went down the stairs, the woman next to me exclaimed, “Oh, shit!” – and that was rather appropriate. The whole underground station was filled with people waiting. I’ve never seen a crowd of that many people in one place (if you don’t count gigantic open-air concerts like Wacken). The display said something about construction work happening… Seriously? That means it’s a *planned* thing, not some kind of disaster that struck unexpectedly. Which in turn means it simply shouldn’t have such a massive impact. Thank you, modern times, thank you, business administration freaks, thank you, “just-in-time” mindset – and all the other illnesses of our time and age!

It’s 8:40 now, and I’ve checked in one of my bags. The queue wasn’t enormous, but it took roughly 20 minutes until it was my turn. Now I’m going to grab something to eat and then head to the security check.

It’s 9:05 now, and I’ve just passed through security. Everything went smoothly; I didn’t have to take off my shoes or remove my electronic devices. Now I’m already sitting near my gate, and boarding will start in less than 20 minutes. Perfect!

It’s 10:40 now, and we’ve reached our designated altitude. Boarding at the gate began on time and went quickly enough. However, after getting onto the bus, it took quite a while for the driver to arrive, and the bus didn’t leave until two late passengers had boarded. We eventually arrived at the plane and boarded just in time for the scheduled takeoff. Of course, we had to go through the usual safety procedures, so we ended up taking off about half an hour late. Since it’s a direct flight and I don’t have to worry about connecting flights, I don’t mind too much. Since I pick up a few things here and there from my daughter who’s learning Russian, I at least understood the stewardess’ greeting when going on board: “Dobar dan” (good day). Since I decided so late on attending this year’s conference, I unfortunately didn’t have any time to look at the language of the country I’m visiting. We were just asked to fasten our seat-belts again as we’re flying through an area with turbulence, so I’m going to stop writing now and probably take a little nap.

There wasn’t much time for the nap, as shortly after I wrote this, the stewardess came along. We were given some Krekeri (“Crackers with aromatic herbs from the Kvarner region”) and water for free – probably as compensation for the delay. It’s 12:00 now, and I’m waiting at baggage claim to retrieve my checked bag. Once I have it back, I’ll look around to find the airline bus.

It’s 12:20 now, and I’m sitting on the airport bus. Things have gone well so far! But now comes the interesting part; when we arrive at the bus terminal, I’ll have to find the tram and figure out how to buy a ticket. And then… I’ll have to find the rest of the way on foot. It’s raining, but not heavily. We shall see. The music on the bus is Croatian, which makes all the difference. I don’t understand a word, but it sets a nice mood. While I wasn’t sure what to expect—I’m entirely unfamiliar with music from the Balkans—it’s actually quite nice.

It’s 15:30 now, and I’m finally in my room. I figured out how to buy a tram ticket: you simply ask the driver (there are no ticket machines). Unlike in Ireland last year, the tram least display the names of the next couple of stations, so that was easy. I got off at the station I had planned for. Street names are properly indicated (unlike two years ago in Coimbra!), too. So, I relatively quickly found my way according to the route I had planned. I was more than an hour early for check-in, so I did a bit of exploring, found something to eat, and a supermarket, too, to get some bottled water. When I went to check in afterwards, it didn’t immediately work (somehow the advance payment hadn’t gone through). Since I don’t currently own a credit card (I’ll probably give up on that one for next year – I’m getting too old for *Nightmare* difficulty; *Ultra-Violence* ought to do!), I had to sort it out differently. But in the end I got my room after all.

It’s almost 19:00 now. The weather wasn’t nice at all, so I decided against going out again today. Instead, I unpacked my clothes and other luggage and took a shower. Then I got connected to the WiFi and started answering some emails that have been piling up for a while now. Since my hair is almost dry now, I think about reading a little bit and then actually getting some sleep.

Tutorial Day 1

It’s a few minutes to 5:00. I slept pretty well; the mattress’ hardness is about perfect for me. My left shoulder hurts a bit from carrying two heavy bags, but otherwise I’m fine. I thought about getting some more sleep, but since I woke up on my own according to the current rhythm… I decided to rather have a look at getting my second laptop online as well.

Okay, that didn’t work out too well. It’s 7:15 now, and I’m giving up. I can’t even find any Wi-Fi device on my Lenovo at all. I got that refurbished T480 because it’s meant to be relatively painless, but sometimes the Wi-Fi chipsets and whatnot do vary, right? I tried a Linux live system, but it doesn’t detect anything either. Of course I don’t have a screwdriver with me, so I can’t open it up to just have a look. On the plus side, I now know a little more about PCI classes, vendor IDs, and the like. Seems like I’m stuck with my Framework laptop, where the Wi-Fi works. I’d prefer the other one, as this machine is currently running Linux (it has an Intel Ultra CPU, and FreeBSD 14.x only works in text mode). Graphical mode is meant to work with 15.0, though, so I should be able to ditch Linux soon – and I’m definitely looking forward to that.

I, of course, wanted ZFS and ideally a non-sucky means of service management. So I went with Void, and while it’s not half bad for a Linux system, it has a couple of limitations that are rather annoying. Some of the packages I want aren’t available, and the means of virtualization are limited, too. I ended up with Qemu (there’s no VirtualBox on Void). Trying to prepare everything for the first tutorial, I set up a FreeBSD VM and then tried to do the same for OpenBSD—however, it segfaulted during installation. Great! I guess I should just use jails and VMs on my remote server instead of local VMs after all.

It’s 8:10 now, and I’m back from breakfast. They offered a good selection of everything, and after some salad, roasted potatoes, and eggs (fried, scrambled, omelet, boiled), as well as some sweet bread afterward, I feel well-fed for the day. I’ll take one last stab at preparing some VMs for my tutorial, take another look at the map and the route, and then head off to the university.

It’s 18:30 now, and I’m back in my room. In the morning, I left a fair bit later than I had planned, but at least I’d managed to install an OpenBSD and a NetBSD VM on my server and was pretty confident that I’d be able to get a FreeBSD jail up, too, upon arrival. Well, that didn’t quite work out, but let’s start at the beginning. Finding the train station turned out to be really easy. Hotel staff had told me that tram tickets are also available at kiosks, so when I walked by a tisak, I got some tickets there. Tisaks are everywhere, by the way, and I thought that this was the Croatian word for kiosk; but it turns out it’s actually a chain that offers various services beyond what you’d expect from a kiosk, like sending or receiving parcels, cash withdrawal, and paying bills. Interestingly, tickets are cheaper there (€0.53 vs. €0.80). I took the tram and found the right station to get off without any problems. There, I turned in the wrong direction at first but soon figured out that the FER building was across the street.

I collected my badge, got a shirt, and immediately bumped into some familiar faces. Talking to a few people, I ended up almost being a bit late for my tutorial. But the room wasn’t even open yet, so that was actually fine. Of course, that meant I didn’t have a chance to prepare anything ahead of time. More importantly, though, it turned out I couldn’t use any of my remote VMs – non-standard ports for SSH were being blocked on the Wi-Fi (and now guess what my servers use). Well, fortunately, we were given remote VMs that the connection to did work. The Ansible tutorial that I went to was good, and Niels covered quite a bit of ground. He didn’t manage to win me over, but I knew beforehand that I prefer Salt over Ansible. However, I picked up some nice bits of knowledge not directly related to the popular configuration management system along the way. Well, and next time I have to use Ansible (which I anticipate will be before too long), I have a bit of a better idea about how to organize things.

During lunch break I met some more people and had good conversations. After the tutorial finished in the evening, I talked quite a while with Roller – and I really look forward to his tutorial tomorrow. It was almost 17:50 when I left the university building. I found my tram quickly and exiting at the right station proved to be no problem, either. It almost felt like a bit of routine already. On the way home I went to the same small market where I bought water yesterday and got some more bottles. Food had been good – both the warm meal and the cake. It’s 19:30 now and I’m going to do a little bit of work while waiting for my hair to dry. I’ll probably go to bed relatively early again.

Tutorial Day 2

It’s 5:30 now. I woke up around 5 but decided to sleep a little longer. My thoughts had already turned towards the day, however, so I decided to just get up now and do some work. At 8:10 I came back from breakfast. I went half an hour later than yesterday, and that made quite a difference. While it wasn’t exactly hard to find a vacant table, the room was much more busy already. They varied the buffet, and for example, today spinach and arugula were available for the salad (I forgot what they had yesterday). This time I was also smart enough to pick up an apple and a banana for later. Since I already know where everything is, I’ve got some spare time on my hands. I thought about leaving now and taking some photos, but it’s still cloudy, gray, and rainy, so maybe tomorrow?

I’m back at the hotel. It’s 18:00 now. I definitely had a great day, enjoying the tutorials and talking to people. In the morning, I went to the kiosk again to get additional tram tickets. This time, the lady there didn’t speak English, but it was easy to get along since I could show her a used ticket and indicate with my fingers how many I wanted.

I had wondered for years why Croatia’s TLD is hr. I knew that the country is called Hrvatska in Croatian, but I didn’t quite understand why that is. Today, when I paid attention to the tram stations being announced and not only looking at the written form, it clicked. One station along the way is tehnicki muzej (the museum of technology). As in many European languages—and unlike English—it’s pronounced with a “ch” sound that you might know from TeX, where the last letter is meant to be a Greek chi. So the Croatian “h” is not as in “hotel” but as the “ch” in Scottish “loch.” This language has quite a few interesting letters that I was interested in hearing spoken, but the differently pronounced “h” surprised me. But it’s the unexpected details that make traveling so interesting, isn’t it?

The first half-day tutorial I went to was about Terraform, Ansible, and Salt. Roller managed to cover a lot in that short time, and I would assume he could easily have made it a full-day tutorial. He gave a fair share of advice on how to use AWS and showed how to use Terraform to implement the required steps easily. He then used Ansible to turn his laptop into a jailhost and to provision two jails (one with a working Salt master and one with a minion). Since Salt was covered last, that section fell a little short since we were running out of time. That was fine for me, though, since that’s the tool that I’m comfortable using already.

For the second tutorial, I went to Benedict’s on AWK. I’ve always wanted to know a bit more about this versatile tool, but never invested the time into learning it properly. So here was my chance—and I don’t regret going there at all. He had slides and explained one topic and then always had some examples and challenges for the participants to solve with AWK. This was both fun and educational (and that’s the way you should do things, right?). He finished a little early, and I thought about staying and talking or going back to the hotel. In the end, I decided to leave as I had noticed an organic market along the way and wanted to get some sweets for my wife. When I actually got there, I found out that it’s open until 21:00, so there hadn’t been any real reason to rush, but I hadn’t known beforehand.

I expected to get a lot to pick from as the shop was not that small, actually. Funny enough, the first thing I saw was “Söbbeke Reibekäse” (grated cheese by a German dairy) and a lot of other brands that are common in German organic markets as well. Same thing for the chocolate—but eventually, I found something that we don’t seem to have. (I think it didn’t taste as good as I had hoped, but it’s the gesture that counts, right?) I stocked up with some more water once again so I’d have enough for the weekend, and this time, there was someone there who actually spoke English.

Now that I’m done writing things down for my travel diary, I’m going to have a shower and then do some ports work. I’ve neglected this for a bit too long to not feel a little guilty actually.

Conclusion on the first half

Choosing the right tutorials is always a bit of a gamble, but after three years of taking some, I have yet to pick one that I regret. Last year I’ve already been thinking about taking Kirk’s introduction tutorials about how FreeBSD works under the hood. Not knowing for how long he’ll continue to give them, I definitely want to take those at some point. However both in Ireland and in Croatia there were other tutorials that better fit topics that are directly relevant to my work. Well, and I really need to sit down and learn a bit of C in advance, since ironically that’s one of the programming languages that I’m not very familiar with. Maybe next year?

As I’m writing this, over two weeks have passed and I have yet to review my notes on the tutorial as well as the material we were given. But things are pretty hectic and it’s hard to find time for something that doesn’t absolutely have to be done (like finally writing this post!). I haven’t used Ansible after the tutorial, but of course I have used AWK (even if only for something boring and trivial). I remember that after the two days I’ve very much been looking forward to the talks of the next two days – and especially for more of the hallway track (i.e. just talking to people).

What’s next?

The next post will be about the main conference days and my trip home.

kraileth
http://eerielinux.wordpress.com/?p=5424
Extensions
A gentle introduction to CP/M
historycomputercp/mlegacyoperating systempackage managementravenportssoftwarevirtualization
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/gentle_introduction_cpm.gmi This article is just what the headline promises: an introduction to the CP/M operating system. No previous knowledge of 1970s and early ’80s operating systems is required. However, some familiarity with … Continue reading A gentle introduction to CP/M
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/gentle_introduction_cpm.gmi

This article is just what the headline promises: an introduction to the CP/M operating system. No previous knowledge of 1970s and early ’80s operating systems is required. However, some familiarity with Linux or a BSD-style operating system is assumed, as the setup process suggested here involves using a package manager and command-line tools. But why explore CP/M in the 2020s? There are (at least) two good reasons: 1) historical education 2) gaining a better understanding of how computers actually work.

Last year I wrote two articles about CP/M after having taken a first look at it:

A journey into the 8-Bit microcomputing past: Exploring the CP/M operating system – part 1
A journey into the 8-Bit microcomputing past: Exploring the CP/M operating system – part 2

These were written with a focus on the first reason; I had (partially) read the manuals and tried out a few commands in an emulator (as well as done a little bit of research). I wrote an outsider’s look at CP/M and covered the various versions that were released and some of their notable features.

This article is different. It’s for readers who want to get started with CP/M themselves. Expect a practical introduction to get familiar enough with the platform to be able to explore a wealth of historic software, often enough ground-breaking and influential.

Getting Ready (Installing an Emulator)

Last time I had tried out a couple of Z80 emulators and found Udo Munk’s z80pack to be the one I liked best. It’s not widely packaged; only FreeBSD includes it, but using the package requires some setup. Other options like YAZE exist, but it’s more work to get the original CP/M working on them whereas z80pack comes with disk images of various CP/M versions.

Of course you can compile the emulator and tools yourself. But to simplify the setup process, I’ve created a port for Ravenports, a universal package system for POSIX operating systems. Via Ravenports, the emulator and tools I use here will soon be available as binary packages for the following operating systems (in the future additional platforms might get added):

  • DragonFly BSD
  • FreeBSD
  • Linux (glibc-based distributions)
  • MidnightBSD
  • NetBSD

If you’re on one of those systems, you can download, inspect and run this script if you want to go that route. It will bootstrap a secondary package manager on your system, which you can use to install additional software on your machine. Those programs live in a separate portion of the filesystem (i. e. below /raven), which means that they won’t interfere with the native package manager of your platform.

The package manager is called ‘rvn’. It supports subpackages and so-called variants which is why the package names look a little complicated at first glance. The z80pack port has no variants, hence only the standard (“std”) is available, but the port is split into three subpackages: “docs”, “images” and “primary”. The first contains documentation, the second one provides the CP/M disk images and the last one is the actual emulator. A special subpackage called “set” can always be used to install all available subpackages of a project.

Tilde characters separate the fields of the package name. At the time of this writing, the complete package is ‘z80pack~set~std~1.38’ (base name, subpackage, variant, version). Package names can be shortened as long as they are unambiguous. So to install the complete package, you can run this:

# /raven/sbin/rvn install z80pack~s

This will pull in ‘z80pack~docs~std~1.38’, ‘z80pack~images~std~1.38’ and ‘z80pack~primary~std~1.38’ as well as the required dependencies.

You will have to add /raven/bin to your PATH environment variable to be able to use it. Depending on your shell of choice use setenv or export. Most people will want to do this:

% export PATH=/raven/bin:$PATH

When you installed the package, the installation message hints at a utility script that I wrote for the port. Just execute ‘runcpm’ and it will display a little help text to let you know what it does and what other command names it’s available under.

The help message from the utility script

Running any of these requires the /raven/bin to be in the PATH variable, otherwise they won’t find the actual emulator binary. Of course you can also modify /raven/bin/runcpm accordingly if you prefer that.

Running CP/M

If you’ve installed the emulator and have your PATH configured, you’re ready to go. You just pick a version from the list that ‘runcpm’ told you about and start the emulator. But which one to try? You can of course try out any of them, but I highly recommend to start with version 2.2 for a couple of reasons. Versions 1.x work but are pretty limited in terms of command-line editing and things like that. They are fascinating relics from an age before monitors were common and when output was usually printed on paper. You can explore them later. Version 3 is more complex (by CP/M standards) and might confuse you. CP/M 2.x is basically “classic” CP/M, a solid but simplistic OS that’s straight-forward to get into. That’s also the version used in this article, so if you want to follow along, just go with 2.2 for now.

Now that we’ve chosen a version, let’s start the emulator. So, as your user just issue

% cpm22

and that will turn your terminal into an emulated Z80 system with CP/M 2.2!

Emulated CP/M 2.2 booted up and ready

On modern systems, the boot process is too short to notice and the system is up instantly. CP/M displays ‘A>’ to let you know that it’s ready to take commands from you. The CCP (Console Command Processor) is the core component of CP/M that handles user interaction like prompting you and executing commands. Think of it as your shell.

In their simplest form, commands are just simple words or abbreviations which you type after the prompt symbol and then hit ENTER to execute them. Let’s issue our first command. Try this:

A>cls

What did it do? Right, all the previous messages are gone. And that’s no wonder: CLS is short for “CLear Screen”. The CCP is case insensitive; it doesn’t care if you input “cls”, “CLS” or “cLs” – that’s all the same thing.

You can always give empty command lines, if you want a bit of screen space between some output and the next. So pressing ENTER without first typing a command is perfectly acceptable. But let’s try a different command:

A>bye

Quitting the emulator

As you might have guessed from the name, this command is used to quit the emulator and returns you to your standard *nix terminal. It’s not the most interesting command but definitely one you will want to know about. It was added to stop z80-sim and is not part of the original CP/M.

Filename Basics

With these basics done, we can finally take a look at something more useful. Try this command:

A>dir

Output of the DIR command

DIR is short for “DIRectory” and it lists all the files recorded in the – you guessed it – directory (i. e. all the files present on the drive). CP/M’s filesystem is flat, which means that there’s no folders or subdirectories. All the files on one drive are together in one place. Files are referenced by what CP/M calls a file specification. These consist of up to four pieces of information (on 2.x).

Okay, let’s take a look at the output. We’ll ignore the “A:” for the moment. File naming follows a schema known as 8.3. This means that a filename can be 8 characters long, then a dot follows and after that it can have a type of up to three characters. Note: Terminology evolved over time. In older CP/M versions, these were known as the primary and secondary names. Later, during DOS times, they were referred to as the filename and the extension.

It’s best to think of the whole thing as the actual name of the file, i. e. the up to 8 characters, the dot, and the type. Only the first character is strictly required, though, so “A” is in fact a perfectly valid filename. Internally, CP/M will fill up the remaining characters with blanks, so this file is represented as an A, 7 spaces, a dot and another 3 spaces. Filenames, just like CCP input, are case-insensitive, too.

Other than being mindful of the maximum length, try to stick to letters and numbers for names. Many special characters are allowed, but some are reserved and must not be used. But you cannot just memorize these once: different versions of CP/M reserved a different set of special characters! The full list for CP/M 3 is this: . , ; : = ? * [ ] | ( ) / \ ! & $ + –

Some of these are not reserved in earlier versions, but again, don’t get fancy and you’ll stay out of trouble. Other than that, you need to be aware that the part before the dot is up to you entirely whereas the type is meant to hint at what kind of file this is.

Now that we understand the filename schema, let’s look at the types of files as the list provided by DIR has them. For example there’s “DUMP.COM” (DIR doesn’t display the dot for some reason), “STAT.COM”, and so on. These are both COM files, which is short for “command” files – and it means that these are executable commands (programs).

The other types that you can see here are UTL and HLP. The former are two “util” files; these are special programs that cannot run on their own but can be loaded by CP/M’s debugger program. The other is short for “help” and was chosen because this file contains the help text for the WM program. DIR uses colons to delimit one column of files from the others.

Now that you know that the COM files are executable commands, DIR basically gave you a list of what programs are available for you to run. But wait a moment! There’s CLS.COM and BYE.COM – but where’s DIR.COM? Good catch. There’s actually two kinds of commands: those like CLS, which exists as COM file on a drive, and the others like DIR. The first kind are called transient commands, the others are built-ins like your Unix shell’s ‘echo’ command. DIR and a few others are part of the CCP and do not exist as separate programs. (Well, in CP/M 3 DIR.COM does exist, even though the command is a built-in, too! That’s because the transient offers additional functionality over the standard command. But like I said before, CP/M 3 is a little different.)

File Specification Basics

So far we have only executed programs which serve a pretty simple purpose and can thus work on their own. Time to take the next step. Let’s execute another program:

A>dump

The result is this error message:

NO INPUT FILE PRESENT ON DISK

DUMP is a tool to get a hex dump of a binary file and with the error message it is telling us that it needs an input file but couldn’t find it (in this case because we didn’t specify one!). So we need to give this program a file to operate on. Let’s have the program display a hex representation of itself. We can do that like this:

A> dump dump.com

This time the result looks much more interesting (see screenshot).

Output of the DUMP command on itself

While admittedly the output is not terribly useful for a user without a programming background, this is still an important achievement. We’ve not just executed another program, we’ve executed it on a specific file. In our little command line, DUMP is the program name like always. However after that (delimited by a space character), we’ve given it the so-called file specification (or filespec for short) to let the program know which file we want a hexadecimal representation of.

Now we will take a look at another command, TYPE. Don’t look for TYPE.COM, it’s another built-in. This is a simple command for displaying the contents of files (i. e. “typing it out” to the console). If we run it without a filespec, this happens:

A>type
?

Unlike the more verbose DUMP, this program is fairly minimal in letting you know that you screwed up. The question mark tells you “nope, doesn’t work that way!” and it’s on you to figure out what the problem is. That is, you have to know that TYPE requires a filespec to be able to type out the file’s contents, of course.

But why is it so minimal? Well, text strings are wasteful. The long error message that DUMP provides could have been used for several program instructions. And remember, that we are in an emulated environment where the machine has 64 kilobytes (!!) of memory, which is not a lot. To make matters worse, CP/M could run on machines with as little as 16k of RAM (versions 1.x at least). Since TYPE is a built-in and the whole CCP has to stay in memory all the time, putting anything in there that’s not strictly required, means stealing from the precious memory which would then no longer be available for other programs. Always keep in mind the extremely constrained environment that people had to make do with back in the day, and you’ll understand most of the design decisions that seem rather weird from today’s perspective.

But since we figured out what we did wrong, let’s try again:

A>type dump.com

This results in the following output:

!9"1W>2!QG}DrYQ|͏}͏#> ex͏#r*
e>	_>
e
 ҉0Ë7e}} :³ʳ7_<2!~ɯ2|\\FILE DUMP VERSION 1.4$
NO INPUT FILE PRESENT ON DISK$

Most of the file is unreadable garbage and some of it even consists of unprintable characters. This is why you normally use TYPE only for plain-text files and view binary files with DUMP. We can see two text strings here, though, one of which is the error message that we’ve already encountered. Given how short the program is, you can see pretty well how wasteful those text strings are!

Some commands take more than one filespec. For example REN (“REName”), another built-in. It allows you to change the name of an existing file to another. One CP/M quirk that you have to be aware of, is that it borrowed the notation from a line of DEC operating systems. It doesn’t copy / rename file 1 TO file 2 as you’re probably used to. Source and destination are inverted, so you copy / rename file 1 FROM file 2.

Let’s see what REN does when you give it only one filespec:

A>ren wm.hlp
FILE EXISTS

The command took the information that it had, tried to rename the file to itself – and couldn’t do that because, of course, that file’s name is already taken. Here’s how to rename the file to RENAME.TST (new name) from the file WM.HLP (old name):

A>ren rename.tst=wm.hlp

The equals character is required as the separator of the two filespecs. This command line doesn’t output any error, which in this case means that it succeeded. Feel free to check it with DIR, before we revert what we just did:

A>ren wm.hlp=rename.tst
More on Filespecs

Some commands like DIR can work both with and without a filespec. We’ve only done the latter so far, so it’s time to give the other option a try:

A>dir dump.com
A: DUMP COM

This will make DIR only display the file that we asked for instead of the whole list. What is this form of DIR good for? Just to check whether a specific file exists? No, there’s a much better use for it. But to understand that, we need to know a bit more about file specifications.

So far we have only used what CP/M calls unambiguous filespecs aka. unambiguous file references aka. unambiguous filenames (ufn), which refer to one particular file only. That means we’ve always used exact names with our commands so far. CP/M supports two kinds of wildcards, though, the question mark and the asterisk. You can use these to construct ambiguous filespecs aka. ambiguous file references aka. ambiguous filenames (afn) which can potentially match several files.

A question mark means any character. For example we could modify the previous command line slightly like this:

A>dir dump.?om
A: DUMP COM

The output is the same, because DUMP.COM is the only file in our directory that matched the afs. But let’s assume there were also files such as DUMP.BOM, DUMP.LOM and so on – in that case the afs would match them, too, and DIR would display all of them. You can use multiple wildcards in a filespec, so for example DUM?.C?M would still match our DUMP.COM file but also other possible files like DUMB.CIM and so on.

The asterisk is even more powerful; it doesn’t match a single character at that position, but translates to anything. For example *.COM means “any filename as long as the file has a type of COM”. You can use this to have DIR list all the available commands only and filter out any other files:

A>dir *.com

This will produce a list where our two UTL files and the HLP file are missing. You can also use something like A*.* to list all the files that begin with the letter A.

Combining these wildcards, you can do some pretty advanced but useful name matching. Think for a moment about what this example matches: ??G*.C* – it matches all files which have a filename of three or more characters where the third one is a G and which has a filetype that starts with C.

By the way, when you run DIR without any filespec, that’s the same as if you run DIR *.* – for the DIR command the universal filespec is the default.

Alright! Now for the last thing that you need to know about filespecs: they can consist of a third component in addition to the filename and type. Run these two commands and compare the output:

A>dir
A>dir a:

Hey, there’s the a: finally. And yes, the output is identical. Try another one, before we talk about what this does:

A>dir a:*.*

It’s exactly the same again! Okay, let’s take one step back and take a look at the prompt that we see all the time: A>. With the greater than character, the CCP tells you that it’s ready to let you input a command. But what’s the A all about? It refers to what CP/M calls the logged-on disk. It let’s you know that disk drive A is the one it will assume commands refer to unless told otherwise.

And that’s what we did with the A: – we requested DIR to list the files on drive A. Since that’s implicitly assumed when we don’t state it, it didn’t make any difference. And the universal filespec (*.*) is the implicit default for DIR, so in our case all of these were identical.

So let’s try out accessing a different disk for the first time, shall we? CP/M 2.2 as it is provided by z80pack consists of two disks, so we have a drive B, too. How about taking a look at which additional programs are on there? We can do that like this:

A>dir b:*.com

Here’s the output:

B: CLS COM : BYE COM : SPEED COM : SURVEY COM
B: R COM : RESET COM : W COM

As you can see, for convenience, there’s CLS.COM and BYE.COM on there, too, but also some additional programs that we haven’t seen, yet.

Drives

Since we’re on the matter, anyways, let’s talk about drives next. A useful command that we haven’t used, yet, is STAT (from STATus). You can use it to find out how much space remains on a certain disk. Let’s check that for both drives:

A>stat a:
Bytes Remaining On A: 11k
A>stat b:
Bytes Remaining On B: 168k

Seems like drive A is somewhat short on space while on B there’s still a lot of room for additional files. If we want to examine the programs on drive B, for example R.COM, we can do this:

A>dump b:r.com

However it’s a bit annoying to always have to use the full filespec including the drive, right? And that’s why the logged-on drive can be changed. We want to do some work mostly on drive B next, so let’s do that. It’s as easy as this:

A>B:

This will change the prompt to B> to let you know that now drive B is the default disk. If you for example run DIR without a filespec now, you’ll get a list of files on that drive until you change back. Let’s try to get a hex dump of one of the other programs on this drive:

B>dump w.com
DUMP?

Huh? What’s this? Well, the CCP let’s you know that it has no idea what you’re talking about. Remember that unlike DIR the DUMP command is a transient. It’s on drive A and it was readily available so far because that drive was the logged-on default. Now we’re on drive B and there is no DUMP.COM there! So to get the hex dump that we were looking for, we can do this:

B>a:dump w.com

That works! But while we don’t have to include B: for the filespec anymore, now we have to include A: to run the command… So we have merely traded one little headache for another. But there’s a solution to this, of course! Let’s take a look at STAT again. It is not only able to tell you about the remaining space on a disk, it can also give you information about a file. Let’s use it to take a look at DUMP.COM on drive A:

B>a:stat a:dump.com
Recs Bytes Ext Acc
3 1k 1 R/W A:DUMP.COM
Bytes Remaining On A: 11k

Okay, looks like the file takes up 3 records in the filesystem which is equivalent to a size of 1k. That’s a fairly small program and we have more than enough space to simply copy it over to drive B. That’s what we will use PIP (from “Peripheral Interchange Program”) for. Remember the syntax of REN? For PIP it’s similar and unlike REN it can actually copy files rather than renaming them and supports doing so across different devices as well. Here’s how we copy over DUMP.COM from drive A:

B>a:pip b:dump.com=a:dump.com

Think about this command line for a second. Do you see which part of a filespec is unnecessary? Exactly, since we have drive B logged-on, we could also have used A:PIP DUMP.COM=A:DUMP.COM instead for the same result. Check with DIR whether the file was copied over if you wish. Now we can simply run the program from the current disk which is much more convenient:

B>dump w.com

Great! Now let’s assume we’re done with exploring programs with DUMP and are eventually running out of space. We need to clean up now and then. Removing files is what the ERA (from “ERAse”) command is good at. To get rid of our additional DUMP.COM on the current drive, we can issue the following commands:

B>dir dump.com
B: DUMP COM
B>era dump.com
B>dir dump.com
NO FILE

That’s 1k of space reclaimed. It may not sound like much, but as we all know, even small files do add up. Oh, and you cannot only run out of space on a drive. You can also run out directory entries! CP/M 2.2 supports up to 64 files on any drive, which is a lot of files, but at the same time not an exceptionally high limit, either.

Control Characters

Let’s change the logged-on drive back to A now:

B>a:

Next we’re going to use STAT again but on its own rather than on a drive or a file:

A>stat
A: R/W, Space: 11k
B: R/W, Space: 168k

This is pretty useful for getting a quick overview. Keep in mind, though, that it will only display information about drives that you have accessed in your current session! If you use STAT the next time after you just started the emulator, it won’t know about drive B, yet. Now let’s do something stupid and try to list files on a non-existing drive:

A>dir c:
Bdos Err On C: Bad Sector

BDOS (or Basic Disk Operating System) is the OS component responsible for disks and filesystems. And it rightfully complains that there’s an error on drive C. You cannot simply acknowledge the error or something; if you press ENTER, the error is simply repeated. The system is in a state from which it cannot recover.

What you have to do in this case is sending the ^C control character (press CTRL-C to produce it). This will make CP/M perform a warm start and you get the CCP prompt back. Never try to change the logged-on drive to a none-existing one, though! In that case a warm start is not enough and you will have to kill the emulator from your host system. Historically warm starts were also required if you physically changed the diskette in a drive.

There’s a couple of other control sequences that are useful to know about. For example if you typed a longer command line and change your mind (or mistyped something right at the beginning), it is useful to press CTRL-U which invalidates the current command line. You can simply press ENTER afterwards and the CCP will ignore what you typed. CP/M 2.x supports a more useful control character, though, CTRL-X, which will simply erase the current command line, allowing you to try again right away.

If you are for example using TYPE to display a longer text file, the contents will rush by on the screen. In case you’re interested not in the end of the file but in some section in the middle, you’re supposed to press CTRL-S to suspend further printing until another key is pressed. This may have worked back in the day (and you can probably still use it if you configure the emulator to run at a slower speed), but it’s not a particularly great mechanic for today.

CTRL-Z means end-of-input. It’s not used on the command line but some programs like the editor ED make use of it.

There’s a few more, but the last one that I want to cover is CTRL-E. Sending this control character causes a carriage return without executing the command line. This is useful if you have to enter a very long command line which won’t fit on a single line. Now this might surprise you since so far all of our command lines have been rather short. But they don’t necessarily have to be! For example, PIP can be used to concatenate multiple files into one. If you’ve got a lot of long filenames, the resulting command line might run over the terminal width.

Other Things to be Aware of

We’ve already covered a bit of ground here and you should have a good idea of basic CP/M usage that you can build upon. But while the known unknowns can be annoying, it’s usually the unknown unknowns that actually bite you. So let’s at least convert some of the latter to the former, shall we?

CP/M 2.x supports 16 so-called user areas, which can be used to organize files, so in a way the previously made statement about the filesystem being flat with all files in one location is not entirely correct. It’s good to know that they exist, but by default only user area 0 is being used and that’s what you may want to stick with.

What is typed after a command name is called a command trail in CP/M lingo. We’ve only used filespecs here, but there’s another thing: parameters. These don’t refer to files but modify the behavior of the command. Unfortunately, they are not standardized! For example, STAT uses dollar notation and PIP expects parameters in square brackets. Here’s a few examples:

A>stat b:speed.c $R/O

This instructs STAT to set the read-only flag for the file instead of displaying file information. STAT also accepts a few special keywords, too, like DSK: which will make it display detailed disk information (see screenshot).

Output of the STAT command displaying disk information

The trouble with PIP is that it can only copy things FROM a different user area and not TO one. This means that when you switch the user area, you need to have PIP available there to copy something else over. But how do you do that without PIP? Well, first you need to load the program into memory. The debugger DDT can do that for us, but then instead of actually debugging it, we’re leaving the application by issuing “G0” at its dash prompt.

A>ddt pip.com
DDT VERS 2.2
NEXT PC
1E00 0100
-g0

PIP is now loaded into RAM, and DDT was nice enough to tell us that the next free memory address is 1E00, which in turn means that PIP occupies 1C memory pages. Converted to decimal, that’s 29 pages. Knowing that, we can change to another user area, e. g. number 8 using the USER build-in:

A>user 8
A>dir
NO FILE

As you can see, it’s empty. Now we can use the build-in command SAVE to write the contents of the 29 memory pages into a file:

A>save 29 pip.com
A>dir
A: PIP COM

Here’s the result: we have PIP! Which means we can use it to copy over another file to this user area, using the G parameter for PIP with user area number 0 from where we want to copy it:

A>pip stat.com=stat.com[g0]

DISK WRITE ERROR: =STAT.COM[G0]

Oops. Or rather, we can’t. Got any guesses why that is?

A>user 0
A>stat stat.com

Recs Bytes Ext Acc
40 5k 1 R/W A:STAT.COM
Bytes Remaining On A: 3k

Of course! The STAT program we wanted to copy over is 5k in size, but the drive has only 3k left…

Having seen these limitations, you probably understand why I suggest not bothering with user areas as you’re getting started with CP/M. I wanted to at least touch on them, though, so you don’t get the feeling that you’re missing out!

Another thing that you should know exists are devices. CP/M reserves some three-letter abbreviations for device names. If you ever wondered, why to this day you cannot create a file called CON in Windows, that’s because it’s CP/M’s reserved device name for the console. PUN is for a paper punch, RDR is a paper tape reader, LST is for a printer and so on. You could use STAT to switch input or output to different devices and PIP supports them, too. This allowed you to read files from the RDR or print a file by copying it to LST.

With this information you should be good to generally find your way around in CP/M. You cannot really do much with it, yet, but we’ll take care of that another time. Tune in again if you like.

What’s next?

I haven’t decided whether I’ll write another CP/M article next (it would make sense, though) or if it will be something else. In autumn, I definitely want to get back to my CBSD series, though!

kraileth
http://eerielinux.wordpress.com/?p=5401
Extensions
Installing *BSD in 2025 part 5 – Bonus: A look beyond our teacup
linuxcomputerIllumosinstalleroperating systemsoftware
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt5.gmi Installers play a huge role in forming the first impression of newcomers: They are the first experience any operating system provides to people who want to get started – or the … Continue reading Installing *BSD in 2025 part 5 – Bonus: A look beyond our teacup
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt5.gmi

Installers play a huge role in forming the first impression of newcomers: They are the first experience any operating system provides to people who want to get started – or the first obstacle.

This article will be the last of a series that went beyond my expectations in about every regard. The original intent was to simply review NetBSD’s installer (I even found a raw first draft for an article dating back to December 2023), but I thought that I could extend that to all four major BSDs. Slightly annoyed by how some gullible people take the answers given by AI chat bots as plain truth, I decided to investigate what various open-source models claim about the BSDs. Then I did the actual installer reviews and was surprised that (mostly for NetBSD but also for OpenBSD) this sparked quite a bit of interest.

Part zero A covered AI answers on DragonFly BSD and FreeBSD and part zero B did the same for NetBSD and OpenBSD.
The actual first part of this series was about FreeBSD’s installer, the second part covered OpenBSD’s installation program and part three discussed NetBSD’s. Part four detailed DragonFly BSD’s installer.

Writing those articles proved to be much more work than anticipated, but I’m happy that they helped spark a bit of discussion. There have been a couple of misunderstandings – for example, someone on HN misinterpreted my comments and thought I was arguing that adding a new keymap to FreeBSD was difficult (which I absolutely wasn’t!). But writing the series has been a lot of fun, too.

So this little “bonus episode” will conclude it. And what better way to wrap things up than to take a (much less in-depth) look at some other installers for non-BSD systems? I think showcasing a few positive examples, and highlighting a top 5 of the worst installer blunders I’ve encountered would make for a nice final part. Warning: There may be a somewhat unhealthy dose of sarcasm or cynicism especially in the second half. 😉

An illumos installer: OmniOSce’s Kayak

One installer that I’ve always liked is the newer one (there’s also a text-only installer still available) that comes with OmniOSce: Kayak. Why? Because of its minimalistic menu-driven style, I’d say. It does use dialog windows but doesn’t rely on them exclusively. I also think that it has a pretty nice color scheme that’s very readable and easy on the eyes. Not everybody might agree, of course, but that’s what I think.

Well, and it’s a remarkably lean installer that allows you to install the OS in just a few steps. So let’s take a quick look.

Kayak: Keyboard layout selection

After starting up, it immediately presents the user with a list of keyboard layouts to choose from. It pre-selects the US keyboard as the default, so a lot of people can just hit ENTER right away.

Kayak: Main menu

Having selected the keymap, the user is presented with the main menu, which is about as simple as it gets: five options and a single ‘OK’ button. Yet it has all the options that you need: Disk selection / root pool creation / installation (which most people probably use), installation to a preconfigured pool, shelling out (to manually create a pool), rebooting, halting the machine. This is perfect!

Kayak: Disk selection

Choosing the first option brings up the disk selection window. It lists all the disks available for potentially installation and lets the user select one or more using a common checkbox mechanism.

Kayak: ZFS VDEV type selection

If multiple disks are selected, the next window allows you to choose the RAID level to use. I’ve selected two disks, so I get the choice to build the pool from two striped VDEVs or two mirror VDEVs. If the system had more disks, additional options would have become available. If only one disk is selected, the only option is stripe, and in that case this window is simply skipped, which makes a lot of sense.

Kayak: ZFS pool configuration

Next is zpool configuration. This is where I think the options Kayak presents are a little too minimalistic. It offers only a few options: the pool name, the partitioning scheme, compression, and the option to force 4k sector size. Especially for compression, it doesn’t even allow the user to select which compression algorithm to use, only to enable or disable it. But that’s why the installer gives the user the option to escape to a shell, run ‘zpool create -O $whateveryouwant’, and then use the manually created pool, right?

Kayak: Hostname selection

Then the hostname needs to be decided. This window is fairly standard, but Kayak does one thing right here: it proposes a default. While you probably don’t want to use that, it makes it clear that the system expects the hostname in its short form and not as an FQDN!

Kayak: Time zone configuration

For timezone selection, the installer again uses a full-screen list instead of a window. There are no bars trying to give you an idea of where in the list you are; instead, a percentage does that. Just like with the keymap selection, I think this works really well.

Kayak: Time zone confirmation

Since using the correct time is extremely important, a window with timezone information is displayed, asking the user to confirm the choice.

Kayak: Installation progress

And that’s really all you have to do! After these few decisions the actual installation process starts, and data is written to the pool.

Kayak: Installation complete!

OmniOSce is a small operating system (the ISO image is not even 300 MB in size for version r151054!), so the installation finishes pretty quickly. An “installation complete” window displays some information about the boot environment that was created, as well as how to proceed from here.

Kayak: Main menu again

Acknowledging the previous window takes the user back to the main menu. The two options to install the system (guided or using a preconfigured pool) are gone, but a new one to configure the system has appeared. I think the “Welcome to the OmniOS installer” line doesn’t make sense when you return to the main menu and should also be replaced by something like “OmniOS has been successfully installed”. But that’s a cosmetic issue.

Kayak: System configuration menu

The system configuration menu is great! Its ability to configure networking, add users, and enable SSH was incredibly helpful when I first explored the OS years ago. Solaris presents unique challenges, especially for newcomers unfamiliar with its networking, user management, and SMF (Solaris’ service manager). This menu acts as a valuable safety net, making it significantly easier to get started.

The menu also allows you to set the root password, enable virtual terminals or the serial console as well as the extra package repository. And in newer versions of the OS, it even allows you to use cloud-init to further provision the system! It doesn’t try to do everything, but what is available makes perfect sense.

Kayak: Network configuration

The network configuration menu provides all the expected standard options. What I find interesting is that OmniOS defaults to static addressing. Of course, it can be switched to DHCP for people who want to use that.

Kayak: User creation

User creation is done in a very nice dialog window. Combining it and the next two windows into a single screen would consolidate user information and improve the workflow. But that might also mean putting too much into one window. It’s hard to say without trying it out.

Kayak: Shell selection

The second user creation window is for selecting the shell to use. Solaris (and thus OmniOS) offers three: ksh (a solid standard), bash, and csh.

Kayak: User privilege selection

The last window is about giving the user privileges. The ‘Primary Administrator’ role allows the user to utilize Solaris’ native ‘pfexec’ for operations requiring root privileges. The option to also offer sudo is nice as people with a Linux or BSD background are more familiar with it.

Kayak: User created

Finally, a confirmation window indicates successful user creation. And that’s really it. I’m not going to discuss the remaining options here.

In my opinion, Kayak is remarkably effective at what it does. It mostly found a great balance between sane defaults, enough flexibility for common different needs, and leaving advanced options for people to do by hand. I really like how it utilizes menus and windows instead of putting everything in a window. Excellent work, Kayak team! You’ve created one of my favorite installers for open-source operating systems.

Some good bits from the Linux world

With a quintillion (or more?) of Linux distributions out there, there’s also a huge number of installers used by such systems. Some distros, like CRUX or Gentoo, never had an installer and are always installed by hand. Others, like Arch, once had an installer (the “Arch Installation Framework”, which however was discontinued ages ago). Most do have some kind of installer, though. In this section, we’ll take a look at what some of them do well in my opinion.

Alpine Linux

Alpine comes with an installation script called ‘setup-alpine’, which allows for an OpenBSD-style installation. It differs in being more verbose and dividing the process into sections, but otherwise it’s the same “just answer questions” way of installing.

Alpine: keymap and network settings

First, the installer asks for the keyboard layout to use and allows you to configure the network.

Alpine: root pw, time and mirror settings

In the next section, the root password, time setting and the package mirror to use are to be decided.

Alpine: User creation, login settings and installation type

Lastly, the installer allows you to create a user, configure the system for remote access, and to actually install the system.

I think the installer wastes quite some space by always printing out the full set of choices for keymap or timezone. It’s useful the first time you do an installation, but then you know, right? I prefer OpenBSD’s less verbose approach, where a list is only printed if the user requests that. But Alpine’s install script has a few things going for it, too. For example, I’ve always appreciated its flexibility in terms of the daemons it supports. As you can see in the third screenshot, it’s possible to use OpenSSH or dropbear for SSH (or no SSH daemon at all). The same is true for NTP servers (busybox, openNTPd, chrony, none), even if that’s not shown in the screenshots.

However, setup-alpine offers another interesting feature: while it doesn’t handle partitioning at all (take what you get or do it by hand!), it offers different types of installation. I chose ‘sys’, which means the selected drive would be used for a typical OS installation that can be booted from. If the user selects ‘data’ instead, the drive will be used for storing persistent data only. This is meant for when you run the actual OS purely in RAM. In this scenario, you typically boot from a USB key or something, and during boot, the system would always install the required packages from the repository. I always found this mode of operation quite interesting.

Debian

Since Debian is popular both on servers and as a desktop distro, it comes with two installers. While a lot of technically versed people prefer text installers for their desktop systems, too, graphical installers can admittedly be more welcoming to newcomers. This is why Debian does the only sane thing: it provides both.

Debian: boot loader menu

The boot menu allows the user to choose between the graphical and text installers. This is a great solution if you don’t want to have different installation images for desktop and server.

Debian graphical installer: language selection

Language selection in the graphical installer provides a list to choose from.

Debian graphical installer: loading components

A progress bar displays the status of the current operation.

Debian text installer: language selection

The text installer is functionally equivalent in providing a list to select a language from. It’s just simpler and you don’t need a mouse.

Debian text installer: loading components

This applies to other aspects of the installer as well. A progress bar is a progress bar and the text version just looks a little nicer (i. e. no useless “polish”).

Debian’s (text) installer is nothing special – but it doesn’t have to be. It simply does what it’s meant to do, and I always liked it for just that.

openSUSE

YaST (Yet Another Setup Tool), openSUSE’s… well, setup tool and I go back quite a while. Back in the mid-1990s, it helped me get any work done at all when I was completely new to Linux. Once I became more comfortable with the shell and understood the underlying principles, I preferred alternative configuration methods. And then I didn’t touch anything SuSE for… about two decades? When I eventually did take a look again, I found that it had evolved – but not as much as I had expected. YaST can be a little weird, and openSUSE’s persistent greeting after logging in – ‘Have a lot of fun!’ – reflects the sometimes quirky experience of getting things done. But in terms of OS installation, I highly respect YaST.

As a distribution that’s used on both servers and desktops, it makes sense that YaST has two faces: a graphical front-end and a text one. Unlike Debian, openSUSE simply defaults to the graphical installer, requiring users to know how to launch the text version. In that regard, they could do better. But let’s take a look at the actual installer. Because while Debian’s graphical one is rather pointless, openSUSE’s actually isn’t.

openSUSE graphical installer: Progress bar

SUSE makes good use of the additional space that graphics mode offers. While I cannot help but think that the left bar was maybe inspired by Windows 98’s installer, that’s not necessarily a bad thing. You get a great overview of where you are within the installation process, which is nice. There’s even the option to change the theme / style (for example for high contrast, which I’m pretty sure the visually impaired will appreciate!).

openSUSE graphical installer: Language, keyboard, license

The welcome screen exemplifies good design, combining language selection and keyboard layout in a logical and efficient manner. And using the remaining space for the license agreement is a good idea as well.

openSUSE graphical installer: Time settings

Now, the time settings screen shows that they decided to go all-in with what graphical mode allows for. The map is definitely fancy, but since the rest of the screen is plain and simple as well as laid out nicely, it actually works. I don’t particularly like fancy, but being limited to one core element while not breaking the design language of the overall installer, I have to admit that it isn’t half bad. Would I have done it like that? Probably not. But in my opinion, it’s one of those rare cases where a bit of polish is not annoying, even though it doesn’t hold much value of its own.

openSUSE graphical installer: Installation options summary

The installation overview is a screen that I’m a big fan of. After making his or her choices, the user can review them all (and actually make changes – the turquoise text lines are links). Not only can you make changes if you changed your mind, but you can also further customize things that the installer didn’t ask about specifically.

openSUSE graphical installer: Package selection

For example, package selection is handled well. Based on the chosen machine role, YaST proposes relevant package sets. Clicking on ‘Software’ in the installation overview lets you select and deselect additional ones. Furthermore, users can enter advanced mode to make granular selections, including individual packages to include or exclude. Fortunately, YaST performs sanity checks on selections, alerting users when it adds dependencies to ensure compatibility. This is pretty impressive.

openSUSE installer options

While the graphical front-end of YaST is pretty good, there’s fortunately a text-based one as well. Because why would you want to deal with the hassle of VNC (which cannot even map keys correctly if you use xmodmap on your workstation!) to install a server?

openSUSE text installer: Progress bar

The text version is mostly equivalent to the graphical installer. A series of items to go through and a progress bar work just the same. You simply have to make do without the global overview bar at the left.

openSUSE text installer: Language, keyboard license

This screen works just like in the graphical version. They’ve done a good job at making it look and behave pretty similar.

openSUSE text installer: Time settings

Time settings are quite different of course. And here it shows that not having a huge map take away so much space, you can fit two lists on the screen instead of hiding them away in pull-down menus. But at the end of the day either works.

openSUSE text installer: Installation options summary

The installation overview is also basically equivalent to the graphical version. However it is complex enough that the text version is more difficult to navigate since you cannot just click on something. It’s still okay, though.

openSUSE text installer: Package selection

The same is no longer true for this screen however. While you can still configure the system down to the package level in text mode, doing so is pretty cumbersome compared to the graphical installer. Hats off to SUSE, though, for making it work nevertheless and for obviously putting some effort into making it relatively painless.

When it comes to Linux installers, openSUSE’s for Leap 15.x is probably my favorite. Someone clearly thought about UI design and the result definitely shows that it’s always well worth to do that! But not only that, the installer might also be the most versatile one. Within the expert partitioner (that I have not showcased here) there’s a couple of things that should be done differently from a UX perspective (i. e. would save you more than a dozen clicks for more complex installations). So I won’t claim that it’s perfect, but I will say that if you want to see what a well-designed installer can look like, give openSUSE Leap 15.x a try. For the upcoming 16.0 the installer regressed massively IMO. I can see why they are doing that, though. SUSE’s various projects like MicroOS have very different requirements than classic OS installations. But yeah… We’ll see what they’ll arrive at when they got some more time to work on the newest iteration of the installer.

RHEL and clones

The RHEL family of distribution comes with a couple of really nice things. One of them is related to the installer, so let’s take a look.

Anaconda installer: Security profiles

Anaconda allows for choosing a so-called security profile. And what’s great about this is that the respective security controls are applied at installation time, so security is not an afterthought that someone had when configuring the fresh system. The additional security measures are active right from the first boot. This is absolutely awesome!

Anaconda installer: PCI-DSS profile selected

Here’s an example of activating a profile. The rather well-known PCI-DSS (for systems dealing with credit cards) is a rather simple one: It installs (and configures) a couple of additional packages and it blocks some others (to block out applications which use unencrypted protocols).

Anaconda installer: DISTA STIG profile selected

The profile for the STIG (Security Technical Implementation Guide) of the DISTA (US Defense Information Systems Agency) goes beyond that and also adds partitioning requirements on top, which make a lot of sense if you still use a filesystem that doesn’t combine volume management and actual filesystems (RHEL uses SGI’s old XFS by default).

Anaconda installer: Importing custom profile

And what if you have special requirements to fulfill? In that case you can simply (ok, this admittedly is an understatement!) create your own custom profile. The installer allows you to just import it! Well… Or rather it used to allow for that. In their ongoing quest for suckiness, Red Hat decided that this was “not flexible enough” and removed the feature for RHEL 10.

Yes, that’s right: They cut a unique feature that allowed everybody to do hardened installs by just applying a security profile! Achieving the same result now requires creating a custom hardened image and a corresponding kickstart profile. Hats off (pun intended) to RH for this! (This led me to seriously evaluate openSUSE’s AutoYaST, which I ultimately found to be more powerful and automatable.)

Void Linux

Void provides a simple installer that can help you get a basic system up and running without breaking a sweat, but it does deliberately not try to allow for everything. For example if you want to use root-on-ZFS (which is relatively well supported on Void), you have to install by hand.

Void installer: Main menu

The installer follows a familiar, menu-driven approach. You navigate a menu, make your choices and eventually end up with a bootable OS.

Void installer: User creation – group memberships

This screenshot is why I included the Void installer: When you create a user, this dialog window is how they let the user select group memberships! It’s a subtle detail, but I appreciate how the installer handles group selection. Offering a list to select groups from is neat enough that I thought I’d include it here.

Top 5 Worst Offenders

Of course not all ideas people have for their installers are good. Now looking for the worst installer crimes of the broader Linux ecosystem could be a dead-serious task. But to not end this article with too negative vibes, let’s make it into a contest of the most stupid or annoying ideas! So without further ado here comes rank no. five:

5th: Debian

The fifth worst offender when it comes to installer stupidities is Debian. Why?

Debian installer: “Popularity contest”

Debian runs a so called “popularity contest” which is about gathering data on which packages are most frequently installed by people. There’s nothing wrong with this if it’s an informed decision for the user. And indeed Debian gets this right: It’s opt-in, not opt-out! This is commendable.

Debian installer: Interruption is in the middle of the installation process!

Of course there’s one catch: This is not done at the beginning of the installation or at the end. Oh no! It happens right in the middle… So whenever you begin an interactive Debian installation, you cannot turn away and come back a while later with the installation finished. That would be too easy. Fortunately somebody came up with the brilliant idea of that stupid interactive window which pauses the installation process! So you’ve got to wait for the basic system to be installed and then again for a while into the installation of additional packages until finally the package contest triggers. That special kind of stupid alone justifies a solid fifth rank in my little contest!

To further support it against the competition, there’s an annoying regression in the Debian installer. I still remember when it would have asked whether or not to try to get network parameters via DHCP. For some reason or another, many years ago Debian started just assuming everyone wants to use DHCP and so now you have to cancel (or wait for it to fail) if you want to do simple static addressing. That means a certain type of packets get broadcasted through your network – which in turn might mean to irritate the watch program that was set up to detect when customers who have root machines try to use DHCP… Thank you so much, Debian!

4th: RHEL and clones

The installer from Red Hat is called ‘Anaconda’. It’s used for RHEL and its various clones (like Rocky Linux, Alma Linux, Oracle Linux, …) as well as other RH distributions like Fedora and CentOS. I’m not terribly fond of it for several reasons. Let’s take a look at some.

Anaconda installer: Language selection

The welcome screen / language selection is not actually half bad: Two lists to select from, an input field and two buttons to the lower right to quit or continue respectively. The continue button even has a nice blue color to make it stand out. If Anaconda had been able to just keep it up like that, it would have not scored 4th and thus worse than Debian, though…

Anaconda installer: Main menu

And here we go: Somebody thought that it would be pretty cool and original if making the various choices for the installation was non-linear. But this is not a game, where non-linearity would indeed likely be a plus. This is an operating system installer! There’s no actual benefit in being able to do things in whatever order you want to. The ‘Begin Installation’ button to the lower right is disabled until you made all the required choices.

Anaconda installer: Software selection

And it gets worse. If you choose anything like ‘software selection’ for example, you end up in a new screen. ‘Minimal Install’ and ‘Custom Operating System’ seem to be doing exactly the same thing – at least I’ve not been able to figure out any difference. But that’s a relatively minor complaint. Much worse is that the ‘Done’ button is not where you’d expect it to be. It was moved to the upper left and into the decoration bar! Having to click there to return to the main menu may not exactly be a tragedy but it’s still very bad and quirky.

Anaconda installer: Disk(s) selection

Then we get to disk partitioning. The standard ‘Automatic’ mode works fine, but a lot of (or most actually?) people have special requirements and prefer custom partitioning. So selecting the ‘Custom’ radio button… simply hides additional information that was present below. Yes, that’s all! No additional options whatsoever. I still remember quite well how I thought “what the heck?” when I used Anaconda the first time.

So what’s the solution? Well, you’re meant to click the ‘Done’ button, even though you are absolutely not done with the partitioning and do not want to return to the main menu. In this case it doesn’t actually do that, anyway! It takes you to another screen…

Anaconda installer: Manual partitioning

Welcome to manual partitioning. I have no idea for how many different operating systems I’ve done custom partitioning in my life, but it’s been a couple. Anaconda’s take at this relatively basic task is… special. The design approach is as counter-intuitive as the ‘Done’ button, which inexplicably serves to both return to the main menu and launch additional screens (but maybe that counts as a twisted form of consistency?).

Also note that the margin for the headline and the ‘Done’ button is off in this screen. Anaconda is not a hobbyist installer; isn’t it baffling that a project backed by such a major player in the Linux world can’t even get the basics of aesthetics right? As if the Anaconda ‘UX’ disaster wasn’t enough.

After this horror show you maybe wonder why this is only rank 4 and who actually managed to screw up even worse? It’s probably only due to me having reported above that RH dropped the security profiles, so I’m not going to hold that against them now. Otherwise we’d have a tie!

3rd: Ubuntu

*Sigh* Alright… Ubuntu. This distribution used the Debian installer for its server installations for years and years – which worked rather well. Then they decided to ditch it, only to replace it with something much worse. Since Canonical did this about the same time they decided to bet on ZFS, you’d bet that their new installer would offer support for it. But heck, no! To install a server with ZFS, they wanted you to grab a desktop installer (!) and then perform a manual installation involving debbootstrap…

I’ve had a lot of… err, fun with the Ubiquity installer (and subiquity), and I failed to find at least one redeeming quality.

Ubiquity installer: Language selection

Ubuntu’s installer is ugly as hell and navigation is super weird in some cases. And these are probably its better characteristics!

Ubiquity installer: Mirror configuration

Wonder how you could escape to a shell? This option among others is hidden under ‘Help’! If you’ve never used it, based on the previous two screenshots you probably think that I’m being overly harsh here. Just wait for the next ones.

Ubiquity installer: Storage configuration

Now the installer is getting warmed up on terrible layout! There’s so much wrong with this screen that I’m not even going to describe it. And of course selecting custom doesn’t make things any better.

Ubiquity installer: Storage overview

Okay, so this is the overview screen (for a relatively simple storage layout, mind you). I just wanted to make that clear in case you didn’t immediately realize. Oh my… This is about as far away from clearly arranged as possible.

Ubiquity installer: Installation progress

And when finally the actual installation begins, the ordeal is far from over. As you can see, there is no progress indicator so you are left wondering when it will ever end. All you get are log-style messages to give you a clue about what’s currently happening. And curtain, the installation tool from hell, is painfully sllloooowww. Oh, and not only that, it’s crash happy as well. Installing on fresh drives usually works, but if you have something else on there already, chances are that it will be unable to delete the old partitions and create the new ones… Major takeaway: If you already got an OS on your machine, don’t replace it with Ubuntu. Chances are it’s something better, anyway.

Ubiquity installer: Security updates

When the installation is finally done, Ubiquity will do security updates, too. That means you’ve got some more time to stare at the awful mess that is Ubuntu’s installer. For 24.04 they removed an option to cancel the security upgrades. Which however doesn’t matter much, since it was just another evil means of punishing the weak who were tempted to use the button! If you did, curtin would spit “cancelling security updates” or something like that in your face and then take its sweet time! I honestly don’t know if waiting for it to cancel or just suffering through the security upgrades made much of a difference in wasting minutes of your life.

Ubiquity is a nightmare of an OS installer. There’s nothing positive I can say at this point. What were you even thinking, Canonical?

2nd: RHEL (yes, again!)

Yes, unfortunately we have to return to Anaconda once more, and yes, in a way it’s even worse than Ubiquity. Let’s get it over with…

Call trace during system boot

By the way, if you ever wondered if you can fail even before the installer, here’s an example for that. Yes, this is the final release, not a beta or anything. But we’re in Linux land, right? “Seems to work” is good enough, even for an “enterprise” distribution (this is Rocky, but it happens with Oracle as well). Why would you investigate a call trace before releasing? But that’s not Anaconda’s fault, it’s just some additional context about how things work in penguin land.

Anaconda: text installer

Anaconda can run both in graphical and in text mode. Making the graphical installer the default for a distribution that’s mostly used for servers is already a quite weird decision, but it certainly doesn’t qualify for second place in this top 5. But imagine you edited the command line in the GRUB boot loader (appending ‘inst.text’) and loaded up the text installer – only to find it crippled… That certainly does. Seriously: what the heck, RH?

I mean, it’s frequently the case that graphical options cannot do everything and for the full power you use the CLI. But the other way round? Remember: It’s not like graphical Anaconda was the zenith of usability and text-mode Anaconda simply didn’t quite reach those heights. In reality the former is sub-par in general and the latter cannot even do that. The fact that they also utilize tmux (a good decision) unfortunately has no chance to save the day. Congratulations, Red Hat, on a solid second place! And shame on you.

Sorry for the German in the screenshot, BTW. This was what the installer came up with for me and I’ve been unable to change it. Yes, there’s option 2 “Spracheinstellungen” (language settings) and you can select English there. But unlike what graphical Anaconda does, this seems to only affect the keyboard layout and does not change the actual installer language. So even that very basic feature is broken.

Well, it doesn’t matter much, since text-mode Anaconda is pretty much broken by design as it openly admits (not being able to do custom partitioning is a complete deal-breaker for me). Oh, and thanks for asking if I would rather do a remote graphical installation using RDP. Haha! Good one. For a Linux server… Yeah, screw you, too.

1st: SUSE

And the winner is… SUSE! Or rather openSUSE Leap 42. Yes, that particular version. This might come as a surprise since I praised YaST as an installer earlier in this article. Well, for Leap 15 it is great and I stand by that. But for some reason SUSE tried something different for the previous version 42. It’s a perfect example that ignorance can have as much of an impact as actual malice. But what did they do?

YaST: Language, keyboard and License Agreement again

Here’s the language, keyboard and license agreement screen of this version of the installer. And no, while additional points for the super ugly color theme would be due (as well as for the lame attempt to transition to a new version scheme), Leap 42’s installer doesn’t need them to score rank 1.

YaST: Installation summary

Here’s the installation summary screen. You don’t have to remember exactly what the one for Leap 15 looked like, but probably you remember that you had to scroll because not everything fit on screen at once. Not so much this time. Somebody obviously had the idea to have as tidy an installer as possible – and boy, did they succeed at that!

Have a look again. Can you see what’s missing? We have ‘Booting’, ‘Software’, ‘Default systemd target’, ‘System’ and ‘Firewall and SSH’. Wait a second… Where’s ‘Networking’? Exactly! It’s not there!

Here’s what happened: YaST silently (!) attempted to configure the network via DHCP. And worse: If that succeeds, there is no frickin’ way to configure it differently! The installer just won’t let you. Now imagine if you will the not exactly far-fetched use case of installing an OS via PXE using a dedicated install network. DHCP is a must for PXE, but of course you want to separate your networks and by not allowing to select other network settings it effectively means that the resulting installation is inaccessible by normal means afterwards…

This is absolutely brilliant. No, let’s not be modest: It’s a stroke of genius. And that ingenuity made SUSE’s YaST of Leap 42 come out ahead even before RH’s Anaconda. Heartfelt congratulations, and my deepest sympathy. Fortunately Leap 42 is quite old now and before long we’ll know what new ways to screw up they came up with for Leap 16.

Honorable mention: NixOS

Of course there’s definitely many more failures to be found in Linux installers. I’d like to end this with one honorable mention that tried really hard but unfortunately couldn’t beat Debian’s decade long stupidly placed popularity contest. And when I say really hard, I mean it. But it’s a niche distro that people know because it comes with this cool purely functional package manager. But even if it screws up hard (and it does), all you do is laugh and move on. Debian on the other hand is a constant nuisance.

NixOS installer

Ah, yes. The beauty of graphical installers gone wrong. As you can see, here’s a summary that doesn’t fit on the screen. There’s scroll bars at the side – but you cannot scroll down more than a few pixels… Also hitting RETURN or SPACE does not trigger an (out of view) ‘next’ button or something. So at the screen resolution of my VNC application this proved to be a dead end before the actual installation would even start!

Sorry NixOS! Admittedly you gave it all and yes, this is pretty embarrassing. But all you get for it is this lousy honorable mention.

Conclusion

I hope that you enjoyed this wild ride through notable good ideas in installers as well as their worst atrocities. Almost all of them have both their merits and their flaws, but all installers were definitely not created equal. In the end that’s probably a good thing because people will continue to try out weird new ideas. And that’s why we all love Unix, right? An OS that by design doesn’t stop you from doing really dumb things, because that might also keep you from doing really smart things.

What’s next?

My list of topics to write about is getting so long that it’s starting to worry me. I haven’t decided what to write about next, yet, but I might pick a one-off topic before starting another series.

kraileth
http://eerielinux.wordpress.com/?p=5356
Extensions
Installing *BSD in 2025 part 4 – A critical look at DragonFly BSD’s installer
bsdcomputerdragonfly bsdinstalleroperating systemsoftware
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt4.gmi The first part of this series was about FreeBSD’s installer, the second covered OpenBSD’s installation program and part 3 discussed NetBSD’s. DragonFly BSD is clearly the one of the four “main” … Continue reading Installing *BSD in 2025 part 4 – A critical look at DragonFly BSD’s installer
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt4.gmi

The first part of this series was about FreeBSD’s installer, the second covered OpenBSD’s installation program and part 3 discussed NetBSD’s.

DragonFly BSD is clearly the one of the four “main” BSD operating systems, that I’m least familiar with. Not because I think it’s bad or don’t like its design decisions or goals. Also certainly not because it’s the least popular one. Well, at least not directly. Indirectly it’s probably related to the latter after all: VMs are nice for some things, but I prefer installing OSes that I want to dig into on real hardware. For DragonFly BSD the range of supported hardware is somewhat narrow – and over all these years that I tried to get a DragonFly system running properly, I haven’t had much luck in that regard.

Oftentimes I’ve indeed been unable to even install the system as the installer threw errors at me. But when it is able to start up properly, it’s easily among the best I’ve used in terms of UX. Like in the previous articles of this series, I’m going to install the OS twice – once using the standard video console and once over serial.

The version used here is DragonFly BSD 6.4.2 on amd64 (which is the only supported platform since DragonFly dropped i386 support many years ago).

A little bit of background

The installer that DragonFly BSD uses is called BSD Installer. While I’m also referring to it as “DragonFly’s installer”, it originally had a bigger scope. Developed by the DragonFly team as a replacement of FreeBSD older installation program (that is sysinstall), BSD Installer was not exclusive to DragonFly BSD but was adopted by pfSense as well. OPNsense, a fork of the former, also used it initially. Eventually it was replaced with FreeBSD’s newer installer, bsdinstall, because the project wanted to support Root-on-ZFS and it was easier for them to adopt an installer which could already do this than to integrate the new functionality into BSD Installer.

The team behind the installer made some interesting design choices like splitting it into a backend and multiple (yes!) frontends. You’ve probably only ever seen the ncurses based one, but historically there at least has been a CGI based frontend, too. BSD Installer as a (semi) independent project vanished over a decade ago, but thanks to the Internet Archive, it’s possible to have a look at what the CGI frontend looked like:

Old BSD Installer screenshots Web page

It seems that work was done to add more features to BSD Installer to make it on-par with sysinstall so FreeBSD 9.0 could finally replace their unloved installer. The FreeBSD project did just that for 9.0 – but that release shipped with bsdinstall, which was a new installer not related to BSD Installer. Ironically, the early releases of bsdinstall were vastly inferior to the old sysinstall!

I don’t know the full history behind why BSD Installer was never adopted by FreeBSD and thus one interesting opportunity to collaborate across projects didn’t happen. Outside of DragonFly, the project (which even supports automated installations via a “pre-flight installer” configuration!) sunk into relative obscurity. But how well does it do its job on the one OS that still uses it?

Installing DragonFly BSD

Unlike OpenBSD and NetBSD, DragonFly BSD does not include X11 or a desktop environment by default, similar to FreeBSD. It also lacks complex storage options. I’ll still try to use the two installations that I’m going to do to show off some of the different paths that you can take. But they will still be somewhat similar compared to what I did in the previous three articles. For the first installation I’m aiming for a “standard” system.

Booting from a DragonFly BSD installation medium will not bring up the installer by default. Instead when the system finishes booting, the user gets the login prompt. A hint suggests to log in as user ‘installer’ to begin the installation. There’s nothing wrong with this approach, but I’d prefer the installer to launch automatically, as it allows exiting to a live system.

Live system booted up

After launching the installer, it first displays a welcome message and a menu with a couple of options. In my opinion the last sentence is a bit weird: “this automated application”? It probably stems from the fact that the installer does support automation. For a newcomer to the DragonFly installer however it’s confusing at best and I would suggest changing it.

The menu options however are excellent and the NetBoot setup one in particular is a really neat and innovative idea!

Welcome message and main menu

Even though I absolutely love the idea behind this, I’m not entirely clear on how it functions. There should be an F1 help page on this one, seriously! The text mentions a fixed address of 10.1.0.1/24 which made me guess that enabling the services will provide the whole stack required for PXE booting including a DHCP server, TFTP and probably NFS?

I took a look and exactly that is the case. They still utilize ISC’s DHCPd, which reached end-of-life in 2022 and would ideally be replaced with Kea. However that isn’t even the main problem that I have with it. What if that address range is already in use within the organization? I haven’t found a way to specify a different range.

However, this is a minor point. Alright, let’s move on to the installation!

NetBoot install services setup

Performing a default installation

If the user chose to install the system rather than one of the other options (like the NetBoot setup), a message is displayed about the installer’s limitations and that an installation should not be attempted before important data that might be on the disk has been backed up. The three options to continue with the installation, go back to the menu or to exit the installer are fine.

Backup notice

Continuing, the next dialog is about the desired type of booting. Older hardware might only support legacy BIOS booting while newer computers support UEFI (sometimes exclusively). It’s nice that the installer simply asks this question and decides on the partitioning schema as well as the loader variant depending on the answer.

Yes, leaving it to the user is the more powerful approach and there’s reasons for wanting to use BIOS+GPT rather than BIOS+MBR for example. But DragonFly BSD is a system that’s mostly meant to be used on modern machines using modern means. So I guess it makes sense to prefer streamlining the installation process over trying to cover more exotic use cases. The latter require a manual installation which isn’t impossible to do, either.

Boot type selection

The next step is to select the disk to install the system on. I would suggest not listing the 0 MB vn drives. They cannot be used as installation targets, anyway, so why list them in the first place?

Selecting the installation target

After selecting the disk, an installer needs to display the obligatory warning about data loss due to changing the disk structure. The message is quite clear and works well here.

Data loss warning

If the user chooses to proceed, the disk is modified and a confirmation message displayed that the drive was formatted. While feedback is good, I wonder if this warrants its own dialog window. Since there’s no selection to make here and the user can just use the “OK” button, why not drop this one and put the information into the next dialog? I. e. “Disk XYZ was formatted. Please select the filesystem to use with DragonFly BSD.” would work even better.

Well, and to offer my honest opinion, I don’t think the term “formatted” is particularly well chosen here. At least I associate formatting with creating a filesystem – which has not been created, yet! I think it would be better to state that the disk was indeed partitioned. This was probably done back in the day when there was the common confusion between BIOS partitions and BSD disklabel partitions. But since a dialog window down the line speaks about subpartitioning, I’d say calling this step partitioning rather than formatting would be the better choice.

Formatting completed

The FS selection dialog is a good one. It’s very useful for newcomers that there’s at least a short explanation about what HAMMER2 and HAMMER1 are, potentially giving people some guidance. Still I think this dialog could benefit from an additional F1 help text briefly explaining the characteristics or use cases of the three options.

Filesystem selection

The subpartitioning is one of the steps where BSD Installer shines. The text is concise but gives all the required information and the mechanism to modify, add or delete additional subpartitions is done really well! I like this a lot and it’s where a thoughtful approach to UX design pays off, delivering about as streamlined an installation experience as possible. Very well done!

Disk subpartitioning

It’s nice that a help text is available about subpartitioning. However I don’t think that the “speeding up” statement is particularly useful. In times where most people use flash memory based storage, it’s obsolete. And even with spinning drives you had to know what you were doing. Without also discussing disk geometry, sector density and so on, this statement might actually confuse newcomers rather than inform them. Like making them believe having lots of subpartitions speeds up the system or something like that. IMO this is a candidate for revising.

Help text about subpartitioning

The warning dialog about using HAMMER on very small drives makes a lot of sense. It allows the user to reconsider and even in cases where they decide to go ahead, it’s an informed decision. Also the pointers to tools that these users need to know about are valuable for newcomers to DragonFly BSD.

What I don’t like is that the buttons are labelled “OK” and “Cancel”. The latter sounds a bit like giving up on the installation. Based on what it does, “Return to Create Subpartitions” would be more accurate. Since the next dialog window uses that very label for a button which does exactly the same, making this change would also improve consistency.

HAMMER FS warning

Next is a dialog window letting the user know that the actual installation can now start and that the process will take a while. It also gives you the option of going back to subpartitioning in case you changed your mind. This works well.

Begin Installation?

The installation process is about as simple as it gets: Various commands are executed (and displayed for people who are interested in what’s happening) and there’s a progress bar as well as a numeric representation in percent. A button gives you the chance to cancel the process if for whatever reason that’s what you want to do. This is very well done, I cannot think of any suggestion to improve it further.

Installation in progress

After all the files have been copied to disk, the installer displays an “installation complete” message. The three buttons to choose from – configuring the installed system, rebooting or returning to the main menu – are also good. Since configuring the system is what most people will want to do, it’s the default option.

Installation complete!

Post-installation configuration

BSD Installer offers nine menu items for post-installation configuration of the system, all of which are useful.

Post-install configuration menu

If the user opts to set date and time, the first question is whether this machine uses UTC time for the CMOS clock or not. This is the usual problem; while all sane operating systems do that, some people have to dual-boot Windows for any number of reasons. So it’s probably a good thing to ask rather than just assuming UTC and have that other OS freak out! 😉

Clock time setting

Next is selecting the time zone to determine local time. Unless you have special needs (and know what you’re doing), you will probably want to select a continent here. But the installer provides the full list for the user to pick from.

Time zone selection: continents

After selecting a continent, a second level menu is displayed and the user can pick a city. This approach is fairly common and there’s nothing wrong with it.

Time zone selection: city

A confirmation message informs the user that the selected timezone has been set. I don’t think this is necessary and would prefer the standard Unix approach here: No error means success! That would be one less relatively useless keystroke.

Time zone confirmation

The next step is entering date and time information. Having all the input fields in one dialog window rather than separating date and time works really well.

Date and time configuration

Then we have another confirmation message. This one however is even more worthless than the one about the timezone which at least mentioned which one was set. My suggestion would be to get rid of the former entirely and revise this one. A summary that informs on whether the clock was set to UTC or local time, which time zone was set and what the current date and time is would be much more useful!

Date and time confirmation

The next configuration option is the keyboard layout to use. There’s a large list to choose from, but it’s not very consistent. Why is it ‘danish’ and ‘finnish’ and not ‘da’ and ‘fi’? Or the other way around: why is there ‘cz’ and ‘jp’ instead of ‘czech’ and ‘japanese’? Either method would be fine, but why mix languages with language codes? I’m not complaining about variants like dvorak or colemak, but the inconsistency of the items in the keyboard layout menu really isn’t pretty.

Keymap selection

Next is setting the root password. The dialog window with the two input fields and two buttons works very well for this. Occasionally a checkbox for “show password characters” could be useful, but this is not a must-have at all.

Setting the root password

Once the root password has been set, a confirmation message is displayed. Once again, while “explicit over implicit” does have its appeal in some situations, I don’t think this is one of them. If I press a button that says “Accept and Set Password”, I expect that exactly that happens. If there’s an error, I want to be told about it, but confirming that the operation succeeded is a little pointless.

Root password confirmation

The “Add user” dialog window with its input fields is another great one. The text explains which fields can be left empty to accept the default values, which is very useful. As with most other BSD installers, I have to make the suggestion that a hint that a membership in ‘wheel’ is required to be able to su to root. Also it wouldn’t hurt to mention multiple additional groups are delimited.

Adding a new user

As usual, after successful creation of the user, a confirmation message is shown. I’m still not a fan of the additional key press necessary to acknowledge this.

User creation confirmation

The next configuration option is a very important one: network configuration. First in the process is selecting the NIC to configure. Listing the loopback device ‘lo0’ here is pretty much pointless and I would suggest filtering it out.

Also I’m repeating here what I said when reviewing the other installers as well: It can be helpful to display the MAC address together with the interface name. Some servers have multiple NICs and when deploying a server OS in a datacenter, MAC addresses are very useful to tell NICs apart.

Network configuration: NIC selection

After that the user gets to select either attempting to autoconfigure the interface using DHCP or to configure it manually. Both options are for IPv4 only, so what I miss here is the opportunity to configure the system for IPv6.

Although I admittedly disable IPv6 on most of my machines, an increasing portion of the internet is now only accessible through this newer protocol. Also due to the scarcity of v4 addresses, those usually cost money with many hosting companies whereas you can get v6 ones for free. Providing network access is one of the fundamental tasks of post-installation configuration and IMO BSD Installer omits a real must-have here.

Network configuration: DHCP or static?

This particular confirmation window after network configuration isn’t particularly helpful. It shows some of the output of ‘ifconfig’ and tells me that an IPv6 link-local address is assigned to the NIC (“inet6”), but there’s no trace of a v4 address! Also this message popped up rather quickly after selecting DHCP. The combination of the two makes me guess that this option only configured the system for DHCP but did not actually attempt to get an address!

This is pretty unusual as about every other installer that I know will test DHCP rather than assuming it would work. DragonFly BSD users probably know what they are doing, but still. This is also something that I would suggest letting the installer handle.

Network configuration: confirmation

Setting the hostname and domain is done well. With the two input fields present there can be no wondering about whether the short or long form of the hostname (FQDN) is expected. Also having them both in the same dialog window is nice.

I tried to come up with a more creative hostname but couldn’t think of anything that appealed to me. So I went with DragonFly BSD’s mascot’s name.

Hostname and domain configuration

The next menu item is something that’s not very common but can be useful nevertheless: Here you get to configure the console font for the fresh system. While most DragonFly BSD systems are probably accessed via SSH most of the time, sometimes you may want to work on the system console. And being able to configure the font for that using the installer is quite nice.

Console font selection

The same is true for the next one. You might not need this all the time, but some people want to configure their system to use a codepage that supports Cyrillic characters for example (KOI8).

Screen map selection

Finishing the installation

And that’s basically it. The last option takes you back to the welcome menu. A little detail: If you didn’t notice that the changed console font took effect immediately, compare the following screenshot with the one from the beginning of the installation.

Back at the Welcome Menu

If you choose to reboot now, you get another dialog window reminding you to remove the installation medium after it has shut down. This is good advice.

Reboot?

After the reboot you can see that the new system started up regularly, so the installation was successful.

New system has booted

Installation over a serial connection

After the standard installation succeeded, it’s time to try and install a system over a serial connection (i. e. using cu to connect to the virtual nullmodem device attached to the VM).

The kernel needs to be configured to provide output to the serial console rather than the default vidconsole. This can be done by escaping to the OK prompt of the boot loader and setting the console appropriately before booting.

Enabling serial console in the loader

Afterwards the boot process works just like before and when it finishes, the user is presented with a login prompt from which the installer can be started.

Live system login prompt

Since this is a serial connection, the user is asked about the terminal type before the actual installer starts. VT100 is a very conservative default here and mentioning a couple of other options probably wouldn’t hurt. Then again – people who do installations over serial probably know what they are doing.

Terminal type selection

Exploring the live system

The welcome menu that we already saw during the first installation appears. Since I used a terminal size of 24 lines of 80 characters max, the window is quite big but fits without scrolling.

Welcome menu

This time I decided to take a quick look at which live utilities are available before doing the actual installation. Selecting this option displays a dialog window with a concise description and a submenu of useful items: “LiveCD Environment”, “System Diagnostics” and “Disk Utilities” as well as the option to exit the installer, reboot the machine or return to the main menu. The first one contains a typo – everywhere else it’s usually written as “Live CD”, with a space. But that’s cosmetics, of course.

The live utilities menu

The Live CD Environment menu features the same options does the post-installation configuration menu – minus the options to set the root password or to add a user. This menu can be useful if you for example want to change the keyboard layout (e. g. because otherwise you might not be able to correctly type the slash character, which is quite unfortunate when defining the mount points!).

This window is also longer then what fits on the screen. It will scroll just fine, but I think that some kind of indication that there are more options below would be very useful. (Yes, a scroll bar is present to the right of the window – but it’s very hard to see if you don’t know that it’s there!)

Live environment configuration

From the diagnostics menu you can view the system message buffer (“dmesg”) or list the PCI or ATA devices that the kernel recognized. This can be very useful to determine if the machine you are trying to install on is a good fit for DragonFly BSD or not.

Live CD diagnostics menu

Lastly, the disk utils menu allows for “formatting” (partitioning) of a disk, wipe out the start of a disk or primary partition on a disk, install the bootblocks or format an MS-DOS floppy disk.

This is obviously one of the more obscure areas of the installer. Especially the last option probably hasn’t seen much use in ages; DragonFly BSD supports only the amd64 ISA since version 4.0 released over a decade ago and such machines almost never have floppy drives!

But the wiping options also scream “MBR” and are thus more or less obsolete as well.

Disk utilities menu

Installing the OS

The message about limitations of the installer and backing up data before proceeding is the same as before …

Backup notice

… but this time I decided to let the installer display the help text that is offered here. Well, two of the three points about when to install manually rather than use BSD Installer are relics of a pre-GPT age. There certainly are more common use cases today which the installer does not cover. So maybe this text could be adapted?

Installation help text

Next is the boot type selection dialog. I would have liked to show off BIOS, but this is not well supported by my hypervisor. So UEFI it is – no stone age today! It might be worth mentioning, though, that selecting BIOS makes an advanced mode available for subpartitioning. It allows for setting options related to UFS.

Machine boot type selection

Disk selection is also the same as before.

Installation target selection

As is the data loss warning window …

Data loss warning

… and the “formatting” confirmation.

Formatting confirmation

Of course the filesystem selection is the same as well. However this time I decided to not use one of DragonFly BSD’s most notable features and opt for an installation on good old UFS!

File system selection

I assume that it’s related to selecting UFS, but for the subpartitioning only three partitions are suggested (leaving out ‘/build’).

Disk partitioning

This time I decided to try out adding a custom partition to be used for /home. Also, since the installer supports it, I opted to have it encrypted for a change.

Adding an additional partition

Selecting encryption reveals a new window that we haven’t seen during the previous installation. The explanation text includes the “LiveCD” typo again. It’s great that it reminds the user about the keymap being US by default. However it pointing at kbdcontrol(1) (and thus to leaving the installer to change the layout and then returning) is weird. Wouldn’t it make much more sense to explain that the keymap can be changed by using the “Live CD Environment” menu?

I’d say staying inside the installer is preferable to having to quit it for such a common task as changing the keymap. Of course it would be even better to place a button here that would open the keyboard selection menu!

Encryption passphrase dialog

After inputting the passphrase twice, the installer creates the filesystems …

FS creation

… and then the encryption fails unexpectedly! I thought that this might be related to me picking UFS. So I tried again using HAMMER1 but ran into the same issue, unfortunately. Eventually I decided to move on without encryption as I don’t particularly like LUKS, anyway.

Encryption failed!

The good thing about hitting this error is that it allows me to show off something else. The authors of BSD Installer obviously thought ahead and implemented error handling. The issue I had has been covered and the message includes a very sensible recommendation.

Error handling

While I changed the filesystem to HAMMER1, I stuck with the partitioning that I prepared earlier. This triggers another information which informs the user that directories like /usr/obj will be on the root partition if none is created for ‘/build’.

Information about a simple partition scheme

Since the message about what to watch out for with very small volumes covers both HAMMER1 and HAMMER2, it gets displayed in the serial installation as well.

Information about HAMMER

The final dialog window letting the user begin the actual installation or going back to subpartitioning is also the same as last time.

Begin installing files?

While we have also already seen the progress window, I managed to screenshot it with a system message printed over it. It’s for cases like this and other glitches that the installer provides the function mentioned in the top bar: “F10=Refresh Display”.

Installation progress

Like many others, the message that the installation has been completed is identical to what we’ve already seen at the end of the previous installation.

Installation finished

Post-installation configuration

Just like in the first installation, the the post-installation configuration menu is available, offering the same options.

Post-installation configuration menu

This time I went with static IP configuration. The dialog window with its input fields is great for configuring IPv4. However there’s two things that I noticed:

  • The option to configure hostname and domain in this window is redundant. They can be configured in the next post-installation configuration menu item as well. And worse: if they are entered with the network configuration, the input fields of the other dialog window will still be empty! This can be confusing.
  • The second button says “Return to Utilities Menu” – which is not where we came from in this case!

Static IP configuration

The confirmation message is also displayed after static network configuration. Unlike with DHCP however, this time the IPv4 address is displayed correctly, though.

Network configuration confirmation

And that’s it! The other options work the same as before and there’s not much to see there. The HAMMER1 installation can also be booted successfully.

New system has booted up

Conclusion

The DragonFly BSD installation is somewhat special. It is at the same time very streamlined and overly verbose. For example it’s the only BSD operating system that does not let the user select which distribution sets to install and which not. You get the whole system or nothing. It’s also the only one that doesn’t ask about the keymap right at the beginning. Many of the dialog windows are well designed and allow for all the necessary input in one dialog rather than splitting the same into two or three. This is very nice. However there are also various confirmation messages which are of doubtful usefulness.

For an operating system like DragonFly BSD which has an advanced filesystem (HAMMER), I’d call the storage options severely lacking. I found it strange that the installer didn’t even let me create a simple software RAID – nothing fancy, just a mirror. I wondered how you set this up in DragonFly BSD. Well, the answer is: you don’t! I even asked a DragonFly user, and it seems like people either use software RAID at the BIOS level or hardware RAID – or they come up with different storage strategies. DragonFly BSD ported LVM from Linux and that theoretically has RAID functionality but seems to not really be tested. There’s also vinum from the old FreeBSD 4.x days which is still available, but it’s ancient and not exactly fun to use.

So a lack of flexible storage options is not BSD Installer’s fault but simply not an area where the small DragonFly BSD team has been doing much work on. I like the installer quite a bit. It’s both easy and pleasant to use – for the most part. There’s some signs of neglect in the more dusty corners, but that’s mostly small issues. The only bigger issue that I found was encryption not working for me.

Of course even with a good installer, there’s usually things that can be improved further. I’ve made a couple of suggestions. Here’s another one: Returning to the post-install configuration menu after setting any option always highlights the first option. While the list is not terribly long, most people will want to set all of these configuration options and thus having the menu remembering the previous menu item position would save several key strokes. This is a very minor thing but still a potential improvement worth mentioning.

I wonder what BSD Installer would have evolved into if FreeBSD had adopted it. Its modern bsdinstall is not half bad, but DragonFly’s clearly has the better UX and “flow”. Unfortunately that’s the trouble with “what if”: We’ll never know. Still I hope that DragonFly BSD will keep improving their installer, as it’s a good one despite a few flaws.

What’s next?

Given the positive reception of this series, I plan on writing a “bonus episode” to conclude it. What will it cover? I’m not going to tell you, yet!

kraileth
http://eerielinux.wordpress.com/?p=5250
Extensions
Installing *BSD in 2025 part 3 – A critical look at NetBSD’s installer
bsdcomputerinstallernetbsdoperating systemsoftware
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt3.gmi The first part of this series was about FreeBSD’s installer and the second covered OpenBSD’s installation program. This is a longer article and it has the most images that I ever … Continue reading Installing *BSD in 2025 part 3 – A critical look at NetBSD’s installer
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt3.gmi

The first part of this series was about FreeBSD’s installer and the second covered OpenBSD’s installation program.

This is a longer article and it has the most images that I ever included in one. While writing the other two articles didn’t take me too long, this one has has occupied several evenings / nights over the course of about three weeks.

NetBSD is an OS that I installed only a couple of times over the years, so I’m not very familiar with its installer, sysinst. This fact was actually what led to this article (or the whole series rather): Talking to a NetBSD developer at EuroBSDcon 2023, I mentioned my impression that NetBSD was harder to install than it needed to be. He was interested in my perspective as a relative newcomer, and so I promised to take a closer look and write about it. While it certainly took me long enough, I finally get to do this. So let’s take a look at NetBSD’s installer, shall we? The version explored here is NetBSD 10.1 on amd64.

Installing a simple graphical NetBSD system

Sysinst is menu-driven like FreeBSD’s installer, but the two are quite different. This is not a direct comparison, but I’m going to mention other installers where appropriate. Like in the previous two articles, I’m going to install the OS twice: One time using the standard VGA console and once to assess how well it works over serial. Both installations will be in VMs just for the sake of convenience.

Language settings

The first screen that the installer presents is the language selection. If you’re used to more mainstream operating systems, you may be surprised that there’s only four languages in addition to English. But hey: Many other installers are available in English only, and if you’re somebody who’s more comfortable with German, (Castilian) Spanish, French, or Polish than with English, it’s nice to have the option!

I like that there’s a short introduction text at the top which briefly explains how to navigate the installer. This is very nice for newcomers! Assigning each item an alphabetic hotkey is also a great mechanic that makes navigating the installer a breeze even if there’s a lot of options (FreeBSD’s choice of numeric hotkeys is obviously inferior as soon as there are more than ten items).

Language selection

After selecting the language, the installer presents a list of supported keyboard layouts. Again, NetBSD’s installer does not offer the most comprehensive list ever, but there are some surprises. Given the relatively short list, your preferred keymap may not be available.

You probably wouldn’t expect that somebody invested the effort to make Icelandic available, would you? And there’s also things like “German (NEO2)”, a relatively obscure ergonomic variant (that I’ve actually used in the past before adopting BONE whith is basically NEO3). Not even FreeBSD offers NEO2, BTW. Those unusual cases are strong indicators of the NetBSD project being happy to include contributions. So if you consider making a keymap for your layout, another option in the list could probably be yours!

Keyboard layout selection

Next is the main menu that allows the user to either install a fresh system, upgrade an existing one, reboot and so on. Like in the menu before, the text at the top did not change. But it didn’t have to since once again the menu options are self-explanatory.

Installer options

The next screen presents some information on the steps of the installation process and asks if that is what the user wants to do. It’s concise and to the point – I like it. It means an additional key press, but it’s helpful for newcomers.

Installation process overview

Preparing the hard disk

Now sysinst needs to know the installation target. I believe a more detailed explanation at the top would be beneficial. It’s probably nitpicking to point out that “Extended partitioning” is not exactly an answer to the question “On which disk do you want to install NetBSD?”. That aside, I genuinely believe this screen could be improved. Something like “Select a single disk as the installation target or choose ‘extended partitioning’ for softraid, a logical volume manager or device encryption.” would be better. Probably mentioning that ‘wd*’ means IDE or SATA drives, ‘sd*’ is for SCSI or external USB drives and ‘ld*’ are logical drives like VirtIO drives and NVME could be helpful as well.

Installation target selection

The next screen does not have any explanatory text at all – another missed opportunity. While people who install NetBSD probably know it, would it hurt to mention that MBR is the scheme that older BIOS systems expect while GPT is required for EFI systems? I guess it wouldn’t.

Partitioning scheme selection

The partition options and the description text for GPT are fine.

Partitioning options

The default partition layout makes sense: One big partition for /, another for swap and a tmpfs-backed one for /tmp – and of course the FAT partition that is required for EFI booting. Since splitting out /usr and /var is common, both are suggested but have a size of 0, so they won’t be used unless the proposed layout is edited.

In general the top text is fine. While the explanation of the plus sign is helpful, I would appreciate a hint on how to select the partition that receives the plus. It took me quite a while to find out that when defining a partition size it can simply be appended! This was not immediately obvious to me.

Partition sizes and file systems

Editing partition sizes is easy enough. However the fact that giving /usr a size that is not 0 by default moves the plus sign to it even if *not* added to the size entered is quite confusing. It makes the plus mechanic appear magic even though it really isn’t. To be honest, before taking a closer look at sysinst, I assumed that it was not possible to add the plus e. g. to /home like I would have liked to do! Up until recently this was one of the things that bugged me about NetBSD’s installer. I read The NetBSD Guide‘s chapter on the installation and that info is not in there, either.

Editing a partition size

While it’s quite common for installers to allow specifying the unit as a suffix to the size, NetBSD does this differently. Sysinst allows for changing the unit via an option in the menu. It’s definitely useful to be able to switch to GB when partitioning large drives (and I guess due to the portability aspect of NetBSD it may make sense for some architectures to allow entering sectors or cylinders for more control).

Changing input units

The drawback with NetBSD’s method is that this makes the EFI partition appear as 0 GB as it’s only 128 MB. Allowing for input sizes like ’20g’ and ‘128m’ would be more flexible. Then again setting the EFI partition’s size (or just leaving it alone altogether) before switching units of course also works. Maybe displaying the size as 0.1 or something instead of 0 in that case would still make sense?

Partition sizes now in GB

Adding more partitions is easy to do; the first menu option below the table will let you do that. Sysinst asks for a mountpoint in that case and adds the new partition to the table. Not being able to cancel the operation with ESC feels a little weird. If the box said “Mount point (leave empty to cancel)?: ” or something like that it would be clear how to abort adding another partition.

Adding a custom partition

I simulated fat-fingering the input here by “accidentally” creating a “/s” partition. Much to my frustration I did not find out how to delete partitions from the table! Yes, since /usr and /var are initially of size 0, one can deduce that allocating no space to it will probably make the installer discard them. It’s details like these that make sysinst feel somewhat unfriendly and leave a negative impression.

I also don’t like that it’s not possible (or I was at least unable to find out how to do it) to change the mount point once the table entry is there. These two problems are also likely much worse with an MBR slice as BSD disklabels have a maximum number of partitions. If you’re doing a complex layout, better get it right the first time! It’s probably less of a problem for regular NetBSD users, but people who are new to an OS and are giving it a first try are not *that* unlikely to change their mind over the partitioning. The feeling of being unable to undo a mistake is discouraging.

Two new partitions added – one as a deliberate mistake

After finishing the partitioning, an overview of the layout is presented that the user can either accept – or cancel the installation. Again as a user I can’t say that I feel in control here. This screen basically asks: “Is this ok?”. And the only option besides “yes, go ahead” is “no, let me start over completely”. How about “let me go back to the partition editor and fix one small mistake”? Why isn’t there an option to modify this layout, and can I only accept or discard it? Again, this is probably not so much a problem for people who regularly install NetBSD. As someone who does so infrequently, I’m not entirely satisfied with this.

Partition layout overview

Next is another screen that gives the user the chance of “yes” and “no”. While it feels a bit redundant, I think it makes sense to make sure people are aware that at this point the changes will be written to the drive and data previously on it will be destroyed. It could probably still be another window over the last screen rather than a separate one. That’s a relatively minor point, though.

Make changes to the drive?

Writing the system to disk

Acknowledging the previous question, sysinst creates the partitions and filesystem(s). Now the user gets to choose which components of the OS to install. I like the options as well as the text.

Selecting the distribution sets

Now the user has to select the source for the distribution sets. The text only mentions FTP and NFS as requiring a network while this is of course the case for HTTP as well. I assume that this is because the other two are traditional sources while HTTP was added later but the text was not updated. This is of course another nit-picky one.

Selecting the installation source

With the source selected, the actual installation (unpacking of the distribution sets) begins. What I find a little strange is that while there is a progress bar, it’s for every single distribution tarball individually. There’s no global progress displayed anywhere! And since NetBSD consists of a respectable number of sets, I actually kind of miss this. Fortunately the system is fairly slim (especially compared to many other operating systems) and so the installation doesn’t take too long (even on machines with old, slow drives).

Extracting a distribution set

When all the sets were extracted, there’s an information screen letting the user know that the new system can now be configured. While in theory the process could be streamlined and this screen be dropped, the completion of the data transfer is probably significant enough to warrant it.

Set extraction complete

System configuration

The first thing that the installer lets you do to configure the system is setting a root password. While this is not technically necessary, basically everybody will want to do that, so it’s a logical choice to present it automatically.

Setting the root password

Afterwards, sysinst presents a very nice configuration menu with various options that allow for convenient configuration of some basics. The “Configure additional items as needed.” would be fine – if all options were self-explanatory. For newcomers however, they aren’t. I would suggest changing “Enable xdm” to “Enable xdm (X11 display manager)”, “Enable cgd” to “Enable cgd (cryptographic disk driver)” and “Enable lvm” to “Enable lvm (logical volume manager)”.

Configuration menu

You usually want to configure the network on your system. If you select the appropriate menu item, you get a list of detected interfaces to pick from. I’m going to make my usual suggestion here: Consider adding the MAC address for each interface!

While it’s often perfectly obvious which one you want to select, this is not always the case. I don’t know how often NetBSD is being deployed in datacenters these days, but servers often have several interfaces and it can be very beneficial for the admins to decide based on the MAC address which one is which (especially since you cannot expect penguins to be familiar with BSD interface naming!). 😉

Network interface selection

Next is selecting the network media type. Not setting it means attempting autoconfiguration. This is another case where sysinst gives me a weird feeling. From the presented information alone I have no clue if leaving it empty will cause the installer to send DHCP requests or if it’s just going to assume 1000baseT full duplex or something for the media type. Also making this a text input rather than a list to pick from automatically (pun intended) makes people wonder what the supported values are. This is not ideal from a UX perspective.

Setting the network media type

Even when leaving the field empty to enable autoconfiguration, a menu pops up asking you if that’s really what you wanted to do. That feels very redundant and is another strong indication that this section of the installer could use an overhaul.

Autoconfiguration?

After that, sysinst asks for the hostname of the machine. Since there’s no standard way of handling this, I always appreciate it when the installer provides a clue as to whether it expects an FQDN or the short form. As I have the habit of using the former, the first time I installed NetBSD I of course noticed my mistake in the next screen.

Hostname configuration

NetBSD expects the short form for the hostname, so in the next screen it asks for the domain name. If DHCP was used, it proposes the domain name it got from it. My suggestion would be to either indicate on the previous screen that only the short form is acceptable, or to indicate that either form is and to skip this screen if an FQDN was entered as the hostname.

Domain name configuration

In the next screen, sysinst will provide a summary of the network parameters and ask the user whether they are ok.

Network parameter summary

If the user accepts them, the installer offers to write the configuration to disk. This is super helpful for people new to NetBSD who will certainly enjoy a working network connection before having to dig into the documentation just for that! However there might be use cases where people use an installation network to access the distfiles while the actual production network settings are different. So I guess presenting the choice to the user is the right thing to do.

Make network configuration persistent?

Next is configuring the time zone. NetBSD defaults to UTC which is a sensible choice. Users who prefer localtime can select items from a list.

Time zone selection step 1

If a continent was chosen in step 1 (like Europe in my case), another list of zones in that area are now presented.

Time zone selection step 2

Choosing an item selects it and makes sysinst jump to the “Exit” menu item which is a nice convenience.

Time zone selection step 3

Most people will not want to use only the base system, so making the pkgin package manager available is something that is commonly done. Luckily sysinst makes doing this really easy. In this screen, the installer allows you to configure the remote repository, protocol to use and so on.

Configuring pkgin repository

Once repository access has been configured, sysinst installs pkgin and uses it to update the package summary.

Fetching the package summary

When that’s done, the installer lets you know that pkgin has been successfully installed.

Pkgin ready

Some people prefer to (or have to) build packages from source. Sysinst assists in installing the Pkgsrc tree on the system, too. Doing this is quite similar to the previous action: The user first needs to configure a remote source …

Preparing to fetch pkgsrc

… and then the compressed tarball is getting downloaded and extracted. Very convenient!

Fetching and installing pkgsrc

Another very common thing that a lot of people will want to do is creating an unprivileged user. This works without any fancy dialog windows by just asking for input of the name.

Adding a user

It then asks whether to add the user to the wheel group, which is excellent. For newcomers (especially from Linux) I’d love to see a little explanation that this means allowing the user to use the ‘su’ command to become root. Otherwise this is fine.

Add user to the wheel group?

Then you get to select which of the three shells that the base system provides to use. This works effectively.

Which shell for the new user?

Finally you are asked to set the password for the user. Altogether the process is pretty bare bones as you can neither customize the home directory nor can you pick the UID or assign the user to additional groups. But you can always create (or modify) users manually after booting into the installed system, right?

Password for user

There are other options here, but they are simply on/off switches. The last item is for finishing the configuration.

Finishing the configuration

The last screen after the installation gives new users some valuable advice like reading afterboot(8) (you installed the man set, right?) and customizing /etc/rc.conf.

Installation finished

After acknowledging this, the installer returns to the main menu, where you can choose to reboot into the newly installed system.

Back on the main menu for rebooting

Installation over serial

To explore more of the installer, this time I’m aiming for a more customized installation fit for a server.

To be able to install via serial, it’s necessary to escape to the loader prompt and then issue the command:

consdev com0,115200

Setting the console to serial in the loader

Changing the console to serial resets the terminal screen. Now it’s possible to just ask the loader to boot the kernel regularly:

boot

Booting the installation system

Just before the installer starts, it asks for the type of terminal that is connected. It needs to know this to make the best use of available features. I’m going with xterm here.

Terminal type selection

The first screen of the installer is the same as in the previous installation which used the video console.

Language selection

The same is true for the main menu …

Sysinst main menu

… and the information screen about the installation procedure.

Installation overview screen

I’ve given this machine two virtual drives, so this time I could choose which one to install to.

Selecting the installation target

While for the first installation I’ve taken the straight-forward path, this time I went with the extended partitioning. This portion of the installer allows for cryptographic volumes, virtual disk images, logical volume management and software raids in addition to more complex partitioning in general. The text contains the instructions to follow and works well for that matter.

Extended partitioning menu

Selecting one of the drives opens a menu with various configuration options. People who only ever go the standard path through the installer miss out on a lot of its capabilities! At least I was surprised by the many options when I first explored extended partitioning. Beforehand I considered sysinst to be quite limited, but that is obviously not the case.

Configuration options for a drive

I went with “Format as RAID”, but since the drive is empty, sysinst first asks about which partitioning schema to use. Your options here are GPT, MBR or BSD disklabels.

Selecting the partitioning schema

The installer went ahead and proposed a partition of type RAID for me. It would span the entire available space.

Proposed RAID partition

Accepting the the partition (going with the proposal or changing the size) takes you back to the partitioning menu. A new partition dk0 has appeared in the list and ld0’s status has changed to USED. (As a newcomer I ask myself what dk is, though. A search in the manpages does not solve the mystery.)

RAID partition created on the first drive

I did the same thing for the second drive and as expected, dk1 appeared.

Second RAID partition created

The next step is to select “Create Software RAID”, which opens a window with configuration options.

Software RAID configuration

Selecting “Disks:” lets the user add or remove disks from the RAID array.

Software RAID disk selection

Choosing “Add” allows to add members to the array. I think this is a little cumbersome, especially if you want to assemble a large RAID with several members. I would suggest getting rid of the window that’s used to add or remove disks and instead provide one where available disks can be marked as member or unused. That would streamline RAID creation.

Adding a disk

After adding disks dk0 and dk1 as RAID members and not selecting any spares, the next thing to do is to choose the RAID level. Sysinst obviously does not take disk requirements into account: It offers RAID 5 even though that requires three or more disks while only two were added. So that’s another thing that could be improved.

Selecting the RAID level

I went with creating a mirror. Besides selecting the disks to use and the RAID level I left everything else alone.

RAID configuration complete

The RAID configuration was done, but the list does not reflect that. The text said to select “Save Changes” after configuring a RAID, so that’s what needs to be done next.

RAID configured but not created, yet

What then happened again surprised me: The RAID is being built by supposedly writing parity information! This is very weird. I selected mirroring and RAID 1 does not use parity information – mirroring means having the same data on both drives after all! But this is probably raidctl(8)’s fault which simply calls mirrored data “parity” as well.

Building RAID: Syncing…

After the sync is complete, the new raid0 device appears in the list. According to the information it is a RAID 1 with two disks and 0 spares. It appears that what I intended to do has worked out.

RAID synced

Now the RAID can be partitioned like the disks beforehand. The same menu window is used for that. This time I go with editing the partitions.

Partitioning the RAID

The RAID array doesn’t contain any data, yet, so it needs a partitioning schema, first. It’s possible to use GPT or disklabels, here.

Partition schema selection for the array

Going with GPT, the user is then presented with an empty partition list and the option to add partitions.

Empty partition table

Adding a new partition presents the user with various options like partition type, size, mount point and so on.

Adding a new partition

Other than the default FFSv2, there are various other types that you can pick from. There’s also “other type” which opens another menu with less common options like vinum, FreeBSD’s old volume manager.

Partition types

I changed everything required to make this new partition be the EFI system partition required to boot from on EFI systems.

Values for an EFI partition

When creating a new partition for a filesystem that is going to be mounted, mount options can be selected.

Filesystem mount options

After adding a swap partition I added a third one for the root filesystem with the values shown on the screenshot below.

The root partition

While doing much more comprehensive partitioning is of course possible, I don’t think it’s necessary to do that here. A simple layout on a software RAID should be fine for the test system.

It appears that this section of the installer was re-used from the standard partitioning path. This is why the text says “This is your last chance to change” the partitions – which is not true. Accepting the partitioning returns you to the extended partition menu from where you could just choose to edit it again. It’s a small inaccuracy, though.

Partition table for raid0

The new partitions appear in the list on the main extended partitioning menu now. So everything is ready to proceed to the actual installation.

Extended partitioning done

The instructions didn’t say that the latest changes need to be saved again, but if you just try to go ahead, sysinst will simply ask you if you want to save or not.

Save partitioning changes?

Like in the previous installation, the next choice is the distribution sets to be installed. I’ll go for a custom installation this time.

Selecting the distribution sets

The standard selection of sets is fairly minimal. I would suggest to at least include the manpages by default!

Custom installation: Standard selection of sets

I chose to install the compiler toolchain (so that Pkgsrc would be usable) as well as the manpages (of course!) and miscellaneous (simply because I have no idea what’s in it).

Custom installation: A couple more sets enabled

To not simply repeat the first installation, I’m going with HTTP as the source for the sets instead of the local medium.

Installing over HTTP

This of course triggers network configuration which was only done after the installation in the previous attempt. I’m not providing screenshots of the other configuration steps as they are identical.

Selecting the network interface

After the network is configured, the mirror to fetch the sets from needs to be selected.

Selecting the mirror to use

And then the installation begins! Or not, since the filesystem for some reason turns out to be read-only …

Whoops! Disk is ro?!

Pain points

The above section ending rather abruptly is not due to any malice on my side trying to break poor little sysinst. In fact I tried to do several dozen installations over the past three weeks, trying out various setups. Truth be told: I’ve failed time and time again.

I didn’t mention it before, but after the first installation I wanted to show a screenshot of the graphical NetBSD system. The installation succeeded, but the system would panic during boot. Bhyve is more of a niche thing and not among the hypervisors supported by NetBSD, so I’m not complaining. But I haven’t been able to finish *any* installation after picking extended partitioning. Going with a software RAID makes the FS read-only. Trying to create a simple LVM lead to this:

Status: Command failed
Command: lvm pvcreate -ffy /dev/rdk2
Hit enter to continue
---
Device /dev/rdk2 not found (or ignored by filtering)

I read the first few chapters of The NetBSD Guide, hoping to better understand what I was doing wrong. It’s a good document but unfortunately pretty outdated, too. When I read “The examples from this chapter were created with NetBSD 8.0.”, I got a feeling what to expect (that version was released 7 years ago, in 2018).

I honestly don’t mind that the image explaining partitioning uses DOS as the other operating system in a dual-boot setup. But the guide does not even mention GPT at all! It’s all legacy MBR which is not terribly helpful for newer machines at this point. Also much to my surprise, the extended partitioning is not even covered. Yes, Software RAID, LVM and friends are covered, but only how to set them up via the CLI on a running system. Sorry, I don’t want to do that, I want to install to a more flexible means of storage than a bare disk with fixed partition sizes!

The system console messages appearing on the screen and messing up parts of the installer can be very annoying, too. Maybe just start sysinst on different virtual terminal to get rid of this?

Installing on real hardware presented me with other problems – and even standard installations can fail. On one machine it took incredibly long – the modules.txr.xz set alone took half an hour with the installation at times going to as slow writes as roughly 4 KiB/s or even stalling entirely. The base set took over 1.5 hours! I assume NetBSD might be struggling with the NVMe? To add insult to injury when it was finally done with all the sets (I had picked a full installation…), this was the result:

Status: Command failed
Command: /sbin/fsck_ffs -p -q /dev/dk0
Hit enter to continue
---
/dev/rdk0: BAD SUPER BLOCK: CAN'T FIND SUPERBLOCK

/dev/rdk0: UNEXPECTED INCONSISTENCY; RUN fsck_ffs MANUALLY.

I tried my luck in the opposite direction and used one of the older laptops that I have. The installer started regularly but at one point simply dropped me to a shell, saying “sysinst terminated.”

The error message was something along the lines of “Screen too narrow (70 + 5 > 64) for menu”. I was able to solve that by connecting a VGA monitor to it, but that was unexpected nevertheless. This little experiment proved useful, though, as it revealed a portion of sysinst that I had not seen before: The installer told me that this machine didn’t provide strong entropy and gave me several options for dealing with that. It’s really nice that NetBSD did great work in that regard!

Conclusion

Well, after all those problems I encountered, you might expect me to condemn sysinst. I won’t. In fact I like the general workflow – minus the weird parts. Sysinst has a lot of neat ideas in addition to some quirks. As mentioned at the beginning, I like the hotkey system a lot. Trying to reserve “x” to finish a screen is one nice detail. I really like the configuration options after the installation. That part is very well done.

On the other hand, network autoconfiguration is weird. I miss the option to decide on configuring the system for v4 only for example. A couple of things could certainly be improved, but few things are perfect. The elephant in the room though is the major problems that I ran into. I often find myself exploring less common paths in programs, which sometimes leads to uncovering bugs. It’s not just sysinst but it happens to me often when I use something not just superficially.

When I sat down to concern myself with the NetBSD installer, I expected that my major critique would be that it doesn’t do ZFS – which is a shame since the availability of that filesystem is one of the things that make NetBSD appeal to me. Various other problems have definitely overshadowed this, though. I remain hopeful that these issues can be addressed, and perhaps the solution lies in clearer guidance for users. As I said, I’m not very familiar with NetBSD. But I’d like to change that fact in the long run. And ideally at some point I’d be able to say: “Of course it runs NetBSD!”

What’s next?

In the next article I’ll take a closer look at DragonFly BSD’s installer.

kraileth
http://eerielinux.wordpress.com/?p=5134
Extensions
Installing *BSD in 2025 part 2 – A critical look at OpenBSD’s installer
bsdcomputerinstalleropenbsdoperating systemsoftware
[New to Gemini? Have a look at my Gemini FAQ.] This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt2.gmi [Edit: Of course this had to be published on the day that OpenBSD 7.7 was released!] This is the second part of the “installing BSD in 2025”. The first one was … Continue reading Installing *BSD in 2025 part 2 – A critical look at OpenBSD’s installer
Show full content

[New to Gemini? Have a look at my Gemini FAQ.]

This article was bi-posted to Gemini and the Web; Gemini version is here: gemini://gemini.circumlunar.space/users/kraileth/neunix/2025/installing_bsd_pt2.gmi

[Edit: Of course this had to be published on the day that OpenBSD 7.7 was released!]

This is the second part of the “installing BSD in 2025”. The first one was about FreeBSD’s installer.

In this article we’ll take a look at OpenBSD’s installer. The version used is the one that comes with release 7.6. Unlike FreeBSD, I don’t install OpenBSD all the time. I’ve done a fair amount of installations over the years, so I’m somewhat familiar with it. However not nearly as familiar that I could do an installation with my eyes closed. If you know everything about the OpenBSD installer (e. g. which username cannot be picked!), then you might want to read this article only if you’re interested in an outsider’s perspective.

Compared to FreeBSD, OpenBSD does a lot of things differently. Their installer is probably as much no-frills, no-nonsense as it could be. Instead of the dialog menu based one of FreeBSD, it simply asks you questions and you type in the answers.

I’m going to install OpenBSD in a VM twice. The first time I’ll be using the video console and opt for a graphical system. The second install will be a more server style one and will use installation over serial.

Installing a simple graphical OpenBSD system

I deliberately limited the VM that I’m using here to only 1GB of RAM, 1 CPU core and 8GB of disk space. This might seem like an odd choice for a desktop system – and to be honest it is. The rationale here is that I want to show that the installer is actually dynamic, accounting for what system resources are available. So these limitations are meant to allow me pointing out how things are different in the second installation.

OpenBSD installer options

After starting the install, a short paragraph explains the basic functionality to new users which is good. Especially the defaults allow for making it through the installer very quickly for the most common cases. At the same time the ability to shell out of the installer gives experienced OpenBSD users ultimate flexibility to do things that the installer won’t do on its own. It can do a lot, though.

The first thing to do is choosing the keymap. You either enter your preferred one or ask for a list if you don’t know what’s available. Then you enter the host name. The installer clearly indicates that it expects the short form rather than an FQDN which is great.

OpenBSD installer: Keymap, network, services and users

Next is the actual network configuration. The installer lists the configurable interfaces and even gives you the option to set up VLANs – which is not terribly common for installers to do. Selecting an interface you’ll be given the option to enter a static IPv4 address for it, attempt to automatically configure it or not use an IPv4 address. Afterwards the same is done for IPv6. If you choose to autoconfigure IPv4 or v6 for an interface, the installer uses the domain name and nameservers provided via DHCP.

These options are about excellent and cover the vast majority of scenarios perfectly. If you’re in need for advanced networking configurations involving things like link e. g. aggregation, you probably want to do that after the installation, anyway.

OpenBSD installer: time zone and disk selection

After the network configuration is done, you set the root password. Then the installer asks you which services to enable by default. On a desktop system you probably don’t want SSH but you want xenodm (OpenBSD’s variant of xdm). You also get the option to change the default console to serial as well as setting up a user (as long as it’s not named ‘yes’! 😉).

Next is setting up the time zone, then selecting the disk(s). The correct time zone has been determined in my case, but the installer assumes the first disk to be the install target. Usually that default should be fine, but in this case it isn’t. Fortunately by letting it display details first, you can see that sd0 is actually the hypervisor’s CD image that you’re installing from.

I remember having to do it manually, but for a while now, the installer has supported full disk encryption (which is very useful). After these selections, the partitioning scheme needs to be selected. Depending on the platform, the installer offers whole disk MBR and GPT or manual for people who want to dual-boot or have other reasons for not dedicating the whole disk to OpenBSD.

OpenBSD installer: Partitioning and installation source

Once the partitioning scheme has been decided on, the installer will propose a partitioning layout, offering the user to just accept that, modify it or do custom partitioning. This is all pretty intuitive if you stick to the defaults and flexible if you want to customize things. The only thing I actually miss in this part of the installer is that it does not allow for creating a softraid mirror (you have to shell out for this if I’m not mistaken and overlooked something). Take a look at the rather simple layout proposed in the screenshot above and take a mental note of it. We’ll come back to this in the second installation.

After the partitioning is done and the filesystems were created, the installer asks for the installation source. The defaults are usually fine but you’ve got other options like using a proxy or getting the distribution files from a local disk or via NFS instead of from HTTPS (even though the installer for historical reasons says HTTP). Once upon a time, installation via FTP was already possible but that option is long gone.

OpenBSD installer: Distribution set selection and fetching

When the installation source has been decided on, the applicable distribution sets found are listed. A full installation is the default but the user can easily de-select single ones or multiple (using patterns). For this desktop-style installation I’m going to install everything.

Up until a while ago, the installer would warn you that the install medium that you’re using cannot be fully trusted since the signature it comes with might have been tempered with. This was the main difference between the physical CDs you could buy and the downloaded ISOs. However the CDs have not been available for years. Since the introduction of signify(1), the CDs used to include the cryptographic signatures for the current and for the next release. So you can still dig out your 6.0 CDs, extract the key for 6.1 and build a chain of trust all the way up to where we are now. However most people probably just check the SHA265 for the image they downloaded and trust that their mirror provider didn’t fall for a sophisticated attack that would result in a modified ISO for which the checksum still matches…

OpenBSD installer: Actual installation and finishing tasks

When the actual installation is done, the installer will let you know if your time is off and offer to correct it. It then writes the configuration bits you selected before, creates device nodes, updates firmware and relinks the kernel before offering you to reboot the system. The latter hasn’t always been the default but became it quite some dime ago.

OpenBSD: installed system has started to graphical mode

Simply answering these couple of questions results in a basic graphical install of OpenBSD, which I think is pretty nice.

Installing a server via serial console

To be able to install via serial, the console has to be changed at the boot loader prompt:

probing: pc0 com0 com1 mem[640K 3046M 20K 948K 16M 3M 1024M]
disk: hd0 hd1*
>> OpenBSD/amd64 BOOTX64 3.67
boot> set tty com0
switching console to com0

>> OpenBSD/amd64 BOOTX64 3.67
boot> boot

Afterwards boot works just like normal:

cannot open hd0a:/etc/random.seed: No such file or directory
booting hd0a:/bsd: 4101039+1721344+3887112+0+704512 [109+465408+318888]=0xab0b98
entry point at 0x1001000
Copyright (c) 1982, 1986, 1989, 1991, 1993
	The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2024 OpenBSD. All rights reserved.  https://www.OpenBSD.org

OpenBSD 7.6 (RAMDISK_CD) #326: Mon Sep 30 09:00:03 MDT 2024
    deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/RAMDISK_CD
real mem = 4252692480 (4055MB)
avail mem = 4119609344 (3928MB)
random: good seed from bootblocks
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.8 @ 0xbfbcf000 (12 entries)
bios0: vendor BHYVE version "14.0" date 10/17/2021
bios0: FreeBSD BHYVE
acpi0 at bios0: ACPI 5.1
acpi0: tables DSDT FACP APIC HPET MCFG SPCR BGRT
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i3-4160 CPU @ 3.60GHz, 3593.36 MHz, 06-3c-03
cpu0: cpuid 1 edx=9f8bfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SS,HTT,PBE> ecx=f6da7a17<SSE3,PCLMUL,DTES64,DS-CPL,SSSE3,SDBG,FMA3,CX16,xTPR,PCID,SSE4.1,SSE4.2,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,HV>
cpu0: cpuid 6 eax=4<ARAT>
cpu0: cpuid 7.0 ebx=7a9<FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID> edx=400<MD_CLEAR>
cpu0: cpuid d.1 eax=1<XSAVEOPT>
cpu0: cpuid 80000001 edx=2c100800<NXE,PAGE1GB,RDTSCP,LONG> ecx=21<LAHF,ABM>
cpu0: cpuid 80000007 edx=100<ITSC>
cpu0: MELTDOWN
cpu0: 32KB 64b/line 8-way D-cache, 32KB 64b/line 8-way I-cache, 256KB 64b/line 8-way L2 cache, 3MB 64b/line 12-way L3 cache
cpu0: apic clock running at 134MHz
cpu at mainbus0: not configured
ioapic0 at mainbus0: apid 0 pa 0xfec00000, version 11, 32 pins
acpihpet0 at acpi0: 16777216 Hz
acpiprt0 at acpi0: bus 0 (PC00)
acpipci0 at acpi0 PC00
com0 at acpi0 COM1 addr 0x3f8/0x8 irq 4: ns16550a, 16 byte fifo
com0: console
com1 at acpi0 COM2 addr 0x2f8/0x8 irq 3: ns16550a, 16 byte fifo
com2 at acpi0 COM3 addr 0x3e8/0x8 irq 4: ns16550a, 16 byte fifo
com3 at acpi0 COM4 addr 0x2e8/0x8 irq 3: ns16550a, 16 byte fifo
acpicmos0 at acpi0
"Bhyve_V_Gen_Counter_V1" at acpi0 not configured
"QEMU0002" at acpi0 not configured
cpu0: using VERW MDS workaround
pvbus0 at mainbus0: bhyve
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 vendor "AMD", unknown product 0x7432 rev 0x00
ahci0 at pci0 dev 2 function 0 "Intel 82801H AHCI" rev 0x00: msi, AHCI 1.3
ahci0: port 0: 6.0Gb/s
scsibus0 at ahci0: 32 targets
sd0 at scsibus0 targ 0 lun 0: <ATA, BHYVE SATA DISK, 001> t10.ATA_BHYVE_SATA_DISK_BHYVE-7412-398C-D234
sd0: 696MB, 512 bytes/sector, 1426368 sectors
virtio0 at pci0 dev 4 function 0 "Qumranet Virtio Storage" rev 0x00
vioblk0 at virtio0
scsibus1 at vioblk0: 1 targets
sd1 at scsibus1 targ 0 lun 0: <VirtIO, Block Device, >
sd1: 40960MB, 512 bytes/sector, 83886080 sectors
virtio0: msix per-VQ
virtio1 at pci0 dev 5 function 0 "Qumranet Virtio Network" rev 0x00
vio0 at virtio1, address 00:a0:98:92:12:3a
virtio1: msix per-VQ
unknown vendor 0xfb5d product 0x40fb (class display subclass VGA, rev 0x00) at pci0 dev 6 function 0 not configured
xhci0 at pci0 dev 30 function 0 "Intel 7 Series xHCI" rev 0x00: msi, xHCI 0.0
usb0 at xhci0: USB revision 3.0
uhub0 at usb0 configuration 1 interface 0 "Intel xHCI root hub" rev 3.00/1.00 addr 1
"Intel 82371SB ISA" rev 0x00 at pci0 dev 31 function 0 not configured
isa0 at mainbus0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0 mux 1
efifb0 at mainbus0: 1024x768, 32bpp
wsdisplay at efifb0 not configured
uhub0: device problem, disabling port 1
softraid0 at root
scsibus2 at softraid0: 256 targets
root on rd0a swap on rd0b dump on rd0b
WARNING: CHECK AND RESET THE DATE!
erase ^?, werase ^W, kill ^U, intr ^C, status ^T

Welcome to the OpenBSD/amd64 7.6 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? i

If the standard installation is selected, the usual short introduction is printed. Unlike with the video console, the installer asks about the capabilities of the connected terminal instead of the keymap before the hostname:

At any prompt except password prompts you can escape to a shell by
typing '!'. Default answers are shown in []'s and are selected by
pressing RETURN.  You can exit this program at any time by pressing
Control-C, but this can leave your system in an inconsistent state.

Terminal type? [vt220] xterm
System hostname? (short form, e.g. 'foo') puffy

The choice of vt220 as the default is interesting, especially since FreeBSD – despite using a more sophisticated dialog window installer – assumes baseline capabilities of the vt100 as the default.

Next is network configuration:

Available network interfaces are: vio0 vlan0.
Network interface to configure? (name, lladdr, '?', or 'done') [vio0] 
IPv4 address for vio0? (or 'autoconf' or 'none') [autoconf] 10.11.12.202
Netmask for vio0? [255.255.255.0] 
IPv6 address for vio0? (or 'autoconf' or 'none') [none] 
Available network interfaces are: vio0 vlan0.
Network interface to configure? (name, lladdr, '?', or 'done') [done] 
Default IPv4 route? (IPv4 address or 'none') 10.11.12.1
add net default: gateway 10.11.12.1
DNS domain name? (e.g. 'example.com') [my.domain] lab.lan
DNS nameservers? (IP address list or 'none') [none] 10.11.12.1

This time I chose static addressing to show off what that looks like. In this case the installer needs to ask about netmask, gateway and nameservers, of course.

Next is root password and enabled services. For a server I definitely want SSH but certainly not xenodm. So this time it looks like this:

Password for root account? (will not echo) 
Password for root account? (again) 
Start sshd(8) by default? [yes] 
Do you want the X Window System to be started by xenodm(1)? [no]

Since this is a serial installation, the default answer to the question about using com0 for the default console changed to ‘yes’ and accepting that, the user gets to select the baud rate for the serial connection:

Change the default console to com0? [yes] 
Available speeds are: 9600 19200 38400 57600 115200.
Which speed should com0 use? (or 'done') [9600] 115200

A baud rate of 9600 is a conservative default choice, but that’s what you can expect just about every serial connections to work with today. Most – but not all – will support higher speeds, though. But if you’re doing a serial installation, it’s a sensible assumption that you know this (or are willing to do some reading if you encounter this installer question).

Following this part is user creation and time zone selection:

Setup a user? (enter a lower-case loginname, or 'no') [no] kraileth
Full name for user kraileth? [kraileth]
Password for user kraileth? (will not echo)
Password for user kraileth? (again)
WARNING: root is targeted by password guessing attacks, pubkeys are safer.
Allow root ssh login? (yes, no, prohibit-password) [no]
What timezone are you in? ('?' for list) [Europe/Berlin]

Since SSH was enabled this time, there’s an additional question that is about remote root login. You almost certainly should not allow it, so ‘no’ is the only sane default here.

Next is selecting the disk(s) to use. This time I’m going to encrypt the disk, just to also show that off (it’s usually the better option for laptops than servers, but I wanted to do that in the serial install so I didn’t have to squeeze it into one of the screenshots of the pc0 console install):

Available disks are: sd0 sd1.
Which disk is the root disk? ('?' for details) [sd0] sd1
Encrypt the root disk with a (p)assphrase or (k)eydisk? [no] p

Configuring the crypto chunk sd1...

No valid MBR or GPT.
Use (W)hole disk MBR, whole disk (G)PT or (E)dit? [gpt]
Setting OpenBSD GPT partition to whole sd1...done.
New passphrase: 
Re-type passphrase: 
sd2 at scsibus2 targ 1 lun 0: <OPENBSD, SR CRYPTO, 006>
sd2: 40699MB, 512 bytes/sector, 83352975 sectors

These choices have made the installer create a crypto softraid which – in this case – is now available as an additional disk ‘sd2’ to install on:

Configuring the root disk sd2...

No valid MBR or GPT.
Use (W)hole disk MBR, whole disk (G)PT or (E)dit? [gpt]

I went with letting the installer create a gpt partition in this crypto drive and it suggests an automatically calculated layout for me:

Setting OpenBSD GPT partition to whole sd2...done.
The auto-allocated layout for sd2 is:
#                size           offset  fstype [fsize bsize   cpg]
  a:          1024.0M           532544  4.2BSD   2048 16384     1 # /
  b:          2971.0M          2629696    swap                    
  c:         40699.7M                0  unused                    
  d:          2432.8M          8714240  4.2BSD   2048 16384     1 # /tmp
  e:          3838.2M         13696512  4.2BSD   2048 16384     1 # /var
  f:          4391.0M         21557248  4.2BSD   2048 16384     1 # /usr
  g:          1024.0M         30549920  4.2BSD   2048 16384     1 # /usr/X11R6
  h:          5360.4M         32647072  4.2BSD   2048 16384     1 # /usr/local
  i:           260.0M               64   MSDOS                    
  j:          2626.2M         43625248  4.2BSD   2048 16384     1 # /usr/src
  k:          6144.0M         49003680  4.2BSD   2048 16384     1 # /usr/obj
  l:         10628.1M         61586592  4.2BSD   2048 16384     1 # /home
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] e

As you can see, this layout is more complex than the one used in the first installation. This doesn’t have anything to do with the crypto softraid, though. It’s because this time I allocated a decent amount of storage to the virtual hard disk (40G) vs. a very small one (8G) last time.

I decided to edit this layout, so I can show of what that looks like:

Label editor (enter '?' for help at any prompt)
sd2> ?
Available commands:
 ? | h    - show help                 n [part] - set mount point
 A        - auto partition all space  p [unit] - print partitions
 a [part] - add partition             q        - quit & save changes
 b        - set OpenBSD boundaries    R [part] - resize auto allocated partition
 c [part] - change partition size     r        - display free space
 D        - reset label to default    s [path] - save label to file
 d [part] - delete partition          U        - undo all changes
 e        - edit label description    u        - undo last change
 i        - modify disklabel UID      w        - write label to disk
 l [unit] - print disk label header   x        - exit & lose changes
 M        - disklabel(8) man page     z        - delete all partitions
 m [part] - modify partition

Suffixes can be used to indicate units other than sectors:
 'b' (bytes), 'k' (kilobytes), 'm' (megabytes), 'g' (gigabytes) 't' (terabytes)
 'c' (cylinders), '%' (% of total disk), '&' (% of free space).
Values in non-sector units are truncated to the nearest cylinder boundary.
sd2> d g

So the help explains what commands are available at the label editor prompt and what they do. I decide to remove partition ‘g’ from the proposed layout as I don’t plan on installing X11, anyway. After confirming my changes, the label is written and the respective filesystems are being created before giving me the option to prepare additional disks the same way:

sd2*> q
Write new label?: [y] 
/dev/rsd2a: 1024.0MB in 2097152 sectors of 512 bytes
6 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd2l: 10628.1MB in 21766336 sectors of 512 bytes
53 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
newfs: reduced number of fragments per cylinder group from 103680 to 103520 to enlarge last cylinder group
/dev/rsd2d: 2432.8MB in 4982272 sectors of 512 bytes
13 cylinder groups of 202.19MB, 12940 blocks, 25920 inodes each
/dev/rsd2f: 4391.0MB in 8992672 sectors of 512 bytes
22 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd2h: 5360.4MB in 10978176 sectors of 512 bytes
27 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd2k: 6144.0MB in 12582912 sectors of 512 bytes
31 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd2j: 2626.2MB in 5378432 sectors of 512 bytes
13 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
/dev/rsd2e: 3838.2MB in 7860736 sectors of 512 bytes
19 cylinder groups of 202.50MB, 12960 blocks, 25920 inodes each
Available disks are: sd0.
Which disk do you wish to initialize? (or 'done') [done]

When all the disks are prepared, the installer mounts the filesystems and moves on to selecting the installation source:

/dev/sd2a (d28b779fb8c39257.a) on /mnt type ffs (rw, asynchronous, local)
/dev/sd2l (d28b779fb8c39257.l) on /mnt/home type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd2d (d28b779fb8c39257.d) on /mnt/tmp type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd2f (d28b779fb8c39257.f) on /mnt/usr type ffs (rw, asynchronous, local, nodev)
/dev/sd2h (d28b779fb8c39257.h) on /mnt/usr/local type ffs (rw, asynchronous, local, nodev)
/dev/sd2k (d28b779fb8c39257.k) on /mnt/usr/obj type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd2j (d28b779fb8c39257.j) on /mnt/usr/src type ffs (rw, asynchronous, local, nodev, nosuid)
/dev/sd2e (d28b779fb8c39257.e) on /mnt/var type ffs (rw, asynchronous, local, nodev, nosuid)

Let's install the sets!
Location of sets? (disk http nfs or 'done') [http]

This time I’m going to let it display the mirror list for me:

HTTP proxy URL? (e.g. 'http://proxy:8080', or 'none') [none] 
HTTP Server? (hostname, list#, 'done' or '?') [ftp.fau.de] ?
     1	ftp.fau.de/pub/OpenBSD                      
     2	ftp.spline.de/pub/OpenBSD                             Berlin, Germany
     3	mirror.hs-esslingen.de/pub/OpenBSD                 Esslingen, Germany
     4	ftp.halifax.rwth-aachen.de/pub/OpenBSD                Aachen, Germany
     5	artfiles.org/openbsd                                 Hamburg, Germany
     6	ftp.hostserver.de/pub/OpenBSD                      Frankfurt, Germany
     7	ftp.fau.de/pub/OpenBSD                              Erlangen, Germany
     8	cdn.openbsd.org/pub/OpenBSD                              Fastly (CDN)
     9	cloudflare.cdn.openbsd.org/pub/OpenBSD               Cloudflare (CDN)
    10	mirror.leaseweb.com/pub/OpenBSD                        LeaseWeb (CDN)
    11	mirror.planetunix.net/pub/OpenBSD                    PlanetUnix (CDN)
    12	openbsd.as250.net/pub/OpenBSD                         AS250.net (CDN)
    13	mirror.aarnet.edu.au/pub/OpenBSD                  Canberra, Australia
    14	ftp2.eu.openbsd.org/pub/OpenBSD                       Vienna, Austria
    15	openbsd.c3sl.ufpr.br/pub/OpenBSD                     Curitiba, Brazil
    16	openbsd.ipacct.com/pub/OpenBSD                        Sofia, Bulgaria
    17	mirror.telepoint.bg/pub/OpenBSD                       Sofia, Bulgaria
    18	ftp.OpenBSD.org/pub/OpenBSD                           Alberta, Canada
    19	openbsd.cs.toronto.edu/pub/OpenBSD                Toronto, ON, Canada
    20	mirrors.aliyun.com/pub/OpenBSD                                  China
    21	mirrors.ucr.ac.cr/pub/OpenBSD                              Costa Rica
    22	mirrors.dotsrc.org/pub/OpenBSD                       Aalborg, Denmark
    23	mirror.group.one/pub/OpenBSD                      Copenhagen, Denmark
--More--

The list is displayed via a pager. I like how it contains just the information you care about – the number, the URL and the location. Here’s the rest of the pretty impressive list:

    24	ftp.fr.openbsd.org/pub/OpenBSD                          Paris, France
    25	ftp.lip6.fr/pub/OpenBSD                                 Paris, France
    26	mirrors.ircam.fr/pub/OpenBSD                            Paris, France
    27	mirror.ibcp.fr/pub/OpenBSD                               Lyon, France
    28	ftp.spline.de/pub/OpenBSD                             Berlin, Germany
    29	mirror.hs-esslingen.de/pub/OpenBSD                 Esslingen, Germany
    30	ftp.halifax.rwth-aachen.de/pub/OpenBSD                Aachen, Germany
    31	artfiles.org/openbsd                                 Hamburg, Germany
    32	ftp.hostserver.de/pub/OpenBSD                      Frankfurt, Germany
    33	ftp.fau.de/pub/OpenBSD                              Erlangen, Germany
    34	ftp.cc.uoc.gr/pub/OpenBSD                           Heraklion, Greece
    35	ftp.jaist.ac.jp/pub/OpenBSD                     Nomi, Ishikawa, Japan
    36	www.ftp.ne.jp/pub/OpenBSD                              Saitama, Japan
    37	ftp.riken.jp/pub/OpenBSD                    Wako-City, Saitama, Japan
    38	repo.jing.rocks/pub/OpenBSD                              Tokyo, Japan
    39	mirror.litnet.lt/pub/OpenBSD                        Kaunas, Lithuania
    40	mirror.ihost.md/pub/OpenBSD                         Chisinau, Moldova
    41	ftp.nluug.nl/pub/OpenBSD                     Utrecht, The Netherlands
    42	ftp.bit.nl/pub/OpenBSD                           Ede, The Netherlands
    43	mirror.laylo.nl/pub/OpenBSD                Amsterdam, The Netherlands
    44	mirror.businessconnect.nl/pub/OpenBSD      Amsterdam, The Netherlands
    45	mirror.fsmg.org.nz/pub/OpenBSD         Anycast within NZ, New Zealand
    46	ftp.eu.openbsd.org/pub/OpenBSD                           Oslo, Norway
    47	ftp.icm.edu.pl/pub/OpenBSD                             Warsaw, Poland
    48  ftp.psnc.pl/pub/OpenBSD                                Poznan, Poland
    49  ftp.rnl.tecnico.ulisboa.pt/pub/OpenBSD               Lisbon, Portugal
    50	mirrors.chroot.ro/pub/OpenBSD                      Bucharest, Romania
    51	mirrors.pidginhost.com/pub/OpenBSD                 Bucharest, Romania
    52	mirror.yandex.ru/pub/OpenBSD                           Moscow, Russia
    53	mirror.freedif.org/pub/OpenBSD                              Singapore
    54	mirror.raiolanetworks.com/pub/OpenBSD                   Madrid, Spain
    55	ftp.lysator.liu.se/pub/OpenBSD                      Linkoping, Sweden
    56	mirror.ungleich.ch/pub/OpenBSD               Linthal, GL, Switzerland
    57	openbsd.paket.ua/pub/OpenBSD                           Odesa, Ukraine
    58	openbsd.eu.paket.ua/pub/OpenBSD                               Ukraine
    59	www.mirrorservice.org/pub/OpenBSD                Kent, United Kingdom
    60	mirror.ox.ac.uk/pub/OpenBSD                    Oxford, United Kingdom
    61	mirrors.sonic.net/pub/OpenBSD                  San Francisco, CA, USA
    62	mirrors.ocf.berkeley.edu/pub/OpenBSD                Berkeley, CA, USA
    63	mirrors.gigenet.com/pub/OpenBSD            Arlington Heights, IL, USA
    64	plug-mirror.rcac.purdue.edu/pub/OpenBSD       West Lafayette, IN, USA
    65	mirrors.mit.edu/pub/OpenBSD                        Cambridge, MA, USA
    66	openbsd.mirror.constant.com/pub/OpenBSD           Piscataway, NJ, USA
    67	ftp.usa.openbsd.org/pub/OpenBSD                     New York, NY, USA
    68	openbsd.mirrors.hoobly.com/pub/OpenBSD            Pittsburgh, PA, USA
    69	cdn.openbsd.org/pub/OpenBSD                               Fastly (CDN)
    70	cloudflare.cdn.openbsd.org/pub/OpenBSD                Cloudflare (CDN)
    71	mirror.leaseweb.com/pub/OpenBSD                         LeaseWeb (CDN)
    72  mirror.planetunix.net/pub/OpenBSD                     PlanetUnix (CDN)
    73	openbsd.as250.net/pub/OpenBSD                          AS250.net (CDN)
    74	mirror.aarnet.edu.au/pub/OpenBSD                   Canberra, Australia
    75	ftp2.eu.openbsd.org/pub/OpenBSD                        Vienna, Austria
    76	openbsd.c3sl.ufpr.br/pub/OpenBSD                      Curitiba, Brazil
    77	openbsd.ipacct.com/pub/OpenBSD                         Sofia, Bulgaria
    78	mirror.telepoint.bg/pub/OpenBSD                        Sofia, Bulgaria
    79	ftp.OpenBSD.org/pub/OpenBSD                            Alberta, Canada
    80	openbsd.cs.toronto.edu/pub/OpenBSD                 Toronto, ON, Canada
    81	mirrors.aliyun.com/pub/OpenBSD                                   China
    82	mirrors.ucr.ac.cr/pub/OpenBSD                               Costa Rica
    83	mirrors.dotsrc.org/pub/OpenBSD                        Aalborg, Denmark
    84	mirror.group.one/pub/OpenBSD                       Copenhagen, Denmark
    85	ftp.fr.openbsd.org/pub/OpenBSD                           Paris, France
    86	ftp2.fr.openbsd.org/pub/OpenBSD                          Paris, France
    87	mirrors.ircam.fr/pub/OpenBSD                             Paris, France
    88	ftp.spline.de/pub/OpenBSD                              Berlin, Germany
    89	mirror.hs-esslingen.de/pub/OpenBSD                  Esslingen, Germany
    90	ftp.halifax.rwth-aachen.de/pub/OpenBSD                 Aachen, Germany
    91	artfiles.org/openbsd                                  Hamburg, Germany
    92	ftp.hostserver.de/pub/OpenBSD                       Frankfurt, Germany
    93	ftp.fau.de/pub/OpenBSD                               Erlangen, Germany
    94	mirror.junda.nl/pub/OpenBSD                       Falkenstein, Germany
    95  ftp.cc.uoc.gr/pub/OpenBSD                            Heraklion, Greece
    96	ftp.jaist.ac.jp/pub/OpenBSD                      Nomi, Ishikawa, Japan
    97	www.ftp.ne.jp/pub/OpenBSD                               Saitama, Japan
    98	ftp.riken.jp/pub/OpenBSD                     Wako-City, Saitama, Japan
    99	repo.jing.rocks/pub/OpenBSD                               Tokyo, Japan
   100	mirror.litnet.lt/pub/OpenBSD                         Kaunas, Lithuania
   101	mirror.ihost.md/pub/OpenBSD                          Chisinau, Moldova
   102	ftp.nluug.nl/pub/OpenBSD                      Utrecht, The Netherlands
   103	ftp.bit.nl/pub/OpenBSD                            Ede, The Netherlands
   104	mirror.fsmg.org.nz/pub/OpenBSD          Anycast within NZ, New Zealand
   105	ftp.uio.no/pub/OpenBSD                                    Oslo, Norway
   106	ftp.eu.openbsd.org/pub/OpenBSD                            Oslo, Norway
   107	mirror.rise.ph/pub/OpenBSD                           Cebu, Philippines
   108	ftp.icm.edu.pl/pub/OpenBSD                              Warsaw, Poland
   109	ftp.psnc.pl/pub/OpenBSD                                 Poznan, Poland
   110	ftp.rnl.tecnico.ulisboa.pt/pub/OpenBSD                Lisbon, Portugal
   111	mirrors.chroot.ro/pub/OpenBSD                       Bucharest, Romania
   112	mirrors.pidginhost.com/pub/OpenBSD                  Bucharest, Romania
   113	mirror.yandex.ru/pub/OpenBSD                            Moscow, Russia
   114	mirror.freedif.org/pub/OpenBSD                               Singapore
   115	mirror.raiolanetworks.com/pub/OpenBSD                    Madrid, Spain
   116	ftp.lysator.liu.se/pub/OpenBSD                       Linkoping, Sweden
   117	mirror.ungleich.ch/pub/OpenBSD                Linthal, GL, Switzerland
   118  openbsd.paket.ua/pub/OpenBSD                            Odesa, Ukraine
   119	openbsd.eu.paket.ua/pub/OpenBSD                                Ukraine
   120	www.mirrorservice.org/pub/OpenBSD                 Kent, United Kingdom
   121	mirror.ox.ac.uk/pub/OpenBSD                     Oxford, United Kingdom
   122	mirrors.sonic.net/pub/OpenBSD                   San Francisco, CA, USA
   123	mirrors.ocf.berkeley.edu/pub/OpenBSD                 Berkeley, CA, USA
   124	mirrors.syringanetworks.net/pub/OpenBSD                 Boise, ID, USA
   125	mirrors.gigenet.com/pub/OpenBSD             Arlington Heights, IL, USA
   126	plug-mirror.rcac.purdue.edu/pub/OpenBSD        West Lafayette, IN, USA
   127	mirrors.mit.edu/pub/OpenBSD                         Cambridge, MA, USA
   128	openbsd.mirror.constant.com/pub/OpenBSD            Piscataway, NJ, USA
   129	ftp.usa.openbsd.org/pub/OpenBSD                      New York, NY, USA
   130	openbsd.mirrors.hoobly.com/pub/OpenBSD             Pittsburgh, PA, USA

Alright, let’s go on with the installation, picking a mirror close to me and then selecting the sets:

HTTP Server? (hostname, list#, 'done' or '?') [ftp.fau.de] 92
HTTP Server? (hostname, list#, 'done' or '?') [ftp.hostserver.de] 
Server directory? [pub/OpenBSD/7.6/amd64] 

Select sets by entering a set name, a file name pattern or 'all'. De-select
sets by prepending a '-', e.g.: '-game*'. Selected sets are labelled '[X]'.
    [X] bsd           [X] base76.tgz    [X] game76.tgz    [X] xfont76.tgz
    [X] bsd.mp        [X] comp76.tgz    [X] xbase76.tgz   [X] xserv76.tgz
    [X] bsd.rd        [X] man76.tgz     [X] xshare76.tgz
Set name(s)? (or 'abort' or 'done') [done] -x*
    [X] bsd           [X] base76.tgz    [X] game76.tgz    [ ] xfont76.tgz
    [X] bsd.mp        [X] comp76.tgz    [ ] xbase76.tgz   [ ] xserv76.tgz
    [X] bsd.rd        [X] man76.tgz     [ ] xshare76.tgz
Set name(s)? (or 'abort' or 'done') [done]

Pay attention how it offers ‘bsd.mp’ here which was not available in the previous installation. This is the SMP kernel and it’s available since this VM has multiple cores whereas the previous one didn’t. I don’t know when this was changed, but I remember being offered the SMP kernel on single-core systems in the past. So definitely a nice little new feature.

I chose to de-select all the X11-related sets for this example, which is very convenient to do. After this, the installer fetches the selected sets and extracts them into the filesystem hierarchy:

Get/Verify SHA256.sig   100% |**************************|  2324       00:00    
Signature Verified
Get/Verify bsd          100% |**************************| 28007 KB    00:20    
Get/Verify bsd.mp       100% |**************************| 28139 KB    00:21    
Get/Verify bsd.rd       100% |**************************|  4600 KB    00:03    
Get/Verify base76.tgz   100% |**************************|   414 MB    05:40    
Get/Verify comp76.tgz   100% |**************************| 81512 KB    01:06    
Get/Verify man76.tgz    100% |**************************|  8039 KB    00:06    
Get/Verify game76.tgz   100% |**************************|  2746 KB    00:02    
Get/Verify BUILDINFO    100% |**************************|    54       00:00    
Installing bsd          100% |**************************| 28007 KB    00:00    
Installing bsd.mp       100% |**************************| 28139 KB    00:00    
Installing bsd.rd       100% |**************************|  4600 KB    00:00    
Installing base76.tgz   100% |**************************|   414 MB    01:47    
Extracting etc.tgz      100% |**************************|   264 KB    00:00    
Installing comp76.tgz   100% |**************************| 81512 KB    00:26    
Installing man76.tgz    100% |**************************|  8039 KB    00:05    
Installing game76.tgz   100% |**************************|  2746 KB    00:00    
Installing BUILDINFO    100% |**************************|    54       00:00    
Location of sets? (disk http nfs or 'done') [done]

It’s possible to select additional sets from another installation source, but I assume that’s rarely done. As the final step, tne installer offers to correct the system time and does the final tasks on its own before asking if the user wants to shell into the new system, halt it or reboot:

Time appears wrong.  Set to 'Fri Apr 25 21:46:55 CEST 2025'? [yes] 
Saving configuration files... done.
Making all device nodes... done.
Multiprocessor machine; using bsd.mp instead of bsd.
fw_update: add intel; update none
Relinking to create unique kernel... done.

CONGRATULATIONS! Your OpenBSD install has been successfully completed!

When you login to your new system the first time, please read your mail
using the 'mail' command.

Exit to (S)hell, (H)alt or (R)eboot? [reboot]
syncing disks... done
rebooting...

And with that we’re done! Here’s the beginning of the boot sequence of the installed system just to show that full disk encryption works:

probing: pc0 com0 com1 mem[640K 3046M 20K 948K 16M 3M 1024M]
disk: hd0 hd1* sr0*
>> OpenBSD/amd64 BOOTX64 3.67
Passphrase:
switching console to com0
>> OpenBSD/amd64 BOOTX64 3.67
boot> 
booting sr0a:/bsd: 20023253+4322312+417824+0+1241088 [1537351+128+1399416+1094998]=0x1ca7998
entry point at 0x1001000
[ using 4032920 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
	The Regents of the University of California.  All rights reserved.
Copyright (c) 1995-2024 OpenBSD. All rights reserved.  https://www.OpenBSD.org

OpenBSD 7.6 (GENERIC.MP) #338: Mon Sep 30 08:55:35 MDT 2024
[...]
Conclusion

How do they say? “Simplicity is the ultimate sophistication”. OpenBSD’s installer is a great example that there’s definitely some truth to this. If the purpose of the OS was to appeal to as many people as possible, I would highly recommend considering something a little more… mainstream. But that’s not a project goal and the system is developed for people who like what it does. So it makes perfect sense that the installer works as a simple collection of prompts to the user.

The defaults selected are all great, I wouldn’t change a thing there. But that’s to be expected, since the sane defaults approach is one of the core ideas behind OpenBSD.

Much earlier versions of the installer were a little hard to use, with the partitioning being something that required quite a bit of technical background. But that’s no longer the case. It’s also safe to say that the group of people that OpenBSD appeals to are above average in terms of *nix knowledge. They are much more likely to appreciate the simple installer than be put off by it.

I’m struggling to find much to critizise here to be honest. I’d like it to support setting up RAID1 and installing directly to mirrored disks, but that’s about all. Much of what could be in the installer doesn’t really have to since you’d typically tune it after the installation.

Final words on this: exceptional work, OpenBSD team! BTW: as a FreeBSD user, I really envy your ramdisk kernel every single time I install OpenBSD.

What’s next?

In the next article I’ll take a closer look at NetBSD’s installer.

kraileth
http://eerielinux.wordpress.com/?p=5015
Extensions