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
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.