listingi_patche_skrypty

Spis treści

Katalog roboczy

export CEL=/opt/target-arm
mkdir $CEL

Konto robocze

groupadd arm
useradd -m -g arm -s /bin/bash -k /dev/null arm
passwd arm
chown arm $CEL
su - arm

Środowisko

cat > ~/.bash_profile << "EOF"
exec env -i HOME=${HOME} TERM=${TERM} PS1='\{}u:\{}w$ ' /bin/bash
EOF
export CEL=/opt/target-arm
export PATH=$CEL/cross-tools/bin:/bin:/usr/bin
set +h
export LC_ALL=POSIX
source ~/.bash_profile
mkdir $CEL/cross-tools
ln -s $CEL/cross-tools /

(E)ABI

export BUILD="-mabi=aapcs-linux"

Dwa zestawy instrukcji

/* przykład.c */
int funkcja1(int c, int d)
{
	return c + d;
}
int funkcja2(int a, int b)
{
	a += 3;
	b -= 2;
	return funkcja1(a,b);
}
 
#Kompilujemy i sprawdzamy:
$ arm-linux-uclibcgnueabi-gcc -c -o test1.o przyklad.c 
$ arm-linux-uclibcgnueabi-gcc -c -mthumb -o test2.o przyklad.c 
$ size test1.o 
   text    data     bss     dec     hex filename
    120       0       0     120      78 test1.o
$ size test2.o 
   text    data     bss     dec     hex filename
     68       0       0      68      44 test2.o
 
#Drugi plik jest mniejszy o 52 bajty (43% !).

Kolejność bajtów w słowie

export TARGET="arm-unknown-linux-uclibcgnueabi"
#Określa architekturę, dla której kompilator będzie tworzył kod.
 
export HOST=$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")
#Określa architekturę na której działa kompilator. (zawartość zmiennej
#$MACHTYPE, ale z drugim polem zamienionym na słowo "cross"), Np.:
# x86_64-pc-linux-gnu -> x86_64-cross-linux-gnu
# x86_64-apple-darwin10.0 -> x86_64-cross-darwin10.0
# ...

Pliki nagłówkowe jądra

wget -c http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.bz2
tar -xjf linux-2.6.32.2.tar.bz2
cd linux-2.6.32.2
 
make mrproper
make ARCH=arm headers_check
make ARCH=arm INSTALL_HDR_PATH=$CEL/usr headers_install

GMP

wget -c ftp://ftp.gmplib.org/pub/gmp-4.3.1/gmp-4.3.1.tar.bz2
tar -xjf gmp-4.3.1.tar.bz2
cd gmp-4.3.1
 
CPPFLAGS=-fexceptions ./configure --prefix=$CEL/cross-tools --enable-cxx
make
make install

MPFR

wget -c http://www.mpfr.org/mpfr-current/mpfr-2.4.2.tar.bz2
tar -xjf mpfr-2.4.2.tar.bz2
cd mpfr-2.4.2
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
  ./configure --prefix=$CEL/cross-tools --enable-shared \
  --with-gmp=$CEL/cross-tools
 
make
make install

PPL

wget -c http://www.cs.unipr.it/ppl/Download/ftp/releases/0.10.2/ppl-0.10.2.tar.bz2
tar -xjf ppl-0.10.2.tar.bz2
cd ppl-0.10.2
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ./configure --prefix=$CEL/cross-tools --enable-shared \
    --enable-interfaces="c,cxx" --disable-optimization \
    --with-libgmp-prefix=$CEL/cross-tools \
    --with-libgmpxx-prefix=$CEL/cross-tools
 
make
make install
wget -c ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-ppl-0.15.7.tar.gz
tar -xzf cloog-ppl-0.15.7.tar.gz
cd cloog-ppl-0.15.7
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ./configure --prefix=$CEL/cross-tools --enable-shared --with-bits=gmp \
    --with-gmp=$CEL/cross-tools --with-ppl=$CEL/cross-tools
 
make
make install

Binutils

wget -c http://ftp.gnu.org/gnu/binutils/binutils-2.20.tar.bz2
tar -xjf binutils-2.20.tar.bz2
 
mkdir binutils-build
cd binutils-build
 
AR=ar AS=as ../binutils-2.20/configure --prefix=$CEL/cross-tools \
   --host=$HOST --target=$TARGET --with-sysroot=$CEL \
   --disable-nls --enable-shared --disable-multilib
 
make configure-host
#sprawdza, czy w systemie bazowym znajdują się
#wszystkie niezbędne do kompilacji narzędzia
 
make
make install

GCC - pierwsza wersja (pomocnicza)

wget -c http://ftp.gnu.org/gnu/gcc/gcc-4.4.2/gcc-4.4.2.tar.bz2
tar -xjf gcc-4.4.2.tar.bz2
 
mkdir gcc-build
cd gcc-build
 
AR=ar LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
  ../gcc-4.4.2/configure --prefix=$CEL/cross-tools \
  --build=$HOST --host=$HOST --target=$TARGET \
  --disable-multilib --with-sysroot=$CEL --disable-nls \
  --without-headers --with-newlib --disable-decimal-float \
  --disable-libgomp --disable-libmudflap --disable-libssp \
  --with-mpfr=$CEL/cross-tools --with-gmp=$CEL/cross-tools \
  --with-ppl=$CEL/cross-tools --with-cloog=$CEL/cross-tools \
  --disable-shared --disable-threads --enable-languages=c
 
make all-gcc all-target-libgcc
make install-gcc install-target-libgcc

Biblioteka standardowa C

wget -c http://www.uclibc.org/downloads/uClibc-0.9.30.1.tar.bz2
tar -xjf uClibc-0.9.30.1.tar.bz2
cd uClibc-0.9.30.1
make menuconfig
Target Architecture (arm)  --->
 
uClibc development/debugging options  --->
	(arm5l-unknown-linux-uclibc-) Cross-compiling toolchain prefix
 
Target Architecture Features and Options  --->
 
	#Do wyboru jest EABI (zalecane) lub OABI (stare).
	Target ABI (EABI)  --->
 
	#Kolejność bajtów w słowie:
	#Little Endian lub Big Endian, w zależności od potrzeb.
	Target Processor Endianness (Little Endian)  --->
 
	#Jeżeli opcja będzie wyłączona, instrukcje zmiennoprzecinkowe
	#będą rozwijane w czasie kompilacji. Jeżeli będzie włączona, zostaną
	#przekazane do jądra, które wykona je na koprocesorze zmiennoprzecinkowym,
	#lub przy pomocy emulatora (patrz kolejny rozdział).
	[ ]   Target CPU has a floating point unit (FPU)
 
	#Aktualna wersja standardu biblioteki matematycznej - zalecane.
	[*]   Enable full C99 math library support
 
	#Ścieżka do źródeł jądra (instalowanych na początku).
	(/opt/target-arm/usr/include) Linux kernel header location 
 
Library Installation Options  --->
 
	#Ścieżki, w których zostaną zainstalowane biblioteki.
	($(RUNTIME_PREFIX)lib) Shared library loader path
	(/) uClibc runtime library directory
	(/usr/) uClibc development environment directory
make CROSS=$TARGET- CC="$TARGET-gcc $BUILD"
make PREFIX=$CEL install

GCC - wersja docelowa

rm -rf gcc-build
mkdir gcc-build
cd gcc-build
 
AR=ar LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ../gcc-4.4.2/configure --prefix=$CEL/cross-tools \
    --build=$HOST --host=$HOST --target=$TARGET \
    --disable-multilib --with-sysroot=$CEL --disable-nls \
    --enable-shared --enable-__cxa_atexit \
    --with-mpfr=$CEL/cross-tools --with-gmp=$CEL/cross-tools \
    --with-ppl=$CEL/cross-tools --with-cloog=$CEL/cross-tools \
    --enable-c99 --enable-long-long --enable-threads=posix --enable-languages=c,c++
make AS_FOR_TARGET=$TARGET-as LD_FOR_TARGET=$TARGET-ld
make install

Korzystanie z toolchaina

$ ls $CEL/cross-tools/bin/
export PATH=$CEL/cross-tools/bin:$PATH

Kompilacja w systemie Mac OS X 10.6

$ uname -v
Darwin Kernel Version 10.2.0: Tue Nov  3 10:37:10 PST 2009; 
 root:xnu-1486.2.11~1/RELEASE_I386
 
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)

