Commiting patch to OpenOCD

1) http://openocd.zylin.com/#/settings/
-> Write USERNAME

2) git commit -s –amend
Sign off is necessary

3) tools/checkpatch.sh

-> Replace spaces with tabs

4) git push review HEAD:refs/for/master

-> push from other branch to master for review

Configuring and compiling u-boot for qemu ARM

Configuration must be deone with : make versatileqemu_config ARCH=arm CROSS_COMPILE=arm-none-eabi-.

Otherwise u-boot will be compiled with FLASH support, and will not be possible to run it in qemu (which do not have flash support).

drasko@Marx:~/u-boot/test/u-boot$ make versatileqemu_config ARCH=arm CROSS_COMPILE=arm-none-eabi-
Configuring for versatileqemu – Board: versatile, Options: ARCH_VERSATILE_QEMU,ARCH_VERSATILE_PB

> make all ARCH=arm CROSS_COMPILE=arm-none-eabi-

ARM QEMU

ARM Qemu

 
Qemu 

Qemu

[ ]# mkdir /home/qemu
[ ]# cd /home/qemu/
[ ]# git clone git://git.qemu.org/qemu.git qemu-git
[ ]# cd qemu-git/
[ ]# ./configure –target-list=”arm-softmmu”
[ ]# make
[ ]# cp arm-softmmu/qemu-system-arm /usr/bin/

Or
http://download.savannah.gnu.org/releases/qemu/qemu-0.14.1.tar.gz

U-boot

[ ]# cd /home/qemu/
[ ]# wget http://ftp.denx.de/pub/u-boot/u-boot-2010.03.tar.bz2
[ ]# cd u-boot-2010.03
[ ]# make versatilepb_config ARCH=arm CROSS_COMPILE=arm-linux-
[ ]# make all ARCH=arm CROSS_COMPILE=arm-linux-
[ ]# qemu-system-arm -M versatilepb -m 128M -nographic -kernel u-boot.bin

 
U-Boot 2010.03 (Jun 15 2011 – 14:38:26)
 
DRAM: 0 kB
## Unknown FLASH on Bank 1 – Size = 0x00000000 = 0 MB
Flash: 0 kB
*** Warning – bad CRC, using default environment
 
In: serial
Out: serial
Err: serial
Net: SMC91111-0
VersatilePB # print
bootargs=root=/dev/nfs mem=128M ip=dhcp netdev=25,0,0xf1010000,0xf1010010,eth0
bootdelay=2
baudrate=38400
bootfile=”/tftpboot/uImage”
stdin=serial
stdout=serial
stderr=serial
verify=n
ethact=SMC91111-0
 
Environment size: 202/8188 bytes
VersatilePB #

Simple “Hello World!” Root File System

[ ]# cd /home/qemu/
[ ]# echo “#include ” > test.c
[ ]# echo “int main() {” >> test.c
[ ]# echo -e ‘\tprintf(“Hello World!\\n”);’ >> test.c
[ ]# echo -e “return 0;” >> test.c
[ ]# echo “}” >> test.c

[ ]# arm-linux-gcc -static test.c -o test
[ ]# echo test | cpio -o –format=newc > rootfs

ARM Linux Versatile (ARMv5)
[ ]# cd /home/qemu/
[ ]# wget http://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.35/linux-2.6.35.12.tar.bz2
[ ]# tar jxvf linux-2.6.35.12.tar.bz2
[ ]# cd linux-2.6.35.12
[ ]# make ARCH=arm versatile_defconfig
[ ]# make ARCH=arm menuconfig

Enabling EABI support in the kernel. (CONFIG_AEABI=y, CONFIG_OABI_COMPAT=y)

[ ]# make ARCH=arm CROSS_COMPILE=arm-linux- all
[ ]# qemu-system-arm -M versatilepb -m 128M -kernel arch/arm/boot/zImage -initrd rootfs -serial stdio -append “console=ttyAMA0 root=/dev/ram rdinit=/test”

You can use “-nographic” instead of “-serial stdio” to launch QEMU without opening another window, but then to close it you have to type Ctrl-A and then “x”.

Running Linux kernel in qemu (compiled by Buildroot)

drasko@Marx:~/buildroot/output/images$ qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.ext2

qemu will output the boot messages.

To log-in, press <Ctrl><Alt><3> to go the qemu console.

Debugging u-boot in qemu

1) Inspect qemu asm :

drasko@Marx:~/u-boot/u-boot$ qemu-system-arm -d in_asm -M versatilepb -m 256 -kernel u-boot.bin

