Programming the ARM chip


135 posts   Page 2 of 6   1, 2, 3, 4, 5, 6
by zippy » Tue May 15, 2012 4:36 pm
mole125 wrote:if memory serves me right some sample code has been provided,


Possibly I've missed that too (if so, a link would be very much appreciated), but I'm not aware of any datasheet or specific example code showing how to configure the video hardware directly and do basic stuff like setup screen modes and create a 2D frame buffer.

Of course it would be possible to hack at least some of this stuff from the linux driver binaries... call me lazy but I'd rather not devote weeks to going down that route. :)

I don't want to do anything fancy with the 3D hardware, just the most basic and fundamental stuff that was one of the crucial steps to learning how my BBC Micro worked almost 30 years ago... how to put stuff on the screen by programming the hardware directly from assembler.

I'm sure this stuff will come sooner or later (possibly even from official sources), it's just that when I saw the above post about the datasheet I thought maybe it was already out there and I'd missed it.
Posts: 21
Joined: Fri Dec 30, 2011 1:28 am
by hzrnbgy » Tue May 15, 2012 8:07 pm
johnbeetem wrote:For a nice way to play with ARM at the bare metal, I suggest the STM32 Discovery boards. They're ARM Cortex-M3 (or M0 or M4) so you're using the Thumb-2 instruction encodings, but you do have control over everything and can boot from flash. It's also easy to disable the USB ST-Link interface and program the target chip directly from your own JTAG interface. You might also check out the NXP mbed and LPCXpresso boards.


You can't go wrong with the STM32F4Discovery. Comes with 1000+ pages just for the reference manual and cost only $15.

Good luck and happy programming
Posts: 106
Joined: Mon Dec 26, 2011 10:55 pm
by hippy » Tue May 15, 2012 10:34 pm
hzrnbgy wrote:You can't go wrong with the STM32F4Discovery. Comes with 1000+ pages just for the reference manual and cost only $15.


I can appreciate where you are coming from but it does seem pointless to go elsewhere when one has an R-Pi that is perfectly suitable and what is learned along the way can feed back into the community and help others along the same path.

As the R-Pi boots from SD card and doesn't need JTAG it's probably one of the friendliest systems for bare metal programming. All that's lacking is some examples of what the code looks like to print "Hello World!" to the frame buffer, send and receive via the UART etc, plus how to turn that into a boot-loadable .img file for those of us unfamiliar with that but would like to have a go. Hopefully that will come as more people get their hands on the hardware and start exploring possibilities.

There are a fair few looking at bare-metal coding and their own OS's and what I've described above will probably be their first steps too. Hopefully they'll document and publish when they reach that milestone and the rest of us can stand on their shoulders and be very grateful for that.
Posts: 757
Joined: Fri Sep 09, 2011 10:34 pm
by hzrnbgy » Wed May 16, 2012 6:23 am
I'm not suggesting the guy to ditch the RPi. What I'm saying is if he really needs to go to the nitty-gritty of ARM programming (i.e considering a career in embedded electronics, design, etc), then there are more suitable and cheaper alternative to the RPi that are actually created to help anyone start out in baremetal programming. These products come with application manuals and real datasheets.

I am also looking forward in doing my own baremetal application for the RPi but I haven't seen a single example on how to actually do it (what/where/how to get the toolchain/IDE/compiler/etc). I hear people keep saying its the same as every other ARM processor but fail to realize that somehow you would have to build your toolchain to compile an application for it.
Posts: 106
Joined: Mon Dec 26, 2011 10:55 pm
by tufty » Wed May 16, 2012 6:32 am
As usual, see my .sig

Simon
Posts: 1330
Joined: Sun Sep 11, 2011 2:32 pm
by jamesh » Wed May 16, 2012 8:13 am
Burngate wrote:To an astronomer anything heavier than helium is a metal - so silicon is a metal, as is carbon, ...


What's their opinion of blancmange?
Moderator
Moderator
Posts: 10580
Joined: Sat Jul 30, 2011 7:41 pm
by Neil » Wed May 16, 2012 11:46 am
jamesh wrote:
Burngate wrote:To an astronomer anything heavier than helium is a metal - so silicon is a metal, as is carbon, ...


What's their opinion of blancmange?

