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.