Sei sulla pagina 1di 61

GNU/Linux su ARM

Vito De Tullio vito.detullio@gmail.com Nicola Corriero ncorriero@di.uniba.it 12 settembre 2008

Copyright 2008 Nicola Corriero, Vito De Tullio. permesso copiare, distribuire e/o modicare questo documento seguendo i termini della Licenza per documentazione libera GNU, versione 1.2 o ogni versione successiva pubblicata dalla Free Software Foundation; senza sezioni non modicabili, senza testi di prima di copertina e di quarta di copertina. Una copia della licenza inclusa nella sezione intitolata Licenza per la documentazione libera GNU.

Indice
1 Kernel & compilatore 1.1 Kernel . . . . . . . . . . . . . . . . 1.2 Compilatore . . . . . . . . . . . . . 1.3 Congurazione dei sorgenti . . . . 1.4 Cross-compilazione . . . . . . . . 1.5 Output (Image, zImage, bzImage) 2 Avvio 2.1 Sorgenti . . . . . 2.2 Decompressione 2.3 Boot . . . . . . . 2.4 Hello, world! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 8 12 13 15 15 16 22 27 29 29 29 30 31 35 35 36 36 38 38 40 41 41

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

3 Test 3.1 Haret . . . . . . . . . . . . . . 3.1.1 Perch . . . . . . . . . 3.1.2 Come usare Haret . . 3.1.3 Codice . . . . . . . . . 3.1.4 Problemi . . . . . . . . 3.1.5 Compilazione di Haret 3.2 Qemu . . . . . . . . . . . . . 3.2.1 Come ottenerlo . . . . 3.2.2 Emulazione . . . . . . 3.2.3 Sistemi emulati . . . . 3.3 U-Boot . . . . . . . . . . . . .

4 Debugger 4.1 A che serve . . . . . . . . . . . . . . . . . . . . . . . . . 3

INDICE 4.2 Quale usare . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 Come usarlo . . . . . . . . . . . . . . . . . . . . . . . . 42 42 45 47 49 49 61

A Assembly per ARM B Comandi principali gdb C Licenza per la documentazione libera GNU C.1 GNU Free Documentation License . . . . . . . . . . . . Bibliograa

Introduzione
Questo lavoro ha la presunzione di voler ordinare le idee riguardo lavvio di un sistema GNU/Linux su Arm dal momento che allo stato attuale delle cose non esiste una guida a proposito. Si inizia parlando della fase di compilazione e del kernel. I problemi nascono dal momento che abitualmente si lavora su piattaforma x86, mentre nel nostro caso si ha lesigenza di compilare su una piattaforma differente. In gergo si parla di cross-compilazione. Infatti, prenderemo un compilatore tipico della piattaforma ARM e lo useremo su piattaforma x86 per generare eseguibili su ARM. Il lavoro continua presentando le componenti del kernel necessarie su ARM e parlando dei possibili output del kernel stesso. Segue una dettagliata descrizione della fase di avvio del kernel commentando direttamente il codice assembly e C eseguito sia in fase di decompressione del kernel sia in fase di avvio. Nel capitolo 3 si analizzano gli strumenti utilizzati per il testing del kernel su ARM. Qemu un programma di emulazione molto semplice da usare e facilmente congurabile per i nostri scopi. Haret un programma scritto in C++ per Windows Mobile; ha lobbiettivo di copiare in memoria il kernel, ed eventualmente INI TRD , spegnere lhardware e avviare il kernel in memoria in maniera non invasiva per la macchina, dal momento che non fa modiche al sistema operativo ospite. U-boot un bootloader universale per i sistemi embedded; rappresenta per una soluzione invasiva dal momento che necessario installarlo sulla memoria ash del dispositivo. Il capitolo 4 descrive come effettuare debugging sui dispositivi embedded. Verr analizzato GDB (Gnu DeBugger), analizzando 5

INDICE

come usarlo per debuggare anche il kernel. In appendice A vi una piccola guida di assembly per ARM per facilitare la compressione del codice assembly presentato nel capitolo 2.

Capitolo 1 Kernel & compilatore


1.1 Kernel

stato usata la versione 2.6.25.10 del kernel vanilla (versione di default, non patchata) reperibile presso ftp://ftp.kernel.org/ pub/linux/kernel/v2.6/linux-2.6.25.10.tar.bz2. Esistono versioni modicate da singoli per supportare questa o quellarchitettura (in particolare da notare la versione del kernel mantenuta da http://www.handhelds.org), ma non abbiamo trovato nessuna versione che gi supportasse nativamente il nostro palmare (un HTC P6300) e quindi abbiamo preferito utilizzare la versione di default.

1.2

Compilatore

Per compilare il kernel linux necessario usare il gcc, a causa delle varie estensioni del compilatore utilizzate dai kernel hackers. Sulla versione da utilizzare non ci sono preferenze, ma, in genere, pi nuovo , meglio . In effetti ci potrebbero essere problemi in caso di versioni del kernel e del compilatore particolarmente differenti tra di loro, a causa delluso (e spesso dellabuso) che viene fatto delle varie estensioni non standard. Nel nostro caso sono state usate varie versioni, principalmente 4.2.3 e 3.4.1, senza riscontrare particolari problemi. 7

CAPITOLO 1. KERNEL & COMPILATORE

1.3

Congurazione dei sorgenti

Dopo aver scaricato ed estratto il kernel, lo dobbiamo congurare per larchitettura ARM utilizzando un x86, e per questo, prima del solito make [x|menu]config, necessario associare alla variabile ARCH il valore arm: $ wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/ linux-2.6.25.10.tar.bz2 $ tar xjf kernel-2.6.25.10.tar.bz2 $ cd kernel-2.6.25.10 $ export ARCH=arm $ make menuconfig necessario prestare attenzione soprattutto al modello di palmare su cui vogliamo eseguire il kernel, pi altre minuzie per far funzionare i vari dispositivi; in particolare dal men S YSTEM T YPE A RM S YSTEM T YPE scegliamo il tipo di sistema base (nel nostro caso S AMSUNG S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443); dal men B OOT OPTIONS impostiamo CONSOLE = TTYAMA0 alla voce D EFAULT KERNEL COMMAND STRING (per poter avere in output i messaggi di comunicazione); dal men G ENERAL SETUP impostiamo 12 come valore della voce K ERNEL LOG BUFFER SIZE ; (con un buffer cos piccolo i messaggi di warning/errore vengono inviati su STDOUT il prima possibile); dal men D EVICE D RIVERS selezioniamo MMC/SD CARD SUP PORT (per poter accedere al supporto sico per il le system). Dopo anche altre personalizzazioni minori, si giunge al .CONFIG nale, che, nel nostro caso, abbastanza minimale: la maggior parte dei moduli, infatti, stata disabilitata, tranne quelli necessari a riconoscere cpu, tastiera e monitor:

1.3. CONFIGURAZIONE DEI SORGENTI

Listing 1.1: .cong nale utilizzato (le voci commentate sono state rimosse)
CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y CONFIG_GENERIC_TIME=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ZONE_DMA=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="-default" CONFIG_LOCALVERSION_AUTO=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_LOG_BUF_SHIFT=12 CONFIG_NAMESPACES=y CONFIG_SYSCTL=y CONFIG_UID16=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y CONFIG_HAVE_OPROFILE=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_BLOCK=y CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_DEFAULT_DEADLINE=y CONFIG_DEFAULT_IOSCHED="deadline" CONFIG_CLASSIC_RCU=y CONFIG_ARCH_VERSATILE=y

CONFIG_MACH_VERSATILE_AB=y CONFIG_CPU_32=y CONFIG_CPU_ARM926T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5TJ=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y

10
CONFIG_CPU_TLB_V4WBI=y CONFIG_CPU_CP15=y CONFIG_CPU_CP15_MMU=y CONFIG_ARM_VIC=y CONFIG_ICST307=y CONFIG_ARM_AMBA=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_HZ=100 CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_ALIGNMENT_TRAP=y CONFIG_ZBOOT_ROM_TEXT=0 CONFIG_ZBOOT_ROM_BSS=0 CONFIG_CMDLINE="console=ttyAMA0"

CAPITOLO 1. KERNEL & COMPILATORE

CONFIG_FPE_NWFPE=y CONFIG_BINFMT_ELF=y CONFIG_PM=y CONFIG_ARCH_SUSPEND_POSSIBLE=y

CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_PREVENT_FIRMWARE_BUILD=y

CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ATKBD=y CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y CONFIG_SERIO_AMBAKMI=y CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y

CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y

CONFIG_SSB_POSSIBLE=y

1.3. CONFIGURAZIONE DEI SORGENTI


CONFIG_VIDEO_OUTPUT_CONTROL=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_DEFERRED_IO=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_ARMCLCD=y CONFIG_FB_S1D13XXX=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_DISPLAY_SUPPORT=y

11

CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_LOGO=y CONFIG_LOGO_LINUX_MONO=y CONFIG_LOGO_LINUX_VGA16=y CONFIG_LOGO_LINUX_CLUT224=y CONFIG_MMC=y CONFIG_MMC_DEBUG=y CONFIG_MMC_BLOCK=y CONFIG_MMC_BLOCK_BOUNCE=y CONFIG_SDIO_UART=y CONFIG_MMC_ARMMMCI=y CONFIG_RTC_LIB=y CONFIG_EXT2_FS=y

CONFIG_FAT_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y

CONFIG_MSDOS_PARTITION=y CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_850=y CONFIG_NLS_ASCII=y CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_15=y CONFIG_NLS_UTF8=y CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y

CONFIG_BITREVERSE=y CONFIG_CRC32=y CONFIG_PLIST=y CONFIG_HAS_IOMEM=y

12
CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y

CAPITOLO 1. KERNEL & COMPILATORE

Listing 1.1: .cong nale utilizzato (le voci commentate sono state rimosse) Alla ne della fase di congurazione, si dovr iniziare a compilare i sorgenti. Poich vogliamo generare un kernel (quindi un eseguibile) per ARM necessario cross-compilare.

1.4

Cross-compilazione

Per compilare un kernel per ARM ci sono le seguenti opzioni: 1. Avere un sistema operativo + compilatore C su architettura ARM (e parecchio tempo, data la potenza di questi dispositivi). 2. Avere un sistema operativo + compilatore C su architettura x86 + istruire il compilatore C a generare eseguibili per architettura ARM. Si scelto di approcciarsi al problema tramite la soluzione 2. Dora innanzi, quindi, si dir
HOST

la macchina x86 su cui sono presenti compilatore e sorgenti

TARGET

la macchina ARM su cui si utilizzer effettivamente il kernel compilato

Ci comporta una serie di vantaggi: si pu utilizzare come HOST un sistema linux gi funzionante (nel nostro caso, sono stati utilizzati una debian Lenny e una OpenSuse 10.3); la capacit di calcolo di una macchina TARGET generalmente limitata, mentre le macchine HOST sono molto pi potenti (minimizzando i tempi morti in attesa del termine della compilazione)

1.5. OUTPUT (IMAGE, ZIMAGE, BZIMAGE)

13

Ovviamente vi la difcolt di avere un compilatore C in grado di generare eseguibili per la macchina TARGET. Per fortuna questo offerto da gcc. Per abilitare questa feature, per, necessario impostare una opzione in fase di compilazione. Nel nostro caso si evitato di ri-compilare il compilatore, ed stata utilizzata una versione pre-compilata di gcc da handhelds.org http://www.handhelds.org/download/projects/toolchain/[Hic08]. Tuttavia necessario istruire il kernel del fatto che vogliamo compilare i sorgenti (gi congurati) con un compilatore diverso (ed un diverso linker, assembler, ecc). Per questo viene in aiuto la variabile dambiente CROSS_COMPILER, che istruisce il make su dove andare a cercare la toolchain adatta. Terminata la parte di congurazione del kernel, come gi fatto nella sezione 1.3, non resta che compilare e testare. $ wget http://www.handhelds.org/download/projects/ toolchain/arm-linux-gcc-3.4.1.tar.bz2 $ su -c "tar xjf arm-linux-gcc-3.4.1.tar.bz2 -C /" [PASSWORD DI ROOT] $ export CROSS_COMPILE=/usr/local/arm/3.4.1/bin/armlinux$ make da notare come CROSS_COMPILE indichi il presso comune a tutti gli eseguibili necessari (ARM - LINUX - GCC, ARM - LINUX - LD...).

1.5

Output (Image, zImage, bzImage)

Terminata la fase di compilazione, verranno generati, oltre ad una serie di le temporanei / di supporto, i seguenti le. vmlinux eseguibile non compresso e non bootable del kernel. Usato soprattutto per debug, come vedremo nel capitolo 4 nella pagina 41. arch/arm/boot/Image immagine del kernel effettivamente eseguita

14

CAPITOLO 1. KERNEL & COMPILATORE

Figura 1.1: Anatomia di bzImage (da en.wikipedia.org) arch/arm/boot/zImage immagine del kernel, compressa tramite gzip e preceduta da un decompressore (obsoleta) arch/arm/boot/bzImage (big zImagebig zImage) concatenatzione di bootsect.o + setup.o + misc.o + piggy.o.[Lin05, vml08]

Capitolo 2 Avvio
Una volta che il bootloader ha caricato il kernel in memoria e lha eseguito, vi la fase di bootstrap che, nellarchitettura ARM, implementata per la maggior parte in assembly.

2.1

Sorgenti

Il codice che si prende carico del boot del sistema presente principalmente nelle directory ARCH / ARM / BOOT / COMPRESSED e ARCH / AR M / KERNEL ove sono presenti, oltre a del codice dappoggio per comprimere e decomprimere leseguibile, anche una serie di le .S (scritti in assembly per ARM) tra i quali sono degni di nota i 2 le HEAD .S. ARCH / ARM / KERNEL / HEAD .S, in particolare, contiene la parte di codice che, di fatto, il punto di partenza del kernel. In effetti questo codice, compilato, corrisponde alle prime istruzioni presenti in nel le I MAGE gi descritto; Ovviamente nel caso si decida di usare i le Z I MAGE e BZ I MAGE, questo codice sar quello invocato al termine della decompressione del kernel stesso. Ci si evince anche dai commenti presenti nel le, come si pu vedere:
59 60 61 62 /* * Kernel startup entry point. * --------------------------*

15

16
63 64 65 66 67 68 69 70 71 * * * * * * * * *

CAPITOLO 2. AVVIO

This is normally called from the decompressor code. The requirements are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, r1 = machine nr, r2 = atags pointer. This code is mostly position independent, so if you link the kernel at 0xc0008000, you call this at __pa(0xc0008000). See linux/arch/arm/tools/mach-types for the complete list of machine numbers for r1.

In particolare, viene fatto riferimento al le ARCH / ARM / TOOLS / MACH questi altro non che un database in cui si associa ad ogni modello supportato dal kernel che implementa le speciche dellARM, una serie di codici univoci usati per poter generare delle guardie per implementare codice dipendente da macchina a macchina. Questo le mantenuto dal The ARM Linux Project[Pro08], che assicura lunivocit degli identicatori usati per i vari palmari. In aggiunta a questo le vi uno script awk (ARCH / ARM / TOOLS / GEN MACH - TYPES ) capace di trasformare questo le di congurazione nel le INCLUDE / ASM - ARM / MACH - TYPES . H, pieno di macro usate in fase di compilazione per abilitare o meno il codice specico della macchina target.
TYPES :

2.2

Decompressione

Le prime istruzioni eseguite allavvio di una zImage sono quelle relative alla decompressione del kernel. Il codice relativo alla decompressione scritto in Assembly e si trova allinterno del le ARCH / ARM / BOOT / COMPRESSED / HEAD . S
109 110 111 112 113 114 115 116 117 118 119 120 121 122 .section ".start", #alloc, #execinstr /* * sort out different calling conventions */ .align start: .type start,#function .rept 8 mov r0, r0 .endr b 1f .word 0x016f2818 loader .word start address

@ Magic numbers to help the @ absolute load/run zImage

2.2. DECOMPRESSIONE
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 .word mov mov _edata r7, r1 r8, #0 @ zImage end address @ save architecture ID @ save r0

17

1:

#ifndef __ARM_ARCH_2__ /* * Booting from Angel - need to enter SVC mode and disable * FIQs/IRQs (numeric definitions from angel arm.h source). * We only do this if we were in user mode on entry. */ mrs r2, cpsr @ get current mode tst r2, #3 @ not user? bne not_angel mov r0, #0x17 @ angel_SWIreason_EnterSVC swi 0x123456 @ angel_SWI_ARM not_angel: mrs r2, cpsr @ turn off interrupts to orr r2, r2, #0xc0 @ prevent angel from running msr cpsr_c, r2 #else teqp pc, #0x0c000003 @ turn off interrupts #endif /* * Note that some cache flushing and other stuff may * be needed here - is there an Angel SWI call for this? */ /* * some architecture specific code can be inserted * by the linker here, but it should preserve r7 and r8. */ .text adr ldmia subs

r0, LC0 r0, {r1, r2, r3, r4, r5, r6, ip, sp} r0, r0, r1 @ calculate the delta offset @ if delta is zero, were @ running at the address we @ were linked at.

beq

not_relocated

/* * Were running at a different address. * up various pointers: r5 - zImage base address * r6 - GOT start * ip - GOT end * */ add r5, r5, r0 add r6, r6, r0 add ip, ip, r0

We need to fix

#ifndef CONFIG_ZBOOT_ROM /* * If were running fully PIC === CONFIG_ZBOOT_ROM = n, * we need to fix up pointers into the BSS region.

18
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 * * * */ add add add r2 - BSS start r3 - BSS end sp - stack pointer r2, r2, r0 r3, r3, r0 sp, sp, r0

CAPITOLO 2. AVVIO

