NetBSD Journey

Logging my quest into the NetBSD universe.

Saturday, August 13, 2011

Guruplug meets NetBSD step 5: IPv4 configuration and daemon startup.

At this point we have a Guruplug which boots NetBSD from a USB stick and which is more-or-less in order. We're still stuck with the serial line so let's just add some basic ip configuration to it so the unit will boot up, configure its ip address (in this case a static one) and launch an SSH daemon.

We will also take this opportunity to shut some of the services which we don't need and will only use scarce resources (and slow down booting).

The currently (by default running processes are, minus the login, ps and csh that is):

GURUPLUGGER# ps -aux
USER    PID %CPU %MEM  VSZ  RSS TTY   STAT STARTED    TIME COMMAND
root      0  3.0  1.4    0 7188 ?     DKl   1:00PM 0:38.74 [system]
root      1  0.0  0.2 3448  892 ?     Ss    1:00PM 0:00.04 init 
root    182  0.0  0.3 5596 1348 ?     Is    1:00PM 0:00.06 /usr/sbin/syslogd -s
postfix 412  0.0  0.4 7644 2220 ?     I     1:00PM 0:00.09 pickup -l -t fifo -u
root    418  0.0  0.4 7652 2220 ?     Is    1:00PM 0:00.12 /usr/libexec/postfix
root    454  0.0  0.2 3488  952 ?     Is    1:00PM 0:00.02 /usr/sbin/cron 
postfix 477  0.0  0.4 7644 2260 ?     I     1:00PM 0:00.08 qmgr -l -t unix -u 
root    484  0.0  0.2 3528  804 ?     Is    1:00PM 0:00.01 /usr/sbin/inetd -l 
root    113  0.0  0.2 3524  852 tty00 O+    1:36PM 0:00.01 ps -aux 
root    491  0.0  0.4 7228 2172 tty00 Is    1:00PM 0:00.52 login 
root    517  0.2  0.2 3288 1024 tty00 S     1:20PM 0:00.07 -csh 

So we will remove cron, postfix and inetd from the startup, only allowing syslog to start up and we will also add an sshd to that list.

This is done through editing /etc/rc.conf and we can look in /etc/defaults/rc.conf for some inspiration.

I've seen some kernel warnings in the past, which result in myself not trusting the RTC for timekeeping when the unit is off hence I'll add an ntpdate(8) to execute just once at boottime followed by the startup of an ntpd(8). Meaning rc.conf looks as follows:

# Load the defaults in from /etc/defaults/rc.conf (if it's readable).
# These can be overridden below.
#
if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
fi

# If this is not set to YES, the system will drop into single-user mode.
#
rc_configured=YES

# Add local overrides below
#

hostname="GURUPLUGGER"

# Do not start some default daemons
cron=NO
inetd=NO
postfix=NO

# Do start SSH
sshd=YES

# Launch an ntpdate at boottime prior to starting the ntpd
ntpdate=YES
ntpdate_flags="-b -s pool.ntp.org"
ntpd=YES

If we would want to launch a dhclient at boottime on the first gigabit device we would add, the following line to rc.conf:
dhclient=YES
However, since this is a standalone box, I really want this box to have a static configuration.