Binutils

$ diff -ruN binutils-2.20-orig binutils-2.20-new
diff -ruN binutils-2.20-orig/binutils/strings.c binutils-2.20-new/binutils/strings.c
--- binutils-2.20-orig/binutils/strings.c  2009-09-14 13:43:26.000000000 +0200
+++ binutils-2.20-new/binutils/strings.c   2009-12-28 15:42:55.000000000 +0100
@@ -88,8 +88,8 @@
 #define file_open(s,m) fopen(s, m)
 #endif
 #ifdef HAVE_STAT64
-typedef struct stat64 statbuf;
-#define file_stat(f,s) stat64(f, s)
+typedef struct stat statbuf;
+#define file_stat(f,s) stat(f, s)
 #else
 typedef struct stat statbuf;
 #define file_stat(f,s) stat(f, s)
diff -ruN binutils-2.20-orig/gas/config/tc-arm.c binutils-2.20-new/gas/config/tc-arm.c
--- binutils-2.20-orig/gas/config/tc-arm.c  2009-08-30 00:10:59.000000000 +0200
+++ binutils-2.20-new/gas/config/tc-arm.c   2009-12-28 15:45:05.000000000 +0100
@@ -2485,8 +2485,9 @@
       know (frag->tc_frag_data.first_map == NULL);
       frag->tc_frag_data.first_map = symbolP;
     }
-  if (frag->tc_frag_data.last_map != NULL)
+  if (frag->tc_frag_data.last_map != NULL) {
     know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
+  }
   frag->tc_frag_data.last_map = symbolP;
 }

uClibc

#W pliku: uClibc-0.9.30.1-orig/extra/scripts/gen_bits_syscall_h.sh
 
sed -nEe 's/^[ ]*#define[ ]*(__ARM_NR_|__NR_)([A-Za-z0-9_]*).*/UCLIBC\1\2 \1\2/gp' \
      -e 's/^[ ]*#undef[ ]*(__ARM_NR_|__NR_)([A-Za-z0-9_]*).*/UNDEFUCLIBC\1\2 \1\2/gp' \ 
# needed to strip out any kernel-internal defines
 
sed -nEe 's/^UCLIBC(__ARM_NR_|__NR_)([A-Za-z0-9_]*) *(.*)/#undef \1\2\
 #define \1\2 \3\
 #define SYS_\2 \1\2/gp' \
      -e 's/^UNDEFUCLIBC(__ARM_NR_|__NR_)([A-Za-z0-9_]*).*/#undef \1\2/gp

Przygotowanie

export CEL=/opt/target-arm-glibc
export PATH=$CEL/cross-tools/bin:$PATH
set +h
export LC_ALL=POSIX
mkdir -p $CEL/cross-tools
 
export BUILD="-mabi=aapcs-linux"
 
export TARGET="arm-unknown-linux-gnu"
 
export HOST=$(echo $MACHTYPE | sed "s/$(echo $MACHTYPE | cut -d- -f2)/cross/")

Nagłówki jądra

wget -c http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.bz2
tar -xjf linux-2.6.32.2.tar.bz2
cd linux-2.6.32.2
 
make mrproper
make ARCH=arm headers_check
make ARCH=arm INSTALL_HDR_PATH=$CEL/usr/ headers_install

GMP

wget -c ftp://ftp.gmplib.org/pub/gmp-4.3.1/gmp-4.3.1.tar.bz2
tar -xjf gmp-4.3.1.tar.bz2
cd gmp-4.3.1
 
CPPFLAGS=-fexceptions ./configure --prefix=$CEL/cross-tools --enable-cxx
make
make install

MPFR

wget -c http://www.mpfr.org/mpfr-current/mpfr-2.4.2.tar.bz2
tar -xjf mpfr-2.4.2.tar.bz2
cd mpfr-2.4.2
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
	./configure --prefix=$CEL/cross-tools --enable-shared \
	--with-gmp=$CEL/cross-tools
 
make
make install

PPL

wget -c http://www.cs.unipr.it/ppl/Download/ftp/releases/0.10.2/ppl-0.10.2.tar.bz2
tar -xjf ppl-0.10.2.tar.bz2
cd ppl-0.10.2
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ./configure --prefix=$CEL/cross-tools --enable-shared \
    --enable-interfaces="c,cxx" --disable-optimization \
    --with-libgmp-prefix=$CEL/cross-tools \
    --with-libgmpxx-prefix=$CEL/cross-tools
 
make
make install
wget -c ftp://gcc.gnu.org/pub/gcc/infrastructure/cloog-ppl-0.15.7.tar.gz
tar -xzf cloog-ppl-0.15.7.tar.gz
cd cloog-ppl-0.15.7
 
LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ./configure --prefix=$CEL/cross-tools --enable-shared --with-bits=gmp \
    --with-gmp=$CEL/cross-tools --with-ppl=$CEL/cross-tools
 
make
make install

Binutils

wget -c http://ftp.gnu.org/gnu/binutils/binutils-2.20.tar.bz2
tar -xjf binutils-2.20.tar.bz2
 
mkdir binutils-build
cd binutils-build
 
AR=ar AS=as ../binutils-2.20/configure --prefix=$CEL/cross-tools \
	--host=$HOST --target=$TARGET --with-sysroot=$CEL \
	--disable-nls --enable-shared --disable-multilib
 
make configure-host
 
make
make install
cp ../binutils-2.20/include/libiberty.h $CEL/usr/include

GCC - wersja pomocnicza

wget -c http://ftp.gnu.org/gnu/gcc/gcc-4.4.2/gcc-4.4.2.tar.bz2
tar -xjf gcc-4.4.2.tar.bz2
 
mkdir gcc-build
cd gcc-build
 
AR=ar LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ../gcc-4.4.2/configure --prefix=$CEL/cross-tools \
    --build=$HOST --host=$HOST --target=$TARGET \
    --disable-multilib --with-sysroot=$CEL --disable-nls \
    --without-headers --with-newlib --disable-decimal-float \
    --disable-libgomp --disable-libmudflap --disable-libssp \
    --with-mpfr=$CEL/cross-tools --with-gmp=$CEL/cross-tools \
    --with-ppl=$CEL/cross-tools --with-cloog=$CEL/cross-tools \
    --disable-shared --disable-threads --enable-languages=c
 
make all-gcc all-target-libgcc
make install-gcc install-target-libgcc

Eglibc

svn co svn://svn.eglibc.org/branches/eglibc-2_10 eglibc-2.10-current
wget -c http://ftp.debian.org/debian/pool/main/e/eglibc/eglibc_2.10.2.orig.tar.gz
tar -czf eglibc_2.10.2.orig.tar.gz
mkdir eglibc-build
cd eglibc-build
echo install_root=$CEL > configparms
ln -s ../ports ../eglibc-2.10-current/libc
cp -v ../eglibc-2.10-current/libc/Makeconfig{,.orig}
sed -e 's/-lgcc_eh//g' ../eglibc-2.10-current/libc/Makeconfig.orig > \
	../eglibc-2.10-current/libc/Makeconfig
GREP=egrep \
BUILD_CC="gcc" CC="$TARGET-gcc" \
AR="$TARGET-ar" \
RANLIB="$TARGET-ranlib" \
../eglibc-2.10-current/libc/configure --prefix=/usr \
	--libexecdir=/usr/lib/eglibc --host=$TARGET --build=$HOST \
	--disable-profile \
	--enable-add-ons \
	--with-tls --enable-kernel=2.6.0 \
	--with-__thread --with-binutils=$CEL/cross-tools/bin \
	--with-headers=$CEL/usr/include
 
make
make install

Kompilator - ostateczna wersja

rm -rf gcc-build 
mkdir gcc-build 
cd gcc-build
 
AR=ar LDFLAGS="-Wl,-rpath,$CEL/cross-tools/lib" \
    ../gcc-4.4.2/configure --prefix=$CEL/cross-tools \
    --build=$HOST --host=$HOST --target=$TARGET \
    --disable-multilib --with-sysroot=$CEL --disable-nls \
    --enable-shared --enable-__cxa_atexit \
    --with-mpfr=$CEL/cross-tools --with-gmp=$CEL/cross-tools \
    --with-ppl=$CEL/cross-tools --with-cloog=$CEL/cross-tools \
    --enable-c99 --enable-long-long --enable-threads=posix --enable-languages=c,c++
 
