BrainyZombie
Posts: 1
Joined: Sun Jul 26, 2020 8:37 pm

Baremetal resources for the Raspberry pi 4B?

Sun Jul 26, 2020 8:47 pm

I am a beginner at baremetal programming. My main goal is to learn to work with ARM processors and CMSIS libraries. I have the raspberry pi 4B, so I wanted to get started on it, but am unable to find learning resources for this version of the Raspberry Pi.
Do such resources exist yet? If not, how compatible is the 4B with the resources for the earlier versions?

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Wed Aug 05, 2020 3:58 am

My Github baremetal project, and the associated books, have been updated for RPi 4. See the following link for more information:
https://sean-lawless.github.io/computersystems/

The biggest change for RPi 4 is the change in the peripheral base to 0xFE000000. Older baremetal RPi code will often work for RPi 4 if you change this base address of the peripherals.
Cheers,
Sean

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Fri Aug 07, 2020 5:30 pm

Hi Sean, thanks for this link. I also searched for such resources. Before I invest anything here, however, I wanted to try the example with the flashing LED. Unfortunately it didn't work. I downloaded your source code, set the value "-DRPI = 4" and compiled it under msys2 with the build.sh script. The result was a "kernel.img", which should also be called. Copied to SD (with former Rasbian) and previously deleted all other kernels * .img. Renaming it in kernel7.img was also unsuccessful.
What am I doing wrong? Is there another trick?
In addition, you do not write which of the two LEDs (red or green) starts to flash.
Greetings, Matthias

User avatar
Paeryn
Posts: 3010
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Baremetal resources for the Raspberry pi 4B?

Fri Aug 07, 2020 11:47 pm

sean.lawless wrote:
Wed Aug 05, 2020 3:58 am
My Github baremetal project, and the associated books, have been updated for RPi 4. See the following link for more information:
https://sean-lawless.github.io/computersystems/

The biggest change for RPi 4 is the change in the peripheral base to 0xFE000000. Older baremetal RPi code will often work for RPi 4 if you change this base address of the peripherals.
Cheers,
Sean
Is the old method of configuring the pullups and pulldowns still useable on the RPi4? I had a quick look at your LED code and it configures them using GPPUD, GPPUDCLK0 & GPPUDCLK1 for all models but the RPi4 has four new registers GPIO_PUP_PDN_CNTRL_REGn (where n is 0..3) for setting them. I was under the impression that the three registers which the earlier RPis use aren't on the RPi4, they aren't listed in the BCM2711 doc.
She who travels light — forgot something.

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 4:15 am

@satyria - A lot can go wrong. Did you follow all the instructions from both main and lab books? If so, please also try turning off optimizations (change -O2 to -O0 in build.sh). I noticed this is -O0 in build.bat, but not build.sh... the for() loop may be optimized away so no blinking can be detected.

If *still* not working, please post the result of command 'arm-none-eabi-gcc -v' as well as 'arm-none-eabi-objdump led.elf' and I will do the best to assist debugging remotely.

@Paeryn, I suspect you are correct and will investigate further. However for compatibility I believe the old registers still exist on the RPI4 ; they just don't anything and the code works because the GPIO defaults for this pin (LED) match.

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 4:46 am

@satyria "Renaming it in kernel7.img was also unsuccessful.

Apologies I missed this. The filename is different on the RPI 4.
For RPI 4 the boot file for 32 bit (arm-none-eabi) is kernel7l.img. For 64 bit (aarch64-none-eabi) the boot file is kernel8.img.

So rename the compiled image kernel7l.img and then it should execute at power-on. Remember to rename/save the original kernel file and it may be required to rename the kernel8.img to prevent it from executing instead of kernel7l.img.

Cheers,
Sean

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 5:42 am

@Paeryn Thank you for your comment. The bcm2711 document references a new GPIO base interface (0x215000 instead of 0x200000). While the old GPIO interface (on 0x200000) still works on RPI4 for set/clear (and is used in the code), as you pointed out the PU/PD on this interface is not plumbed into the hardware on RPI4. To be fair to RPI4 readers who may need this feature on a different GPIO, the code will be updated to use the new GPIO interface (0x215000).

User avatar
Paeryn
Posts: 3010
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 10:00 am

