I'm trying to write a very basic cross compiler for the Raspberry Pi B+ Version to build simple bare metal programmes. My compiler is able to translate simple commands into the corresponding machine language instruction, using the ARM Instruction Set Datasheet.
Turning on LEDs (orientating myself on the baking pi course, http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/) works fine.
But now i want to do some branch instructions, and this is where nothing seems to work anymore:
First i would like to branch to absolute addresse, no relative branches using the B / BL instruction.
To test a branch, I'm using the following disassembled code (disassembled using the Hopper Disassembler V3 Test Version), wich turns on a LED connected with GPIO 16 and22:
00000000 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
00000004 orr r0, r0, #0x200000
00000008 mov r1, #0x40 ;Load the Set Function Mask (for GPIO 22) into r1
0000000c str r1, [r0, #0x8] ;Store the Set Function Mask into the GPFSEL2
00000010 mov r1, #0x400000 ;Move the Set Output Mask (for GPIO 22) into r1
00000014 str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000018 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
0000001c orr r0, r0, #0x200000
00000020 mov r1, #0x40000 ;Load the Set Function Mask (for GPIO 16) into r1
00000024 str r1, [r0, #0x4] ;Store the Set Function Mask into the GPFSEL2
00000028 mov r1, #0x10000 ;Move the Set Output Mask (for GPIO 16) into r1
0000002c str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000030 b 0x30 ;Infinity Loop to keep the processor up
Now I want to add a branch to the beginning of the code, to skip the first section, so that only the second LED is activated.
I tried it like that:
mov r15, #0x1c
but the only effect is that both LEDs stay dark.
My second attempt is like that:
mov r2, #0x20
bx r2
But that neither works.
So my question is:
- How do I perform such a branch?
- Am I using the Addresses the right way?
-ffreestanding
option to build code that doesn't depend on any libraries. I assume the GNU assembler can assemble ARM asm into a flat binary file if you ask it to, so you can use that to write the startup code that sets up to run your compiler-output functions. As I understand it, this is basically how the Linux kernel is built: mostly C with some asm for setup, and a build process that makes a kernel image instead of an ELF executable. – Peter Cordes