krisk
Posts: 1
Joined: Mon Oct 08, 2018 7:01 am

Help With Simple Hello World Program in Bare Metal ASM

Mon Oct 08, 2018 7:10 am

Hello,

I've been following a tutorial on how to setup the GPIO and UART peripherals and output hello world on my Pi, but I am unable to get it to work.

The tutorial is: https://www.youtube.com/watch?v=4RrMoa5PS_M&t=165s

My Pi is: Zero W Version 1.1

My code is:

Code: Select all

	/* Store PIO-controller & UART-controller base-addresses. */
	ldr r0, =0x20200000	/* r0 = 0x20200000 */
	ldr r1, =0x20201000	/* r1 = 0x20201000 */
	
	/* Disable UART. */
	mov r2, #0		/* r2 = 0 */
	str r2, [r1, #0x30]	/* [20201030] = 0x0 */
	
	/* Setup GPIO pins (GGPUD). */
	str r2, [r0, #0x94]	/* [20200094] = 0x0 */

	/* Pause for 0x400000 loops. */
	ldr r3, =0x400000	/* r3 = 0x400000 */
l1:
	sub r3, r3, #1		/* r3 = r3 - 1 */
	cmp r3, #0		/* if r1 != 0x0 */
	bne l1		
	
	/* Setup GPIO pins (GGPUDCLK0). */
	mov r2, #0xC000		/* r2 = 0xC000 */
	str r2, [r0, #0x98]	/* [20200098] = 0xC000 */

	/* Pause for 0x400000 loops. */
	ldr r3, =0x400000	/* r3 = 0x400000 */
l2:
	sub r3, r3, #1		/* r3 = r3 - 1 */
	cmp r3, #0		/* if r1 != 0x0 */
	bne l2	
	
	/* Setup GPIO pins (GGPUD). */
	mov r2, #0x0		/* r2 = 0x0 */
	str r2, [r0, #0x98]	/* [20200098] = 0x0 */
	
	/* Config UART Inturrupt Clear Register (ICR). */
	ldr r2, =0x7FF		/* r2 = 0x7FF */
	str r2, [r1, #0x44]	/* [20201044] = 0x7FF */
	
	/* Set UART Baud rate (IBRD)/(FBRD). */
	mov r2, #1		/* r2 = 1 */
	str r2, [r1, #0x24]	/* [20201024] = 0x1 */
	
	mov r2, #40		/* r2 = 40 */
	str r2, [r1, #0x28]	/* [20201028] = 40 */
	
	/* Set UART Line Control Register (LCRH). */
	mov r2, #70			/* r2 = 70 */
	str r2, [r1, #0x2c]	/* [2020102c] = 70 */
	
	/* Set UART Inturrupt Set Mask Clear (IMSC) register. */
	ldr r2, =0x7F2		/* r2 = 0x7f2 */
	str r2, [r1, #0x38]	/* [20201038] = 0x7f2 */
	
	/* Set UART control-register. */
	ldr r2, =0x301		/* r2 = 0x301 */
	str r2, [r1, #0x30]	/* [20201030] = 0x301 */

	/* Output "Hello world!" to the UART Data Register. */
	mov r2, #0x48		/* r2 = 'H' (hex) */
	str r2, [r1]		/* [20201000] = 'H' (hex) */
	
	mov r2, #0x65		/* r2 = 'e' (hex) */
	str r2, [r1]		/* [20201000] = 'e' (hex) */
	
	mov r2, #0x6c		/* r2 = 'l' (hex) */
	str r2, [r1]		/* [20201000] = 'l' (hex) */
	str r2, [r1]		/* [20201000] = 'l' (hex) */
	
	mov r2, #0x6F		/* r2 = 'o' (hex) */
	str r2, [r1]		/* [20201000] = 'o' (hex) */
	
	mov r2, #0x20		/* r2 = ' ' (hex) */
	str r2, [r1]		/* [20201000] = ' ' (hex) */
	
	mov r2, #0x77		/* r2 = 'w' (hex) */
	str r2, [r1]		/* [20201000] = 'e' (hex) */
	
	mov r2, #0x6F		/* r2 = 'o' (hex) */
	str r2, [r1]		/* [20201000] = 'o' (hex) */
	
	mov r2, #0x72		/* r2 = 'r' (hex) */
	str r2, [r1]		/* [20201000] = 'r' (hex) */
	
	mov r2, #0x6c		/* r2 = 'l' (hex) */
	str r2, [r1]		/* [20201000] = 'l' (hex) */
	
	mov r2, #0x64		/* r2 = 'd' (hex) */
	str r2, [r1]		/* [20201000] = 'd' (hex) */
	
	mov r2, #0x21		/* r2 = '!' (hex) */
	str r2, [r1]		/* [20201000] = '!' (hex) */
Does anybody know where I've gone wrong with this?

Thanks in advance.

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

Re: Help With Simple Hello World Program in Bare Metal ASM

Mon Oct 08, 2018 3:37 pm

The video is for a different model the Pi1 you would need to adjust the peripheral address 0x20000000 vs 0x3F000000.

Goto the resources in the sticky threads and start there.

dwelch67
Posts: 944
Joined: Sat May 26, 2012 5:32 pm

Re: Help With Simple Hello World Program in Bare Metal ASM

Mon Oct 08, 2018 6:09 pm

its a pi-zero so 0x20xxxxxx is correct yes?

User avatar
rpdom
Posts: 12856
Joined: Sun May 06, 2012 5:17 am
Location: Ankh-Morpork

Re: Help With Simple Hello World Program in Bare Metal ASM

Mon Oct 08, 2018 6:32 pm

LdB wrote:
Mon Oct 08, 2018 3:37 pm
The video is for a different model the Pi1 you would need to adjust the peripheral address 0x20000000 vs 0x3F000000.
The Pi Zero uses the same SoC as the Pi1, so the address should be the same.

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

Re: Help With Simple Hello World Program in Bare Metal ASM

Tue Oct 09, 2018 2:55 am

Okay but isn't the address given the PL011 uart which will be going to the Wifi on the PiZeroW.
I suspect the 16550 uart (0x20215040) will be the one acting as the kernel output.

I use a few lines of assembler code to autodetect all this rubbish to avoid having to think about it but I was messing around with uart on models a few weeks ago and that is what I remember. So I will preface the above statement with I still think your address is wrong but for a different reason.

Anyhow look it up to be sure.

Return to “Bare metal, Assembly language”