sean.lawless wrote:
Mon Aug 10, 2020 5:42 am
@Paeryn Thank you for your comment. The bcm2711 document references a new GPIO base interface (0x215000 instead of 0x200000). While the old GPIO interface (on 0x200000) still works on RPI4 for set/clear (and is used in the code), as you pointed out the PU/PD on this interface is not plumbed into the hardware on RPI4. To be fair to RPI4 readers who may need this feature on a different GPIO, the code will be updated to use the new GPIO interface (0x215000).
I think the GPIO base in the doc is a typo and should be 0x200000 just like the other models, 0x215000 is the AUX base (page 12 of the 2711 doc). It's just the pull-updown registers that changed.
She who travels light — forgot something.

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 10:40 am

sean.lawless wrote:
Mon Aug 10, 2020 4:15 am
@satyria - A lot can go wrong. Did you follow all the instructions from both main and lab books? If so, please also try turning off optimizations (change -O2 to -O0 in build.sh). I noticed this is -O0 in build.bat, but not build.sh... the for() loop may be optimized away so no blinking can be detected.

If *still* not working, please post the result of command 'arm-none-eabi-gcc -v' as well as 'arm-none-eabi-objdump led.elf' and I will do the best to assist debugging remotely.

@Paeryn, I suspect you are correct and will investigate further. However for compatibility I believe the old registers still exist on the RPI4 ; they just don't anything and the code works because the GPIO defaults for this pin (LED) match.
Hello, thank you for your feedback and the circumstances you are going through.
I just proceeded as you described it, unfortunately without success.
A note beforehand: I have also made the experiments with an RPI1 and RPI2, without success there either.

Here are the relevant extracts for the RPi4:
ls for the Boot-SD:

Code: Select all

_kernel.img
_kernel7.img
_kernel7l.img
bcm2708-rpi-b.dtb
bcm2708-rpi-b-plus.dtb
bcm2708-rpi-cm.dtb
bcm2708-rpi-zero.dtb
bcm2708-rpi-zero-w.dtb
bcm2709-rpi-2-b.dtb
bcm2710-rpi-3-b.dtb
bcm2710-rpi-3-b-plus.dtb
bcm2710-rpi-cm3.dtb
bcm2711-rpi-4-b.dtb
bootcode.bin
cmdline.txt
config.txt
COPYING.linux
fixup.dat
fixup_cd.dat
fixup_db.dat
fixup_x.dat
fixup4.dat
fixup4cd.dat
fixup4db.dat
fixup4x.dat
issue.txt
kernel.list
kernel.map
kernel7l.img
LICENCE.broadcom
overlays
start.elf
start_cd.elf
start_db.elf
start_x.elf
start4.elf
start4cd.elf
start4db.elf
start4x.elf
System Volume Information
arm-none-eabi-gcc -v:

Code: Select all

Using built-in specs.
COLLECT_GCC=C:\msys64\usr\bin\arm-none-eabi-gcc.exe
COLLECT_LTO_WRAPPER=c:/msys64/usr/bin/../libexec/gcc/arm-none-eabi/9.2.1/lto-wrapper.exe
Target: arm-none-eabi
Configured with: /tmp/lto_build/src/gcc/configure --target=arm-none-eabi --prefix=/tmp/lto_build/build-mingw-arm-none-eabi/install// --with-gmp=/tmp/lto_build/build-mingw-arm-none-eabi/host-tools --with-mpfr=/tmp/lto_build/build-mingw-arm-none-eabi/host-tools --with-mpc=/tmp/lto_build/build-mingw-arm-none-eabi/host-tools --with-isl=/tmp/lto_build/build-mingw-arm-none-eabi/host-tools --disable-shared --disable-nls --disable-threads --disable-tls --enable-checking=release --enable-languages=c,c++,fortran --with-newlib --with-libiconv-prefix=/tmp/lto_build/build-mingw-arm-none-eabi/host-tools --host=i686-w64-mingw32 --with-pkgversion='GNU Toolchain for the A-profile Architecture 9.2-2020.02 (arm-9.10)' --with-bugurl=https://bugs.linaro.org/
Thread model: single
gcc version 9.2.1 20191025 (GNU Toolchain for the A-profile Architecture 9.2-2020.02 (arm-9.10))
arm-none-eabi-objdump -S led.elf

Code: Select all

led.elf:     file format elf32-littlearm


Disassembly of section .text:

