Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

F421: work around bug in old bootloader #68

Merged
merged 1 commit into from
Sep 12, 2024

Conversation

tridge
Copy link
Member

@tridge tridge commented Aug 19, 2024

the released F421 bootloader that comes on F4A boards (at least for the holybro 4-in-1) does this:

   0x08000b3a:	ldr	r0, [r4, #24]
   0x08000b3c:	str	r0, [r4, #28]
   0x08000b3e:	ldr	r0, [r5, #0]
   0x08000b40:	msr	MSP, r0
   0x08000b44:	ldr	r0, [r4, #28]
   0x08000b46:	ldmia.w	sp!, {r4, r5, r7, lr}
   0x08000b4a:	bx	r0

that writes to the application stack area before jumping. If the application stack is set to the end of ram then the ldmia instruction hard faults as it writes past the end of memory

this avoids the issue by only giving the app 15k instead of 16k of ram. This is not needed when we fix the bootloader to use the right jump method, which is this:

// setup sp, msp and jump
asm volatile(
    "mov sp, %0	\n"
    "msr msp, %0	\n"
    "bx	%1	\n"
: : "r"(stack_top), "r"(JumpAddress) :);

this issue is why the gcc generated F421 code didn't boot on F4A. The linker script for the gcc build puts the stack at the end of ram 0x20004000, whereas for some strange reason keil puts it at 0x20000e50

Note that the F421 bootloader currently in the download section of am32.ca has different jump code. It does this:
image
that does not write to the stack before the bx, so doesn't have the problem.
I'd guess the f421 bootloader was recompiled at some stage with different keil compiler or different compiler options?

Copy link
Collaborator

@freasy freasy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested on an Airbot G4 AIO - confirmed working with gcc build

@tridge tridge force-pushed the pr-f421-bootloader-workaround branch from 4956783 to e13dc3e Compare September 10, 2024 23:50
the released F421 bootloader does this:

   0x08000b3a:	ldr	r0, [r4, am32-firmware#24]
   0x08000b3c:	str	r0, [r4, am32-firmware#28]
   0x08000b3e:	ldr	r0, [r5, #0]
   0x08000b40:	msr	MSP, r0
   0x08000b44:	ldr	r0, [r4, am32-firmware#28]
   0x08000b46:	ldmia.w	sp!, {r4, r5, r7, lr}
   0x08000b4a:	bx	r0

that writes to the application stack area before jumping. If the
application stack is set to the end of ram then the ldmia instruction
hard faults as it writes past the end of memory

this avoids the issue by only giving the app 15k instead of 16k of
ram. This is not needed when we fix the bootloader to use the right
jump method, which is this:

    // setup sp, msp and jump
    asm volatile(
        "mov sp, %0	\n"
        "msr msp, %0	\n"
        "bx	%1	\n"
	: : "r"(stack_top), "r"(JumpAddress) :);
@tridge tridge force-pushed the pr-f421-bootloader-workaround branch from e13dc3e to cb42516 Compare September 12, 2024 02:10
@AlkaMotors AlkaMotors merged commit a3ff2af into am32-firmware:main Sep 12, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants