blog - git - desktop - contact
2026-09-18
I wanted to try something new and different. I'm running Linux for over 25 years now (and almost 20 years exclusively Linux on my PCs at home), my servers are on OpenBSD for almost ten years, and I had toyed with FreeBSD every now and then. And then there's the distant past with DOS, OS/2, and Windows, of course.
But NetBSD? Somehow slipped through the cracks.
So, how about NetBSD on my Netbook? Ha.
The netbook in question is my Samsung NC10 Plus from 2011:
CPU -- Integrated Intel Atom N455, 1x 1.6 GHz with HT
RAM -- 1 GiB DDR3
GFX -- Intel GMA 3150, 256 MiB Shared Memory
DSP -- 10.1", matte, 1024x600
HDD -- Samsung SSD 830, 256 GB, SATA
LAN -- Marvell 88E8040
WLAN -- Broadcom BCM4313
BT -- Broadcom (0a5c:219c)
WLAN being Broadcom will be a "problem" later.
In the story below, I went wrong a couple of times. My brain is extremely foggy these days (... weeks, months). This isn't a tutorial.
And sorry for the shoddy photos.
Table of contents:
I went with NetBSD-11.0-amd64-install.img, put it on a USB drive, and
launched the installer.
First order of business: NetBSD boots with a gigantic font, which is too large for the installer to work.
(I think I should report this, but I know nothing about the proper channels for that, yet. I'll get to it eventually.)
After a bit of help from a person called sirius_a on Mastodon, a workaround had been found. After the installer crashed, change the font and try again:
wsconsctl -dw font=Boldface
exit
Then continue with the installer. To persist a smaller font in the
installed system, /etc/wscons.conf needs to be adjusted a bit (later,
once the setup has finished, of course). I went with Terminus:
font Terminus16B-ISO8859-1 - - - /usr/share/wscons/fonts/ter-116b.wsf
setvar ttyE0 font Terminus16B-ISO8859-1
setvar ttyE1 font Terminus16B-ISO8859-1
setvar ttyE2 font Terminus16B-ISO8859-1
setvar ttyE3 font Terminus16B-ISO8859-1
Great! First installation finished and we have a working system.
(Looks like I forgot to configure the network settings, hm? Prompt doesn't show a hostname.)
/homeI use this netbook for taking notes and a bit of journalling, so an unencrypted drive isn't a great idea, in case I lose it. I thus went ahead and reinstalled it a few days later.
(Although, as I jokingly said to a coworker the other day: "Using the system is access control enough." Virtually nobody, especially not a thief, will know how to access my data on NetBSD -- or Linux, for that matter. I had a (different) coworker try to open a terminal window on my PC at work once, and he failed. Still, it's 2026, encryption is easy and it helps me sleep.)
I didn't bother with encrypting the system itself. /home is the only
relevant part in my case.
The installer offers to set up encrypted devices, but I wanted to learn a bit more on how to do this manually. That's the whole point, isn't it? I don't want a one-click solution.
My first idea was to just reinstall onto a smaller root partition and then set up the rest from the running system. I wanted to choose a traditional disklabel, because I didn't want to deal with the additional layer of abstraction of dk(4):
But either this is completely wrong (now that I'm checking that photo
again: partition a should not start at offset zero, should it?) or
there's a bug, because suddenly the install process was extremely slow
and sometimes stalled entirely:
This was from a USB drive, not over the network. I even tried a different drive. Maybe this would have finished eventually, but I didn't want to wait several hours.
Okay, so let's go with GPT instead. To be fair, the installer nudges you anyway to use this. I had to go out of my way to even select traditional disklabels.
The next screen was pretty confusing:
Isn't the c partition supposed to be "all available space" (or "all
available space in this wedge")? Why is /home there? I ignored this
and continued with the installation, which was now as fast as expected:
Once finished, the partition layout looks like this:
sleepy# dkctl wd0 listwedges
/dev/rwd0: 3 wedges:
dk0: 9f814d02-dd5a-40d7-bb26-8b4fa635fab4, 40960000 blocks at 2048, type: ffs
dk1: 1f3165aa-9868-4d52-8d5b-8d143bfa3304, 2076672 blocks at 40962048, type: swap
dk2: b95cf1f5-cac4-4054-b8a6-d423b1094d18, 457079439 blocks at 43038720, type: ffs
sleepy# df -h
Filesystem Size Used Avail %Cap Mounted on
/dev/dk0 19G 1.5G 16G 9% /
/dev/dk2 215G 4.0K 204G 1% /home
tmpfs 1.8G 4.0K 1.8G 1% /tmp
kernfs 1.0K 1.0K 0B 100% /kern
ptyfs 1.0K 1.0K 0B 100% /dev/pts
procfs 4.0K 4.0K 0B 100% /proc
tmpfs 253M 0B 253M 0% /var/shm
So there's no wd0a or something like that but the dk* devices on top
of it. That's what I wanted to avoid, but maybe this is more modern and
more "standard" now anyway? I don't know, I kept it. It's probably a
good thing after all, because I'm now getting to learn dk.
Okay, so, following the NetBSD cryptographic device driver guide, I created a CGD device and set a passphrase (there was nothing to backup/migrate and I didn't bother with wiping the device; I'm also not very well versed in cryptographic methods, so I kept the cipher from the example):
sleepy# umount /home
sleepy# cgdconfig -g -V gpt -o /etc/cgd/dk2 aes-cbc 256
pkcs5_pbkdf2: calibrating iterations............... done
sleepy# cgdconfig -V re-enter cgd0 /dev/dk2
/dev/dk2's passphrase:
re-enter device's passphrase:
The cgd0 device is a container that can be partitioned as well. Since
I'm coming from Linux, I had expected that I could instead just make a
filesystem directly on cgd0, but:
sleepy# newfs -O 2ea cgd0
newfs: /dev/rcgd0 partition type is not `4.2BSD'
Okay, as an excercise, let's create a tiny little disklabel -- in other words, basically a no-op, just use the "fictitious" label and write it to disk:
sleepy# disklabel -iI cgd0
Enter '?' for help
partition>P
4 partitions:
# size offset fstype [fsize bsize cpg/sgs]
a: 457079439 0 4.2BSD 0 0 0 # (Cyl. 0 - 223183*)
d: 457079439 0 unused 0 0 # (Cyl. 0 - 223183*)
partition>W
Label disk [n]?y
Label written
partition>Q
(I first suspected that this step is optional, because the a partition
existed anyway in the kernel's view? But see below, it's probably better
this way. I'm still not 100% sure that this is correct, though:
Partition a is at offset zero again. Is that after the disklabel?
I'll check some other day.)
Anyway, now there's a filesystem:
sleepy# newfs -O 2ea cgd0a
/dev/rcgd0a: 223183.3MB (457079432 sectors) block size 32768, fragment size 4096
using 301 cylinder groups of 741.50MB, 23728 blks, 46848 inodes.
super-block backups (for fsck_ffs -b #) at:
192, 1518784, 3037376, 4555968, 6074560, 7593152, 9111744, 10630336, 12148928,
..................................................................................
-- edit: I wasn't happy with this situation, so I moved partition
cgd0a to offset 64, even though I think it should be fine (see second
paragraph in
fs(5),
the space at the beginning should be left untouched, I think). And I
switched to using just newfs -O 2, because I kept getting ALTERNATE
SUPERBLK(S) ARE INCORRECT in fsck when using 2ea. I also see this
in a VM. Will have to check some other day.
Editing /etc/fstab to contain this instead of the old line:
/dev/cgd0a /home ffs rw 1 2
Can we mount it now? Yep:
sleepy# mount /home
sleepy# df -h
Filesystem Size Used Avail %Cap Mounted on
/dev/dk0 19G 1.5G 16G 9% /
tmpfs 1.8G 4.0K 1.8G 1% /tmp
kernfs 1.0K 1.0K 0B 100% /kern
ptyfs 1.0K 1.0K 0B 100% /dev/pts
procfs 4.0K 4.0K 0B 100% /proc
tmpfs 253M 0B 253M 0% /var/shm
/dev/cgd0a 215G 4.0K 204G 1% /home
Okay, as some last steps, enable CGD during boot:
sleepy# cat /etc/cgd/cgd.conf
cgd0 /dev/dk2
sleepy# grep cgd /etc/rc.conf
cgd=YES
Does it survive a reboot? Yyyyyes ... Kind of ... ? No.
Did I mistype? Huh?
Okay. Boot from the USB drive again, mount the rootfs, clear
/etc/cgd/cgd.conf, disable cgd in /etc/rc.conf and comment out the
entry in /etc/fstab. The system boots normally again, no /home
mounted of course.
Can I unlock it now, from a normally running system?
sleepy# cgdconfig cgd0 /dev/dk2
/dev/dk2's passphrase:
cgdconfig: verification failed, please reenter passphrase
No.
(I could have and should have tried this before actually rebooting. I was feeling too confident, I guess. :-))
Where did I go wrong? Here:
sleepy# cgdconfig -g -V gpt -o /etc/cgd/dk2 aes-cbc 256
-V gpt sets the "verification method" to gpt and I didn't really
think about this earlier. "Hey, I use GPT, so this must be right." Nope,
the manual page
cgdconfig(8)
explains how this works:
Verification Method
The verification method is how cgdconfig determines if the generated key
is correct. [...] The following verification methods are supported:
none perform no verification.
disklabel scan for a valid disklabel.
mbr scan for a valid Master Boot Record.
gpt scan for a valid GUID partition table.
ffs scan for a valid FFS file system.
Scan for a GPT. In other words, CGD decrypts with whatever key you supplied and then searchs for something that looks like a GPT. (This is a little bit unexpected to me and the manual even lists probabilities for this to work, but as I said, I'm not a cryptographer -- I trust the smart people on this one.)
I didn't set up a GPT inside the CGD container, though, I used a disklabel. So obviously it can't find one.
This is the correct thing to do:
sleepy# cgdconfig -g -V disklabel -o /etc/cgd/dk2 aes-cbc 256
I re-setup the whole CGD device, but I suppose editing /etc/cgd/dk2
would have been sufficient.
(As you can see, this also lists ffs as a verification method, so a
filesystem without a disklabel or GPT should work, I guess.)
(I'd also assume that all this means that you can't ever change the passphrase? Short of, maybe, re-encrypting every block in-place, if there is such a tool? There's nothing like the "key slots" in LUKS?)
One final adjustment: The dk* devices are numbered across drives. So
if I haver happen to boot with a USB drive attached, it might happen
that /dev/dk2 is not the CGD device but something else entirely. To
improve this, let's rename/adjust the configs:
sleepy# mv /etc/cgd/dk2 /etc/cgd/homecgd
sleepy# dkctl wd0 listwedges | grep dk2
dk2: b95cf1f5-cac4-4054-b8a6-d423b1094d18, 457079439 blocks at 43038720, type: ffs
sleepy# cat /etc/cgd/cgd.conf
cgd0 NAME=b95cf1f5-cac4-4054-b8a6-d423b1094d18 /etc/cgd/homecgd
And, lo and behold, it survives a reboot now. I added a user and now we
have a running system with an encrypted /home and X11:
(While taking this last photo, I dropped the stupid phone onto the netbook and almost broke the display. Great, huh?)
Reading manual pages through more is a bit annoying, so I added this
to /etc/profile:
export PAGER=less
Bootstrapping pkgin, which is the recommended or at least
"user-friendly" tool these days
(NetBSD pkgsrc guide):
sleepy# PATH="/usr/pkg/sbin:/usr/pkg/bin:$PATH"
sleepy# PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages"
sleepy# PKG_PATH="$PKG_PATH/NetBSD/x86_64/11.0/All/"
sleepy# export PATH PKG_PATH
sleepy# pkg_add pkgin
(Setting these variables is a one-time thing.)
I also enabled xdm and wanted to keep the default ctwm setup for now, so:
sleepy$ grep xdm /etc/rc.conf
xdm=YES
sleepy$ ln -s /etc/X11/xinit/xinitrc .xsession
Here's the thing: I didn't care.
I had OpenBSD installed on the netbook a while ago and WLAN didn't work there as well. This sounds like it would be very annoying, but WLAN in my apartment is super bad anyway and/or I broke the netbook's WLAN antenna at some point in the past. Even on Linux, I had to use Ethernet all the time. So I'm used to it.
So far, I thoroughly enjoyed the whole process. It's a breeze of fresh air that I sorely needed.
For me, personally, it's a great balance between "a familiar system" (it's a UNIX system, I know this), "a modern featureful system" (it's not as minimal as OpenBSD), and "something I hadn't done before" (never ran it on a netbook or with encryption, only toyed with it in VMs).
I actually might just keep it -- not just as an experiment. Because there's another reason for me choosing NetBSD: They pride themselves with portability and that is going to be an issue for me soon-ish. My hardware is getting older and older, but it works just fine and I refuse to replace it just because there's something newer. I had already written about this a few years ago: Sooner or later, Arch Linux might drop support for my current CPU(s). The more experience I have with systems other than Arch, the better.
In general, I don't want to depend on Linux as much as I currently do. That's also one reason for running OpenBSD on my servers. Diversity is good: In life in general, and in the computing world as well.
Besides, NetBSD is super fast and snappy on that "tiny" computer. I love it.
As a side note: I forgot to plug in the power supply for a long time. Reinstalled several times, installed packages, copied lots of data, and then eventually: "System powering down, battery low!" Oops. But hey, that works!
One caveat to all this: I kept mistyping "CGD" as GCD while writing this blog post, it still hurts my brain a little, and I hope that I fixed all those mistakes. :-)
Just dumping data to /dev/ulpt0. The netbook doesn't have a parallel
port, so this must be done over USB. NetBSD.escp was created by a
little custom ESC/P converter written in C.
(NetBSD has a proper printing system. I just did it this way for fun. :-))