Sunday, May 26, 2013

Raspberry Pi GPIOs

GPIO : General Purpose Input Output

Consider a GPIO as a pin whose behavior will be controlled by the software. The raspberry pi board has a 26-pin expansion header containing 17 GPIO pins that can be used to control external devices (lights, LCD display, ...) or to read information from the outside (temperature sensor, ADC output, etc ...).


As shown on the picture, some of the GPIOs are already used (depending on your kernel) for communication lines such as I2C, SPI or UART. It doesn't mean that we can't use them for other purposes, their usage can be customized.

GPIO voltage level

1 : High-Level : 3,3V
0 : Low-Level : 0V
Current is configurable from 2mA up to 16mA (for the whole block, no just only one pin)

Important note : there is no over-voltage protection circuit on the board. Be careful when plugging your active devices.

GPIO control

Two choices here :

  • usage of the kernel drivers in arch/arm/mach-bcm2708 (not included in vanilla kernel sources)
  • usage of a dedicated library installed in user space

Note : the raspberry pi is usually referred as bcm2835 but some of the drivers are located in bcm2708 directory. Technically bcm2708 is the chip family and bcm2835 is one of its implementation, the only one officially supported by linux.

Sunday, May 19, 2013

Build a minimalist root filesystem

During my research, I have seen many different tutorials to create a minimalist root filesystem. Some of them advise to copy files from the host's root filesystem and then proceed to customization, others use very handy tools like Buildroot and finally some people create it manually.

It is this last option that we will experiment here thanks to this twiki written by T.I.

Our root filesystem is based on BusyBox which offers the main linux command line utilities in a single executable.

Build BusyBox

Download the latest release of busybox on the official website and extract it to your working directory.
cd busybox-1.21.0
make menuconfig
Follow the instructions as detailed in the T.I. twiki to customize your binary. I have made some different choices here and there to add additional commands like fdisk. Do as you like, it does not really matter...

Build ...
ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make
... and install it on the second partition of your SD Card :
make CONFIG_PREFIX=/media/<path_to_your_sd_card_p2> install
Here is what you should see on your partition after the last step :
bin  linuxrc  lost+found  sbin  usr

Create compulsory directories

The official rules to build a root filesystem are detailed in the Filesystem Hierarchy Standard (FHS). Here is a complete list of the top level directories :

bin : essential user command binaries
boot : files used by the bootloader
dev : devices files
etc : system configuration files
home : users home directory
lib : essential libraries (C library, kernel modules,...)
media : mount points for removable medias
mnt : mount points for temporarily mounted filesystems
opt : Add-on software packages
proc : virtual filesystem for kernel and process information
root : root user's home directory
sbin : essntial system administration binaries
sys : virtual filesystem for system information and control
tmp : temporary files
usr : secondary hierarchy containing most applications and documents useful to most users
var : variable data stored by daemons and utilities

We don't need all of them as we won't provide a multi-user environment. /home, /mnt, and /opt can be ommited.

Create the directories (as root)

cd /media/<path_to_your_sd_card_p2>
sudo mkdir dev dev/pts etc etc/init.d lib mnt opt proc root sys tmp var var/log
Optional : debug is needed by debugfs, add it if your kernel has been built with this option
sudo mkdir debug

Create a static node for console

Like Unix systems, every object in Linux is visible as a file (except for networking interfaces). As such, /dev contains device files (nodes) that represent the system devices. This directory needs to be populated either statically (old fashion way, every node has to be created manually with mknode) or dynamically (common way thanks to udev or mdev).

In our case, we will only add a node for the console.
mknod dev/console c 5 1
The rest of the nodes will be added by mdev which is part of BusyBox.
cd etc
gedit mdev.conf
audio       0:5 0666
console     0:5 0600
control.*   0:0 0660 @/bin/mv /dev/$MDEV /dev/snd/
dsp         0:5 0666
event.*     0:0 0600 @/bin/mv /dev/$MDEV /dev/input/
fb          0:5 0666
nfs         0:5 0770
null        0:0 0777
pcm.*       0:0 0660 @/bin/mv /dev/$MDEV /dev/snd/
rtc         0:0 0666
tty         0:5 0660
tty0*       0:5 0660
tty1*       0:5 0660
tty2*       0:5 0660
tty3*       0:5 0660
tty4*       0:5 0660
tty5*       0:5 0660
tty6*       0:5 0660
ttyS*       0:5 0640
urandom     0:0 0444
zero        0:0 0666

Create an fstab file to mount /proc and /dev/pts at boot

fstab is system configuration file used to list the available disks and disk partitions and describes how they are initialized. The mount command relies on this file to determine which option should be used when mounting a specific device.
# still in /etc
gedit fstab
proc            /proc           proc    defaults        0 0
none            /dev/pts        devpts  mode=0622       0 

Login utilities

/etc must contain the files group, passwd and hosts for login. For the moment, root only needs to be defined in group and hosts only needs to have the localhost registered.
gedit group
root:x:0:root
gedit passwd
root::0:0:root:/root:/bin/ash
gedit hosts
127.0.0.1       localhost

Create inittab

Read this post for information about inittab.
gedit inittab
::sysinit:/etc/init.d/rcS 

# /bin/ash
#
# Start an "askfirst" shell on the serial port
console::askfirst:-/bin/ash

# Stuff to do when restarting the init process
::restart:/sbin/init

# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

Create init script

gedit init.d/rcS
#!/bin/sh
#   ---------------------------------------------
#   Common settings
#   ---------------------------------------------
HOSTNAME=MYPI
VERSION=1.0.0

hostname $HOSTNAME

#   ---------------------------------------------
#   Prints execution status.
#
#   arg1 : Execution status
#   arg2 : Continue (0) or Abort (1) on error
#   ---------------------------------------------
status ()
{
       if [ $1 -eq 0 ] ; then
               echo "[SUCCESS]"
       else
               echo "[FAILED]"

               if [ $2 -eq 1 ] ; then
                       echo "... System init aborted."
                       exit 1
               fi
       fi

}

#   ---------------------------------------------
#   Get verbose
#   ---------------------------------------------
echo ""
echo "    System initialization..."
echo ""
echo "    Hostname       : $HOSTNAME"
echo "    Filesystem     : v$VERSION"
echo ""
echo ""
echo "    Kernel release : `uname -s` `uname -r`"
echo "    Kernel version : `uname -v`"
echo ""


#   ---------------------------------------------
#   MDEV Support
#   (Requires sysfs support in the kernel)
#   ---------------------------------------------
echo -n " Mounting /proc             : "
mount -n -t proc /proc /proc
status $? 1

echo -n " Mounting /sys              : "
mount -n -t sysfs sysfs /sys
status $? 1

echo -n " Mounting /dev              : "
mount -n -t tmpfs mdev /dev
status $? 1

echo -n " Mounting /dev/pts          : "
mkdir /dev/pts
mount -t devpts devpts /dev/pts
status $? 1

echo -n " Enabling hot-plug          : "
echo "/sbin/mdev" > /proc/sys/kernel/hotplug
status $? 0

echo -n " Populating /dev            : "
mkdir /dev/input
mkdir /dev/snd

mdev -s
status $? 0

#   ---------------------------------------------
#   Disable power management
#   (Requires sysfs support in the kernel)
#   ---------------------------------------------
# echo -n " Disabling Power mgmt       : "
# echo -n "1" > /sys/power/cpuidle_deepest_state
# status $? 1

#   ---------------------------------------------
#   Turn off LCD after 1 hour of inactivity
#   (Requires sysfs support in the kernel)
#   ---------------------------------------------
# echo -n " Turn off LCD after 1 hour  : "
# echo -n "3600" > /sys/power/fb_timeout_value
# status $? 1


#   ---------------------------------------------
#   Mount the default file systems
#   ---------------------------------------------
echo -n " Mounting other filesystems : "
mount -a
status $? 0


#   ---------------------------------------------
#   Set PATH
#   ---------------------------------------------
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin


#   ---------------------------------------------
#   Start other daemons
#   ---------------------------------------------
echo -n " Starting syslogd           : "
/sbin/syslogd
status $? 0

echo -n " Starting telnetd           : "
/usr/sbin/telnetd
status $? 0


#   ---------------------------------------------
#   Done!
#   ---------------------------------------------
echo ""
echo "System initialization complete."


make it executable
chmod +x rcS

Copy the dependencies 

We built BusyBox with the ARM cross toolchain as a C program without the -static option, which means that it will look for C libraries at runtime.We have to add them !

Note : Use ldd to list the dependencies of a binary