Hence configuring the network will be done by adding the following lines to rc.conf:
auto_ifconfig=yes
ifconfig_mvgbe0="inet 192.168.10.2 netmask 0xffffff00" 
defaultroute="192.168.10.1"
Here mvgbe0 is the interface on which the configuration should be applied. Alternatively we could also have written the route to /etc/mygate and the interface specific things to /etc/ifconfig.mvgbe0 (ifconfig.if(5).

Next we add the nameservers to resolv.conf(5):
GURUPLUGGER# cat /etc/resolv.conf
nameserver 195.130.130.5
nameserver 195.130.131.5
And setup a default route, we can either write this in /etc/mygate or append the following to rc.conf:
defaultroute="192.168.10.1"

If we're adding an sshd, we also need to add a user (unless we modify the sshd config to permit root logins which is not a good idea). This can be done as follows:
GURUPLUGGER# useradd -m edb
GURUPLUGGER# passwd edb
Changing password for edb.
New Password:
Retype New Password:
GURUPLUGGER# usermod -G wheel edb
In the last step we added edb to the wheel group, this is required for the su(1) command to function.

And after a reboot we see that our mission has been accomplished, the network is propery configured, only the daemons we requested are running:
GURUPLUGGER# ifconfig mvgbe0                                            
mvgbe0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	capabilities=3700<IP4CSUM_Rx,IP4CSUM_Tx,TCP4CSUM_Rx,UDP4CSUM_Rx,UDP4CSUM_Tx>
	enabled=0
	address: f0:ad:4e:ff:11:d5
	media: Ethernet autoselect (100baseTX full-duplex)
	status: active
	inet 192.168.10.2 netmask 0xffffff00 broadcast 192.168.10.255
	inet6 fe80::f2ad:4eff:feff:11d5%mvgbe0 prefixlen 64 scopeid 0x1
GURUPLUGGER# netstat -rn -f inet
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use    Mtu Interface
default            192.168.10.1       UGS         1       73      -  mvgbe0
127/8              127.0.0.1          UGRS        0        0  33192  lo0
127.0.0.1          127.0.0.1          UH          1        0  33192  lo0
192.168.10/24      link#1             UC          2        0      -  mvgbe0
192.168.10.1       00:14:bf:8a:1b:c1  UHLc        1        0      -  mvgbe0
192.168.10.103     00:1d:e0:6f:b6:cf  UHLc        0       98      -  mvgbe0
GURUPLUGGER# ps -aux                     
USER PID %CPU %MEM  VSZ  RSS TTY   STAT STARTED    TIME COMMAND
root   0  0.0  1.4    0 7288 ?     DKl  12:27PM 0:00.40 [system]
root   1  0.0  0.2 3448  968 ?     Is   12:27PM 0:00.04 init 
root 195  0.0  0.3 5596 1356 ?     Ss   12:27PM 0:00.06 /usr/sbin/syslogd -s 
root 324  0.0  1.0 5340 5224 ?     Ss   12:28PM 0:00.33 /usr/sbin/ntpd 
root 344  0.0  0.4 8196 1996 ?     Is   12:28PM 0:00.02 /usr/sbin/sshd 
root 108  0.0  0.2 3524  976 tty00 O+   12:33PM 0:00.01 ps -aux 
root 326  0.0  0.5 7228 2432 tty00 Is   12:28PM 0:00.51 login 
root 398  0.0  0.2 3288 1176 tty00 S    12:29PM 0:00.05 -csh 

References:

Sunday, August 7, 2011

Guruplug meets NetBSD step 4: A closer look at our rootfs creation

In the second step I started from a distribution build in build.sh this was an unprivileged build and I used this build to populate my rootfs by passing through a tarball. Initially this has worked but it exhibited some fundamental problems which are side-effects of my hackish approach there.

An unprivileged build creates the rootfs in desdir (obj/destdir.evbarm) and stores the permissions in a file called METALOG:

edb@lapedb:~/netbsd/src$ head -n 10 obj/destdir.evbarm/METALOG
. type=dir uname=root gname=wheel mode=0755
./.cshrc type=file uname=root gname=wheel mode=0555 size=1297 sha256=0f09961bfa5543fa7da2cf8836935d6459d3ae3180795b33e2d04c81536c10a9
./.profile type=file uname=root gname=wheel mode=0555 size=849 sha256=55bacdbebf6e16e4cebd76e48ead3875615fb9236f622dfded41843a2a4d8b14
./altroot type=dir uname=root gname=wheel mode=0755
./bin type=dir uname=root gname=wheel mode=0755
./bin/[ type=file uname=root gname=wheel mode=0555 size=12902 sha256=8af5ca258dbc6ff97b586ce0b9c7fae5f692d35e45db01b97844e123ccc649b3
./bin/cat type=file uname=root gname=wheel mode=0555 size=12546 time=1312632230.0 sha256=ad8ec94d65ca37c69aeeeddf88aa99e4cb2e318bfc23ef7b0d42417df9f29d53
./bin/chgrp type=link mode=0755 link=/sbin/chown
./bin/chio type=file uname=root gname=wheel mode=0555 size=16052 time=1312632230.0 sha256=579bf34f922708e10b2196edfa77f666e865748b41662b380d19c2ba64f51d5d
./bin/chmod type=file uname=root gname=wheel mode=0555 size=9906 time=1312632231.0 sha256=76aacc5979b482c04796b0c844b74d40d9f9d475f178e90871f0e783c1df63b8
...

In order to create a proper rootfilesystem the information stored in METALOG should also be applied otherwise just copying destdir over will look funny, (permission wise that is).


For some local testing I generated the binary installation sets (which will also contains the faulty permissions), to get to know which ones are there:

edb@lapedb:~/netbsd/src$ ./build.sh -j 2 -m evbarm -U -u sets 
...
edb@lapedb:~/netbsd/src$ ls -hal obj/releasedir/evbarm/binary/sets/
total 128M
drwxr-xr-x 2 edb edb 4.0K Aug  7 11:39 .
drwxr-xr-x 3 edb edb 4.0K Aug  7 11:37 ..
-rw-r--r-- 1 edb edb  453 Aug  7 11:39 MD5
-rw-r--r-- 1 edb edb 1.4K Aug  7 11:39 SHA512
-rw-r--r-- 1 edb edb  35M Aug  7 11:38 base.tgz
-rw-r--r-- 1 edb edb  56M Aug  7 11:39 comp.tgz
-rw-r--r-- 1 edb edb 396K Aug  7 11:38 etc.tgz
-rw-r--r-- 1 edb edb 3.2M Aug  7 11:38 games.tgz
-rw-r--r-- 1 edb edb  13M Aug  7 11:39 man.tgz
-rw-r--r-- 1 edb edb 3.4M Aug  7 11:39 misc.tgz
-rw-r--r-- 1 edb edb 1.2M Aug  7 11:39 modules.tgz
-rw-r--r-- 1 edb edb  13M Aug  7 11:39 tests.tgz
-rw-r--r-- 1 edb edb 3.4M Aug  7 11:39 text.tgz


And then I installed the rootfs to a local directory:
edb@lapedb:~/netbsd/src$ export DESTDIR=/home/edb/netbsd/src/obj/destdir.evbarm 
edb@lapedb:~/netbsd/src$ export RELEASEDIR=/home/edb/netbsd/src/obj/releasedir 
edb@lapedb:~/netbsd/src$ export INSTALLSETS="base comp etc games man misc modules tests text"  ./build.sh -j 2 -m evbarm -E  -U -u install=/tmp/blah

Here I repeat the DESTDIR and RELEASEDIR variables, since the -E (expert) flag of build.sh somehow removes these and then an UNPRIVED installation will take place in /tmp/blah, this will typically be a copy of DESTDIR (with the permissions set to a wrong value), but later on we can omit certain installation sets (games, modules, tests come to mind). But a next step is actually applying the permissions stored in the METALOG file, this can be done by using the mtree(8) command. On my host system
(Linux) it is not available, but it is luckily/obviously part of the toolchain:

edb@lapedb:~/netbsd/src$ sudo obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmtree -f obj/destdir.evbarm/METALOG -p /tmp/blah -N /tmp/blah/etc/ -u

Some comments:
  • sudo: since some binaries will need to end up with setuid privileges etc this needs to be done with elevated privileges.
  • -f: Reference to the METALOG file
  • -p: Path containing the root directory
  • -N: Use the user databases (passwd and friends) from this location, obviously from out target, this because my host does not per see need to have all users/groups referenced (e.g. wheel group isn't available on Linux, this while the METALOG references users and groups by name instead of by id
  • -u: Update the fields

Okay, so this would allow us to repopulate the partition on the USB stick we are using, however nothing forbids us to apply these settings on our running filesystem (post-mortem that is). So let's just give that a try.

GURUPLUGGER# mtree -f /METALOG -p / -u
...

And you will see it will fix the permissions of all files. (Along with all other anomalies in the filesystem, e.g. in the previous step we touched rc.conf and mtree will show that the hash has changed).

Saturday, August 6, 2011

Guruplug meets NetBSD step 3: Some cleaning up

So to summarize where we are at this point or the step of actions that are still required at this point to get the Guruplug booted to a shell prompt.
  • In U-boot we need to enter some magical commands
  • We needed to answer some of NetBSD's initial questions
  • At this point the rootfs is still unconfigured
And at this point we have a system which does something bit is not yet that close to the real stuff as we'd want it to be.

The first step we will do is not NetBSD specific but it just consists out of updating the U-boot environment variables so that the bootloader will automatically attempt loading NetBSD.

The printenv command will show you what the current U-boot environment variables are:
Marvell>> printenv
bootcmd=${x_bootcmd_ethernet}; ${x_bootcmd_usb}; ${x_bootcmd_kernel}; setenv bootargs ${x_bootargs} ${x_bootargs_root}; bootm 0x6400000;
bootdelay=3
baudrate=115200
x_bootcmd_ethernet=ping 192.168.2.1
x_bootcmd_usb=usb start
x_bootcmd_kernel=nand read.e 0x6400000 0x100000 0x400000
x_bootargs=console=ttyS0,115200
ethact=egiga0
ethaddr=F0:AD:4E:FF:11:D5
x_bootargs_root=root=/dev/sda1 rootdelay=10
stdin=serial
stdout=serial
stderr=serial

Environment size: 439/131068 bytes
Which variables are important here ?
  • bootcmd: This is the actual command U-boot will executed when it will start booting. And these rely on several sub-commands (the length of a U-boot command is limited, and making small changes over a serial line with limited text editing capabilities is not that great either, this is why it's split up in several subcommands).
  • bootdelay: The amount of time U-boot will wait for user input to start executing bootcmd

Hence I will just leave bootdelay at 3, giving me three seconds to do some manual override. But I will replace the entire bootcmd by my own (not using the x_... commands). This can be done as follows:

Marvell>> setenv bootcmd ping 1.2.3.4\; usb start\; fatload usb 0:1 0x100000 uImage \; bootm 0x100000
Marvell>> printenv
bootdelay=3
baudrate=115200
x_bootcmd_ethernet=ping 192.168.2.1
x_bootcmd_usb=usb start
x_bootcmd_kernel=nand read.e 0x6400000 0x100000 0x400000
x_bootargs=console=ttyS0,115200
ethact=egiga0
ethaddr=F0:AD:4E:FF:11:D5
x_bootargs_root=root=/dev/sda1 rootdelay=10
stdin=serial
stdout=serial
stderr=serial
bootcmd=usb start; fatload usb 0:1 0x100000 uImage ; bootm 0x100000

Environment size: 370/131068 bytes
Marvell>> saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x40000 -- 100% complete.
Writing to Nand... done

With
  • setenv : You set variable to value, do keep in mind to escape the ; or U-boot will interpret this as a sequence of commands instead of a value containing a sequence. Put value to an empty string to unset the variable.
  • saveenv: Save the entire U-boot environment to a designated sector in Flash (NAND flash in the case of the Guruplug, this is just a name value list protected with a CRC, the CRC is used at boottime to figure out if the environment is a valid one).
  • printenv: Shows the current environment variables. Keep in mind that variables are only written to flash after a saveenv, this means that a printenv will show the current state of the variables in memory, not that of the variables stored in flash.

IMPORTANT NOTE: The bootcommand starts with a ping 1.2.3.4, just a ping of a bogus IP address, if this is omitted then NetBSD will not be able detect the PHY and you will have no ethernet connectivity whatsoever.

Without ping U-boot:
mvgbec0 at mvsoc0 unit 0 offset 0x70000-0x73fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec0 port 0 not configured
mvgbec1 at mvsoc0 unit 1 offset 0x74000-0x77fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec1 port 0 not configured

With ping in U-boot:
mvgbec0 at mvsoc0 unit 0 offset 0x70000-0x73fff: Marvell Gigabit Ethernet Controller
mvgbe0 at mvgbec0 port 0 irq 11
mvgbe0: Ethernet address f0:ad:4e:ff:11:d5
makphy0 at mvgbe0 phy 0: Marvell 88E1149 Gigabit PHY, rev. 3
makphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseT, 1000baseT-FDX, auto
mvgbec1 at mvsoc0 unit 1 offset 0x74000-0x77fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec1 port 0 not configured


If we powercycle the unit now, then we will see it boot to the point where the NetBSD kernel starts prompting us for input:

Marvell>> reset
resetting ...


U-Boot 2009.11-rc1-00602-g8e6db3d (Dec 24 2009 - 03:11:17)
Marvell-Plug2

SoC:   Kirkwood 88F6281_A0
DRAM:  512 MB
NAND:  512 MiB
In:    serial
Out:   serial
Err:   serial
Net:   egiga0
88E1121 Initialized on egiga0
Hit any key to stop autoboot:  0 
(Re)start USB...
USB:   Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... 3 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found
reading uImage
......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

4980889 bytes read
## Booting kernel from Legacy Image at 00100000 ...
   Image Name:   netbsd
   Image Type:   ARM NetBSD Kernel Image (uncompressed)
   Data Size:    4980825 Bytes =  4.8 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
## Transferring control to NetBSD stage-2 loader (at address 00000000) ...

NetBSD/evbarm (sheevaplug) booting ...
Loaded initial symtab at 0xc0388ec8, strtab at 0xc03bf1e4, # entries 13786
pmap_postinit: Allocated 35 static L1 descriptor tables
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 5.99.55 (SHEEVAPLUG) #0: Wed Jul 13 17:57:19 CEST 2011
 edb@lapedb:/home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG
...

This actually solves the first goal, and brings us to our second goal. The NetBSD kernel is now asking us the following questions:
boot device: <unknown>
root device: sd0a
dump device (default sd0b): none
file system (default generic): ext2fs
root on sd0a
sd0: fabricating a geometry
warning: no /dev/console
init path (default /sbin/init): 

After this it knows where to find init, and what remains is part of our third goal. But the question remains, how are we able to tell NetBSD that it is fairly good idea to attempt to mount an ext2 formatted rootfs which we hid as /dev/sd0a and from that point starts executing /sbin/init ?

In the Linux world, the kernel would learn that information from the bootargs U-boot environment variable (see also the U-boot printenv output shown earlier).

The SHEEVAPLUG kernel configuration src/sys/arch/evbarm/conf/SHEEVAPLUG contains the following line:

config  netbsd  root on ? type ?

Let's change this into:

config  netbsd  root on sd0a type ext2fs

Which should already get us a bit further. Next we recompile it, and put the u-boot image on the USB stick and retry.

edb@lapedb:~/netbsd/src$ ./build.sh -j 2 -u -m evbarm kernel=SHEEVAPLUG
...
/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmkubootimage -A arm -T kernel -a 0x00008000 -n NetBSD/sheevaplug 5.99.55 -C none netbsd.bin netbsd.ub
 magic:       0x27051956
 time:        Sat Aug  6 17:14:25 2011
 size:        4415424
 load addr:   0x00008000
 entry point: 0x00008000
 data crc:    0x128165e8
 os:          2 (netbsd)
 arch:        2 (arm)
 type:        2 (kernel)
 comp:        0 (none)
 name:        NetBSD/sheevaplug 5.99.55
 header crc:  0xa6c200d2
/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmkubootimage -A arm -T kernel -a 0x00008000 -e 0x00800000 -n NetBSD/sheevaplug 5.99.55 -C none netbsd.bin netbsd-old.ub
 magic:       0x27051956
 time:        Sat Aug  6 17:14:25 2011
 size:        4415424
 load addr:   0x00008000
 entry point: 0x00800000
 data crc:    0x128165e8
 os:          2 (netbsd)
 arch:        2 (arm)
 type:        2 (kernel)
 comp:        0 (none)
 name:        NetBSD/sheevaplug 5.99.55
 header crc:  0xa14b2f1b
===> Kernels built from SHEEVAPLUG:
  /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd
===> build.sh ended:      Sat Aug  6 17:14:26 CEST 2011
===> Summary of results:
  build.sh command:    ./build.sh -j 2 -u -m evbarm kernel=SHEEVAPLUG
  build.sh started:    Sat Aug  6 17:14:05 CEST 2011
  NetBSD version:      5.99.55
  MACHINE:             evbarm
  MACHINE_ARCH:        arm
  Build platform:      Linux 2.6.39-2-686-pae i686
  HOST_SH:             /bin/sh
  TOOLDIR path:        /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686
  DESTDIR path:        /home/edb/netbsd/src/obj/destdir.evbarm
  RELEASEDIR path:     /home/edb/netbsd/src/obj/releasedir
  Updated makewrapper: /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmake-evbarm
  Building kernel without building new tools
  Building kernel:     SHEEVAPLUG
  Build directory:     /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG
  Kernels built from SHEEVAPLUG:
   /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd
  build.sh ended:      Sat Aug  6 17:14:26 CEST 2011
===> .
edb@lapedb:~/netbsd/src$ mount /dev/sdb1 /mnt/
edb@lapedb:~/netbsd/src$ sudo cp /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd     
netbsd         netbsd-old.ub  netbsd.bin     netbsd.bin.gz  netbsd.gdb     netbsd.gz.ub   netbsd.map     netbsd.ub      
edb@lapedb:~/netbsd/src$ sudo cp /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd.ub /mnt/uImage
edb@lapedb:~/netbsd/src$ umount /mnt/


And when we use this image, the startup gets a bit further again:
...
sd0 at scsibus0 target 0 lun 0: <USB, USB 2.0 Flash, 8.07> disk removable
sd0: fabricating a geometry
sd0: 1003 MB, 1003 cyl, 64 head, 32 sec, 512 bytes/sect x 2055680 sectors
boot device: <unknown>
root on sd0a dumps on sd0b
sd0: fabricating a geometry
warning: no /dev/console
init: copying out path `/sbin/init' 11
/etc/rc.conf is not configured.  Multiuser boot aborted.
Enter pathname of shell or RETURN for /bin/sh: 


This means that our first two goals are already completed, the bootloader and the kernel are already cooperating. At this point we lack some userland configuration, these a probably the files which get generated during a regular installation (rc.conf and passwd, shadow and friends come immediately to mind).


Now how do we prepare the filesystem ? Well I could start guessing and fixing things as we go (I actually started this way), but a more sensible approach is to just steal the flow from somewhere. And this somewhere is actually the installer, the installer (sysinst) is located in src/distrib/utils/sysinst and there is a file install.c which contains the function do_install() which will setup the partitioning but after that it gets interesting:
if (make_filesystems())
  return;

 if (make_fstab() != 0)
  return;

 if (md_post_newfs() != 0)
  return;

 /* Unpack the distribution. */
 if (get_and_unpack_sets(0, MSG_disksetupdone,
     MSG_extractcomplete, MSG_abortinst) != 0)
  return;

 if (md_post_extract() != 0)
  return;

 set_timezone();

 set_root_password();
 set_root_shell();

 sanity_check();

 md_cleanup_install();

 msg_display(MSG_instcomplete);

Deducing from this we will need to:
  • Create an fstab
  • Set the timezone, but when no timezone is set, the box will default to UTC, which sounds sensible enough to me.
  • Setup the root user (password and shell)
  • And sanity_check() actually calls enable_rc_conf() hence, cleanup rc.conf

So the first setup will consist out of setting up fstab, to make sure the partitions can be found. First we make sure our rootfs is mounted read-writeable
# mount /dev/sd0a /

And we create an /etc/fstab (inspired by src/distrib/utils/sysinst/disks.c and the files in src/share/examples/fstab).
# cat /etc/fstab
/dev/sd0a /  ext2fs rw  1 1
/dev/sd0b none  swap sw  0 0
/kern  /kern  kernfs rw  0 0
/proc  /proc  procfs rw  0 0
ptyfs  /dev/pts ptyfs rw  0 0
# mkdir /kern /proc 

After this (and after a reboot) the following is sufficient to setup mounts properly (this will be done automagically once rc.conf is configured):
# mount -a  
/dev/sd0a: file system not clean; please fsck(8)
# mount
/dev/sd0a on / type ext2fs (local)
tmpfs on /dev type tmpfs (union, local)
kernfs on /kern type kernfs (local)
procfs on /proc type procfs (local)
ptyfs on /dev/pts type ptyfs (local)


Next is setting up a password for root:
# passwd -l root
New password:
Retype new password:
If you would want to change the shell for root (the default in /etc/passwd is csh for root) you can use chpass -s /path/to/shell root where /etc/shells contains supported shells.

And last but not least we mark rc.conf and being properly set up, this is what keeping us away from booting properly into a multiuser system. For now it contains:

# cat /etc/rc.conf
#       $NetBSD: rc.conf,v 1.96 2000/10/14 17:01:29 wiz Exp $
#
# see rc.conf(5) for more information.
#
# Use program=YES to enable program, NO to disable it. program_flags are
# passed to the program on the command line.
#

# Load the defaults in from /etc/defaults/rc.conf (if it's readable).
# These can be overridden below.
#
if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
fi

# If this is not set to YES, the system will drop into single-user mode.
#
rc_configured=NO

# Add local overrides below
#

And we update this the following way:
# sed 's/rc_configured=NO/rc_configured=YES/' /etc/rc.conf > /tmp/rc.conf ; mv /tmp/rc.conf /etc/rc.conf 
# echo 'hostname="GURUPLUGGER"'>> /etc/rc.conf

(Note that at the end we also added the hostname, otherwise some additional warnings will appear while rebooting).

And now we reboot. And we see that now init really kicks in ! Starting from the detection of the rootfilesystem the output looks as follows:

root on sd0a dumps on sd0b
sd0: fabricating a geometry
WARNING: clock lost 2536 days
WARNING: using filesystem time
WARNING: CHECK AND RESET THE DATE!
warning: no /dev/console
init: copying out path `/sbin/init' 11
Sun Jul 24 10:01:46 UTC 2011
Starting root file system check:
/dev/rsd0a: file system is clean; not checking
swapctl: adding /dev/sd0b as swap device at priority 0
Starting file system checks:
Setting tty flags.
Setting sysctl variables:
ddb.onpanic: 1 -> 0
Starting network.
Hostname: GURUPLUGGER
IPv6 mode: host
Configuring network interfaces:.
Adding interface aliases:.
Building databases: dev, utmp, utmpx, services done
Starting syslogd.
Mounting all filesystems...
Clearing temporary files.
Creating a.out runtime link editor directory cache.
Checking quotas: done.
Setting securelevel: kern.securelevel: 0 -> 1
Starting virecover.
Checking for core dump...
savecore: no core dump
Starting local daemons:.
Updating motd.
postfix: rebuilding /etc/mail/aliases (missing /etc/mail/aliases.db)
Jul 24 10:02:02 GURUPLUGGER postfix/master[578]: fatal: open lock file /var/db/postfix/master.lock: cannot create file exclusively: Permission denied
Starting inetd.
Starting cron.
Sun Jul 24 10:02:02 UTC 2011

NetBSD/evbarm (GURUPLUGGER) (console)

login: root
Password:
Jul 24 10:02:14 GURUPLUGGER syslogd[182]: last message repeated 5 times
Jul 24 10:02:14 GURUPLUGGER login: ROOT LOGIN (root) on tty console
Jul 24 10:02:14 GURUPLUGGER login: /etc/login.conf: not owned by root
Last login: Sun Jul 24 09:56:11 2011 on console
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 5.99.55 (SHEEVAPLUG) #6: Sat Aug 6 17:14:12 CEST 2011

Welcome to NetBSD!

This system is running a development snapshot of the NetBSD operating system,
also known as NetBSD-current.  It is very possible that it has serious bugs,
regressions, broken features or other problems.  Please bear this in mind
and use the system with care.

You are encouraged to test this version as thoroughly as possible.  Should you
encounter any problem, please report it back to the development team using the
send-pr(1) utility (requires a working MTA).  If yours is not properly set up,
use the web interface at: http://www.NetBSD.org/support/send-pr.html

Thank you for helping us test and improve NetBSD.

Terminal type is vt100.                                                 
We recommend that you create a non-root account and use su(1) for root access.
GURUPLUGGER# 


In order to set the time we should use the date command (which apparently syncs the RTC as well, there doesn't seem to be a hwclock variant on NetBSD)

GURUPLUGGER# date 201108061940.15
Aug  6 19:40:15  date: date set by root
Sat Aug  6 19:40:15 UTC 2011
GURUPLUGGER# date
Sat Aug  6 19:40:18 UTC 2011
GURUPLUGGER# reboot 

This will remove the time warnings shown in the boot log.

But we achieved the from zero to login prompt without the need to do any typing.

Thursday, August 4, 2011

NetBSD goes git

According to The NetBSD Blog somebody has set up an automatic synchronization between the NetBSD CVS repositories and a git repository hosted at github. What interests me the most is the git copy of the src repository which can be found at: https://github.com/jsonn/src. Why prefer this over CVS ? Simple, just clone the repository and you can use git locally to commit your local changes and you'll have version control/history/diffs for your local work in the NetBSD tree.

Now how do we set this up locally ?

edb@lapedb:~/netbsd/git$ git clone http://github.com/jsonn/src.git
Cloning into src...
remote: Counting objects: 2913258, done.
remote: Compressing objects: 100% (826840/826840), done.
remote: Total 2913258 (delta 2353085), reused 2609790 (delta 2049617)
Receiving objects: 100% (2913258/2913258), 837.73 MiB | 2.02 MiB/s, done.
Resolving deltas: 100% (2353085/2353085), done.
edb@lapedb:~/netbsd/git$ cd src/
edb@lapedb:~/netbsd/git/src$ ls
BUILDING  Makefile.inc  bin       common  crypto  distrib  etc       extsrc  gnu      lib      regress  sbin   sys    tools    usr.sbin
Makefile  UPDATING      build.sh  compat  dist    doc      external  games   include  libexec  rescue   share  tests  usr.bin  x11
edb@lapedb:~/netbsd/git/src$ git status
# On branch trunk
nothing to commit (working directory clean)
edb@lapedb:~/netbsd/git/src$ git log | head 
commit 67570f9afcde1a61861eb4f26091764e41faf7b5
Author: mrg <mrg>
Date:   Thu Aug 4 00:52:49 2011 +0000

    switch sparc64 to GCC 4.5.3.

commit 62473a1fb983afc22917dc08f6b6a5a6bd692d1e
Author: he <he>
Date:   Wed Aug 3 22:19:31 2011 +0000


And we're good to go ! We can now perform local changes, import changes through github, put our local changes on a branch etc.

Sunday, July 24, 2011

Guruplug meets NetBSD part two: Temporary userland

In my previous post I illustrated how to go from zero to booting a kernel on a Guruplug server, my first post ended with what Linux users would call a kernel kernel panic, cannot open root device or which was in the case of NetBSD a more polite enter root device query.


At this point I want to take the entire system one step further. This means that at this point I will extend the Guruplug with a USB stick of 1 gigabyte. But my main point here is that I will not yet make use of any MTD-alike device (more specifically the internal NAND flash) nor will I make use of an NFS rootfs, at the end of this post I want something which can be booted standalone and which can later on be improved.

So continuing where I left the last time, first we start with bringing our CVS tree up to date, and rebuild the kernel (for more details on this last step, see my last blog post):
edb@lapedb:~/netbsd/src$ cvs update 
edb@lapedb:~/netbsd/src$ export HOST_CC=/usr/bin/gcc-4.5
edb@lapedb:~/netbsd/src$ export HOST_CXX=/usr/bin/g++-4.5
edb@lapedb:~/netbsd/src$ ./build.sh -j 2 -u -m evbarm kernel=SHEEVAPLUG
In my specific case the kernel version did not change, so I will simply reuse the kernel uImage which I created last time.

And in the next step the so-called distribution build will be triggered:

edb@lapedb:~/netbsd/src$ time ./build.sh -j 2 -U -u -m evbarm distribution 
===> build.sh command:    ./build.sh -j 2 -U -u -m evbarm distribution
===> build.sh started:    Sat Jul 23 10:20:34 CEST 2011
===> NetBSD version:      5.99.55
===> MACHINE:             evbarm
===> MACHINE_ARCH:        arm
===> Build platform:      Linux 2.6.39-2-686-pae i686
===> HOST_SH:             /bin/sh
===> TOOLDIR path:        /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686
===> DESTDIR path:        /home/edb/netbsd/src/obj/destdir.evbarm
===> RELEASEDIR path:     /home/edb/netbsd/src/obj/releasedir
===> Updated makewrapper: /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmake-evbarm
--- distribution ---
...
--- check_DESTDIR ---
--- checkflist ---
cd /home/edb/netbsd/src/distrib/sets &&  DESTDIR=/home/edb/netbsd/src/obj/destdir.evbarm  MACHINE=evbarm  MACHINE_ARCH=arm  AWK=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbawk  CKSUM=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbcksum  DB=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbdb  HOST_SH=/bin/sh  MAKE=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmake  MKTEMP=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmktemp  MTREE=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmtree  PAX=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbpax  COMPRESS_PROGRAM=gzip  PKG_CREATE=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbpkg_create  SED=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbsed  TSORT=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbtsort\ -q  /bin/sh /home/edb/netbsd/src/distrib/sets/checkflist  -L base  -M /home/edb/netbsd/src/obj/destdir.evbarm/METALOG.sanitised
make distribution started at:  Sat Jul 23 10:20:35 CEST 2011
make distribution finished at: Sat Jul 23 11:18:27 CEST 2011
===> Successful make distribution
===> build.sh ended:      Sat Jul 23 11:18:27 CEST 2011
===> Summary of results:
  build.sh command:    ./build.sh -j 2 -U -u -m evbarm distribution
  build.sh started:    Sat Jul 23 10:20:34 CEST 2011
  NetBSD version:      5.99.55
  MACHINE:             evbarm
  MACHINE_ARCH:        arm
  Build platform:      Linux 2.6.39-2-686-pae i686
  HOST_SH:             /bin/sh
  TOOLDIR path:        /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686
  DESTDIR path:        /home/edb/netbsd/src/obj/destdir.evbarm
  RELEASEDIR path:     /home/edb/netbsd/src/obj/releasedir
  Updated makewrapper: /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmake-evbarm
  Successful make distribution
  build.sh ended:      Sat Jul 23 11:18:27 CEST 2011
===> .
edb@lapedb:~/netbsd/src$ cd obj/
edb@lapedb:~/netbsd/src/obj$ ls
destdir.evbarm  tooldir.Linux-2.6.39-2-686-pae-i686
edb@lapedb:~/netbsd/src/obj$ du -sh destdir.evbarm 
459M destdir.evbarm

Here I instructed build.sh to:
  • -j 2: Use my two cores when building.
  • -U: Run an unpriviliged build (as a normal user, you don't want build.sh to upgrade your host too eagerly.
  • -u: Do an update, do not rebuild the toolchain and others just-for-fun.
  • -m evbarm: We are still crosscompiling the evaluation board ARM type.
  • distribution: We want to see build.sh create a distribution in $DESTDIR (-D dest Set DESTDIR to dest. [Default: destdir.MACHINE], this last expression means we can expect our rootfs in obj/destdir.evbarm relative to the src directory.

The BUILDING (located next to build.sh) describes the distribution target as follows:
distribution  Do a ``make build'', and then install a full distribution
                   (which does not include a kernel) into DESTDIR, including
                   files in DESTDIR/dev, DESTDIR/etc, DESTDIR/root and
                   DESTDIR/var.
Which is good since we have our kernel image already.


A next step is preparing our storage, remember I'm still running this all from my Debian-testing host. My initial attempt consisted out of creating a NetBSD disklabel on the stick and adding a UFS partitions there. Along that way I encountered some problems (a bug in ufsutils, the fact that I had to recompile the Linux UFS module with write support, ...) which resulted in an intermediary solution, I will in this scenario make use of an ext2 partition for my rootfilesystem (and not an UFS2). The fact that ext2 support is present in the kernel can be learned from the SHEEVAPLUG config file:

edb@lapedb:~/netbsd/src$ cat sys/arch/evbarm/conf/SHEEVAPLUG  | grep file-system
file-system  FFS  # UFS
file-system  EXT2FS  # second extended file system (linux)
#file-system  LFS  # log-structured file system
#file-system  MFS  # memory file system
file-system  NFS  # Network File System client
#file-system  NTFS  # Windows/NT file system (experimental)
#file-system  CD9660  # ISO 9660 + Rock Ridge file system
file-system  MSDOSFS  # MS-DOS file system
file-system  FDESC  # /dev/fd
file-system  KERNFS  # /kern
#file-system  NULLFS  # loopback file system
#file-system  OVERLAY  # overlay file system
#file-system  PORTAL  # portal filesystem (still experimental)
file-system  PROCFS  # /proc
#file-system  UMAPFS  # NULLFS + uid and gid remapping
#file-system  UNION  # union file system
#file-system  CODA  # Coda File System; also needs vcoda (below)
#file-system  SMBFS  # experimental - CIFS; also needs nsmb (below)
file-system  PTYFS  # /dev/ptm support
file-system  TMPFS  # Efficient memory file-system
#file-system  UDF  # experimental - OSTA UDF CD/DVD file-system
#file-system  HFS  # experimental - Apple HFS+ (read-only)

First I start with partitioning my USB stick, I will split the stick in two, first a small VFAT partition to contain the uImage, this for the simple reason that the bootloader on the Guruplug has support for FAT filesystems (and not for ext2) and also for the same reason, this partition will be outside the NetBSD disklabel.

lapedb:~# fdisk /dev/sdb 

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-1021, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-1021, default 1021): +100M

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (104-1021, default 104): 
Using default value 104
Last cylinder, +cylinders or +size{K,M,G} (104-1021, default 1021): 
Using default value 1021

Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): a9
Changed system type of partition 2 to a9 (NetBSD)

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): b
Changed system type of partition 1 to b (W95 FAT32)

Command (m for help): p

Disk /dev/sdb: 1052 MB, 1052508160 bytes
33 heads, 61 sectors/track, 1021 cylinders
Units = cylinders of 2013 * 512 = 1030656 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xa02121e3

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         103      103639    b  W95 FAT32
/dev/sdb2             104        1021      923967   a9  NetBSD


Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
lapedb:~# fdisk /dev/sdb 

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): b
Reading disklabel of /dev/sdb2  at sector 207340.
/dev/sdb2  contains no disklabel.
Do you want to create a disklabel? (y/n) y
# /dev/sdb2 :
type: SCSI
disk: 
label: 
flags:
bytes/sector: 512
sectors/track: 61
tracks/cylinder: 33
sectors/cylinder: 2013
cylinders: 1021
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0  # milliseconds
track-to-track seek: 0 # milliseconds
drivedata: 0 
4 partitions:
#       start       end      size     fstype   [fsize bsize   cpg]
  c:      104      1021       918     unused        0     0       
  d:        1      1021      1021     unused        0     0       

BSD disklabel command (m for help): n
Partition (a-p): a
First cylinder (104-1021, default 104): 110
Last cylinder or +size or +sizeM or +sizeK (110-1021, default 1021): 1000

BSD disklabel command (m for help): t
Partition (a-d): a
Hex code (type L to list codes): L

 0  unused           5  4.1BSD           9  4.4LFS           d  boot           
 1  swap             6  Eighth Edition   a  unknown          e  ADOS           
 2  Version 6        7  4.2BSD           b  HPFS             f  HFS            
 3  Version 7        8  MS-DOS           c  ISO-9660        10  AdvFS          
 4  System V       
Hex code (type L to list codes): 7

BSD disklabel command (m for help): n
Partition (a-p): b
First cylinder (104-1021, default 104): 1000
Last cylinder or +size or +sizeM or +sizeK (1000-1021, default 1021): 
Using default value 1021

BSD disklabel command (m for help): t
Partition (a-d): b
Hex code (type L to list codes): 1

BSD disklabel command (m for help): w
Writing disklabel to /dev/sdb2 .

Syncing disks.
Calling ioctl() to re-read partition table.

BSD disklabel command (m for help): p

4 partitions:
#       start       end      size     fstype   [fsize bsize   cpg]
  a:      110      1000       891     4.2BSD        0     0     0 
  b:     1000      1021        22       swap                      
  c:      104      1021       918     unused        0     0       
  d:        1      1021      1021     unused        0     0       

BSD disklabel command (m for help): 

lapedb:~# dmesg | tail -n 3
[ 2358.300068] sd 7:0:0:0: [sdb] Assuming drive cache: write through
[ 2358.304145]  sdb: sdb1 sdb2
[ 2358.304146]  sdb2: <netbsd: sdb5 sdb6 >

Important note: Why did I create a swap partition ? (Remember this is a flash medium, the last thing you want to do there is use it as swap ...) To be honest I don't know (yet), when I just created the a partition covering cylinders 15 to 1020 the Linux kernel failed to detect the disklabel and my dmesg output was:
[10031.190078] sd 6:0:0:0: [sdb] Assuming drive cache: write through
[10031.191935]  sdb: sdb1 sdb2
[10031.191938]  sdb2: <netbsd: >

At this point we can access the VFAT partition through /dev/sdb1 and the NetBSD partition through /dev/sdb5. At this point we need to create the filesystems and populate them.

We start with the FAT partition which only needs to have the U-boot kernel image, which I still had from last time, I reuse the one which I used during the TFTP boot in my previous post:


lapedb:~# mkfs.vfat /dev/sdb1 
mkfs.vfat 3.0.9 (31 Jan 2010)
lapedb:~# mount /dev/sdb1 /tmp/target/
lapedb:~# cp /srv/tftp/uImage  /tmp/target
lapedb:~# umount /tmp/target

And the nexst step is creating an ext2 partition on /dev/sdb5, after this I create a tarball of the NetBSD distribution build and extract it on this partition:

lapedb:~# mkfs.ext2  /dev/sdb5
mke2fs 1.42-WIP (02-Jul-2011)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
56112 inodes, 224197 blocks
11209 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=230686720
7 block groups
32768 blocks per group, 32768 fragments per group
8016 inodes per group
Superblock backups stored on blocks: 
 32768, 98304, 163840

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 0 mounts or
0 days, whichever comes first.  Use tune2fs -c or -i to override.
lapedb:~# mount /dev/sdb5 /tmp/target
lapedb:~# cd /tmp/target
lapedb:/tmp/target# tar -xf /tmp/rootfs.tar 
lapedb:/tmp/target# cd ..
lapedb:/tmp/# umount /tmp/target 

At this point my USB stick is ready. And I clan plug it in into the Guruplug. Looking that the serial connection we can then instruct U-boot to obtain the kernel from the USB stick as follows (this could just as well be done using the TFTP image, but I want to end up in a situation where I can boot the Guruplug standalone):

Marvell>> usb start
(Re)start USB...
USB:   Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... 3 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found
Marvell>> fatls usb 0:1 /
  4980889   uimage 

1 file(s), 0 dir(s)

Marvell>> fatload usb 0:1 0x100000 uImage
reading uImage
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
......................................................

4980889 bytes read

At this point my kernel image is loaded in DDR (at offset 0x100000) and I can instruct U-boot to start booting that image. Then I get the kernel messages again, but I can do something useful when NetBSD is asking me for a root filesystem:

Marvell>> bootm 0x100000
## Booting kernel from Legacy Image at 00100000 ...
   Image Name:   netbsd
   Image Type:   ARM NetBSD Kernel Image (uncompressed)
   Data Size:    4980825 Bytes =  4.8 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
## Transferring control to NetBSD stage-2 loader (at address 00000000) ...

NetBSD/evbarm (sheevaplug) booting ...
Loaded initial symtab at 0xc0388ec8, strtab at 0xc03bf1e4, # entries 13786
pmap_postinit: Allocated 35 static L1 descriptor tables
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 5.99.55 (SHEEVAPLUG) #0: Wed Jul 13 17:57:19 CEST 2011
 edb@lapedb:/home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG
total memory = 512 MB
avail memory = 497 MB
mainbus0 (root)
cpu0 at mainbus0: Sheeva 88SV131 rev 1 (ARM9E-S core)
cpu0: DC enabled IC enabled WB enabled EABT branch prediction enabled
cpu0: 16KB/32B 4-way Instruction cache
cpu0: 16KB/32B 4-way write-back-locking-C Data cache
mvsoc0 at mainbus0: Marvell 88F6281 Rev. A1  Kirkwood
mvsoc0: CPU Clock 1200.000 MHz  SysClock 400.000 MHz  TClock 200.000 MHz
mvsoctmr0 at mvsoc0 unit 0 offset 0x20300-0x203ff: Marvell SoC Timer
mvsocgpp at mvsoc0 unit 0 not configured
mvsocrtc0 at mvsoc0 unit 0 offset 0x10300-0x10317: Marvell SoC Real Time Clock
com0 at mvsoc0 unit 0 offset 0x12000-0x1201f irq 33: ns16550a, working fifo
com0: console
com1 at mvsoc0 unit 1 offset 0x12100-0x1211f irq 34: ns16550a, working fifo
ehci0 at mvsoc0 unit 0 offset 0x50000-0x51fff irq 19: Marvell USB 2.0 Interface
usb0 at ehci0: USB revision 2.0
gttwsi0 at mvsoc0 unit 0 offset 0x11000-0x11fff irq 29: Marvell TWSI controller
iic0 at gttwsi0: I2C bus
mvcesa at mvsoc0 unit 0 not configured
mvgbec0 at mvsoc0 unit 0 offset 0x70000-0x73fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec0 port 0 not configured
mvgbec1 at mvsoc0 unit 1 offset 0x74000-0x77fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec1 port 0 not configured
mvpex at mvsoc0 unit 0 not configured
mvsata at mvsoc0 unit 0 not configured
mvsdio0 at mvsoc0 unit 0 offset 0x90000-0x9ffff irq 28: Marvell Secure Digital Input/Output Interface
sdmmc0 at mvsdio0
uhub0 at usb0: Marvell EHCI root hub, class 9/0, rev 2.00/1.00, addr 1
sdmmc0: bad CIS ptr 0
sdmmc0: couldn't read CIS
sdmmc0: i/o init failed
sdmmc0: bad CIS ptr 0
sdmmc0: couldn't read CIS
sdmmc0: i/o init failed
"Marvell, 802.11 SDIO ID: 10, " (manufacturer 0x2df, product 0x9103) at sdmmc0 function 1 not configured
"Marvell, 802.11 SDIO ID: 10, " (manufacturer 0x2df, product 0x9103) at sdmmc0 function 2 not configured
uhub1 at uhub0 port 1: Genesys Logic USB2.0 Hub, class 9/0, rev 2.00/77.63, addr 2
uhub1: single transaction translator
umass0 at uhub1 port 3 configuration 1 interface 0
umass0: USB Mass Storage, rev 2.00/1.07, addr 3
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0:  disk removable
sd0: fabricating a geometry
sd0: 1003 MB, 1003 cyl, 64 head, 32 sec, 512 bytes/sect x 2055680 sectors
boot device: <unknown>
root device: sd0a
dump device (default sd0b): none
file system (default generic): ext2fs
root on sd0a
sd0: fabricating a geometry
warning: no /dev/console
init path (default /sbin/init): 
init: copying out path `/sbin/init' 11
/etc/rc.conf is not configured.  Multiuser boot aborted.
Enter pathname of shell or RETURN for /bin/sh: 

#

See that ? That's a shell crying for my commands ! Let's try something.

# uname -a
NetBSD  5.99.55 NetBSD 5.99.55 (SHEEVAPLUG) #0: Wed Jul 13 17:57:19 CEST 2011  edb@lapedb:/home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG evbarm
# mount
root_device on / type ext2fs (read-only, local)
tmpfs on /dev type tmpfs (union, local)
# mount /dev/sd0a /
# mount
/dev/sd0a on / type ext2fs (local)
tmpfs on /dev type tmpfs (union, local)

Apparently the ext2fs was mounted read-only so we corrected this.



Some closing comments:
  • Although I managed to get away with just an ext2 filesystem, I did not manage to boot it without the NetBSD disklabel present on the USB stick
  • At this point by setting the U-boot bootcmd environment variables I could have the Guruplug auto-boot until the point where it queries for the rootfs. This will be fixed in the nexst post.
  • The rootfs is at this point clearly not configured properly, no rc.conf, no user authentication, ... no nothing.
  • A rootfs of half a gigabyte is rather large for an embedded box isn't it ?

These subjects will be tackled in coming posts.

References:

Wednesday, July 13, 2011

Guruplug meets NetBSD: The first steps

I have at this point a Guruplug Server by globalscale technologies at my possession and also a JTAG/UART board which connects to the serial connector. There is a large enough community around these devices out there so I will not go into much detail there. It is sufficient to say it's the standard edition with just one gigabit ethernet connection and some USB ports (not the one with the embedded SD slot and the eSATA port). I will assume that the Guruplug is already equipped with a bootloader (u-boot in this case) and I do not have the intention to play around with u-boot if it does not appear to be necessary.

A block diagram of the GuruPlug standard edition is shown in the image below:





Since my NetBSD blog is also in suspended mode for a year (due to lack of time/toys), I'm hoping that this new toy will bring it back alive. This first step consists out of obtaining some source:

edb@lapedb:~$ mkdir netbsd 
edb@lapedb:~$ cd netbsd/
edb@lapedb:~/netbsd$ export CVS_RSH="ssh"
edb@lapedb:~/netbsd$ export CVSROOT="anoncvs@anoncvs.NetBSD.org:/cvsroot"
edb@lapedb:~/netbsd$ cvs co -P src

And then we need to use the NetBSD build system to build up a toolchain (the crosscompiler capable of cross-compiling the NetBSD kernel for the ARM architecture which runs on my standard Linux/x86 laptop) for the NetBSD/evbarm port. This we can do by executing:
edb@lapedb:~/netbsd$ cd src/
edb@lapedb:~/netbsd/src$ time ./build.sh -u -m evbarm tools
...

One sidenote, my Debian gave me a GCC 4.6.1 which can check for several new warnings, warnings which NetBSD's 5.99.22 external binutils cannot cope with, requiring me to use an older gcc. This can be accomplished with prefixing the build with:
edb@lapedb:~/netbsd/src$ export HOST_CC=/usr/bin/gcc-4.5
edb@lapedb:~/netbsd/src$ export HOST_CXX=/usr/bin/g++-4.5

Update 6 August 2011: , I created a ticket for the problem described above, and in the meantime the CVS repository of NetBSD contains a fix for this issue. You can track this at NetBSD ticket #45140.

This gives use a nice cross-compiler as a result:

edb@lapedb:~/netbsd/src$ obj/tooldir.Linux-2.6.39-2-686-pae-i686/arm--netbsdelf/bin/gcc -v
Using built-in specs.
Target: arm--netbsdelf
Configured with: /home/edb/netbsd/src/tools/gcc/../../gnu/dist/gcc4/configure --target=arm--netbsdelf --enable-long-long --enable-threads --with-bugurl=http://www.NetBSD.org/Misc/send-pr.html --with-pkgversion=NetBSD nb1 20110620 --enable-__cxa_atexit --disable-nls --disable-multilib --program-transform-name=s,^,arm--netbsdelf-, --enable-languages=c c++ objc --prefix=/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686
Thread model: posix
gcc version 4.1.3 20080704 (prerelease) (NetBSD nb2 20081120)

A next step is building a kernel. First try is trying to steal a default configuration file and src/sys/arch/evbarm/conf contains a configuration file called SHEEVAPLUG which was the name of the predecessor of the Guruplug, which means this one should be worth the shot.

edb@lapedb:~/netbsd/src$ ./build.sh -j 2 -u -m evbarm kernel=SHEEVAPLUG
...
===> Summary of results:
  build.sh command:    ./build.sh -j 2 -u -m evbarm kernel=SHEEVAPLUG
  build.sh started:    Wed Jul 13 17:55:38 CEST 2011
  NetBSD version:      5.99.55
  MACHINE:             evbarm
  MACHINE_ARCH:        arm
  Build platform:      Linux 2.6.39-2-686-pae i686
  HOST_SH:             /bin/sh
  TOOLDIR path:        /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686
  DESTDIR path:        /home/edb/netbsd/src/obj/destdir.evbarm
  RELEASEDIR path:     /home/edb/netbsd/src/obj/releasedir
  Updated makewrapper: /home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmake-evbarm
  Building kernel without building new tools
  Building kernel:     SHEEVAPLUG
  Build directory:     /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG
  Kernels built from SHEEVAPLUG:
   /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd
  build.sh ended:      Wed Jul 13 17:57:21 CEST 2011
===> .
edb@lapedb:~/netbsd/src$ file /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd
/home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd: ELF 32-bit LSB executable, ARM, version 1, statically linked, for NetBSD 5.99.55, not stripped
edb@lapedb:~/netbsd/src$ ls -hal /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd
-rwxr-xr-x 1 edb edb 4.8M Jul 13 17:57 /home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG/netbsd

At this point I am already a proud owner of a tftp service operating on 10.0.0.1, connect a UTP cable between my laptop and the Guruplug, so I just need to wrap the netbsd file in a u-boot compatible format (using u-boots mkimage tool) copy the netbsd kernel which is now inside the u-boot image to my tftp root:

edb@lapedb:~/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG$ mkimage -A arm -O netbsd -T kernel -C none -a 0 -e 0 -n netbsd -d netbsd /srv/tftp/uImage
Image Name:   netbsd
Created:      Wed Jul 13 18:17:52 2011
Image Type:   ARM NetBSD Kernel Image (uncompressed)
Data Size:    4980825 Bytes = 4864.09 kB = 4.75 MB
Load Address: 00000000
Entry Point:  00000000

Update August 6, 2011: Actually mkimage, or at least the NetBSD variant of this tool mkubootimage are part of the toolchain, and if you build the kernel, build.sh will already create a proper image for you. This will be called netbsd.ub and you can see how it gets created just before the summary of the build, this will look as follows:
/home/edb/netbsd/src/obj/tooldir.Linux-2.6.39-2-686-pae-i686/bin/nbmkubootimage -A arm -T kernel -a 0x00008000 -n NetBSD/sheevaplug 5.99.55 -C none netbsd.bin netbsd.ub
 magic:       0x27051956
 time:        Sat Aug  6 17:14:25 2011
 size:        4415424
 load addr:   0x00008000
 entry point: 0x00008000
 data crc:    0x128165e8
 os:          2 (netbsd)
 arch:        2 (arm)
 type:        2 (kernel)
 comp:        0 (none)
 name:        NetBSD/sheevaplug 5.99.55
 header crc:  0xa6c200d2


Next on the serial connection with the Guruplug from the U-boot prompt I attempt the following:
U-Boot 2009.11-rc1-00602-g8e6db3d (Dec 24 2009 - 03:11:17)
Marvell-Plug2

SoC:   Kirkwood 88F6281_A0
DRAM:  512 MB
NAND:  512 MiB
In:    serial
Out:   serial
Err:   serial
Net:   egiga0
88E1121 Initialized on egiga0
Hit any key to stop autoboot:  0 
Marvell>> setenv serverip 10.0.0.1
Marvell>> setenv ipaddr 10.0.0.2
Marvell>> tftpboot 0x100000 uImage
Using egiga0 device
TFTP from server 10.0.0.1; our IP address is 10.0.0.2
Filename 'uImage'.
Load address: 0x100000
Loading: #################################################################
  #################################################################
  #################################################################
  #################################################################
  #################################################################
  ###############
done
Bytes transferred = 4980889 (4c0099 hex)
Marvell>> bootm 0x100000
## Booting kernel from Legacy Image at 00100000 ...
   Image Name:   netbsd
   Image Type:   ARM NetBSD Kernel Image (uncompressed)
   Data Size:    4980825 Bytes =  4.8 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK
## Transferring control to NetBSD stage-2 loader (at address 00000000) ...

NetBSD/evbarm (sheevaplug) booting ...
Loaded initial symtab at 0xc0388ec8, strtab at 0xc03bf1e4, # entries 13786
pmap_postinit: Allocated 35 static L1 descriptor tables
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    2006, 2007, 2008, 2009, 2010, 2011
    The NetBSD Foundation, Inc.  All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
    The Regents of the University of California.  All rights reserved.

NetBSD 5.99.55 (SHEEVAPLUG) #0: Wed Jul 13 17:57:19 CEST 2011
 edb@lapedb:/home/edb/netbsd/src/sys/arch/evbarm/compile/obj/SHEEVAPLUG
total memory = 512 MB
avail memory = 497 MB
mainbus0 (root)
cpu0 at mainbus0: Sheeva 88SV131 rev 1 (ARM9E-S core)
cpu0: DC enabled IC enabled WB enabled EABT branch prediction enabled
cpu0: 16KB/32B 4-way Instruction cache
cpu0: 16KB/32B 4-way write-back-locking-C Data cache
mvsoc0 at mainbus0: Marvell 88F6281 Rev. A1  Kirkwood
mvsoc0: CPU Clock 1200.000 MHz  SysClock 400.000 MHz  TClock 200.000 MHz
mvsoctmr0 at mvsoc0 unit 0 offset 0x20300-0x203ff: Marvell SoC Timer
mvsocgpp at mvsoc0 unit 0 not configured
mvsocrtc0 at mvsoc0 unit 0 offset 0x10300-0x10317: Marvell SoC Real Time Clock
com0 at mvsoc0 unit 0 offset 0x12000-0x1201f irq 33: ns16550a, working fifo
com0: console
com1 at mvsoc0 unit 1 offset 0x12100-0x1211f irq 34: ns16550a, working fifo
ehci0 at mvsoc0 unit 0 offset 0x50000-0x51fff irq 19: Marvell USB 2.0 Interface
usb0 at ehci0: USB revision 2.0
gttwsi0 at mvsoc0 unit 0 offset 0x11000-0x11fff irq 29: Marvell TWSI controller
iic0 at gttwsi0: I2C bus
mvcesa at mvsoc0 unit 0 not configured
mvgbec0 at mvsoc0 unit 0 offset 0x70000-0x73fff: Marvell Gigabit Ethernet Controller
mvgbe0 at mvgbec0 port 0 irq 11
mvgbe0: Ethernet address f0:ad:4e:ff:11:d5
OUI 0x784a7a model 0x0014 rev 9 at mvgbe0 phy 0 not configured
mvgbe0: no PHY found!
mvgbec1 at mvsoc0 unit 1 offset 0x74000-0x77fff: Marvell Gigabit Ethernet Controller
mvgbe at mvgbec1 port 0 not configured
mvpex at mvsoc0 unit 0 not configured
mvsata at mvsoc0 unit 0 not configured
mvsdio0 at mvsoc0 unit 0 offset 0x90000-0x9ffff irq 28: Marvell Secure Digital Input/Output Interface
sdmmc0 at mvsdio0
uhub0 at usb0: Marvell EHCI root hub, class 9/0, rev 2.00/1.00, addr 1
sdmmc0: bad CIS ptr 0
sdmmc0: couldn't read CIS
sdmmc0: i/o init failed
sdmmc0: bad CIS ptr 0
sdmmc0: couldn't read CIS
sdmmc0: i/o init failed
"Marvell, 802.11 SDIO ID: 10, " (manufacturer 0x2df, product 0x9103) at sdmmc0 function 1 not configured
"Marvell, 802.11 SDIO ID: 10, " (manufacturer 0x2df, product 0x9103) at sdmmc0 function 2 not configured
uhub1 at uhub0 port 1: Genesys Logic USB2.0 Hub, class 9/0, rev 2.00/77.63, addr 2
uhub1: single transaction translator
umass0 at uhub1 port 3 configuration 1 interface 0
umass0: Hama SD Card Reader, rev 2.00/94.04, addr 3
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0:  disk removable
sd0: fabricating a geometry
sd0: 7600 MB, 7600 cyl, 64 head, 32 sec, 512 bytes/sect x 15564800 sectors
boot device: <unknown>
root device: 
use one of: mvgbe0 sd0[a-h] ddb halt reboot


So far, so good, so we set the ip address for the guruplug to use, the ip address of the tftp server, we loaded the image (uImage) which we put in our tftp root into DDR memory (at offset 0x100000) and we asked the bootloader (U-boot) to boot the image which we put at memory address 0x100000. And then we see the NetBSD kernel messages appearing on our serial line. After loading the kernel it stops and prompts us for a root device to use (but we are not yet at that phase).


Some preliminary comments on this output:
  • My unit has a USB to SD convertor attached to the USB port, one which was detected, this will in the future be the first host for a root filesystem, since this is easier to deal with than internal NAND flash.
  • Some guruplug/sheevaplugs have an onboard microSD slot, here an attempt to probe it is done which fails.
  • The Guruplug I'm using is known to have some problems with its ethernet phy, it looses the link every now and then, hence some oddities can be expected there.

External sources:

Tuesday, August 3, 2010

Dual booting NetBSD with Linux using Grub

So far I've been playing with NetBSD and virtualbox, this is nice as a starting point, but next to this I also like something running on the bare metal.So I picked a desktop of mine which had a Debian stable installed and turned this into a dual boot system. Doing this is something very simple.

The first thing you need to do is make sure you start off the right foot, this means that in this case when I partitioned the disk and installed Debian on it, I already foresaw that I would install NetBSD on it, so I left some spare space in an empty partition. In the NetBSD installer I let NetBSD do its thing (create the BSD disklabel) in that partition.

And once you're at this point you're already at one third of the effort. When NetBSD prompts you that it did not find a valid bootloader in the MBR and asks you to install one for you, just say no in this case GRUB (which _is_ a valid bootloader) is already installed and we will use GRUB to boot into NetBSD.

So far so good, the installer will complete and when the system is done and reboots you should see GRUB and at this point you should see no trace of NetBSD whatsoever, don't panic, this is what we expect and what we will repair now.


For grub 0.9x you can access a command line by pressing 'c', from there you can enter some commands at the "grub>" prompt. If you type here

grub> rootnoverify (hd0,1)
grub> chainloader +1
grub> boot

Et voila, you should see the NetBSD loader appearing. Note that this change is not permanent and you will need to type this each time you want to boot into NetBSD (which is not part of the plan) hence we will edit the grub configuration file, typically this lives in /boot/grub/menu.lst  (but your experience may vary, sometimes this is called grub.conf as well), and also beware that at least a part of this file is typically auto generated by your distribution (typically when the kernel is upgraded, e.g. based upon rules in /etc/grub.d/* ), but in this file you can add (append at the bottom is typically a good idea) something like:

title NetBSD
rootnoverify (hd0,1)
chainloader +1

And the next time grub will show you to option to boot NetBSD from the list of GRUB options. For those not familiar with GRUB's notation of disks and partition (hd0,1) means the second partition of the first hard disk (all grown up people start counting at zero ;-) ).

For grub 2 (or 1.xx) the steps are almost similar, one important difference however is that they start counting disks at 0 (as with the old one) but partitions start to count at 1. Meaning that my earlier example from the commandline would look like:


grub> set root=(hd0,2)
grub> chainloader +1
grub> boot

Or you can extend the configuration file (by editing /boot/grub/grub.cfg directly, or by editing /etc/grub.d/40_custom and running something like update-grub2, the latter probably being the recommended way). In my case this last file contains:

#!/bin/sh
exec tail -n +3 $0
# This file is an example on how to add custom entries
menuentry "NetBSD" {
     set root=(hd0,2)
     chainloader +1
}

Or just add the last three lines to the grub.cfg file directly if you don't want to use the upgrade-grub2 mechanism.

Wednesday, June 23, 2010

From 5.1 RC2 to current (part I: the kernel)

The first post showed how NetBSD 5.1 RC2 could be installed, this week an announcement was made that NetBSD 5.1 RC3 is available which turns my installation into something outdated. Nevertheless this also gives me the ideal excuse (or forces me to, depends on which sentence you like best) to upgrade my installation to current. In this context is nothing more than a fancy for CVS head, or tracking the most current developments, this way (in conjunction to subscribing to several of the netbsd  mailing lists ) I hope to get a bit familiar with the source code and the NetBSD development process, and this obviously opens the door for some contributions by myself (the last one being a long term and idealistic goal, and I don't have a clue if I will ever reach that point).

An advantage of playing around with Virtualbox, as I'm doing now, is that one can easily export the appliance (read: make a full backup) and import an appliance (read: make a full restore), or even run multiple versions in parallel. So before you start doing this, just make a full backup, this will allow you to play around and to break things, and falling back to a stable situation is just a couple of clicks (and some patience) away.

This blog post is just something I'm writing up for my own reference, I'm not reinventing the wheel myself, so I'm also just following the documentation a first suggested way to make use of the binary images which the NetBSD project provides (accessible at http://nyftp.netbsd.org/pub/NetBSD-daily/ ), this is a solution, but I call this the easy way out, thus I will not follow this path, if I want to modify code, I need to be able to have these images build myself.  For this reason I also choose to host the CVS sources on my Linux host OS, this way I can mount the CVS sources in several NetBSD guests (over NFS). Thus on my local system I obtain a CVS copy:

edb@lapedb:~$ mkdir netbsd 
edb@lapedb:~$ cd netbsd/
edb@lapedb:~/netbsd$ export CVS_RSH="ssh
edb@lapedb:~/netbsd$ export CVSROOT="anoncvs@anoncvs.NetBSD.org:/cvsroot"
edb@lapedb:~/netbsd$ cvs co -P src
...
edb@lapedb:~/netbsd$ du -sh src
1.4G src

Next I set up NFS locally (note: lapedb is my Linux host os, flying_spaghetti_monster is my NetBSD guest):

edb@lapedb:/etc$ apt-get install nfs-common nfs-kernel-server
edb@lapedb:/etc$ cat /etc/exports  | tail -n 1
/home/edb/netbsd/src 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)

And on the guest I can run

flying_spaghetti_monster# mount -t nfs 192.168.10.100:/home/edb/netbsd/src /mnt/nfs/
flying_spaghetti_monster# cd /mnt/nfs/
flying_spaghetti_monster# cvs update 
Warning: Permanently added the RSA host key for IP address '204.152.190.16' to the list of known hosts.

This also gives me the opportunity to do a little benchmarking, I compared the delay in time between a cvs update running native on the Linux host, and a cvs update from the NetBSD guest mounted over NFS (with the options set to sync and async). This while the repository is up to date:

native on Linux host: 
real 1m19.054s
user 0m1.400s
sys 0m1.396s

nfs sync on NetBSD guest
      117.33 real         0.80 user        57.79 sys
nfs async on NetBSD guest
      111.22 real         0.66 user        55.75 sys
So this means that by adding the NFS/Virtualization I loose about 38 seconds on a CVS update. Okay, a bit higher than my expectations, but still very workable. Okay, the story so far, we have the CVS sources available in our sandbox so we can start playing.

We start by following the crosscompilation chapter in the NetBSD guide

flying_spaghetti_monster# cd /mnt/nfs/
flying_spaghetti_monster# ./build.sh -m i386 tools
===> build.sh command: ./build.sh -m i386 tools
===> build.sh started: Sat Jun 19 15:35:20 CEST 2010
===> NetBSD version:   5.99.31
===> MACHINE:          i386
===> MACHINE_ARCH:     i386
===> Build platform:   NetBSD 5.1_RC2 i386
===> HOST_SH:          /bin/sh
===> No $TOOLDIR/bin/nbmake, needs building.
===> Bootstrapping nbmake
...
===> Tools built to /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386
===> build.sh ended:   Sat Jun 19 15:55:51 CEST 2010
===> Summary of results:
         build.sh command: ./build.sh -m i386 tools
         build.sh started: Sat Jun 19 15:35:20 CEST 2010
         NetBSD version:   5.99.31
         MACHINE:          i386
         MACHINE_ARCH:     i386
         Build platform:   NetBSD 5.1_RC2 i386
         HOST_SH:          /bin/sh
         No $TOOLDIR/bin/nbmake, needs building.
         Bootstrapping nbmake
         TOOLDIR path:     /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386
         DESTDIR path:     /mnt/nfs/obj/destdir.i386
         RELEASEDIR path:     /mnt/nfs/obj/releasedir
         Created /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake
         makewrapper:      /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
         Updated /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
         Tools built to /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386
         build.sh ended:   Sat Jun 19 15:55:51 CEST 2010

This build.sh is actually a really nice system, it has just build a crosscompiler which runs on NetBSD 5.1_RC2, and will compile for i386. But I could actually run the same script on my native Linux box and use build.sh to construct a toolchain to build NetBSD for any architecture.

Now that we have the tools in place, let's start with compiling our kernel. But first we collect some proof, tihs is our current kernel:

flying_spaghetti_monster# uname -a 
NetBSD flying_spaghetti_monster 5.1_RC2 NetBSD 5.1_RC2 (GENERIC) #0: Fri May 21 04:32:33 UTC 2010  builds@b8.netbsd.org:/home/builds/ab/netbsd-5-1-RC2/i386/201005210534Z-obj/home/builds/ab/netbsd-5-1-RC2/src/sys/arch/i386/compile/GENERIC i386

The kernel configurations are located in sys/arch/i386/conf/ and we will now build the GENERIC kernel.

flying_spaghetti_monster# ls -hal ./sys/arch/i386/conf/GENERIC
-rw-r--r--  1 1000  1000   56K Jun  1 04:40 ./sys/arch/i386/conf/GENERIC
flying_spaghetti_monster# ./build.sh -u -m i386 kernel=GENERIC
===> build.sh command: ./build.sh -u -m i386 kernel=GENERIC
===> build.sh started: Mon Jun 21 22:23:48 CEST 2010
===> NetBSD version:   5.99.31
===> MACHINE:          i386
===> MACHINE_ARCH:     i386
===> Build platform:   NetBSD 5.1_RC2 i386
===> HOST_SH:          /bin/sh
===> TOOLDIR path:     /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386
===> DESTDIR path:     /mnt/nfs/obj/destdir.i386
===> RELEASEDIR path:     /mnt/nfs/obj/releasedir
===> makewrapper:      /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
===> Updated /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
===> Building kernel without building new tools
#    objdir  /mnt/nfs/sys/arch/i386/compile/obj
===> Building kernel:  GENERIC
===> Build directory:  /mnt/nfs/sys/arch/i386/compile/obj/GENERIC
Build directory is /mnt/nfs/sys/arch/i386/compile/obj/GENERIC
Don't forget to run "make depend"
depending the kern library objects
#    create  kern/__cmsg_alignbytes.d

....

#    link  GENERIC/netbsd
/mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/i486--netbsdelf-ld -Map netbsd.map --cref -T /mnt/nfs/sys/arch/i386/conf/kern.ldscript -Ttext c0100000 -e start -X -o netbsd ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
NetBSD 5.99.31 (GENERIC) #0: Mon Jun 21 23:06:06 CEST 2010
   text    data     bss     dec     hex filename
9684860  541396  554716 10780972         a4812c netbsd

===> Kernels built from GENERIC:
  /mnt/nfs/sys/arch/i386/compile/obj/GENERIC/netbsd
===> build.sh ended:   Mon Jun 21 23:06:27 CEST 2010
===> Summary of results:
         build.sh command: ./build.sh -u -m i386 kernel=GENERIC
         build.sh started: Mon Jun 21 22:23:48 CEST 2010
         NetBSD version:   5.99.31
         MACHINE:          i386
         MACHINE_ARCH:     i386
         Build platform:   NetBSD 5.1_RC2 i386
         HOST_SH:          /bin/sh
         TOOLDIR path:     /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386
         DESTDIR path:     /mnt/nfs/obj/destdir.i386
         RELEASEDIR path:     /mnt/nfs/obj/releasedir
         makewrapper:      /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
         Updated /mnt/nfs/obj/tooldir.NetBSD-5.1_RC2-i386/bin/nbmake-i386
         Building kernel without building new tools
         Building kernel:  GENERIC
         Build directory:  /mnt/nfs/sys/arch/i386/compile/obj/GENERIC
         Kernels built from GENERIC:
          /mnt/nfs/sys/arch/i386/compile/obj/GENERIC/netbsd
         build.sh ended:   Mon Jun 21 23:06:27 CEST 2010
===> .
flying_spaghetti_monster# file /mnt/nfs/sys/arch/i386/compile/obj/GENERIC/netbsd
/mnt/nfs/sys/arch/i386/compile/obj/GENERIC/netbsd: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for NetBSD 5.99.31, not stripped

Jay, this means we have a kernel image available. Now we will need to boot from it, so we copy it over the original kernel (after creating a backup):

flying_spaghetti_monster# mv /netbsd /netbsd.old
flying_spaghetti_monster# cp /mnt/nfs/sys/arch/i386/compile/obj/GENERIC/netbsd /netbsd
flying_spaghetti_monster# ls -hal /netbsd*
-rwxr-xr-x  1 root  wheel   11M Jun 21 23:14 /netbsd
-rwxr-xr-x  1 root  wheel   11M May 21 06:32 /netbsd.old 
flying_spaghetti_monster# shutdown -r now 

And we cross our fingers. If things fail, we can fall back to the original kernel by following the following steps:


However after a reboot this fallback mechanism was already necessary (boot the old kernel, and copy netbsd.old to netbsd because the GENERIC kernel has loadable module support by default and the filesystems are compiled in (out) as modules, hence just booting the GENERIC results in a kernel which can't mount its root filesystem. The workaround is to either put the proper modules there or to build the kernel with the MONOLITHIC config, this config should not rely on modules. If we take a look at the config file for the MONOLITHIC kernel:

# $NetBSD: MONOLITHIC,v 1.11 2010/04/09 14:02:05 ahoka Exp $
#
# Non MODULAR, used mostly as a reference as to what we modularized.
#
include "arch/i386/conf/GENERIC"

no options MODULAR

options  EXEC_AOUT # exec a.out binaries
options  EXEC_ELF32 # exec ELF binaries
options  EXEC_SCRIPT # exec #! scripts
options  COREDUMP

options  P1003_1B_SEMAPHORE # p1003.1b semaphore support
options  AIO  # POSIX asynchronous I/O, built as a module
options  MQUEUE  # POSIX messsage queues, built as a module

options  COMPAT_OSSAUDIO # OSS (Voxware) audio driver compatibility
options  COMPAT_SVR4 # binary compatibility with SVR4
options  COMPAT_IBCS2 # binary compatibility with SCO and ISC
options  COMPAT_LINUX # binary compatibility with Linux
options  COMPAT_FREEBSD # binary compatibility with FreeBSD

# File systems
file-system  FFS  # UFS
file-system  EXT2FS  # second extended file system (linux)
file-system  LFS  # log-structured file system
file-system  MFS  # memory file system
file-system  NFS  # Network File System client
file-system  NTFS  # Windows/NT file system (experimental)
file-system  CD9660  # ISO 9660 + Rock Ridge file system
file-system  MSDOSFS  # MS-DOS file system
file-system  FDESC  # /dev/fd
file-system  KERNFS  # /kern
file-system  NULLFS  # loopback file system
file-system  OVERLAY  # overlay file system
file-system  PROCFS  # /proc
file-system  UMAPFS  # NULLFS + uid and gid remapping
file-system  UNION  # union file system
file-system  CODA  # Coda File System; also needs vcoda (below)
file-system  SMBFS  # experimental - CIFS; also needs nsmb (below)
file-system  PTYFS  # /dev/ptm support
file-system  TMPFS  # Efficient memory file-system
file-system PUFFS  # Userspace file systems (e.g. ntfs-3g & sshfs) 

We see that it just extends the GENERIC configuration and adds the file system support. However after building the monolithic kernel
flying_spaghetti_monster# ./build.sh -u -m i386 kernel=GENERIC

And following the same steps (copying it to /netbsd) and rebooting we are now running our own-rolled kernel:

flying_spaghetti_monster# uname -a
NetBSD flying_spaghetti_monster 5.99.31 NetBSD 5.99.31 (MONOLITHIC) #0: Wed Jun 23 23:49:20 CEST 2010  root@flying_spaghetti_monster:/mnt/nfs/sys/arch/i386/compile/obj/MONOLITHIC i386

Next step, building userland and using a generic kernel with module support.

Post scriptum:
Later experimentations showed that the NFS mount turned out to be rather painful and it did not fulfill my needs (mainly talking about performance here). So in a later phase I started using build.sh to build on my Linux host (when I set up the NFS I was not aware that build.sh was powerful enough to do this.

Tuesday, June 15, 2010

NetBSD meets Xorg meets Virtualbox

Personally I'm a console lover, which makes me belong to a group of people which is becoming a smaller and smaller part of the population. Thus the goal of this post is to explain how to get the X-server (in this case Xorg) functioning properly within Virtualbox. Configuring the X server is something which has been causing people troubles for years and years, even though things have evolved a lot the past decade. Thus we start by asking Xorg to create us a configuration file:

flying_spaghetti_monster# Xorg -configure 

As a result a new configuration file gets created which gets located in /root/xorg.conf.new at this point we can give the X server a testrun by calling:


flying_spaghetti_monster# X -config /root/xorg.conf.new

Et voila, we have an operational X-server:
To terminate this and to go back to the console press CTRL+ALT+BACKSPACE. As a next step we will copy this configuration file (which we tested) to a location where it can easily be found by scripts such a startx.

flying_spaghetti_monster# cp /root/xorg.conf.new /etc/X11/xorg.conf

If you now start the xserver using startx it will automatically use this configuration file and this time it will launch the twm window manager, xclock and two xterms.


flying_spaghetti_monster# startx

Which looks like this:
Okay, from the 70s look which the screenshots of the first post gave us, we now officially entered the 80s. At this point the maximum resolution however is only 800x600 for the simple reason that no guest additions are already available for NetBSD :(, which means the Xorg server can only use the vesa video driver and not the commonly used vboxvideo driver.

Friday, June 11, 2010

Poor men's NetBSD part II (aka configuring NetBSD for usage in virtualbox)

In my previous post I documented the installation of NetBSD using virtualbox, the result was that at the end we had a virtual instance running which booted to a prompt. While this is already a good starting point, we're still virtually nowhere. 

The first thing we will need however is access to the network, the default installation of virtualbox gave me a pseudo Intel E1000 ethernet adapter which is NAT'ed by default. When the virtual instance boots there is not attempt made to configure the network but after running

dhclient wm0

manually I get an ip address and a connection to my host operating system (and the Internet is possible).  However for my purposes what I really need is the ability to access the guest OS (being NetBSD) from the host OS. (The main reason to do this is because then I can just copy/paste snippets from the console, without the need to keep taking screenshots. In order to accomplish this we need to edit the virtual machine settings:

And here we change the type from NAT to Bridged and we create a bridge with whatever real device your are using on your host system (in this case I'm using my wlan) and then we say we will bridge this with the Intel PRO/1000 which will be visible in the guest (just don't expect gigabit speeds ;-) ). Running a
dhclient wm0
will give you a DHCP lease in your 'regular' domain (in this case a lease handed out by my wireless access point instead of one handed out in a private range by virtualbox itself), the good news is that this ip address is accessible from the host os as well. This implies that I can now connect to it and start copy pasting. And a first copy paste is perhaps the output of ifconfig -a which shows a configured ethernet adapter and the loopback device:

# ifconfig -a
wm0: flags=8843 mtu 1500
        capabilities=2bf80<TSO4,IP4CSUM_Rx,IP4CSUM_Tx,TCP4CSUM_Rx,TCP4CSUM_Tx,UDP4CSUM_Rx,UDP4CSUM_Tx,TCP6CSUM_Tx,UDP6CSUM_Tx>
        enabled=0
        address: 08:00:27:4c:94:06
        media: Ethernet autoselect (1000baseT full-duplex)
        status: active
        inet 192.168.10.104 netmask 0xffffff00 broadcast 192.168.10.255
        inet6 fe80::a00:27ff:fe4c:9406%wm0 prefixlen 64 scopeid 0x1
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33192
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2

Now in order to connect to the system it is advised to start the sshd daemon by issuing
# /etc/rc.d/sshd start
Instead of using start you can also use start, stop, restart and status as parameters:
# /etc/rc.d/sshd status
sshd is running as pid 357.
At this point we've done all these tings manually, while we really want the system to do this by default at startup. For this the files /etc/rc.conf  and /etc/defaults/rc.conf come into play. The file /etc/rc.conf is sourced by rc, meaning that rc.conf should contains valid sh-compatible statements (read: setting variables).  man 5 rc.conf  will give you a full description of the known variables, but take also a look in /etc/defaults/rc.conf since this file is sourced by rc.conf:

# Load the defaults in from /etc/defaults/rc.conf (if it's readable).
# These can be overridden below.
#
if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
fi

In the case of sshd, the defaults file states it should not be started:

# cat ./defaults/rc.conf | grep -i ssh
sshd=NO                 sshd_flags=""
ssh_keygen_flags="-b 1024"      # generate 1024 bit keys if host keys missing 

So by adding sshd=YES to /etc/rc.conf we can have the rc system start the ssh daemon at startup. Sometimes you want to know which rc.conf variables can help you to influence the behavior of an initscript. For this you can call an rc.d script with the rcvar  parameter.

# /etc/rc.d/sshd rcvar
# sshd
$sshd=YES

Now all we need after this is proper network configuration, in this case we extend rc.conf with:

dhclient=YES
hostname=flying_spaghetti_monster

Setting the hostname is optional, after a reboot the dhcp client will start and it will be accessible through ssh.

An interesting paper to get a better understanding of the NetBSD rc system can be found at http://www.mewburn.net/luke/papers/rc.d.pdf and there is also the rc chapter in the NetBSD guide at http://www.netbsd.org/docs/guide/en/chap-rc.html

Post scriptum:
In the setup above I suggested the use of a bridged adapter, this however is not without risks, later on I used this setup in combination with an NFS share (NFS share between host and guest), this however resulted in a lot of NFS related packets going over the ether, which caused my poor wireless router to suffocate.  A better solution is to used the 'host-only adapter' option, this will create a virtual interface on your host in a private subnet with your guest, this way (given that your NAT is configured properly) the same requirements as above can be met.

Saturday, June 5, 2010

Poor men's NetBSD (aka installing NetBSD 5.1 RC2 in virtualbox)

A week ago I did a NetBSD installation in a virtualbox, which is running under Debian unstable, at this point I use Debian for work and the goal is to start playing with NetBSD for fun. This blog is here mainly to track some of the steps/experiments I'm doing, it could be that this grows, it could be that this dies silently in the future ....

However, as a first step I read NetBSD 5.1 RC2 is available (e.g. see here on the NetBSD blog), so I will start doing a writeup on how to install this NetBSD 5.1 RC2 under virtualbox (like probably a lot of people have already done before me, but one's got to start somewhere). And at least that brings the test count of the 5.1 RC2 up by one.

So we start with downloading the iso image which can be found at the following location http://ftp.netbsd.org/pub/NetBSD/NetBSD-5.1_RC2/iso/

There download the i386 iso (this applies to each other version of NetBSD as well), next I assume you already have virtualbox installed (and operational). Next we start virtualboxroot and we click the 'New' button in the toolbar, the 'New Virtual Machine Wizard' appears, here we click next to get started.


Next we need to tell it what the name and type of our virtual machine should be, here we name it NetBSD.


We start with assigning it some memory. Here I choose half a gigabyte (but we can change it later on if we would need more.


We specify a new virtual hard disk should be created.


This launches the new virtual disk wizard.


This is my favorite virtualbox feature, instead of assigning (and thus loosing) a lot of storage by sacrificing it upfront, we let virtualbox dynamically expand the storage as the demand grows.


We need to specify an upper limit, but we don't loose it immediately (when I look at the NetBSD.vdi file after the installation which you can typically find in ~/.Virtualbox/HardDisks it consumes about 700 megabyte of space).


Virtual Disk was created.


And the virtual machine is ready as well.


Next we select File -> Virtual Media Manager and we go to the known CD/DVD Image tab.


There we add the NetBSD ISO which we downloaded at the beginning.


Next we go the settings of the Virtual machine (right mouse) select storage and attach the CD/DVD image which was just made as secondary master device.


And now we power on the Virtual Machine, it will boot from CD.


The welcome message, and we all speak English:


We use a sensible keyboard lay-out:


And we want to install NetBSD:


Confirm.


There is only one disk, this makes it easy.


And we have enough room for a full install.


This is the 10 GB disk we created, simply use it.


The disk is only there to contain NetBSD, so we dedicate it entirely.


And we need a bootloader.


Let NetBSD do whatever it thinks is best.


Confirm the suggestion.



What's in a name ?


Setting up is done, start the installation.


Creating the filesystems.


Output should appear on VGA, not on a serial connection.


Show some test scrolling on the screen during the installation.


Everything is on the iso image, so let's use that.


Accept the defaults.


Then it starts unpacking the packages onto the target.


Packages are installed.


We select a timezone, your answers may differ ;).


Pick a choice, even though this is just a local plaything I can't force myself to make use of the weak DES.


Then we set the root password.


A shell.


And we're done !


Now we select reboot, when you see it booting from the CD again, simply power off (close) the virtual box window (it is already installed, we don't want to do it again).


In the virtual machine settings (right mouse) we disconnect the CD image.


And we power the virtual machine again (press start, oh and don't mind my sin in that list, it's there for work :()


This is the NetBSD bootcode.


And after boot we can log in (with the password we specified) and this shows the NetBSD 5.1 RC2 is running.



Et voila, we have NetBSD running inside a Virtualbox. You could typer poweroff now, or do a shutdown, or close the window to terminate it. You could even export your virtual machine (File->Export Appliance) to share it with your friends.