Linux Kernel
Building a Kernel
The current mechanism to support a specific Xtensa processor configuration is not yet fully automated, but is a very simple and straight forward process. Note that the Xtensa port of Linux uses the terminology variant to describe a processor configuration. For this example, we will use MyCore as the new processor name, but any name can be used. The steps involved adding a processor configuration are:
- Create a new directory for the processor variant (MyCore) and copy a set of configuration files that describes the processor to that directory
- Add the name of the processor configuration to a Linux configuration file.
- Add the path of the variant directory to a Makefile
Create a directory for the variant and copy configuration files
All processor configuration specific sources and header files are located in arch/xtensa/variants/variant-name for source files, and arch/xtensa/variants/variant-name/include/variant for header files. The include directory typically contains at least the following three files that describe the processor configuration:
- tie.h - describing custom defined TIE registers
- tie-asm.h - macros to access additional TIE registers
- core.h - describing various processor configurations, such as cache sizes, register options, etc.
All processor configurations provide a set of these files as part of the overlay provided by Tensilica.
If we want to add another processor, we have to create the following directory and copy the three configurations file to that directory:
mkdir -p arch/xtensa/variants/MyCore/include/variant cp tie.h tie-asm.h core.h arch/xtensa/variants/MyCore/include/variant
Add the processor name to a Linux configuration file
The file arch/xtensa/Kconfig contains a list of processor configurations. Simply add a new entry under the menu "Processor type and features" in the "Xtensa Processor Configuration" list. In most cases, the configuration will have an MMU, so add also the line select MMU.
choice prompt "Xtensa Processor Configuration" ... config XTENSA_VARAINT_DC233C bool "dc233c - Diamond 233L Standard Core Rev.C (LE)" select MMU help ... config XTENSA_VARIANT_MYCORE bool "MyCore - My extreeem core" select MMU help MyCore with various optimizations.
Add the processor to the makefile
Simply add a line for your core at the top of the file. The part of the configuration name CONFIG_XTENSA_VARIANT_MYCORE after CONFIG_ must match the name that was added to Kconfig, and the right hand side must match the name of the directory created in step 1.
variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000 variant-$(CONFIG_XTENSA_VARIANT_MYCORE) := MyCore
Kernel loadable modules using FLIX with L32R
The kernel module loader (for the Xtensa architecture) supports only the limited set of relocations needed for module loading. This includes, for example, relocation of literals referenced by L32R instructions. This loader is not given specific information about any custom TIE configured in the processor, and thus is currently not able to relocate L32R instructions encoded in a FLIX bundle.
To ensure kernel modules load properly, they need to avoid L32R instructions within FLIX instruction bundles.
Existing kernel code does not generate such instructions, so it is not susceptible. However, it is possible to generate FLIX instructions using assembly code, or using the Tensilica XCC compiler. In the case of assembly code, simply avoid using L32R or MOVI instructions within a FLIX instruction bundle, unless a MOVI is known to fit without expanding ("relaxing") into an L32R instruction. In the case of XCC, pass the -mno-flix to the compiler (xt-xcc) to avoid generating FLIX bundles.
Note: The use of Tensilica software tools (including XCC) for Linux development is described in the Tensilica OSKit Guide, available from Tensilica.
Debugging Kernel Loadable Modules
Debugging loadable modules isn't easy, a few pointers mentioned here might save you some time. There is a mechanism that Amit Kalie mentioned on his KGDB webpage on loading the module symbols into gdb while loading a module Debuging init_module.
The insmod command has a --map option that dumps the module component offsets needed by Amit's approach. Unfortunately the initial Xtensa buildroot snapshots have a version of insmod that doesn't provide this option. Also, while debugging the kernel it's not convenient to run insmod on the console of the target.
A workaround to this problem is to hack the kernel module.c file and enable debugging.
#if 1 #define DEBUGP printk #else #define DEBUGP(fmt , a...) #endif
This will enable module.c to print the module section addresses. You then just list them in the gdb add-symbol-file command using that command's section (-s) options. Note that the .text section is specified without using the -s option: its address is given alone before any -s option.
final section addresses: [Kernel Console Log/Output] 0xc02a9098 .note.gnu.build-id 0xc02b1000 .init.literal 0xc02a7000 .text 0xc02b11d8 .init.text 0xc02a90bc .rodata 0xc02a92c4 .rodata.str1.4 0xc02ac27c .data 0xc02ac640 __param 0xc02ac668 .gnu.linkonce.this_module 0xc02ac76c .bss 0xc02aaf0c .symtab 0xc02ab8fc .strtab
add-symbol-file /export/src/Transwitch/a2000_src/a2000_src/Linux_atlanta/ctlm-cpe/drivers/ctlmeth/ctlmeth.ko \ 0xc02a7000 \ -s .data 0xc02ac27c \ -s .init.text 0xc02b11d8 \ -s .bss 0xc02ac76c \ -s .init.literal 0xc02b1000 \ -s .rodata 0xc02a90bc
You likely want to compile your modules unoptimized and unstripped to facilitate debugging and provide the path to the module source to gdb with the dir command. For example:
dir /home/pdelaney/src/Transwitch/a2000_src/a2000_src/Linux_atlanta/ctlm-cpe/drivers/ctlmeth/