cd /media/<path_to_your_sd_card_p2>/lib
# Copy the C libraries
copy -r /usr/arm-linux-gnueabi/lib/* .
# Remove the debug informations from the libraries to save space
arm-linux-gnueabi-strip 

At this point, you have a valid root filesystem with the bare minimum. It does not include the kernel modules yet and if you want to add more executables, you'll also need to add their dependencies. The filesystem will get larger when these files are added.

First boot

Here is my display at first boot :


This time, there is no panic displayed. The kernel finds the init process and executes our script.
To access BusyBox press Enter :


Saturday, May 11, 2013

Compile the Linux Kernel (part1)

Compile the Linux Kernel (part1)



Les distributions classiques fournissent des noyaux binaires pré-compilés, soit sous forme d’archives RPM dans le cas des distributions Red Hat, soit sous forme d’archives DEB dans le cas de la distribution DEBIAN.

L’utilisation de Linux dans un environnement industriel embarqué obligera à adapter le noyau à l’environnement matériel.

Il peut arriver que certains pilotes de périphériques ne soient par fournis sur l’archive officielle du noyau Linux.

Le noyau est tout simplement le programme qui gère les interactions entre le matériel et les autres programmes. C'est lui qui amorce le système d'exploitation.

Une chose que beaucoup de personnes ne comprennent pas est que le noyau est un programme comme les autres, vous pouvez parfaitement avoir plusieurs noyaux et utiliser celui de votre choix.

Pourquoi compiler son noyau ? Les noyaux fournis par défaut dans votre distribution /Linux sont des noyaux capables de tourner sur un maximum de machines et de matériels. Ils sont donc souvent plus lourds, mais la différence de rapidité est en général assez faible. En fait les vraies raisons de compiler son propre noyau sont les suivantes :

  1. Comprendre comment fonctionne le noyau Linux.
  2. Faire fonctionner un matériel qui n'est pas pris en charge par votre noyau actuel.
  3. Appliquer un correctif.
  4. Vous voulez utiliser une distribution qui oblige de compiler votre noyau.

La compilation du noyau est longue et demande beaucoup d'attention sous peine de ne plus pouvoir démarrer sa machine. Si vous n'avez pas le temps de lire beaucoup de documentation et si vous n'êtes pas prêt à galérer sérieusement, alors inutile de vous fatiguer pour rien.
Ce qui nous intéresse ici est la compilation de noyau destiné à l'embarqué et particulièrement aux architectures ARM.

Il est possible d'émuler la plateforme ARM sur votre poste de travail Linux pour tester les kernel compilés avec Qemu.

List all installed package on your Ubuntu system:
serge#> dpkg –get-selections
Install the ARM toochain:
serge#> sudo apt-get install gcc-arm-linux-gnueabi
Check the proper installation of the package :
serge#> dpkg --get-selections | grep arm

Télecharger un emulateur ARM (QEMU) pour tester vos kernel (en attendant le matériel).

List all available package with the name qemu to download :
serge#> apt-cache search qemu
serge#> sudo apt-get install qemu
serge#> sudo apt-get install qemu-kvm-extras


Pour Information, le noyau est identifié par un triplet version.révision.patch, exemple 2.4.13
Les révisions paires identifient des noyaux stables. En toute rigueur, ce sont les seuls qu’il faut utiliser dans le cas de produits industriels. Les révisions impaires sont des noyaux de développement. La fréquence de diffusion de ces noyaux peut être très élevée, parfois un par semaine ou plus. Leur utilisation n’est absolument pas recommandée pour des applications industrielles.

Pour commencer, récupérer la dernière version du noyau 3.8.9 depuis :

Créer un répertoire de travail en local et copier l'archive téléchargée dans ce nouveau répertoire:

serge#> cd /home/serge
serge#> mkdir kernel_compilation
serge#> cp ./Downloads/linux-3.8.9.tar.xz ./kernel_compilation/
serge#> cd kernel_compilation/
serge#> ls -lrt

Décompresser l'archive dans le répertoire kernel_compilation :
serge#> tar -xvf linux-3.8.9.tar.xz

Voici une brève description des fichiers et sous-répertoires de l’arborescence du noyau :



arch contient le code source spécifique des architectures matérielles comme x86, ppc, alpha ou m68k.

Documentation contient des fichiers de documentation au format.

drivers contient l’arborescence des divers pilotes de périphériques.

fs contient le code source des différents systèmes de fichiers, ou file-systems supportés par le noyau. Nous pouvons citer par exemple ext2, vfat ou iso9660.

include contient les fichiers d’en-tête C nécessaires à la compilation du noyau mais également au développement d’applications.

init contient le fichier principal main.c, contenant la fonction principale main(), du noyau Linux.

ipc contient le code source de la version des IPC System V du noyau Linux.

kernel contient le code source des fonctions majeures du noyau comme la gestion des tâches ou des processus.

mm contient les fonctions de gestion de la mémoire ou memory-management.

net contient le code source des différents protocoles réseau supportés par le noyau Linux. Nous pouvons citer ipv4, ipv6 ou x25.

scripts contient le code source des outils de configuration du noyau.

Makefile et Rules.make sont les fichiers utilisés par la commande make lors de la compilation du noyau.

sound contient dans le cas du noyau 2.6 les pilotes ALSA (Advanced Linux Sound Archicture) désormais intégrés en standard aux sources du noyau.

Télécharger Git, le svn de Linux pour faire de la gestion de configuration :
serge#> apt-cache search git
serge#> sudo apt-get install git


L'adresse du repository Git de travail est la suivante: https://linux389pi@bitbucket.org/linux389pi/linux389pi.git
L'adresse du repository officiel de la Rasperry est:
https://github.com/raspberrypi/linux

Clôner le répertoire de travail en local depuis le repository Git (équivalent svn checkout):
serge#> git clone https://linux389pi@bitbucket.org/linux389pi/linux389pi.git

Au cas où, faire un pull ou fetch pour récupérer les derniers fichiers du repository (equivalent à svn update):
serge#> cd ~/kernel_compilation/linux389pi/arch/arm/configs
serge#> git pull origin

Go to the configuration folder to check the default configuration :
serge#> cd /home/serge/kernel_compilation/linux389pi/arch/arm/configs

Check the presence of the Rasperry Pi configuration file
bcmrpi_deconfig

Define your local environment before compilation:
serge#> export ARCH=arm
serge#> export CROSS_COMPILE=arm-linux-gnueabi-
serge#> alias make='make -j8'
Comment: The number coming after the “j” letter is obtained by doing: 2*<number of CPUs>

You can get the number of CPU by checking the file:
cat /proc/cpuinfo
Configure the kernel from the root of your working directory:
serge#> cd ~/kernel_compilation/linux389pi
serge#> make bcmrpi_defconfig
After entering the command, a .config file should be generated.
Build the kernel from the root of your working directory:
serge#> cd ~/kernel_compilation/linux389pi
serge#> make
If building the kernel produces compilation errors, fix the errors and perform a clean before rebuilding again with the command:
serge#> make mrproper

Correcting the build errors by applying a patchfile to the vanilla kernel

The vanilla kernel version is not adapted to compile for an ARM architecture, that is why we encountered compiling errors. In order to fix these errors, we are going to apply a patchfile to the vanilla version.

First, Go to the main directory
cd kernel_compilation/
Rename the directory you downloaded from your central repository:
mv linux389pi linux_vanilla_kernel
Go inside the Official Raspberry Pi directory you downloaded rom the official website:
cd rpi-3.8.y/
Initialize a new local git repository on this directory:
git init
git add .
Commit all the subdirectories
git commit -m "added : rpi-3.8.y sources"
Add a new local repository from the Pi repository and fetch:
git remote add vanilla ../linux_vanilla_kernel/
git fetch vanilla
Generate the patch file based on the deltas between vanilla kernel version and the official Rasperry Pi version:
git diff --no-prefix vanilla/master HEAD > patchfile
Move the patchfile to the vanilla kernel directory:
mv patchfile ../linux_vanilla_kernel/
Apply the patchfile to the vanilla version
patch -p0 < patchfile
Rebuild the kernel:
make mrproper
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
alias make='make -j8'
make bcmrpi_defconfig
make

Check that no errors occurred.

Linux init process

As we have seen before, the usual boot sequence of a Linux-based platform consists of several steps :


The init process :
  • completes the boot procedure
  • have the process ID '1'
  • starts the system processes (as described in /etc/inittab)
  • is not part of the kernel, it belongs to the user space ( /sbin/init )
  • never dies : it handles the operating system's life cycle (restart, shutdown,..)
There are many alternatives for the init process, it is usually installed with one of the following startup programs :

  • sysvinit : linux traditional init program
  • upstart : used by most of the linux distributions
  • systemd : Fedora
  • busybox : for small embedded systems
When built, these projects generate an init process and a set of common tools like telinit or initctl.

Run level

At boot, init checks the inittab configuration file for the runlevel parameter. This value goes from 0 to 6 and a specific set of actions is executed for each of them.


Depending on the default init level setting, the system will execute the programs from one of the following folders :

  • Run level 0 : /etc/rc.d/rc0.d
  • Run level 1 : /etc/rc.d/rc1.d
  • Run level 2 : /etc/rc.d/rc2.d
  • Run level 3 : /etc/rc.d/rc3.d
  • Run level 4 : /etc/rc.d/rc4.d
  • Run level 5 : /etc/rc.d/rc5.d
  • Run level 6 : /etc/rc.d/rc6.d
In these directories, the program names start with either S or K followed with a sequence number and the program name.
  • The programs starting with an S are executed on system Start while the programs starting with a K are executed on system Kill. 
  • The sequence number indicates when the program has the be executed.
For example, S12syslog has to be started before S80sendmail.

Thursday, May 9, 2013

Prepare your SD Card to boot a kernel

Read this post for the kernel build instructions.
Read this post if you're interested in how the pi boots once powered up.
Read this post for the partitioning instructions.

The following files are needed on your boot partition :

- bootcode.bin
- start.elf
- fixup.dat
- cmdline.txt
- kernel.img

To get (most of) them, you can either clone this repo : https://github.com/raspberrypi/firmware.git
or download the latest repository content here.

Note : The source code of bootcode.bin and start.elf is not open source.

First boot

For the first boot tryout, we will use the files provided by the raspberry pi foundation. We voluntarily omit the modules and the file system for now, we just want to see if the booting chain is OK until the startup of the init process.

Copy bootcode.bin, start.elf, fixup.dat and kernel.img to the boot partition of your SD card.
Create a text file named cmdline.txt right next to these files and add the following kernel parameters to it :
root=/dev/mmcblk0p1 rootdelay=2
Unmount the sdcard, plug it to your Pi, power up, and pray...

Here is the resulting display :



As we can see, the kernel boots perfectly until trying to start the init process :-)

Kernel image

We want to use our own-built kernel :
# Go the build output directory
 cd /arch/arm/boot 
# Backup the previous kernel image
mv /media/mysdcard/boot/kernel.img /media/mysdcard/boot/kernel.img.backup
# Copy the kernel image to your sd card and rename it
cp Image /media/mysdcard/boot/kernel.img
Here is the result with our image :



The result is identical (except for 2 or 3 different log traces). We can now step further ...



Sunday, May 5, 2013

Raspberry Pi boot sequence

Read this post if you are not familiar with bootloaders.
For a long time, the boot sequence consisted of 3 stages as shown above. Lately, the 3rd stage has been short circuited : the start.elf image is now directly read by the 2nd stage bootloader.

Saturday, May 4, 2013

Partition your SD Card for Pi

Create the parition table

1. Plug your SD Card to your computer.

2. Identify your /dev/ node

sudo fdisk -l
The output lists your disks :
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1        2473    19864341    7  HPFS/NTFS
/dev/sda2            2474       19456   136415745    f  W95 Ext'd (LBA)
/dev/sda5            3279        6374    24868588+   7  HPFS/NTFS
/dev/sda6            6375       19456   105081133+   7  HPFS/NTFS
/dev/sda7            2474        3237     6133760   83  Linux
/dev/sda8            3237        3278      330752   82  Linux swap / Solaris

Partition table entries are not in disk order

Disk /dev/sdb: 3974 MB, 3974103040 bytes
4 heads, 16 sectors/track, 121280 cylinders
Units = cylinders of 64 * 512 = 32768 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1         611       19544   83  Linux
/dev/sdb2             612      121280     3861408   83  Linux

Note : sda identifies your hard drives (or partitions) while sdb (or c, d, ...) is used for removable disks

My SD Card is referred as /dev/sdb and it currently has 2 partitions.

3. Clear the partition table

sudo fdisk /dev/sdb/
At the fdisk command line prompt, enter 'o'. It will create a new virtual  DOS partition table :
Building a new DOS disklabel with disk identifier 0xd39a6636.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Now enter 'p', it will display the SD Card properties. Note the card size somewhere, we will need it later :
Disk /dev/sdb: 3974 MB, 3974103040 bytes
...

4. Set SD Card geometry

Enter 'x' to go into the expert mode.

The setup configuration is : 255 heads and 63 sectors (512 bytes each). We need to calculate the number of cylinders :

cylinders_nb = card_size_bytes / heads_nb / sectors_nb / sector_size

Here :

cylinders_nb = 3974103040 / 63 / 255 / 512 = 483, 15

The result must be rounded down, which means that cylinders_nb = 483.

Enter 'h' and set the heads number :
Expert command (m for help): h
Number of heads (1-256, default 4): 255
Enter 's' and set the sectors number:
Expert command (m for help): s
Number of sectors (1-63, default 16): 63
Warning: setting sector offset for DOS compatiblity
Enter 'c' and set the cylinders number :
Expert command (m for help): c
Number of cylinders (1-1048576, default 121280): 483

5 . Create a FAT32 partition (boot partition)

Enter 'r' to go back to normal mode.

Follow these steps :
Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-483, default 1): 1
Last cylinder, +cylinders or +size{K,M,G} (1-483, default 483): +50

Command (m for help): t
Selected partition 1
Hex code (type L to list codes): c
Changed system type of partition 1 to c (W95 FAT32 (LBA))

Command (m for help): a
Partition number (1-4): 1

6. Create a Linux partition (root filesystem)

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (52-483, default 52): (press Enter)
Using default value 52
Last cylinder, +cylinders or +size{K,M,G} (52-483, default 483): (press Enter)
Using default value 483

7. Apply the partition table to the card

Enter 'p' and verify that you have these 2 partitions :
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1          51      409626    c  W95 FAT32 (LBA)
/dev/sdb2              52         483     3470040   83  Linux
Enter 'w' to write it on the card.

Format the SD Card

1. Format the DOS partition

sudo mkfs.msdos -F 32 /dev/sdb1 -n DOS

2. Format the Linux partition to ext3

sudo mkfs.ext3 /dev/sdb2 
And that's it ! To avoid doing this manually everytime, the Pi-community have written some scripts that execute these commands for you. One of them can be found here and all you have to do is :
# Make it executable
chmod +x mkcard.txt
# Run it (use your own disk node ! )
./mkcard.txt /dev/sdb

Build vanilla kernel for Raspberry Pi

Check this post if you're looking for the build instructions.
Check this post if you're looking for the git main commands.


Raspberry Pi's official kernel git repository :


We could have cloned this repository, built it and ran a linux on our Pi.... yes we could, but we are a bit sadistic and as they say in my fitness club : "No pain, no gain". So let's try something fun : cloning the mainline kernel ( the latest stable version ) and adapt it for the Pi.

Our repository is hosted on bitbucket - which is free by the way - and is a clone of the mainline kernel 3.8.9 :


What we need to do first is grabbing the raspberry Pi's defconfig file. Manually configuring the build would take too much time and requires strong technical skills. This method will be experimented later...
Now we got the file, copy it to arch/arm/configs, and run :
make bcmrpi_defconfig
(ARCH and CROSS_COMPILE must be defined)

First build attempt will fail with :
ERROR: "v7wbi_flush_kern_tlb_range" [drivers/staging/zsmalloc/zsmalloc.ko] undefined!
make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2
Not surprising, otherwise a git repository dedicated to the Pi would certainly not exist. The next step is to modify our sources to make them build for the Pi.

Generate a patch to merge the vanilla sources with the rpi ones

The following method is not really the best way for the patch generation, you should consider using git format-patch instead, but, if like me you're living in a building with a poor internet connection, you may want to do it like this :

1. Download the official linux rpi-3.8.y archive from github (about 100 MB, not a big deal compared to GBs of data that you have to download using git fetch command with the rpi remote repo)
2. Create a local git repo with your rpi sources :
# Create a directory where you'll store the rpi linux sources
mkdir rpi-3.8.y
cd rpi-3.8.y
# Move the archive to the current directory
mv /Downloads/linux-rpi-3.8.y.tar.gz .
# Extract it
tar -xf linux-rpi-3.8.y.tar.gz
# Initialize the repository
git init
# Add all elements
git add .
# Commit them
git commit -m "added : rpi-3.8.y sources"
3. Let's assume that your vanilla kernel sources are in a directory named linux_vanilla_kernel :
# Add the vanilla kernel git repo 
git remote add vanilla ../linux_vanilla_kernel/
# Fetch the vanilla kernel repo
git fetch vanilla
After a while, you should obtain an output saying that a branch has been created with vanilla kernel sources :
master --> master/vanilla
4. Generate the patch
git diff --no-prefix master/vanilla HEAD > patchfile

5. You can now apply the patch to your vanilla kernel sources
# Move the patch to your vanilla kernel working directory
mv patchfile ../linux_vanilla_kernel/
cd ../linux_vanilla_kernel
# Apply the patch
patch -p0 < patchfile
6.Build again
make bcmrpi_defconfig
make -j8
The build process should end successfully now.


Tuesday, April 30, 2013

Git tutorial

Git is a distributed version control system which means that it does not require a central server to store all the data, unlike SVN or CVS. In practice, there is usually a central repository (remote repository, typically hosted on the internet) that one can copy (cloning). When cloning an existing repository , the user grabs the whole working tree. If you'd like to create a branch for instance to work on a specific part of your code in parallel, the branch will be local. The central copy does not need to have a counterpart.

Linux kernel's project is using git as its version control system. Some of the following commands may be useful :

Create a Git repository

# Run it in your development directory
git init
This folder will then contain a .git directory containing the complete history of the repository and .git/config will store the local configuration for it.

Add files to the repository

# Replace . by the file name if you're not planning to add all files
git add .
The marked files have been added to the staging area. It means that they will be part of the next commit. All of your modified files need to be staged (added) so that they will be included in the next commit.

Check repository status

git status
You will see which files have been modified, which ones are staged and which are not, conflicts, etc...

Commit files to the repository

git commit -m "Commit message"

Trace back your modifications

git log
You will see the list of your commits and your activity in your working tree.

Move / Rename a file

git mv <orignial file path> <new file path>

Remove a file from repository

git rm <file name>
Note : you can also simply delete the file manually. In this case, you have to add the '-a' option to the commit command to take the deletion into account.

Remove a file from staging area

git reset <file name>

Working with Remote Repositories

Ok, now we got the basics, how do we synchronize our work with others ? In the example above, we started from scratch, and our repository is local. What if somebody would like to copy it ?

Clone a remote repository

Imagine that we created a repo in a folder named "original_repo". Let's move back and create a new folder :
cd ..
mkdir clone_repo
cd clone_repo
Once we're here, we will clone the "original_repo" into "clone_repo" :
git clone ../original_repo.git .
Note : A git repository address always end with a ".git" extension.
Note 2 : If you omit the '.' at the end of the command, git will create a directory named like the origin (here 'original_repo'), move into it and pull the files from there.

If the git repository is hosted on the web, it is almost the same :
git clone https://linux389pi@bitbucket.org/linux389pi/linux389pi.git

Push changes to a remote repository


You probably noticed that git commit does not mirror your modifications on the remote repository. Instead, it creates a local commit object (snapshot). To send your modification to the central repository, you will have to push your local repository:
git push

Pull changes from the remote repository

The opposite action of pushing is pulling. You will synchronize your repository with the central one by pulling :
git pull

If you are looking for more information about git, check this link :

Git - Book 

If you are also willing to experiment git with a very cool tutorial, here is the link :

Git in practice 

Sunday, April 28, 2013

Boot sequence on embbeded platform

When powered on, the CPU will fetch its first instruction from an address preassigned by the manufacturer. From there, two options :

  • the bootlader is programmed at this address (on a NOR memory)
  • the CPU has an integrated boot code that will start ( ROM memory)

The former is not very common anymore as it requires some NOR flash to be wired to the CPU while the latter boots in two steps (first and second stage). Here is a typical example with an AT91 CPU:


The mechanism is almost always identical with other CPUs. The first stage bootloader is usually provided by the CPU vendor (X-Loader instead of AT91Bootstrap for OMAP3 CPUs) and limited in size due to hardware constraints (SRAM size).

The Bootloader

It is a small piece of code responsible of :

  • low level hardware initialization (network, USB, ...)
  • loading the operating system kernel to memory (from disk, network or non-volatile storage)
  • booting the kernel 

Additionally, the bootloader may provide a shell and some services for testing, diagnosis or file transfer.

You can find information about the existing bootloaders at :
Comparison of bootloaders

A very good page describing the boot sequence in details for AT91:
AT91 Boot sequence

We will focus on the bootloader named u-boot as it is the most popular one for ARM platforms.

Saturday, April 27, 2013

Embedded development setups

Linked Setup (most common)

The host and the target are permanently connected using a cable (serial or ethernet). With this configuration, the host builds the cross-compiled binaries and downloads them directly on the device's storage media. The cable is also used for debugging although there are usually 2 cables : serial for debugging and ethernet for downloading the software.

Requirements for this setup :
  • host : cross-platform development environment installed
  • target : appropriate bootloader, functional kernel, minimal root filesystem
Note : the root filesystem could also be NFS-mounted instead of being on the storage media in the target. This is perfect for development as it avoids having to copy the program modifications all the time.

Removable Storage Setup

The host and the target are not physically connected. Instead, the host builds the binaries and copy them to a removable storage media such as an MMC Card. The card is then inserted into the device's socket and loaded by the target's minimal bootloader upon startup.

Requirements for this setup :
  • host : cross-platform development environment installed
  • target : minimal bootloader 
  • card : kernel, root filesystem, optionnally a second bootloader

Standalone setup


The development is made exclusively on the target. The development tools run in their native environments and the required storage is local to the target. We are not in a Host/Target setup anymore but more a Host/Host setup.

Requirements for this setup :
  • target : bootloader, kernel, full root filesystem, native development environment

Friday, April 26, 2013

Delivered !

I am now the lucky owner of this small piece of hardware :-)



The Raspberry Pi will be our development board during our initiation to linux. It is small, light, cheap and powerful enough to read 720p videos without a hitch.

You can find additional information about this very popular board on :

GPL and LGPL licenses

Most of the components making up a Linux system are distributed under two type of licenses :

  •  GPL : mainly used for applications (gcc compiler, gdb debugger)
  •  LGPL : mainly used for libraries (C library, GTK widget toolkit, ...)

Other licenses exist (BSD, Mozilla, ...) but are less used.

GPL restrictions
(summarized) :

  • one can make several copies of the program as long as the licence and copyright remain intact
  • a program distributed under this licence comes with no warranty whatsoever unless it is brought by the distributor
  • you can charge for the act of copying and for warranty protection
  • if you distribute copies of the binary, you must accompany them with the original source code
  • if you're modifying the source code of a GPL binary, the resulting program will be subject to the GPL license as well with no additional restriction permitted

If you're planning to link your software against a GPL-licensed library (statically or dynamically), you're falling under the GPL too. It is the main difference with LGPL which allows you to use unmodified parts of a program without license restriction. Thus, you can link against an LGPL library with no fear of being forced to distribute your binary under the same license. However, you are not free to distribute a modified LGPL library under any other license than LGPL.

Saturday, April 20, 2013

Embedded Linux (part 2)


Méthodologie de création d'un système Linux embarqué



La structure du système est calquée sur les autres systèmes Unix libres ou propriétaires à savoir :

• un noyau ou kernel réalisant les fonctions essentielles comme la gestion des tâches et de la mémoire, ainsi que l’interfaçage entre le matériel et les applicatifs grâce entre autres aux pilotes de périphériques ou en anglais device drivers ;

• une bibliothèque principale appelée libc ou glibc (GNU libc) sous Linux et contenant
les fonctions de base utilisées par les applicatifs ;

• les applicatifs eux-mêmes, appelés également commandes, soit livrés en standard avec
le système ou bien développés pour des besoins spécifiques.


À ces éléments standards il faut ajouter un programme de démarrage ou bootstrap comme LILO (LInux LOader). À la différence des autres composants du système, le programme de démarrage ou chargeur est très dépendant du matériel utilisé.
Le schéma de démarrage d’un système Linux est relativement simple et on peut le décomposer comme suit :

1. Chargement du système par LILO ou un programme équivalent, comme GRUB.

2. Chargement du noyau Linux. Le chargement s’accompagne de l’initialisation des périphériques matériels indispensables au démarrage, et donc au chargement des pilotes de périphériques associés. Le noyau Linux tente également de charger sa partition principale ou root partition sur laquelle il ira chercher les éléments nécessaires à la suite du lancement du système.

3. Lorsque le noyau Linux est chargé, il exécute un programme d’initialisation qui, par défaut, correspond à la commande /sbin/init. Cependant, on peut indiquer facilement au noyau de passer la main à un autre programme.

4. Dans le cas de l’utilisation du programme init standard, ce dernier explore le fichier de configuration /etc/inittab qui contient le chemin d’accès à un script de démarrage, comme ceci :
# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.d/rc.sysinit
Le script en question poursuit l’initialisation du système.

1.Le noyau LINUX

Le noyau est l’élément principal du système, d'abord parce que ce noyau fut initialement conçu par Linus Torvalds, créateur du système Linux et de composants provenant en majorité du projet GNU de Richard Stallman. Ensuite parce que la structure monolithique du noyau en fait l’interface unique entre le système et le matériel dans la quasi-totalité des cas de figure.

1.1. Structure globale du noyau

Dans le cas de Linux, le noyau est un fichier exécutable, monolithique ou presque, chargé d’assurer les fonctions essentielles du système comme la gestion des tâches, ou scheduling, la gestion de la mémoire et le pilotage des périphériques que ceux-ci soient réellement des périphériques matériels ou bien qu’ils soient des périphériques virtuels.
Dans une distribution Linux classique, le noyau est physiquement représenté par un fichier localisé sur le répertoire /boot :

serge@serge-Aspire-4830TG:/boot$ ls -lrt
total 46484
-rw------- 1 root root 2320733 Oct 9 2012 System.map-3.5.0-17-generic
-rw-r--r-- 1 root root 154429 Oct 9 2012 config-3.5.0-17-generic
-rw-r--r-- 1 root root 853738 Oct 9 2012 abi-3.5.0-17-generic
-rw-r--r-- 1 root root 5171760 Oct 17 19:08 vmlinuz-3.5.0-17-generic
-rw-r--r-- 1 root root 178944 Jan 3 23:47 memtest86+_multiboot.bin
-rw-r--r-- 1 root root 176764 Jan 3 23:47 memtest86+.bin
-rw------- 1 root root 5169520 Mar 25 21:29 vmlinuz-3.5.0-27-generic
-rw------- 1 root root 2320304 Mar 25 21:29 System.map-3.5.0-27-generic
-rw-r--r-- 1 root root 154652 Mar 25 21:29 config-3.5.0-27-generic
-rw-r--r-- 1 root root 860818 Mar 25 21:29 abi-3.5.0-27-generic
-rw-r--r-- 1 root root 15066322 Apr 16 21:16 initrd.img-3.5.0-17-generic
drwxr-xr-x 5 root root 4096 Apr 16 21:29 grub
-rw-r--r-- 1 root root 15142645 Apr 16 21:30 initrd.img-3.5.0-27-generic


Le nom du noyau est libre mais il est généralement suffixé en fonction de la version du noyau, ici 3.5.0 et de l’extra-version choisie par celui qui a généré ce noyau, soit 17 dans le cas présent.
Nous verrons que l’extra-version est définie dans le fichier Makefile de l’arborescence des sources du noyau.
Le noyau Linux utilise également un fichier nommé System.map qui contient des informations sur des adresses internes du noyau. Ces informations sont utiles à la gestion des modules décrits ci-après. Le fichier System.map est également présent sur le répertoire /boot. En toute rigueur, il est lié à la version complète du noyau généré, y compris l’extra-version, car il est généré lors de la compilation du noyau.

1.2. Les modules chargeables du noyau

Dans les cas d’applications classiques de Linux, le noyau utilise le plus souvent des modules qui peuvent être dynamiquement chargés et déchargés en fonction des besoins du système.
Ces modules peuvent être des pilotes de périphériques matériels, comme des cartes d’extension, ou bien liés à un support générique de plus haut niveau comme le support SCSI. L’utilisation des modules permet d’optimiser la mémoire du système à un instant donné car un pilote non utilisé pourra être déchargé, libérant ainsi sa mémoire.
De même, l’utilisation des modules permettra d’ajouter dynamiquement des périphériques sans redémarrer le système.

Dans le cas d’un noyau embarqué, on pourra cependant se poser la question quant à l’utilisation des modules sachant que ceux-ci nécessitent la validation d’options spécifiques lors de la compilation du noyau, ce qui augmente légèrement sa taille. De même, la hiérarchie des modules nécessite la mise en place du répertoire /lib/modules, ce qui augmente le nombre de fichiers, la complexité du système et aussi légèrement l’espace occupé par ce dernier.

Le choix de l’utilisation ou non des modules sera laissé à la charge de l’intégrateur du système en fonction de ses besoins.
serge@serge-Aspire-4830TG:/boot$ ls -l /lib/modules
total 8
drwxr-xr-x 4 root root 4096 Oct 17 17:00 3.5.0-17-generic
drwxr-xr-x 4 root root 4096 Apr 16 21:28 3.5.0-27-generic

À chaque sous-répertoire correspond une version du noyau. Dans le cas présent, les
modules utilisés par le noyau seront localisés dans le répertoire 3.5.0-17.
serge@serge-Aspire-4830TG:/lib/modules$ ls -l 3.5.0-17-generic
total 4640
lrwxrwxrwx 1 root root 39 Nov 14 23:08 build -> /usr/src/linux-headers-3.5.0-17-generic
drwxr-xr-x 2 root root 4096 Oct 17 16:58 initrd
drwxr-xr-x 10 root root 4096 Oct 17 16:59 kernel
-rw-r--r-- 1 root root 739381 Oct 17 17:00 modules.alias
-rw-r--r-- 1 root root 719847 Oct 17 17:00 modules.alias.bin
-rw-r--r-- 1 root root 6027 Oct 9 2012 modules.builtin
-rw-r--r-- 1 root root 7365 Oct 17 17:00 modules.builtin.bin
-rw-r--r-- 1 root root 69 Oct 17 17:00 modules.ccwmap
-rw-r--r-- 1 root root 351471 Oct 17 17:00 modules.dep
-rw-r--r-- 1 root root 518442 Oct 17 17:00 modules.dep.bin
-rw-r--r-- 1 root root 214 Oct 17 17:00 modules.devname
-rw-r--r-- 1 root root 889 Oct 17 17:00 modules.ieee1394map
-rw-r--r-- 1 root root 295 Oct 17 17:00 modules.inputmap
-rw-r--r-- 1 root root 21817 Oct 17 17:00 modules.isapnpmap
-rw-r--r-- 1 root root 2486 Oct 17 17:00 modules.ofmap
-rw-r--r-- 1 root root 144391 Oct 9 2012 modules.order
-rw-r--r-- 1 root root 471479 Oct 17 17:00 modules.pcimap
-rw-r--r-- 1 root root 1765 Oct 17 17:00 modules.seriomap
-rw-r--r-- 1 root root 131 Oct 17 17:00 modules.softdep
-rw-r--r-- 1 root root 285690 Oct 17 17:00 modules.symbols
-rw-r--r-- 1 root root 363056 Oct 17 17:00 modules.symbols.bin
-rw-r--r-- 1 root root 1063926 Oct 17 17:00 modules.usbmap

Les modules sont répartis dans des sous-répertoires selon une classification fonctionnelle.
La liste ci-après permet de visualiser les modules correspondant à des pilotes réseau :
serge@serge-Aspire-4830TG:/lib/modules/3.5.0-17-generic$ ls -l /lib/modules/3.5.0-17-generic/kernel/drivers/net | head
total 244
drwxr-xr-x 2 root root 4096 Oct 17 16:59 appletalk
drwxr-xr-x 2 root root 4096 Oct 17 16:59 arcnet
drwxr-xr-x 2 root root 4096 Oct 17 16:58 bonding
drwxr-xr-x 2 root root 4096 Oct 17 16:59 caif
drwxr-xr-x 7 root root 4096 Oct 17 16:59 can
drwxr-xr-x 2 root root 4096 Oct 17 16:59 dsa
-rw-r--r-- 1 root root 7464 Oct 9 2012 dummy.ko
-rw-r--r-- 1 root root 9280 Oct 9 2012 eql.ko
drwxr-xr-x 46 root root 4096 Oct 17 16:59 ethernet

serge@serge-Aspire-4830TG:/lib/modules/3.5.0-17-generic/kernel/net/wireless$ ls -lrt
total 268
-rw-r--r-- 1 root root 9608 Oct 9 2012 lib80211.ko
-rw-r--r-- 1 root root 6760 Oct 9 2012 lib80211_crypt_wep.ko
-rw-r--r-- 1 root root 12672 Oct 9 2012 lib80211_crypt_tkip.ko
-rw-r--r-- 1 root root 8328 Oct 9 2012 lib80211_crypt_ccmp.ko
-rw-r--r-- 1 root root 225020 Oct 9 2012 cfg80211.ko

Le fichier modules.dep contient les dépendances entre les modules sous la forme d’une
simple liste contenant une définition de dépendance par ligne. Cette liste est générée au
démarrage du système par la commande depmod -a.

On doit également utiliser cette commande chaque fois que l’on ajoute un nouveau
module à l’arborescence des modules. Un extrait de la liste est présenté ci-après :

/lib/modules/2.4.7-10/kernel/fs/vfat/vfat.o:
/lib/modules/2.4.7-10/kernel/fs/fat/fat.o
La ligne ci-après montre que le module vfat.o nécessite la présence du module fat.o.

Bien que les modules soient normalement chargés de manière automatique par le système, nous allons décrire en quelques lignes les principales commandes de manipulation des modules, et ce afin de donner un bon aperçu des opérations possibles sur les modules.
Remarque
Les modules sont manipulés grâce à un paquetage nommé modutils. En cas d’utilisation du noyau 2.6, il est nécessaire d’utiliser une version récente du paquetage (module-init-tools-3.0 ou supérieur) disponible en téléchargement avec les sources du noyau. Ces dernières versions sont compatibles 2.4 et 2.6.

On peut forcer le chargement d’un module en utilisant la commande insmod. Prenons l’exemple d’un module hello.o sans dépendance avec aucun autre module.
On peut charger ce module au moyen de la commande :
root#> insmod hello.o

On peut aussi ajouter ce module à l’arborescence des modules standards en effectuant :
root#> cp hello.o /lib/modules/2.4.7-10/kernel/drivers/char/lib/modules/2.4.7-1/kernel/driver/char
root#> depmod -a


puis charger ce module avec la commande :
root#> insmod hello Using /lib/modules/2.4.7-10/kernel/drivers/char/hello.o

Notez qu’il est nécessaire d’être super-utilisateur pour charger un module.
Dans le cas où le module est installé dans l’arborescence, on ne spécifie pas le suffixe. La trace du chargement effectif du module est visible dans le fichier des messages du noyau(dmesg). On peut également vérifier sa présence en utilisant la commande lsmod:

root#> dmesg | tail -1
Hello world!
root#> lsmod
Module  
Size Used by
hello     292   0 (unused)


Lors du chargement du module, il est possible de spécifier des paramètres par la ligne de commande :
root#> insmod bttv card=39

Les paramètres peuvent être spécifiés dans le fichier /etc/modules.conf afin d’être utilisés automatiquement lors du chargement du module. Dans le cas du noyau 2-6, on utilise le fichier /etc/conf.modules :
alias eth0 3c59x
options i2c-algo-bit bit_test=1
options bttv card=39


La commande alias permet de faire une association automatique entre un nom de module générique et le nom de module effectif. Dans le cas présent, le module 3c59x sera chargé lors de l’initialisation de l’interface réseau Ethernet qui nécessite le module générique eth0. Après chaque modification du fichier, on doit utiliser la commande /sbin/depmod -a.
Pour décharger le module, on utilise la commande rmmod :
root#> rmmod hello
root#> dmesg | tail -1
Goodbye cruel world!


Remarque
Dans le cas de modules dépendant d’autres modules, on ne peut cependant pas utiliser la commande
insmod.

Le système de fichier /proc

Pour communiquer avec l’espace utilisateur, le noyau Linux utilise un concept emprunté à Unix System V : le système de fichier /proc. À la différence des systèmes de fichiers classiques qui sont associés à des périphériques réels, le système de fichier /proc est virtuel. Sa structure de système de fichier en fait une représentation facile pour manipuler des paramètres du noyau Linux. On peut en effet utiliser les commandes standards de manipulation des fichiers classiques, ainsi que la redirection des entrées/sorties très utilisée sous Linux.

On peut aussi:

lister les modules charger dans le kernel:
root#> cat /proc/modules

visualiser la mémoire disponible:
root#> cat /proc/meminfo

visualiser les systèmes de fichiers supportés par le noyau:
root#> cat /proc/filesystems

visualiser la version du noyau:
root#> cat /proc/version

visualiser le type de processeur utilisé:
root#> cat /proc/cpuinfo

De même, les valeurs numériques présentes dans /proc représentent les zones d’information des processus courant, chaque valeur correspondant au PID du processus en question. Ces sous-répertoires contiennent les informations propres au processus en question :

serge@serge-Aspire-4830TG:/proc$ ls -l /proc/3962
ls: cannot read symbolic link /proc/3962/cwd: Permission denied
ls: cannot read symbolic link /proc/3962/root: Permission denied
ls: cannot read symbolic link /proc/3962/exe: Permission denied
total 0
dr-xr-xr-x 2 root root 0 Apr 20 13:36 attr
-rw-r--r-- 1 root root 0 Apr 20 13:36 autogroup
-r-------- 1 root root 0 Apr 20 13:36 auxv
-r--r--r-- 1 root root 0 Apr 20 13:36 cgroup
--w------- 1 root root 0 Apr 20 13:36 clear_refs
-r--r--r-- 1 root root 0 Apr 20 13:36 cmdline
-rw-r--r-- 1 root root 0 Apr 20 13:36 comm
-rw-r--r-- 1 root root 0 Apr 20 13:36 coredump_filter
-r--r--r-- 1 root root 0 Apr 20 13:36 cpuset
lrwxrwxrwx 1 root root 0 Apr 20 13:36 cwd
-r-------- 1 root root 0 Apr 20 13:36 environ
lrwxrwxrwx 1 root root 0 Apr 20 13:36 exe
dr-x------ 2 root root 0 Apr 20 13:36 fd
dr-x------ 2 root root 0 Apr 20 13:36 fdinfo
-r-------- 1 root root 0 Apr 20 13:36 io
-r--r--r-- 1 root root 0 Apr 20 13:36 latency
-r--r--r-- 1 root root 0 Apr 20 13:36 limits
-rw-r--r-- 1 root root 0 Apr 20 13:36 loginuid
dr-x------ 2 root root 0 Apr 20 13:36 map_files
-r--r--r-- 1 root root 0 Apr 20 13:36 maps
-rw------- 1 root root 0 Apr 20 13:36 mem
-r--r--r-- 1 root root 0 Apr 20 13:36 mountinfo
-r--r--r-- 1 root root 0 Apr 20 13:36 mounts
-r-------- 1 root root 0 Apr 20 13:36 mountstats
dr-xr-xr-x 5 root root 0 Apr 20 13:36 net
dr-x--x--x 2 root root 0 Apr 20 13:36 ns
-rw-r--r-- 1 root root 0 Apr 20 13:36 oom_adj
-r--r--r-- 1 root root 0 Apr 20 13:36 oom_score
-rw-r--r-- 1 root root 0 Apr 20 13:36 oom_score_adj
-r--r--r-- 1 root root 0 Apr 20 13:36 pagemap
-r--r--r-- 1 root root 0 Apr 20 13:36 personality
lrwxrwxrwx 1 root root 0 Apr 20 13:36 root
-rw-r--r-- 1 root root 0 Apr 20 13:36 sched
-r--r--r-- 1 root root 0 Apr 20 13:36 schedstat
-r--r--r-- 1 root root 0 Apr 20 13:36 sessionid
-r--r--r-- 1 root root 0 Apr 20 13:36 smaps
-r--r--r-- 1 root root 0 Apr 20 13:36 stack
-r--r--r-- 1 root root 0 Apr 20 13:36 stat
-r--r--r-- 1 root root 0 Apr 20 13:36 statm
-r--r--r-- 1 root root 0 Apr 20 13:36 status
-r--r--r-- 1 root root 0 Apr 20 13:36 syscall
dr-xr-xr-x 3 root root 0 Apr 20 13:36 task
-r--r--r-- 1 root root 0 Apr 20 13:36 wchan


Par exemple, le fichier status contient des informations sur l’état du processus en question.
Le système de fichier /proc est également utilisable en écriture, ce qui permet de
modifier dynamiquement le comportement du noyau Linux sans aucune compilation.

Un exemple classique est la validation d’option comme par le transfert de paquets IP (IP forwarding). On peut connaître la valeur de l’option d’IP forwarding en faisant :
root#> cat /proc/sys/net/ipv4/ip_forward
1

Le système retourne la valeur 1, ce qui signifie que l’IP forwarding est validé. On peut l’inhiber en faisant simplement :
root#> echo 0 > /proc/sys/net/ipv4/ip_forward

Une description complète du pseudo-système de fichiers /proc est disponible dans le répertoire de documentation des sources du noyau Linux, soit :
root#> more usr/src/linux-2.4/Documentation/filesystems/proc.txt
pour les noyaux 2.4 et 2.6.

###########################################################

Bibliographie

  • Linux embarqué (2e edition - Eyrolles)
  • wikipédia

 
biz.