Introduction
With a bit of effort, DSLinux can be built on BSD. You'll need Linux binary emulation enabled and working. This guide covers FreeBSD, NetBSD and OpenBSD.
We are going to construct a small Linux environment that we can chroot into. The environment will have everything necessary to build dslinux, and is in fact a subset of a Slackware Linux installation. I chose Slackware because the packages are easy to unpack manually. No special tools required.
The setup described here has been verified to work on FreeBSD 6.1 and 6.2, NetBSD 3.0 and OpenBSD 4.1.
I chose to use Slackware packages from Slackware 9.0, since the Linux kernel version emulated by FreeBSD-6.1 (2.4.2) is relatively close to the Slackware 9.0 kernel version (2.4.20), while still providing glibc version 2.3, which we need to run the pre-built toolchain. In fact, version numbers do not really seem to matter that much. They are the least of our problems. So go ahead and try to use Slackware 10 or whatever. Earlier versions than 9.0 won't work.
If you are on a non-i386 architecture, you should either use a port of Slackware to your architecture if one exists, or use packages from another distribution that supports your architecture.
Now, this is the first command for this howto:
mkdir ~/dslinux
We will put everything into that directory.
Getting the Slackware packages
Pick your favourite slackware mirror (see this page), and go into the slackware-9.0/slackware directory.
Slackware is split up into several sections. Each section is a subdirectory of slackware-9.0/slackware/. Create directories to hold the packages of sections we are interested in:
mkdir -p ~/dslinux/packages/{a,ap,d,l}Then download packages so you have the following files in your package/* directories:
~/dslinux/packages/a:
bash-2.05b-i386-2.tgz
bin-8.5.0-i386-1.tgz
elflibs-9.0.3-i386-1.tgz
fileutils-4.1-i386-2.tgz
findutils-4.1.7-i386-1.tgz
gawk-3.1.1-i386-2.tgz
gettext-0.11.5-i386-1.tgz
glibc-solibs-2.3.1-i386-3.tgz
grep-2.5-i386-2.tgz
gzip-1.3.3-i386-2.tgz
sed-4.0.5-i386-2.tgz
sh-utils-2.0-i386-1.tgz
tar-1.13.25-i386-1.tgz
textutils-2.0-i386-1.tgz
util-linux-2.11z-i386-1.tgz
~/dslinux/packages/ap:
diffutils-2.8.1-i386-1.tgz
~/dslinux/packages/d:
binutils-2.13.90.0.18-i386-1.tgz
bison-1.35-i386-1.tgz
gcc-3.2.2-i386-3.tgz
gcc-g++-3.2.2-i386-1.tgz
gettext-tools-0.11.5-i386-1.tgz
kernel-headers-2.4.20-i386-5.tgz
make-3.80-i386-1.tgz
perl-5.8.0-i386-3.tgz
~/dslinux/packages/l:
glibc-2.3.1-i386-3.tgz
ncurses-5.3-i386-1.tgz
zlib-1.1.4-i386-3.tgzTo build the toolchain from source, you have to download these files too:
~/dslinux/packages/a:
bzip2-1.0.2-i386-4.tgz
~/dslinux/packages/n:
openssl-0.9.7a-i386-2.tgz
wget-1.8.2-i386-2.tgz
Unpacking the Slackware packages
Copy-paste the following script into a file called ~/dslinux/unpack.sh.
#!/bin/sh
# makes Slackware's install scripts work on BSD
fix_install_script() {
cp $1 $1.bak
cat $1.bak | sed -e 's/cp -a/cp -R/' \
-e "s/ldconfig/ldconfig-$$-nonexistent/" > $1
}
# create some required directories
for d in etc bin dev tmp var var/tmp usr usr/bin proc
do
[ -e $d ] || mkdir $d
done
# fake some files and programs we'll need.
if [ ! -e etc/passwd ]
then
echo "Creating chroot /etc/passwd"
echo "root:x:0:0:root:/:/bin/bash" > etc/passwd
fi
if [ ! -e etc/group ]
then
echo "Creating chroot /etc/group"
echo "root:x:0:" > etc/group
fi
if [ ! -e etc/hostname ]
then
echo "Creating chroot /etc/hostname"
echo "echo `hostname`" > etc/hostname
fi
# unpack packages
for p in "$@"
do
# remove install script from previous package
[ -d ./install ] && rm -r ./install
# unpack
echo "Unpacking $p"
tar -zxf $p
# run install script if present
if [ -e ./install/doinst.sh ]
then
fix_install_script ./install/doinst.sh
sh ./install/doinst.sh
fi
done
# somehow this symlink is not set by the bash package
[ ! -L bin/sh ] && (cd bin ; ln -sf bash sh)
# remove install script from last package
[ -d ./install ] && rm -r ./installRun the script like so:
cd ~/dslinux && sh ./unpack.sh ./packages/*/*tgz
Tweaking the environment
Copy-paste the following script into a file called ~/dslinux/start.sh:
#!/bin/sh export PATH="/toolchain/bin:$PATH" export PS1="\u@\h CHROOT \w $ " export HOME=/ exec /bin/bash
Add an entry for your user to ~/dslinux/etc/passwd. Just copy the passwd entry for root and adjust the user name, uid, group name and gid fields.
For example, my passwd looks like this:
root:x:0:0:root:/:/bin/bash stsp:x:1000:1000:stsp:/:/bin/bash
You should also add an entry for your user's default group to ~/dslinux/etc/group. This is very simple. Here is an example:
stsp:x:1001:
Getting the toolchain
See here for instructions on how to obtain the toolchain.
In case you want to or have to compile it yourself, it should compile fine inside the chroot. In fact, the "official" dslinux toolchain releases for Linux/i686 have likely been compiled on FreeBSD inside a chroot setup as described here. Note that some additional slackware packages may be required to compile the toolchain. All build-time dependencies are listed in the toolchain/README file.
You will need the toolchain binaries in your path when you're in the chroot. Assuming that your toolchain binaries are in ~/dslinux/dslinux-toolchain-2006-11-04-i686/bin, create a symlink so the PATH that is set in start.sh can pick up the toolchain binaries:
(cd ~/dslinux && ln -s toolchain-2006-11-04-i686 toolchain)
On FreeBSD and OpenBSD, you need to manually brand statically linked binaries as Linux binaries.
FreeBSD:
cd ~/dslinux/toolchain brandelf -t Linux arm-linux-elf/bin/elf2flt brandelf -t Linux arm-linux-elf/bin/flthdr brandelf -t Linux bin/arm-linux-elf-elf2flt brandelf -t Linux bin/arm-linux-elf-flthdr brandelf -t Linux bin/ndstool
OpenBSD:
cd ~/dslinux/toolchain elf2olf -o linux arm-linux-elf/bin/elf2flt elf2olf -o linux arm-linux-elf/bin/flthdr elf2olf -o linux bin/arm-linux-elf-elf2flt elf2olf -o linux bin/arm-linux-elf-flthdr elf2olf -o linux bin/ndstool
This step is not needed on NetBSD.
Now we have a working toolchain.
Getting DSLinux sources
See this section for instructions. Put the sources into ~/dslinux/dslinux/.
Configuring sudo
On FreeBSD, sudo must be installed from ports:
cd /usr/ports/security/sudo && make install clean && rehash
On NetBSD, install sudo from pkgsrc:
cd /usr/pkgsrc/security/sudo && make install clean && rehash
OpenBSD has sudo pre-installed.
Now run visudo as root to configure sudo, and add a line like this at the bottom of the file, using your login instead of stsp:
stsp ALL = (ALL) NOPASSWD:/usr/sbin/chroot
Getting ready for chroot
FreeBSD
Now mount the dev and linproc filesystems into ~/dslinux. This needs to be done as root, unless you have usermount enabled.
mount_devfs devfs /home/stsp/dslinux/dev mount_linprocfs linprocfs /home/stsp/dslinux/proc
You can also add appropriate entries in /etc/fstab:
linproc /home/stsp/dslinux/proc linprocfs rw 0 0 devfs /home/stsp/dslinux/dev devfs rw 0 0
NetBSD and OpenBSD
On NetBSD and OpenBSD, there is no devfs, so create device nodes manually as root:
cd /home/stsp/dslinux mknod dev/zero c 2 12 mknod dev/null c 2 2 chmod 666 dev/*
To mount the linux proc filesystem, run
mount_procfs -o linux procfs ~/dslinux/proc
An example fstab line that automates this:
none /home/stsp/dslinux/proc procfs rw,linux 0 0
Additional steps needed on OpenBSD
On OpenBSD, Linux binaries require the /emul/linux/ directory to run correctly. We can easily take care of this by doing:
mkdir ~/dslinux/emul cd ~/dslinux/emul ln -s / linux
These commands need to be run on OpenBSD to make the dynamic loader work correctly:
elf2olf -o linux ~/dslinux/sbin/ldconfig cp -p ~/dslinux/lib/ld-2.3.1.so ~/dslinux/usr/bin/ld-2.3.1-olf.so elf2olf -o linux ~/dslinux/usr/bin/ld-2.3.1-olf.so perl /usr/ports/emulators/fedora/base/files/fix-ldd.pl ~/dslinux/bin/ld-2.3.1-olf.so
Next, edit the file ~/dslinux/usr/bin/ldd and replace the line
RTLDLIST=/lib/ld-linux.so.2
with this one:
RTLDLIST=/usr/bin/ld-2.3.1-olf.so
Finally, make sure these two lines are in ~/dslinux/etc/ld.so.conf:
/usr/lib /usr/i386-slackware-linux/lib
Chrooting
Now you can enter the chroot environment by running a command like:
sudo chroot -u stsp ~/dslinux /start.sh
Building DSLinux
cd /dslinux
Now build DSLinux, as described here.