1:

/* * Relocate */ ldr r1, add r1, str r1, cmp r6, blo 1b

all entries in the GOT table. [r6, #0] r1, r0 [r6], #4 ip @ relocate entries in the GOT @ table. This fixes up the @ C references.

#else /* * Relocate entries in the GOT table. We only relocate * the entries that are outside the (relocated) BSS region. */ ldr r1, [r6, #0] @ relocate entries in the GOT cmp r1, r2 @ entry < bss_start || cmphs r3, r1 @ _end < entry addlo r1, r1, r0 @ table. This fixes up the str r1, [r6], #4 @ C references. cmp r6, ip blo 1b

1:

#endif not_relocated: 1: mov str str str str cmp blo r0, r0, r0, r0, r0, r2, 1b #0 [r2], [r2], [r2], [r2], r3

#4 #4 #4 #4

@ clear bss

/* * The C runtime environment should now be setup * sufficiently. Turn the cache on, set up some * pointers, and start decompressing. */ bl cache_on mov add r1, sp r2, sp, #0x10000 @ malloc space above stack @ 64k max

/* * Check to see if we will overwrite ourselves. r4 = final kernel address * r5 = start of this image * r2 = end of malloc space (and therefore this image) * * We basically want: r4 >= r2 -> OK * r4 + image length <= r5 -> OK *

2.2. DECOMPRESSIONE
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 */ cmp bhs add cmp bls mov mov mov bl add bic /* * r0 * r1-r3 * r4 * r5 * r6 * r7 * r8-r14 */ = = = = = = = r4, r2 wont_overwrite r0, r4, #4096*1024 r0, r5 wont_overwrite r5, r2 r0, r5 r3, r7 decompress_kernel r0, r0, #127 r0, r0, #127

19

@ 4MB largest kernel size

@ decompress after malloc space

@ align the kernel length

decompressed kernel length unused kernel execution address decompressed kernel start processor ID architecture ID unused add adr ldr add ldmia stmia ldmia stmia cmp blo bl add r1, r5, r0 r2, reloc_start r3, LC1 r3, r2, r3 r2!, {r8 - r13} r1!, {r8 - r13} r2!, {r8 - r13} r1!, {r8 - r13} r2, r3 1b cache_clean_flush pc, r5, r0 @ end of decompressed kernel

1:

@ copy relocation code

@ call relocation code

/* * Were not in danger of overwriting ourselves. * = kernel execution address * r4 = architecture ID * r7 */ wont_overwrite: mov r0, r4 mov r3, r7 bl decompress_kernel b call_kernel .type .word .word .word .word .word .word .word .word LC0, #object LC0 __bss_start _end _load_addr _start _got_start _got_end user_stack+4096

Do this the simple way.

LC0:

@ @ @ @ @ @ @ @

r1 r2 r3 r4 r5 r6 ip sp

20
294 295 LC1: .word .size reloc_end - reloc_start LC0, . - LC0

CAPITOLO 2. AVVIO

Dove la funzione STAR T _ KERNEL presente nel le BOOT / COMPRESSED / MISC . C .


345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361

ARCH / ARM /-

ulg decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p, int arch_id) { output_data = (uch *)output_start; /* Points to kernel start */ free_mem_ptr = free_mem_ptr_p; free_mem_ptr_end = free_mem_ptr_end_p; __machine_arch_type = arch_id; arch_decomp_setup(); makecrc(); puts("Uncompressing Linux..."); gunzip(); puts(" done, booting the kernel.\n"); return output_ptr; }

La funzione gunzip() presente nel le


1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177

LIB / INFLATE . C

/* * Do the uncompression! */ static int INIT gunzip(void) { uch flags; unsigned char magic[2]; /* magic header */ char method; ulg orig_crc = 0; /* original crc */ ulg orig_len = 0; /* original uncompressed length */ int res; magic[0] = NEXTBYTE(); magic[1] = NEXTBYTE(); method = NEXTBYTE(); if (magic[0] != 037 || ((magic[1] != 0213) && (magic[1] != 0236))) { error("bad gzip magic numbers"); return -1; } /* We only support method #8, DEFLATED */ if (method != 8) { error("internal error, invalid method"); return -1; } flags = (uch)get_byte();

2.2. DECOMPRESSIONE
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 if ((flags & ENCRYPTED) != 0) { error("Input is encrypted"); return -1; } if ((flags & CONTINUATION) != 0) { error("Multi part input"); return -1; } if ((flags & RESERVED) != 0) { error("Input has invalid flags"); return -1; } NEXTBYTE(); /* Get timestamp */ NEXTBYTE(); NEXTBYTE(); NEXTBYTE(); (void)NEXTBYTE(); (void)NEXTBYTE(); /* Ignore extra flags for the moment */ /* Ignore OS type for the moment */

21

if ((flags & EXTRA_FIELD) != 0) { unsigned len = (unsigned)NEXTBYTE(); len |= ((unsigned)NEXTBYTE())<<8; while (len--) (void)NEXTBYTE(); } /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { /* Discard the old name */ while (NEXTBYTE() != 0) /* null */ ; } /* Discard file comment if any */ if ((flags & COMMENT) != 0) { while (NEXTBYTE() != 0) /* null */ ; } /* Decompress */ if ((res = inflate())) { switch (res) { case 0: break; case 1: error("invalid compressed format (err=1)"); break; case 2: error("invalid compressed format (err=2)"); break; case 3: error("out of memory"); break; case 4: error("out of input data"); break; default: error("invalid compressed format (other)"); }

22
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 return -1; } /* Get the crc and original length */ /* crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ orig_crc = (ulg) NEXTBYTE(); orig_crc |= (ulg) NEXTBYTE() << 8; orig_crc |= (ulg) NEXTBYTE() << 16; orig_crc |= (ulg) NEXTBYTE() << 24; orig_len orig_len orig_len orig_len = (ulg) NEXTBYTE(); |= (ulg) NEXTBYTE() << 8; |= (ulg) NEXTBYTE() << 16; |= (ulg) NEXTBYTE() << 24;

CAPITOLO 2. AVVIO

/* Validate decompression */ if (orig_crc != CRC_VALUE) { error("crc error"); return -1; } if (orig_len != bytes_out) { error("length error"); return -1; } return 0; underrun: /* NEXTBYTE() gotos here if needed */ error("out of input data"); return -1; }

2.3

Boot

Tornando alla sequenza di boot, analizziamo un attimo le prime istruzioni presenti in ARCH / ARM / KERNEL / HEAD .S:
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 .section ".text.head", "ax" .type stext, %function ENTRY(stext) msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled mrc p15, 0, r9, c0, c0 @ get processor id bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error p bl __lookup_machine_type @ r5=machinfo movs r8, r5 @ invalid machine (r5=0)? beq __error_a @ yes, error a bl __vet_atags bl __create_page_tables

2.3. BOOT
92 93 94 95 96 97 98 99 100 101 102 /* * The following calls CPU specific code in a position independent * manner. See arch/arm/mm/proc-*.S for details. r10 = base of * xxx_proc_info structure selected by __lookup_machine_type * above. On return, the CPU will be ready for the MMU to be * turned on, and r0 will hold the CPU control register value. */ ldr r13, __switch_data @ address to jump to after @ mmu has been enabled adr lr, __enable_mmu @ return (PIC) address add pc, r10, #PROCINFO_INITFUNC

23

Allinizio degni di nota sono soprattutto i controlli effettuati dal kernel sulla possibilit di supportare processore e macchina. In caso derrore vengono invocate delle funzioni per avvisare lutente e terminare lesecuzione del programma. Altrimenti vengono salvati nel registro 10 il processore e nel registro 8 il tipo di macchina riconosciuti. Una volta superati i controlli lesecuzione continua con il codice specico della cpu. Ma vengono salvate alcune funzioni da eseguire in seguito. Nelle ultime tre righe, infatti, si istruisce il programma a salvare in r13 il codice di __ SWITCH _ DATA e a salvare il LR1 il codice per abilitare lMMU. Questi dovr essere eseguito dopo il codice specico della macchina: lultima riga, infatti, altro non fa che scrivere su PC la somma di r10 (indirizzo di memoria che contiene le informazioni sulla cpu riconosciuta) col valore di PROCINFO_INITFUNC, denito in ARCH / ARM / KERNEL / ASM - OFFSETS . C come
DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));

dove PROC _ INFO _ LIST altro non che la struttura della variabile contenente le informazioni del processore, e __ CPU _ FLUSH un suo campo. PROCINFO_INITFUNC, quindi, loffset per arrivare allindirizzo dellattributo __ CPU _ FLUSH partendo dallindirizzo base della struttura. Nel nostro caso verr eseguito il codice presente nel le ARCH / ARM / MM / PROC - ARM 926.S (cpu per la quale stiamo compilando il kernel).
471 472 473 .type __arm926_proc_info,#object __arm926_proc_info: .long 0x41069260 @ ARM926EJ-S (v5TEJ)

last register; allappendice A