White or pink?
Posts: 88
Joined: Thu Sep 29, 2011 7:10 am
by Neil » Wed May 16, 2012 11:53 am
zippy wrote:
nick.mccloud wrote:The Broadcom documentation gives info on addresses to use for the frame buffer for display.


Really? This is exactly what I've been waiting for but in the BCM2835 pdf file I have it doesn't mention anything at all about accessing the hardware directly to display something on screen. Is there a new and updated file which now has this info?

As you say, keyboard access via USB is another hurdle, but if we can at least have a dumb 2D frame buffer direct from ARM code (without an OS) that is a huge step forward.


There is no direct hardware access to the "screen" (whatever that means). What you do have is a simple means to communicate with the firmware running on the VideoCore to set up a framebuffer in memory to which you can poke bitmaps and have them appear on whatever display device is connected (HDMI or analogue SDTV).

I think Dom posted some code to illustrate this. If not, grab the source files from the repos and there should be everything you need to be able to drive the framebuffer.

Neil
Posts: 88
Joined: Thu Sep 29, 2011 7:10 am
by johnbeetem » Wed May 16, 2012 2:46 pm
hzrnbgy wrote:I am also looking forward in doing my own baremetal application for the RPi but I haven't seen a single example on how to actually do it (what/where/how to get the toolchain/IDE/compiler/etc). I hear people keep saying its the same as every other ARM processor but fail to realize that somehow you would have to build your toolchain to compile an application for it.

I use the pre-compiled CodeSourcery tool chain to cross-compile for the BeagleBoard. It should work nicely for RasPi with different compiler options. Here's a good starting point: http://www.elinux.org/ARMCompilers. The "Sourcery G++ Lite" version is gratis but doesn't have an IDE. I've successfully used "Sourcery G++ Lite 2011.03-41 for ARM GNU/Linux" on an Ubuntu 11.10 PC and an earlier "G++ Lite" version on a Windows 2000 PC.

For native RasPi development I believe the Debian release includes GCC so you don't need to cross compile and don't need to build a tool chain.
User avatar
Posts: 938
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Coast
by hippy » Wed May 16, 2012 5:22 pm
johnbeetem wrote:The "Sourcery G++ Lite" version is gratis but doesn't have an IDE.


I found that very easy to install and easy enough to use from a Windows command prompt so that's my recommendation as a novice Linux programmer. Haven't tried running an actual ARM / R-Pi executable but stuff cross-compiled for X86 ran okay under Ubuntu.
Posts: 757
Joined: Fri Sep 09, 2011 10:34 pm
by __----__----__ » Thu May 17, 2012 7:51 am
johnbeetem wrote:For native RasPi development I believe the Debian release includes GCC so you don't need to cross compile and don't need to build a tool chain.


Can gcc produce straight binary (compiled) ARM bytecode which would run
as is much like NASM? (i.e. no elf headers, relocation code, bss,data & code sections)
Otherwise it would just compile it to standard Linux elf which is not much good
for a bare metal setup.
User avatar
Posts: 16
Joined: Tue May 15, 2012 9:33 am
by mole125 » Thu May 17, 2012 8:52 am
Presumably if it can produce the linux kernel which runs from bare metal (give or take a bootloader) then it can build an alternative 'kernel' running a specific bare metal application?
Posts: 230
Joined: Tue Jan 10, 2012 2:01 pm
by __----__----__ » Thu May 17, 2012 9:03 am
@mole125
Makes sense to me.

I also found FASMARM which is FASM for ARM.
http://arm.flatassembler.net

It can produce Linux elf executables and straight binaries.

EDIT:
Been playing around with FASMARM and rather like it as it has two
advantages over gcc (IMHO):
Syntax is much less convoluted then using inline asm in gcc and FASMARM
has a basic but perfectly adequate IDE which runs under Windows so I can
develop code for the Pi in Windows, transfer it to the SD card and run it.
User avatar
Posts: 16
Joined: Tue May 15, 2012 9:33 am
by tufty » Thu May 17, 2012 10:50 am
Good god almighty, don't compare a dedicated assembler to inline assembler in gcc. Or attempt to anything other than minor macros using inline asm, come to that - it's horrible. You can use the assembler directly (and you can use the gcc preprocessor to keep your define the same between asm and c). Again, see my .sig for examples.

If you require an ide, you could use eclipse with CDT, and thus do all your mixed c/asm stuff together.

