Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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 . . . . . . . . . . . . .
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.
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
1.3
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:
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
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"
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_SSB_POSSIBLE=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_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
12
CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y
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
TARGET
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)
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
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
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
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
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:
/* * 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
LC0:
@ @ @ @ @ @ @ @
r1 r2 r3 r4 r5 r6 ip sp
20
294 295 LC1: .word .size reloc_end - reloc_start LC0, . - LC0
CAPITOLO 2. AVVIO
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; }
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)
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
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 explicitly mcr p15, 7, r0, c15, c0, 0 #endif
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
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
1:
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
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 */
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
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
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
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(); }
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
33
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");
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.
$ 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
QEMU
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 -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-
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.
45
46
48
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
C.1
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
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
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.
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.
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.
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.
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.
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