Moin moin! (Auf vielfachen Wunsch hin uebersetze ich meinen Orignalen Post jetzt mal auf Deutsch. )
Vor einiger Zeit brauchte ich mal ein besonders schlankes Raspberry Pi Image. Es gab zwar fertige Distributionen, und Builder wie Yocto und Linux from Scratch. Aber die waren noch immer nicht ganz das, was ich brauchte. Daher habe ich mich entschieden, selbst eine Sammlung von Skripten zu erstellen. In unregelmaessigen Abstaenden aktualisiere ich die immer auf http://dettus.net/detLFS/, aber hier wuerde ich jetzt mal eine Anleitung mit Euch teilen, wie ihr selbst zu einem besonders kleinen Image kommt.
ALS ALLERERSTES solltet ihr wissen, als welches Device eine SD-Karte bei euch auftaucht. Das kriegt ihr raus, indem ihr mit
nachguckt, als was sie auftaucht, nachdem ihr sie eingelegt habt.
Danach solltet ihr ein Verzeichnis anlegen, und darin das skeldir.tgz entpacken, welches ich an diesen Thread angehaengt habe.
Dieses Paket enthaelt alle notwendigen Startskripte und Basis-Konfigurationen. Unter anderem wird das root-password auf "root" gesetzt.
Nachdem ihr das getan habt, BLEIBT IN DEM VERZEICHNIS "myVeryOwnLinux". Dann muesst ihr einige Source-Pakete runterladen. Das geht am einfachsten mit folgendem Skript:
#!/bin/sh
# $Id: 0_getit.sh 53 2019-03-05 05:38:34Z dettus $
echo "
----- -----
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
\\ / \\ / \\
\\ / \\ / \\
----- ----- detLFS -
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
http://www.dettus.net/detLFS/detLFS_0.06.tar.gz
This script is downloading the packages prior to anything else.
It is also unpacking them in the Sources folder, and renamining
them. This makes upgrading the system easier, because the Version
numbers have to be changed in here, nowhere else.
The kernel is being downloaded from the Raspberry Github, since
this is the platform I plan on running everything on.
" ; date
export DOWNLOADSDIR=`pwd`/Downloads
export SOURCESDIR=`pwd`/Sources
mkdir -p $DOWNLOADSDIR
mkdir -p $SOURCESDIR
echo ">>> downloading the kernel, specifically for the Raspberry Pi" ; date
(
cd $DOWNLOADSDIR
git clone https://github.com/raspberrypi/linux
git reset --hard git 4eda74f2dfcc8875482575c79471bde6766de3ad # this version of the kernel matches the pre-defined config file. you can use the latest version, but then you'd have to change 2_basesytem.sh as well.
rm -rf linux/.git
cp -r $DOWNLOADSDIR/linux $SOURCESDIR/
)
echo ">>> downloading Raspberry Pi's bootloader" ; date
(
wget -O $DOWNLOADSDIR/bootcode.bin "https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/bootcode.bin"
wget -O $DOWNLOADSDIR/start.elf "https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start.elf"
)
echo ">>> downloading busybox" ; date
(
# if you are updating to a new version of busybox, you will have to monitor the build process. the standard config_busybox file might fail.
wget --directory-prefix=$DOWNLOADSDIR -c https://busybox.net/downloads/busybox-1.27.0.tar.bz2
cd $SOURCESDIR ; tar xfj $DOWNLOADSDIR/busybox-1.27.0.tar.bz2 ; mv busybox-1.27.0 busybox
)
echo ">>> downloading binutils" ; date
(
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/binutils/binutils-2.32.tar.xz
cd $SOURCESDIR ; tar xfJ $DOWNLOADSDIR/binutils-2.32.tar.xz ; mv binutils-2.32 binutils
)
echo ">>> downloading glibc" ; date
(
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/glibc/glibc-2.29.tar.xz
cd $SOURCESDIR ; tar xfJ $DOWNLOADSDIR/glibc-2.29.tar.xz ; mv glibc-2.29 glibc
)
echo ">>> downloading gcc" ; date
(
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.xz
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/mpfr/mpfr-4.0.2.tar.xz
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/gcc/gcc-8.3.0/gcc-8.3.0.tar.gz
cd $SOURCESDIR ; tar xfz $DOWNLOADSDIR/gcc-8.3.0.tar.gz ; mv gcc-8.3.0 gcc
cd gcc
tar xfJ $DOWNLOADSDIR/gmp-6.1.2.tar.xz ; mv gmp-6.1.2 gmp
tar xfJ $DOWNLOADSDIR/mpfr-4.0.2.tar.xz ; mv mpfr-4.0.2 mpfr
tar xfz $DOWNLOADSDIR/mpc-1.1.0.tar.gz ; mv mpc-1.1.0 mpc
)
echo ">>> downloading make" ; date
(
wget --directory-prefix=$DOWNLOADSDIR -c ftp://ftp.gnu.org/gnu/make/make-4.2.1.tar.gz
cd $SOURCESDIR ; tar xfz $DOWNLOADSDIR/make-4.2.1.tar.gz ; mv make-4.2.1 make
# fixing make/glob/glob.c to circumvent an old __alloca bug
echo "232a233
> # define __alloca alloca" | patch -p0 make/glob/glob.c
)
echo ">>> done" ; date
Alles anzeigen
Danach koennt ihr euren ganz eigenen, ganz persoenlichen Cross-Compilier compilieren. Die meisten Menschen haben Angst davor, weil es kein trivialer Prozess ist. Aber wenn man erstmal verstanden hat, dass man dazu einen halben Linux-Kernel build, mehrmals die glibc UND gcc nacheinander compilieren muss, ist es eigentlich ganz einfach.
Ich habe mir erlaubt, den Cross-Compiler noch zu testen, indem ich vorher folgende Datei angelegt habe:
Aber ohne geht es auch.
Das Skript:
#!/bin/sh
# $Id: 1_buildtools.sh 41 2017-07-15 11:21:51Z dettus $
echo "
----- -----
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
\\ / \\ / \\
\\ / \\ / \\
----- ----- detLFS -
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
http://www.dettus.net/detLFS/detLFS_0.06.tar.gz
The purpose of this script is to build the cross compiler to be used later.
Hopefully, the previous scripts are finished at this point.
" ; date
export TOOLSDIR=`pwd`/Tools
export BUILDDIR=`pwd`/Build
export SOURCESDIR=`pwd`/Sources
export DOWNLOADSDIR=`pwd`/Downloads
mkdir -p $BUILDDIR
mkdir -p $TOOLSDIR
echo ">>> installing Kernel Headers" ; date
(
cd $BUILDDIR
cp -r $SOURCESDIR/linux .
cd linux
echo ">>>" ; date
cd linux
mkdir -p $TOOLSDIR/usr/include/asm
make ARCH=arm INSTALL_HDR_PATH=$TOOLSDIR/usr headers_install
)
echo ">>> installing glibc headers" ; date
(
cd $BUILDDIR
mkdir glibc1 ; cd glibc1
CC=gcc NM=nm $SOURCESDIR/glibc/configure --host=arm-linux-gnueabihf --prefix=$TOOLSDIR/ --with-headers=$TOOLSDIR/usr/include --with-fp
make -k cross-compiling=yes install-headers
mkdir -p $TOOLSDIR/include/gnu/
touch $TOOLSDIR/include/gnu/stubs.h
)
echo ">>> installing glibc headers" ; date
(
cd $BUILDDIR
mkdir glibc2 ; cd glibc2
CC=gcc NM=nm $SOURCESDIR/glibc/configure --host=arm-linux-gnueabihf --prefix=$TOOLSDIR/arm-linux-gnueabihf/ --with-headers=$TOOLSDIR/usr/include --with-fp
make -k cross-compiling=yes install-headers
mkdir -p $TOOLSDIR/arm-linux-gnueabihf/include/gnu/
touch $TOOLSDIR/arm-linux-gnueabihf/include/gnu/stubs.h
)
echo ">>> building binutils (cross)" ; date
(
cd $BUILDDIR
mkdir binutils1 ; cd binutils1
$SOURCESDIR/binutils/configure --target=arm-linux-gnueabihf --prefix=$TOOLSDIR --with-sysroot --disable-nls --disable-werror
make && make install
)
echo ">>> building gcc (cross)" ; date
(
cd $BUILDDIR
mkdir gcc1 ; cd gcc1
$SOURCESDIR/gcc/configure --target=arm-linux-gnueabihf --prefix=$TOOLSDIR --disable-nls --disable-shared --enable-languages=c,c++ --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --disable-multilib --with-headers=$TOOLSDIR/usr/include --with-build-time-tools=$TOOLSDIR --with-build-sysroot=$TOOLSDIR
make all-target-libgcc && make install-gcc && make install-target-libgcc
)
echo "At this point, the cross compiler can be used to build the glibc" ; date
export PATH=$TOOLSDIR/bin:$TOOLSDIR/usr/bin:$PATH
echo ">>> installing glibc (for real)" ; date
(
cd $BUILDDIR
mkdir glibc3 ; cd glibc3
$SOURCESDIR/glibc/configure --host=arm-linux-gnueabihf --prefix=$TOOLSDIR --with-headers=$TOOLSDIR/usr/include --with-fp
make cross-compiling=yes
make cross-compiling=yes install
make install
)
echo ">>> installing glibc (for the build)" ; date
(
cd $BUILDDIR
mkdir glibc4 ; cd glibc4
$SOURCESDIR/glibc/configure --host=arm-linux-gnueabihf --prefix=$TOOLSDIR/arm-linux-gnueabihf/ --with-headers=$TOOLSDIR/usr/include --with-fp
echo ">>>" ; date
make cross-compiling=yes
make cross-compiling=yes install
make install
)
echo ">>> building gcc (with shared)" ; date
(
cd $BUILDDIR
mkdir gcc2 ; cd gcc2
$SOURCESDIR/gcc/configure --target=arm-linux-gnueabihf --prefix=$TOOLSDIR --disable-nls --enable-languages=c,c++ --disable-multilib --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-headers=$TOOLSDIR/usr/include --with-build-time-tools=$TOOLSDIR
echo ">>>" ; date
make all-target-libgcc && make install-gcc && make install-target-libgcc
make
make install
)
echo "Checking the Tools" ; date
$TOOLSDIR/bin/arm-linux-gnueabihf-gcc -o Helloworld_shared.app helloworld.c
$TOOLSDIR/bin/arm-linux-gnueabihf-gcc -static -o Helloworld_static.app helloworld.c
file Helloworld_shared.app
file Helloworld_static.app
echo ">>> done" ; date
Alles anzeigen
Nachdem der Cross-Compiler gebaut wurde, kann er dazu verwendet werden den Linux-Kernel und Busybox zu bauen. Wenn ihr das Skript genauer anguckt, dann werdet ihr feststellen, dass darin ein "make menuconfig" verwendet wird. Das verlangt natuerlich nach Benutzerinteraktion. Ihr muesst dann Einstellungen vornehmen, die ich Euch hier leider nicht erklaeren kann, weil ich sie leider selbst nicht kenne.
Auch werdet ihr lange warten muessen.
EHRLICH: Es tut mir leid...
Zum Trost habe ich aber noch ein Osterei versteckt. In den Kommentaren findet ihr einen Hinweis, wie ihr Euer eigenes, ganz persoenliches Logo beim Booten anzeigen koennt. Mal etwas anderes als immer nur die Himbeere. EDIT: Bitte keine verbotenen Symbole oder AfD-Logos. Das hat der Raspberry nicht verdient.
#!/bin/sh
# $Id: 2_basesystem.sh 49 2019-03-04 10:29:39Z dettus $
echo "
----- -----
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
\\ / \\ / \\
\\ / \\ / \\
----- ----- detLFS -
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
http://www.dettus.net/detLFS/detLFS_0.06.tar.gz
The purpose of this script is to build the linux Kernel and Busybox.
It will also copy the init-scripts and the bootloader into the Destination
directory. The configuration part could be performed with menuconfig, for
the purpose of minimalism, this script is copying a generic configuration.
Hopefully, the previous scripts are finished at this point.
" ; date
export DETLFSROOT=`pwd`
export TOOLSDIR=`pwd`/Tools
export BUILDDIR=`pwd`/Build
export SOURCESDIR=`pwd`/Sources
export DOWNLOADSDIR=`pwd`/Downloads
export DESTINATIONDIR=`pwd`/Destination
mkdir -p $DESTINATIONDIR
export PATH=$TOOLSDIR/bin:$PATH
echo ">>> building KERNEL (raspberry pi specific)" ; date
(
cd $BUILDDIR/
rm -rf linux ; cp -r $SOURCESDIR/linux .
cd linux
export KERNEL=kernel7
# if you want to create your very own bootlogo, do something like this
# convert IMAGE.png -scale \!80x80 /tmp/mylogo.png
# pngtopnm /tmp/mylogo.png | ppmquant 224 | pnmnoraw >drivers/video/logo/logo_linux_clut224.ppm
make ARCH=arm CROSS_COMPILE=$TOOLSDIR/bin/arm-linux-gnueabihf- bcm2709_defconfig
make ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=$TOOLSDIR/bin/arm-linux-gnueabihf- zImage modules dtbs
mkdir -p $DESTINATIONDIR/boot $DESTINATIONDIR/usr
make ARCH=arm CROSS_COMPILE=$TOOLSDIR/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=$DESTINATIONDIR/ INSTALL_HDR_PATH=$DESTINATIONDIR/usr/ modules_install headers_install
cp arch/arm/boot/zImage $DESTINATIONDIR/boot/kernel.img
cp arch/arm/boot/dts/*.dtb $DESTINATIONDIR/boot
mkdir -p $DESTINATIONDIR/boot/overlays
cp arch/arm/boot/dts/overlays/*.dtb $DESTINATIONDIR/boot/overlays
cp arch/arm/boot/dts/overlays/README $DESTINATIONDIR/boot/overlays
)
echo ">>> building BUSYBOX" ; date
(
cd $BUILDDIR/
rm -rf busybox ; cp -r $SOURCESDIR/busybox . ; cd busybox
make ARCH=arm CROSS_COMPILE=$TOOLSDIR/bin/arm-linux-gnueabihf- defconfig
make ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=$TOOLSDIR/bin/arm-linux-gnueabihf- install
cd _install && \
(
pwd
tar cvf - * | ( cd $DESTINATIONDIR ; tar xvf - )
)
date
)
echo ">>> copying skeldir/" ; date
(
cd $DETLFSROOT/skeldir
pwd
tar cvf - * | ( cd $DESTINATIONDIR ; tar xvf - )
)
echo ">>> copying raspberry specific bootloader files" ; date
(
cp $DOWNLOADSDIR/start.elf $DOWNLOADSDIR/bootcode.bin $DESTINATIONDIR/boot/
)
du -sh $DESTINATIONDIR
echo ">>>> done" ; date
Alles anzeigen
Danach findet sich alles, was ihr gebaut und konfiguriert habt in dem Verzeichnis "Destination" wieder. Dieses muss auf eine SD-Karte kopiert werden. Das ist ein gefaehrlicher Prozess.
Geht auf Nummer sicher, dass ihr wisst, welches Device die SD-Karte ist. Im Skript habe ich zur Sicherheit /dev/null angegeben.
Rauskriegen, welches Device es ist, tut mir, indem ihr nach dem Einstecken in Euren Computer
eingebt. Merkt euch den Device-Namen, und tragt ihn im Skript anstelle des /dev/null ein. Mit einem Editor Eurer Wahl. Ausserdem muesst ihr die Zeile
rauswerfen.
Wenn ihr das Skript dann endlich startet, wird es fuer Euch fdisk aufrufen. Das wichtige ist, dass ihr dort zwei Partionen anlegt:
Partition 1, typ c=msdos, 64 Mbyte gross
Partition 2, typ 83=Linux, 1Gbyte oder mehr.
wie gross die tatsaechlich sein sollten, verraet euch aber das Skript.
auf jeden Fall sind die Befehle bei fdisk dafuer
- n, new partition, Groesse ist 64M bzw. 1G.
- t, type. (c=MSDOS, 83=Linux)
- w, write (und das Programm verlassen)
eine falsch angelegte partition koennt ihr mit
- d, delete, loeschen
- q, quit, beenden ohne speichern
vermeiden.
Und jetzt das boese, boese Skript:
#!/bin/sh
# $Id: 4_mksdcard.sh 44 2019-03-02 10:41:03Z dettus $
echo "
----- -----
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
\\ / \\ / \\
\\ / \\ / \\
----- ----- detLFS -
/ \\ / \\ /
/ \\ / \\ /
----- ----- -----
http://www.dettus.net/detLFS/detLFS_0.06.tar.gz
The purpose of this script is to prepare the SD Card. It has
to be run with ROOT PRIVILEDGES and is DANGEROUS. PLEASE LOOK
AT IT BEFORE YOU RUN IT!!!
Hopefully, the previous scripts are finished at this point.
" ; date
echo "aborting now." ; exit ## COMMENT THIS ONE OUT ONCE YOU UNDERSTAND THE SCRIPT
export DESTINATIONDIR=`pwd`/Destination
export MNTDIR=`pwd`/Mnt
export MMCCARD="/dev/null"
export BOOTFS=$MMCCARD"1"
export ROOTFS=$MMCCARD"2"
echo "WARNING! THIS WILL ERASE THE CONTENT OF "$MMCCARD
echo "AND CREATE boot "$BOOTFS" AND root "$ROOTFS" ON IT."
echo "YOU HAVE 30 seconds TO ABORT"
sleep 30
mkdir -p $MNTDIR
for I in $MMCCARD"*"
do
umount $I
done
dd if=/dev/zero of=$MMCCARD bs=1M count=16
echo "please create one msdos-partioni (16Mb), and one linux-partition."
echo "n - new partition"
echo "t - type"
echo " c=msdos, 83=linux"
echo "w - write"
echo
echo "the boot partition should be at least this big:"
du -sh $DESTINATIONDIR/boot
echo "and the rest:"
du -sh $DESTINATIONDIR/
fdisk $MMCCARD
echo "formatting "$MMCCARD
mkfs.msdos $BOOTFS
mkfs.ext4 $ROOTFS
echo
mkdir $MNTDIR
mount $ROOTFS $MNTDIR
mkdir $MNTDIR/boot
mount $BOOTFS $MNTDIR/boot
cd $MNTDIR
( cd $DESTINATIONDIR ; tar cvf - * ) | ( tar xvf - )
mknod dev/console c 5 1
mknod dev/null c 1 3
mknod dev/tty0 c 4 0
mknod dev/tty1 c 4 1
mknod dev/tty2 c 4 2
mknod dev/ttyAMA0 c 204 64
chown -R root:root .
cd ..
du -h $MNTDIR
umount $BOOTFS
umount $ROOTFS
echo ">>> done" ; date
Alles anzeigen
Viel Spass damit!
Wie gesagt, in unregelmaessigen Abstaenden veroeffentliche ich auch immer eine neue Version auf meiner Homepage.
Ausserdem habe ich mir erlaubt, die aktuelle Dokumentation ebenfalls mit hochzuladen.