make AS_FOR_TARGET=$TARGET-as LD_FOR_TARGET=$TARGET-ld
make install

Korzystanie z toolchaina

$ ls $CEL/cross-tools/bin/
arm-unknown-linux-gnu-addr2line  arm-unknown-linux-gnu-ld
arm-unknown-linux-gnu-ar         arm-unknown-linux-gnu-nm
arm-unknown-linux-gnu-as         arm-unknown-linux-gnu-objcopy
arm-unknown-linux-gnu-c++        arm-unknown-linux-gnu-objdump
arm-unknown-linux-gnu-c++filt    arm-unknown-linux-gnu-ranlib
arm-unknown-linux-gnu-cpp        arm-unknown-linux-gnu-readelf
arm-unknown-linux-gnu-g++        arm-unknown-linux-gnu-size
arm-unknown-linux-gnu-gcc        arm-unknown-linux-gnu-strings
arm-unknown-linux-gnu-gcc-4.4.2  arm-unknown-linux-gnu-strip
arm-unknown-linux-gnu-gccbug     cloog
arm-unknown-linux-gnu-gcov       ppl-config
arm-unknown-linux-gnu-gprof      ppl_lcdd
export PATH=$CEL/cross-tools/bin:$PATH

Instalacja

wget -c http://buildroot.uclibc.org/downloads/buildroot-2009.11.tar.bz2
tar -xjf buildroot-2009.11.tar.bz2
cd buildroot-2009.11

Konfiguracja

make menuconfig
 
Target Architecture (arm)  --->
Target Architecture Variant (generic_arm)  --->
Target ABI (EABI)  --->
 
Toolchain  ---> 
	#Można użyć gotowego toolchain-a, jeżeli taki posiadamy.
	Toolchain type (Buildroot toolchain)  --->
	#Wersja jądra do wydobycia nagłówków.
	Kernel Headers (Linux 2.6.31.x kernel headers)  --->
	#Wersja biblioteki standardowej.
	uClibc C library Version (uClibc 0.9.30.1)  --->
 
	#W tym pliku można umieścić własną konfigurację uClibc
	(toolchain/uClibc/uClibc-0.9.30.config) uClibc configuration file to use?
 
	#Wersja binutils
	Binutils Version (binutils 2.19.1)  ---> 
 
	#Wersja GCC
	GCC compiler Version (gcc 4.4.x)  --->
 
	#Czy kompilator będzie sam rowijał operacje zmiennoprzecinkowe.
	#Włączenie spowoduje dodanie opcji -msoft-float
	[*] Use software floating point by default 
 
	#Oprócz wymaganego kompilatora C zostanią również zbudowane
	#kompilator C++ i biblioteka STL
	[*] Build/install c++ compiler and libstdc++?
 
	#Narzędzie strip
	[*] Install sstrip for the host/build system
Package Selection for the target  --->
Target filesystem options  --->
Kernel  --->

Kompilacja

make

Korzystanie z narzędzi

$ ls -l output/staging/usr/bin/ | awk '{print $8 " " $9 " " $10}'
 
arm-linux-addr2line -> arm-linux-uclibcgnueabi-addr2line
arm-linux-ar -> arm-linux-uclibcgnueabi-ar
arm-linux-as -> arm-linux-uclibcgnueabi-as
arm-linux-c++ -> arm-linux-uclibcgnueabi-c++
arm-linux-cc -> arm-linux-uclibcgnueabi-cc
arm-linux-c++filt -> arm-linux-uclibcgnueabi-c++filt
arm-linux-cpp -> arm-linux-uclibcgnueabi-cpp
arm-linux-g++ -> arm-linux-uclibcgnueabi-g++
arm-linux-gcc -> arm-linux-uclibcgnueabi-gcc
arm-linux-gcc-4.4.2 -> arm-linux-uclibcgnueabi-gcc-4.4.2
arm-linux-gccbug -> arm-linux-uclibcgnueabi-gccbug
arm-linux-gcov -> arm-linux-uclibcgnueabi-gcov
arm-linux-gprof -> arm-linux-uclibcgnueabi-gprof
arm-linux-ld -> arm-linux-uclibcgnueabi-ld
arm-linux-ldconfig -> arm-linux-uclibcgnueabi-ldconfig
arm-linux-ldd -> arm-linux-uclibcgnueabi-ldd
arm-linux-nm -> arm-linux-uclibcgnueabi-nm
arm-linux-objcopy -> arm-linux-uclibcgnueabi-objcopy
arm-linux-objdump -> arm-linux-uclibcgnueabi-objdump
arm-linux-ranlib -> arm-linux-uclibcgnueabi-ranlib
arm-linux-readelf -> arm-linux-uclibcgnueabi-readelf
arm-linux-size -> arm-linux-uclibcgnueabi-size
arm-linux-sstrip -> arm-linux-uclibcgnueabi-sstrip
arm-linux-strings -> arm-linux-uclibcgnueabi-strings
arm-linux-strip -> arm-linux-uclibcgnueabi-strip
arm-linux-uclibcgnueabi-addr2line
arm-linux-uclibcgnueabi-ar
arm-linux-uclibcgnueabi-as
arm-linux-uclibcgnueabi-c++
arm-linux-uclibcgnueabi-cc -> arm-linux-uclibcgnueabi-gcc
arm-linux-uclibcgnueabi-c++filt
arm-linux-uclibcgnueabi-cpp
arm-linux-uclibcgnueabi-g++
arm-linux-uclibcgnueabi-gcc
arm-linux-uclibcgnueabi-gcc-4.4.2
arm-linux-uclibcgnueabi-gccbug
arm-linux-uclibcgnueabi-gcov
arm-linux-uclibcgnueabi-gprof
arm-linux-uclibcgnueabi-ld
arm-linux-uclibcgnueabi-ldconfig -> ldconfig
arm-linux-uclibcgnueabi-ldd -> ldd
arm-linux-uclibcgnueabi-nm
arm-linux-uclibcgnueabi-objcopy  
arm-linux-uclibcgnueabi-objdump
arm-linux-uclibcgnueabi-ranlib
arm-linux-uclibcgnueabi-readelf
arm-linux-uclibcgnueabi-size
arm-linux-uclibcgnueabi-sstrip
arm-linux-uclibcgnueabi-strings
arm-linux-uclibcgnueabi-strip
ldconfig
ldd
$ export PATH=$(pwd)/output/staging/usr/bin/:$PATH
$ set +h

Qemu

qemu-system-arm -M versatilepb -kernel zImage.bin
qemu-arm -L /cross-tools \
	$CEL/busybox ls

Język programowania

http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/C-Extensions.html

Przykład - Planista

...
 
...
/*
 * context_switch - switch to the new MM and the new
 * thread's register state.
 */
static inline void
context_switch(struct rq *rq, struct task_struct *prev,
               struct task_struct *next)
{
        struct mm_struct *mm, *oldmm;
 
        prepare_task_switch(rq, prev, next);
        trace_sched_switch(rq, prev, next);
        mm = next->mm;
        oldmm = prev->active_mm;
        /*
         * For paravirt, this is coupled with an exit in switch_to to
         * combine the page table reload and the switch backend into
         * one hypercall.
         */
        arch_start_context_switch(prev);
 
        if (unlikely(!mm)) {
                next->active_mm = oldmm;
                atomic_inc(&oldmm->mm_count);
                enter_lazy_tlb(oldmm, next);
        } else
                switch_mm(oldmm, mm, next);
 
        if (unlikely(!prev->mm)) {
                prev->active_mm = NULL;
                rq->prev_mm = oldmm;
        }
        /*
         * Since the runqueue lock will be released by the next
         * task (which is an invalid locking op but in the case
         * of the scheduler it's an obvious special-case), so we
         * do an early lockdep release here:
         */
#ifndef __ARCH_WANT_UNLOCKED_CTXSW
        spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#endif
 
        /* Here we just switch the register state and the stack. */
        switch_to(prev, next, prev);
 
        barrier();
        /*
         * this_rq must be evaluated again because prev may have moved
         * CPUs since it called schedule(), thus the 'rq' on its stack
         * frame will be invalid.
         */
        finish_task_switch(this_rq(), prev);
}
...
#define switch_to(prev,next,last)                                       \
do {                                                                    \
        last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));        \
} while (0)

Kolejność bajtów w słowie

cpu_to_be32
cpu_to_le32
be32_to_cpu
le32to_cpu

Brak operacji zmiennoprzecinkowych

Floating point emulation  --->
	*** At least one emulation must be selected ***
	[ ] NWFPE math emulation
	[ ] FastFPE math emulation (EXPERIMENTAL)
	[ ] VFP-format floating point maths (NEW)

Nie ma stałego API

http://lwn.net/Articles/2.6-kernel-api/
Documentation/feature-removal-schedule.txt

Przykład operacji na I2C

#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
 
#include "i2c-dev.h" #z pakietu i2c-tools
 
int main(int argc, char** argv) {
  int file;
  char filename[] = "/dev/i2c-0";
 
  file = open(filename, O_RDWR);
  if (file < 0) {
    printf("ERROR opening device.\{}n");
    exit(1);
  }
 
  int addr = 0x34; /* Adres urządzenia */
  if (ioctl(file,I2C_SLAVE, addr) < 0) {
    printf("ERROR connecting to device.\{}n");
    exit(1);
  }
 
  __u32 res;
  __u8 reg = 0x04; /* Adres rejestru */
  char buf[10];
 
  __u8 w = 0x01; /* Wartość do zapisania */
  if (argv[1][0] == '0') w = 0x00;
 
  res = i2c_smbus_write_word_data(file, reg, w);
  if (res < 0) {
    printf("ERROR talking to device.\{}n");
    exit(1);
  } else {
    printf("LED %d\{}n",w);
  }
  return 0;
}

Kod źródłowy jądra

http://kernel.org/
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree
git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
http://git.kernel.org/

Konfiguracja

make menuconfig
 
make xconfig
make gconfig
make config
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
 181 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
 182 export KBUILD_BUILDHOST := $(SUBARCH)
 183 ARCH            ?= arm
 184 CROSS_COMPILE   ?= arm-linux-
 185 
#Dla systemu ARM Versatile - emulowanego w QEMU
make versatile_defconfig
 
#Dla systemu na płycie deweloperskiej
make at91sam9261ek_defconfig
Kernel Features  --->
    [*] Use the ARM EABI to compile the kernel
    [*]   Allow old ABI binaries to run with this kernel (EXPERIMENTAL)

Kompilacja i instalacja

make ARCH=arm CROSS_COMPILE=arm-linux-
arch/arm/boot/zImage
make ARCH=arm CROSS_COMPILE=arm-linux- uImage
make MOD_INSTALL_PATH=$CEL modules_install
$CEL/lib/modules/<wersja jądra>/

Grep i wyrażenia regularne

alias grep='grep --color=auto'
grep -C 3 -r "^#define.*switch_to" /usr/src/linux

cscope

cscope -Rk

LXR

http://lxr.linux.no/

Pierwszy moduł

/* hello.c */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
 
static int __init hello_init(void)
{
    printk(KERN_ALERT "Witaj świecie!\{}n");
    return 0;
}
 
static void __exit hello_exit(void)
{
    printk(KERN_ALERT "Koniec!\{}n");
}
 
module_init(hello_init);
module_exit(hello_exit);
 
MODULE_LICENSE("GPL");
 
MODULE_DESCRIPTION("Pierwszy moduł");
MODULE_AUTHOR("Marcin Bis");

Makefile

obj-m := hello.o
 
KDIR := /lib/modules/`uname -r`/build 
PWD := $(shell pwd)
 
default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

Moduł z parametrem

/* hello_param.c */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
 
MODULE_LICENSE("GPL");
 
/* 
 *Dwa parametry: ile razy mówimy Czesc i do kogo
 */
 
static char *whom = "kolego";
module_param(whom, charp, 0);
 
static int howmany = 1;
module_param(howmany, int, 0);
 
static int __init hello_init(void)
{
    int i;
    for (i = 0; i < howmany; i++)
    	printk(KERN_ALERT "(%d) Czesc %s\{}n", i, whom);
    return 0;
}
 
static void __exit hello_exit(void)
{
    printk(KERN_ALERT "Zegnaj %s\{}n", whom);
}
 
module_init(hello_init);
module_exit(hello_exit);
insmod ./hello_param.ko howmany=2 whom=Swiecie
options hello_param howmany=2 whom=Swiecie
modprobe hello_param
hello_param.howmany=2 hello_param.whom=Swiecie

Deklarowanie parametrów

#include <linux/moduleparam.h>
 
module_param(
	name,		/* nazwa parametru */
	type,		/* typ, jeden z: byte, short, ushort, int, uint, long,
				    ulong, charp, or bool. 
				    (sprawdzane na etapie kompilacji!) */
	perm		/* uprawnienia dla pliku: 
			            /sys/module/<module_name>/parameters/<param>
				    0: - wyłącza tworzenie pliku */
);
int irq=5;
module_param(irq, int, S_IRUGO);
#include <linux/moduleparam.h>
 
module_param_array(
	name,		/* nazwa tablicy (musi być już zdefiniowana) */
	type,		/* typ, tak samo, jak dla module_param */
	num,		/* ilość elementów, albo NULL (nie sprawdzaj) */
	perm		/* to samo, co w module_param */
);
static int base[MAX_DEVICES] = { 0x820, 0x840 };
module_param_array(base, int, NULL, 0);

Dodawanie źródeł do drzewa jądra

drivers/usb/serial/navman.c
config USB_SERIAL_NAVMAN
        tristate "USB Navman GPS device"
        depends on USB_SERIAL
        help
          To compile this driver as a module, choose M here: the
          module will be called navman.
obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o
make menuconfig

Tworzenie łat

cp -a linux-2.6.32.2 linux-2.6.32.2-orig
make distclean
diff -ruN linux-2.6.32.2-orig linux-2.6.32.2 > plik.patch
cd linux-<wersja>
cat ../plik.path | patch -p1
Witaj mistrzu! Korzystasz aktualnie z jądra w wersji <wersja>.

Zarejestrowane urządzenia

$ cat /proc/devices
Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  7 vcs
 10 misc
#(...)
 
Block devices:
259 blkext
  7 loop
  8 sd
  9 md
 11 sr
 65 sd
#(...)

Rejestracja nowego numeru

#include <linux/fs.h>
 
int register_chrdev_region(
	dev_t from, 		/* Starting device number */
	unsigned count, 	/* Number of device numbers */
	const char *name); 	/* Registered name */
static dev_t acme_dev = MKDEV(202, 128);
 
if (register_chrdev_region(acme_dev, acme_count, "acme")) {
	printk(KERN_ERR “Failed to allocate device number\{}n”);
...

Operacje na pliku urządzenia

int (*open) (
	struct inode *, /* Corresponds to the device file */
	struct file *); /* Corresponds to the open file descriptor */
int (*release) (
	struct inode *,
	struct file *);
ssize_t (*read) (
	struct file *, 	 /* Open file descriptor */
	__user char *, /* User-space buffer to fill up */
	size_t, 	 /* Size of the user-space buffer */
	loff_t *); 	 /* Offset in the open file */
ssize_t (*write) (
	struct file *,	       /* Open file descriptor */
	__user const char *, /* User-space buffer to write
				  to the device */
	size_t,	       /* Size of the user-space buffer */
	loff_t *); 		/* Offset in the open file */

Wymiana danych jądro - proces

include <asm/uaccess.h>
unsigned long copy_to_user (void __user *to,
				    const void *from,
				    unsigned long n);
 
unsigned long copy_from_user (void *to,
				    const void __user *from,
				    unsigned long n);

ioctl

int (*ioctl) (struct inode *, struct file *,
              unsigned int, unsigned long);

mmap

int (*mmap) (struct file *,
             struct vm_area_struct *);

Przykład operacji odczytu

static ssize_t
acme_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
   /* The acme_buf address corresponds to a device I/O memory area */
   /* of size acme_bufsize, obtained with ioremap() */
   int remaining_size, transfer_size;
 
   remaining_size = acme_bufsize - (int) (*ppos); // bytes left to transfer
   if (remaining_size == 0) { /* All read, returning 0 (End Of File) */
	  return 0;
   }
 
   /* Size of this transfer */
   transfer_size = min(remaining_size, (int) count);
 
   if (copy_to_user(buf /* to */, acme_buf + *ppos /* from */, transfer_size)) {
      return -EFAULT;
   } else { /* Increase the position in the open file */
      *ppos += transfer_size;
      return transfer_size;
   }
}

Przykład operacji zapisu

static ssize_t
acme_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
   int remaining_bytes;
 
   /* Number of bytes not written yet in the device */
   remaining_bytes = acme_bufsize - (*ppos);
 
   if (count > remaining_bytes) {
	  /* Can't write beyond the end of the device */
	  return -EIO;
   }
 
   if (copy_from_user(acme_buf + *ppos /* to */, buf /* from */, count)) {
      return -EFAULT;
   } else {
	  /* Increase the position in the open file */
      *ppos += count;
      return count;
   }
}

Definiowanie operacji

#include <linux/fs.h>
static struct file_operations acme_fops =
{
	.owner = THIS_MODULE,
	.read = acme_read,
	.write = acme_write,
};

Rejestracja urządzenia

#include <linux/cdev.h>
static struct cdev acme_cdev;
cdev_init(&acme_cdev, &acme_fops);
if (cdev_add(&acme_cdev, acme_dev, acme_count)) {
  printk (KERN_ERR “Char driver registration failed\{}n”);
...
int cdev_add(
	struct cdev *p, /* Character device structure */
	dev_t dev, 	/* Starting device major / minor number */
	unsigned count); /* Number of devices */

Zwalnianie urządzenia

void cdev_del(struct cdev *p);
void unregister_chrdev_region(dev_t from, unsigned count);
cdev_del(&acme_cdev);
unregister_chrdev_region(acme_dev, acme_count);

Reguły udev-a

atrybut1==wartość, ..., atrybutN==wartość, lista1+=wartość, ..., listaN+=wartość

mdev

CONFIG_MDEV=y
CONFIG_FEATURE_MDEV_CONF=y
CONFIG_FEATURE_MDEV_EXEC=y

/etc/inittab

# /etc/inittab
 
::sysinit:/etc/init.d/rcS
 
ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
 
null::respawn:/sbin/syslogd -n -m 0
null::respawn:/sbin/klogd -n
 
::ctrlaltdel:/sbin/reboot
 
null::shutdown:/usr/bin/killall klogd
null::shutdown:/usr/bin/killall syslogd
null::shutdown:/bin/umount -a -r
null::shutdown:/usr/bin/killall app1
null::shutdown:/usr/bin/killall app2
null::shutdown:/usr/bin/killall app3
null::shutdown:/bin/usleep 1000000
null::shutdown:/bin/sync
null::shutdown:/bin/umount -fl /SD
null::shutdown:/bin/umount -fl /NAND
null::shutdown:/bin/usleep 1000000
null::shutdown:/usr/bin/power_off

/etc/init.d/rcS

#!/bin/sh
/bin/mount -t sysfs sysfs /sys
/bin/mount -t proc proc /proc
/bin/mount -t tmpfs -o size=64k mdev /dev
/bin/mount -t tmpfs -o size=8M home /tmp
/bin/mkdir /dev/pts
/bin/mount -t devpts devpts /dev/pts
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
/bin/cat /etc/hostname  > /proc/sys/kernel/hostname
#Tworzy początkowy zestaw urządzeń.
/sbin/mdev -s
(
mkdir /dev/input
mknod /dev/input/event0 c `cat /sys/class/input/event0/dev | tr : \' \'`
/sbin/insmod /lib/modules/2.6.30-c2/kernel/drivers/mmc/core/mmc_core.ko
/sbin/insmod /lib/modules/2.6.30-c2/kernel/drivers/mmc/host/at91_mci.ko
/sbin/insmod /lib/modules/2.6.30-c2/kernel/drivers/mmc/card/mmc_block.ko
/sbin/insmod /lib/modules/2.6.30-c2/kernel/drivers/mmc/card/sdio_uart.ko
) &
( 
/bin/ip link set lo up
/bin/ip addr flush dev lo
/bin/ip addr add 127.0.0.1/8 dev lo
/bin/ip route add 127.0.0.0/8 dev lo
) &
(
mkdir /dev/snd
MAJ=`cat /proc/devices | awk '$2 ~ /alsa/ { print $1 }'`
while read LINE
  do
  MIN=`echo $LINE | cut -d: -f1`
  DEV=`echo $LINE | \
    awk -F: \'$3 ~ /control/ { print "controlC0" }
	     $3 ~ /digital audio playback/ { print "pcmC0D0p" }  
	     $3 ~ /digital audio capture/ { print "pcmC0D0c" } 
	     $3 ~ /timer/ { print "timer" }\'`
  mknod /dev/snd/$DEV c $MAJ $MIN
done < /proc/asound/devices
 
/usr/sbin/alsactl restore
) &
echo \'[ -x /NAND/login.sh ] && /NAND/login.sh\' > /root/.profile

/etc/mdev.conf

ubi[0-9]* 0:0 644 @ /etc/custom.d/ubi_on
ubi[0-9]* 0:0 644 $ /etc/custom.d/ubi_off
mmcblk[0-9]p1 0:0 644 @ /etc/custom.d/sd_on
mmcblk[0-9] 0:0 644 $ /etc/custom.d/sd_off

/etc/custom.d/sd\_on

#!/bin/sh
cat /proc/mounts | grep ${MDEV} > /dev/null || \
	mount -o noatime,sync ${MDEV} /SD
 
[ "`lsmod | awk \'$1 ~ /g_file_storage/ { print 1 }\'`" == 1 ] || \
insmod /lib/modules/2.6.30-c2/kernel/drivers/usb/gadget/g_file_storage.ko \
	removable file=${MDEV}
 
( until [ -r /tmp/.nand ]; do
        usleep 10
done
 
[ -r /NAND/sd.sh ] && /NAND/sd.sh 
) &

/etc/custom.d/sd\_off

#!/bin/sh
umount -fl /SD >/dev/null 2>/dev/null
rmmod g_file_storage

/etc/custom.d/ubi\_on

#!/bin/sh
mount -t ubifs -o noatime,sync ${MDEV}:data /NAND/
 
[ -e /NAND/.ok ] || /bin/format-nand.sh
touch /tmp/.nand
/usr/sbin/saslauthd
#@MOUNT-ECRYPTFS@#
(
until [ -r /dev/input/event0 ] ; do usleep 10 ; done
[ -r /NAND/autostart.sh ] && /NAND/autostart.sh
) &

/etc/custom.d/ubi\_off

!/bin/sh
sync
umount /NAND/
rm /tmp/.nand

Skrypty powłoki

#!/bin/bash
echo "Hello world!"
zmienna=wartosc
$ a=kot
$ echo $a
kot
$ echo ${a}ek
kotek

Podmiany i rozwinięcia

$ echo plik{1..3}.{txt,pdf}
plik1.txt plik1.pdf plik2.txt plik2.pdf plik3.txt plik3.pdf
$ echo $((2+2))
4
$ a="a b  c   d"
$ echo $a
a b c d
$ echo "$a"
a b  c   d
$ echo "\$a"
$a
$ echo '$a'
$a

Warunki

if warunek
then
	polecenia
elif warunek
then
	polecenia
else
	polecenia
fi

Funkcje

function nazwa_funkcji () {
	polecenie
	polecenie
}

Pętle

while warunek; do
	polecenia
done
until warunek; do
	polecenia
done
for nazwa in słowa; do 
	polecenia
done

Kompilacja

wget -c ftp://www.at91.com/pub/at91bootstrap/AT91Bootstrap1.15.zip
unzip x AT91Bootstrap1.15.zip
 
cd board/at91sam9260ek/dataflash
make clean
 
make CROSS_COMPILE=<sciezka/prefix->

Program uruchomieniowy u-boot

git clone git://git.denx.de/u-boot.git
 
make distclean
 
make at91sam9xxxek_dataflash_config
#lub
make at91sam9xxxek_dataflash_cs0_config
#lub
make at91sam9xxxek_nandflash_config
#w zależności od tego, gdzie chcemy przechowywać ustawienia
make CROSS_COMPILE=<ścieżka/prefix->

Ustawienia udev-a

setenv baudrate 115200
setenv linux 'cp.b 0xC0042000 0x20400000 0x15ea00'
setenv initrd 'cp.b 0xc01a0a00 0x20560000 0x287a00'
setenv bootargs 'mem=64M console=ttyS0,115200 mtdparts=atmel_nand:-(data) \
	ubi.mtd=0 initrd=0x20560000,0x287a00 root=/dev/ram0 \
	rootfstype=squashfs ro quiet'
setenv bootcmd 'run linux; run initrd; bootm 0x20400000'
setenv bootdelay 1
 
saveenv

mkimage

mkimage -A arm -O linux -C none -T kernel -a 20400000 \
	-e 20400000 -n linux-2.6 -d arch/arm/boot/Image uImage

Uruchamianie systemu przez sieć

setenv ethadr 00:11:22:33:44:55
setenv ipaddr 10.0.0.100
setenv serverip 10.0.0.50
 
saveenv

Uruchamianie jądra bezpośrednio przez AT91bootstrap

make uImage

Modyfikacja kodu AT91bootstrap

int main(void)
{
/* ================== 1st step: Hardware Initialization ================= */
/* Performs the hardware initialization */
hw_init();
 
/* Load from Nandflash in RAM */
load_nandflash(IMG_ADDRESS, IMG_SIZE, JUMP_ADDR);
 
/* Jump to the Image Address */
return JUMP_ADDR;
}
typedef struct image_header {
uint32_t    ih_magic;    /* Image Header Magic Number    */
uint32_t    ih_hcrc;    /* Image Header CRC Checksum    */
uint32_t    ih_time;    /* Image Creation Timestamp    */
uint32_t    ih_size;    /* Image Data Size        */
uint32_t    ih_load;    /* Data     Load  Address        */
uint32_t    ih_ep;        /* Entry Point Address        */
uint32_t    ih_dcrc;    /* Image Data CRC Checksum    */
uint8_t        ih_os;        /* Operating System        */
uint8_t        ih_arch;    /* CPU architecture        */
uint8_t        ih_type;    /* Image Type            */
uint8_t        ih_comp;    /* Compression Type        */
uint8_t        ih_name[IH_NMLEN];    /* Image Name        */
} image_header_t;
/* makro do konwersji BigEndian -> LittleEndian */
#define be32_to_cpu(a) ((a)[0] << 24 | (a)[1] << 16 | (a)[2] << 8 | (a)[3])
/* adres, do którego zostanie wczytany obraz z pamięci */
#define PHYS_SDRAM_BASE 0x20000000
 
int main(void)
{
unsigned char *tmp;
unsigned long jump_addr;
unsigned long load_addr;
unsigned long size;
 
hw_init();
 
/* Wczytaj początkowe 20 bajtów obrazu */
load_nandflash(IMG_ADDRESS, 0x20, PHYS_SDRAM_BASE);
 
/* Odczytaj rozmir jądra (ih_size) */
tmp = PHYS_SDRAM_BASE + 12;
size = be32_to_cpu(tmp);
 
/* Odczytaj adres pod który ma być zapisane jądro (ih_load) */
tmp += 4;
load_addr = be32_to_cpu(tmp);
 
/* Odczytaj adres pierwszej instrukcji (ih_ep) */
tmp += 4;
jump_addr = be32_to_cpu(tmp);
 
/* Wczytaj i uruchom jądro */
load_nandflash(IMG_ADDRESS, size, load_addr - 0x40);
 
return jump_addr;
}

Parametry jądra uruchamianego bezpośrednio

CONFIG_CMDLINE="mem=64M console=ttyS0,115200 mtdparts=atmel_nand:-(data) \
	ubi.mtd=0 initrd=0x20560000,0x287a00 root=/dev/ram0 \
	rootfstype=squashfs ro quiet"

pamięć nieulotna (NAND i NOR), urządzenia MTD w linuksie

CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTITIONS=y
 
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
 
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ATMEL=y

UBI

git://git.infradead.org/mtd-utils.git

squashfs

wget -c \
http://downloads.sourceforge.net/project/squashfs/squashfs/squashfs4.0/squashfs4.0.tar.gz
mksquashfs source1 source2 ... destination [options]

Przykład kodowania

$ echo "Wiadomosc" | openssl base64
V2lhZG9tb3NjCg==
$ echo "V2lhZG9tb3NjCg==" | openssl base64 -d
Wiadomosc

Blokowe szyfry symetryczne

$ echo "Wiadomosc" | openssl aes-256-cbc -a -k Klucz
U2FsdGVkX1/ibRklh2eUNp/TUXEYwz6v3rsQNITKGhI=
$ echo U2FsdGVkX1/ibRklh2eUNp/TUXEYwz6v3rsQNITKGhI= | \
	openssl aes-256-cbc -d -a -k Klucz
Wiadomosc

Przykład użycia RSA

$ openssl genrsa -out priv.pem 2048
Generating RSA private key, 2048 bit long modulus
...............................................+++
..+++
e is 65537 (0x10001)
$ openssl rsa -in priv.pem -pubout -out pub.pem
writing RSA key
$ echo "Wiadomość" | \
	openssl rsautl -pubin -inkey pub.pem -encrypt -out plik.zaszyfrowany
$ openssl rsautl -inkey priv.pem -decrypt -in plik.zaszyfrowany
Wiadomość

Weryfikacja danych (w praktyce)

$ openssl passwd -1 -salt "szczyptasoli"
Password:
$1$szczypta$SiBQ9m.54P38sODWieb2F1
$ cat <plik> | openssl dgst -sha1
#lub:
$ md5sum <plik>

ccrypt

cd ccrypt-1.9
./configure --disable-libcrypt --disable-nls --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install

Optymalizacja czasu uruchamiania

cat /proc/uptime

Mierzenie opóźnień

...
[    0.010000] Memory: 64MB = 64MB total
[    0.010000] Memory: 59376KB available (2588K code, 198K data, 104K init, 0K )
[    0.010000] Calibrating delay loop... 98.91 BogoMIPS (lpj=494592)
[    0.210000] Mount-cache hash table entries: 512
[    0.210000] CPU: Testing write buffer coherency: ok
[    0.220000] net_namespace: 296 bytes
[    0.220000] NET: Registered protocol family 16
[    0.230000] AT91: Power Management
[    0.230000] AT91: Starting after user reset
[    0.230000] tcb_clksrc: tc0 at 12.916 MHz
...

Profilowanie uruchamiania

dmesg | perl scripts/bootgraph.pl > output.svg

Pętla opóźniająca

[    0.010000] Calibrating delay loop... 98.91 BogoMIPS (lpj=494592)
lpj=494592

Szybszy reset

reboot=soft

Ręczne zarządzanie przydziałami pamięci

buf = ioremap(
	0x3e00000, /* Start: 62MB */
	0x200000   /* Rozmiar: 2MB */
	);

Opóźniona inicjalizacja sterowników

module_init(foo_init) -> deferred_module_init(foo_init)
echo 1 >/proc/deferred_initcalls

Likwidowanie opóźnień

diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 42065ff..e42d83f 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -86,8 +86,10 @@ #endif
/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN	500	/* Before opening: 1/2 second */ 
-#define CONF_POST_OPEN	1000	/* After opening: 1 second */
+/*#define CONF_PRE_OPEN	500	/* Before opening: 1/2 second */
+/*#define CONF_POST_OPEN	1000	/* After opening: 1 second */
+#define CONF_PRE_OPEN	5	/* Before opening: 5 milli seconds */
+#define CONF_POST_OPEN	10	/* After opening: 10 milli seconds */
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES	2	/* (Re)open devices twice */ 

init

#!/bin/sh
(
# Polecenia1 ...
) &
(
# ... i polecenia2 ...
) &
# ... wykonają się równolegle.

Optymalizacja na etapie kompilacji

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

strip

$TARGET-strip plik
$ gcc -o hello hello.c
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), not stripped
$ strip hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped

Redukacja fork-ów

cat /proc/cpuinfo | grep model
#zmieniamy na:
grep model /proc/cpuinfo

System plików

Documentation/filesystems/tmpfs.txt

dekompresja mp3

wget -c ftp://ftp.mars.org/pub/mpeg/libmad-0.15.1b.tar.gz
tar -xzf libmad-0.15.1b.tar.gz
cd libmad-0.15.1b
 
CC=$TARGET-gcc ./configure --host=$TARGET \
	--prefix=/usr \
	--enable-shared --enable-static \
	--enable-fpm=arm
 
make
make DESTDIR=$CEL install
--enable-speed
wget -c http://www.gzip.org/zlib/zlib-1.2.3.tar.bz2
tar -xjf zlib-1.2.3.tar.bz2
cd zlib-1.2.3/
 
CC=$TARGET-gcc ./configure --prefix=$CEL/usr
make
make install
wget -c ftp://ftp.mars.org/pub/mpeg/libid3tag-0.15.1b.tar.gz
tar -xzf libid3tag-0.15.1b.tar.gz
cd libid3tag-0.15.1b/
 
CC=$TARGET-gcc \
CFLAGS="-I$CEL/usr/include -L$CEL/usr/lib" \
./configure --host=$TARGET \
	--prefix=/usr \
	--enable-shared --enable-static
 