per questo e per altri comandi assembly si rimanda

24
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 .long .long

CAPITOLO 2. AVVIO
0xff0ffff0 PMD_TYPE_SECT | \ PMD_SECT_BUFFERABLE | \ PMD_SECT_CACHEABLE | \ PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ .long PMD_TYPE_SECT | \ PMD_BIT4 | \ PMD_SECT_AP_WRITE | \ PMD_SECT_AP_READ b __arm926_setup .long cpu_arch_name .long cpu_elf_name .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP| HWCAP_JAVA .long cpu_arm926_name .long arm926_processor_functions .long v4wbi_tlb_fns .long v4wb_user_fns .long arm926_cache_fns .size __arm926_proc_info, . - __arm926_proc_info

Quindi andremo ad eseguire il codice presente nella funzione __ ARM 926_ SETUP, denita nello stesso le
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 .type __arm926_setup, __arm926_setup: mov r0, #0 mcr p15, 0, r0, c7, mcr p15, 0, r0, c7, #ifdef CONFIG_MMU mcr p15, 0, r0, c8, #endif #function

c7 c10, 4 c7

@ invalidate I,D caches on v4 @ drain write buffer on v4 @ invalidate I,D TLBs on v4

#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 explicitly mcr p15, 7, r0, c15, c0, 0 #endif

@ disable write-back on caches

adr r5, arm926_crval ldmia r5, {r5, r6} mrc p15, 0, r0, c1, c0 @ get control register v4 bic r0, r0, r5 orr r0, r0, r6 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN orr r0, r0, #0x4000 @ .1.. .... .... .... #endif mov pc, lr .size __arm926_setup, . - __arm926_setup

A parte il codice specico, da notare come le istruzioni ter-

2.3. BOOT

25

minino impostando il program counter col valore del last register, cio lindirizzo di __ ENABLE _ MMU. Essa denita in HEAD .S.
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 /* * Setup common bits before finally enabling the MMU. Essentially * this is just loading the page table pointer and domain access * registers. */ .type __enable_mmu, %function __enable_mmu: #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A #else bic r0, r0, #CR_A #endif #ifdef CONFIG_CPU_DCACHE_DISABLE bic r0, r0, #CR_C #endif #ifdef CONFIG_CPU_BPREDICT_DISABLE bic r0, r0, #CR_Z #endif #ifdef CONFIG_CPU_ICACHE_DISABLE bic r0, r0, #CR_I #endif mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \ domain_val(DOMAIN_IO, DOMAIN_CLIENT)) mcr p15, 0, r5, c3, c0, 0 @ load domain access register mcr p15, 0, r4, c2, c0, 0 @ load page table pointer b __turn_mmu_on

Lultima riga invoca la funzione __ TURN _ MMU _ ON, denita subito dopo.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 /* * Enable the MMU. This completely changes the structure of the visible * memory space. You will not be able to trace execution through this. * If you have an enquiry about this, *please* check the linux-arm-kernel * mailing list archives BEFORE sending another post to the list. * * r0 = cp#15 control register * r13 = *virtual* address to jump to upon completion * * other registers depend on the function called upon completion */ .align 5 .type __turn_mmu_on, %function __turn_mmu_on: mov r0, r0 mcr p15, 0, r0, c1, c0, 0 @ write control reg mrc p15, 0, r3, c0, c0, 0 @ read id reg mov r3, r3 mov r3, r3 mov pc, r13

26

CAPITOLO 2. AVVIO

Al termine della funzione, viene modicato il program counter per eseguire il contenuto di r13, contenente loggetto __ SWITCH _ DATA. Questo denito nel le ARCH / ARM / KERNEL / HEAD - COMMON .S
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 .type __switch_data: .long .long .long .long .long .long .long .long .long .long __switch_data, %object __mmap_switched __data_loc @ r4 __data_start @ r5 __bss_start @ r6 _end @ r7 processor_id @ r4 __machine_arch_type @ r5 __atags_pointer @ r6 cr_alignment @ r7 init_thread_union + THREAD_START_SP @ sp

/* * The following fragment of code is executed with the MMU on in MMU mode, * and uses absolute addresses; this is not position independent. * * r0 = cp#15 control register * r1 = machine ID * r2 = atags pointer * r9 = processor ID */ .type __mmap_switched, %function __mmap_switched: adr r3, __switch_data + 4 ldmia cmp cmpne ldrne strne bne mov cmp strcc bcc ldmia str str str bic stmia b r3!, {r4, r5, r6, r7} r4, r5 r5, r6 fp, [r4], #4 fp, [r5], #4 1b fp, #0 r6, r7 fp, [r6],#4 1b r3, {r4, r5, r6, r7, sp} r9, [r4] r1, [r5] r2, [r6] r4, r0, #CR_A r7, {r0, r4} start_kernel

@ Copy data segment if needed

1:

@ Clear BSS (and zero fp)

1:

@ @ @ @ @

Save processor ID Save machine type Save atags pointer Clear A bit Save control register values

Il primo campo delloggetto __ SWITCH _ DATA la funzione __ MMAP _ SWITCHED che, eseguita, termina invocando STAR T _ KERNEL, la funzione ad alto livello implementata in C nel le INIT / MAIN . C. E direi che pu bastare

2.4. HELLO, WORLD!

27

2.4

Hello, world!

Avendo capito dov il punto di avvio del kernel, e volendone modicare il comportamento allavvio, abbiamo deciso di iniziare dal classico Hello, world!. In particolare, abbiamo modicato i sorgenti nei le ARCH / ARM / KERNEL / HEAD COMMON .S (in modo da invocare una funzione diversa al termine della fase di bootstrap) 61 b start_kernel_hello_os /* b start_kernel */

e abbiamo modicato il le funzione da invocare allavvio)

INIT / MAIN . C