00008000 <main>:
/*        main: Application Entry Point                              */
/*                                                                   */
/*     Returns: Exit error                                           */
/*...................................................................*/
int main(void)
{
    8000:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
    8004:	e28db000 	add	fp, sp, #0
    8008:	e24dd00c 	sub	sp, sp, #12
  unsigned int i, select;

#if RPI == 4
  /* GPIO 42 is 2nd register in GPFSEL4, so 2 * 3 bits or bit 6. */
  /* Clear the 3 bit range (7) starting at bit 6 */
  select = REG32(GPFSEL4);
    800c:	e59f3244 	ldr	r3, [pc, #580]	; 8258 <main+0x258>
    8010:	e5933000 	ldr	r3, [r3]
    8014:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 6);
    8018:	e51b300c 	ldr	r3, [fp, #-12]
    801c:	e3c33d07 	bic	r3, r3, #448	; 0x1c0
    8020:	e50b300c 	str	r3, [fp, #-12]

  /* Configure the LED (GPIO 42) starting at bit 6, as output (1). */
  select |= (GPIO_OUTPUT << 6);
    8024:	e51b300c 	ldr	r3, [fp, #-12]
    8028:	e3833040 	orr	r3, r3, #64	; 0x40
    802c:	e50b300c 	str	r3, [fp, #-12]
  REG32(GPFSEL4) = select;
    8030:	e59f2220 	ldr	r2, [pc, #544]	; 8258 <main+0x258>
    8034:	e51b300c 	ldr	r3, [fp, #-12]
    8038:	e5823000 	str	r3, [r2]
  /*   (0) disable pull up and pull down to float the GPIO */
  /*   (1 << 0) enable pull down (low) */
  /*   (1 << 1) enable pull up (high) */

  /* Always pull up (high) for LEDs as they require voltage. */
  REG32(GPPUD) = GPPUD_PULL_UP;
    803c:	e59f3218 	ldr	r3, [pc, #536]	; 825c <main+0x25c>
    8040:	e3a02002 	mov	r2, #2
    8044:	e5832000 	str	r2, [r3]

  /* Loop to wait until GPPUD assignment persists. */
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    8048:	e3a03000 	mov	r3, #0
    804c:	e50b3008 	str	r3, [fp, #-8]
    8050:	ea000005 	b	806c <main+0x6c>
    select = REG32(GPFSEL4);
    8054:	e59f31fc 	ldr	r3, [pc, #508]	; 8258 <main+0x258>
    8058:	e5933000 	ldr	r3, [r3]
    805c:	e50b300c 	str	r3, [fp, #-12]
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    8060:	e51b3008 	ldr	r3, [fp, #-8]
    8064:	e2833001 	add	r3, r3, #1
    8068:	e50b3008 	str	r3, [fp, #-8]
    806c:	e51b3008 	ldr	r3, [fp, #-8]
    8070:	e3530e7d 	cmp	r3, #2000	; 0x7d0
    8074:	3afffff6 	bcc	8054 <main+0x54>

#if RPI == 4
  /* Push GPPUD settings to GPPUDCLK1 GPIO 42. */
  REG32(GPPUDCLK1) = (1 << (42 - 32)); /* GPIO 42 */
    8078:	e59f31e0 	ldr	r3, [pc, #480]	; 8260 <main+0x260>
    807c:	e3a02b01 	mov	r2, #1024	; 0x400
    8080:	e5832000 	str	r2, [r3]
  /* Push GPPUD settings to GPPUDCLK1 GPIO 47. */
  REG32(GPPUDCLK1) = (1 << (47 - 32)); /* GPIO 47 */
#endif

  /* Loop to wait until GPPUD clock assignment persists. */
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    8084:	e3a03000 	mov	r3, #0
    8088:	e50b3008 	str	r3, [fp, #-8]
    808c:	ea000005 	b	80a8 <main+0xa8>
    select = REG32(GPFSEL4);
    8090:	e59f31c0 	ldr	r3, [pc, #448]	; 8258 <main+0x258>
    8094:	e5933000 	ldr	r3, [r3]
    8098:	e50b300c 	str	r3, [fp, #-12]
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    809c:	e51b3008 	ldr	r3, [fp, #-8]
    80a0:	e2833001 	add	r3, r3, #1
    80a4:	e50b3008 	str	r3, [fp, #-8]
    80a8:	e51b3008 	ldr	r3, [fp, #-8]
    80ac:	e3530e7d 	cmp	r3, #2000	; 0x7d0
    80b0:	3afffff6 	bcc	8090 <main+0x90>
  /*
   * Enable the JTAG GPIOs
  */

  /* Disable pull up/down for the next configured GPIO. */
  REG32(GPPUD) = GPPUD_OFF;
    80b4:	e59f31a0 	ldr	r3, [pc, #416]	; 825c <main+0x25c>
    80b8:	e3a02000 	mov	r2, #0
    80bc:	e5832000 	str	r2, [r3]

  /* Loop to wait until GPPUD assignment persists. */
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    80c0:	e3a03000 	mov	r3, #0
    80c4:	e50b3008 	str	r3, [fp, #-8]
    80c8:	ea000005 	b	80e4 <main+0xe4>
    select = REG32(GPFSEL4);
    80cc:	e59f3184 	ldr	r3, [pc, #388]	; 8258 <main+0x258>
    80d0:	e5933000 	ldr	r3, [r3]
    80d4:	e50b300c 	str	r3, [fp, #-12]
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    80d8:	e51b3008 	ldr	r3, [fp, #-8]
    80dc:	e2833001 	add	r3, r3, #1
    80e0:	e50b3008 	str	r3, [fp, #-8]
    80e4:	e51b3008 	ldr	r3, [fp, #-8]
    80e8:	e3530e7d 	cmp	r3, #2000	; 0x7d0
    80ec:	3afffff6 	bcc	80cc <main+0xcc>

  // Apply to all the JTAG GPIO pins
  REG32(GPPUDCLK0) = (1 << 22) | (1 << 23) | (1 << 24) | (1 << 25) |
    80f0:	e59f316c 	ldr	r3, [pc, #364]	; 8264 <main+0x264>
    80f4:	e3a0253f 	mov	r2, #264241152	; 0xfc00000
    80f8:	e5832000 	str	r2, [r3]
                     (1 << 26) | (1 << 27);

  /* Loop to wait until GPPUD clock assignment persists. */
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    80fc:	e3a03000 	mov	r3, #0
    8100:	e50b3008 	str	r3, [fp, #-8]
    8104:	ea000005 	b	8120 <main+0x120>
    select = REG32(GPFSEL4);
    8108:	e59f3148 	ldr	r3, [pc, #328]	; 8258 <main+0x258>
    810c:	e5933000 	ldr	r3, [r3]
    8110:	e50b300c 	str	r3, [fp, #-12]
  for (i = 0; i < TOGGLE_LOOP_CNT / 1000; ++i)
    8114:	e51b3008 	ldr	r3, [fp, #-8]
    8118:	e2833001 	add	r3, r3, #1
    811c:	e50b3008 	str	r3, [fp, #-8]
    8120:	e51b3008 	ldr	r3, [fp, #-8]
    8124:	e3530e7d 	cmp	r3, #2000	; 0x7d0
    8128:	3afffff6 	bcc	8108 <main+0x108>

  // Select level alternate 4 to enable JTAG
  select = REG32(GPFSEL2);
    812c:	e59f3134 	ldr	r3, [pc, #308]	; 8268 <main+0x268>
    8130:	e5933000 	ldr	r3, [r3]
    8134:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 6); //gpio22
    8138:	e51b300c 	ldr	r3, [fp, #-12]
    813c:	e3c33d07 	bic	r3, r3, #448	; 0x1c0
    8140:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 6; //alt4 ARM_TRST
    8144:	e51b300c 	ldr	r3, [fp, #-12]
    8148:	e38330c0 	orr	r3, r3, #192	; 0xc0
    814c:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 9); //gpio23
    8150:	e51b300c 	ldr	r3, [fp, #-12]
    8154:	e3c33c0e 	bic	r3, r3, #3584	; 0xe00
    8158:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 9; //alt4 ARM_RTCK
    815c:	e51b300c 	ldr	r3, [fp, #-12]
    8160:	e3833c06 	orr	r3, r3, #1536	; 0x600
    8164:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 12); //gpio24
    8168:	e51b300c 	ldr	r3, [fp, #-12]
    816c:	e3c33a07 	bic	r3, r3, #28672	; 0x7000
    8170:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 12; //alt4 ARM_TDO
    8174:	e51b300c 	ldr	r3, [fp, #-12]
    8178:	e3833a03 	orr	r3, r3, #12288	; 0x3000
    817c:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 15); //gpio25
    8180:	e51b300c 	ldr	r3, [fp, #-12]
    8184:	e3c3390e 	bic	r3, r3, #229376	; 0x38000
    8188:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 15; //alt4 ARM_TCK
    818c:	e51b300c 	ldr	r3, [fp, #-12]
    8190:	e3833906 	orr	r3, r3, #98304	; 0x18000
    8194:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 18); //gpio26
    8198:	e51b300c 	ldr	r3, [fp, #-12]
    819c:	e3c33707 	bic	r3, r3, #1835008	; 0x1c0000
    81a0:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 18; //alt4 ARM_TDI
    81a4:	e51b300c 	ldr	r3, [fp, #-12]
    81a8:	e3833703 	orr	r3, r3, #786432	; 0xc0000
    81ac:	e50b300c 	str	r3, [fp, #-12]
  select &= ~(7 << 21); //gpio27
    81b0:	e51b300c 	ldr	r3, [fp, #-12]
    81b4:	e3c3360e 	bic	r3, r3, #14680064	; 0xe00000
    81b8:	e50b300c 	str	r3, [fp, #-12]
  select |= GPIO_ALT4 << 21; //alt4 ARM_TMS
    81bc:	e51b300c 	ldr	r3, [fp, #-12]
    81c0:	e3833606 	orr	r3, r3, #6291456	; 0x600000
    81c4:	e50b300c 	str	r3, [fp, #-12]
  REG32(GPFSEL2) = select;
    81c8:	e59f2098 	ldr	r2, [pc, #152]	; 8268 <main+0x268>
    81cc:	e51b300c 	ldr	r3, [fp, #-12]
    81d0:	e5823000 	str	r3, [r2]
  for (;;)
  {
    /* Turn on the activity LED. */
#if RPI == 4
    /* RPI 4 has LED at GPIO 42, so set GPIO 42. */
    REG32(GPSET1) = 1 << (42 - 32);
    81d4:	e59f3090 	ldr	r3, [pc, #144]	; 826c <main+0x26c>
    81d8:	e3a02b01 	mov	r2, #1024	; 0x400
    81dc:	e5832000 	str	r2, [r3]
    /* Other RPIs have LED at GPIO 47, so set GPIO 47. */
    REG32(GPSET1) = 1 << (47 - 32);
#endif

    // Loop to wait a bit
    for (i = 0; i < TOGGLE_LOOP_CNT; ++i) /* loop to pause LED on */
    81e0:	e3a03000 	mov	r3, #0
    81e4:	e50b3008 	str	r3, [fp, #-8]
    81e8:	ea000005 	b	8204 <main+0x204>
      select = REG32(GPFSEL4);
    81ec:	e59f3064 	ldr	r3, [pc, #100]	; 8258 <main+0x258>
    81f0:	e5933000 	ldr	r3, [r3]
    81f4:	e50b300c 	str	r3, [fp, #-12]
    for (i = 0; i < TOGGLE_LOOP_CNT; ++i) /* loop to pause LED on */
    81f8:	e51b3008 	ldr	r3, [fp, #-8]
    81fc:	e2833001 	add	r3, r3, #1
    8200:	e50b3008 	str	r3, [fp, #-8]
    8204:	e51b3008 	ldr	r3, [fp, #-8]
    8208:	e59f2060 	ldr	r2, [pc, #96]	; 8270 <main+0x270>
    820c:	e1530002 	cmp	r3, r2
    8210:	3afffff5 	bcc	81ec <main+0x1ec>

    /* Turn off the activity LED. */
#if RPI == 4
    /* RPI 4 has LED at GPIO 42, so clear GPIO 42. */
    REG32(GPCLR1) = 1 << (42 - 32);
    8214:	e59f3058 	ldr	r3, [pc, #88]	; 8274 <main+0x274>
    8218:	e3a02b01 	mov	r2, #1024	; 0x400
    821c:	e5832000 	str	r2, [r3]
    /* Other RPIs have LED at GPIO 47, so clear GPIO 47. */
    REG32(GPCLR1) = 1 << (47 - 32);
#endif

    // Loop to wait a bit
    for (i = 0; i < TOGGLE_LOOP_CNT; ++i) /* loop to pause LED off */
    8220:	e3a03000 	mov	r3, #0
    8224:	e50b3008 	str	r3, [fp, #-8]
    8228:	ea000005 	b	8244 <main+0x244>
      select = REG32(GPFSEL4);
    822c:	e59f3024 	ldr	r3, [pc, #36]	; 8258 <main+0x258>
    8230:	e5933000 	ldr	r3, [r3]
    8234:	e50b300c 	str	r3, [fp, #-12]
    for (i = 0; i < TOGGLE_LOOP_CNT; ++i) /* loop to pause LED off */
    8238:	e51b3008 	ldr	r3, [fp, #-8]
    823c:	e2833001 	add	r3, r3, #1
    8240:	e50b3008 	str	r3, [fp, #-8]
    8244:	e51b3008 	ldr	r3, [fp, #-8]
    8248:	e59f2020 	ldr	r2, [pc, #32]	; 8270 <main+0x270>
    824c:	e1530002 	cmp	r3, r2
    8250:	3afffff5 	bcc	822c <main+0x22c>
    REG32(GPSET1) = 1 << (42 - 32);
    8254:	eaffffde 	b	81d4 <main+0x1d4>
    8258:	fe200010 	.word	0xfe200010
    825c:	fe200094 	.word	0xfe200094
    8260:	fe20009c 	.word	0xfe20009c
    8264:	fe200098 	.word	0xfe200098
    8268:	fe200008 	.word	0xfe200008
    826c:	fe200020 	.word	0xfe200020
    8270:	001e8480 	.word	0x001e8480
    8274:	fe20002c 	.word	0xfe20002c
If you still need any information, just report
Regards, Matthias

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

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 12:17 pm

Your code will crash from the first assembler code ... you obviously didn't read any of the stickies
You haven't set the stack pointer (SP) how the hell do you expect to push onto the stack "push {fp}" or you are using only C with no assembler boot?????

How about you try something really basic like we all started set the SP at the top of the start address so it can work down towards 0x0 if need

Code: Select all

mov sp,#0x8000

If you are trying to write only in C you will need to make main naked attribute it can't carry prolog or epilog
https://www.keil.com/support/man/docs/a ... 564298.htm
The first line in the main code is then inline assembler for the SP above

Code: Select all

__attribute__((naked)) void main (void) 
{

	__asm volatile("mov sp,#0x8000");

      // Rest of C code here

}
The output of that is this

Code: Select all

kernel.elf:     file format elf32-littlearm


Disassembly of section .init:

00008000 <main>:
    8000:	e3a0d902 	mov	sp, #32768	; 0x8000

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 1:04 pm

LdB wrote:
Mon Aug 10, 2020 12:17 pm
Your code will crash from the first assembler code ... you obviously didn't read any of the stickies
You haven't set the stack pointer (SP) how the hell do you expect to push onto the stack "push {fp}" or you are using only C with no assembler boot?????

How about you try something really basic like we all started set the SP at the top of the start address so it can work down towards 0x0 if need

Code: Select all

mov sp,#0x8000

If you are trying to write only in C you will need to make main naked attribute it can't carry prolog or epilog
https://www.keil.com/support/man/docs/a ... 564298.htm
The first line in the main code is then inline assembler for the SP above

Code: Select all

__attribute__((naked)) void main (void) 
{

	__asm volatile("mov sp,#0x8000");

      // Rest of C code here

}
The output of that is this

Code: Select all

kernel.elf:     file format elf32-littlearm


Disassembly of section .init:

00008000 <main>:
    8000:	e3a0d902 	mov	sp, #32768	; 0x8000
Hm, I stuck to the documentation from Post 2 here. The corresponding source is also offered here to compile the examples. Since this is a kind of commercial offer, I assume that it will also work.
Maybe I misunderstood something there. Unfortunately, English is not my native language.

Greetings, Matthias

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

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 1:22 pm

Again >>> YOUR COMPILER <<< is producing prolog which will crash the system ... it has nothing to do with code
https://en.wikipedia.org/wiki/Function_prologue

This is what this is .... stock standard ARM prolog

Code: Select all

    8000:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
    8004:	e28db000 	add	fp, sp, #0
    8008:	e24dd00c 	sub	sp, sp, #12

You need to do one of two options
1.) stop the prolog being produced .. aka you need some compiler directive on your makefile

OR

2.) place a naked attribute on main and set the stack pointer as shown above.
So if prolog is created by the compiler the stack pointer (SP) is valid

Either will fix the problem ... so pick one and do it

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 7:00 pm

@ Satyria The problem is as LdB described. With newer arm-none-eabi-gcc/ld the prolog (push) is crashing the application because the the stack pointer (SP) was not explicitly set first. The only known work around is to boot into Raspbian, rename the /boot/kernel7l.img and replace with the compiled application, and then restart. Upon restart the bare metal application will have a valid SP (left over from Linux boot) and will execute (in my tests).

In Chapter 7 of the book/lab we discuss the stack pointer (SP) in detail, but for simplicity (and not to overwhelm the reader) we omit discussion until then and instead (unreliably) rely on a default SP (or no prolog). This decision to discuss SP later appears to have been a mistake as the compiled bare metal applications no longer reliably work with newer arm-none-eabi-gcc/ld due to undefined SP.

I will update the code with the naked attribute and explicit SP assignment, as suggested by LdB. For now you can change Lab4 LED/main.c to:

Code: Select all

__attribute__((naked)) void main(void)
{
  __asm volatile("mov sp,#0x8000");

  // Rest of C code is the same
  unsigned int i, select;
After this the bare metal application should execute without the work around above (boot into linux first). This change needs to be applied to all applications until Chapter 7, until I update the Git repo. Or you can test any application from Chapter 7 onward as these set the SP.

User avatar
Paeryn
Posts: 3010
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 7:38 pm

I'd be wary about declaring main() with the naked attribute, you aren't supposed to have any C code in a naked function. To quote gcc (emphasis mine)
naked

This attribute allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only basic asm statements can safely be included in naked functions. While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
She who travels light — forgot something.

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Mon Aug 10, 2020 8:54 pm

@Paeryn "I'd be wary about declaring main() with the naked attribute"

Yes! The example intends to show how main() is executed first because it is first in the link order (we have not created _start() assembly function yet). The fix I just checked in adds a global inline assembly statement before main() that initializes the stack pointer. This avoids the need to define main as naked. This one line was added to the main.c of all three affected chapters (4, 5, and 6). Thank you for helping me pinpoint the problem and Satyria for bringing this to my attention. Bare metal tools and hardware are always a moving target. Next revision of the book will include a brief discussion of SP and this line (move from chapter 7).

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

Re: Baremetal resources for the Raspberry pi 4B?

Tue Aug 11, 2020 1:50 am

1.) If the compiler is kicking out prolog/epilog the naked attribute will work ... it is what it is designed to do and the only function level way of controlling it. The GCC is statement is rather funny when you look at the GCC source code it is rather obvious what it does on both an ARM and Intel and I would trust the GCC manual at about the same level of much of their other documentation (hint try looking up flags). However at the end of day you just do what I did compile it and see what it does and it's quite clear that it did the right thing.

2.) I already commented above there should be an assembler bootstub which was missing.

Sean I haven't looked at your later examples but you have more issues to deal with. The Pi starts with the FPU offline you will need code to bring it online if you start with code that wants to use the FPU it will crash. The core is also still in hypovisor mode in your first examples you will need to do some register settings if you want to take interrupts at that level personally I would drop to EL1 in either sys or svc mode.

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Tue Aug 11, 2020 2:23 am

@LdB

1. Yes your change did the right thing. I suspect the documentation warning is related to function calls within a naked function which would be unreliable without a stack. However, I felt the change to set the SP before main and remove the naked attribute would be easier to explain in the book.

2. The assembler bootstub (_start()) is introduced in Chapter 7 when we discuss the stack pointer in detail and devise a strategy so RAM can be shared between both the bootloader and the downloaded application executing simultaneously (ie. switching back and forth without stepping on each others stack).

As for FPU, moving out of hypovisor mode ("low peripheral" mode?) and enabling interrupts, this is beyond our intended audience, at least by Chapter 4. Since the code does not use the FPU or interrupts we can avoid this discussion. We have to take some liberties and assume the HW/Firmware defaults are enough to avoid overwhelming the reader (this philosophy is why we missed the stack pointer, not because it was unnecessary, but because we didn't want to talk about it yet and the defaults appeared to work).

If you are an experienced embedded engineer I do not believe the books/Github project are going to challenge/engage your level of curiosity, except for possibly our novel asynchronous scheduler (OS). This said, I am trying to set up a website/blog where others can post chapters/appendix's that expand on particular gaps, such as the FPU, Interrupts, etc. Hopefully over time we can make the code base more robust and suitable for use as a base for third party applications.

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Tue Aug 11, 2020 9:21 am

sean.lawless wrote:
Mon Aug 10, 2020 7:00 pm

Code: Select all

__attribute__((naked)) void main(void)
{
  __asm volatile("mov sp,#0x8000");

  // Rest of C code is the same
  unsigned int i, select;
Thanks for pointing this out, after a small change it has now worked.
Before:

Code: Select all

__attribute__((naked)) void main(void)
After that:

Code: Select all

__attribute__((naked)) int main(void)
LdB wrote: How about you try something really basic like we all started set the SP at the top of the start address so it can work down towards 0x0 if need
For me this was a basic thing. Before I go deeper into the matter, I wanted to at least clarify the basics. In this regard, I only had setbacks with RPI2 when it came to USB support. At the time, the RPI2 was new to the market and information was few. Here were my experiments in pure "assembler" and I did not have this problem. For me this is the first time that I have tried something like this with "C" ... Now I want to try again with the RPI4 and possibly again in pure assembler. But even like back then, the information is still very few and I was overjoyed to find this guide. But if you try that and then it doesn't work, it's very depressing.

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

Re: Baremetal resources for the Raspberry pi 4B?

Tue Aug 11, 2020 1:03 pm

You are going to struggle on a Pi4 in assembler the A72 is an out of order CPU . I ran into trouble just getting my normal smartstart boot code up with a couple of memory barriers required. Then you have the problem the Pi4 documentation is sparse.

If you really want to just mess around with assembler on these sorts of boards I would strongly suggest something like a stock standard AllWinner V3s. There are dozens of open hardware designs around for it one that takes the Pi format is called blueberry Pi
https://github.com/petit-miner/Blueberry-PI

That has full schematics, PCB files and linux code etc it's all there and it's a single core cortexA7. The reference doesn't add external ram so it's only got 64Mb but it's plenty for playing around baremetal. I use it on a number of custom embedded projects and it's only $3USD for the chip if you want to get you own board design made up.

Just trying to be realistic here the Pi4 is not something to play around with as a beginner.

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Wed Aug 12, 2020 8:56 am

sean.lawless wrote:
Tue Aug 11, 2020 2:23 am
fly
Got a new problem with the documentation.
I have now successfully tested the LED example for the RPI4 and RPI2. However, it does not work on the RPI1. I changed the build.sh file accordingly:

Code: Select all

arm-none-eabi-gcc -c -DRPI=1 -O2 -ffreestanding -I. -o main.o main.c
and tested with:

Code: Select all

arm-none-eabi-gcc -c -DRPI=1 -O0 -ffreestanding -I. -o main.o main.c
What could this be due to?

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Wed Aug 12, 2020 1:56 pm

Hi,

I once solved it for my RPi1. Here it was because the wrong pin was being addressed. I changed the following code:

Code: Select all

#else
    /* Other RPIs have LED at GPIO 47, so set GPIO 47. */
    /* old: REG32(GPSET1) = 1 << (47 - 32);*/
    /* new:*/
	REG32(GPSET0) = 1 << (16);
	
#endif
Other RPIs have LED at GPIO 47, so set GPIO 47.
That is not correct. With an RPI1 is the address GPIO 16.

This at least worked on my RPI1. But I like to be taught if I am wrong.
Greetings, Matthias

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Wed Aug 12, 2020 4:51 pm

I have now changed a very old resource for the RPi1 to an RPi4 code.
The original can be found on the page
https://www.cl.cam.ac.uk/projects/raspb ... ndex.html
with the project OK02.
You can find the modified code at http://raspi.satyria.de/assem/ok0204/main.s if you are interested.

sean.lawless
Posts: 23
Joined: Thu Jun 06, 2019 6:07 pm

Re: Baremetal resources for the Raspberry pi 4B?

Fri Aug 14, 2020 4:03 am

satyria wrote:
Wed Aug 12, 2020 1:56 pm
Other RPIs have LED at GPIO 47, so set GPIO 47.
That is not correct. With an RPI1 is the address GPIO 16.

This at least worked on my RPI1. But I like to be taught if I am wrong.
Greetings, Matthias
For the RPI 1B+ the LED GPIO is 47. I suspect you have an RPI 1A? Hardware I have and test with are RPI 1B+, RPI 2, RPI 3B+ and RPI 4B.

User avatar
rpdom
Posts: 17427
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Baremetal resources for the Raspberry pi 4B?

Fri Aug 14, 2020 4:53 am

The 1A and 1B had the ACT LED on GPIO 16.
Unreadable squiggle

satyria
Posts: 28
Joined: Sun May 12, 2013 5:41 pm

Re: Baremetal resources for the Raspberry pi 4B?

Thu Aug 20, 2020 11:03 am

Is there a list of all Raspi's, to which GPIO the internal LEDs are connected?

Return to “Bare metal, Assembly language”