make
make DESTDIR=$CEL install
wget -c ftp://ftp.mars.org/pub/mpeg/madplay-0.15.2b.tar.gz
 
tar -xzf madplay-0.15.2b.tar.gz
 
cd ..
cd madplay-0.15.2b
 
CC=$TARGET-gcc \
CFLAGS="-I$CEL/usr/include -L$CEL/usr/lib" \
./configure --host=$TARGET \
	--prefix=/usr \
	--disable-nls
 
make
make DESTDIR=$CEL install
$TARGET-gcc -o madplay \
	madplay.o getopt.o getopt1.o version.o \
	resample.o filter.o tag.o crc.o rgain.o \
	player.o audio.o audio_aiff.o audio_cdda.o \
	audio_hex.o audio_null.o audio_raw.o audio_snd.o \
	audio_wave.o audio_oss.o \
	$CEL/usr/lib/libmad.a \
	$CEL/usr/lib/libid3tag.a \
	$CEL/usr/lib/libz.a \
	-lm

kompresja mp3

#LAME
http://lame.sourceforge.net/
#GOGO
http://freshmeat.net/projects/gogo/
#W pliku Makefile należy ustawić opcje:
CC=arm-linux-uclibcgnueabi-gcc
AS=arm-linux-uclibcgnueabi-as
STRIP=arm-linux-uclibcgnueabi-strip
#a następnie wykonać polecenie:
 
make
l3enc -b 64 /dev/dsp output.mp3

OGG

speexenc --quality 7 input.wav output.spx
#Pobieramy interesującą nas wersję ...
svn co http://svn.xiph.org/trunk/Tremor Tremor-trunk
#... lub ...
svn co http://svn.xiph.org/branches/lowmem-branch/Tremor Tremor-low-memory-branch
#... i przystępujemy do budowania.
 
cd Tremor-trunk
./autogen.sh --host=$TARGET --prefix=/usr
make
 
make DESTDIR=$CEL install
wget -c http://downloads.xiph.org/releases/ogg/libogg-1.1.4.tar.gz
tar -xzf libogg-1.1.4.tar.gz
cd libogg-1.1.4
 
./configure --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install
wget -c http://downloads.xiph.org/releases/ao/libao-0.8.8.tar.gz
tar -xzf libao-0.8.8.tar.gz 
cd libao-0.8.8/
 
CPPFLAGS=-I$CEL/usr/include \
LDFLAGS=-L$CEL/usr/lib \
./configure --host=$TARGET --prefix=/usr \
	--enable-alsa9 \
	--enable-oss \
	--disable-esd --disable-nas \
	--disable-alsa --disable-pulse --disable-arts \
	--enable-static
 
make
make DESTDIR=$CEL install
wget -c http://downloads.xiph.org/releases/vorbis/vorbis-tools-1.2.0.tar.gz
tar -xzf vorbis-tools-1.2.0.tar.gz
cd vorbis-tools-1.2.0
 
patch -p1 < ../vorbis-tools-tremor.path
 
CPPFLAGS=-I$CEL/usr/include \
LDFLAGS=-L$CEL/usr/lib \
./configure --host=$TARGET --prefix=/usr \
	--with-ogg=$CEL/usr \
	--with-vorbis=$CEL/usr \
	--with-ao=$CEL/usr \
	--disable-nls \ 
	--disable-vorbiscomment
 
cd share
make
 
cd ../ogg123/
make
$TARGET-gcc -O2 -Wall -ffast-math -fsigned-char -o ogg123-static \
	audio.o buffer.o callbacks.o cfgfile_options.o \
	cmdline_options.o file_transport.o format.o ogg123.o \
	oggvorbis_format.o playlist.o status.o remote.o \
	transport.o vorbis_comments.o \
	../share/libutf8.a ../share/libgetopt.a \
	$CEL/usr/lib/libvorbisidec.a \
	$CEL/usr/lib/libogg.a \
	$CEL/usr/lib/libao.a \
	-ldl -lnsl -lpthread -Wl,--rpath \
	-Wl,/home/xc/tmp/test/usr/lib \
	-Wl,--rpath -Wl,$CEL/usr/lib
wget -c \
http://downloads.sourceforge.net/project/flac/flac-src/flac-1.2.1-src/flac-1.2.1.tar.gz
 
tar -xzf flac-1.2.1.tar.gz
cd flac-1.2.1/
 
./configure --host=$TARGET --prefix=/usr \
	--disable-cpplibs --with-ogg=$CEL/usr
 
make
make DESTDIR=$CEL install

ALSA

[    1.700000] Advanced Linux Sound Architecture Driver Version 1.0.20.
[    1.700000] No device for DAI atmel-ssc0
[    1.700000] No device for DAI atmel-ssc1
[    1.700000] No device for DAI atmel-ssc2
[    1.710000] asoc: WM8731 <-> atmel-ssc1 mapping ok
[    1.710000] at91ebd9261_wm8731 : at91ebd9261_wm8731_init() called
[    1.720000] ALSA device list:
[    1.720000]   #0: AT91EBD9261 (WM8731)
pcm.mojakarta {
	type hw
	card 0
	device 0
}
aplay -D mojakarta sample.wav
http://www.alsa-project.org/main/index.php/SALSA-Library
wget -c ftp://ftp.suse.com/pub/people/tiwai/salsa-lib/salsa-lib-0.0.26.tar.bz2
tar -xjf salsa-lib-0.0.26.tar.bz2
cd salsa-lib-0.0.26
 
./configure --host=$TARGET --prefix=/usr \
	--enable-everything --with-compat-version=1.0.18
 
make
make DESTDIR=$CEL install

Narzędzia ALSA

wget -c ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.22.tar.bz2
tar -xjf alsa-lib-1.0.22.tar.bz2
cd alsa-lib-1.0.22
./configure --host=arm-linux --prefix=/usr \
	--disable-old-symbols --disable-python
LDFLAGS=-lm \
./configure --host=arm-linux --prefix=/usr \
	--with-softfloat \
	--disable-old-symbols --disable-python
 
make
make DESTDIR=$CEL install
wget -c ftp://ftp.alsa-project.org/pub/utils/alsa-utils-1.0.22.tar.bz2
tar -xjf alsa-utils-1.0.22.tar.bz2
cd alsa-utils-1.0.22
 
CPPFLAGS=-I$CEL/usr/include \
LDFLAGS=-L$CEL/usr/lib \
./configure --host=arm-linux --prefix=/usr \
	--disable-xmlto --disable-nls
 
make
make DESTDIR=$CEL install

synteza mowy - open-source

wget -c http://www.speech.cs.cmu.edu/flite/packed/flite-1.4/flite-1.4-release.tar.bz2
tar -xjf flite-1.4-release.tar.bz2
cd flite-1.4-release
 
./configure --host=$TARGET --prefix=$CEL/usr
 
make
make install

DirectFB

wget -c http://www.gzip.org/zlib/zlib-1.2.3.tar.bz2
tar -xjf zlib-1.2.3.tar.bz2
cd zlib-1.2.3/
 
CC=$TARGET-gcc ./configure --prefix=$CEL/usr
make
make install
wget -c http://download.sourceforge.net/libpng/libpng-1.2.42.tar.gz
tar -xzf libpng-1.2.42.tar.gz
cd libpng-1.2.42
 
LDFLAGS=-L$CEL/usr/lib \
CPPFLAGS=-I$CEL/usr/include \
./configure --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install
wget -c http://www.ijg.org/files/jpegsrc.v8.tar.gz
tar -jzf jpegsrc.v8.tar.gz
cd jpeg-8
 
