Embedded Kanotix
So meldet sich mein Rechner blackbox per SSH:
BusyBox v1.00-rc3 (2004.09.30-12:24+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
~ # uname -a
Linux blackbox 2.6.8.1-kanotix-5 #1 Sun Sep 19 14:41:18 CEST 2004 i586 unknown
~ # df
Filesystem 1k-blocks Used Available Use% Mounted on
/dev/hda1 30721 7660 21475 26% /
tmpfs 29224 4 29220 0% /tmp
~ # free
total used free shared buffers
Mem: 58448 5984 52464 0 152
Swap: 0 0 0
Total: 58448 5984 52464
~ #
Hardware: PC104, 32MB Compact Flash, 64MB Ram, National Geode GX1 Prozessor mit 200 MHz
Software: Ein (bis zur Unkenntlichkeit) abgespecktes Kanotix BH8. Original Kernel, original libc, busybox, dropbear (SSH) und tinylogin.
Mein Kochrezept, um ein Embedded Kanotix zu realisieren:
Ein paar Definitionen
DEVICE=/dev/sdc
PARTITION=/dev/sdc1
# Mountpoint
FLASH=/mnt/sdc1
1.) bootbare Linux Partition anlegen
cfdisk $DEVICE
2.) Filesystem erzeugen
mkfs.ext2 $PARTITION
3.) Checks ausschalten
(bash)tune2fs -c 0 -i 0 $PARTITION
4.) CF mounten
mount $PARTITION $FLASH
5.) $FLASH/lost+found kann gelöscht werden
6.) GRUB installieren
grub-install --no-floppy --root-directory=$FLASH $DEVICE
echo "(hd0) /dev/hda" > $FLASH/boot/grub/device.map
7.) kernel -> $FLASH/boot/vmlinuz kopieren
8.) Benötigte Module nach $FLASH/lib/modules... kopieren
9.) $FLASH/boot/grub/menu.lst anpassen, z.B.:
(bash)
default 0
timeout 10
#German keyboard (darf nur einmal aufgerufen werden)
setkey y z
setkey z y
setkey Y Z
setkey Z Y
setkey equal parenright
setkey parenright parenleft
setkey parenleft asterisk
setkey doublequote at
setkey plus bracketright
setkey minus slash
setkey slash ampersand
setkey ampersand percent
setkey percent caret
setkey underscore question
setkey question underscore
setkey semicolon less
setkey less numbersign
setkey numbersign backslash
setkey colon greater
setkey greater bar
setkey asterisk braceright
title Linux ash.static
root (hd0,0)
kernel /boot/vmlinuz root=/dev/hda1 init=/bin/ash.static
boot
title Linux
root (hd0,0)
kernel /boot/vmlinuz root=/dev/hda1
boot
10.) Eine minimale Shell zur Verfügung stellen
(bash)mkdir $FLASH/bin
cp -a /bin/ash.static $FLASH/bin
11.) Devices einrichten
(bash)mkdir $FLASH/dev
for n in 0 1 2 3 4 5 6 7 8 9; do
mknod $FLASH/dev/tty$n c 4 $n
chown root:tty $FLASH/dev/tty$n
chmod 666 $FLASH/dev/tty$n
done
mknod $FLASH/dev/tty c 5 0
mknod $FLASH/dev/console c 5 1
12.) UNIX 98 pty devices einrichten, noch nicht nötig
mkdir $FLASH/dev/pts
mknod $FLASH/dev/ptmx c 5 2
Jetzt müßte der Kernel schon mal mit ash.static starten...
Auf meinem Entwicklungssystem besteht folgende Verzeichnisstruktur:
/root
/projects
/blackbox
/src
/busybox
/dropbear
/tinylogin
/target
...
/template
...
make_target
make_template
template.tgz
Wenn der Kernel mit ash.static startet, dann ein Abbild in template erzeugen.
und mit ./make_template ein komprimiertes Abbild erzeugen.
make_template:
#!/bin/sh
cd template
tar cvfz ../template.tgz
In template/etc sind jetzt einige Anpassungen nötig, bei mir siehts so aus:
/dropbear
/init.d
/rcS.d
busybox.conf
fstab
hosts
hostname
inittab
group
gshadow
passwd
shadow
Das Verzeichnis dropbear enthält die SSH-keys.
group, gshadow, passwd und shadow können (erstmal) vom Entwicklungsrechner übernommen werden.
fstab:
/dev/hda1 / ext2 defaults 0 0
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
pts /dev/pts devpts gid=5,mode=0620 0 0
hosts und hostname sind klar.
init.d und
rcS?.d gehören zu init, inittab weicht allerdings vom Standard ab, da busybox verwendet wird.
inittab:
# Run first
::sysinit:/etc/init.d/rcS
#
::ctrlaltdel:/sbin/reboot
# To do before rebooting
::shutdown:/bin/umount -a -r
# Restart init
::restart:/sbin/init
#Shells on tty1..4
tty1::respawn:/sbin/getty 38400 /dev/tty1
tty2::respawn:/sbin/getty 38400 /dev/tty2
tty3::respawn:/sbin/getty 38400 /dev/tty3
tty4::respawn:/sbin/getty 38400 /dev/tty4
Drei Softwarepakete liefern kompakte Programme für den Embedded-Bereich:
Die Quellen nach src installieren und anpassen. Die Default-Werte sind soweit ganz gut. Nur bei dropbear habe ich "dropbearmulti" in options.h eingestellt.
Mit make_target wird jetzt alles zusammen gemixt, template.tgz wird entpackt, zusätzliche (Standard-)Programme werden kopiert, busybox, dropbear und tinylogin werden installiert, einige Standard-Libraries (pam, terminfo,..) werden installiert und anschließend werden per ldd alle Library-Abhängigkeiten ermittelt und die zugehörigen *.so kopiert.
make_target:
#!/bin/sh
WORK="/root/projects/blackbox
TARGET="$WORK/target"
#BINS="clear dmesg fuser gawk login netcat passwd pico rz scp setserial sftp smbclient smbpasswd ssh ssh-add ssh-agent ssh-keyconverter ssh-keygen ssh-keyscan strace stty su sudo sz zip"
#SBINS="dhcpcd dhcpd hwclock mgetty netdate nmbd nscd portmap pppd smbd sshd tcpd"
BINS="fuser apm"
SBINS="hwclock"
function error {
echo " ERROR: " $* " ERROR"
}
function do_cp {
cp -puv $1 $2 || error "cp $1 $2"
}
# MAIN
if [ ! -d $TARGET ] ; then
error "could not find the target-directory $TARGET"
exit 1;
fi
echo "first we delete old stuff"
rm -rf $TARGET/*
echo "install template"
cd $TARGET
tar xzvf $WORK/template.tgz
cd $WORK
if [ "$BINS" ] ; then
echo "copy $BINS to /bin:"
mkdir -p $TARGET/bin
mkdir -p $TARGET/usr/bin
for i in $BINS ; do
if [ -e /bin/$i ] ; then
do_cp /bin/$i $TARGET/bin
strip $TARGET/bin/$i
elif [ -e /usr/bin/$i ] ; then
do_cp /usr/bin/$i $TARGET/usr/bin
strip $TARGET/usr/bin/$i
else
error "cannot locate /bin/$i nor /usr/bin/$i"
fi
done
fi
if [ "$SBINS" ] ; then
echo "copy $SBINS to /sbin:"
mkdir -p $TARGET/sbin
mkdir -p $TARGET/usr/sbin
for i in $SBINS ; do
if [ -e /sbin/$i ] ; then
do_cp /sbin/$i $TARGET/sbin
strip $TARGET/sbin/$i
elif [ -e /usr/sbin/$i ] ; then
do_cp /usr/sbin/$i $TARGET/usr/sbin
strip $TARGET/usr/sbin/$i
else
error "cannot locate /sbin/$i nor /usr/sbin/$i"
fi
done
fi
# busybox updaten
echo "update busybox"
cd $WORK/src/busybox
make all
make install
cd _install
tar czf $WORK/bb.tgz *
cd $TARGET
tar xzvf $WORK/bb.tgz
cd $WORK
# dropbear updaten
echo "update dropbear"
cd $WORK/src/dropbear
make dropbearmulti
cp dropbearmulti $TARGET/usr/sbin
ln -s dropbearmulti $TARGET/usr/sbin/dropbear
ln -s dropbearmulti $TARGET/usr/sbin/dropbearkey
ln -s dropbearmulti $TARGET/usr/sbin/dropbearconvert
make scp
cp scp $TARGET/usr/bin
# tinylogin updaten
echo "update tinylogin"
cd $WORK/src/tinylogin
make all
make install
cd _install
tar czf $WORK/tl.tgz *
cd $TARGET
tar xzvf $WORK/tl.tgz
cd $WORK
# copy needed libs
echo "copy terminfo :"
mkdir -p $TARGET/usr/share/terminfo/l
cp -puv /usr/share/terminfo/l/linux $TARGET/usr/share/terminfo/l
mkdir -p $TARGET/usr/lib/terminfo/l
cp -puv /usr/lib/terminfo/l/linux $TARGET/usr/lib/terminfo/l
echo "copy pam & co:"
cp -av /etc/pam.d $TARGET/etc
cp -av /etc/security $TARGET/etc
cp -av /etc/nsswitch.conf $TARGET/etc
echo "copy /lib/security/*"
mkdir -p $TARGET/lib/security
cp -r /lib/security/* $TARGET/lib/security
echo "copy ld-linux.so.*"
for i in /lib/ld-linux.so.[0-9] ; do
do_cp $i $TARGET/lib
strip $TARGET/$i
done
echo "copy libnss*"
for i in /lib/libnss* ; do
do_cp $i $TARGET/lib
strip $TARGET/$i
done
echo "copy libraries dynamic ..."
LIBS=$( ldd $TARGET/sbin/* $TARGET/bin/* $TARGET/usr/bin/* $TARGET/usr/sbin/* $TARGET/lib/security/* 2> /dev/null | grep "[[:space:]]lib" | awk '{print $1}' | sort -u )
echo "copy $LIBS to /lib :"
for i in $LIBS ; do
if [ -e /lib/$i ] ; then
do_cp /lib/$i $TARGET/lib
strip $TARGET/lib/$i
elif [ -e /usr/lib/$i ] ; then
do_cp /usr/lib/$i $TARGET/usr/lib
strip $TARGET/usr/lib/$i
else
error "cannot locate /lib/$i nor /usr/lib/$i"
fi
done
Zum Abschluß wird target ins Flash kopiert:
Fortsetzung folgt...