(aggiungendo la nuova

534 extern void printascii(const char*); 535 536 asmlinkage void __init start_kernel_hello_os(void) { 537 printascii("Hello, world!\n"); 538 } Il prototipo della funzione start_kernel_hello_os() identico a quello della funzione start_kernel(), inidicando al compilatore che essa una funzione che non ha parametri n restituisce niente (i due void) che la funzione non utilizzer i registri, ma solo lo stack per i parametri (come ottimizzazione)2 che il codice generato dovr essere presente in una parte ben denita del binario (in questo caso nella sezione .init.text)3 Inoltre stato necessario introdurre il prototipo della funzione printascii(), implementata in assembly nel le ARCH / ARM / KERNEL / DE BUG .S. 116 ENTRY(printascii) 117 addruart r3
2 3

Confronta http://kernelnewbies.org/FAQ/asmlinkage Confronta http://kernelnewbies.org/FAQ/InitExitMacros

28 118 119 1: 120 121 122 123 124 125 2: 126 127 128 129 b 2f waituart r2, r3 senduart r1, r3 busyuart r2, r3 teq r1, #\n moveq r1, #\r beq 1b teq r0, #0 ldrneb r1, [r0], #1 teqne r1, #0 bne 1b mov pc, lr

CAPITOLO 2. AVVIO

Purtroppo, limplementazione delle macro addruart, waituart, senduart e busyuart implemention dened, nel senso che ogni singola architettura dellARM denisce una sua versione delle quattro macro. Esse sono denite nei vari le INCLUDE / ASM - ARM / ARCH */ DEBUG - MACRO .S.

Capitolo 3 Test
La fase di test consistita nel vericare il funzionamento del kernel prima sul dispositivo HTC P6300, usando una smart card come dispositivo di boot e Haret come bootloader; poi utilizzando qemu per realizzare una macchina virtuale su cui abbiamo installato il kernel che abbiamo debuggato usando gdb; inne si vedr il comportamento del kernel usando U-boot come bootloader presente sulla memoria ash del dispositivo.

3.1

Haret

Haret[ZOS08] un boot-loader scritto in C++ per Windows Mobile

3.1.1

Perch

Esistono due modi per far partire linux su un comune palmare. Invasivo Non invasivo Nel modo invasivo viene modicato la memoria interna del palmare installandoci sopra un bootloader universale U-boot il quale permette di far partire kernel anche da remoto sin dallavvio. Con questa modalit per si perde tutto il software preinstallato sulla macchina dal momento che si sovrascrive la memoria stessa. 29

30

CAPITOLO 3. TEST

Nel modo non invasivo viene avviato un programma sotto Windows Mobile per lanciare il kernel dopo aver disabilitato lhardware in modo da non danneggiarlo. Questa , in effetti, una modalit abbastanza utilizzata anche se vi possono essere problemi di compatibilit tra lhardware e il bootloader. Volendo scelgliere la modalit non invasiva, ci siamo concentrati sul bootloader, Haret. Sul sito del progetto presente anche un wiki dove possibile trovare una lista di dispositivi testati ed in fase di testing.

3.1.2

Come usare Haret

Il suo obiettivo di preparare il dispositivo al lancio del kernel linux. Prima di tutto dobbiamo ottenerlo: sono disponibili versioni precompilate per Windows Mobile, ma abbiamo preferito lavorare con i sorgenti prelevandoli dal server svn di sviluppo. Volendo usare i sorgenti, per, sorge il problema di compilarli da una macchina x86 con sistema operativo linux verso una macchina ARM con sistema operativo Windows Mobile. Per questultimo problema, si rimanda alla sezione 3.1.5. Nel caso si preferisca usare una versione gi precompilata, baster scaricarla e copiarla sulla miniSD con alcuni le di congurazione e il kernel stesso. $ wget http://www.handhelds.org/~koconnor/haret/haret -0.5.1.exe Il le di congurazione
STAR TUP. TXT :

set KERNEL "zImage-2.6.12" set MTYPE 766 set INITRD "initrd-2.6.12-hh2.gz" set CMDLINE "root=/dev/ram0 console=tty0" bootlinux indica alleseguibile HARET. EXE come settare alcuni parametri (variabili globali allinterno del codice di haret) quali KERNEL, MTYPE,

3.1. HARET

31

INITRD, CMDLINE ed inne avvia la funzione (interna al codice di haret quindi scritta in C++) bootlinux().

3.1.3

Codice

Il codice del programma prevede parti scritte in C++ e parti scritte in Assembly. Le funzioni pi interessanti sono presenti allinterno del le LINBOOT. CPP. La funzione launchKernel() ad esempio responsabile di inibire lhardware e lanciare il kernel
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 static void launchKernel(struct bootmem *bm) { // Prep the trampoline. uint32 physAddrTram = setupTrampoline(); if (! physAddrTram) return; // Cache an mmu pointer for the trampoline uint8 *virtAddrMmu = memPhysMap(cpuGetMMU()); Output("MMU setup: mmu=%p/%08x", virtAddrMmu, cpuGetMMU()); // Call per-arch setup. int ret = Mach->preHardwareShutdown(); if (ret) { Output(C_ERROR "Setup for machine shutdown failed"); return; } Screen("Go Go Go..."); // Disable interrupts take_control(); fb_clear(&bm->pd->fbi); fb_printf(&bm->pd->fbi, "HaRET boot\nShutting down hardware\n"); // Call per-arch boot prep function. Mach->hardwareShutdown(&bm->pd->fbi); fb_printf(&bm->pd->fbi, "Turning off MMU...\n"); // Disable MMU and launch linux. mmu_trampoline(physAddrTram, virtAddrMmu, bm->physExec, Mach->flushCache); // The above should not ever return, but we attempt recovery here. return_control(); }

mentre la funzione preloader()


245 246 247 248 249 250 251 252 253 // Code to launch kernel. static void __preload preloader(struct preloadData *data) { data->fbi.fb = (uint16 *)data->physFB; data->fbi.fonts = (unsigned char *)data->physFonts; FB_PRINTF(&data->fbi, "In preloader\\n"); uint32 psr = do_cpuGetPSR(); FB_PRINTF(&data->fbi, "PSR=%%x\\n", psr);

32
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305

CAPITOLO 3. TEST
if ((psr & 0xc0) != 0xc0) FB_PRINTF(&data->fbi, "ERROR: IRQS not off\\n"); if (fbOverlaps(data)) { FB_PRINTF(&data->fbi, "Disabling framebuffer feedback\\n"); data->fbi.fb = 0; } // Copy tags to beginning of ram. char *destTags = (char *)data->startRam + PHYSOFFSET_TAGS; do_copy(destTags, data->tags, TAGSIZE); FB_PRINTF(&data->fbi, "Tags relocated\\n"); // Copy kernel image char *destKernel = (char *)data->startRam + PHYSOFFSET_KERNEL; int kernelCount = PAGE_ALIGN(data->kernelSize) / PAGE_SIZE; do_copyPages((char *)destKernel, data->indexPages, 0, kernelCount); FB_PRINTF(&data->fbi, "Kernel relocated\\n"); // Copy initrd (if applicable) char *destInitrd = (char *)data->startRam + PHYSOFFSET_INITRD; int initrdCount = PAGE_ALIGN(data->initrdSize) / PAGE_SIZE; do_copyPages(destInitrd, data->indexPages, kernelCount, initrdCount); FB_PRINTF(&data->fbi, "Initrd relocated\\n"); // Do CRC check (if enabled). if (data->doCRC) { FB_PRINTF(&data->fbi, "Checking tags crc..."); uint32 crc = crc32_be(0, destTags, TAGSIZE); crc = crc32_be_finish(crc, TAGSIZE); if (crc == data->tagsCRC) FB_PRINTF(&data->fbi, "okay\\n"); else FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n"); FB_PRINTF(&data->fbi, "Checking kernel crc..."); crc = crc32_be(0, destKernel, data->kernelSize); crc = crc32_be_finish(crc, data->kernelSize); if (crc == data->kernelCRC) FB_PRINTF(&data->fbi, "okay\\n"); else FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n"); if (data->initrdSize) { FB_PRINTF(&data->fbi, "Checking initrd crc..."); crc = crc32_be(0, destInitrd, data->initrdSize); crc = crc32_be_finish(crc, data->initrdSize); if (crc == data->initrdCRC) FB_PRINTF(&data->fbi, "okay\\n"); else FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n"); } } FB_PRINTF(&data->fbi, "Jumping to Kernel...\\n"); // Boot typedef void (*lin_t)(uint32 zero, uint32 mach, char *tags); lin_t startfunc = (lin_t)destKernel; startfunc(0, data->machtype, destTags);

sicuramente la pi importante dal momento che nelle ultime tre righe passa il controllo al kernel terminando lesecuzione di

3.1. HARET haret stesso quindi.


315 typedef void (*lin_t)(uint32 zero, uint32 mach, char *tags);

33

viene denita un prototipo di funzione di tipo puntatore a lin_t


316 lin_t startfunc = (lin_t)destKernel;

denita una variabile startfunc di tipo lin_t come cast della variabile destKernel, buffer di memoria contenente il kernel in ram
317 startfunc(0, data->machtype, destTags);

lanciata la funzione startfunc() con in input uno 0, il valore della variabile Mtype passata in precedenza e il valore di destTags, buffer di memoria contenenti i tags in ram. La programmazione in C++ suddivisa in due fasi dal momento che dopo lo shutdown dellhardware il programma accede direttamente alla memoria e non riesce a tradurre le funzioni e librerie tipiche del C++ con conseguente uso di funzion ad-hoc. Ad esempio nella funzione preloader() vi
251 FB_PRINTF(&data->fbi, "In preloader\\n");

la quale risulta una macro denita nel codice in modo seguente


225 226 227 228 229 230 231 232 233 234 235 #define STR_IN_CODE(sec,str) ({\ const char *__str;\ asm(".section " #sec ", 1\n"\ "1: .asciz\"" str "\"\n"\ " .balign 4\n"\ " .section " #sec ", 0\n"\ " add %0, pc, #( 1b - . - 8 )\n"\ : "=r" (__str));\ __str;\ }) #define FB_PRINTF(fbi,fmt,args...) fb_printf((fbi), STR_IN_CODE (.text.preload, fmt) , ##args )

Per quanto riguarda la comunicazione verso lutente in haret esistono due tipologie di output le di log; stampa a video.

34

CAPITOLO 3. TEST

Per abilitare loutput su le di log necessario creare un le vuoto allinterno della cartella dove presente leseguibile HARET. EXE e rinominarlo EARLYHARETLOG . TXT. Il le di log HARETLOG . TXT verr creato nella stessa cartella. Allinterno del codice la funzione Output() la responsabile della scrittura su le. La seconda tipologia di output si rende necessaria quando avviene lo shutdown dellhardware dal momento che non si ha pi accesso alla memoria della miniSD. Allinterno del codice la funzione fb_printf() stampa a video ove previsto. Questo rappresenta la parte nale di un le di log. Nella prima parte vi il riconoscimento della macchina da parte del sistema.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Welcome, this is HaRET pre-0.5.2-20080711_124633 running on WindowsCE v5.1 Minimal virtual address: 00010000, maximal virtual address: 7FFFFFFF Detected machine Panda/s3c2442 (Plat=PocketPC OEM=PAND100) CPU is ARM ARM arch 4T stepping 0 running in system mode Enter HELP for a short command summary. Running WSAStartup Starting gui In initdialog Found machine Panda executing startup.txt HaRET(1)# set MTYPE 1806 HaRET(2)# set KERNEL "zImage" HaRET(3)# set CMDLINE "root=/dev/mmcblk0p2 console=tty0 mem=128M rootdelay=5" HaRET(4)# bootlinux boot KERNEL=zImage INITRD= Opening file zImage boot params: RAMADDR=30000000 RAMSIZE=08000000 MTYPE=1806 CMDLINE=root=/dev/ mmcblk0p2 console=tty0 mem=128M rootdelay=5 Boot FB feedback: 1 Built virtual to physical page mapping Allocated 265 pages (tags=4FB00000/36b4e000 kernel=4FB01000/36b4f000 initrd=4 FC05000/36a47000 index=4FC05000/36a47000) Built kernel tags area Built page index Video buffer at 52800000 sx=240 sy=320 mx=60 my=53 Video Phys FB=10800000 Fonts=36a45064 preload=2260@4FC08000/36a44000 sj=4FC08000 stack=4FC06000/36a46000 data=4FC07000 /36a45000 exec=36a44128 Reading 1062116 bytes... Read complete Launching to physical address 36a44010 Trampoline setup (tram=136@00024AEC/1c024aec/30882aec) MMU setup: mmu=A0250000/30550000 Go Go Go...

Si noti come al terzo rigo avvisa dellavvenuto riconoscimento della macchina e della tipologia di cpu. Poi parte nellesecuzione del contenuto di STAR TUP. TXT come fossero comandi separati tra

3.1. HARET

35

loro (si noti il carattere # indicatore della pseudo-shell). Lultimo comando appunto bootlinux il quale fa partire lesecuzione del codice visto in precedenza. Alla ne del le di log vi la scritta Go Go Go ... che lultimo messaggio previsto dal codice prima di spegnere lhardware e lasciare lesecuzione al kernel. La presenza di questo messaggio quindi implica il successo nellesecuzione di haret. Tutti gli eventuali problemi successivi saranno dovuti al kernel non pi ad haret.

3.1.4

Problemi

Abbiamo constatato delle difcolt a debuggare su un sistema embedded. Nel nostro caso avevamo problemi dal momento che ci appariva la scritta Go Go Go... ma il kernel non partiva. Eravamo quindi davanti una serie di possibili cause da dimostrare. Il primo dubbio risolto riguardava errori presenti allinterno del codice di haret. Con un attento debug tramite stringhe stampate sullo schermo ci siamo accertati che effettivamente il controllo passava al kernel (tre righe nali viste in precedenza). Il dubbio immediatamente successivo riguardava un problema di errato passaggio del le del kernel. Anche in questo caso abbiamo stampato a video e confrontato bit a bit il le del kernel con il contenuto del buffer di memoria che veniva avviato da haret.

3.1.5

Compilazione di Haret

Per la compilazione di Haret necessario usare un compilatore C++ per ARM con Windows Mobile. Noi abbiamo usato armmingw32ce, toolset sviluppato nel progetto cegcc[ceg08], sviluppato allo scopo di compilare binari per windows CE. Dopo il dowload1 e la scompattazione si ritroveranno una serie di binari pronti alluso con il formato arm-wince-cegcc-* o arm-wince-mingw32ce-*.
Non possibile segnalare il link diretto, in quanto il progetto si appoggia a sourceforge.net, che utilizza un insieme di mirror per lo storage dei le.
1

36

CAPITOLO 3. TEST

Se si scompattano i le nella directory radice, non sar necessario modicare il Makele dei sorgenti di Haret. $ su -c "tar xzf cegcc-gcc430.tar.gz -C /" [PASSWORD DI ROOT] Per ottenere lultima versione dei sorgenti, necessario usare cvs: $ cvs -d :pserver:anoncvs@anoncvs.handhelds.org:/cvs login CVS password: anoncvs $ cvs -d :pserver:anoncvs@anoncvs.handhelds.org:/cvs co haret $ cd haret $ make al termine della compilazione, sar stato generato il le OUT / HARET. EXE, pronto per essere usato come gi detto nella sezione 3.1.2.

3.2

Qemu

Qemu un emulatore e virtualizzatore generico open source. Nello specico stato usato per emulare unarchitettura basata su cpu ARM (Versatile AB prima, Samsung S3C2442B dopo) per semplicare le procedure di testing e debugging del kernel.

3.2.1

Come ottenerlo

Qemu libero e gi installato nella maggior parte delle distribuzioni. Le versioni da noi usate sono state la 0.9.0 e la 0.9.1. Se non gi installato sar sufciente usare il package manager della distribuzione (YaST per OpenSuSE, Synaptic per Debian e derivate, installpkg per Slackware, eccetera); nella (improbabile) ipotesi che non sia disponibile, i sorgenti sono disponibili presso http://bellard.org/qemu/qemu-0.9.1.tar.gz. In ogni caso si avr accesso allapplicazione tramite terminale.

3.2. QEMU Listing 3.1: Output di


QEMU

37 lanciato senza parametri

$ qemu QEMU PC emulator version 0.9.1, Copyright (c) 2003-2008 Fabrice Bellard usage: qemu [options] [disk_image] disk_image is a raw hard image image for IDE hard disk 0 Standard options: -M machine select emulated machine (-M ? for list) -cpu cpu select CPU (-cpu ? for list) -fda/-fdb file use file as floppy disk 0/1 image -hda/-hdb file use file as IDE hard disk 0/1 image -hdc/-hdd file use file as IDE hard disk 2/3 image -cdrom file use file as IDE cdrom image (cdrom is ide1 master) -drive [file=file][,if=type][,bus=n][,unit=m][,media=d][index=i] [,cyls=c,heads=h,secs=s[,trans=t]][snapshot=on|off] [,cache=on|off] use file as a drive image -mtdblock file use file as on-board Flash memory image -sd file use file as SecureDigital card image -pflash file use file as a parallel flash image -boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n) -snapshot write to temporary files instead of disk image files -no-frame open SDL window without a frame and window decorations -alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt) -no-quit disable SDL window close capability -no-fd-bootchk disable boot signature checking for floppy disks -m megs set virtual RAM size to megs MB [default=128] -smp n set the number of CPUs to n [default=1] -nographic disable graphical output and redirect serial I/Os to console -portrait rotate graphical output 90 deg left (only PXA LCD) -k language use keyboard layout (for example "fr" for French) -audio-help print list of audio drivers and their options -soundhw c1,... enable audio support and only specified sound cards (comma separated list) use -soundhw ? to get the list of supported cards use -soundhw all to enable all of them -localtime set the real time clock to local time [default=utc] -full-screen start in full screen -win2k-hack use it when installing Windows 2000 to avoid a disk full bug -usb enable the USB driver (will be the default soon) -usbdevice name add the host or guest USB device name -name string set the name of the guest Network options: -net nic[,vlan=n][,macaddr=addr][,model=type] create a new Network Interface Card and connect it to VLAN n -net user[,vlan=n][,hostname=host] connect the user mode network stack to VLAN n and send hostname host to DHCP clients -net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile] connect the host TAP network interface to VLAN n and use the network scripts file (default=/etc/qemu-ifup) and dfile (default=/etc/qemu-ifdown); use [down]script=no to disable script execution; use fd=h to connect to an already opened TAP interface -net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port] connect the vlan n to another VLAN using a socket connection -net socket[,vlan=n][,fd=h][,mcast=maddr:port] connect the vlan n to multicast maddr and port -net none use it alone to have zero network devices; if no -net option is provided, the default is -net nic -net user -tftp dir allow tftp access to files in dir [-net user] -bootp file advertise file in BOOTP replies -smb dir allow SMB access to files in dir [-net user] -redir [tcp|udp]:host-port:[guest-host]:guest-port redirect TCP or UDP connections from host to guest [-net user] Linux boot specific: -kernel bzImage use bzImage as kernel image -append cmdline use cmdline as kernel command line -initrd file use file as initial ram disk Debug/Expert options: -monitor dev redirect the monitor to char device dev -serial dev redirect the serial port to char device dev -parallel dev redirect the parallel port to char device dev -pidfile file Write PID to file -S freeze CPU at startup (use c to start execution) -s wait gdb connection to port -p port set gdb connection port [default=1234] -d item1,... output log to /tmp/qemu.log (use -d ? for a list of log items) -hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS

38

CAPITOLO 3. TEST

translation (t=none or lba) (usually qemu can guess them) set the directory for the BIOS, VGA BIOS and keymaps enable KQEMU full virtualization (default is user mode only) disable KQEMU kernel module usage simulate a standard VGA card with VESA Bochs Extensions (default is CL-GD5446 PCI VGA) -no-acpi disable ACPI -no-reboot exit instead of rebooting -loadvm file start right away with a saved state (loadvm in monitor) -vnc display start a VNC server on display -daemonize daemonize QEMU after initializing -option-rom rom load a file, rom, into the option ROM space -clock force the use of the given methods for timer alarm. To see what timers are available use -clock help During emulation, the following keys are useful: ctrl-alt-f toggle full screen ctrl-alt-n switch to virtual console n ctrl-alt toggle mouse and keyboard grab When using -nographic, press ctrl-a h to get some help. $ -L path -kernel-kqemu -no-kqemu -std-vga

Listing 3.1: Output di

QEMU

lanciato senza parametri

Per poter emulare anche il chip Samsung S3C2442B stata utilizzata anche una versione di qemu custom modicata e manutenuta dagli sviluppatori del progetto openmoko[ope08]. Per migliorare le prestazioni di qemu possibile installare anche kqemu, un modulo kernel scritto per velocizzare lemulazione di x86 su x86 http://bellard.org/qemu/download.html