Simon
Posts: 1330
Joined: Sun Sep 11, 2011 2:32 pm
by __----__----__ » Thu May 17, 2012 10:58 am
@tufty
Quite right.
Just mentioned FASMARM as an alternative to gcc if using assembler.
Most folks would probably try gcc simply because it's included with the
Debian Distro.

The drawback with Eclipse is it's size.
User avatar
Posts: 16
Joined: Tue May 15, 2012 9:33 am
by DexOS » Thu May 17, 2012 12:29 pm
People some times make life harder for them selfs
FasmArm is so easy, why make life hard.
Lets make a quick raspberry pi OS with fasmArm (we can fill the blanks as we get more info)

Here our basic code to print to the Uart
Code: Select all
;---------------------------------------------------
;Demo of using Uart functions   UartTest.asm
;
;Assemble:
;     c:\FasmArm UartTest.asm UartTest.bin <enter>
;
;     (c) Team DexOS 2009
;---------------------------------------------------

format binary                                  ; Tell the assembler output type
org     0x30008000                             ; This is where we are load to, i use SDram + 8000, because thats the fix address linux users.
                                               ; Maybe room for vectors ?
use32                                          ; Use 32 bit code
include 'DexArm\Macro.inc'                     ; We will add many more macros to this
;********************************;
; Start.                         ;
;********************************;
start:
;********************************;
; Print char Uart                ;
;********************************;
        mov     r0,'D'                         ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,'e'                         ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,'x'                         ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,'O'                         ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,'S'                         ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,10                          ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,13                          ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,10                          ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

        mov     r0,13                          ; To print char, move letter into r0
        bl      PrintCharUart0                 ; Call the function

;********************************;
; Print String Uart              ;
;********************************;
        adr     r0,STR_DEX                     ; To print zero ending string, do this
        bl      PrintStringUart0               ; Call the function

;********************************;
; Print Hex word Uart            ;
;********************************;
        ldr     r0,[pc,VAR1-$-8]               ; To print a hex word (32bits), we do this
        bl      PrintHexWord                   ; Call the function

;********************************;
; Print Next Lne Uart            ;
;********************************;
        adr     r0,STR_NEXTLINE                ; we can do nextline by using the print function
        bl      PrintStringUart0               ; Call the function

;********************************;
; Print String Uart              ;
;********************************;
        adr     r0,STR_DEX2                    ; To print zero ending string, do this
        bl      PrintStringUart0               ; Call the function

;********************************;
; Print Hex Nibble Uart          ;
;********************************;
        mov     r0,0xd                         ; move the nibble into r0, to print nibble
        bl      PrintHexNibble                 ; Call the function

        mov     r0,0xe                         ; move the nibble into r0, to print nibble
        bl      PrintHexNibble                 ; Call the function

        mov     r0,0xa                         ; move the nibble into r0, to print nibble
        bl      PrintHexNibble                 ; Call the function

        mov     r0,0xd                         ; move the nibble into r0, to print nibble
        bl      PrintHexNibble                 ; Call the function

;********************************;
; End of code so loop            ;
;********************************;
Justloop:
       b        Justloop                       ; Just loop for now


;********************************;
; Data                           ;
;********************************;
align 4                                         ; keep things 4byte aligned
include 'DexArm\Uart.inc'
align 4
VAR1    dw 0xABCDEf03                           ; var to print word in hex

align 4
STR_DEX:                 db  "DexOS is supper cool",10,13
                         db  "I hope this works, as i have been working",10,13
                         db  "on it all day and part of the night.",10,13,10,13
                         db  "PS: Have a good day ;)",10,13,0
align 4
STR_DEX2:                db  "Supper cool if this also works",10,13,0
align 4
STR_NEXTLINE:            db   10,13,0         ; how to do next line

align 4
times 20000- ($-start)  db 0                  ; Just pack the progam out, but as long as your program
                                              ; is at least 20k, you should not need this.     

Uart.inc
Code: Select all
;---------------------------------------------------
;UART Functions   Uart.inc
;
;     (c) Team DexOS 2009
;---------------------------------------------------

align 4
include 'UartInc.inc'

