Reputation: 1
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:
Upvotes: 0
Views: 628
Reputation: 1
Thanks to the hint from @TimothyBaldwin I've got now the answer (I hope its okay if I write a own answers providing more details instead of simply accepting his one).
As mentioned by @TimothyBaldwin, the Problem was that the Programm is loaded at 0x8000, as you can see in the diagram found at https://raspberrypi.stackexchange.com/questions/10442/what-is-the-boot-sequence.
As explained there, in my case it works perfectly nice if I add to my config.txt the following line:
disable_commandline_tags=1
because then the code is loaded at 0x0, and everything works as expected.
Upvotes: 0
Reputation: 71576
Bx or blx should be your first choices for instructions. You can pop into the pc, but why setup a register, push, and the pop, just bx. And there may be some others that can correctly modify the pc, not sure if mov is one but the arm docs will tell you.
If bx is not working for you then you are either encoding the bx wrong or you are not placing the address in the register right.
mov r3,#0x12000000
orr r3,r3,#0x00340000
orr r3,r3,#0x00005600
orr r3,r3,#0x00000078
bx r3
produces
0: e3a03412 mov r3, #301989888 ; 0x12000000
4: e383370d orr r3, r3, #3407872 ; 0x340000
8: e3833c56 orr r3, r3, #22016 ; 0x5600
c: e3833078 orr r3, r3, #120 ; 0x78
10: e12fff13 bx r3
and will branch to address 0x12345678
Upvotes: 1
Reputation: 3729
Although I don't know the Raspbery Pi registers, I think there are several problems in this code:
By the way, the for loop for the delay may be something like:
MOV r0, #1000 ; Start of the counter
loop: SUBS r0, #1 ; Decrement the counter (Sets the flags for the branch)
BNE loop ; Branch to loop label until r0 is 0
Upvotes: 0
Reputation: 3675
You are branching to the wrong address, your program is loaded at 0x8000. If you use labels the linker should calculate the addresses for you.
Upvotes: 0