3.2.2

Emulazione

Qemu fornisce alcune utility allemulazione. Ad esempio qemu-img un programmino per la creazione di hard disk virtuali su cui far girare o installare il sistema emulato. Per lavvio di una emulazione possibile specicare oltre ad un hard disk virtuale anche uno sico presente sulla macchina. Nel nostro caso abbiamo lanciato qemu specicando come hard disk la memory card miniSD su cui avevano installato la distribuzione per Arm da testare.

3.2.3

Sistemi emulati

Per avviare un sistema x86 partente da cd con un hard disk e 128 mb di ram necessario lanciare $ qemu -cdrom image.iso -hda /dev/sda1 -m 128 -boot d dove qemu in realt un link a qemu-system-i386.

3.2. QEMU

39

Per emulare un sistema ARM con macchina versatileab con kernel contenuto nel le locale zImage e 128 mb di ram e avente come hard disk unimmagine virtuale locale hd0.img necessario lanciare $ qemu-system-arm -M versatileab -kernel zImage nographic -m 126 -hda hd0.img e cosi via per tutti i sistemi attualmente emulati da qemu:
$ cd /usr/bin $ ls qemu-* qemu-alpha qemu-ppc qemu-arm qemu-ppc64 qemu-armeb qemu-ppc64abi32 qemu-cris qemu-sh4 qemu-i386 qemu-sh4eb qemu-img qemu-sparc qemu-m68k qemu-sparc32plus qemu-mips qemu-sparc64 qemu-mipsel qemu-system-arm $ qemu-system-cris qemu-system-i386 qemu-system-m68k qemu-system-mips qemu-system-mips64 qemu-system-mips64el qemu-system-mipsel qemu-system-ppc qemu-system-ppc64 qemu-system-ppcemb qemu-system-sh4 qemu-system-sh4eb qemu-system-sparc qemu-system-x86_64 qemu-system-z80 qemu-x86_64

in particolare, ture

QEMU - SYSTEM - ARM

supporta le seguenti architet-

$ qemu-system-arm -M ? Supported machines are: integratorcp ARM Integrator/CP (ARM926EJ-S) (default) versatilepb ARM Versatile/PB (ARM926EJ-S) versatileab ARM Versatile/AB (ARM926EJ-S) realview ARM RealView Emulation Baseboard (ARM926EJ-S) akita Akita PDA (PXA270) spitz Spitz PDA (PXA270) borzoi Borzoi PDA (PXA270) terrier Terrier PDA (PXA270) cheetah Palm Tungsten|E aka. Cheetah PDA (OMAP310) lm3s811evb Stellaris LM3S811EVB lm3s6965evb Stellaris LM3S6965EVB connex Gumstix Connex (PXA255) verdex Gumstix Verdex (PXA270) mainstone Mainstone II (PXA27x)

e le seguenti cpu
$ qemu-system-arm -cpu ? Available CPUs: arm926 arm946 arm1026 arm1136 arm11mpcore cortex-m3

40
cortex-a8 ti925t pxa250 pxa255 pxa260 pxa261 pxa262 pxa270 pxa270-a0 pxa270-a1 pxa270-b0 pxa270-b1 pxa270-c0 pxa270-c5 any

CAPITOLO 3. TEST

3.3
To do

U-Boot

Capitolo 4 Debugger
Abbiamo avuto problemi a far partire il kernel di linux sul dispositivo palmare, quindi abbiamo cercato di trovare un modo per avere feedback sullesecuzione del codice e sugli eventuali errori riscontrati sulla piattaforma. Poich vorremmo analizzare il comportamento di un kernel, per, non possibile utilizzare STDOUT / STDERR come canali di comunicazione, n loggare il comportamento su le, in quanto non ancora disponibile uninterfaccia verso queste strutture ad alto livello. Per questo motivo abbiamo considerato lidea di usare un debugger. Per poterla applicare, per, avremmo avuto bisogno di un eseguibile per il sistema operativo Windows Mobile che si integrasse con Haret (vedi capitolo3.1). Lalternativa scelta stata quella di usare un emulatore per larchitettura, e di usare il classico GDB per il debug. Questa scelta ha semplicato lanalisi e il debug dellesecuzione delle singole istruzioni del codice.

4.1

A che serve

Usare un debugger col kernel stato utile soprattutto per scoprire qual la prima funzione invocata dal kernel stesso. Se vero che su architettura x86 vi la funzione main() in 41

42
ARCH / X 86/ BOOT / MAIN . C

CAPITOLO 4. DEBUGGER

che identica la prima funzione invocata, su architettura ARM questo non succede. Al contrario, vi sono una serie di cartelle per raggruppare limplementazione delle funzioni per piattaforma e per singolo modello, in quanto il modello di distribuzione delle speciche di ARM diverso dal modello di sviluppo intel[arm08]. Come si visto nel capitolo 2, la fase iniziale del boot su ARM implementata in assembly; vi una parte comune (la decompressione della bzImage, il caricamento in memoria dellimmagine del kernel, alcune funzioni dappoggio) a tutte le CPU e una parte specica.

4.2

Quale usare

Poich vogliamo usare gdb su un HOST x86, ma con TARGET ARM, abbiamo bisogno di usare un debugger compilato per x86, che sappia tracciare le istruzioni ed estrarre i simboli da un binario (il kernel) compilato per ARM. Per questo abbiamo scaricato i sorgenti, li abbiamo estratti e compilati, facendo attenzione a impostare TARGET = ARM - LINUX nella fase di congurazione per analizzare binari per ARM. $ $ $ $ $ wget http://ftp.gnu.org/gnu/gdb/gdb-6.8.tar.gz tar xzf gdb-6.8.tar.gz cd gdb-6.8 ./configure --target=arm-linux make && su -c "make install"

Alla ne della fase di compilazione, in / USR / LOCAL / BIN (o dovunque sia stato denito il PREFIX in fase di congurazione), saranno stati generati i le ARM - LINUX - GDB (il debugger vero e proprio), ARM LINUX - GDBTUI (frontend semi-graco) e ARM - LINUX - RUN (simulatore in grado di eseguire i programmi per ARM su x86).

4.3

Come usarlo

Usare un debugger per monitorare processi utente ragionevolmente facile. Le cose si complicano parecchio in caso si voglia de-

4.3. COME USARLO

43

Figura 4.1: Schema di funzionamento di gdb con qemu buggare il kernel stesso! Questo perch lattivit di debugging altro non che eseguire un processo (il debugger) che, tramite chiamate di sistema (ad esempio tipo la funzione PTRACE()) analizza il comportamento di un altro processo (il programma da controllare). Tuttavia nel caso si voglia controllare il kernel, non possibile avere accesso alle chiamate di sistema stesse (visto che riguardano il programma da controllare). Tuttavia una soluzione esiste. Lavorando con qemu possibile impostare lemulatore (che un programma utente, sulla macchina host) per offrire una connessione a gdb (come se si volesse fare debugging remoto su unaltra macchina). Per fare ci basta eseguire qemu aggiungendo le opzioni -S (per non far partire la cpu dallinizio) e - S (per attendere una connessione dal client gdb). $ qemu-system-arm ... -S -s In questo modo il programma rimarr in attesa. Da un altro terminale, quindi, sar possibile lanciare il debugger: $ arm-linux-gdbtui vmlinux

44

CAPITOLO 4. DEBUGGER

dove il parametro di gdb proprio il le VMLINUX creato in fase di compilazione dei sorgenti. La prima cosa da fare effettuare la connessione ad una sessione remota, usando il comando target remote :1234 che indica a gdb di collegarsi a localhost (indirizzo implicito) usando la porta 1234 (creata di default da qemu). Nellappendice B diamo un piccolo prontuario per le operazioni pi comuni di debug.

Appendice A Assembly per ARM


Tratto da [Uni06a] ldr (load register) carica un valore in un registro lr last register (ultimo registro). usato come implementazione dello stack dal momento che in questo registro vengono memorizzati i riferimenti al codice a cui si vuol ritornare dopo una chiamata ad un sottoprogramma. Ad esempio vedere righe 101 e 102 di 2.3 adr aggiunge al secondo il terzo valore e lo memorizza nel primo 1b label utilizzata per ciclare verso una label (1) precedente nel codice (before) 1f label utilizzata per ciclare verso una label (1) avanti nel codice (forward) b (branch) salta alla label indicata (esempio:
B STAR T _ KERNEL ) BLO DECOMPRESS _ KERNEL )

