61
GNU/Linux su ARM Vito De Tullio [email protected] Nicola Corriero [email protected] 12 settembre 2008

Boot Linux Arm

  • Upload
    zed

  • View
    98

  • Download
    4

Embed Size (px)

Citation preview

Page 1: Boot Linux Arm

GNU/Linux su ARM

Vito De Tullio [email protected] Corriero [email protected]

12 settembre 2008

Page 2: Boot Linux Arm

2

Copyright © 2008 Nicola Corriero, Vito De Tullio.

È permesso copiare, distribuire e/o modificare questo documento

seguendo i termini della “Licenza per documentazione libera GNU”,

versione 1.2 o ogni versione successiva pubblicata dalla Free Soft-

ware Foundation; senza sezioni non modificabili, senza testi di pri-

ma di copertina e di quarta di copertina. Una copia della licenza

è inclusa nella sezione intitolata “Licenza per la documentazione

libera GNU”.

Page 3: Boot Linux Arm

Indice

1 Kernel & compilatore 71.1 Kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2 Compilatore . . . . . . . . . . . . . . . . . . . . . . . . . 71.3 Configurazione dei sorgenti . . . . . . . . . . . . . . . . 81.4 Cross-compilazione . . . . . . . . . . . . . . . . . . . . 121.5 Output (Image, zImage, bzImage) . . . . . . . . . . . . 13

2 Avvio 152.1 Sorgenti . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.2 Decompressione . . . . . . . . . . . . . . . . . . . . . . 162.3 Boot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.4 Hello, world! . . . . . . . . . . . . . . . . . . . . . . . . 27

3 Test 293.1 Haret . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

3.1.1 Perché . . . . . . . . . . . . . . . . . . . . . . . . 293.1.2 Come usare Haret . . . . . . . . . . . . . . . . . 303.1.3 Codice . . . . . . . . . . . . . . . . . . . . . . . . 313.1.4 Problemi . . . . . . . . . . . . . . . . . . . . . . . 353.1.5 Compilazione di Haret . . . . . . . . . . . . . . . 35

3.2 Qemu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363.2.1 Come ottenerlo . . . . . . . . . . . . . . . . . . . 363.2.2 Emulazione . . . . . . . . . . . . . . . . . . . . . 383.2.3 Sistemi emulati . . . . . . . . . . . . . . . . . . . 38

3.3 U-Boot . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4 Debugger 414.1 A che serve . . . . . . . . . . . . . . . . . . . . . . . . . 41

3

Page 4: Boot Linux Arm

4 INDICE

4.2 Quale usare . . . . . . . . . . . . . . . . . . . . . . . . . 424.3 Come usarlo . . . . . . . . . . . . . . . . . . . . . . . . 42

A Assembly per ARM 45

B Comandi principali gdb 47

C Licenza per la documentazione libera GNU 49C.1 GNU Free Documentation License . . . . . . . . . . . . 49

Bibliografia 61

Page 5: Boot Linux Arm

Introduzione

Questo lavoro ha la presunzione di voler ordinare le idee riguardol’avvio di un sistema GNU/Linux su Arm dal momento che allostato attuale delle cose non esiste una guida a proposito.

Si inizia parlando della fase di compilazione e del kernel. I prob-lemi nascono dal momento che abitualmente si lavora su piattafor-ma x86, mentre nel nostro caso si ha l’esigenza di compilare su unapiattaforma differente. In gergo si parla di cross-compilazione. In-fatti, prenderemo un compilatore tipico della piattaforma ARM e louseremo su piattaforma x86 per generare eseguibili su ARM.

Il lavoro continua presentando le componenti del kernel neces-sarie su ARM e parlando dei possibili output del kernel stesso.

Segue una dettagliata descrizione della fase di avvio del kernelcommentando direttamente il codice assembly e C eseguito sia infase di decompressione del kernel sia in fase di avvio.

Nel capitolo 3 si analizzano gli strumenti utilizzati per il testingdel kernel su ARM.Qemu è un programma di emulazione molto semplice da usare efacilmente configurabile per i nostri scopi.Haret è un programma scritto in C++ per Windows Mobile®; hal’obbiettivo di copiare in memoria il kernel, ed eventualmente INI-TRD, spegnere l’hardware e avviare il kernel in memoria in manieranon invasiva per la macchina, dal momento che non fa modificheal sistema operativo ospite.U-boot è un bootloader universale per i sistemi embedded; rapp-resenta però una soluzione invasiva dal momento che è necessarioinstallarlo sulla memoria flash del dispositivo.

Il capitolo 4 descrive come effettuare debugging sui disposi-tivi embedded. Verrà analizzato GDB (Gnu DeBugger), analizzando

5

Page 6: Boot Linux Arm

6 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 nelcapitolo 2.

Page 7: Boot Linux Arm

Capitolo 1

Kernel & compilatore

1.1 Kernel

