I’ve been needing to have a reliable time server and yet I don’t need something that is large, or consumes a lot of power.
Enter the Raspberry Pi. I picked up a Cana Kit , Model B, a 700MHz ARM SoC (System on Chip), 512MB RAM, USB, Ethernet, SD slot. It came with all the bits needed to get started. A bit of google work turned up some hints on putting FreeBSD on it.
FreeBSD, PPS kernel config
FreeBSD offers the ability to provide PPS (pulse per second) to facilitate better time tracking (used as input to NTP). If you wish to do this, you need to create a new kernel config file, define the PPS option, and include the generic config. Something like this:
1 #
2 # PPS -- Generic kernel configuration file for FreeBSD RPI/ARM PPS
3 #
4 include RPI-B
5 ident PPS-RPI-B
6 options PPS_SYNC
Define your KERNCONF in /etc/make.conf:
Build script
If you want an automated way to build these images, I’ve cobbled a script. It requires the following: FreeBSD 10.0 or newer (10.0 should be released this week, so that shouldn’t be an issue) - VM is fine Ensure that Subversion installed
Ensure that the auditdistd user exists:
The script looks like this:
1 #!/bin/sh
2 # © Louis Kowolowski 2014
3 # Script to handle getting source, compiling, generating and customizing image for
4 # Raspberry Pi
5
6 # Stop on errors (we should always handle things properly so this can be enabled)
7 set -e
8
9 while getopts "nbuit" COMMAND_LINE_ARGUMENT ; do
10 case "${COMMAND_LINE_ARGUMENT}" in
11 b) BUILD="YES"
12 ;;
13 i) IMAGE="YES"
14 ;;
15 n) NEW="YES"
16 ;;
17 u) UPDATE="YES"
18 ;;
19 t) test_mode="YES"
20 ;;
21 \?) echo "-h <host> is required, -p <password> is required"
22 exit 1
23 ;;
24 esac
25 done
26
27 # Change these to suite your build and network environment
28 export SRCROOT="/src/FreeBSD/head"
29 export MNTDIR="/mnt"
30 export MAKEOBJDIRPREFIX="/src/FreeBSD/obj"
31 export GPU_MEM="128"
32 export IMG="/src/FreeBSD/obj/bsd-pi.img"
33 export IMG_SIZE="7"
34 export NS1="198.18.3.10"
35 export NS2="198.18.3.11"
36 export DOMAIN="cmhome"
37
38 export TARGET_ARCH="armv6"
39 export MAKESYSPATH="$SRCROOT/share/mk"
40 export KERNCONF="PPS-RPI-B"
41 export _ncpu="`sysctl -n hw.ncpu`"
42
43 mkdir -p $SRCROOT
44 mkdir -p $MAKEOBJDIRPREFIX
45
46 export KERNEL=`realpath $MAKEOBJDIRPREFIX`/arm.armv6/`realpath $SRCROOT`/sys/$KERNCONF/kernel
47 export UBLDR=`realpath $MAKEOBJDIRPREFIX`/arm.armv6/`realpath $SRCROOT`/sys/boot/arm/uboot/ubldr
48 export DTB=`realpath $MAKEOBJDIRPREFIX`/arm.armv6`realpath $SRCROOT`/sys/$KERNCONF/rpi.dtb
49
50 get_source() {
51 cd $SRCROOT
52 cd ..
53 mv head head.old
54 rm -Rf head.old &
55 mv obj obj.old
56 rm -Rf obj.old &
57 svn co http://svn0.us-west.freebsd.org/base/releng/10.0 head
58 }
59
60 update_source() {
61 cd $SRCROOT
62 svn up
63 }
64
65 generate_kernel_config() {
66 cd $SRCROOT/sys/arm/conf
67 cat > $KERNCONF <<__EOC__
68 #
69 # PPS -- Generic kernel configuration file for FreeBSD Raspberry Pi PPS
70 #
71 include RPI-B
72 ident $KERNCONF
73 options PPS_SYNC
74 __EOC__
75 }
76
77 build() {
78 cd $SRCROOT
79 make -C $SRCROOT kernel-toolchain
80 cat $SRCROOT/sys/arm/conf/$KERNCONF
81 make -C $SRCROOT KERNCONF=$KERNCONF WITH_FDT=yes buildkernel
82 make -j${_ncpu} -C $SRCROOT buildworld
83
84 buildenv=`make -C $SRCROOT buildenvvars | sed 's/MACHINE_ARCH=armv6/MACHINE_ARCH=arm/'`
85 cd sys/boot
86 eval $buildenv make -C $SRCROOT/sys/boot clean
87 eval $buildenv make -C $SRCROOT/sys/boot obj
88 eval $buildenv make -C $SRCROOT/sys/boot UBLDR_LOADADDR=0x2000000 clean obj all
89 }
90
91 generate_image() {
92 rm -f $IMG
93 dd if=/dev/zero of=$IMG bs=1024m count=$IMG_SIZE
94 MDFILE=`mdconfig -a -f $IMG`
95 gpart create -s MBR ${MDFILE}
96
97 # Boot partition
98 gpart add -s 32m -t '!12' ${MDFILE}
99 gpart set -a active -i 1 ${MDFILE}
100 newfs_msdos -L boot -F 16 /dev/${MDFILE}s1
101 mount_msdosfs /dev/${MDFILE}s1 $MNTDIR
102 fetch -q -o - \
103 http://people.freebsd.org/~gonzo/arm/rpi/freebsd-uboot-20121129.tar.gz | \
104 tar -x -v -z -C $MNTDIR -f -
105
106 cat >> $MNTDIR/config.txt <<__EOC__
107 gpu_mem=$GPU_MEM
108 device_tree=devtree.dat
109 device_tree_address=0x100
110 disable_commandline_tags=1
111 __EOC__
112
113 cp $UBLDR $MNTDIR
114 cp $DTB $MNTDIR/devtree.dat
115 umount $MNTDIR
116
117 # FreeBSD partition
118 gpart add -t freebsd ${MDFILE}
119 gpart create -s BSD ${MDFILE}s2
120 gpart add -t freebsd-ufs ${MDFILE}s2
121 newfs /dev/${MDFILE}s2a
122
123 # Turn on Softupdates
124 tunefs -n enable /dev/${MDFILE}s2a
125 # Turn on SUJ with a minimally-sized journal.
126 # This makes reboots tolerable if you just pull power on the BB
127 # Note: A slow SDHC reads about 1MB/s, so a 30MB
128 # journal can delay boot by 30s.
129 tunefs -j enable -S 4194304 /dev/${MDFILE}s2a
130 # Turn on NFSv4 ACLs
131 tunefs -N enable /dev/${MDFILE}s2a
132
133 mount /dev/${MDFILE}s2a $MNTDIR
134
135 make -C $SRCROOT DESTDIR=$MNTDIR installkernel
136 make -C $SRCROOT DESTDIR=$MNTDIR installworld
137 make -C $SRCROOT DESTDIR=$MNTDIR distribution
138
139 echo 'fdt addr 0x100' > $MNTDIR/boot/loader.rc
140
141 echo '/dev/mmcsd0s2a / ufs rw,noatime 1 1' > $MNTDIR/etc/fstab
142
143 cat > $MNTDIR/etc/resolv.conf <<__EORC__
144 search $DOMAIN
145 nameserver $NS1
146 nameserver $NS2
147 __EORC__
148
149 cat > $MNTDIR/etc/rc.conf <<__EORC__
150 hostname="fbsd-pi.cmhome"
151 ifconfig_ue0="DHCP"
152 sshd_enable="YES"
153 ntpd_enable="YES"
154 ntpd_sync_on_start="YES"
155
156 # Turn off a lot of standard stuff
157 # for more free memory.
158 sendmail_submit_enable="NO"
159 sendmail_outbound_enable="NO"
160 sendmail_msp_queue_enable="NO"
161 #ifconfig_ue0="198.18.3.5/24"
162 #defaultrouter="198.18.3.1"
163 __EORC__
164
165 cat > $MNTDIR/etc/ttys <<__EOTTYS__
166 ttyv0 "/usr/libexec/getty Pc" xterm on secure
167 ttyv1 "/usr/libexec/getty Pc" xterm on secure
168 ttyv2 "/usr/libexec/getty Pc" xterm on secure
169 ttyv3 "/usr/libexec/getty Pc" xterm on secure
170 ttyv4 "/usr/libexec/getty Pc" xterm on secure
171 ttyv5 "/usr/libexec/getty Pc" xterm on secure
172 ttyv6 "/usr/libexec/getty Pc" xterm on secure
173 ttyv7 "/usr/libexec/getty Pc" xterm on secure
174 ttyu0 "/usr/libexec/getty 3wire.115200" dialup on secure
175 __EOTTYS__
176
177 # Generate loader.conf. W/o this, we seem to drop to a debugger.
178 cat > $MNTDIR/boot/loader.conf <<__EOF__
179 hw.bcm2835.sdhci.hs=0
180 __EOF__
181
182 # Extra config bits to make things better
183 # Set time to UTC
184 cp -iv $MNTDIR/usr/share/zoneinfo/UTC /mnt/etc/localtime
185 # Setup syslog to log to our loghost
186 echo "*.* @log.cmhome/" >> $MNTDIR/etc/syslog.conf
187 # Set SSH to be pubkey only
188 sed -i -e 's/##ChallengeResponseAuthentication\ yes/ChallengeResponseAuthentication\ no/' \
189 $MNTDIR/etc/ssh/sshd_config
190
191 # Add user louisk, create $HOME, copy pubkey, set permissions/ownership
192 mkdir -p $MNTDIR/home/louisk/.ssh
193 pw -V /mnt/etc useradd louisk -u 1001 -s /bin/tcsh -d /home/louisk
194 echo "password" | pw -V /mnt/etc usermod louisk -h 0
195 pw -V $MNTDIR/etc groupmod wheel -n louisk
196 cp ~louisk/.ssh/authorized_keys $MNTDIR/home/louisk/.ssh
197 chmod 700 $MNTDIR/home/louisk/.ssh
198 chmod 600 $MNTDIR/home/louisk/.ssh/authorized_keys
199 chown -R 1001 $MNTDIR/home/louisk
200
201 umount $MNTDIR
202 mdconfig -d -u $MDFILE
203
204 # compress image
205 gzip $IMG
206 }
207
208 # main()
209 if [ "$UPDATE" == "YES" ] ; then
210 update_source
211 fi
212
213 if [ "$NEW" == "YES" ] ; then
214 get_source
215 generate_kernel_config
216 fi
217
218 if [ "$BUILD" == "YES" ] ; then
219 build
220 fi
221
222 if [ "$IMAGE" == "YES" ] ; then
223 generate_image
224 fi
With this, I can (relatively) easily test new builds and images somewhat independently. Nice when I just want to make a change to an rc script, or config file and don’t need to rebuild the entire system. Once you have the image, you can copy it to the system with the SD card and then use dd(1) to write out the image.
NOTE: Rather than do this very manual approach, I’d now suggest using crochet
Comments