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
$ 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
$ 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
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
LXR
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
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
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
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