È stato usata la versione 2.6.25.10 del kernel vanilla (versione didefault, non patchata) reperibile presso ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.10.tar.bz2. Esistonoversioni modificate da singoli per supportare questa o quell’ar-chitettura (in particolare è da notare la versione del kernel man-tenuta da http://www.handhelds.org), ma non abbiamo trovatonessuna versione che già supportasse nativamente il nostro pal-mare (un HTC P6300) e quindi abbiamo preferito utilizzare la ver-sione di default.

1.2 Compilatore

Per compilare il kernel linux è necessario usare il gcc, a causa dellevarie 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 delkernel e del compilatore particolarmente differenti tra di loro, acausa dell’uso (e spesso dell’abuso) che viene fatto delle varie es-tensioni non standard.

Nel nostro caso sono state usate varie versioni, principalmente4.2.3 e 3.4.1, senza riscontrare particolari problemi.

7

Page 8: Boot Linux Arm

8 CAPITOLO 1. KERNEL & COMPILATORE

1.3 Configurazione dei sorgenti

Dopo aver scaricato ed estratto il kernel, lo dobbiamo configurareper l’architettura ARM utilizzando un x86, e per questo, prima delsolito make [x|menu]config, è necessario associare alla variabileARCH 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 pal-mare su cui vogliamo eseguire il kernel, più altre minuzie per farfunzionare i vari dispositivi; in particolare

• dal menù SYSTEM TYPE . ARM SYSTEM TYPE scegliamo iltipo di sistema base (nel nostro caso SAMSUNG S3C2410,S3C2412, S3C2413, S3C2440, S3C2442, S3C2443);

• dal menù BOOT OPTIONS impostiamo CONSOLE=TTYAMA0 al-la voce DEFAULT KERNEL COMMAND STRING (per poter avere inoutput i messaggi di comunicazione);

• dal menù GENERAL SETUP impostiamo 12 come valore del-la voce KERNEL LOG BUFFER SIZE; (con un buffer così picco-lo i messaggi di warning/errore vengono inviati su STDOUT ilprima possibile);

• dal menù DEVICE DRIVERS selezioniamo MMC/SD CARD SUP-PORT (per poter accedere al supporto fisico per il file system).

Dopo anche altre personalizzazioni minori, si giunge al .CONFIG fi-nale, che, nel nostro caso, è abbastanza minimale: la maggior partedei moduli, infatti, è stata disabilitata, tranne quelli necessari ariconoscere cpu, tastiera e monitor:

Page 9: Boot Linux Arm

1.3. CONFIGURAZIONE DEI SORGENTI 9

Listing 1.1: .config finale utilizzato (le voci commentate sono staterimosse)

CONFIG_ARM=yCONFIG_SYS_SUPPORTS_APM_EMULATION=yCONFIG_GENERIC_TIME=yCONFIG_GENERIC_CLOCKEVENTS=yCONFIG_MMU=yCONFIG_GENERIC_HARDIRQS=yCONFIG_STACKTRACE_SUPPORT=yCONFIG_LOCKDEP_SUPPORT=yCONFIG_TRACE_IRQFLAGS_SUPPORT=yCONFIG_HARDIRQS_SW_RESEND=yCONFIG_GENERIC_IRQ_PROBE=yCONFIG_RWSEM_GENERIC_SPINLOCK=yCONFIG_GENERIC_HWEIGHT=yCONFIG_GENERIC_CALIBRATE_DELAY=yCONFIG_ARCH_SUPPORTS_AOUT=yCONFIG_ZONE_DMA=yCONFIG_VECTORS_BASE=0xffff0000CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

CONFIG_EXPERIMENTAL=yCONFIG_BROKEN_ON_SMP=yCONFIG_INIT_ENV_ARG_LIMIT=32CONFIG_LOCALVERSION="-default"CONFIG_LOCALVERSION_AUTO=yCONFIG_SYSVIPC=yCONFIG_SYSVIPC_SYSCTL=yCONFIG_LOG_BUF_SHIFT=12CONFIG_NAMESPACES=yCONFIG_SYSCTL=yCONFIG_UID16=yCONFIG_SYSCTL_SYSCALL=yCONFIG_KALLSYMS=yCONFIG_HOTPLUG=yCONFIG_PRINTK=yCONFIG_BUG=yCONFIG_ELF_CORE=yCONFIG_BASE_FULL=yCONFIG_FUTEX=yCONFIG_ANON_INODES=yCONFIG_EPOLL=yCONFIG_SIGNALFD=yCONFIG_TIMERFD=yCONFIG_EVENTFD=yCONFIG_SHMEM=yCONFIG_VM_EVENT_COUNTERS=yCONFIG_SLAB=yCONFIG_HAVE_OPROFILE=yCONFIG_HAVE_KPROBES=yCONFIG_HAVE_KRETPROBES=yCONFIG_PROC_PAGE_MONITOR=yCONFIG_SLABINFO=yCONFIG_RT_MUTEXES=yCONFIG_BASE_SMALL=0CONFIG_BLOCK=y

CONFIG_IOSCHED_NOOP=yCONFIG_IOSCHED_DEADLINE=yCONFIG_DEFAULT_DEADLINE=yCONFIG_DEFAULT_IOSCHED="deadline"CONFIG_CLASSIC_RCU=y

CONFIG_ARCH_VERSATILE=y

CONFIG_MACH_VERSATILE_AB=y

CONFIG_CPU_32=yCONFIG_CPU_ARM926T=yCONFIG_CPU_32v5=yCONFIG_CPU_ABRT_EV5TJ=yCONFIG_CPU_CACHE_VIVT=yCONFIG_CPU_COPY_V4WB=y

Page 10: Boot Linux Arm

10 CAPITOLO 1. KERNEL & COMPILATORE

CONFIG_CPU_TLB_V4WBI=yCONFIG_CPU_CP15=yCONFIG_CPU_CP15_MMU=y

CONFIG_ARM_VIC=yCONFIG_ICST307=y

CONFIG_ARM_AMBA=y

CONFIG_GENERIC_CLOCKEVENTS_BUILD=yCONFIG_HZ=100CONFIG_SELECT_MEMORY_MODEL=yCONFIG_FLATMEM_MANUAL=yCONFIG_FLATMEM=yCONFIG_FLAT_NODE_MEM_MAP=yCONFIG_SPLIT_PTLOCK_CPUS=4096CONFIG_ZONE_DMA_FLAG=1CONFIG_BOUNCE=yCONFIG_VIRT_TO_BUS=yCONFIG_ALIGNMENT_TRAP=y

CONFIG_ZBOOT_ROM_TEXT=0CONFIG_ZBOOT_ROM_BSS=0CONFIG_CMDLINE="console=ttyAMA0"

CONFIG_FPE_NWFPE=y

CONFIG_BINFMT_ELF=y

CONFIG_PM=yCONFIG_ARCH_SUSPEND_POSSIBLE=y

CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"CONFIG_PREVENT_FIRMWARE_BUILD=y

CONFIG_INPUT=y

CONFIG_INPUT_MOUSEDEV=yCONFIG_INPUT_MOUSEDEV_SCREEN_X=1024CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768

CONFIG_INPUT_KEYBOARD=yCONFIG_KEYBOARD_ATKBD=yCONFIG_INPUT_MOUSE=yCONFIG_MOUSE_PS2=yCONFIG_MOUSE_PS2_ALPS=yCONFIG_MOUSE_PS2_LOGIPS2PP=yCONFIG_MOUSE_PS2_SYNAPTICS=yCONFIG_MOUSE_PS2_LIFEBOOK=yCONFIG_MOUSE_PS2_TRACKPOINT=yCONFIG_INPUT_TOUCHSCREEN=y

CONFIG_SERIO=yCONFIG_SERIO_SERPORT=yCONFIG_SERIO_AMBAKMI=yCONFIG_SERIO_LIBPS2=y

CONFIG_VT=yCONFIG_VT_CONSOLE=yCONFIG_HW_CONSOLE=y

CONFIG_SERIAL_AMBA_PL011=yCONFIG_SERIAL_AMBA_PL011_CONSOLE=yCONFIG_SERIAL_CORE=yCONFIG_SERIAL_CORE_CONSOLE=yCONFIG_UNIX98_PTYS=y

CONFIG_SSB_POSSIBLE=y

Page 11: Boot Linux Arm

1.3. CONFIGURAZIONE DEI SORGENTI 11

CONFIG_VIDEO_OUTPUT_CONTROL=yCONFIG_FB=yCONFIG_FIRMWARE_EDID=yCONFIG_FB_CFB_FILLRECT=yCONFIG_FB_CFB_COPYAREA=yCONFIG_FB_CFB_IMAGEBLIT=yCONFIG_FB_DEFERRED_IO=yCONFIG_FB_MODE_HELPERS=y

CONFIG_FB_ARMCLCD=yCONFIG_FB_S1D13XXX=yCONFIG_BACKLIGHT_LCD_SUPPORT=yCONFIG_LCD_CLASS_DEVICE=yCONFIG_BACKLIGHT_CLASS_DEVICE=y

CONFIG_DISPLAY_SUPPORT=y

CONFIG_DUMMY_CONSOLE=yCONFIG_FRAMEBUFFER_CONSOLE=yCONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=yCONFIG_FRAMEBUFFER_CONSOLE_ROTATION=yCONFIG_FONT_8x8=yCONFIG_FONT_8x16=yCONFIG_LOGO=yCONFIG_LOGO_LINUX_MONO=yCONFIG_LOGO_LINUX_VGA16=yCONFIG_LOGO_LINUX_CLUT224=y

CONFIG_MMC=yCONFIG_MMC_DEBUG=y

CONFIG_MMC_BLOCK=yCONFIG_MMC_BLOCK_BOUNCE=yCONFIG_SDIO_UART=y

CONFIG_MMC_ARMMMCI=yCONFIG_RTC_LIB=y

CONFIG_EXT2_FS=y

CONFIG_FAT_FS=yCONFIG_VFAT_FS=yCONFIG_FAT_DEFAULT_CODEPAGE=437CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"

CONFIG_PROC_FS=yCONFIG_PROC_SYSCTL=yCONFIG_SYSFS=y

CONFIG_MSDOS_PARTITION=yCONFIG_NLS=yCONFIG_NLS_DEFAULT="iso8859-1"CONFIG_NLS_CODEPAGE_437=yCONFIG_NLS_CODEPAGE_850=yCONFIG_NLS_ASCII=yCONFIG_NLS_ISO8859_1=yCONFIG_NLS_ISO8859_15=yCONFIG_NLS_UTF8=y

CONFIG_ENABLE_WARN_DEPRECATED=yCONFIG_ENABLE_MUST_CHECK=yCONFIG_DEBUG_KERNEL=yCONFIG_DEBUG_BUGVERBOSE=yCONFIG_DEBUG_INFO=yCONFIG_FRAME_POINTER=yCONFIG_DEBUG_USER=yCONFIG_DEBUG_ERRORS=yCONFIG_DEBUG_LL=y

CONFIG_BITREVERSE=yCONFIG_CRC32=yCONFIG_PLIST=yCONFIG_HAS_IOMEM=y

Page 12: Boot Linux Arm

12 CAPITOLO 1. KERNEL & COMPILATORE

CONFIG_HAS_IOPORT=yCONFIG_HAS_DMA=y

Listing 1.1: .config finale utilizzato (le voci commentate sono staterimosse)

Alla fine della fase di configurazione, si dovrà iniziare a com-pilare i sorgenti. Poiché vogliamo generare un kernel (quindi uneseguibile) 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 architetturaARM (e parecchio tempo, data la potenza di questi dispositivi).

2. Avere un sistema operativo + compilatore C su architetturax86 + istruire il compilatore C a generare eseguibili per ar-chitettura ARM.

Si è scelto di approcciarsi al problema tramite la soluzione 2. D’orainnanzi, quindi, si dirà

HOST la macchina x86 su cui sono presenti compilatore e sorgenti

TARGET la macchina ARM su cui si utilizzerà effettivamente il ker-nel 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 unaOpenSuse 10.3);

• la capacità di calcolo di una macchina TARGET è generalmentelimitata, mentre le macchine HOST sono molto più potenti(minimizzando i tempi morti in attesa del termine della com-pilazione)

Page 13: Boot Linux Arm

1.5. OUTPUT (IMAGE, ZIMAGE, BZIMAGE) 13

Ovviamente vi è la difficoltà di avere un compilatore C in grado digenerare eseguibili per la macchina TARGET. Per fortuna questoè offerto da gcc. Per abilitare questa feature, però, è necessarioimpostare 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.orghttp://www.handhelds.org/download/projects/toolchain/[Hic08].

Tuttavia è necessario istruire il kernel del fatto che vogliamocompilare i sorgenti (già configurati) con un compilatore diverso(ed un diverso linker, assembler, ecc).

Per questo viene in aiuto la variabile d’ambiente CROSS_COMPILER,che istruisce il make su dove andare a cercare la toolchain adatta.

Terminata la parte di configurazione del kernel, come già fattonella 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/arm-

linux-$ make

È da notare come CROSS_COMPILE indichi il prefisso comunea 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 unaserie di file temporanei / di supporto, i seguenti file.

vmlinux eseguibile non compresso e non bootable del kernel. Us-ato soprattutto per debug, come vedremo nel capitolo 4 nellapagina 41.

arch/arm/boot/Image immagine del kernel effettivamente esegui-ta

Page 14: Boot Linux Arm

14 CAPITOLO 1. KERNEL & COMPILATORE

Figura 1.1: Anatomia di bzImage (da en.wikipedia.org)

arch/arm/boot/zImage immagine del kernel, compressa tramitegzip e preceduta da un decompressore (obsoleta)

arch/arm/boot/bzImage (big zImagebig zImage) concatenatzionedi bootsect.o + setup.o + misc.o + piggy.o.[Lin05, vml08]

Page 15: Boot Linux Arm

Capitolo 2

Avvio

Una volta che il bootloader ha caricato il kernel in memoria e l’haeseguito, vi è la fase di bootstrap che, nell’architettura ARM, èimplementata per la maggior parte in assembly.

2.1 Sorgenti

Il codice che si prende carico del boot del sistema è presente princi-palmente nelle directory ARCH/ARM/BOOT/COMPRESSED e ARCH/AR-M/KERNEL ove sono presenti, oltre a del codice d’appoggio per com-primere e decomprimere l’eseguibile, anche una serie di file .S(scritti in assembly per ARM) tra i quali sono degni di nota i 2file HEAD.S.

ARCH/ARM/KERNEL/HEAD.S, in particolare, contiene la parte dicodice che, di fatto, è il punto di partenza del kernel. In effettiquesto codice, compilato, corrisponde alle prime istruzioni presentiin nel file IMAGE già descritto;

Ovviamente nel caso si decida di usare i file ZIMAGE e BZIMAGE,questo codice sarà quello invocato al termine della decompressionedel kernel stesso.

Ciò si evince anche dai commenti presenti nel file, come si puòvedere:

