prep.sh

prep.sh
#!/bin/bash
# ================================ Konfiguracja ===============================
 
#Nazwa systemu - ustawiana jako hostname
HNAME="linuxembedded"
 
#Wersja jądra i katalog, w którym zostało zbudowane:
KERNEL="2.6.34"
KERNEL_BUILD_PATH="$HOME/BUILD/linux-$KERNEL"
 
#Zmienna określająca prefix Cross-kompilatora (używana do uruchamiania readelf/
CROSS_COMPILE=arm-unknown-linux-gnueabi
 
#Katalog zawierający zainstalowany program Busybox (wszystko jedno czy 
#poszczególne polecenia są dowiązaniami symbolicznymi czy twardymi):
BUSYBOX_INSTALL_PATH="$HOME/BUILD/busybox-1.18.0/_install"
 
#Katalog, w którym znajduje się biblioteka standardowa z toolchain-a 
#(przykład dla wersji zbudowanej przy pomocy Crosstool-ng) 
LIBRARIES_BUILD_PATH=\
"$HOME/x-tools/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/lib"
 
#Katalogi, w których skrypt szuka dodatkowych bibliotek i programów.
#Zdefinowane są dwie zmienne, aby można było część bibliotek budować
#ręcznie, a część automatycznie (np.: Buildrootem).
#Drugi katalog jest wyłączony (ustawiony na nieistniejący).
#Zakładamy, że biblioteki znajdują się w podkatalogach usr/lib.
STAGING=$HOME/staging
AUXILIARY=/noexistent
 
#Hasło konta root ustawiane w docelowym systemie.
HASLO="tajne"
 
#Lista programów, króre znajdą się w docelowym systemie są to ścieżki
#względne z odpowiednich katalogów z danymi. Należy w niej umieścić wszystkie
#programy, których zależności mają zostać sprawdzone i zainstalowane.
BINARIES=" \
bin/busybox \
usr/bin/openssl \
usr/bin/strace \
usr/bin/alsamixer \
usr/bin/aplay \
usr/bin/arecord \
usr/sbin/alsactl \
usr/bin/madplay \
usr/sbin/flash_erase \
usr/sbin/ubirmvol \
usr/sbin/ubiformat \
usr/sbin/ubimkvol \
usr/bin/l3enc \
usr/bin/ccrypt \
usr/bin/iconv \
usr/bin/espeak"
 
# ================================ Przygotowania ==============================
 
#Polecenie tworzy katalog tymczasowy i zapisuje jego nazwę w zmiennej $TARGET
TARGET=$(mktemp -d /tmp/target-XXXXXX)
 
