LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 2:34 am

I am on same windows so that can't be problem.

You don't need to download FreeRTos it is on the repository :-)
https://github.com/LdB-ECM/Raspberry-Pi ... TOSv10.1.1
You just needed to change directory and do make Pi3-64

However given I have already made the new makefile for myBlinker try that first.

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 2:50 am

ok got it to work :).

line 27 in the make file had an extra '-gcc' in its directory path.

trillions of thanks again!!

if i were to just compile the 2 lines of code you mentioned in your post yesterday about MPIDR and get a result could you please advise how i can do that.

my process would be to:
create another e.g., a test.s file with the 2 lines it
change the file name in the make file to test.s (line 29)
do a make clean
then finally make Pi3-64
convert the .elf file to .img
copy the .img to SD card and boot from it

If the above procedure is correct I can compile and run any aarch64.s file and get to see an output? I use qemu as well as a physical monitor attached by hdmi.

cheers

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 3:05 am

Woot .. good news you are away.

Just set the EL2 register straight after the label _start:

After you do the drop to EL1 do the second part read EL1 and see what you have.

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 4:22 am

treading very cautiously here since i want to understand what is going on intimately.

_start: .global _start
.global main

main:
mrs x0, VMPIDR_EL2
.end

is the above what you meant by saying set el2

thx

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 5:44 am

You must have a section descriptor first then the global declaration which has a strange spelling ... I think correct spelling works these days but I am old school.

mrs is read from a register, msr is write to a register ... second letter r = read s = store is way to remember

you might want to read thru at least chapter 1-8 of this
https://thinkingeek.com/2016/10/08/expl ... -chapter1/
https://thinkingeek.com/2016/10/08/expl ... chapter-2/
https://thinkingeek.com/2016/10/23/expl ... chapter-3/
https://thinkingeek.com/2016/10/23/expl ... chapter-4/
https://thinkingeek.com/2016/11/13/expl ... chapter-5/
https://thinkingeek.com/2016/11/27/expl ... chapter-6/
https://thinkingeek.com/2017/03/19/expl ... chapter-7/
https://thinkingeek.com/2017/05/29/expl ... chapter-8/

anyhow code should be something like

Code: Select all

.section ".init", "ax", %progbits
.globl _start
_start:	
mov	x0, #7
msr VMPIDR_EL2, x0

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 6:26 am

ok maybe the last questions for today...

ofcourse it's MSR not MRS... for write..sorry my bad
why was there an mov instruction to mov 7 to x0

are the below lines standard for gcc assembler

.section ".init", "ax", %progbits
.globl _start
_start:

cheers

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 7:30 am

I thought that is what you wanted to write some virtual core id (I chose 7 as an example) into the EL2 level and check you got it back at EL1?

The only reason to write to that register is that :-)

Those lines are standard to both GCC and any aarch64 assembler
In the section line the name may vary that is up to the programmer

some just call the section .text
some will call it .boot
some will call it .init

It does not matter what you call the section so long as it matches the linker file

In my linker file we nominated it as being .init that starts at 0x80000
https://github.com/LdB-ECM/Raspberry-Pi ... r/rpi64.ld

Code: Select all

.init 0x80000 : {
		KEEP(*(.init))
	}

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 9:56 pm

Good Morning Mate,

Could you please advise how I can run the above code via command line. Do I have to run it from a linux pc or can I do it from Windows

This is what I did from command prompt...

aarch64-elf-as D:\RPi\Tests\test.s -o D:\RPi\Tests\test.o

test.s had your mpidr code in it. This command produced the .o file but what do I do with it or is this not the way to do it.

cheers

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Mon Feb 11, 2019 10:05 pm

ofcourse i need to link the file with rpi64.ld?

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Tue Feb 12, 2019 3:20 am

You do :-)

The easy cheat is just copy the makefile and linker file (rpi64.ld) from myblinker and edit the makefile to reflect your start.S.

For now just make an minimal main.c with

Code: Select all

int main(void)
{
    return 0;
}
You can also use qemu for the Raspberry Pi on Windows if you wish to debug and play with code on the PC.
https://www.codepool.biz/raspberry-pi-e ... ndows.html

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Tue Feb 12, 2019 3:55 am

do i need to have the c code? do i need to edit the .ld file to not include any c file?

i tried to use qemu but kept getting a message about not specifying block size. I will send you the message shortly after I redo the simulation.

thx.

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Wed Feb 13, 2019 9:19 pm

Good morning mate

Still working on getting an output from the aarch64 code to display in qemu.

I get a GTK warning at the command prompt but don’t see an output on the qemu console.

Any tips.

Cheers

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Thu Feb 14, 2019 1:37 am

Open a github account or similar and throw your work directory up .. be much easier if I could see everything to advise you.

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Sat Mar 16, 2019 4:35 am

Hi there LdB,

My apologies for this late reply. Just been caught up with work and I am now thinking of back tracking my learning objective to being an absolute beginner in assembly, c & aarch64. I was too quick to jump into the deep end.

I will for now try to focus my strengths on aarch64 assembly to the point of learning all there is about it incl. assembling it from command line and seeing an output. The assembly code can be as simple as adding 2 numbers and getting an output or displaying a simple text in command line. There will be no c code at all at this stage. I will work with an aarch64 assembly code with a linker and a make file. I have an assembly code below...

I also have a make file and a linker script. When I run it from command line I don't see the desired output. All I see is the output attached. The command I use is make run

/*
* Copyright (C) 2018 bzt ([email protected])
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/

.section ".text.boot"

.global _start

start = 1 /* start index */
max = 31 /* end index */

_start:
mov x9,start /* put index into x9 */
mov x10,10 /* Keep the divisor 10 in x10 */
loop:
mov x11,x9 /* move index into x11 */