59 /*60 * Kernel startup entry point.61 * ---------------------------62 *

15

Page 16: Boot Linux Arm

16 CAPITOLO 2. AVVIO

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

In particolare, viene fatto riferimento al file ARCH/ARM/TOOLS/MACH-TYPES: questi altro non è che un “database” in cui si associa adogni modello supportato dal kernel che implementa le specifichedell’ARM, una serie di codici univoci usati per poter generare delleguardie per implementare codice dipendente da macchina a macchi-na. Questo file è mantenuto dal “The ARM Linux Project”[Pro08],che assicura l’univocità degli identificatori usati per i vari palmari.

In aggiunta a questo file vi è uno script awk (ARCH/ARM/TOOLS/GEN-MACH-TYPES) capace di trasformare questo file di configurazionenel file INCLUDE/ASM-ARM/MACH-TYPES.H, pieno di macro usate infase di compilazione per abilitare o meno il codice specifico dellamacchina target.

2.2 Decompressione

Le prime istruzioni eseguite all’avvio di una zImage sono quellerelative alla decompressione del kernel.

Il codice relativo alla decompressione è scritto in Assembly e sitrova all’interno del file ARCH/ARM/BOOT/COMPRESSED/HEAD.S

109 .section ".start", #alloc, #execinstr110 /*111 * sort out different calling conventions112 */113 .align114 start:115 .type start,#function116 .rept 8117 mov r0, r0118 .endr119120 b 1f121 .word 0x016f2818 @ Magic numbers to help the

loader122 .word start @ absolute load/run zImage

address

Page 17: Boot Linux Arm

2.2. DECOMPRESSIONE 17

123 .word _edata @ zImage end address124 1: mov r7, r1 @ save architecture ID125 mov r8, #0 @ save r0126127 #ifndef __ARM_ARCH_2__128 /*129 * Booting from Angel - need to enter SVC mode and disable130 * FIQs/IRQs (numeric definitions from angel arm.h source).131 * We only do this if we were in user mode on entry.132 */133 mrs r2, cpsr @ get current mode134 tst r2, #3 @ not user?135 bne not_angel136 mov r0, #0x17 @ angel_SWIreason_EnterSVC137 swi 0x123456 @ angel_SWI_ARM138 not_angel:139 mrs r2, cpsr @ turn off interrupts to140 orr r2, r2, #0xc0 @ prevent angel from running141 msr cpsr_c, r2142 #else143 teqp pc, #0x0c000003 @ turn off interrupts144 #endif145146 /*147 * Note that some cache flushing and other stuff may148 * be needed here - is there an Angel SWI call for this?149 */150151 /*152 * some architecture specific code can be inserted153 * by the linker here, but it should preserve r7 and r8.154 */155156 .text157 adr r0, LC0158 ldmia r0, {r1, r2, r3, r4, r5, r6, ip, sp}159 subs r0, r0, r1 @ calculate the delta offset160161 @ if delta is zero, we’re162 beq not_relocated @ running at the address we163 @ were linked at.164165 /*166 * We’re running at a different address. We need to fix167 * up various pointers:168 * r5 - zImage base address169 * r6 - GOT start170 * ip - GOT end171 */172 add r5, r5, r0173 add r6, r6, r0174 add ip, ip, r0175176 #ifndef CONFIG_ZBOOT_ROM177 /*178 * If we’re running fully PIC === CONFIG_ZBOOT_ROM = n,179 * we need to fix up pointers into the BSS region.

Page 18: Boot Linux Arm

18 CAPITOLO 2. AVVIO

180 * r2 - BSS start181 * r3 - BSS end182 * sp - stack pointer183 */184 add r2, r2, r0185 add r3, r3, r0186 add sp, sp, r0187188 /*189 * Relocate all entries in the GOT table.190 */191 1: ldr r1, [r6, #0] @ relocate entries in the GOT192 add r1, r1, r0 @ table. This fixes up the193 str r1, [r6], #4 @ C references.194 cmp r6, ip195 blo 1b196 #else197198 /*199 * Relocate entries in the GOT table. We only relocate200 * the entries that are outside the (relocated) BSS region.201 */202 1: ldr r1, [r6, #0] @ relocate entries in the GOT203 cmp r1, r2 @ entry < bss_start ||204 cmphs r3, r1 @ _end < entry205 addlo r1, r1, r0 @ table. This fixes up the206 str r1, [r6], #4 @ C references.207 cmp r6, ip208 blo 1b209 #endif210211 not_relocated: mov r0, #0212 1: str r0, [r2], #4 @ clear bss213 str r0, [r2], #4214 str r0, [r2], #4215 str r0, [r2], #4216 cmp r2, r3217 blo 1b218219 /*220 * The C runtime environment should now be setup221 * sufficiently. Turn the cache on, set up some222 * pointers, and start decompressing.223 */224 bl cache_on225226 mov r1, sp @ malloc space above stack227 add r2, sp, #0x10000 @ 64k max228229 /*230 * Check to see if we will overwrite ourselves.231 * r4 = final kernel address232 * r5 = start of this image233 * r2 = end of malloc space (and therefore this image)234 * We basically want:235 * r4 >= r2 -> OK236 * r4 + image length <= r5 -> OK

Page 19: Boot Linux Arm

2.2. DECOMPRESSIONE 19

237 */238 cmp r4, r2239 bhs wont_overwrite240 add r0, r4, #4096*1024 @ 4MB largest kernel size241 cmp r0, r5242 bls wont_overwrite243244 mov r5, r2 @ decompress after malloc space245 mov r0, r5246 mov r3, r7247 bl decompress_kernel248249 add r0, r0, #127250 bic r0, r0, #127 @ align the kernel length251 /*252 * r0 = decompressed kernel length253 * r1-r3 = unused254 * r4 = kernel execution address255 * r5 = decompressed kernel start256 * r6 = processor ID257 * r7 = architecture ID258 * r8-r14 = unused259 */260 add r1, r5, r0 @ end of decompressed kernel261 adr r2, reloc_start262 ldr r3, LC1263 add r3, r2, r3264 1: ldmia r2!, {r8 - r13} @ copy relocation code265 stmia r1!, {r8 - r13}266 ldmia r2!, {r8 - r13}267 stmia r1!, {r8 - r13}268 cmp r2, r3269 blo 1b270271 bl cache_clean_flush272 add pc, r5, r0 @ call relocation code273274 /*275 * We’re not in danger of overwriting ourselves. Do this the simple way.276 *277 * r4 = kernel execution address278 * r7 = architecture ID279 */280 wont_overwrite: mov r0, r4281 mov r3, r7282 bl decompress_kernel283 b call_kernel284285 .type LC0, #object286 LC0: .word LC0 @ r1287 .word __bss_start @ r2288 .word _end @ r3289 .word _load_addr @ r4290 .word _start @ r5291 .word _got_start @ r6292 .word _got_end @ ip293 .word user_stack+4096 @ sp

Page 20: Boot Linux Arm

20 CAPITOLO 2. AVVIO

294 LC1: .word reloc_end - reloc_start295 .size LC0, . - LC0

Dove la funzione START_KERNEL è presente nel file ARCH/ARM/-BOOT/COMPRESSED/MISC.C.

345 ulg346 decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,347 int arch_id)348 {349 output_data = (uch *)output_start; /* Points to kernel start

*/350 free_mem_ptr = free_mem_ptr_p;351 free_mem_ptr_end = free_mem_ptr_end_p;352 __machine_arch_type = arch_id;353354 arch_decomp_setup();355356 makecrc();357 puts("Uncompressing Linux...");358 gunzip();359 puts(" done, booting the kernel.\n");360 return output_ptr;361 }

La funzione gunzip() è presente nel file LIB/INFLATE.C1149 /*1150 * Do the uncompression!1151 */1152 static int INIT gunzip(void)1153 {1154 uch flags;1155 unsigned char magic[2]; /* magic header */1156 char method;1157 ulg orig_crc = 0; /* original crc */1158 ulg orig_len = 0; /* original uncompressed length */1159 int res;11601161 magic[0] = NEXTBYTE();1162 magic[1] = NEXTBYTE();1163 method = NEXTBYTE();11641165 if (magic[0] != 037 ||1166 ((magic[1] != 0213) && (magic[1] != 0236))) {1167 error("bad gzip magic numbers");1168 return -1;1169 }11701171 /* We only support method #8, DEFLATED */1172 if (method != 8) {1173 error("internal error, invalid method");1174 return -1;1175 }11761177 flags = (uch)get_byte();

Page 21: Boot Linux Arm

2.2. DECOMPRESSIONE 21

1178 if ((flags & ENCRYPTED) != 0) {1179 error("Input is encrypted");1180 return -1;1181 }1182 if ((flags & CONTINUATION) != 0) {1183 error("Multi part input");1184 return -1;1185 }1186 if ((flags & RESERVED) != 0) {1187 error("Input has invalid flags");1188 return -1;1189 }1190 NEXTBYTE(); /* Get timestamp */1191 NEXTBYTE();1192 NEXTBYTE();1193 NEXTBYTE();11941195 (void)NEXTBYTE(); /* Ignore extra flags for the moment */1196 (void)NEXTBYTE(); /* Ignore OS type for the moment */11971198 if ((flags & EXTRA_FIELD) != 0) {1199 unsigned len = (unsigned)NEXTBYTE();1200 len |= ((unsigned)NEXTBYTE())<<8;1201 while (len--) (void)NEXTBYTE();1202 }12031204 /* Get original file name if it was truncated */1205 if ((flags & ORIG_NAME) != 0) {1206 /* Discard the old name */1207 while (NEXTBYTE() != 0) /* null */ ;1208 }12091210 /* Discard file comment if any */1211 if ((flags & COMMENT) != 0) {1212 while (NEXTBYTE() != 0) /* null */ ;1213 }12141215 /* Decompress */1216 if ((res = inflate())) {1217 switch (res) {1218 case 0:1219 break;1220 case 1:1221 error("invalid compressed format (err=1)");1222 break;1223 case 2:1224 error("invalid compressed format (err=2)");1225 break;1226 case 3:1227 error("out of memory");1228 break;1229 case 4:1230 error("out of input data");1231 break;1232 default:1233 error("invalid compressed format (other)");1234 }

Page 22: Boot Linux Arm

22 CAPITOLO 2. AVVIO

1235 return -1;1236 }12371238 /* Get the crc and original length */1239 /* crc32 (see algorithm.doc)1240 * uncompressed input size modulo 2^321241 */1242 orig_crc = (ulg) NEXTBYTE();1243 orig_crc |= (ulg) NEXTBYTE() << 8;1244 orig_crc |= (ulg) NEXTBYTE() << 16;1245 orig_crc |= (ulg) NEXTBYTE() << 24;12461247 orig_len = (ulg) NEXTBYTE();1248 orig_len |= (ulg) NEXTBYTE() << 8;1249 orig_len |= (ulg) NEXTBYTE() << 16;1250 orig_len |= (ulg) NEXTBYTE() << 24;12511252 /* Validate decompression */1253 if (orig_crc != CRC_VALUE) {1254 error("crc error");1255 return -1;1256 }1257 if (orig_len != bytes_out) {1258 error("length error");1259 return -1;1260 }1261 return 0;12621263 underrun: /* NEXTBYTE() goto’s here if needed */1264 error("out of input data");1265 return -1;1266 }