#Kopiowane są pliki Busybox-a a następnie ustawiane zalecane atrybuty pliku
cp -a $BUSYBOX_INSTALL_PATH/* $TARGET
chmod u+s $TARGET/bin/busybox
 
#Instalacja modułów jądra do katalogu docelowego (powinno ono być już zbudowane).
make -C $KERNEL_BUILD_PATH ARCH=arm INSTALL_MOD_PATH=$TARGET modules_install
#Usuwanie dodatkowych plików instalowanych z modułami, niepotrzebnych 
#w Busybox-ie
for i in $TARGET/lib/modules/$KERNEL/{build,source,modules.builtin,\
modules.order,modules.alias,modules.alias.bin,modules.builtin.bin,\
modules.dep,modules.dep.bin,modules.symbols,modules.symbols.bin,\
modules.devname,modules.softdep} ; do
	rm -f $i
done 
 
#Tworzenie bazowych katalogów.
DIRS="\
proc \
sys \
tmp \
dev/pts \
dev/shm \
dev/snd \
dev/input \
etc/custom.d \
mnt/SD \
root \
lib \
usr/lib \
usr/share/alsa/cards \
usr/share/alsa/init \
usr/share/alsa/pcm \
usr/sbin \
usr/share/terminfo/v \
var/run \
var/cache/ldconfig"
 
for i in $DIRS; do
	mkdir -p $TARGET/$i 
done
chmod 1777 $TARGET/tmp
 
#Pliki urządzeń - tylko minimalny zestaw niezbędny do startu, pozostałe
#zostaną stworzone przez program mdev.
D=$TARGET/dev
 
sudo mknod $D/tty c 5 0
sudo mknod $D/console c 5 1
sudo mknod $D/null c 1 3
 
# ================================ Kopiowaine plików ==========================
#Jeżeli plik nie jest Busybox-em, to skopiuj go z jednego lub drugiego katalogu.
for i in $BINARIES; do
	if [ "$i" != "bin/busybox" ]; then
		if [ -e $STAGING/$i ]; then
			cp -av $STAGING/$i $TARGET/$i
		elif [ -e $AUXILIARY/$i ]; then
			cp -av $AUXILIARY/$i $TARGET/$i
		fi
	fi
done
 
#Znajdowanie i kopiowanie zależności:
while [ "$BINARIES" ]; do
  LIBRARIES=""
  for i in $BINARIES; do
    #Jeżeli ścieżka nie zaczyna się od /, zmień ją na pełną ścieżkę do pliku
    #w katalogu  docelowego obrazu         
    if [ "${i:0:1}" != "/" ]; then
      i="$TARGET/$i"
    fi
 
    #Do zmiennej z listą bibliotek dopisywane są te, których wymaga program.
    LIBRARIES="$LIBRARIES $(
      $CROSS_COMPILE-readelf -d $i | \
      awk '$2 == "(NEEDED)" { gsub(/[\[\]]/,"",$NF); print $NF }'
    )"
  done
  #W zmiennej LIBRARIES, jest teraz lista wszystkich bibliotek wymaganych
  #przez programy skopiowane w poprzednim kroku, a więc możemy wyczyścić
  #listę programów:
  BINARIES=""
 
  #Usuwane są powtarzające się wpisy
  LIBRARIES=$(echo $LIBRARIES | tr " " "\n" | sort -u)
 
  #Następna pętla zajmuje się kopiowaniem bibliotek w odpowiednie miejsca 
  for i in $LIBRARIES; do
    #Zmienna i przyjmuje po kolei nazwy bibliotek z listy, szukamy ich w
    #odpowienich miejscach.
    if [ -e "$LIBRARIES_BUILD_PATH/$i" ]; then
      LIBFILE="$LIBRARIES_BUILD_PATH/$i"
      PREFIX="lib"
    elif [ -e "$STAGING/usr/lib/$i" ]; then
      LIBFILE="$STAGING/usr/lib/$i"
      PREFIX="usr/lib"
    elif [ -e "$AUXILIARY/usr/lib/$i" ]; then
      LIBFILE="$AUXILIARY/usr/lib/$i"
      PREFIX="usr/lib"
    else
      #Nie udało się odnaleźć biblioteki - przetwarzana jest następna
      #można zastąpić instrukcją exit, która spowoduje zakończenie skryptu.
      PREFIX=""
      continue
    fi
    #W zmiennej LIBFILE - zapisana jest pełna ścieżka do biblioteki
    #w zmiennej PREFIX - ścieżka do podkatalogu w TARGET, w którym powinna
    #                    się znaleźć
 
    #Sprawdzamy, czy biblioteka nie znajduje się już na miejscu.
    if [ ! -e $TARGET/$PREFIX/$i ]; then
      #Nazwa biblioteki, zapisana w pliku wykonywalnym, wskazuje zazwyczaj
      #na plik, który jest dowiązaniem symbolicznym do właściwej biblioteki.
 
      #Odczytujemy ścieżkę rzeczywistego pliku z biblioteką.
      #Komenda zwraca pełną ścieżkę do pliku, na który wskazuje dowiązanie,
      #a jeżeli argument jest zwykłym plikiem - zwraca go. Następnie ścieżka
      #do pliku jest dodawana do zmiennej zawierającej pliki, których
      #zależności będą sprawdzane w następnym kroku.
      REALLIBFILE_FULL_PATH=$(readlink -f $LIBFILE)
      BINARIES="$BINARIES $REALLIBFILE_FULL_PATH"
 
      #Jeżeli plik biblioteki jest dowiązaniem symbolicznym, skopiowane
      #zostaną oba pliki - dowiązanie i docelowy:
      if [ -h $LIBFILE ]; then
        LIBFILE="$LIBFILE $REALLIBFILE_FULL_PATH"
      fi
      cp -av $LIBFILE $TARGET/$PREFIX
    fi
 
  done
  #Kolejny obrót pętli sprawdzi kolejne pliki z BINARIES
done
 
#Wszystkie biblioteki bibliotek konsolidowanych dynamicznie, znajdują się
# w odpowiednich ścieżkach.
 
# ================================ Haki =======================================
 
#Plik z definicją terminala używany przez ncurses
cp -av $STAGING/usr/share/terminfo/v/vt102 $TARGET/usr/share/terminfo/v/
 
#Dodatkowe biblioteki wykorzystywane przez bibliotekę standardową
#eglibc, GNU/libc.
cp -av \
  $LIBRARIES_BUILD_PATH/{libnss_files-2.9.so,libnss_files.so.2} \
  $TARGET/usr/lib
 
#Dane programu syntezy mowy
cp -av $STAGING/usr/share/espeak-data $TARGET/usr/share/
 
#Pliki konfiguracyjne bibliotek i narzędzi ALSA
cp -av $STAGING/usr/share/alsa/alsa.conf $TARGET/usr/share/alsa
touch $TARGET/usr/share/alsa/smixer.conf
cat << EOF > $TARGET/usr/share/alsa/cards/aliases.conf
<confdir:pcm/default.conf>
<confdir:pcm/dmix.conf>
<confdir:pcm/dsnoop.conf>
EOF
cp -av $STAGING/usr/share/alsa/pcm/* $TARGET/usr/share/alsa/pcm
cp -av $STAGING/usr/share/alsa/init/* $TARGET/usr/share/alsa/init
 
#Plik /init niezbędny w przypadku użycia systemu plików jako
#ramdysku
ln -s bin/busybox $TARGET/init
 
# =============== Skrypty startowe i pliki konfiguracyjne =====================
#mdev - automatyczne montowanie karty SD
cat << EOF > $TARGET/etc/mdev.conf
mmcblk[0-9]p1 0:0 644 @ /etc/custom.d/sd_on
mmcblk[0-9] 0:0 644 $ /etc/custom.d/sd_off
EOF
 
cat << EOF > $TARGET/etc/custom.d/sd_on
#!/bin/sh
cat /proc/mounts | grep ${MDEV} > /dev/null || \
mount -o noatime,sync,utf8 ${MDEV} /mnt/SD
EOF
 
cat << EOF > $TARGET/etc/custom.d/sd_off
#!/bin/sh
umount -fl /SD >/dev/null 2>/dev/null
EOF
 
chmod 755 $TARGET/etc/custom.d/*
 
#inittab - konfiguracja programu init
cat << EOF > $TARGET/etc/inittab
null::sysinit:/etc/rc.sysinit
ttyS0::askfirst:/sbin/getty 115200 ttyS0
null::shutdown:/bin/umount -a -r
EOF
 
#/etc/rc.sysinit - skrypt startowy
cat << EOF > $TARGET/etc/rc.sysinit
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sys /sys
echo $HNAME > /proc/sys/kernel/hostname
mount -t devpts devpts /dev/pts
/bin/ip link set lo up &
/sbin/mdev -s
EOF
chmod 755 $TARGET/etc/rc.sysinit
 
#nsswitch.conf
cat > $TARGET/etc/nsswitch.conf << EOF
passwd: files
group: files
shadow: files
hosts: files dns
networks: files
protocols: files
services: files
ethers: files
rpc: files
EOF
 
#strefa czasowa - plik jest kopiowany z systemu PC (dla GNU/libc)
cp -av /usr/share/zoneinfo/Europe/Warsaw $TARGET/etc/localtime
 
#/etc/hosts
cat > $TARGET/etc/hosts << EOF
127.0.0.1 $HNAME localhost
EOF
 
#konta użytkowników
cat << EOF > $TARGET/etc/passwd
root:x:0:0:root:/root:/bin/ash
EOF
 
T_HASLO=$(echo -n ${HASLO} | openssl passwd -1 -stdin -quiet)
T_DATA=$(( $( date +%s ) / ( 3600 * 24 ) ))
cat << EOF > $TARGET/etc/shadow
root:$T_HASLO:$T_DATA:0:99999:7:::
EOF
chmod 400 $TARGET/etc/shadow
 
cat << EOF > $TARGET/etc/group
root:x:0:
EOF
 
#Konfiguracja konsolidatora dla GNU/libc
touch $TARGET/etc/ld.so.conf
touch $TARGET/var/cache/ldconfig/aux-cache
/sbin/ldconfig -i -r $TARGET -C /etc/ld.so.cache /lib /usr/lib
 
# ============================== Przygotowanie obrazu =========================
 
#usuwanie symboli debuggera
# z plików wykonywalnych
find $TARGET{,/usr}/{,s}bin \
  -type f \
  ! -inum $(ls -i $TARGET/bin/busybox | cut -d' ' -f 1) \
  ! -name '*.sh' \
  -exec arm-unknown-linux-gnueabi-strip --strip-all {} \;
 
# z plików  bibliotek
find $TARGET{,/usr}/lib \
  -type f \
  ! -name '*.ko' \
  -exec chmod 755 {} \; \
  -exec arm-unknown-linux-gnueabi-strip --strip-debug {} \;
 
 
#Uprawnienia do plików - właścicielem wszystkich plików będzie root
sudo chown -R --no-dereference root:root $TARGET
 
#Wykonanie archiwum
sudo su -c "cd  $TARGET; find . | cpio -o -H newc > $HOME/rootfs.cpio"
 
#Zmiana właściciela pliku wynikowego
sudo chown $LOGNAME $HOME/rootfs.cpio
 
#Usunięcie tymczasowych plików
#sudo rm -rf $TARGET
ostatnio zmienione: 2011/08/19 13:50