./configure --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install
wget -c http://downloads.sourceforge.net/project/freetype/freetype2/2.3.11/freetype-2.3.11.tar.bz2
tar -xjf freetype-2.3.11.tar.bz2
cd freetype-2.3.11
 
./configure --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install
#$CEL/usr/bin/libpng-config, zmieniamy:
prefix="/usr"
#na:
prefix="$CEL/usr"
$ pkg-config --version
0.23
wget -c http://www.directfb.org/downloads/Core/DirectFB-1.4/DirectFB-1.4.3.tar.gz
tar -xzf DirectFB-1.4.3.tar.gz 
cd DirectFB-1.4.3/
 
LDFLAGS=-L$CEL/usr/lib \
CPPFLAGS=-I$CEL/usr/include \
PATH=$CEL/usr/bin:$PATH \
PKG_CONFIG_PATH=$CEL/usr/lib/pkgconfig \
PKG_CONFIG_SYSROOT_DIR=$CEL \
./configure --host=$TARGET --prefix=/usr \
	--with-gfxdrivers=none \
	--with-inputdrivers=keyboard,linuxinput
 
make
make DESTDIR=$CEL install
wget -c http://www.directfb.org/downloads/Core/DirectFB-1.2/DirectFB-1.2.10.tar.gz
tar -xzf DirectFB-1.2.10.tar.gz
cd DirectFB-1.2.10/
 
LDFLAGS=-L$CEL/usr/lib \
CPPFLAGS=-I$CEL/usr/incude \
PATH=$CEL/usr/bin:$PATH \
FREETYPE_CFLAGS="-I$CEL/usr/include/freetype2" \
FREETYPE_LIBS=--lfreetype \
./configure --host=$TARGET --prefix=/usr \
	--with-gfxdrivers=none \
	--with-inputdrivers=keyboard,linuxinput
 
make
make DESTDIR=$CEL install
$CEL/usr/bin/freetype-config --cflags
$CEL/usr/bin/freetype-config --libs
wget -c http://www.directfb.org/downloads/Extras/DirectFB-examples-1.2.0.tar.gz
tar -xzf DirectFB-examples-1.2.0.tar.gz
cd DirectFB-examples-1.2.0
 
DIRECTFB_LIBS="-L$CEL/usr/lib -ldirectfb -lfusion -ldirect -lpthread" \
DIRECTFB_CFLAGS="-I$CEL/usr/include/directfb -D_REENTRANT" \
./configure --host=$TARGET --prefix=/usr
 
make
make DESTDIR=$CEL install
$CEL/usr/bin/directfb-config --cflags
$CEL/usr/bin/directfb-config --libs
#define M_CLEAR(m) bzero(m, MATRIX_SIZE)
#define M_CLEAR(m) memset(m, 0, MATRIX_SIZE)
./df_fire
./df_andi

gcj

class Hello {
	public static void main(String args[]) {
		System.out.println("Hello World");
	}
};
$ gcj Hello.java --main=Hello -o hello
$ file hello hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), 
for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped
$ ./hello
Hello World
$ ldd hello
# ...
libgcj.so.90 => /usr/lib/libgcj.so.90 (0xb5f5c000)
# ...

Biblioteka klas

./configure --host=$HOST --prefix=/usr \
	--disable-gtk-peer --disable-gconf-peer --disable-plugin
make DESTDIR=$CEL install

JamVM

CPPFLAGS=-I$CEL/usr/include \
LDFLAGS=-L$CEL/usr/lib \
./configure --host=$HOST --prefix=/usr \
	--with-classpath-install-dir=/usr
 
make
make DESTDIR=$CEL install

JamVM - testy

class Test {
	public static void main(String args[]) {
		System.out.println("To jest test");
	}
}
ecj Test.java
jamvm -Xmx2M Test
# -Xmx - ustawia maksymalną wielkość stosu na 2MB (domyślnie 16MB).

phoneME

cvm -cp democlasses.jar cdc.HelloWorld
cvm -jar democlasses.jar
cvm -cp testclasses.zip Test
*CONGRATULATIONS: test Test completed with 411 tests passed and 0 failures
*Output lines starting with a * should be checked for correctness
*They can be compared to src/share/javavm/test/TestExpectedResult
mkdir phoneme
cd phoneme
 
svn checkout https://phoneme.dev.java.net/svn/phoneme/components/cdc/trunk cdc
svn checkout https://phoneme.dev.java.net/svn/phoneme/components/tools/trunk tools
#użytkownik: guest, hasło:guest
 
cd cdc/build/linux-arm-generic
 
export JDK_DIR=/usr/lib/jvm/j2sdk1.4.2_19
 
LD_LIBRARY_PATH=$JDK_DIR/jre/lib/i386/client:\
$JDK_DIR/jre/lib/i386:$LD_LIBRARY_PATH \
PATH=$JDK_DIR/bin:$JDK_DIR/jre/bin:$PATH \
make CVM_TARGET_TOOLS_PREFIX=$TARGET- \
	JDK_HOME=$JDK_DIR \
	J2ME_CLASSLIB=foundation

QEMU

aptitude install nasm libx11-dev \
	libsdl1.2-dev zlib1g-dev texi2html sharutils \
	libgnutls-dev libasound2-dev libgpmg1-dev \
	libbrlapi-dev quilt 
 
wget -c http://download.savannah.gnu.org/releases/qemu/qemu-0.12.1.tar.gz
 
./configure --enable-system --target-list=arm-softmmu
qemu-system-arm -M versatilepb \
	-m 16 -kernel vmlinuz-qemu-arm-2.6.20 \
	-append "clocksource=pit quiet rw"

Poziomy rejestrowania

printk(KERN_WARNING "To jest ostrzeżenie!\{}n");
printk(KERN_DEBUG "To jest komunikat diagnostyczny!\{}n");
printk("To jest komunikat bez określonego poziomu rejestrowania,
	dostanie wartość default_message_level!\{}n");
  #define KERN_EMERG      "<0>"   /* system is unusable                   */
  #define KERN_ALERT      "<1>"   /* action must be taken immediately     */
  #define KERN_CRIT       "<2>"   /* critical conditions                  */
  #define KERN_ERR        "<3>"   /* error conditions                     */
  #define KERN_WARNING    "<4>"   /* warning conditions                   */
  #define KERN_NOTICE     "<5>"   /* normal but significant condition     */
  #define KERN_INFO       "<6>"   /* informational                        */
  #define KERN_DEBUG      "<7>"   /* debug-level messages                 */
$ cat /proc/sys/kernel/printk
7	4	1	7
#include <linux/module.h>
 
MODULE_LICENSE("GPL");
 
int init_module(void) {
  printk(KERN_ALERT "Hello World\{}n);
  return 0;
}
 
void cleanup_module(void) {
  printk(KERN_NOTICE "Good Bye\{}n);
}
echo 4 > /proc/sys/kernel/printk

Bufor komunikatów

dmesg
#tylko odczytuje, lub:
 
dmesg -c
#odczytuje i czyści bufor

Dedykowane systemy plików

sudo mount -t debugfs none /mnt/debugfs
http://free-electrons.com/kerneldoc/latest/DocBook/filesystems/index.html

Przykład Debugfs

#include <linux/debugfs.h>
 
static char *acme_buf;				// module buffer
static unsigned long acme_bufsize;
static struct debugfs_blob_wrapper acme_blob;
static struct dentry *acme_buf_dentry;
 
static u32 acme_state;				// module variable
static struct dentry *acme_state_dentry;
 
/* Module init */
acme_blob.data = acme_buf;
acme_blob.size = acme_bufsize;
acme_buf_dentry = debugfs_create_blob("acme_buf", S_IRUGO		// Create
						NULL, &acme_blob);	// new files
acme_state_dentry = debugfs_create_bool("acme_state", S_IRUGO,	// in debugfs
						NULL, &acme_state);
 
 
/* Module exit */
debugfs_remove (acme_buf_dentry);		// removing the files from debugfs
debugfs_remove (acme_state_dentry);

GDB

gdb /usr/src/linux/vmlinux /proc/kcore

kgdb

kgdboc=<tty-device>,[baud]
 
#np.:
kgdboc=ttyS0,115200
 
#dodatkowa opcja
kgdbwait
#spowoduje, że jądro poczeka na połączenie z gdb
% gdb ./vmlinux
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0