2.3 Boot

Tornando alla sequenza di boot, analizziamo un attimo le primeistruzioni presenti in ARCH/ARM/KERNEL/HEAD.S:

77 .section ".text.head", "ax"78 .type stext, %function79 ENTRY(stext)80 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode81 @ and irqs disabled82 mrc p15, 0, r9, c0, c0 @ get processor id83 bl __lookup_processor_type @ r5=procinfo r9=cpuid84 movs r10, r5 @ invalid processor (r5=0)?85 beq __error_p @ yes, error ’p’86 bl __lookup_machine_type @ r5=machinfo87 movs r8, r5 @ invalid machine (r5=0)?88 beq __error_a @ yes, error ’a’89 bl __vet_atags90 bl __create_page_tables91

Page 23: Boot Linux Arm

2.3. BOOT 23

92 /*93 * The following calls CPU specific code in a position independent94 * manner. See arch/arm/mm/proc-*.S for details. r10 = base of95 * xxx_proc_info structure selected by __lookup_machine_type96 * above. On return, the CPU will be ready for the MMU to be97 * turned on, and r0 will hold the CPU control register value.98 */99 ldr r13, __switch_data @ address to jump to after

100 @ mmu has been enabled101 adr lr, __enable_mmu @ return (PIC) address102 add pc, r10, #PROCINFO_INITFUNC

All’inizio degni di nota sono soprattutto i controlli effettuati dalkernel sulla possibilità di supportare processore e macchina.

In caso d’errore vengono invocate delle funzioni per avvisarel’utente e terminare l’esecuzione del programma. Altrimenti ven-gono “salvati” nel registro 10 il processore e nel registro 8 il tipo dimacchina riconosciuti.

Una volta superati i controlli l’esecuzione continua con il codicespecifico della cpu. Ma vengono salvate alcune funzioni da eseguirein seguito.

Nelle ultime tre righe, infatti, si istruisce il programma a sal-vare in r13 il codice di __SWITCH_DATA e a salvare il LR1 il codiceper abilitare l’MMU. Questi dovrà essere eseguito dopo il codicespecifico della macchina: l’ultima riga, infatti, altro non fa chescrivere su PC la somma di r10 (indirizzo di memoria che con-tiene le informazioni sulla cpu riconosciuta) col valore di PROCIN-FO_INITFUNC, definito in ARCH/ARM/KERNEL/ASM-OFFSETS.C comeDEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));

dove PROC_INFO_LIST altro non è che la struttura della variabilecontenente le informazioni del processore, e __CPU_FLUSH è un suocampo. PROCINFO_INITFUNC, quindi, è l’offset per arrivare al-l’indirizzo dell’attributo __CPU_FLUSH partendo dall’indirizzo basedella struttura. Nel nostro caso verrà eseguito il codice presentenel file ARCH/ARM/MM/PROC-ARM926.S (cpu per la quale stiamocompilando il kernel).

471 .type __arm926_proc_info,#object472 __arm926_proc_info:473 .long 0x41069260 @ ARM926EJ-S (v5TEJ)

1last register; per questo e per altri comandi assembly si rimandaall’appendice A

Page 24: Boot Linux Arm

24 CAPITOLO 2. AVVIO

474 .long 0xff0ffff0475 .long PMD_TYPE_SECT | \476 PMD_SECT_BUFFERABLE | \477 PMD_SECT_CACHEABLE | \478 PMD_BIT4 | \479 PMD_SECT_AP_WRITE | \480 PMD_SECT_AP_READ481 .long PMD_TYPE_SECT | \482 PMD_BIT4 | \483 PMD_SECT_AP_WRITE | \484 PMD_SECT_AP_READ485 b __arm926_setup486 .long cpu_arch_name487 .long cpu_elf_name488 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|

HWCAP_JAVA489 .long cpu_arm926_name490 .long arm926_processor_functions491 .long v4wbi_tlb_fns492 .long v4wb_user_fns493 .long arm926_cache_fns494 .size __arm926_proc_info, . - __arm926_proc_info

Quindi andremo ad eseguire il codice presente nella funzione__ARM926_SETUP, definita nello stesso file

395 .type __arm926_setup, #function396 __arm926_setup:397 mov r0, #0398 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4399 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4400 #ifdef CONFIG_MMU401 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4402 #endif403404405 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH406 mov r0, #4 @ disable write-back on caches

explicitly407 mcr p15, 7, r0, c15, c0, 0408 #endif409410 adr r5, arm926_crval411 ldmia r5, {r5, r6}412 mrc p15, 0, r0, c1, c0 @ get control register v4413 bic r0, r0, r5414 orr r0, r0, r6415 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN416 orr r0, r0, #0x4000 @ .1.. .... .... ....417 #endif418 mov pc, lr419 .size __arm926_setup, . - __arm926_setup

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

Page 25: Boot Linux Arm

2.3. BOOT 25

minino impostando il program counter col valore del last register,cioè l’indirizzo di __ENABLE_MMU. Essa è definita in HEAD.S.

149 /*150 * Setup common bits before finally enabling the MMU. Essentially151 * this is just loading the page table pointer and domain access152 * registers.153 */154 .type __enable_mmu, %function155 __enable_mmu:156 #ifdef CONFIG_ALIGNMENT_TRAP157 orr r0, r0, #CR_A158 #else159 bic r0, r0, #CR_A160 #endif161 #ifdef CONFIG_CPU_DCACHE_DISABLE162 bic r0, r0, #CR_C163 #endif164 #ifdef CONFIG_CPU_BPREDICT_DISABLE165 bic r0, r0, #CR_Z166 #endif167 #ifdef CONFIG_CPU_ICACHE_DISABLE168 bic r0, r0, #CR_I169 #endif170 mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \171 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \172 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \173 domain_val(DOMAIN_IO, DOMAIN_CLIENT))174 mcr p15, 0, r5, c3, c0, 0 @ load domain access register175 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer176 b __turn_mmu_on

L’ultima riga invoca la funzione __TURN_MMU_ON, definita subitodopo.

178 /*179 * Enable the MMU. This completely changes the structure of the visible180 * memory space. You will not be able to trace execution through this.181 * If you have an enquiry about this, *please* check the linux-arm-kernel182 * mailing list archives BEFORE sending another post to the list.183 *184 * r0 = cp#15 control register185 * r13 = *virtual* address to jump to upon completion186 *187 * other registers depend on the function called upon completion188 */189 .align 5190 .type __turn_mmu_on, %function191 __turn_mmu_on:192 mov r0, r0193 mcr p15, 0, r0, c1, c0, 0 @ write control reg194 mrc p15, 0, r3, c0, c0, 0 @ read id reg195 mov r3, r3196 mov r3, r3197 mov pc, r13

Page 26: Boot Linux Arm

26 CAPITOLO 2. AVVIO

Al termine della funzione, viene modificato il program counterper eseguire il contenuto di r13, contenente l’oggetto __SWITCH_DATA.Questo è definito nel file ARCH/ARM/KERNEL/HEAD-COMMON.S

17 .type __switch_data, %object18 __switch_data:19 .long __mmap_switched20 .long __data_loc @ r421 .long __data_start @ r522 .long __bss_start @ r623 .long _end @ r724 .long processor_id @ r425 .long __machine_arch_type @ r526 .long __atags_pointer @ r627 .long cr_alignment @ r728 .long init_thread_union + THREAD_START_SP @ sp2930 /*31 * The following fragment of code is executed with the MMU on in MMU mode,32 * and uses absolute addresses; this is not position independent.33 *34 * r0 = cp#15 control register35 * r1 = machine ID36 * r2 = atags pointer37 * r9 = processor ID38 */39 .type __mmap_switched, %function40 __mmap_switched:41 adr r3, __switch_data + 44243 ldmia r3!, {r4, r5, r6, r7}44 cmp r4, r5 @ Copy data segment if needed45 1: cmpne r5, r646 ldrne fp, [r4], #447 strne fp, [r5], #448 bne 1b4950 mov fp, #0 @ Clear BSS (and zero fp)51 1: cmp r6, r752 strcc fp, [r6],#453 bcc 1b5455 ldmia r3, {r4, r5, r6, r7, sp}56 str r9, [r4] @ Save processor ID57 str r1, [r5] @ Save machine type58 str r2, [r6] @ Save atags pointer59 bic r4, r0, #CR_A @ Clear ’A’ bit60 stmia r7, {r0, r4} @ Save control register values61 b start_kernel

Il primo campo dell’oggetto __SWITCH_DATA è la funzione __MMAP_SWITCHED

che, eseguita, termina invocando START_KERNEL, la funzione “adalto livello” implementata in C nel file INIT/MAIN.C.

E direi che può bastare

Page 27: Boot Linux Arm

2.4. HELLO, WORLD! 27

2.4 Hello, world!

Avendo capito dov’è il punto di avvio del kernel, e volendone mod-ificare il comportamento all’avvio, abbiamo deciso di iniziare dalclassico “Hello, world!”.

In particolare, abbiamo modificato i sorgenti nei file ARCH/ARM/KERNEL/HEAD-COMMON.S (in modo da invocare una funzione diversa al terminedella fase di bootstrap)

61 b start_kernel_hello_os /* b start_kernel */