align 4
 ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
 ; Prints char to serial                              ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;  Input:                                            ;
 ;      r0 = Ascii character to write.                ;
 ;      (r1 = Uart line control register address)     ;
 ;                                                    ;
 ; Output:                                            ;
 ;      None.                                         ;
 ;                                                    ;
 ; Modifies:                                          ;
 ;      r0,r1,r2                                      ;
 ;                                                    ;
 ; ( ) = not needed as we are using default base      ;
 ;....................................................;
PrintCharUart0:
        mov   r1,ULCon0                                 ; Set the Uart base
TxEmpty:
        ldr   r2,[r1,UtrStat0]                          ; Load what in Uart line control register address + 0x10 into r2
        and   r2,r2,UtrStatTxEmpty                      ; and it 4
        tst   r2,UtrStatTxEmpty                         ; test if 0 or not
        beq   TxEmpty                                   ; not empty loop
        str   r0,[r1,UTxBuffer0l]                       ; write a byte to the UART transmit buffer register (little end)
        mov   pc,lr                                     ; Return to the next instruction past the call one

align 4
 ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
 ; Prints char to serial                              ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;  Input:                                            ;
 ;      r0 = points to a zero termanated string.      ;
 ;      (r1 = Uart line control register address.)    ;
 ;                                                    ;
 ; Output:                                            ;
 ;      None.                                         ;
 ;                                                    ;
 ; Modifies:                                          ;
 ;      r0,r1,r2,r3                                   ;
 ;                                                    ;
 ; ( ) = not needed as we are using default base      ;
 ;....................................................;
PrintStringUart0:
         mov    r1, ULCon0                              ; We need to save some regs here (first we need to setup a stack)
PrintStringUart0Loop:                                   ;
        ldrB  r3,[r0],1                                 ; Load a byte from the address in r0 into r3, plus add a byte to r0 address
        cmp   r3,0                                      ; test for end of string
        beq   PrintStringUart0Exit                      ; if so exit
TxEmptyString:                                          ;
        ldr   r2,[r1,UtrStat0]                          ; Load what in Uart line control register address + 0x10 into r2
        and   r2,r2,UtrStatTxEmpty                      ; and it 4
        tst   r2,UtrStatTxEmpty                         ; test if 0 or not
        beq   TxEmptyString                             ; not empty loop
        str   r3,[r1,UTxBuffer0l]                       ; write a byte to the UART transmit buffer register (little end)
        b     PrintStringUart0Loop                      ; get the next letter
PrintStringUart0Exit:                                   ;
        mov   pc,lr                                     ; Return to the next instruction past the call one



align 4
 ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
 ; Print Hex least-significant Nibble to serial       ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;  Input:                                            ;
 ;      r0 = contains nibble to write as Hex.         ;
 ;      (r1 = Uart line control register address.)    ;
 ;                                                    ;
 ; Output:                                            ;
 ;      None.                                         ;
 ;                                                    ;
 ; Modifies:                                          ;
 ;      r0,r1,r2                                      ;
 ;                                                    ;
 ; ( ) = not needed as we are using default base      ;
 ;....................................................;
PrintHexNibble:
        adr   r2,hex_digits                             ; Mov the address of HEX_TO_ASCII_TABLE into r2
        and   r0,r0,0xF                                 ; make sure other than we want is zero
        ldrb  r0,[r2, r0]                               ; convert to ascii
        b     PrintCharUart0                            ; jmp to print char

align 4
 ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
 ; Print Hex word to serial                           ;
 ;----------------------------------------------------;
 ;                                                    ;
 ;  Input:                                            ;
 ;      r0 = Print number in r0 as 8 hex digits       ;
 ;     (r1 = Uart line control register address.)     ;
 ;                                                    ;
 ; Output:                                            ;
 ;      None.                                         ;
 ;                                                    ;
 ; Modifies:                                          ;
 ;      r0,r1,r2,r4,r9             (Conforms to APCS) ;
 ;                                                    ;
 ; ( ) = not needed as we are using default base      ;
 ;....................................................;
PrintHexWord:
        ;stmfd sp!, {r4, lr}                           ; As soon as we have a stack this will be added
        mov   r9,lr 
        adr   r2,hex_digits
        adr   r3,print_hex_string
        mov   r4,28

