# README-develop.ronetix # Application and Linux Kernel developing and debugging # for AT91SAM9G45/AT91SAM9263/AT91SAM9261 based boards: # PM9G45, PM9263 and PM9261. # # Ronetix GmbH # www.ronetix.at # February, 2012 # Table of Contents: 1. Matching Linux Kernel, the rootfs to your application 2. Download and install the GNU toolchain 3. Compiling a simple GNU/Linux application 4. Transferring the executable file from the PC to the target 5. Debugging application 6. Kernel debugging 7. Tips and tricks 8. Issues and bug 1. Matching Linux Kernel, the rootfs to your application Take a look at README-linux_kernel.ronetix "7.1. Matching Linux Kernel and the rootfs" The description there applies to your application and the rest of the software. So use the same toolchain as for the Kernel and rootfs. 2. Download and install the GNU toolchain See the toolchain README 3. Compiling a simple GNU/Linux application A. Create a text file example.c with contents: --- example.c --- #include int main(int argc, char** argv){ printf("Hello world\n"); return 0; } --- example.c --- Compiling: Substitute "arm-oe-linux-gnueabi-gcc" with the toolchain used to build kernel and root file system utilities. $ arm-oe-linux-gnueabi-gcc -o example example.c The result is the ELF file called "example". B. Compiling spidev test program which comes with Linux kernel Install the "KaeilOS v2010.1 SDK", see the toolchain README. $ cd linux-2.6.30-git_repo/Documentation/spi $ arm-oe-linux-gnueabi-gcc -I /usr/local/kaeilos/arm/arm-oe-linux-gnueabi/usr/include/ spidev_test.c -o spidev_test Adjust the "-I" path to the installation place of the SDK. 4. Transferring the executable file from the PC to the target A. Using USB stick The simples way is to use a USB stick - just copy the file example to a USB stick inserted into your PC. Unmount the stick and put it into the target board. After few seconds the USB stick will be discovered(most probably). You should have support of the file system on the USB stick, most probably it will be VFAT(FAT32). Take a look at the kernel messages to see the device node of your USB stick. Depending auto-mounter is enabled and installed on the rootfs, the USB stick could be automatically mounted. To see if it is automatically mounted: On target hachine: # mount /dev/sda1 on /media/sda1 In case it is not mounted automatically: On target machine: # mkdir /mnt/sda1 # mount /dev/sda1 /mnt/sda1 -t vfat # cp /mnt/sda1/main . # chmod +x main # ./main Hello world B. Tftp over network A tftp server should work on a host(or any development) computer. On host: $ cp hello tftp_boot_dir/ On target machine: # udhcpc # tftp -g -r tftp_boot_dir/hello -l hello 192.168.3.1 # chmod u+x hello # ./hello Hello world Alternatively to the "udhcpc" you can use "dhclient eth0". 5. Debugging application TODO: 6. Kernel debugging 6.1. vmlinux(the bare kernel) debugging Information on ARM Linux kernel boot process take a look at: http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html http://www.arm.linux.org.uk/developer/booting.php http://gicl.cs.drexel.edu/people/sevy/linux/ARM_Linux_boot_sequence.html A. For PM9G45 To debug a code running on PM9G45, PEEDI shall not init the target to let the environment(MCU setting) clean, but left a software in the pm9g45 to do that - AT91Bootstrap can do the boards setup. So in PEEDI configuration file make an empty init section and set COREn_STARTUP_MODE = RESET. The RESET startup mode lets the PEEDI to attach to the target at the very beginning - the reset state of the CPU. The JTAG clock have to be set as shown "JTAG_CLOCK = 3, 3" this means slow JTAG clock because the PLLs have not been yet initialized. Later when the PLLs and high clock have been turned on JTAG clock can be set higher in the PEEDI command line - "clock 20000". Check if PEEDI has stopped/attached to the target at reset state as executing PEEDI command "info reg" and make sure the registers and state are as shown: --- info reg --- pc : 00000000 cpsr : 000000D3 spsr : 00000000 State: Supervisor --- info reg --- The PEEDI have to be attached to the board, and the board have to be at the reset state, then the GDB can be attached to PEEDI either with the shown .gdbinit script or with the commands entered by hand in the GDB commadn line(commands entered by hand do not need a delay). In this case the Linux kernel binary file have been programmed in NAND. (the same note as for Bootloader) The Bootloader except loading the Linux kernel, it also set parameters to the kernel so loading kernel in RAM from PEEDI is complicate. --- .gdbinit --- target remote 192.168.10.42:2000 -attach shell sleep 1s symbol-file pm9g45_bb9g45_vmlinux shell sleep 1s hbreak start_kernel shell sleep 1s continue shell sleep 3s monitor clock 20000 shell sleep 1s delete --- .gdbinit --- Description of each .gdbinit line: Line1: attaches the GDB to PEEDI, when target is at reset state. Line3: tells GDB where are the symbols. Line5: put a hardware breakpoint at the point where kernel is starting. Line7: start the target .... Line8: wait for a while until AT91Bootsrap, and bootloader are gone. Three seconds should be enough. Line9: At this time the kernel break point shloud be hit. Increase the JTAG clock. Line11: delete the hardware breakpoint, it can be useful later. After a gdb command a short delay is needed - delay is determined experimentally. B. For PM9263 and PM9261 The board should be programmed with the u-boot and the binary version of the kernel. Start gdb/insight: $ arm-oe-linux-gnueabi-gdb vmlinux In the console window: (gdb) target remote peedi_ip:2000 (gdb) set $pc = 0x10000040 ; the u-boot is flashed at ; 0x10000000 (after remap) (gdb) c The board is running: first starts the u-boot, then the Linux kernel. If you have a serial console you can see that the Linux is working. Now you can halt the kernel and set breakpoints where you want. If you want to have a breakpoint before the kernel is running you have to do the following: (gdb) target remote peedi_ip:2000 (gdb) set $pc = 0x10000040 ; assuming the u-boot is flashed ; at 0x10000000 (gdb) hbreak start_kernel ; hardware breakpoint is used ; because the MMU is still not ; active (gdb) c The board is running (u-boot, then the kernel) and will stop at the start_kernel function. (gdb) delete ; delete the hardware breakpoint. Now you can use the software breakpoints. 6.2. Modules debugging TODO: 7. Tips and tricks 7.1. Detach and attach When gdb connects to the PEEDI(target), the PEEDI resets the target. If you do not want to reset the target, attach to it. (gdb) target remote peedi_ip:2000 --attach If leaving gdb and don't want to reset the target: (gdb) detach (gdb) quit later you can attach again. 7.2. Enable debug information in Linux kernel In "Kernel hacking/" select "Kernel debugging" and "Compile the kernel with debug info". 7.3. Tftp client notes The tftp client could be Busybox or GNU inetutils. A. BusyBox usage # tftp -g -r tftp_boot_dir/hello -l hello 192.168.3.1 B. GNU inetutils usage # tftp 192.168.3.1 tftp> get tftp_boot_dir/hello 8. Issues and bug bug: Eclipse shows wrong file in Debug perspective when debugging multi CPU architecture project and files with the same names exists for each architecture. fix: In the Debug Configuration in the Source tab remove Default source lookup path, and add Absolute path.