e abbiamo modificato il file INIT/MAIN.C (aggiungendo la nuovafunzione da invocare all’avvio)

534 extern void printascii(const char*);535536 asmlinkage void __init start_kernel_hello_os(void) {537 printascii("Hello, world!\n");538 }

Il prototipo della funzione start_kernel_hello_os() è identico aquello della funzione start_kernel(), inidicando al compilatore

• che essa è una funzione che non ha parametri né restituisceniente (i due void)

• che la funzione non utilizzerà i registri, ma solo lo stack per iparametri (come ottimizzazione)2

• che il codice generato dovrà essere presente in una parte bendefinita del binario (in questo caso nella sezione “.init.text”)3

Inoltre è stato necessario introdurre il prototipo della funzione print-ascii(), implementata in assembly nel file ARCH/ARM/KERNEL/DE-BUG.S.

116 ENTRY(printascii)117 addruart r3

2Confronta http://kernelnewbies.org/FAQ/asmlinkage3Confronta http://kernelnewbies.org/FAQ/InitExitMacros

Page 28: Boot Linux Arm

28 CAPITOLO 2. AVVIO

118 b 2f119 1: waituart r2, r3120 senduart r1, r3121 busyuart r2, r3122 teq r1, #’\n’123 moveq r1, #’\r’124 beq 1b125 2: teq r0, #0126 ldrneb r1, [r0], #1127 teqne r1, #0128 bne 1b129 mov pc, lr

Purtroppo, l’implementazione delle macro addruart, waituart,senduart e busyuart è “implemention defined”, nel senso che ognisingola architettura dell’ARM definisce una sua versione delle quat-tro macro. Esse sono definite nei vari file INCLUDE/ASM-ARM/ARCH-*/DEBUG-MACRO.S.

Page 29: Boot Linux Arm

Capitolo 3

Test

La fase di test è consistita nel verificare il funzionamento del kernelprima sul dispositivo HTC P6300, usando una smart card comedispositivo di boot e Haret come bootloader; poi utilizzando qemuper realizzare una macchina virtuale su cui abbiamo installato ilkernel che abbiamo debuggato usando gdb; infine si vedrà il com-portamento del kernel usando U-boot come bootloader presentesulla memoria flash 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 modificato la memoria interna del palmareinstallandoci sopra un bootloader universale U-boot il quale per-mette di far partire kernel anche da remoto sin dall’avvio. Conquesta modalità però si perde tutto il software preinstallato sullamacchina dal momento che si sovrascrive la memoria stessa.

29

Page 30: Boot Linux Arm

30 CAPITOLO 3. TEST

Nel modo non invasivo viene avviato un programma sotto Win-dows Mobile® per lanciare il kernel dopo aver disabilitato l’hard-ware in modo da non danneggiarlo. Questa è, in effetti, una modal-ità abbastanza utilizzata anche se vi possono essere problemi dicompatibilità tra l’hardware e il bootloader.

Volendo scelgliere la modalità non invasiva, ci siamo concentratisul bootloader, Haret. Sul sito del progetto è presente anche unwiki dove è possibile trovare una lista di dispositivi testati ed infase di testing.

3.1.2 Come usare Haret

Il suo obiettivo è di preparare il dispositivo al lancio del kernellinux.

Prima di tutto dobbiamo ottenerlo: sono disponibili versioni pre-compilate per Windows Mobile®, ma abbiamo preferito lavorare coni sorgenti prelevandoli dal server svn di sviluppo.

Volendo usare i sorgenti, però, sorge il problema di compilarli dauna macchina x86 con sistema operativo linux verso una macchinaARM con sistema operativo Windows Mobile®. Per quest’ultimoproblema, si rimanda alla sezione 3.1.5.

Nel caso si preferisca usare una versione già precompilata, basteràscaricarla e copiarla sulla miniSD con alcuni file di configurazionee il kernel stesso.

$ wget http://www.handhelds.org/~koconnor/haret/haret-0.5.1.exe

Il file di configurazione STARTUP.TXT:

set KERNEL "zImage-2.6.12"set MTYPE 766set INITRD "initrd-2.6.12-hh2.gz"set CMDLINE "root=/dev/ram0 console=tty0"bootlinux

indica all’eseguibile HARET.EXE come settare alcuni parametri (vari-abili globali all’interno del codice di haret) quali KERNEL, MTYPE,

Page 31: Boot Linux Arm

3.1. HARET 31

INITRD, CMDLINE ed infine avvia la funzione (interna al codice diharet quindi scritta in C++) bootlinux().

3.1.3 Codice

Il codice del programma prevede parti scritte in C++ e parti scrittein Assembly. Le funzioni più interessanti sono presenti all’internodel file LINBOOT.CPP.

La funzione launchKernel() ad esempio è responsabile di inibirel’hardware e lanciare il kernel