printhex_loop:
        ;; For r4 = 28 to 0 step -4
        mov   r1,r0,lsr r4                              ; Get digit n
        and   r1,r1, 0x0f                               ; mask off lower nibble
        ldrb  r1,[r2, r1]                               ; r0 now contains a hex number,
                                                        ; look it up in table
        strb  r1,[r3], 1
        subs  r4,r4, 4
        bpl   printhex_loop

        adr   r0,print_hex_string
        bl    PrintStringUart0

        mov   lr,r9
        mov   pc,lr                                     ; Return.
       ;ldmfd sp!,{r4, pc}                              ; As soon as we have a stack this will be added



align 4
hex_digits:
            db       "0123456789ABCDEF"
align 4
print_hex_string:
            db       "12345678",0                       ; storage for 8 digit hex string,
                                                        ; null terminated             

Macro.inc
Code: Select all
;---------------------------------------------------
;Some macros   Macro.inc
;
;     (c) Team DexOS 2009
;---------------------------------------------------

       macro adr reg,location {   ; simple micro
       add  reg,pc,location-$-8
}                                             

UartInc.inc
Code: Select all
;---------------------------------------------------
;Special Registers   UartInc.inc
;
;     (c) Team DexOS 2009
;---------------------------------------------------

UtrStatTxEmpty   = 4                       ;TX/RX status reg, TX  empty  bit
UtrStatTxReady   = 1                       ;TX/RX status reg, RX  ready  bit
UTxBuffer0l      = 0x20                    ;UART transmit buffer register (little-end)(Note: you need to add the UART line control register address)
UTxBuffer0b      = 0x23                    ;UART transmit buffer register (big end)(Note: you need to add the UART line control register address)
ULCon0           = 0x50000000              ;UART line control register address ( the first Uart)
UtrStat0         = 0x10                    ;UART Tx/Rx status register (Note: you need to add the UART line control register address)               


Now the bit that will need changing to run from the R-PI SD card are the
Code: Select all
org     0x30008000

You can find this from linux code, next bit is the UartInc.inc these are from a different ARM, just look in the ARM manual for the R-PI and change the values.
Thats it, you have the basic to debug a R-PI OS.
To assemble just down load FasmArm for your OS (win or linux) make the folders above and stick the right includes in and at the command line do

FasmArm UartTest.asm UartTest.bin <enter>

Now there are things to watch, has i have no PI yet, i can not test and theres little info.
But you may need to try these things
1. Replace UartTest.bin with the name of the linux image when assembling
2. Pack it out, so it bigger ( just see the "Just pack the progam out" code).
3. Theres also a chance the when it boots the linux image it looks for magic numbers in the image before passing control.
If thats the case i have a file that will convert the UartTest.bin and add the magic number i will find it and post.

Now it up to you who have the R-PI to get started first.

NOTE: This code is make assumptions that may not be the case, they are that a lot of work, in the setup is done by the GPU binary blob, before pass control to linux.
If this is not the case, them much more work will be need to be done and more info will be needed.
I have tried to keep this R-PI starter OS, very simple.
Batteries not included, Some assembly required.
User avatar
Posts: 851
Joined: Wed May 16, 2012 6:32 pm
by tufty » Thu May 17, 2012 1:15 pm
I'd just like to point out that the above won't work.

a - You don't have a vector table, so nothing will happen when you try to load. Woops.
b - 0xc0000000 is way, way above the ARM's physical memory map, which stops at 0x40000000 (0xc0008000 is the *virtual* memory address that the Linux kernel gets when the ARM MMU is fired up)

Simon
Posts: 1330
Joined: Sun Sep 11, 2011 2:32 pm
by Dave_G_2 » Thu May 17, 2012 1:19 pm
Thanks DexOS, perfect as a starting point.

As soon as I get my Pi, I will change the code from using the Uart to just toggling some GPIOs.
This way any uncertainty in the Uart code which you say you got from another ARM, is eliminated.
Once the rest of the code is confirmed as working 100%, then move on to the Uart.
(By the way, where do you set the baud rate, num bits etc of the uart?)

Now we just wait for the Foundation and Broadcom to start releasing some more details on the Pi.

@tufty
Surely vectors are only needed when we have calls from external pgms to the "kernel" functions?
User avatar
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm
by DexOS » Thu May 17, 2012 1:54 pm
tufty wrote:I'd just like to point out that the above won't work.

a - You don't have a vector table, so nothing will happen when you try to load. Woops.
b - 0xc0000000 is way, way above the ARM's physical memory map, which stops at 0x40000000 (0xc0008000 is the *virtual* memory address that the Linux kernel gets when the ARM MMU is fired up)