/* Find out if index is 1 or 2 digits */
udiv x12,x11,x10 /* divide x11 by x10, put quotient in x12 */
msub x13,x10,x12,x11 /* remainder = x13 = x11 - (x10 * x12) */

/* Ones Decimal */
add x14,x13,0x30 /* remainder x13 + 0x30 = ASCII equivalent, move to x14 */
adr x15,msg /* load x15 with the address of msg */
strb w14,[x15,7] /* store w14 byte to address pointed by x15 + 7 */

/* Check if there is a tens decimal */
cmp x12,0 /* check if the quotient is 0 */
b.eq noTens /* if 0, there is no tens, just print msg */

/* There is a tens decimal */
add x14,x12,0x30 /* quotient x12 + 0x30 = ASCII equivalent, move to x14 */
adr x15,msg /* load x15 with the address of msg */
strb w14,[x15,6] /* store w14 byte to address pointed by x15 + 7 */

noTens:

mov x0,1 /* stdout = 1, move to argument 1 */
adr x1,msg /* move pointer to msg address to argument 2 */
mov x2,len /* move msg length to argument 3 */
mov x8,64 /* syscal 64 = write */
svc 0 /* invoke syscall */

/* Increment Loop */
add x9,x11,1 /* Index in x11 + 1, put in x9 loop index */
cmp x9,max /* compare index to max */
b.ne loop /* jump to loop if not equal */

/* Exit */
mov x0,0 /* status 0 = good */
mov x8,93 /* syscall 93 = exit */
svc 0 /* invoke syscall */

.data

msg: .ascii "Loop \n"
len = . - msg

__________________________________________________________________________

linker script

SECTIONS
{
. = 0x80000;
.text : { *(.text.boot) }

/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
}

__________________________________________________________________________

make file

CFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles

all: clean kernel8.img

start.o: start.S
aarch64-elf-gcc $(CFLAGS) -c start.S -o start.o

kernel8.img: start.o
aarch64-elf-ld -nostdlib -nostartfiles start.o -T link.ld -o kernel8.elf
aarch64-elf-objcopy -O binary kernel8.elf kernel8.img

clean:
rm kernel8.elf *.o *.img>/dev/null 2>/dev/null || true

run:
qemu-system-aarch64 -M virt -kernel kernel8.img -d in_asm

______________________________________________________________________________

output is attached.
Attachments
Screenshot from 2019-03-16 15-31-56.png
Screenshot from 2019-03-16 15-31-56.png (9.55 KiB) Viewed 591 times

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Sat Mar 16, 2019 4:54 am

Few obvious things

1.) You have a data section with a msg which currently has no positioning in your linker directive file. It looks like constant text so leave it in text section or put it in a RODATA section. DATA sections are for things that change and are data.
2.) You need to use KEEP(*(.text.boot)) you have discard on at end so you must nominate a keep section or everything may get discarded
3.) You have no setup for the CPU in any way no stacks, FPU etc which leads into point 4
4.) You have calls to svc 0 which you call syscall ... in baremetal you have not set any vector table and that goes know where except CPU death. What were you expecting svc 0 to do?

Can I suggest you do some reading .. read the 64bit starting section 5 page 35
https://static.docs.arm.com/dai0527/a/D ... essors.pdf
You can run without the cache but things like the vector table, stack, fp etc may be required especially if your code uses them :-)

Tony201800
Posts: 28
Joined: Sun Sep 09, 2018 9:57 am

Re: Bare Metal - Blinking an LED

Sat Mar 16, 2019 8:31 am

I guess I was confused again about what it is that I really want to do.

That bit of assembly code had an output screen under it where I got it from. I don't know whether it was coded up for baremetal or it had an OS but it was aarch64 assembly and that was what that pulled me towards it to try and run it myself.

Now I must teach 2 things to myself atleast:
aarch64 assembly
aarch64 assembly for baremetal

Naturally the later requires a great deal more effort and skill compared to just learning aarch64 assembly.

If I were to simply code up a very simple assembly code (absolutely no c at all) for adding 2 numbers in baremetal and outputting it to qemu-system-aarch64 chapter 5 of the pdf is what I need?

LdB
Posts: 1059
Joined: Wed Dec 07, 2016 2:29 pm

Re: Bare Metal - Blinking an LED

Sat Mar 16, 2019 12:44 pm

Okay I am going to direct you to Peter Lemons site it will clear things as there is no C at all
https://github.com/PeterLemon/RaspberryPi

Specifically his HelloWorld example without DMA in the CPU directory
https://github.com/PeterLemon/Raspberry ... ernel8.asm
Note it uses a bitmap map font which is a needs to make the characters on screen
This is each character between space and tilde which is 8 pixels wide by 8 pixels high .. hence 8x8
https://github.com/PeterLemon/Raspberry ... ont8x8.asm
If you want to understand the font I refer you to
https://wiki.osdev.org/VGA_Fonts

That is bare minimum code to put something up on screen so its a couple hundred lines + font bitmaps

If you have an external uart board you can make it less because writing a character is just a dump to uart rather than having to draw pixels on screen. I guess on your original code svc 0 dumped to the OS to draw a character string but in baremetal you have to provide that functionality.

Now a small thing Peter's code he uses a config.txt file and sets kernel_old=1 so his CPU starts at 0x0 and in EL3.
In most instances it doesn't matter except at the very start of the code he may punch EL3 registers and set orig that you don't need as you are entering via the normal Pi loader. So in https://github.com/PeterLemon/Raspberry ... ernel8.asm

He uses "org $0000" for you it will be "org $80000" and the next bit is not needed as the normal loader does it .. so you can start from FBInit:

Return to “Bare metal, Assembly language”