blo salta loopando alla label indicata (esempio:

45

46

APPENDICE A. ASSEMBLY PER ARM

Appendice B Comandi principali gdb


Tratto da [Uni06b] h [comando] stampa informazioni, generali o sul comando specicato q esci dal debugger target connette gdb ad un processo o ad una sessione remota gi in esecuzione b [nome_le:]numero_riga inserisci un breakpoint nel le e nella riga specicati b funzione inserisci un breakpoint ove la funzione invocata d numero rimuove il breakpoing numero run [parametri] esegue il programma debuggato, eventualmente con i parametri passati. Per quanto generalmente utile, non necessaria nel caso specico di qemu, in quanto lesecuzione del codice gi stata iniziata c continua lesecuzione no al termine o al raggiungimento di un breakpoint u [nome_le:]numero_riga continua lesecuzione no al raggiungimento nel le e nella riga specicati (come se ci fosse un breakpoint) 47

48

APPENDICE B. COMANDI PRINCIPALI GDB

n passa allistruzione successiva; se linvocazione di una subroutine viene trattata come una singola istruzione, ottenendo direttamente il risultato s passa allistruzione successiva; se linvocazione di una subroutine si entra nello stack della funzione si come s, ma attraverso le istruzioni denite in assembly ni come n, ma attraverso le istruzioni denite in assembly p espressione stampa a video il valore dellespressione (qualunque espressione valida in C, con inoltre, laccesso ai registri tramite loperatore $) i [sottocomando] info consente di ottenere informazioni varie sul programma, in particolare i lo informazioni sulle variabili locali i s informazioni sullo stack i r informazioni sui registri

Appendice C Licenza per la documentazione libera GNU


Questo documento distribuito secondo i termini della licenza GNU Free Documentation License. Come previsto dalla licenza, ecco in allegato il testo completo (in inglese).

C.1

GNU Free Documentation License

Version 1.2, November 2002 Copyright 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modications made by others.

49

50APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU


This License is a kind of copyleft, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS


This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The Document, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as you. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A Modied Version of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modications and/or translated into another language. A Secondary Section is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Documents overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The Invariant Sections are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not t the above denition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The Cover Texts are certain short passages of text that are listed, as FrontCover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A Transparent copy of the Document means a machine-readable copy, repre-

C.1. GNU FREE DOCUMENTATION LICENSE

51

sented in a format whose specication is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent le format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modication by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not Transparent is called Opaque. Examples of suitable formats for Transparent copies include plain ASCII without A markup, Texinfo input format, LTEX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modication. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machinegenerated HTML, PostScript or PDF produced by some word processors for output purposes only. The Title Page means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, Title Page means the text near the most prominent appearance of the works title, preceding the beginning of the body of the text. A section Entitled XYZ means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specic section name mentioned below, such as Acknowledgements, Dedications, Endorsements, or History.) To Preserve the Title of such a section when you modify the Document means that it remains a section Entitled XYZ according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in

52APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU


all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies.

3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Documents license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to t legibly, you should put the rst ones listed (as many as t reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computernetwork location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

C.1. GNU FREE DOCUMENTATION LICENSE


4. MODIFICATIONS

53

You may copy and distribute a Modied Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modied Version under precisely this License, with the Modied Version lling the role of the Document, thus licensing distribution and modication of the Modied Version to whoever possesses a copy of it. In addition, you must do these things in the Modied Version:

[A.] Use in the Title Page (and on the covers, if any) a title distinct from
that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.

[B.] List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modications in the Modied Version, together with at least ve of the principal authors of the Document (all of its principal authors, if it has fewer than ve), unless they release you from this requirement.

[C.] State on the Title page the name of the publisher of the Modied Version, as the publisher.

[D.] Preserve all the copyright notices of the Document. [E.] Add an appropriate copyright notice for your modications adjacent to
the other copyright notices.

[F.] Include, immediately after the copyright notices, a license notice giving
the public permission to use the Modied Version under the terms of this License, in the form shown in the Addendum below.

[G.] Preserve in that license notice the full lists of Invariant Sections and
required Cover Texts given in the Documents license notice.

[H.] Include an unaltered copy of this License. [I.] Preserve the section Entitled History, Preserve its Title, and add to it
an item stating at least the title, year, new authors, and publisher of the Modied Version as given on the Title Page. If there is no section Entitled History in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modied Version as stated in the previous sentence.

54APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU [J.] Preserve the network location, if any, given in the Document for public
access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the History section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.

[K.] For any section Entitled Acknowledgements or Dedications, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.

[L.] Preserve all the Invariant Sections of the Document, unaltered in their
text and in their titles. Section numbers or the equivalent are not considered part of the section titles.

[M.] Delete any section Entitled Endorsements. Such a section may not
be included in the Modied Version.

[N.] Do not retitle any existing section to be Entitled Endorsements or to


conict in title with any Invariant Section.

[O.] Preserve any Warranty Disclaimers.


If the Modied Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modied Versions license notice. These titles must be distinct from any other section titles. You may add a section Entitled Endorsements, provided it contains nothing but endorsements of your Modied Version by various partiesfor example, statements of peer review or that the text has been approved by an organization as the authoritative denition of a standard. You may add a passage of up to ve words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modied Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modied Version.

C.1. GNU FREE DOCUMENTATION LICENSE


5. COMBINING DOCUMENTS

55

You may combine the Document with other documents released under this License, under the terms dened in section 4 above for modied versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodied, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled History in the various original documents, forming one section Entitled History; likewise combine any sections Entitled Acknowledgements, and any sections Entitled Dedications. You must delete all sections Entitled Endorsements.

6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS


A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an aggregate if the copyright resulting from the compilation is not used to limit the legal rights of the compilations users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Documents Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in

56APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU


electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

8. TRANSLATION
Translation is considered a kind of modication, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled Acknowledgements, Dedications, or History, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE


The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. Each version of the License is given a distinguishing version number. If the Document species that a particular numbered version of this License or any later version applies to it, you have the option of following the terms and conditions either of that specied version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents


To use this License in a document you have written, include a copy of the License

C.1. GNU FREE DOCUMENTATION LICENSE

57

in the document and put the following copyright and license notices just after the title page:

Copyright YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled GNU Free Documentation License.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the with . . . Texts. line with this:

with the Invariant Sections being LIST THEIR TITLES, with the FrontCover Texts being LIST, and with the Back-Cover Texts being LIST.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

58APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

Elenco dei simboli


big zImage vedi bzImage bootstrap Letteralmente la fascetta di cuoio cucita sul bordo posteriore degli stivali per aiutarsi a calzarli, fa riferimento alla leggenda del Barone di Mnchhausen e alla sua capacit di sollevarsi in aria tirandosi per gli stivali. Indica la fase di avvio di un pc bzImage Immagine del kernel compressa ed eseguibile, ma composta da tre parti separate host In ambiente di emulazione, la macchina reale che ospita lemulatore. In ambiente di cross-compilazione, la macchina che ospita il compilatore. Vedi: target Image Immagine del kernel effettivamente eseguita miniSD Mini Secure Digital, versione pi piccola (20x21.5) delle schede di memoria SD (24x32) MMU Memory Management Unit svn SubVersioN: sistema per controllo di revisione, usato nello sviluppo di sistemi software, consente di avere e condividere la storia delle modiche effettuate sui le del progetto

target In ambiente di emulazione, la macchina virtuale generata dallemulatore. 59

60APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU In ambiente di cross-compilazione, la macchina su cui verranno utilizzati i programmi compilati. Vedi: host toolchain Insieme di tutti gli strumenti (tra gli altri preprocessore, assembler, compilatore, linker...) necessari alla generazione di codice eseguibile a partire da sorgenti. vmlinux Eseguibile non compresso e non bootable del kernel. wiki categoria particolare di siti web, accomunati dalla possibilit di offrire agli utenti stesssi del sito la possibilit di modicarlo a loro piacimento, senza dover accedere direttamente ai le presenti in remoto. Windows Mobile Microsoft Windows Mobile, sistema operativo concepito per palmari, telefoni cellulari e Pocket PC zImage Immagine del kernel compressa preceduta da un decompressore (obsoleta)

Bibliograa
[arm08] Uso di architettura arm o intel per il mobile. http://en. wikipedia.org/wiki/Controversies_regarding_ the_use_of_ARM_or_Intel_architectures_in_ mobile_computers, giugno 2008. [ceg08] cegcc. http://cegcc.sourceforge.net, agosto 2008. [Hic08] Jamey Hicks. Handhelds toolchain. http://www. handhelds.org/download/projects/toolchain/, giugno 2008. [Lin05] Bellevue Linux. vmlinuz denition. http://www.linfo. org/vmlinuz.html, marzo 2005. [ope08] Openmoko under qemu. http://wiki.openmoko.org/ wiki/Openmoko_under_QEMU, giugno 2008. [Pro08] The ARM Linux Project. mach-type. http://www.arm. linux.org.uk/developer/machines/download.php, agosto 2008. [Uni06a] University of New South Wales. Assembler intro, febbraio 2006. [Uni06b] University of New South Wales. Gdb intro, febbraio 2006. [vml08] Differenze tra vmlinu[x|z] e [[b]z]image. http://en. wikipedia.org/wiki/Vmlinux, giugno 2008. [ZOS08] Andrew Zabolotny, Kevin OConnor, and Paul Sokolovsky. Haret. http://handhelds.org/moin/moin.cgi/HaRET, giugno 2008. 61