Simon

I do not think you read my post right or misunderstood it.
I point out in the above post that the
1. ORG will need changing.
2. That i have assumed, that the binary blob has done the setting up.

Now from the info we have, it must have set this stuff up to a known state, or it would not be able to do any setting up of the GPU etc.
Also LINUX expects to be in a known state when control is pass to it.
This would normally be done by a boot loader, like U-Boot.
But that work will be done by the blob.

Now when linuxs get control it may reset things to it liking, but i would say we are safe for now, until we have more info, as a basic hello world R-PI OS.
But i did point out these things in my post.

@Dave_G_2, Your welcome, i am very confident that with the changes that i have high lighted, that will need fixing as we get some info.
The code will work and write debug info to the Uart.
Batteries not included, Some assembly required.
User avatar
Posts: 851
Joined: Wed May 16, 2012 6:32 pm
by tufty » Thu May 17, 2012 3:44 pm
DexOS wrote:
tufty wrote:I'd just like to point out that the above won't work.

a - You don't have a vector table, so nothing will happen when you try to load. Woops.
b - 0xc0000000 is way, way above the ARM's physical memory map, which stops at 0x40000000 (0xc0008000 is the *virtual* memory address that the Linux kernel gets when the ARM MMU is fired up)

Simon

I do not think you read my post right or misunderstood it.
I point out in the above post that the
1. ORG will need changing.

OK, I'll accept that. It will need changing to 0x00000000. That's where the kernel binary is expected to be loaded (and is, in fact, loaded). That's been stated on the forums - ummmm - somewhere.

DexOS wrote:2. That i have assumed, that the binary blob has done the setting up.

Yep, the binary blob sets up the Pi in that it sets up a mapping for the GPU's MMC, which maps the ARM's "physical" address space to the MMU address space, and hooks up the various peripherals to the ARM. It will not set up the ARM's MMU. Once it has done that, it loads a flat binary kernel image into ARM memory starting at address 0x0 and triggers the ARM's reset.

As such, the first thing the ARM will do is jump to the reset vector address (0x0, as we are operating in "hardware" space).

So, your binary image *needs* to start with a valid vector table, and it *needs* to assume that it starts at 0x0. Obviously, once it's into the reset code, it can remap memory to its heart's content, but at least the first bits of code loaded will be operating under the assumption that they are at a given offset from 0x0.

This can be verified by dumping the first part of any linux kernel.img built for the Pi. It's not trivial to do, so here's the start of one:

Code: Select all
       0:       ea000006        b       0x20
       4:       e1a00000        nop                     ; (mov r0, r0)
       8:       e1a00000        nop                     ; (mov r0, r0)
       c:       e1a00000        nop                     ; (mov r0, r0)
      10:       e1a00000        nop                     ; (mov r0, r0)
      14:       e1a00000        nop                     ; (mov r0, r0)
      18:       e1a00000        nop                     ; (mov r0, r0)
      1c:       e1a00000        nop                     ; (mov r0, r0)
      20:       e3a00000        mov     r0, #0
      24:       e3a01042        mov     r1, #66 ; 0x42
      28:       e3811c0c        orr     r1, r1, #3072   ; 0xc00
      2c:       e59f2000        ldr     r2, [pc, #0]    ; 0x34
      30:       e59ff000        ldr     pc, [pc, #0]    ; 0x38


The uart is a pl011, by the way. Example code on arm.com
Posts: 1330
Joined: Sun Sep 11, 2011 2:32 pm
by Dave_G_2 » Thu May 17, 2012 3:54 pm
@tufty
Thanks for the dump.
This is coming together nicely as a start for a simple bare metal "OS" for the Pi.
So the ORG must be 0000000, at which there is a "jump" to offset 0x20, one thing that is confusing me
though, what are the 7 nops for ? (alignment)?
User avatar
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm
by tufty » Thu May 17, 2012 4:41 pm
Dave_G2 wrote:This is coming together nicely as a start for a simple bare metal "OS" for the Pi.
So the ORG must be 0000000, at which there is a "jump" to offset 0x20, one thing that is confusing me
though, what are the 7 nops for ? (alignment)?

They are the rest of the (initial, in the case of linux) vector table. If you're wanting to do an actual OS, you'll need more than just nops there :) Any bare metal arm reference will cover this <trumpet id='mine">as does my blog</trumpet>

When you come in, you're in SVC mode, with interrupts off and no mmu. Clock is set up, as is initial pin muxing (most μCs dont have this done, so you have to do it yourself). Oh, and you have no stack allocated, so be careful...

Simon.
Posts: 1330
Joined: Sun Sep 11, 2011 2:32 pm
by Dave_G_2 » Thu May 17, 2012 4:53 pm
@tufty
OK, heard the trumpet loud and clear :-) and now know the significance of the first 32 bytes
which form part of the vector table:

