Annotation of wikisrc/tutorials/how_to_use_thumb_mode_on_arm.mdwn, revision 1.5

1.2       schmonz     1: This howto explains how NetBSD **current** can use thumb mode on ARM architecture (evbarm). 
                      3: #   Introduction 
                      5: While normal ARM instructions are 32 bits wide, thumb provides a subset of ARM instructions in 16 bits, and thus reduces executable sizes both in memory and on filesystem [[1|How to reduce libc size]]. See [Wikipedia]( for more details. 
                      7: On large codebases like NetBSD, ARM and thumb mode code can, and must, co-exists. This is because some parts of ARM specific code can not be programmed with the 16 bit thumb instructions. Luckily GCC makes this relatively easy with the **thumb-interwork** option. 
                      9: As an overview, most machine independent (MI) C code can be compiled to thumb mode and most machine dependent (MD) C and assembly code can only be compiled to ARM mode. Some parts of the ARM port specific code in NetBSD have support for thumb mode, but most of them do not. 
                     11: NetBSD's CPUFLAGS build variable is used tell the compiler, when an object file is compiled to thumb mode and when thumb interworking needs to enabled. The GCC options are **-mthumb** and **-mthumb-interwork**. By default ARM target binaries are of course compiled to ARM mode. 
                     13: In a large codebase like NetBSD it becomes difficult to manually check if any one object file can be compiled to thumb mode. Luckily brute force works with the help of make option **-k**, as in keep going even one object file does not compile. By compiling whole tree with CPUFLAGS=-mthumb and MAKEFLAGS=-k, all of the build time failing machine dependent object files can be found, and marked with the help of [[Per file build options override]] to be compiled to ARM mode with thumb interworking. 
                     16: Build time failures are of course not the only things can go wrong with thumb support. At run time, some parts of the kernel or userspace are expected to be in ARM mode. In userspace, for example, this means that the dynamic linker (ld.elf_so), userspace locking and C runtime initialization (CSU) parts need to be in ARM mode. 
                     18: #   Userspace 
                     20: Userspace in **current** compiles to userspace, but doesn't work due to a linker bug [2]([3]( 
                     23: If the binutils package is upgraded to 2.18.50 from 2.16.1, then thumb mode works for userspace. After this, only a build script marking the ARM and thumb mode files is needed. 
                     25: Following patches do it all for **current** snapshot from Oct 22nd 2008: 
                     27:   * binutils upgrade and tuning for NetBSD in [4]( and [5](
                     28:   * thumb build script [6](
                     31: After the patches have been applied on top of **current**, the build process continues like this: 
                     33:   * build tools 
                     35:     ./ -U -O obj -m evbarm -j 3 tools
                     38:   * build userspace to thumb, note that the script expects to find tools directory under obj 
                     40:     ./
                     43:   * build a normal ARM mode kernel, where CONFIG is the configuration file name like TISDP2420 
                     45:     ./ -U -O obj -m evbarm -j 3 kernel=CONFIG
                     48: The next step is to verify that the thumb mode userspace works by booting into it. On OMAP 2420 development board this requires setting up a TFTP server for the kernel executable netbsd.bin and then setting up the root filesystem over NFS (and configuring the kernel accordingly). 
                     50: ##   Known problems 
                     52: While the thumb mode userspace boots and most programs and the shell work, some programs may have issues. Known regressions at this time are: 
                     54:   * thumb mode gcc segfaults on target 
1.5     ! sevan      56: <pre><code>
        !            57:     # cat > test.c << EOF
1.2       schmonz    58:     > int main(void){
                     59:     > return 0;
                     60:     > }
                     61:     > EOF
1.5     ! sevan      62:     # gcc --verbose -Wall test.c
1.2       schmonz    63:     Using built-in specs.
                     64:     Target: arm--netbsdelf
                     65:     Configured with: /usr/src/tools/gcc/../../gnu/dist/gcc4/configure --enable-longtThread model: posix
                     66:     gcc version 4.1.3 20080704 prerelease (NetBSD nb1 20080202)
                     67:      /usr/libexec/cc1 -quiet -v test.c -quiet -dumpbase test.c -auxbase test -Wall s#include "..." search starts here:
1.5     ! sevan      68:     #include <...> search starts here:
1.2       schmonz    69:      /usr/include
                     70:     End of search list.
                     71:     GNU C version 4.1.3 20080704 prerelease (NetBSD nb1 20080202) (arm--netbsdelf)
                     72:             compiled by GNU C version 4.1.3 20080704 (prerelease) (NetBSD nb1 20080.GGC heuristics: --param
                     73:             ggc-min-expand=34 --param ggc-min-heapsize=7808
                     74:     Compiler executable checksum: c67c46e1fc2de869e7015b2c172bd073
                     75:     test.c: In function 'main':
                     76:     test.c:3: internal compiler error: Segmentation fault
                     77:     Please submit a full bug report,
                     78:     with preprocessed source if appropriate.
1.4       sevan      79:     See <> for instructions.
1.5     ! sevan      80: </code></pre>
1.2       schmonz    81: 
                     83:   * thumb mode gdb segfaults on target 
1.5     ! sevan      85: <pre><code>
1.2       schmonz    86:     # gdb --verbose /bin/cat
                     87:     [1]   Segmentation fault (core dumped) gdb --verbose /bin/cat
1.5     ! sevan      88: </code></pre>
1.2       schmonz    89:     
                     91: These issues may be solved by upgrading to newer versions of GCC compiler and gdb debugger. 
                     93: Another problem is that newer binutils adds more symbols in thumb mode than older binutils, which makes thumb mode binaries file size larger than the with old binutils and larger than ARM mode binaries [7]( These extra symbols only affect the file size and sections loaded to memory are smaller in thumb mode than in ARM mode. Also, all of these extra sections and symbols can be easily stripped by providing NetBSD build tools with a **STRIPFLAG=-s** build variable, though without [this patch]( libraries are not stripped. 

CVSweb for NetBSD wikisrc <> software: FreeBSD-CVSweb