556 static void557 launchKernel(struct bootmem *bm)558 {559 // Prep the trampoline.560 uint32 physAddrTram = setupTrampoline();561 if (! physAddrTram)562 return;563 // Cache an mmu pointer for the trampoline564 uint8 *virtAddrMmu = memPhysMap(cpuGetMMU());565 Output("MMU setup: mmu=%p/%08x", virtAddrMmu, cpuGetMMU());566 // Call per-arch setup.567 int ret = Mach->preHardwareShutdown();568 if (ret) {569 Output(C_ERROR "Setup for machine shutdown failed");570 return;571 }572 Screen("Go Go Go...");573 // Disable interrupts574 take_control();575 fb_clear(&bm->pd->fbi);576 fb_printf(&bm->pd->fbi, "HaRET boot\nShutting down hardware\n");577 // Call per-arch boot prep function.578 Mach->hardwareShutdown(&bm->pd->fbi);579 fb_printf(&bm->pd->fbi, "Turning off MMU...\n");580 // Disable MMU and launch linux.581 mmu_trampoline(physAddrTram, virtAddrMmu, bm->physExec, Mach->flushCache);582 // The above should not ever return, but we attempt recovery here.583 return_control();584 }

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

Page 32: Boot Linux Arm

32 CAPITOLO 3. TEST

254 if ((psr & 0xc0) != 0xc0)255 FB_PRINTF(&data->fbi, "ERROR: IRQS not off\\n");256 if (fbOverlaps(data)) {257 FB_PRINTF(&data->fbi, "Disabling framebuffer feedback\\n");258 data->fbi.fb = 0;259 }260 // Copy tags to beginning of ram.261 char *destTags = (char *)data->startRam + PHYSOFFSET_TAGS;262 do_copy(destTags, data->tags, TAGSIZE);263 FB_PRINTF(&data->fbi, "Tags relocated\\n");264 // Copy kernel image265 char *destKernel = (char *)data->startRam + PHYSOFFSET_KERNEL;266 int kernelCount = PAGE_ALIGN(data->kernelSize) / PAGE_SIZE;267 do_copyPages((char *)destKernel, data->indexPages, 0, kernelCount);268 FB_PRINTF(&data->fbi, "Kernel relocated\\n");269 // Copy initrd (if applicable)270 char *destInitrd = (char *)data->startRam + PHYSOFFSET_INITRD;271 int initrdCount = PAGE_ALIGN(data->initrdSize) / PAGE_SIZE;272 do_copyPages(destInitrd, data->indexPages, kernelCount, initrdCount);273 FB_PRINTF(&data->fbi, "Initrd relocated\\n");274 // Do CRC check (if enabled).275 if (data->doCRC) {276 FB_PRINTF(&data->fbi, "Checking tags crc...");277 uint32 crc = crc32_be(0, destTags, TAGSIZE);278 crc = crc32_be_finish(crc, TAGSIZE);279 if (crc == data->tagsCRC)280 FB_PRINTF(&data->fbi, "okay\\n");281 else282 FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n");283 FB_PRINTF(&data->fbi, "Checking kernel crc...");284 crc = crc32_be(0, destKernel, data->kernelSize);285 crc = crc32_be_finish(crc, data->kernelSize);286 if (crc == data->kernelCRC)287 FB_PRINTF(&data->fbi, "okay\\n");288 else289 FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n");290 if (data->initrdSize) {291 FB_PRINTF(&data->fbi, "Checking initrd crc...");292 crc = crc32_be(0, destInitrd, data->initrdSize);293 crc = crc32_be_finish(crc, data->initrdSize);294 if (crc == data->initrdCRC)295 FB_PRINTF(&data->fbi, "okay\\n");296 else297 FB_PRINTF(&data->fbi, "FAIL FAIL FAIL\\n");298 }299 }300 FB_PRINTF(&data->fbi, "Jumping to Kernel...\\n");301 // Boot302 typedef void (*lin_t)(uint32 zero, uint32 mach, char *tags);303 lin_t startfunc = (lin_t)destKernel;304 startfunc(0, data->machtype, destTags);305 }

è sicuramente la più importante dal momento che nelle ultimetre righe passa il controllo al kernel terminando l’esecuzione di

Page 33: Boot Linux Arm

3.1. HARET 33

haret stesso quindi.

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

viene definita un prototipo di funzione di tipo puntatore a lin_t

316 lin_t startfunc = (lin_t)destKernel;

è definita una variabile startfunc di tipo lin_t come cast dellavariabile 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 valoredella 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 momentoche dopo lo shutdown dell’hardware il programma accede diret-tamente alla memoria e non riesce a tradurre le funzioni e librerietipiche del C++ con conseguente uso di funzion ad-hoc. Ad esempionella funzione preloader() vi è

251 FB_PRINTF(&data->fbi, "In preloader\\n");

la quale risulta una macro definita nel codice in modo seguente

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

(.text.preload, fmt) , ##args )

Per quanto riguarda la comunicazione verso l’utente in haretesistono due tipologie di output

• file di log;

• stampa a video.

Page 34: Boot Linux Arm

34 CAPITOLO 3. TEST

Per abilitare l’output su file di log è necessario creare un file vuotoall’interno della cartella dove è presente l’eseguibile HARET.EXE erinominarlo EARLYHARETLOG.TXT. Il file di log HARETLOG.TXT ver-rà creato nella stessa cartella. All’interno del codice la funzioneOutput() è la responsabile della scrittura su file.

La seconda tipologia di output si rende necessaria quando avvienelo shutdown dell’hardware dal momento che non si ha più acces-so alla memoria della miniSD. All’interno del codice la funzionefb_printf() stampa a video ove previsto.

Questo rappresenta la parte finale di un file di log. Nella primaparte vi è il riconoscimento della macchina da parte del sistema.

1 Welcome, this is HaRET pre-0.5.2-20080711_124633 running on WindowsCE v5.12 Minimal virtual address: 00010000, maximal virtual address: 7FFFFFFF3 Detected machine Panda/s3c2442 (Plat=’PocketPC’ OEM=’PAND100’)4 CPU is ARM ARM arch 4T stepping 0 running in system mode5 Enter ’HELP’ for a short command summary.6 Running WSAStartup7 Starting gui8 In initdialog9 Found machine Panda

10 executing startup.txt11 HaRET(1)# set MTYPE 180612 HaRET(2)# set KERNEL "zImage"13 HaRET(3)# set CMDLINE "root=/dev/mmcblk0p2 console=tty0 mem=128M rootdelay=5"14 HaRET(4)# bootlinux15 boot KERNEL=zImage INITRD=16 Opening file zImage17 boot params: RAMADDR=30000000 RAMSIZE=08000000 MTYPE=1806 CMDLINE=’root=/dev/

mmcblk0p2 console=tty0 mem=128M rootdelay=5’18 Boot FB feedback: 119 Built virtual to physical page mapping20 Allocated 265 pages (tags=4FB00000/36b4e000 kernel=4FB01000/36b4f000 initrd=4

FC05000/36a47000 index=4FC05000/36a47000)21 Built kernel tags area22 Built page index23 Video buffer at 52800000 sx=240 sy=320 mx=60 my=5324 Video Phys FB=10800000 Fonts=36a4506425 preload=2260@4FC08000/36a44000 sj=4FC08000 stack=4FC06000/36a46000 data=4FC07000

/36a45000 exec=36a4412826 Reading 1062116 bytes...27 Read complete28 Launching to physical address 36a4401029 Trampoline setup (tram=136@00024AEC/1c024aec/30882aec)30 MMU setup: mmu=A0250000/3055000031 Go Go Go...

Si noti come al terzo rigo avvisa dell’avvenuto riconoscimentodella macchina e della tipologia di cpu. Poi parte nell’esecuzionedel contenuto di STARTUP.TXT come fossero comandi separati tra

Page 35: Boot Linux Arm

3.1. HARET 35

loro (si noti il carattere # indicatore della pseudo-shell). L’ultimocomando è appunto bootlinux il quale fa partire l’esecuzione delcodice visto in precedenza. Alla fine del file di log vi è la scritta“Go Go Go ...” che è l’ultimo messaggio previsto dal codice prima dispegnere l’hardware e lasciare l’esecuzione al kernel. La presenzadi questo messaggio quindi implica il successo nell’esecuzione diharet. Tutti gli eventuali problemi successivi saranno dovuti alkernel non più ad haret.

3.1.4 Problemi

Abbiamo constatato delle difficoltà a debuggare su un sistema em-bedded.

Nel nostro caso avevamo problemi dal momento che ci apparivala 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 all’interno del

codice di haret. Con un attento debug tramite stringhe stam-pate sullo schermo ci siamo accertati che effettivamente il controllopassava al kernel (tre righe finali viste in precedenza).

Il dubbio immediatamente successivo riguardava un problemadi errato passaggio del file del kernel.

Anche in questo caso abbiamo stampato a video e confrontatobit a bit il file del kernel con il contenuto del buffer di memoria cheveniva avviato da haret.

3.1.5 Compilazione di Haret

Per la compilazione di Haret è necessario usare un compilatoreC++ per ARM con Windows Mobile®. Noi abbiamo usato arm-mingw32ce, toolset sviluppato nel progetto cegcc[ceg08], sviluppa-to allo scopo di compilare binari per windows CE. Dopo il dowload1

e la scompattazione si ritroveranno una serie di binari pronti al-l’uso con il formato arm-wince-cegcc-* o arm-wince-mingw32ce-*.

1Non è possibile segnalare il link diretto, in quanto il progetto si appoggia asourceforge.net, che utilizza un insieme di mirror per lo storage dei file.

Page 36: Boot Linux Arm

36 CAPITOLO 3. TEST

Se si scompattano i file nella directory radice, non sarà necessariomodificare il Makefile dei sorgenti di Haret.

$ su -c "tar xzf cegcc-gcc430.tar.gz -C /"[PASSWORD DI ROOT]

Per ottenere l’ultima versione dei sorgenti, è necessario usarecvs:

$ cvs -d :pserver:[email protected]:/cvslogin

CVS password: anoncvs$ cvs -d :pserver:[email protected]:/cvs

co haret$ cd haret$ make

al termine della compilazione, sarà stato generato il file OUT -/HARET.EXE, pronto per essere usato come già detto nella sezione3.1.2.

3.2 Qemu

Qemu è un emulatore e virtualizzatore generico open source. Nel-lo specifico è stato usato per emulare un’architettura basata sucpu ARM (Versatile AB prima, Samsung S3C2442B dopo) persemplificare 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à sufficiente usare il package managerdella distribuzione (YaST per OpenSuSE, Synaptic per Debian ederivate, installpkg per Slackware, eccetera); nella (improbabile)ipotesi che non sia disponibile, i sorgenti sono disponibili pressohttp://bellard.org/qemu/qemu-0.9.1.tar.gz.

In ogni caso si avrà accesso all’applicazione tramite terminale.

Page 37: Boot Linux Arm

3.2. QEMU 37

Listing 3.1: Output di QEMU lanciato senza parametri$ qemuQEMU PC emulator version 0.9.1, Copyright (c) 2003-2008 Fabrice Bellardusage: qemu [options] [disk_image]’disk_image’ is a raw hard image image for IDE hard disk 0Standard 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 cardsuse -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 guestNetwork 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 sendhostname ’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 thenetwork 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 optionis 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 diskDebug/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

Page 38: Boot Linux Arm

38 CAPITOLO 3. TEST

translation (t=none or lba) (usually qemu can guess them)-L path set the directory for the BIOS, VGA BIOS and keymaps-kernel-kqemu enable KQEMU full virtualization (default is user mode only)-no-kqemu disable KQEMU kernel module usage-std-vga 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 helpDuring emulation, the following keys are useful:ctrl-alt-f toggle full screenctrl-alt-n switch to virtual console ’n’ctrl-alt toggle mouse and keyboard grabWhen using -nographic, press ’ctrl-a h’ to get some help.$

Listing 3.1: Output di QEMU lanciato senza parametri

Per poter emulare anche il chip Samsung S3C2442B è statautilizzata anche una versione di qemu custom modificata e manutenu-ta dagli sviluppatori del progetto openmoko[ope08].

Per migliorare le prestazioni di qemu è possibile installare anchekqemu, un modulo kernel scritto per velocizzare l’emulazione dix86 su x86 http://bellard.org/qemu/download.html

3.2.2 Emulazione

Qemu fornisce alcune utility all’emulazione. Ad esempio qemu-imgè un programmino per la creazione di hard disk virtuali su cui fargirare o installare il sistema emulato. Per l’avvio di una emulazioneè possibile specificare oltre ad un hard disk virtuale anche unofisico presente sulla macchina. Nel nostro caso abbiamo lanciatoqemu specificando come hard disk la memory card miniSD su cuiavevano 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 128mb 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.

Page 39: Boot Linux Arm

3.2. QEMU 39

Per emulare un sistema ARM con macchina versatileab con ker-nel contenuto nel file locale zImage e 128 mb di ram e aventecome hard disk un’immagine virtuale locale hd0.img è necessariolanciare

$ 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-system-cris qemu-system-ppcembqemu-arm qemu-ppc64 qemu-system-i386 qemu-system-sh4qemu-armeb qemu-ppc64abi32 qemu-system-m68k qemu-system-sh4ebqemu-cris qemu-sh4 qemu-system-mips qemu-system-sparcqemu-i386 qemu-sh4eb qemu-system-mips64 qemu-system-x86_64qemu-img qemu-sparc qemu-system-mips64el qemu-system-z80qemu-m68k qemu-sparc32plus qemu-system-mipsel qemu-x86_64qemu-mips qemu-sparc64 qemu-system-ppcqemu-mipsel qemu-system-arm qemu-system-ppc64$

in particolare, QEMU-SYSTEM-ARM supporta le seguenti architet-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 LM3S811EVBlm3s6965evb Stellaris LM3S6965EVBconnex Gumstix Connex (PXA255)verdex Gumstix Verdex (PXA270)mainstone Mainstone II (PXA27x)

e le seguenti cpu$ qemu-system-arm -cpu ?Available CPUs:

arm926arm946arm1026arm1136arm11mpcorecortex-m3

Page 40: Boot Linux Arm

40 CAPITOLO 3. TEST

cortex-a8ti925tpxa250pxa255pxa260pxa261pxa262pxa270pxa270-a0pxa270-a1pxa270-b0pxa270-b1pxa270-c0pxa270-c5any

3.3 U-Boot

To do

Page 41: Boot Linux Arm

Capitolo 4

Debugger

Abbiamo avuto problemi a far partire il kernel di linux sul dis-positivo palmare, quindi abbiamo cercato di trovare un modo peravere feedback sull’esecuzione del codice e sugli eventuali erroririscontrati sulla piattaforma.

Poiché vorremmo analizzare il comportamento di un kernel, però,non è possibile utilizzare STDOUT / STDERR come canali di co-municazione, né loggare il comportamento su file, in quanto nonè ancora disponibile un’interfaccia verso queste strutture ad altolivello.

Per questo motivo abbiamo considerato l’idea di usare un de-bugger. Per poterla applicare, però, avremmo avuto bisogno di uneseguibile per il sistema operativo Windows Mobile® che si inte-grasse con Haret (vedi capitolo3.1). L’alternativa scelta è stataquella di usare un emulatore per l’architettura, e di usare il classicoGDB per il debug.

Questa scelta ha semplificato l’analisi e il debug dell’esecuzionedelle 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

Page 42: Boot Linux Arm

42 CAPITOLO 4. DEBUGGER

ARCH/X86/BOOT/MAIN.C che identifica la prima funzione invocata,su architettura ARM questo non succede.

Al contrario, vi sono una serie di cartelle per raggruppare l’im-plementazione delle funzioni per piattaforma e per singolo modello,in quanto il modello di distribuzione delle specifiche di ARM è di-verso dal modello di sviluppo intel[arm08]. Come si è visto nelcapitolo 2, la fase iniziale del boot su ARM è implementata in as-sembly; vi è una parte comune (la decompressione della bzImage, ilcaricamento in memoria dell’immagine del kernel, alcune funzionid’appoggio) a tutte le CPU e una parte specifica.

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 sap-pia tracciare le istruzioni ed estrarre i simboli da un binario (ilkernel) compilato per ARM.

Per questo abbiamo scaricato i sorgenti, li abbiamo estratti ecompilati, facendo attenzione a impostare –TARGET=ARM-LINUX nel-la fase di configurazione 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 fine della fase di compilazione, in /USR/LOCAL/BIN (o dovunquesia stato definito il PREFIX in fase di configurazione), saranno statigenerati i file ARM-LINUX-GDB (il debugger vero e proprio), ARM-LINUX-GDBTUI (frontend semi-grafico) e ARM-LINUX-RUN (simulatorein grado di eseguire i programmi per ARM su x86).

4.3 Come usarlo

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

Page 43: Boot Linux Arm

4.3. COME USARLO 43

Figura 4.1: Schema di funzionamento di gdb con qemu

buggare il kernel stesso! Questo perché l’attività di debugging altronon è che eseguire un processo (il debugger) che, tramite chia-mate di sistema (ad esempio tipo la funzione PTRACE()) analizza ilcomportamento di un altro processo (il programma da controllare).

Tuttavia nel caso si voglia controllare il kernel, non è possibileavere accesso alle chiamate di sistema stesse (visto che riguardanoil programma da controllare).

Tuttavia una soluzione esiste.Lavorando con qemu è possibile impostare l’emulatore (che è un

programma utente, sulla macchina host) per offrire una connes-sione a gdb (come se si volesse fare debugging remoto su un’altramacchina).

Per fare ciò basta eseguire qemu aggiungendo le opzioni -S (pernon far partire la cpu dall’inizio) e -S (per attendere una connes-sione dal “client” gdb).

$ qemu-system-arm ... -S -s

In questo modo il programma rimarrà in attesa. Da un altroterminale, quindi, sarà possibile lanciare il debugger:

$ arm-linux-gdbtui vmlinux

Page 44: Boot Linux Arm

44 CAPITOLO 4. DEBUGGER

dove il parametro di gdb è proprio il file VMLINUX creato in fasedi compilazione dei sorgenti.

La prima cosa da fare è effettuare la connessione ad una ses-sione 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).

Nell’appendice B diamo un piccolo prontuario per le operazionipiù comuni di debug.

Page 45: Boot Linux Arm

Appendice A

Assembly per ARM

Tratto da [Uni06a]

ldr (load register) carica un valore in un registro

lr last register (ultimo registro). è usato come implementazionedello stack dal momento che in questo registro vengono mem-orizzati i riferimenti al codice a cui si vuol ritornare dopo unachiamata ad un sottoprogramma. Ad esempio vedere righe101 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 nelcodice (before)

1f label utilizzata per ciclare verso una label (1) avanti nel codice(forward)

b (branch) salta alla label indicata (esempio: B START_KERNEL)

blo salta loopando alla label indicata (esempio: BLO DECOMPRESS_KERNEL)

45

Page 46: Boot Linux Arm

46 APPENDICE A. ASSEMBLY PER ARM

Page 47: Boot Linux Arm

Appendice B

Comandi principali gdb

Tratto da [Uni06b]

h [comando] stampa informazioni, generali o sul comando speci-ficato

q esci dal debugger

target connette gdb ad un processo o ad una sessione remota giàin esecuzione

b [nome_file:]numero_riga inserisci un breakpoint nel file e nellariga specificati

b funzione inserisci un breakpoint ove la funzione è invocata

d numero rimuove il breakpoing numero

run [parametri] esegue il programma debuggato, eventualmentecon i parametri passati. Per quanto generalmente utile, non ènecessaria nel caso specifico di qemu, in quanto l’esecuzionedel codice è già stata iniziata

c continua l’esecuzione fino al termine o al raggiungimento di unbreakpoint

u [nome_file:]numero_riga continua l’esecuzione fino al raggiung-imento nel file e nella riga specificati (come se ci fosse unbreakpoint)

47

Page 48: Boot Linux Arm

48 APPENDICE B. COMANDI PRINCIPALI GDB

n passa all’istruzione successiva; se è l’invocazione di una sub-routine viene trattata come una singola istruzione, ottenendodirettamente il risultato

s passa all’istruzione successiva; se è l’invocazione di una subrou-tine si entra nello stack della funzione

si come s, ma attraverso le istruzioni definite in assembly

ni come n, ma attraverso le istruzioni definite in assembly

p espressione stampa a video il valore dell’espressione (qualunqueespressione valida in C, con inoltre, l’accesso ai registri tramitel’operatore $)

i [sottocomando] info consente di ottenere informazioni varie sulprogramma, in particolare

i lo informazioni sulle variabili locali

i s informazioni sullo stack

i r informazioni sui registri

Page 49: Boot Linux Arm

Appendice C

Licenza per ladocumentazione libera GNU

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

C.1 GNU Free Documentation LicenseVersion 1.2, November 2002Copyright © 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 doc-ument, but changing it is not allowed.

Preamble

The purpose of this License is to make a manual, textbook, or other functionaland useful document “free” in the sense of freedom: to assure everyone the ef-fective freedom to copy and redistribute it, with or without modifying it, eithercommercially or noncommercially. Secondarily, this License preserves for theauthor and publisher a way to get credit for their work, while not being consid-ered responsible for modifications made by others.

49

Page 50: Boot Linux Arm

50APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

This License is a kind of “copyleft”, which means that derivative works of thedocument must themselves be free in the same sense. It complements the GNUGeneral 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 comewith manuals providing the same freedoms that the software does. But thisLicense 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. Werecommend this License principally for works whose purpose is instruction orreference.

1. APPLICABILITY AND DEFINITIONS

This License applies to any manual or other work, in any medium, that containsa notice placed by the copyright holder saying it can be distributed under theterms 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 pub-lic 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 “Modified Version” of the Document means any work containing the Doc-ument or a portion of it, either copied verbatim, or with modifications and/ortranslated into another language.A “Secondary Section” is a named appendix or a front-matter section of theDocument that deals exclusively with the relationship of the publishers or au-thors of the Document to the Document’s 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 maynot explain any mathematics.) The relationship could be a matter of histori-cal 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 des-ignated, as being those of Invariant Sections, in the notice that says that theDocument is released under this License. If a section does not fit the abovedefinition of Secondary then it is not allowed to be designated as Invariant. TheDocument may contain zero Invariant Sections. If the Document does not iden-tify any Invariant Sections then there are none.The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document isreleased under this License. A Front-Cover Text may be at most 5 words, and aBack-Cover Text may be at most 25 words.A “Transparent” copy of the Document means a machine-readable copy, repre-

Page 51: Boot Linux Arm

C.1. GNU FREE DOCUMENTATION LICENSE 51

sented in a format whose specification is available to the general public, that issuitable for revising the document straightforwardly with generic text editors or(for images composed of pixels) generic paint programs or (for drawings) somewidely available drawing editor, and that is suitable for input to text formattersor for automatic translation to a variety of formats suitable for input to text for-matters. A copy made in an otherwise Transparent file format whose markup,or absence of markup, has been arranged to thwart or discourage subsequentmodification by readers is not Transparent. An image format is not Transparentif used for any substantial amount of text. A copy that is not “Transparent” iscalled “Opaque”.Examples of suitable formats for Transparent copies include plain ASCII withoutmarkup, Texinfo input format, LATEX input format, SGML or XML using a pub-licly available DTD, and standard-conforming simple HTML, PostScript or PDFdesigned for human modification. Examples of transparent image formats in-clude PNG, XCF and JPG. Opaque formats include proprietary formats that canbe read and edited only by proprietary word processors, SGML or XML for whichthe DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for out-put purposes only.The “Title Page” means, for a printed book, the title page itself, plus such fol-lowing pages as are needed to hold, legibly, the material this License requires toappear in the title page. For works in formats which do not have any title pageas such, “Title Page” means the text near the most prominent appearance of thework’s title, preceding the beginning of the body of the text.A section “Entitled XYZ” means a named subunit of the Document whose titleeither is precisely XYZ or contains XYZ in parentheses following text that trans-lates XYZ in another language. (Here XYZ stands for a specific section namementioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”,or “History”.) To “Preserve the Title” of such a section when you modify theDocument means that it remains a section “Entitled XYZ” according to this def-inition.The Document may include Warranty Disclaimers next to the notice which statesthat this License applies to the Document. These Warranty Disclaimers are con-sidered to be included by reference in this License, but only as regards disclaim-ing warranties: any other implication that these Warranty Disclaimers may haveis 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 commerciallyor noncommercially, provided that this License, the copyright notices, and thelicense notice saying this License applies to the Document are reproduced in

Page 52: Boot Linux Arm

52APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

all copies, and that you add no other conditions whatsoever to those of thisLicense. You may not use technical measures to obstruct or control the readingor further copying of the copies you make or distribute. However, you may acceptcompensation in exchange for copies. If you distribute a large enough numberof copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you maypublicly display copies.

3. COPYING IN QUANTITY