B _reset /* Reset: relative branch allows remap */
B . /* Undefined Instruction */
B . /* Software Interrupt */
B . /* Prefetch Abort */
B . /* Data Abort */
B . /* Reserved */
B . /* IRQ */
B . /* FIQ */
User avatar
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm
by DexOS » Thu May 17, 2012 8:54 pm
If it is 0x00000000 then its as simple case of adding the
Code: Select all
b labels

Jumps labels
Then setting all, but reset, to just loop.
And putting the start of our code at 0x8000, i will look into it more tomorrow.
Batteries not included, Some assembly required.
User avatar
Posts: 851
Joined: Wed May 16, 2012 6:32 pm
by Dave_G_2 » Sat May 19, 2012 3:34 pm
Been doing some more reading and if the reset vector is at 0x0000000 then ignoring interrupts
and stack etc for now, then won't simple code like this work as a starting point?
Once this is working then support for INTS and Fast INTS, STACK etc can be added.

Code: Select all
format binary
org     0x00000000
use32

; -------------------------------------------------------
; Vector table, only _RESET used for now
; others added after this confirmed
; to work.
; -------------------------------------------------------

Start:
   b   RealStart
   b   EndlessLoop
   b   EndlessLoop
   b   EndlessLoop
   b   EndlessLoop
   b   EndlessLoop
   b   EndlessLoop
   b   EndlessLoop

; -------------------------------------------------------
; For now, IRQ's, etc not used so
; simply go into endless loop or even
; toggle a GPIO pin every second.
; -------------------------------------------------------

EndlessLoop:

   b   EndlessLoop

; -------------------------------------------------------
The "kernel" will start here.
; -------------------------------------------------------

RealStart:

; kernel code here
; for example the DexOS Uart code.

; -------------------------------------------------------
; DATA and variables go here.
; As a basic start, we have no stack so
; variables can be used to store each of
; the 32 registers plus an extra for the
; PC register.
; -------------------------------------------------------

align 4
VAR_R0    dw 0x0
VAR_R1    dw 0x0
VAR_R2    dw 0x0
VAR_R3    dw 0x0

; etc etc

VAR_PC     dw 0x0

align 4
; -------------------------------------------------------
; Just pack the progam out, but as long as your program
; is at least 20k, you should not need this.
; -------------------------------------------------------

times 20000- ($-Start)  db 0



The disassembly as follows:

Code: Select all
Start:

0x00000000   ea000007   b   loc_24 ; (start of vector table)
0x00000004   ea000005   b   loc_20
0x00000008   ea000004   b   loc_20
0x0000000c   ea000003   b   loc_20
0x00000010   ea000002   b   loc_20
0x00000014   ea000001   b   loc_20
0x00000018   ea000000   b   loc_20
0x0000001c   eaffffff   b   loc_20 ; (end of vector table)

EndlessLoop:

0x00000020         loc_20: 
0x00000020   eafffffe   b   loc_20

RealStart:

0x00000024         loc_24:  ("kernel" code would normally follow)

DataSection

0x00000024   00000000   andeq   r0, r0, r0 ; (ignore as it's data for VAR_R1)
0x00000028   00000000   andeq   r0, r0, r0 ; (ignore as it's data for VAR_R2)
0x0000002c   00000000   andeq   r0, r0, r0 ; (ignore as it's data for VAR_R3)
0x00000030   00000000   andeq   r0, r0, r0 ; (ignore as it's data for VAR_R4)
       etc etc


Obviously this wouldn't make for a very useful OS.
It's meant only as a start off point.
Last edited by Dave_G_2 on Sat May 19, 2012 3:42 pm, edited 1 time in total.
User avatar
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm