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.tgz

To 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 ./install

Run 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.

CompilingDSLinuxOnBSD (last edited 2008-01-22 14:02:38 by localhost)