drasko@Marx:~/u-boot/u-boot$ gvim /tmp/qemu.log

Turns out that program has been loaded here :

—————-
IN:
0x00000000: mov r0, #0 ; 0x0
0x00000004: mov r1, #131 ; 0x83
0x00000008: orr r1, r1, #256 ; 0x100
0x0000000c: ldr r2, [pc, #0] ; 0x14
0x00000010: ldr pc, [pc, #0] ; 0x18

—————-
IN:
0x00010000: b 0x10050

—————-
IN:
0x00010050: mrs r0, CPSR <—- we can see from disasm that this is our _start (explanations below in discussion)
0x00010054: bic r0, r0, #31 ; 0x1f
0x00010058: orr r0, r0, #211 ; 0xd3
0x0001005c: msr CPSR_fc, r0

—————-

2) Start qemu :
qemu-system-arm -s -S -M versatilepb -m 256 -kernel u-boot.bin

3) Start GDB :
drasko@Marx:~/u-boot/u-boot$ arm-none-eabi-gdb u-boot

4) Set breakpoints :

drasko@Marx:~/u-boot/u-boot$ arm-none-eabi-gdb u-boot
GNU gdb (Sourcery G++ Lite 2009q3-68) 6.8.50.20090630-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-none-eabi”.
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>&#8230;
(gdb) p _start
$1 = {<text variable, no debug info>} 0x1000000 <_start>
(gdb) target remote :1234
Remote debugging using :1234
0x00000000 in ?? ()
(gdb) add-symbol-file u-boot 0x00010000
add symbol table from file “u-boot” at
.text_addr = 0x10000
(y or n) y
Reading symbols from /home/drasko/u-boot/u-boot/u-boot…done.
(gdb) b *0x00010000
Breakpoint 1 at 0x10000: file start.S, line 55.
(gdb) c
Continuing.

Breakpoint 1, _start () at start.S:55
55 b reset
(gdb) l
50 */
51
52
53 .globl _start
54 _start:
55 b reset
56 #ifdef CONFIG_PRELOADER
57 /* No exception handlers in preloader */
58 ldr pc, _hang
59 ldr pc, _hang
(gdb)

DISCUSSION :

<drasko> info registers, found it
* trem (~trem@mol92-1-81-57-136-23.fbx.proxad.net) has joined #qemu
* malc_ (~malc@188.123.242.211) has joined #qemu
* paveljanik (~Pavel@unaffiliated/paveljanik) has joined #qemu
* hpoussin has quit (Remote host closed the connection)
* buntfalke has quit (Excess Flood)
* buntfalke (~nobody@openvpn-p0-147.triple-a.uni-kl.de) has joined #qemu
* buntfalke has quit (Changing host)
* buntfalke (~nobody@unaffiliated/buntfalke) has joined #qemu
* paveljanik has quit (Quit: This computer has gone to sleep)
* iksaif has quit (Ping timeout: 258 seconds)
* iksaif (~iksaif@88.191.73.63) has joined #qemu
<drasko> Hi all. I am tying to debug u-boot in qemu-system-arm. Putting breakpoint on _start or reset vector seems to have no effect, and program goes by it and boots int u-boot. Do you have any idea what is happening ?
<nox-> mmu not setup yet?
* nox- just guessing…
<drasko> nox-, yes, MMU is not set up, and will not be
<drasko> I do not have MMU mapping in u-boot
<nox-> that could have something to do with it
<drasko> Anyway – I am just putting _start symbol at 0x10000000. There is where code begins. But putting breakpoint here in gdb has no effect…
<nox-> oh and you could run with -d in_asm to verify the load address
* muelli has quit (Ping timeout: 260 seconds)
* quintela has quit (Remote host closed the connection)
<trem> nite all, sweet dreams
* quintela (~quintela@trasno.trasno.org) has joined #qemu
<drasko> nox-, how to do this ?
* trem has quit (Quit: Ex-Chat)
<nox-> as arg to qemu
<nox-> then look in /tmp/qemu.log
<drasko> and what is this option -d ? I am starting it with : qemu-system-arm -s -S -M versatilepb -m 256 -kernel u-boot.bin. Then I connect with GDB via target remote :1234.
<nox-> -d is for what goes in the log
<nox-> there is in_asm,out_asm,intr and maybe a few others
* quintela has quit (Quit: quintela)
<drasko> Well, in log I can see that “reset” label is put to 0x00010050. And it should be 0x01000000.
* muelli (~muelli@port-8979.pppoe.wtnet.de) has joined #qemu
<drasko> The thing is that U-Boot is compiled for address in RAM, but executed from addr 0x01000000 in the begining while it relocates itself to this address in RAM (for which it was compiled)
* dl9pf (~quassel@opensuse/member/dl9pf) has joined #qemu
<drasko> cool, I found the workaround.
<drasko> With add-symbol-file u-boot 0x00010000 and b *0x00010050 gets me where I want – at the begining of a reset vector
<drasko> Thanks nox-
<nox-> yw 🙂
* muellisoft (~muelli@port-1916.pppoe.wtnet.de) has joined #qemu
* tchan has quit (Quit: WeeChat 0.3.3-dev)
* muelli has quit (Ping timeout: 240 seconds)
* tchan (~tchan@c-69-243-144-70.hsd1.il.comcast.net) has joined #qemu
* tchan has quit (Changing host)
* tchan (~tchan@lunar-linux/developer/tchan) has joined #qemu
* muellisoft has quit (Ping timeout: 265 seconds)
* rmm (~matinata@201.82.147.236) has joined #qemu
* quintela (~quintela@trasno.trasno.org) has joined #qemu
* muellisoft (~muelli@port-90704.pppoe.wtnet.de) has joined #qemu
<drasko> nox-, do you have any idea why qemu puts assembly portion of code to 0x00010000 instead of 0x01000000 ? I look at symbols in my elf, and : 01000000 T _start. Also, dissasembling gives that .text starts at : 01000000 <_start>.
<nox-> afaik embedded boards usually load the bootcode at some (board-dependent) fixed address regardless of contents
* pbrook_ (~paul@cpc10-seac20-2-0-cust474.seac.cable.virginmedia.com) has left #qemu
<nox-> emulating a rom or whatever…
* chkr has quit (Quit: Leaving)
* pbrook (~paul@cpc10-seac20-2-0-cust474.seac.cable.virginmedia.com) has joined #qemu
<pbrook> My guess is you’re not actually loading the ELF image.
<nox-> ah yeah the image is just mapped as is not really interpreted?
<pbrook> The arm image loader should loas uboot and ELF images properly. Everything else is assumes to be a linux kernel blob (zImage).
<drasko> I am loading u-boot.bin, i. e. not elf
<pbrook> That’ll be your problem then.
<drasko> pbrook, why exactly ? Whay is it changing addresses for only asm portion ?
<nox-> you said it relocates itself…
<drasko> nox-, what do you mean exactly with mapping/interpretting ?
<nox-> interpreting the elf header
<nox-> vs just mmap’ing the raw elf
<pbrook> There’s no way for qemu to know where it’s supposed to load random binary blobs so it loads them as an arbitrary address (in this case probably 0x10000).
<pbrook> Any sets up machine state so that if the blob happens to be a linux kernel then it’ll work.
<nox-> and that address is board-dependent, right?
<pbrook> It’s arbitrary.
<nox-> mm
<drasko> pbrook, nox-, I get it now. So u-boot.bin is mmaped to arbitrary addr, and then it will relocate itself to a good one (during execution).
<nox-> yep
<pbrook> If you want your image to be loaded at a specific address, then use an image format that contains that information (i.e. ELF or uimage).
<pbrook> If you provide a raw binary bob (it sounds like u-boot.bin is one) then it will be loaded at an arbitrary address. Whether it chooses to relocate itself later is not something qemu knows or cares about.
<pbrook> i.e. the best answer is probably “don’t do that”.
<drasko> pbrook, nox- very nice! With elf it works perfectly, and I learned a lot. Thanks guys.

Debugging After Relocation

In order to debug U-Boot after relocation, we need to know the address which U-Boot relocates itself to. There are couple of ways to get it,

  1. Get it from U-Boot ‘bdinfo’ command.
    VersatilePB # bdinfo
    arch_number = 0x00000183
    boot_params = 0x00000100
    DRAM bank   = 0x00000000
    -> start    = 0x00000000
    -> size     = 0x08000000
    ethaddr     = (not set)
    ip_addr     = 0.0.0.0
    baudrate    = 38400 bps
    TLB addr    = 0x07FF0000
    relocaddr   = 0x07FC5000   <--
    reloc off   = 0x07FB5000
    irq_sp      = 0x07FA2F70
    sp start    = 0x07FA2F60
    FB base     = 0x00000000
    VersatilePB #
  2. Print the value of gd->relocaddr. Since gd is avalable after board_init_f(), and it is storeed in register $r1,
    (gdb) b relocate_code
    Breakpoint 1 at 0x1007c: file start.S, line 226.
    (gdb) c
    Continuing.
    
    Breakpoint 1, relocate_code () at start.S:226
    226             mov     r5, r1  /* save addr of gd */
    (gdb) p/x ((gd_t *)$r1)->relocaddr
    $1 = 0x7fc5000
    (gdb)

Having the relocated address, we need to reload the symbol file accordingly.

(gdb) d
Delete all breakpoints? (y or n) y
(gdb) symbol-file
Discard symbol table from `/home/winfred/u-boot/u-boot'? (y or n) y
No symbol file now.
(gdb) add-symbol-file u-boot 0x7fc5000
add symbol table from file "u-boot" at
.text_addr = 0x7fc5000
(y or n) y
Reading symbols from /home/winfred/u-boot/u-boot...done.
(gdb)

Then, debug U-Boot after relocation. Let’s try to break at the first function after the relocation,

(gdb) b board_init_r
Breakpoint 2 at 0x7fc5d64: file board.c, line 455.
(gdb) c
Continuing.

Breakpoint 2, board_init_r (id=0x7fa2f70, dest_addr=133976064) at board.c:455
455             gd = id;
(gdb)

Porting Atomthreads

1) cd drasko@Marx:~/atomthreads/atomthreads/ports/arm
> make

Will make all test apps for ARM (defined im Makefile $PREFIX)

2) drasko@Marx:~/atomthreads/atomthreads/ports/arm$ gvim ../../tests/kern1.c

3) drasko@Marx:~/atomthreads/atomthreads/ports/arm$ qemu-system-arm -M versatilepb -m 128M -nographic -s -S -kernel build/kern1.elf

4)
drasko@Marx:~/atomthreads/atomthreads/ports/arm/build$ arm-none-eabi-gdb ./kern1.elf
GNU gdb (Sourcery G++ Lite 2009q3-68) 6.8.50.20090630-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-none-eabi”.
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>&#8230;
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x00008018 in __do_global_dtors_aux ()
(gdb)

5) drasko@Marx:~/atomthreads/atomthreads/ports/arm$ gvim tests-main.c

Now, debbuging it will fail, i.e. no “n” in gdb will be possible — missing
stack !

We can :
1) compile with plain gcc, change $PREFIX in Makefile to nothing
2) run user-space simulation in plain i386 userspace gdb :
gdb kern1.elf

This will allow us to do a few steps, but then everything will crash => we are
missing sp set-up, no stack configured.

Solution :

6) Add start.s

drasko@Marx:~/atomthreads/atomthreads/ports/arm$ gvim start.s

.global _reset
_reset:
ldr sp, =stack_top
bl main
b .

7) Add arm.ld

drasko@Marx:~/atomthreads/atomthreads/ports/arm$ gvim arm.ld

ENTRY(_reset)
SECTIONS
{
. = 0x10000;
.start . : { build/start.o }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
. = . + 0x1000; /* 4kB of stack memory */
stack_top = .;
}

8) Add them to the build system :

drasko@Marx:~/atomthreads/atomthreads/ports/arm$ gvim Makefile

APP_ASM_OBJECTS = atomport-asm.o start.o

# Test ELF files (one application build for each test)
$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
$(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) –output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map -Wl,-T,arm.ld

9) make clean; make

10) Start qemu :
drasko@Marx:~/atomthreads/atomthreads/ports/arm/build$ qemu-system-arm -M versatilepb -m 128M -nographic -s -S -kernel kern1.elf

11) connect with GDB :

drasko@Marx:~/atomthreads/atomthreads/ports/arm/build$ arm-none-eabi-gdb –eval-command=”target remote localhost:1234″ kern1.elf
GNU gdb (Sourcery G++ Lite 2009q3-68) 6.8.50.20090630-cvs
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “–host=i686-pc-linux-gnu –target=arm-none-eabi”.
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>&#8230;
Remote debugging using localhost:1234
0x00010000 in _reset ()
(gdb) b main
Breakpoint 1 at 0x1038c: file tests-main.c, line 181.
(gdb) c
Continuing.

Breakpoint 1, main () at tests-main.c:181
181 status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES – 1], (IDLE_STACK_SIZE_BYTES/2));
(gdb) l
176 * OS from prefilling it.
177 *
178 * If you are not reusing the idle thread’s stack during startup then
179 * you should pass in the correct size here.
180 */
181 status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES – 1], (IDLE_STACK_SIZE_BYTES/2));
182 if (status == ATOM_OK)
183 {
184 /* Enable the system tick timer */
185 avrInitSystemTickTimer();
(gdb)