If you publish printed copies (or copies in media that commonly have printedcovers) of the Document, numbering more than 100, and the Document’s licensenotice 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 andlegibly identify you as the publisher of these copies. The front cover must presentthe full title with all words of the title equally prominent and visible. You mayadd other material on the covers in addition. Copying with changes limited tothe covers, as long as they preserve the title of the Document and satisfy theseconditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you shouldput the first ones listed (as many as fit reasonably) on the actual cover, andcontinue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering morethan 100, you must either include a machine-readable Transparent copy alongwith each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access todownload using public-standard network protocols a complete Transparent copyof the Document, free of added material. If you use the latter option, you musttake reasonably prudent steps, when you begin distribution of Opaque copiesin quantity, to ensure that this Transparent copy will remain thus accessible atthe stated location until at least one year after the last time you distribute anOpaque copy (directly or through your agents or retailers) of that edition to thepublic.

It is requested, but not required, that you contact the authors of the Documentwell before redistributing any large number of copies, to give them a chance toprovide you with an updated version of the Document.

Page 53: Boot Linux Arm

C.1. GNU FREE DOCUMENTATION LICENSE 53

4. MODIFICATIONS

You may copy and distribute a Modified Version of the Document under theconditions of sections 2 and 3 above, provided that you release the ModifiedVersion under precisely this License, with the Modified Version filling the roleof the Document, thus licensing distribution and modification of the ModifiedVersion to whoever possesses a copy of it. In addition, you must do these thingsin the Modified Version:

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

• [B.] List on the Title Page, as authors, one or more persons or entitiesresponsible for authorship of the modifications in the Modified Version,together with at least five of the principal authors of the Document (allof its principal authors, if it has fewer than five), unless they release youfrom this requirement.

• [C.] State on the Title page the name of the publisher of the Modified Ver-sion, as the publisher.

• [D.] Preserve all the copyright notices of the Document.

• [E.] Add an appropriate copyright notice for your modifications adjacent tothe other copyright notices.

• [F.] Include, immediately after the copyright notices, a license notice givingthe public permission to use the Modified Version under the terms of thisLicense, in the form shown in the Addendum below.

• [G.] Preserve in that license notice the full lists of Invariant Sections andrequired Cover Texts given in the Document’s license notice.

• [H.] Include an unaltered copy of this License.

• [I.] Preserve the section Entitled “History”, Preserve its Title, and add to itan item stating at least the title, year, new authors, and publisher of theModified Version as given on the Title Page. If there is no section Entitled“History” in the Document, create one stating the title, year, authors, andpublisher of the Document as given on its Title Page, then add an itemdescribing the Modified Version as stated in the previous sentence.

Page 54: Boot Linux Arm

54APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

• [J.] Preserve the network location, if any, given in the Document for publicaccess to a Transparent copy of the Document, and likewise the networklocations given in the Document for previous versions it was based on.These may be placed in the “History” section. You may omit a networklocation for a work that was published at least four years before the Doc-ument itself, or if the original publisher of the version it refers to givespermission.

• [K.] For any section Entitled “Acknowledgements” or “Dedications”, Pre-serve the Title of the section, and preserve in the section all the substanceand tone of each of the contributor acknowledgements and/or dedicationsgiven therein.

• [L.] Preserve all the Invariant Sections of the Document, unaltered in theirtext and in their titles. Section numbers or the equivalent are not consid-ered part of the section titles.

• [M.] Delete any section Entitled “Endorsements”. Such a section may notbe included in the Modified Version.

• [N.] Do not retitle any existing section to be Entitled “Endorsements” or toconflict in title with any Invariant Section.

• [O.] Preserve any Warranty Disclaimers.

If the Modified Version includes new front-matter sections or appendices thatqualify as Secondary Sections and contain no material copied from the Docu-ment, you may at your option designate some or all of these sections as invari-ant. To do this, add their titles to the list of Invariant Sections in the ModifiedVersion’s license notice. These titles must be distinct from any other sectiontitles.You may add a section Entitled “Endorsements”, provided it contains nothingbut endorsements of your Modified Version by various parties–for example, state-ments of peer review or that the text has been approved by an organization asthe authoritative definition of a standard.You may add a passage of up to five words as a Front-Cover Text, and a passageof up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in theModified Version. Only one passage of Front-Cover Text and one of Back-CoverText may be added by (or through arrangements made by) any one entity. If theDocument already includes a cover text for the same cover, previously added byyou or by arrangement made by the same entity you are acting on behalf of, youmay not add another; but you may replace the old one, on explicit permissionfrom the previous publisher that added the old one.The author(s) and publisher(s) of the Document do not by this License give per-mission to use their names for publicity for or to assert or imply endorsement ofany Modified Version.

Page 55: Boot Linux Arm

C.1. GNU FREE DOCUMENTATION LICENSE 55

5. COMBINING DOCUMENTS

You may combine the Document with other documents released under this Li-cense, under the terms defined in section 4 above for modified versions, providedthat you include in the combination all of the Invariant Sections of all of theoriginal documents, unmodified, and list them all as Invariant Sections of yourcombined work in its license notice, and that you preserve all their WarrantyDisclaimers.The combined work need only contain one copy of this License, and multipleidentical Invariant Sections may be replaced with a single copy. If there aremultiple Invariant Sections with the same name but different contents, makethe 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 aunique number. Make the same adjustment to the section titles in the list ofInvariant Sections in the license notice of the combined work.In the combination, you must combine any sections Entitled “History” in the var-ious original documents, forming one section Entitled “History”; likewise com-bine any sections Entitled “Acknowledgements”, and any sections Entitled “Ded-ications”. You must delete all sections Entitled “Endorsements”.

6. COLLECTIONS OF DOCUMENTS

You may make a collection consisting of the Document and other documentsreleased under this License, and replace the individual copies of this Licensein 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 ofthe documents in all other respects.You may extract a single document from such a collection, and distribute itindividually under this License, provided you insert a copy of this License intothe extracted document, and follow this License in all other respects regardingverbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS

A compilation of the Document or its derivatives with other separate and in-dependent documents or works, in or on a volume of a storage or distributionmedium, is called an “aggregate” if the copyright resulting from the compila-tion is not used to limit the legal rights of the compilation’s users beyond whatthe 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 notthemselves derivative works of the Document.If the Cover Text requirement of section 3 is applicable to these copies of theDocument, then if the Document is less than one half of the entire aggregate,the Document’s Cover Texts may be placed on covers that bracket the Documentwithin the aggregate, or the electronic equivalent of covers if the Document is in

Page 56: Boot Linux Arm

56APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

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

8. TRANSLATION

Translation is considered a kind of modification, so you may distribute transla-tions of the Document under the terms of section 4. Replacing Invariant Sectionswith translations requires special permission from their copyright holders, butyou may include translations of some or all Invariant Sections in addition tothe original versions of these Invariant Sections. You may include a translationof this License, and all the license notices in the Document, and any WarrantyDisclaimers, provided that you also include the original English version of thisLicense and the original versions of those notices and disclaimers. In case of adisagreement between the translation and the original version of this License ora 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 typicallyrequire changing the actual title.

9. TERMINATION

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

10. FUTURE REVISIONS OF THIS LICENSE

The Free Software Foundation may publish new, revised versions of the GNUFree Documentation License from time to time. Such new versions will be similarin spirit to the present version, but may differ in detail to address new problemsor concerns. See http://www.gnu.org/copyleft/.Each version of the License is given a distinguishing version number. If the Doc-ument specifies that a particular numbered version of this License “or any laterversion” applies to it, you have the option of following the terms and conditionseither of that specified version or of any later version that has been published(not as a draft) by the Free Software Foundation. If the Document does not spec-ify 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

Page 57: Boot Linux Arm

C.1. GNU FREE DOCUMENTATION LICENSE 57

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

Copyright © YEAR YOUR NAME. Permission is granted to copy, dis-tribute and/or modify this document under the terms of the GNUFree Documentation License, Version 1.2 or any later version pub-lished by the Free Software Foundation; with no Invariant Sections,no Front-Cover Texts, and no Back-Cover Texts. A copy of the li-cense is included in the section entitled “GNU Free DocumentationLicense”.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replacethe “with . . . Texts.” line with this:

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

If you have Invariant Sections without Cover Texts, or some other combinationof the three, merge those two alternatives to suit the situation.If your document contains nontrivial examples of program code, we recommendreleasing 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.

Page 58: Boot Linux Arm

58APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

Page 59: Boot Linux Arm

Elenco dei simboli

big zImage vedi bzImage

bootstrap Letteralmente la fascetta di cuoio cucita sul bordo pos-teriore degli stivali per aiutarsi a calzarli, fa riferimento allaleggenda del Barone di Münchhausen e alla sua capacità disollevarsi in aria tirandosi per gli stivali.Indica la fase di avvio di un pc

bzImage Immagine del kernel compressa ed eseguibile, ma com-posta da tre parti separate

host In ambiente di emulazione, la macchina reale che ospita l’em-ulatore.In ambiente di cross-compilazione, la macchina che ospita ilcompilatore.Vedi: target

Image Immagine del kernel effettivamente eseguita

miniSD Mini Secure Digital, versione più piccola (20x21.5) delleschede di memoria SD (24x32)

MMU Memory Management Unit

svn SubVersioN: sistema per controllo di revisione, usato nellosviluppo di sistemi software, consente di avere e condividerela storia delle modifiche effettuate sui file del progetto

target In ambiente di emulazione, la macchina virtuale generatadall’emulatore.

59

Page 60: Boot Linux Arm

60APPENDICE C. LICENZA PER LA DOCUMENTAZIONE LIBERA GNU

In ambiente di cross-compilazione, la macchina su cui ver-ranno utilizzati i programmi compilati.Vedi: host

toolchain Insieme di tutti gli strumenti (tra gli altri preprocessore,assembler, compilatore, linker...) necessari alla generazionedi 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 modifi-carlo a loro piacimento, senza dover accedere direttamente aifile presenti in remoto.

Windows Mobile® Microsoft® Windows Mobile®, sistema operativoconcepito per palmari, telefoni cellulari e Pocket PC

zImage Immagine del kernel compressa preceduta da un decom-pressore (obsoleta)

Page 61: Boot Linux Arm

Bibliografia

[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 definition. 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, febbraio2006.

[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 O’Connor, and Paul Sokolovsky.Haret. http://handhelds.org/moin/moin.cgi/HaRET,giugno 2008.

61